Skip to main content

Web Browsers

WebdriverIO automates desktop browsers (Chrome, Chromium, Firefox, Microsoft Edge and Safari) through standard browser drivers. By default it tries to open a WebDriver BiDi session, the bi-directional successor of the classic WebDriver protocol. BiDi powers features such as network mocking and Web API emulation. Set wdio:enforceWebDriverClassic: true in your capabilities to opt out. You don't need to install drivers yourself: set a browserName and WebdriverIO downloads and starts the matching Chromedriver, Geckodriver or Edgedriver. It also installs Chrome, Chromium or Firefox when no local installation is found. Microsoft Edge must already be installed, and Safaridriver ships with macOS. The same testrunner can also run tests inside the browser with the Browser Runner. This covers unit and component tests for React, Vue, Svelte, SolidJS, Preact, Lit and Stencil.

Quick start

Scaffold a project interactively with npm init wdio@latest .. Passing --yes picks the defaults: Mocha, Chrome and page objects. To set a project up by hand, install the testrunner, a framework adapter, a reporter and tsx for TypeScript:

npm install --save-dev @wdio/cli @wdio/local-runner @wdio/mocha-framework @wdio/spec-reporter tsx
tsconfig.json
{
"compilerOptions": {
"types": ["node", "@wdio/globals/types", "@wdio/mocha-framework"]
}
}
wdio.conf.ts
export const config: WebdriverIO.Config = {
runner: 'local',
specs: ['./test/specs/**/*.ts'],
maxInstances: 10,
capabilities: [{
browserName: 'chrome'
}, {
browserName: 'firefox'
}],
logLevel: 'info',
waitforTimeout: 10000,
framework: 'mocha',
reporters: ['spec'],
mochaOpts: {
ui: 'bdd',
timeout: 60000
}
}
test/specs/login.e2e.ts
import { expect, browser, $ } from '@wdio/globals'

describe('My Login application', () => {
it('should login with valid credentials', async () => {
await browser.url('https://the-internet.herokuapp.com/login')

await $('#username').setValue('tomsmith')
await $('#password').setValue('SuperSecretPassword!')
await $('button[type="submit"]').click()

await expect($('#flash')).toBeExisting()
await expect($('#flash')).toHaveText(
expect.stringContaining('You logged into a secure area!'))
})
})
npx wdio run ./wdio.conf.ts

Each capability gets its own worker processes, so this runs the spec in both Chrome and Firefox. Other valid browserName values are chromium, msedge and safari. To run headless, add browser arguments such as 'goog:chromeOptions': { args: ['headless', 'disable-gpu'] }. See Run Browser Headless for Firefox and Edge; Safari has no headless mode.

Choose your path

End-to-end testing across browsers:

  • Capabilities: browser options, headless mode, browser channels (Canary, Nightly, Safari Technology Preview) and wdio:* driver options.
  • Driver Binaries: how automatic browser and driver setup works, and how to point at custom binaries.
  • Automation Protocols: WebDriver vs. WebDriver BiDi.
  • WebDriver BiDi commands: raw BiDi protocol commands available on the browser object.
  • Selectors: CSS, text, ARIA, deep (shadow DOM) and React selectors.
  • Auto-waiting and Timeouts: how WebdriverIO waits for elements and what to tune.
  • Multiremote: control several browsers in one test, e.g. for chat or WebRTC apps.

Browser capabilities that need WebDriver BiDi (Chrome, Edge and Firefox; not Safari):

  • Request Mocks and Spies: intercept, modify or stub network requests with browser.mock(). See also the Mock object.
  • Emulation: emulate geolocation, color scheme, user agent, navigator.onLine, the clock and device viewports with browser.emulate().

Component and unit testing in a real browser:

Visual and accessibility testing:

  • Visual Testing: screen, element and full-page image comparison with @wdio/visual-service.
  • Snapshot: DOM and object snapshot assertions.
  • Axe Core: run Deque axe accessibility scans from your tests.

Scaling out:

A component test uses the same config file with a different runner. For example, to use the React preset:

wdio.conf.ts
export const config: WebdriverIO.Config = {
runner: ['browser', {
preset: 'react'
}],
specs: ['./src/**/*.test.tsx'],
capabilities: [{
browserName: 'chrome'
}],
framework: 'mocha',
reporters: ['spec']
}

The Browser Runner requires @wdio/browser-runner. The React preset also needs @vitejs/plugin-react, and the guides recommend @testing-library/react for rendering. Presets exist for vue, svelte, solid, react, preact and stencil. For anything else, use viteConfig instead.

Troubleshooting

  • Chrome fails to start in CI with "user data directory is already in use" or "DevToolsActivePort file doesn't exist": see Headless & Xvfb.
  • browser.mock() or browser.emulate() has no effect: the session is not using WebDriver BiDi. Check your browser (Safari has no BiDi support), your cloud vendor, and wdio:enforceWebDriverClassic.
  • Drivers or browsers can't be downloaded behind a proxy: see Custom Driver Download Host and Proxy Setup.
  • Flaky tests: see Retry Flaky Tests and Debugging.

Next steps

Welcome! How can I help?

WebdriverIO AI Copilot