Testland
Browse all skills & agents

electron-spectron

Legacy reference for Spectron - Electron's original ChromeDriver-based testing framework, officially deprecated 2022-02-01 at v19.0.0. Documents what Spectron was, the architectural reason it became unmaintainable, the migration path to Playwright `_electron`, and the residual support contract for projects still on Spectron. Use only when auditing a legacy suite or planning a migration off Spectron - for new work use Playwright's `_electron` API.

Install with skills.sh (any agent)

npx skills add testland/qa --skill electron-spectron
View source

electron-spectron

Overview

Spectron was a Node.js library that drove Electron applications through ChromeDriver + the legacy WebDriverIO API. It shipped from the official electron-userland org and was - for several years - the only sanctioned end-to-end driver for Electron apps.

Per the Spectron repository (opens in new window):

"Spectron is officially deprecated as of February 1, 2022."

The final release was v19.0.0 (published 2022-02-02), pinned to Electron ^19.0.0 (spectronrepo (opens in new window)). The repository is archived read-only with 233 open issues and 31 unmerged pull requests as of the deprecation snapshot (spectronrepo (opens in new window)).

This skill is a pure reference. There are no "run these commands" steps because no new project should start on Spectron.

When to use

  • Auditing an existing Electron test suite still on Spectron.
  • Estimating migration effort from Spectron to Playwright.
  • Triaging Spectron test failures in projects that haven't migrated yet (and shouldn't migrate this sprint).
  • Writing a deprecation-debt ticket - quoting the cited deprecation notice for stakeholder context.

For new projects: stop here and read electron-playwright instead.

Why Spectron was deprecated

The Spectron repository announcement itself does not enumerate reasons (spectronrepo (opens in new window)), but the architectural context is observable from the surrounding ecosystem at the deprecation moment:

  1. ChromeDriver was the wrong substrate. Electron's main process (Node.js, native modules, IPC, packaged-app lifecycle, file dialogs) sits outside the ChromeDriver model, so Spectron bridged it with bespoke RPC that grew progressively harder to keep aligned with Electron's multi-process model.
  2. The WebDriverIO sync API was retired. Spectron's API shape depended on the WDIO sync API, dropped in WDIO 6+; migrating to the async API was a breaking change, so Spectron's surface froze.
  3. Native testing tools matured. Per Electron's automated- testing guide (opens in new window), Electron now recommends three first-class alternatives - Playwright, WebDriverIO (modern async), Selenium - each with native Electron support paths.

Per Electron's official tutorial (opens in new window), the three current recommendations are:

ToolApproach
Playwright_electron.launch() returns an ElectronApp handle; expose main-process modules via electronApp.evaluate(...)
WebdriverIO (WDIO)npm init wdio@latest ./ → wizard asks "Desktop Testing - of Electron Applications"
SeleniumWebDriver API bindings; lower-level than the above

Playwright is the de-facto replacement most projects migrate to - see electron-playwright for the implementation SKILL.

What Spectron looked like

For pattern-recognition during a migration audit, a Spectron test centres on a new Application({ path }) handle with app.start() / app.stop() fixtures and app.client.<webdriver-method> calls:

// Legacy Spectron - DO NOT use for new code
const app = new Application({ path: '/path/to/MyApp' });
before(async () => { await app.start(); });
after(async () => { if (app && app.isRunning()) await app.stop(); });
it('opens a window', async () => {
  assert.strictEqual(await app.client.getWindowCount(), 1);
});

The before/after Playwright _electron equivalent and the concept-by-concept mapping (the migration shopping list) live in references/spectron-migration.md. See electron-playwright for the full Playwright _electron authoring, running, and CI workflow.

Residual support contract

If a project must remain on Spectron in the short term:

  • Pin spectron: 19.0.0 (the final release per spectronrepo (opens in new window)) and electron: ^19.0.0. Newer Electron versions will break.
  • Pin Node.js to a version compatible with the bundled ChromeDriver - typically Node 16 for the Spectron 19 era.
  • Do not file issues upstream - the repository is archived (spectronrepo (opens in new window)). Patches must live as local forks.
  • Schedule the migration. Spectron will not get security or Electron-version updates; running CI on a deprecated ChromeDriver in production-adjacent suites is a known-quality risk.

Anti-patterns

