A WebdriverIO plugin to report in spec style
—
Advanced integration features for Sauce Labs test execution including job link generation and authentication.
Generate Sauce Labs job URLs with optional sharable authentication tokens.
/**
* Generate Sauce Labs job URLs for test sessions
* Creates links to view test results in Sauce Labs dashboard
* @param options - Test link configuration with capabilities and session info
* @returns Array of formatted job link strings (empty if not applicable)
*/
getTestLink(options: TestLink): string[];
interface TestLink {
/** Browser capabilities and configuration */
capabilities: Capabilities.ResolvedTestrunnerCapabilities;
/** WebDriver session ID */
sessionId: string;
/** Whether using multiremote setup */
isMultiremote: boolean;
/** Name of multiremote instance (optional) */
instanceName?: string;
}Usage Examples:
import SpecReporter from "@wdio/spec-reporter";
const reporter = new SpecReporter({
sauceLabsSharableLinks: true
});
// Single browser test link
const link = reporter.getTestLink({
capabilities: {
browserName: 'chrome',
browserVersion: '91',
platformName: 'Windows 10'
},
sessionId: 'abc123def456',
isMultiremote: false
});
// Returns: ["Check out job at https://app.saucelabs.com/tests/abc123def456?auth=token123"]
// Multiremote test links
const multiLinks = reporter.getTestLink({
capabilities: {
browserA: { browserName: 'chrome' },
browserB: { browserName: 'firefox' }
},
sessionId: 'def456ghi789',
isMultiremote: true,
instanceName: 'browserA'
});
// Returns: ["Check out browserA job at https://app.saucelabs.com/tests/def456ghi789?auth=token456"]
// Real Device Cloud (RDC) link from capabilities
const rdcLink = reporter.getTestLink({
capabilities: {
'appium:deviceName': 'iPhone 12',
testobject_test_report_url: 'https://app.eu-central-1.saucelabs.com/tests/xyz789'
},
sessionId: 'xyz789abc123',
isMultiremote: false
});
// Returns: ["Check out job at https://app.eu-central-1.saucelabs.com/tests/xyz789"]Control whether Sauce Labs job links include authentication tokens for public access.
interface SharableLinkOptions {
/**
* Enable/disable Sauce Labs sharable links
* When true, generates links that can be viewed by anyone
* When false, generates standard team-only links
* @default true
*/
sauceLabsSharableLinks: boolean;
}Usage Examples:
// Enable sharable links (default)
const reporter = new SpecReporter({
sauceLabsSharableLinks: true
});
// Generates: https://app.saucelabs.com/tests/session123?auth=abcdef123456
// Disable sharable links (team-only access)
const teamOnlyReporter = new SpecReporter({
sauceLabsSharableLinks: false
});
// Generates: https://app.saucelabs.com/tests/session123
// WebdriverIO configuration
export const config = {
reporters: [
['spec', {
sauceLabsSharableLinks: false // Disable public sharing
}]
]
};Utility function for generating Sauce Labs authentication tokens.
/**
* Generate Sauce Labs authentication token for sharable links
* Creates HMAC-MD5 token using username, access key, and session ID
* @param user - Sauce Labs username
* @param key - Sauce Labs access key
* @param sessionId - WebDriver session ID
* @returns Authentication query parameter string
*/
function sauceAuthenticationToken(user: string, key: string, sessionId: string): string;Usage Examples:
import { sauceAuthenticationToken } from "@wdio/spec-reporter";
// Generate authentication token
const token = sauceAuthenticationToken(
'myusername',
'my-access-key-123',
'session-abc-123'
);
// Returns: "?auth=a1b2c3d4e5f6..."
// Full URL construction
const sessionId = 'abc123def456';
const baseUrl = 'https://app.saucelabs.com/tests/';
const authToken = sauceAuthenticationToken('user', 'key', sessionId);
const fullUrl = `${baseUrl}${sessionId}${authToken}`;
// Result: "https://app.saucelabs.com/tests/abc123def456?auth=a1b2c3d4e5f6..."Automatic URL generation for different Sauce Labs data centers.
interface DataCenterConfig {
/** Sauce Labs hostname indicating data center */
hostname: string;
/** Region configuration (us-east-4, eu-central-1, etc.) */
region?: string;
/** Sauce Labs username */
user: string;
/** Sauce Labs access key */
key: string;
}Usage Examples:
// US West (default)
const usWestConfig = {
hostname: 'ondemand.saucelabs.com',
user: 'myuser',
key: 'mykey'
};
// Generates: https://app.saucelabs.com/tests/...
// US East 4
const usEast4Config = {
hostname: 'ondemand.us-east-4.saucelabs.com',
user: 'myuser',
key: 'mykey'
};
// Generates: https://app.us-east-4.saucelabs.com/tests/...
// EU Central 1
const euConfig = {
hostname: 'ondemand.eu-central-1.saucelabs.com',
user: 'myuser',
key: 'mykey'
};
// Generates: https://app.eu-central-1.saucelabs.com/tests/...
// Via region property
const regionConfig = {
hostname: 'ondemand.saucelabs.com',
region: 'eu-central-1',
user: 'myuser',
key: 'mykey'
};
// Generates: https://app.eu-central-1.saucelabs.com/tests/...Special handling for Real Device Cloud (RDC) and mobile testing.
interface MobileCapabilities {
/** Direct RDC test report URL from capabilities */
testobject_test_report_url?: string;
/** Mobile device name */
'appium:deviceName'?: string;
/** Mobile platform version */
'appium:platformVersion'?: string;
/** Mobile platform name */
'appium:platformName'?: string;
}Usage Examples:
// Real Device Cloud with direct URL
const rdcCapabilities = {
'appium:deviceName': 'iPhone 12',
'appium:platformVersion': '14.5',
'appium:platformName': 'iOS',
testobject_test_report_url: 'https://app.eu-central-1.saucelabs.com/tests/mobile123'
};
const rdcLink = reporter.getTestLink({
capabilities: rdcCapabilities,
sessionId: 'mobile123',
isMultiremote: false
});
// Returns: ["Check out job at https://app.eu-central-1.saucelabs.com/tests/mobile123"]
// Virtual Device Cloud (VDC)
const vdcCapabilities = {
'appium:deviceName': 'Android GoogleAPI Emulator',
'appium:platformVersion': '11.0',
'appium:platformName': 'Android',
browserName: 'Chrome'
};
// Uses standard VDC URL construction with authentication tokensSupport for multiple browser instances in a single test session.
interface MultiremoteTestLink extends TestLink {
/** Whether this is a multiremote test setup */
isMultiremote: true;
/** Name of the specific browser instance */
instanceName: string;
/** Capabilities object containing multiple browser configs */
capabilities: {
[instanceName: string]: Capabilities.ResolvedTestrunnerCapabilities;
};
}Usage Examples:
const reporter = new SpecReporter({});
// Multiremote configuration generates separate links for each browser
const multiremoteCapabilities = {
chrome: {
browserName: 'chrome',
browserVersion: '91',
sessionId: 'chrome-session-123'
},
firefox: {
browserName: 'firefox',
browserVersion: '89',
sessionId: 'firefox-session-456'
}
};
// Link for Chrome instance
const chromeLink = reporter.getTestLink({
capabilities: multiremoteCapabilities,
sessionId: 'chrome-session-123',
isMultiremote: true,
instanceName: 'chrome'
});
// Returns: ["Check out chrome job at https://app.saucelabs.com/tests/chrome-session-123?auth=..."]
// Link for Firefox instance
const firefoxLink = reporter.getTestLink({
capabilities: multiremoteCapabilities,
sessionId: 'firefox-session-456',
isMultiremote: true,
instanceName: 'firefox'
});
// Returns: ["Check out firefox job at https://app.saucelabs.com/tests/firefox-session-456?auth=..."]Sauce Labs links are automatically included in test reports when applicable.
// Example report output with Sauce Labs links:
// ------------------------------------------------------------------
// [chrome 91 Windows 10 #0-0] Running: chrome (v91) on Windows 10
// [chrome 91 Windows 10 #0-0] Session ID: abc123def456
// [chrome 91 Windows 10 #0-0]
// [chrome 91 Windows 10 #0-0] » /tests/login.test.js
// [chrome 91 Windows 10 #0-0] Login Tests
// [chrome 91 Windows 10 #0-0] ✓ should display login form
// [chrome 91 Windows 10 #0-0] ✓ should authenticate valid user
// [chrome 91 Windows 10 #0-0]
// [chrome 91 Windows 10 #0-0] 2 passing (3.2s)
// [chrome 91 Windows 10 #0-0]
// [chrome 91 Windows 10 #0-0] Check out job at https://app.saucelabs.com/tests/abc123def456?auth=xyz789Install with Tessl CLI
npx tessl i tessl/npm-wdio--spec-reporter