Implementation:Webdriverio Webdriverio AiHandler Class
| Knowledge Sources | |
|---|---|
| Domains | BrowserStack, AI_Testing |
| Last Updated | 2026-02-12 00:00 GMT |
Overview
The AiHandler class implements BrowserStack's AI self-healing feature for element location failures, providing automatic alternative locator discovery when findElement commands fail.
Description
The AiHandler class integrates with the @browserstack/ai-sdk-node package to provide AI-powered self-healing capabilities. During setup (setup), it authenticates the user with the TCG (Test Case Generation) service, stores auth results in environment variables, and updates capabilities with healing extensions. When a findElement command fails (handleHealing), the handler executes a healing script in the browser, polls the TCG service for an alternative selector, and retries the element lookup. It supports both single browser and multiremote configurations, and handles Firefox extension installation separately. The module exports a singleton instance.
Usage
Use this handler when selfHeal: true is configured in BrowserStack service options. It is initialized by BrowserstackLauncherService.onPrepare for capability setup and by BrowserstackService.before for per-session self-healing activation.
Code Reference
Source Location
- Repository: Webdriverio_Webdriverio
- File: packages/wdio-browserstack-service/src/ai-handler.ts
- Lines: 18-237
Signature
class AiHandler {
authResult: BrowserstackHealing.InitSuccessResponse | BrowserstackHealing.InitErrorResponse
wdioBstackVersion: string
constructor()
async authenticateUser(user: string, key: string): Promise<BrowserstackHealing.InitSuccessResponse | BrowserstackHealing.InitErrorResponse>
updateCaps(authResult, options: BrowserstackOptions, caps): Capabilities.ResolvedTestrunnerCapabilities
async setToken(sessionId: string, sessionToken: string): Promise<void>
async installFirefoxExtension(browser: WebdriverIO.Browser): Promise<void>
async handleHealing(originalFunc, using: string, value: string, browser: WebdriverIO.Browser, options: BrowserstackOptions): Promise<unknown>
async setup(config, browserStackConfig, options, caps, isMultiremote: boolean): Promise<WebdriverIO.Capabilities>
async handleSelfHeal(options: BrowserstackOptions, browser: WebdriverIO.Browser): Promise<void>
async selfHeal(options: BrowserstackOptions, caps, browser: WebdriverIO.Browser): Promise<void>
}
// Exported as singleton
export default new AiHandler()
Import
import AiHandler from './ai-handler.js'
I/O Contract
Inputs
| Name | Type | Required | Description |
|---|---|---|---|
| user | string |
Yes | BrowserStack username for TCG authentication |
| key | string |
Yes | BrowserStack access key for TCG authentication |
| options | BrowserstackOptions |
Yes | Service options; selfHeal: true enables healing
|
| caps | WebdriverIO.Capabilities |
Yes | Capabilities to be updated with healing extensions |
| browser | WebdriverIO.Browser |
Yes | Browser instance for overwriting findElement command |
| using | string |
Yes | Locator strategy (e.g., 'css selector', 'xpath') |
| value | string |
Yes | Locator value for the element being searched |
Outputs
| Name | Type | Description |
|---|---|---|
| Updated capabilities | WebdriverIO.Capabilities |
Capabilities with healing extension configuration added |
| Healed element result | unknown |
The element found using the original or healed locator |
| process.env.BSTACK_TCG_AUTH_RESULT | string |
JSON-serialized auth result for cross-process access |
Usage Examples
Setup in launcher for non-BrowserStack sessions
// In BrowserstackLauncherService.onPrepare
if (!shouldAddServiceVersion(this._config, this._options.testObservability)) {
capabilities = await AiHandler.setup(
this._config,
this.browserStackConfig,
this._options,
capabilities as WebdriverIO.Capabilities,
false // isMultiremote
)
}
Activating self-healing per session
// In BrowserstackService.before
if (!isBrowserstackSession(this._browser)) {
await AiHandler.selfHeal(this._options, caps, this._browser)
}