Skip to main content

Serenity/JS for WebdriverIO Users

Already using WebdriverIO? Serenity/JS plugs right into your existing setup — Mocha, Cucumber, or Jasmine, your choice.

You keep WebdriverIO's cross-browser support, WebDriver protocol compliance, and mobile testing capabilities. Serenity/JS brings the structure and reporting that matter once your test suite outgrows a handful of specs.


Why add Serenity/JS?

Serenity/JS works on top of WebdriverIO — your existing test code, browser configuration, parallel execution, and CI/CD pipeline all stay exactly as they are. You don't need to rewrite anything.

Here's how Serenity/JS helps you address common WebdriverIO challenges:

ChallengeHow Serenity/JS helps
Duplicated selectors and test logicThe Screenplay Pattern gives you composable, reusable Tasks that separate what from how
Reports show only pass/failStructured reports show every action, with timing and screenshots
Stakeholders can't read test reportsSerenity BDD reports generate living documentation for both technical and business audiences
Logic duplicated across API and UI testsScreenplay Tasks work across interfaces
Slow UI-only test suitesBlended testing — use APIs for setup, UI only where it matters
Locked into one toolScreenplay Tasks are portable — switch to Playwright without rewriting test logic

Get started in 5 minutes

You don't have to adopt everything at once. The progression most teams go through looks like this:

  1. Add reporting (Steps 1–3) — configure the framework adapter and reporters. Existing tests get better reports immediately.
  2. Use Screenplay for new tests (Step 4) — use the actor model for new scenarios. Old tests stay untouched.
  3. Extract shared Tasks — refactor common workflows into reusable building blocks.
  4. Consider portability — if you ever need Playwright (or both), your Tasks move with you.

Step 0: Create a WebdriverIO project

Already have a WebdriverIO project?

Skip this step and proceed with the remaining steps from your project directory.

Create a new directory and run the WebdriverIO wizard:

mkdir my-serenity-project
cd my-serenity-project
npm init wdio@latest .

When prompted, select the following options to get a project with Serenity/JS pre-configured:

  • Type of testing: E2E Testing
  • Automation backend: local
  • Environment: web
  • Browser: Chrome
  • Framework: Mocha with Serenity/JS (or Cucumber/Jasmine with Serenity/JS)
  • Compiler: TypeScript
  • Generate test files: yes
  • Test file location: accept the defaults
  • Test reporter: any (Serenity/JS configures its own reporting)
  • Plugins/add-ons/services: none

This creates a fully configured Serenity/JS + WebdriverIO project with example tests, reporters, and a wdio.conf.ts ready to go.

Serenity/JS already configured?

If you selected a "with Serenity/JS" framework option in the wizard, Steps 1 and 2 are already done — skip straight to Step 3: Run.

Step 1: Install

Prerequisites

You'll need a recent Node.js LTS version (Serenity/JS supports Node 20, 22, and 24), as well as Java 11+ for the Serenity BDD reports.

npm install --save-dev @serenity-js/core @serenity-js/webdriverio @serenity-js/web @serenity-js/assertions @serenity-js/console-reporter @serenity-js/serenity-bdd @serenity-js/mocha rimraf npm-failsafe

→ Learn more: Full WebdriverIO installation guide | Why Serenity/JS?

Step 2: Configure

Update your wdio.conf.ts to use the Serenity/JS framework adapter. You need to make two changes:

  1. Set framework to '@serenity-js/webdriverio'
  2. Add the serenity configuration block with your test runner and reporters
Reading the diffs

Lines marked with + should be added to your file; lines marked with - should be removed. Don't copy the +/- prefixes themselves.

wdio.conf.ts
+ import { WebdriverIOConfig } from '@serenity-js/webdriverio';

