@supatest/wdio-appium-reporter
v0.0.4
Published
Supatest Appium reporter - stream mobile test results to Supatest dashboard
Maintainers
Readme
@supatest/wdio-appium-reporter
WebdriverIO reporter for Appium that streams mobile test results to the Supatest dashboard in real-time. Captures device metadata, screenshots, screen recordings, and CI/Git context for iOS and Android runs.
Requirements
- Node.js >= 18.0.0
- WebdriverIO >= 8.0.0
- Appium >= 2.0.0
@wdio/appium-service
Installation
npm install @supatest/wdio-appium-reporter --save-dev
# or
pnpm add @supatest/wdio-appium-reporter --save-devConfiguration
Add to your wdio.conf.ts:
import type { Options } from '@wdio/types';
export const config: Options.Testrunner = {
services: [
['appium', {
command: 'appium',
args: { relaxedSecurity: true },
}],
],
reporters: [
'spec',
['@supatest/wdio-appium-reporter', {
projectId: process.env.SUPATEST_PROJECT_ID,
apiKey: process.env.SUPATEST_API_KEY,
}],
],
};iOS example
const iosCapabilities = {
platformName: 'iOS',
'appium:deviceName': 'iPhone 15 Pro',
'appium:platformVersion': '17.2',
'appium:automationName': 'XCUITest',
'appium:app': '/path/to/MyApp.app',
'appium:bundleId': 'com.example.myapp',
};Android example
const androidCapabilities = {
platformName: 'Android',
'appium:deviceName': 'emulator-5554',
'appium:platformVersion': '13',
'appium:automationName': 'UiAutomator2',
'appium:app': '/path/to/MyApp.apk',
'appium:appPackage': 'com.example.myapp',
'appium:appActivity': 'com.example.myapp.MainActivity',
};Environment Variables
| Variable | Description |
|----------|-------------|
| SUPATEST_API_KEY | Required. Your Supatest API key |
| SUPATEST_PROJECT_ID | Required. Your project identifier for organizing test runs |
| SUPATEST_API_URL | Optional. Custom API endpoint (default: https://code-api.supatest.ai) |
| SUPATEST_DRY_RUN | Optional. Set to true to log payloads instead of sending |
Configuration Options
| Option | Type | Default | Description |
|--------|------|---------|-------------|
| projectId | string | — | Required. Your Supatest project ID |
| apiKey | string | — | Required. Your Supatest API key |
| apiUrl | string | https://code-api.supatest.ai | API endpoint URL |
| uploadAssets | boolean | true | Upload screenshots and screen recordings |
| screenshotDir | string | — | Watch this directory for screenshots saved via browser.saveScreenshot() |
| maxConcurrentUploads | number | 5 | Maximum concurrent asset uploads |
| retryAttempts | number | 3 | Retry attempts for failed API calls |
| timeoutMs | number | 30000 | Timeout for API calls in milliseconds |
| dryRun | boolean | false | Log payloads without sending to API |
Features
Mobile Metadata
Automatically captured from Appium capabilities:
platformName,deviceName,platformVersionautomationName(XCUITest / UiAutomator2)udid,bundleId,appPackage,appActivity- Appium version and session ID
Screenshot Capture
Screenshots are automatically captured and uploaded when you call:
await browser.saveScreenshot('./screenshots/my-screen.png');The reporter intercepts the saveScreenshot and takeScreenshot commands and uploads the images as test attachments.
Screen Recording
Screen recordings are captured when you use Appium's recording API:
await driver.startRecordingScreen({ videoType: 'mp4', videoQuality: 'low' });
// ... run your test steps ...
const video = await driver.stopRecordingScreen();The reporter intercepts stopRecordingScreen and uploads the MP4 as a test attachment.
Stable Test IDs
Assign stable IDs in test titles for consistent tracking across runs:
it('should login with valid credentials @id:TC-M-001 @priority:critical', async () => {
// ...
});Supported tags: @id:, @priority:, @owner:, @feature:
CI/CD Integration
Automatically detects and captures context from:
- GitHub Actions, GitLab CI, Jenkins, CircleCI, Travis CI, Buildkite, Azure Pipelines
Git information (branch, commit, author) is extracted from CI environment variables and the local git repository.
Example wdio.conf.ts
import { existsSync, mkdirSync } from 'node:fs';
import type { Options } from '@wdio/types';
export const config: Options.Testrunner = {
runner: 'local',
specs: [['./test/specs/**/*.ts']], // grouped = one Appium session
maxInstances: 1,
capabilities: [{
platformName: 'iOS',
'appium:deviceName': 'iPhone 15 Pro',
'appium:platformVersion': '17.2',
'appium:automationName': 'XCUITest',
'appium:app': '/path/to/MyApp.app',
'appium:bundleId': 'com.example.myapp',
'appium:newCommandTimeout': 240,
}],
services: [
['appium', {
command: 'appium',
args: { relaxedSecurity: true, log: './logs/appium.log' },
}],
],
framework: 'mocha',
reporters: [
'spec',
['@supatest/wdio-appium-reporter', {
projectId: process.env.SUPATEST_PROJECT_ID,
apiKey: process.env.SUPATEST_API_KEY,
apiUrl: process.env.SUPATEST_API_URL,
uploadAssets: true,
screenshotDir: './screenshots',
dryRun: process.env.SUPATEST_DRY_RUN === 'true',
}],
],
mochaOpts: { ui: 'bdd', timeout: 180000 },
onPrepare() {
if (!existsSync('./screenshots')) mkdirSync('./screenshots', { recursive: true });
if (!existsSync('./logs')) mkdirSync('./logs', { recursive: true });
},
};Development
Running Tests
pnpm test:run # Unit tests (Vitest)
pnpm test:coverage # Unit tests with coverageIntegration Tests
pnpm test:integration # Build + run full E2E against a real device/emulatorRequires:
- A running iOS Simulator or Android emulator
- The target app installed
- Local API running on
http://localhost:9090
Dry-Run Verification
To verify the reporter data flow without a real device:
npx tsx scripts/dry-run-verify.tsThis exercises the full reporter lifecycle with synthetic Android and iOS data — no device or API key required.
Test Suite Configuration
# reporter-test-suites/appium-saucedemo/.env
SUPATEST_API_URL=http://localhost:9090
SUPATEST_API_KEY=sk_test_...
SUPATEST_PROJECT_ID=proj_local_appium
SUPATEST_DRY_RUN=false
# Platform (ios | android)
PLATFORM=ios
IOS_UDID=<simulator-udid>
IOS_APP_PATH=/path/to/MyApp.appLicense
ISC