Anti-patternWhy it failsFix
Starting a new Electron test project on Spectron in 2026Archived; no Electron 20+ supportUse electron-playwright
"Just upgrade Electron" without migrating off SpectronSpectron pinned to Electron 19; newer Electron breaks Spectron's ChromeDriver bridgeMigrate to Playwright _electron
Big-bang Spectron → Playwright migration in one PRHigh risk; no fall-back if behaviour differsFile-by-file migration with both suites green
Patching the archived Spectron repository upstreamRepository is read-only; PRs aren't being merged (spectronrepo (opens in new window))Fork; or invest the same effort into migration
Citing Spectron's deprecation as the only reason to migrateStakeholders ask "but it still works"Cite (1) Electron-version lock, (2) no security updates, (3) no support - all in the deprecation notice (spectronrepo (opens in new window))

Limitations

  • No first-party migration script. Electron / Playwright don't ship a codemod for Spectron → Playwright. Migration is hand- ported per test file.
  • API surface drift. Spectron's main-process RPC (app.electron.<…>) doesn't have a 1:1 mapping to Playwright's electronApp.evaluate() for every case - some tests need a small refactor.
  • WebDriverIO modern path is technically also a Spectron successor (electrontest (opens in new window)). For projects already on WDIO for browser tests, wdio-electron-service may be a better migration target than Playwright _electron. This SKILL documents the Playwright path because it's the most common successor; WDIO path is out of scope.

References

  • Spectron repository (archived) - spectronrepo (opens in new window).
  • Electron Automated Testing tutorial - electrontest (opens in new window).
  • Successor SKILL: electron-playwright.
  • Strategic context: desktop-test-strategy-reference describes the Electron-renderer + Electron-main two-surface architecture that made ChromeDriver-only drivers like Spectron structurally insufficient.

Spectron -> Playwright migration reference

View source (opens in new window)

Spectron -> Playwright migration reference

The before/after code and the concept-by-concept mapping, kept out of the SKILL spine. See SKILL.md (opens in new window) for the deprecation facts and the residual support contract, and electron-playwright for the full Playwright _electron authoring, running, and CI workflow.

Sources: Spectron repository (archived) (opens in new window), Electron Automated Testing tutorial (opens in new window).

Before: a Spectron test

// Legacy Spectron - DO NOT use for new code
const Application = require('spectron').Application;
const app = new Application({
  path: '/path/to/electron/MyApp.app/Contents/MacOS/MyApp',
});

before(async () => {
  await app.start();
});

after(async () => {
  if (app && app.isRunning()) {
    await app.stop();
  }
});

it('opens a window', async () => {
  const count = await app.client.getWindowCount();
  assert.strictEqual(count, 1);
});

After: the Playwright _electron equivalent

// Modern replacement (per electrontest)
const { _electron: electron } = require('playwright');

let electronApp;
beforeAll(async () => {
  electronApp = await electron.launch({ args: ['.'] });
});
afterAll(async () => {
  await electronApp.close();
});

test('opens a window', async () => {
  const windowCount = electronApp.windows().length;
  expect(windowCount).toBe(1);
});

Migration shopping list

A Spectron-to-Playwright migration touches:

Spectron conceptPlaywright _electron replacement
new Application({ path })electron.launch({ args: ['.'] }) (electrontest (opens in new window))
app.start() / app.stop()electronApp.launch() / electronApp.close()
app.client.<webdriver-method>page = await electronApp.firstWindow(); then standard page.<method> (electrontest (opens in new window))
app.browserWindow.<method> (sync RPC into main process)electronApp.evaluate(({ BrowserWindow }) => { … }) - typed handle (electrontest (opens in new window))
Window counting via app.client.getWindowCount()electronApp.windows().length
ChromeDriver binary lifecycleImplicit - Playwright bundles Chromium and exposes packaged-app launch directly

Plan migration test-file-by-test-file, not big-bang: tag each file as migrated, run both suites in CI until the Spectron set is empty, then delete spectron from package.json.

Related skills

appium-windows-driver

Authors and runs Appium 2.x tests against the Windows driver, the actively-maintained Node.js proxy in front of Microsoft's WinAppDriver: `appium driver install windows`, capabilities (`platformName: windows`, `appium:automationName: windows`, `appium:app`, `appium:appTopLevelWindow`, `appium:appArguments`), Windows gestures (`windows: scroll` / `clickAndDrag` / `keys`), PowerShell prerun/postrun hooks, and CI. Use when the stack already uses Appium for iOS / Android / Mac2 and Windows fits the existing client + capability model; to drive WinAppDriver directly from a Selenium-style client use winappdriver, and for a C#-only FlaUI client use flaui-tests.

at-spi-linux

