Jump to content

Connect Leeroopedia MCP: Equip your AI agents to search best practices, build plans, verify code, diagnose failures, and look up hyperparameter defaults.

Implementation:Webdriverio Webdriverio Cloud Service Hooks

From Leeroopedia

Template:Metadata

Overview

Concrete tool for managing cloud testing session metadata through WDIO service lifecycle hooks.

Description

The BrowserstackService, SauceService, and TestingBotService classes implement WDIO's Services.ServiceInstance interface to synchronize test execution with cloud platforms. They intercept lifecycle events and update cloud APIs with test names, results, and metadata.

Each service class follows the same fundamental pattern:

  1. Accept configuration options, capabilities, and config in the constructor
  2. Store a reference to the browser instance in the before hook
  3. Update the cloud session name in beforeTest
  4. Record pass/fail results in afterTest
  5. Set the final session status in after
  6. Handle session refresh in onReload

BrowserstackService (857 lines) is the most feature-rich, incorporating observability, accessibility testing, Percy visual testing, performance measurement, and crash reporting. It manages a complex state machine tracking test outcomes, scenario names, and failure reasons.

SauceService (505 lines) integrates with the Sauce Labs REST API and supports both the Virtual Cloud and Real Device Cloud (RDC). It includes CI metadata detection, test run batching, and asset management for screenshots and logs.

TestingBotService (279 lines) is the most lightweight, focusing on core session status updates and name synchronization.

Source Files

Service File Lines
BrowserstackService packages/wdio-browserstack-service/src/service.ts L44-857
SauceService packages/wdio-sauce-service/src/service.ts L24-505
TestingBotService packages/wdio-testingbot-service/src/service.ts L9-279

Code Reference

Class Signatures

// packages/wdio-browserstack-service/src/service.ts:L44
export default class BrowserstackService implements Services.ServiceInstance {
    private _sessionBaseUrl = 'https://api.browserstack.com/automate/sessions'
    private _failReasons: string[] = []
    private _scenariosThatRan: string[] = []
    private _failures: number = 0
    private _browser?: WebdriverIO.Browser
    private _suiteTitle?: string
    private _options: BrowserstackConfig & BrowserstackOptions

    constructor(
        options: BrowserstackConfig & Options.Testrunner,
        private _caps: Capabilities.ResolvedTestrunnerCapabilities,
        private _config: Options.Testrunner
    )
}
// packages/wdio-sauce-service/src/service.ts:L24
export default class SauceService implements Services.ServiceInstance {
    private _testCnt = 0
    private _failures = 0
    private _isServiceEnabled = true
    private _options: SauceServiceConfig
    private _api: SauceLabs.default
    private _browser?: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser

    constructor(
        options: SauceServiceConfig,
        private _capabilities: Capabilities.ResolvedTestrunnerCapabilities,
        private _config: Options.Testrunner
    )
}
// packages/wdio-testingbot-service/src/service.ts:L9
export default class TestingBotService implements Services.ServiceInstance {
    private _browser?: WebdriverIO.Browser | WebdriverIO.MultiRemoteBrowser
    private _isServiceEnabled?: boolean
    private _suiteTitle?: string
    private _failures = 0
    private _testCnt = 0

    constructor(
        private _options: TestingbotOptions,
        private _capabilities: Capabilities.ResolvedTestrunnerCapabilities,
        private _config: Options.Testrunner
    )
}

Key Hooks Implemented

All three services implement a common set of lifecycle hooks:

Hook Signature Purpose
beforeSession beforeSession(config, capabilities) Configure session metadata before WebDriver session creation
before before(caps, specs, browser) Store browser reference, initialize session tracking
beforeSuite beforeSuite(suite) Track current suite title for session naming
beforeTest beforeTest(test) Update cloud session name with current test title
afterTest afterTest(test, context, results) Record test pass/fail, capture error messages
after after(result) Set final session status (passed/failed) via REST API
onReload onReload(oldSessionId, newSessionId) Transfer metadata and update status on session refresh

I/O Contract

Inputs:

  • Test lifecycle events emitted by the WDIO test runner
  • Session IDs from the WebDriver session
  • Test results including pass/fail status, error messages, and duration
  • Configuration options (user credentials, build name, project name)

Outputs:

  • Cloud session status updated via REST API (PUT /sessions/{id})
  • Session name and annotations set on the cloud dashboard
  • Build and project grouping metadata applied
  • Videos and screenshots captured and correlated with test results

Error Handling:

  • Services check for valid credentials before making API calls (_isServiceEnabled)
  • API call failures are logged but do not fail the test
  • Missing session IDs (e.g., multiremote without proper setup) are handled gracefully

Configuration

// BrowserStack
services: ['browserstack']

// Sauce Labs
services: ['sauce']

// TestingBot with options
services: [['testingbot', {
    tbTunnel: false,
    tbSecret: 'your-secret',
    tbUser: 'your-user'
}]]

Services are configured via the services array in wdio.conf.ts and auto-loaded by the WDIO test runner through the plugin resolution mechanism.

Usage Examples

Automatic session naming in BrowserStack:

// No code changes needed -- the service automatically names sessions
// In wdio.conf.ts:
export const config = {
    services: ['browserstack'],
    capabilities: [{
        'bstack:options': {
            buildName: 'nightly-2024-01-15',
            projectName: 'e-commerce-app'
        }
    }]
}
// Tests will appear in BrowserStack with names like:
// "Login Suite - should authenticate valid user"

Sauce Labs with custom job data:

// wdio.conf.ts
export const config = {
    services: [['sauce', {
        setJobName: true,
        maxErrorStackLength: 10
    }]],
    capabilities: [{
        'sauce:options': {
            build: `build-${Date.now()}`,
            tags: ['smoke', 'regression'],
            name: 'default-job-name'
        }
    }]
}

Related Pages

Page Connections

Double-click a node to navigate. Hold to expand connections.
Principle
Implementation
Heuristic
Environment