- export const config = {
+ export const config: WebdriverIOConfig = {
+ framework: '@serenity-js/webdriverio',
+ serenity: {
+ runner: 'mocha',
+ crew: [
+ '@serenity-js/console-reporter',
+ [ '@serenity-js/serenity-bdd', { specDirectory: './test/specs' } ],
+ [ '@serenity-js/core:ArtifactArchiver', {
+ outputDirectory: './target/site/serenity'
+ } ],
+ ],
+ },
// ... keep your existing settings ...
- framework: 'mocha',

Next, add the following scripts to your package.json:

package.json
 {
"scripts": {
+ "serenity": "failsafe serenity:clean wdio [...] serenity:report",
+ "serenity:clean": "rimraf target",
+ "wdio": "wdio run ./wdio.conf.ts",
+ "serenity:report": "serenity-bdd run --features='./test/specs'"
}
}

→ Learn more: WebdriverIO configuration | Serenity BDD reporter setup | Using npm-failsafe

Step 3: Run

npm run serenity

That's it. Your existing tests run as before, but now produce a rich HTML report in target/site/serenity/. Open target/site/serenity/index.html in your browser to view it.

Running a single test

The [...] wildcard in the serenity script is provided by npm-failsafe and passes any arguments you provide directly to WebdriverIO. For example, to run a single spec file:

npm run serenity -- --spec=test/specs/website.spec.ts

→ Learn more: Reporting overview | Serenity BDD reports

Example Serenity BDD report generated by Serenity/JS (source)

Step 4 (optional): Write your first Screenplay test

Steps 1–3 give you better reporting with zero changes to your test logic. When you're ready to see what the Screenplay Pattern looks like in practice, add a new test file:

test/specs/website.spec.ts
import { describe, it } from 'mocha';
import { actorCalled } from '@serenity-js/core';
import { Ensure, includes } from '@serenity-js/assertions';
import { Navigate, Page } from '@serenity-js/web';

describe('Website', () => {

it('should have a descriptive title', async () => {
await actorCalled('Serena').attemptsTo(
Navigate.to('https://serenity-js.org/'),
Ensure.that(
Page.current().title().describedAs('current page title'),
includes('Serenity/JS')
),
);
});
});

Run npm run serenity again. In the Serenity BDD report you'll now see each interaction (Navigate.to, Ensure.that) listed as a separate step with timing — giving you a clear activity breakdown without any extra configuration.

This test uses actorCalled and Screenplay interactions instead of WebdriverIO's browser object directly. The key differences:

  • actorCalled('Serena') creates a named actor — the actor has a browser, but can also interact with REST APIs, multiple browser contexts, etc.
  • Navigate.to() and Ensure.that() are composable interactions that show up as named steps in your reports.
  • Screenplay Tasks are portable — the same test code works with WebdriverIO and Playwright, only the config differs.

→ Learn more: Screenplay Pattern | Your first web scenario

For a more advanced example showing composable Tasks, the Lean Page Objects pattern, and masked credentials, see the Complete example below.

Same Tasks, different tool

Screenplay code is identical whether you use Playwright or WebdriverIO — only the config differs. See Serenity/JS with Playwright.


Reference projects

Complete example

A self-contained project you can copy in full. It includes:

  • test/specs/website.spec.ts — a simple Screenplay test using Navigate and Ensure (same pattern as Step 4)
  • test/specs/swag-labs.spec.ts — a more advanced test interacting with the Swag Labs demo website, using composable Task definitions and the Lean Page Objects pattern

Run npm install then npm run serenity — the Serenity BDD HTML report lands in target/site/serenity/index.html.

Credentials in examples

The password secret_sauce is hard-coded in these examples to keep them simple and self-contained. In real-world tests, load credentials from environment variables or a password vault to avoid committing secrets to your repository.

package.json
{
"name": "my-serenity-js-webdriverio-project",
"version": "1.0.0",
"scripts": {
"serenity": "failsafe serenity:clean wdio [...] serenity:report",
"serenity:clean": "rimraf target",
"wdio": "wdio run ./wdio.conf.ts",
"serenity:report": "serenity-bdd run --features='./test/specs'"
},
"devDependencies": {
"@serenity-js/assertions": "^3.43.2",
"@serenity-js/console-reporter": "^3.43.2",
"@serenity-js/core": "^3.43.2",
"@serenity-js/mocha": "^3.43.2",
"@serenity-js/serenity-bdd": "^3.43.2",
"@serenity-js/web": "^3.43.2",
"@serenity-js/webdriverio": "^3.43.2",
"@wdio/cli": "^9.0.0",
"@wdio/local-runner": "^9.0.0",
"npm-failsafe": "^1.4.0",
"rimraf": "^6.0.0",
"typescript": "^5.7.0",
"webdriverio": "^9.0.0"
}
}

Project templates

If you'd rather start from a fully configured project than add Serenity/JS to an existing one, use one of these GitHub template repositories. Each comes with CI configuration, example tests, and live reports you can preview.

StackLive Report
Cucumber + WebdriverIOSerenity BDD
Mocha + WebdriverIOSerenity BDD
Jasmine + WebdriverIOSerenity BDD

All project templates


FAQ

Does it slow down my tests?

No. Serenity/JS adds negligible overhead. Your tests still run on WebdriverIO's engine with the same parallelism.

Do I have to rewrite all my tests?

No. You can mix Screenplay and non-Screenplay tests in the same project. Start with reporting and introduce Screenplay gradually for new tests.

Can I switch to Playwright later?

Yes. Screenplay Tasks import from @serenity-js/web and @serenity-js/core — not from WebdriverIO directly. If you ever want to move to Playwright (or use both), your Tasks are portable. Only the configuration changes.

Do I need Java?

Yes, for the Serenity BDD HTML reports (Java 11+). If you'd rather stay Java-free, use the console reporter alone.

Something not working?

Check the Troubleshooting guide for solutions to common issues with reports, screenshots, and configuration.


Next steps

Using Playwright instead?

Serenity/JS works just as well with Playwright Test. See Serenity/JS with Playwright.