Authors Linux desktop UI tests via AT-SPI - the DBus-based Assistive Technology Service Provider Interface implemented by `at-spi2-core` (registry daemon + `libatspi` C library + ATK GTK bridge). Covers enabling toolkit accessibility (`gsettings set org.gnome.desktop.interface toolkit-accessibility true`), driving GTK + Qt apps through Python `dogtail` (object-oriented + procedural APIs), inspecting the tree with Accerciser, scripting via `pyatspi`, and CI integration on headless Linux runners with `Xvfb` + `dbus-launch`. Use for Linux-side desktop tests of GTK applications, Qt apps with QAccessible enabled, and Electron apps on Linux.

desktop-test-strategy-reference

Pure-reference catalog of desktop GUI test strategies across Windows, macOS, and Linux. Defines the three accessibility-tree backends (Microsoft UI Automation on Windows, Apple Accessibility / XCTest on macOS, AT-SPI on Linux), the wrapper-tools that drive each backend (WinAppDriver, Appium-Windows, XCUIApplication, AT-SPI clients), the cross-toolkit Electron + Qt paths, and a per-OS decision matrix with accessibility-first locator strategy. Deep operational detail (per-OS asynchronous-wait hierarchies, parallel-test policy, foreground-lock / UAC / TCC / AT-SPI elevation hazards, and the high-DPI / per-monitor test matrix) lives in references/. Use when choosing how to test or automate a desktop GUI application (desktop app testing, GUI automation, automate desktop UI) on Windows, macOS, or Linux - the strategic reference before picking a desktop test stack, ahead of the per-tool implementation skills.

electron-playwright

Authors Playwright `_electron` tests for packaged Electron desktop apps - launches the app via `electron.launch({ args })`, returns an `ElectronApplication` handle, drives renderer windows as Playwright `Page` objects, and probes the main process via `electronApp.evaluate(({ app, BrowserWindow }) => …)`. Distinct from ordinary browser page automation: this wraps the `_electron` API for launching packaged Electron apps and probing main + renderer processes. Use for end-to-end tests of Electron apps where main-process state, IPC, and renderer DOM must all be asserted from one suite.

flaui-tests

Authors and runs FlaUI-based Windows UI tests - the .NET-native wrapper around Microsoft UI Automation (UIA2 + UIA3). Covers the `FlaUI.Core` / `FlaUI.UIA2` / `FlaUI.UIA3` NuGet packages, `Application.Launch` / `Application.Attach` lifecycles, `ConditionFactory` + `FindFirstDescendant` locator patterns, `Retry` waits, and xUnit / NUnit / MSTest harness integration. Use when the test stack is C# / .NET-first and the team wants idiomatic in-process UIA calls rather than the HTTP/JSON wire protocol of `winappdriver` or the Appium proxy layer of `appium-windows-driver`.

qt-test-framework

Authors and runs Qt Test - the first-party C++ unit + GUI test framework that ships with Qt 6 (via the `QtTest` module header). Covers the `QTEST_MAIN` / `QTEST_APPLESS_MAIN` / `QTEST_GUILESS_MAIN` entry-point macros, the `QObject` private-slot test pattern, `QVERIFY` / `QCOMPARE` / `QFETCH` assertions, GUI event simulation (`QTest::mouseClick`, `QTest::keyClick`, `QTest::touchEvent`), `QSignalSpy` for signal introspection, `QBENCHMARK` for performance regression, and the `-o file,junitxml` CI output. Use for in-process testing of Qt widgets, QObject signal/slot chains, and Qt Quick / QML application logic; for out-of-process Qt-app driving, use an OS-native accessibility driver instead.

winappdriver

Authors and runs Windows UI tests against WinAppDriver, Microsoft's W3C-WebDriver service for UWP / WPF / WinForms / Win32 apps: installing + launching `WinAppDriver.exe` on `127.0.0.1:4723`, declaring `app` / `platformName` / `appArguments` / `appTopLevelWindow` capabilities, finding elements by `AccessibilityId` / `Name` / `ClassName`, and Windows-runner CI. Use when driving a native Windows app from a Selenium-style client (C#, Java, Python, Ruby, JS); for the actively-maintained Appium 2.x wrapper over the same server use appium-windows-driver, for a C#-only FlaUI client use flaui-tests, and to choose among Windows desktop drivers first use desktop-test-strategy-reference.

xctest-mac-desktop

Authors and runs XCTest UI + unit tests for macOS desktop apps - the Apple-first-party test framework that ships with Xcode. Covers the `XCTestCase` subclass + `test*` method-naming convention, `XCUIApplication` / `XCUIElement` / `XCUIElementQuery` for UI tests, accessibility-identifier-based locators (the stable replacement for label-based queries), `XCTAssert*` macros, `measureBlock:` for performance regressions, and `xcodebuild test` for CI execution. Use when the macOS app is built with Xcode and the test target is in-tree alongside the app - for cross-OS sharing see Appium Mac2 driver as a separate path.