Electron apps

Launch an Electron app, test its first window and choose how its data persists.

Use an Electron target to test your desktop app with browser locators, actions and checks. Retest launches the app for each test and gives it the first window as a page.

Platform coverage

Electron support was checked with Electron 44.5.1 on macOS on Apple silicon. Linux and packaged apps have not been exercised, and Windows is unsupported. Electron windows appear on screen because the target has no headless mode.

Configure the app Link to Configure the app

You need an Electron executable and your app's folder or entry file. The config below uses Electron installed in the project. To use Retest's pinned build, run this command and replace executablePath with the binary path it prints.

Terminal
npx retest install electron
retest.config.ts
import { defineConfig, electron } from '@rehearsal-labs/retest'const config = defineConfig({  apps: {    desktop: electron({      executablePath: './node_modules/electron/dist/Electron.app/Contents/MacOS/Electron',      appPath: './desktop',    }),  },})export default configdeclare module '@rehearsal-labs/retest' {  interface Register {    config: typeof config  }}

Relative paths start from retest.config.ts, and the app folder must contain its package.json. Retest sets the debugging pipe and data folder, so do not add those switches to args.

Terminal
npx retest doctor

Doctor checks that the executable and app exist without launching the app. An Electron target has no baseUrl, viewport, emulation or proxy, though it may have start for a backend server.

Test the first window Link to Test the first window

For an app whose first window contains the task form, the save test uses the same test ids as the web example. Begin with a locator because the app opens its own page during launch.

tests/desktop.retest.ts
import { expect, test } from '@rehearsal-labs/retest'test('saves a task', { apps: ['desktop'] }, async ({ desktop }) => {  await desktop.getByTestId('task-title').fill('Release checklist')  await desktop.getByTestId('save-task').click()  await expect(desktop.getByTestId('saved-task')).toHaveText('Release checklist')})

Retest launches the app afresh for the test and quits it when the test ends. goto() is unavailable because the app controls which page its window shows. Closing the first window loses the session; Retest cannot switch to another window.

Terminal
npx retest run tests/desktop.retest.ts

Choose how data persists Link to Choose how data persists

Without userDataDir, every launch gets a temporary Chromium data folder, removed after the app quits. To reuse that storage, add a folder to the target:

TypeScript
defineConfig({  apps: {    desktop: electron({      executablePath: './node_modules/electron/dist/Electron.app/Contents/MacOS/Electron',      appPath: './desktop',      userDataDir: './.retest/desktop-data',    }),  },})

Launches using that folder take turns, and the report records reused storage. Two targets cannot name the same data folder. Retest does not reset files, user defaults or backend data the app keeps elsewhere, even when its Chromium folder is fresh.

Saved browser states cannot be restored into Electron. For secrets, explicitly allow the window's http or https origin in secretOrigins; a file:// window cannot receive a secret fill. Naming an origin means trusting the Electron app with the secret.

Supported features and limits Link to Supported features and limits

The first window uses the Chromium driver. Retest was checked with test id, role, label and text locators, and with fill, click, press and check. Its checked matchers cover text, count, checked state, visibility, title and address.

Uploads, file pickers, JavaScript dialogs and drag and drop were also checked. Downloads through page.download(), native menus and dialogs, the main process, later windows, frames, popups, mocked responses and screenshot comparisons are unavailable.

Electron captures its first window only. Diagnostics are partial when that window already shows a page other than about:blank, or Retest cannot tell. An app that loads its page at launch therefore has partial capture, so requireComplete prevents its tests from passing. Capture excludes the main process and other windows.

The run folder also keeps a windows.json inventory for each launch. Use it when a failure follows a window opening or closing, alongside the steps shown by Debugging a failure.

Next steps Link to Next steps