Skip to main content

Serenity/JS for Electron Users

Building an Electron app? Serenity/JS lets you test it using the same Screenplay Pattern APIs you'd use for web testing — Click, Enter, Ensure, and more.

Under the hood, Serenity/JS leverages Playwright's Electron support to connect to your app's renderer process. You get expressive tests, reusable interactions, and rich reporting — for desktop applications.


Why add Serenity/JS?

Serenity/JS works on top of Playwright Test — your existing test infrastructure stays the same. You don't need Electron-specific testing APIs.

Here's how Serenity/JS helps you test Electron apps effectively:

ChallengeHow Serenity/JS helps
No standard testing approach for ElectronSerenity/JS provides a consistent API that works for both web and desktop apps
Tests coupled to implementation detailsThe Screenplay Pattern gives you composable Tasks that separate what from how
Hard to tell what a test didStructured reports show every interaction with timing and screenshots
Test code can't be reused across web and desktopSame interactions work for browser testing and Electron — share Tasks across projects
App lifecycle management is complexSerenity/JS handles launching and closing your app automatically

Get started in 5 minutes

The progression most teams go through looks like this:

  1. Set up Playwright Test with Serenity/JS (Steps 0–2) — configure the test runner and reporters.
  2. Write your first Electron test (Step 3) — use extraAbilities to launch your app and interact with it.
  3. Extract Lean Page Objects — organise page elements for maintainability.
  4. Share code with web tests — reuse the same Tasks across Electron and browser-based tests.

Step 0: Create a Playwright Test project

Already have a Playwright Test project?

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

Create a new directory and scaffold a Playwright Test project inside it:

mkdir my-serenity-project
cd my-serenity-project
npm init --yes playwright@latest -- --quiet

This creates a TypeScript Playwright Test project with tests in the tests/ directory, a playwright.config.ts config file, and example tests.

Want to customise the setup?

Drop the --quiet flag to get interactive prompts where you can choose your preferred language, test directory, and browsers:

npm init playwright@latest

Step 1: Install

Prerequisites

To use Serenity/JS, you'll need:

  • A recent Node.js LTS version (Serenity/JS supports Node 20, 22, and 24)
  • Java 11+ for the Serenity BDD reports
  • An existing Electron app to test (with electron as a dependency)

From your Electron project directory, install Serenity/JS and Playwright Test:

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

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

Step 2: Configure

Update your playwright.config.ts to add the Serenity/JS reporter. You need to make three changes:

  1. Add the SerenityFixtures and SerenityWorkerFixtures import
  2. Add type parameters to defineConfig
  3. Replace the reporter option with the Serenity/JS reporter configuration
Reading the diffs

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

playwright.config.ts
- import { defineConfig, devices } from '@playwright/test';
+ import { defineConfig, devices } from '@playwright/test';
+ import { SerenityFixtures, SerenityWorkerFixtures } from '@serenity-js/playwright-test';

