Adding visual testing to your WebdriverIO tests


Covered in this doc

  • Integrating Percy with your WebdriverIO tests
  • Installing and importing percySnapshot()
  • Calling and configuring percySnapshot(browser, <snapshotName>, <options>)

Package Status Test


This documentation is for @percy/webdriverio v2.0.0 or above, and is not compatible with older versions. If you're already using Percy for WebdriverIO, see our docs to upgrade to our newest version.


Install @percy/webdriverio:

npm install --save-dev @percy/cli @percy/webdriverio

This is an example using the percySnapshot() function in async mode.

const percySnapshot = require('@percy/webdriverio');

describe('webdriver.io page', () => {
  it('should have the right title', async () => {
    await browser.url('https://webdriver.io');
    await expect(browser).toHaveTitle('WebdriverIO · Next-gen browser and mobile automation test framework for Node.js');
    await percySnapshot('webdriver.io page');

Running the test above will result in the following log:

$ wdio wdio.conf.js

[...] webdriver.io page
[percy] Percy is not running, disabling snapshots
[...]    ✓ should have the right title


Before you can successfully run Percy, the PERCY_TOKEN environment variable must be set:

# Windows
$ set PERCY_TOKEN=<your token here>

# PowerShell
$ $Env:PERCY_TOKEN="<your token here>"

# Unix 
$ export PERCY_TOKEN=<your token here>

When running with percy exec, and your project's PERCY_TOKEN, a new Percy build will be created and snapshots will be uploaded to your project. Your new test command becomes:

$ percy exec -- wdio wdio.conf.js
[percy] Percy has started!
[percy] Created build #1: https://percy.io/[your-project]
[percy] Running "wdio wdio.conf.js"

[...] webdriver.io page
[percy] Snapshot taken "webdriver.io page"
[...]    ✓ should have the right title

[percy] Stopping percy...
[percy] Finalized build #1: https://percy.io/[your-project]
[percy] Done!

Standalone mode

When using WebdriverIO in standalone mode, the browser object must be provided as the first argument to the percySnapshot function.

const { remote } = require('webdriverio');
const percySnapshot = require('@percy/webdriverio');

(async () => {
  const browser = await remote({
    logLevel: 'trace',
    capabilities: {
      browserName: 'chrome'

  await browser.url('https://duckduckgo.com');

  const inputElem = await browser.$('#search_form_input_homepage');
  await inputElem.setValue('WebdriverIO');

  const submitBtn = await browser.$('#search_button_homepage');
  await submitBtn.click();

  // the browser object is required in standalone mode
  percySnapshot(browser, 'WebdriverIO at DuckDuckGo');

  await browser.deleteSession();
})().catch((e) => console.error(e));


percySnapshot(name[, options])

percySnapshot(browser, name[, options]) (standalone mode only)

Global configuration

You can also configure Percy to use the same options over all snapshots. To see supported configuration including widths read our SDK configuration docs


If you're coming from a pre-2.0 version of this package, the percySnapshot function is now the default export, and the browser argument is now only required when used in standalone mode.

// before 
const { percySnapshot } = require('@percy/webdriverio');
await percySnapshot(browser, 'Snapshot name', options);

// after
const percySnapshot = require('@percy/webdriverio');
await percySnapshot('Snapshot name', options);

// in standalone mode, browser is still required
await percySnapshot(browser, 'Snapshot name', options);

Migrating Config

If you have a previous Percy configuration file, migrate it to the newest version with the config:migrate command:

$ percy config:migrate

What's next

Once you've set up Percy for WebdriverIO, the next step is to add Percy to your CI service. That way, every time CI runs, Percy will automatically kick off visual tests as well.