# Electron apps

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

Source: https://rehearsal.dev/retest/docs/platforms/electron

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.

> [!NOTE]
> **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

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.

```sh
npx retest install electron
```

```ts filename="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 config

declare 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`.

```sh
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

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.

```ts filename="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.

```sh
npx retest run tests/desktop.retest.ts
```

## 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:

```ts
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

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](https://rehearsal.dev/retest/docs/essentials/debugging.md).

## Next steps

- [Uploads and downloads](https://rehearsal.dev/retest/docs/guides/files.md): Upload files through the window's form or picker.
- [Signing in and secrets](https://rehearsal.dev/retest/docs/guides/signing-in.md): Authorise credentials for the window's origin.
- [Console and network](https://rehearsal.dev/retest/docs/guides/console-and-network.md): Read diagnostics and their capture limits.