- export default defineConfig({
+ export default defineConfig<SerenityFixtures, SerenityWorkerFixtures>({
testDir: './spec',
// ... keep your existing settings ...
- reporter: 'html',
+ reporter: [
+ [ 'line' ],
+ [ '@serenity-js/playwright-test', {
+ crew: [
+ '@serenity-js/console-reporter',
+ [ '@serenity-js/serenity-bdd', {
+ specDirectory: './spec'
+ } ],
+ [ '@serenity-js/core:ArtifactArchiver', {
+ outputDirectory: './reports/serenity'
+ } ],
+ ]
+ }]
+ ],

Add the following scripts to your package.json:

package.json
 {
"scripts": {
+ "clean": "rimraf target",
+ "test": "failsafe clean test:execute [...] test:report",
+ "test:execute": "npx playwright test",
+ "test:report": "serenity-bdd run --features='./spec' --source='./reports/serenity' --destination='./reports/serenity'"
}
}

→ Learn more: Configuration options | Serenity BDD reporter setup | Using npm-failsafe

Step 3: Write your first Electron test

Use extraAbilities to tell Serenity/JS how to launch your Electron app. Each test gets a fresh instance:

spec/my-electron-app.spec.ts
import { Ensure, equals } from '@serenity-js/assertions'
import { BrowseTheWebWithPlaywright } from '@serenity-js/playwright'
import { describe, it, test } from '@serenity-js/playwright-test'
import { Text, PageElement, By } from '@serenity-js/web'
import path from 'path'

const electronAppPath = path.resolve(__dirname, '..')

describe('My Electron App', () => {

test.use({
extraAbilities: [
BrowseTheWebWithPlaywright.launchingElectronApp({
args: [ path.join(electronAppPath, 'lib', 'main.js') ],
cwd: electronAppPath,
})
],
})

it('displays the welcome screen', async ({ actor }) => {
await actor.attemptsTo(
Ensure.that(
Text.of(PageElement.located(By.css('h1'))),
equals('Welcome'),
),
)
})
})

Step 4: Run

npm test

Your Electron app launches, the test runs, and you get a Serenity BDD report in reports/serenity/. Open reports/serenity/index.html in your browser to view it.

Running a single test

The [...] wildcard in the test script is provided by npm-failsafe and passes any arguments you provide directly to Playwright Test. For example:

npm test -- --grep="welcome screen"

→ Learn more: Reporting overview | Serenity BDD reports


Organising page elements

For maintainable Electron tests, extract your page elements into Lean Page Objects:

spec/screenplay/MyApp.ts
import { PageElement, By } from '@serenity-js/web'

export const MyApp = {
title: PageElement.located(By.css('h1')).describedAs('the app title'),
textInput: PageElement.located(By.id('text-input')).describedAs('the text input'),
submitButton: PageElement.located(By.id('submit-button')).describedAs('the submit button'),
result: PageElement.located(By.id('result')).describedAs('the result message'),
}

Then use them in your tests:

spec/my-app.spec.ts
import { Ensure, includes } from '@serenity-js/assertions'
import { describe, it } from '@serenity-js/playwright-test'
import { Click, Enter, Text } from '@serenity-js/web'

import { MyApp } from './screenplay/MyApp'

describe('My Electron App', () => {

it('allows the user to submit a form', async ({ actor }) => {
await actor.attemptsTo(
Enter.theValue('Alice').into(MyApp.textInput),
Click.on(MyApp.submitButton),
Ensure.that(Text.of(MyApp.result), includes('Hello, Alice!')),
)
})
})

Worker-scoped apps for faster suites

If launching the app per test is too slow, share a single instance across all tests in a worker using extraWorkerAbilities:

test.use({
extraWorkerAbilities: [
async ({}, use) => {
await use((actorName: string) => [
BrowseTheWebWithPlaywright.launchingElectronApp({
args: [ path.join(electronAppPath, 'lib', 'main.js') ],
cwd: electronAppPath,
})
])
}, { scope: 'worker' }],
})

The app persists for the lifetime of the worker — useful for testing multi-step workflows where state carries over between tests.

→ Learn more: Testing Electron apps — full guide


FAQ

Does it work with any Electron app?

Yes. Serenity/JS connects to the renderer process via Playwright, so any Electron app with a web-based UI can be tested.

Can I share test code between my Electron app and web app?

Yes. Since Serenity/JS interactions (Click, Enter, Text, etc.) work identically for both browser and Electron testing, your Tasks and Lean Page Objects are reusable across both.

Do I need to install browsers?

No. Electron apps use their own Chromium instance. You don't need to install separate browsers for Electron testing.

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 or Playwright's built-in HTML report.

Something not working?

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


Next steps

Testing web apps instead?

If you're testing a browser-based application, see Serenity/JS for Playwright Users for a simpler setup that doesn't require Electron configuration.