Spectron
Spectron is an end-to-end testing framework designed specifically for Electron applications. It leverages ChromeDriver and WebdriverIO to provide an API for interacting with Electron apps, allowing developers to simulate user interactions and assert application state. The current stable version is 19.0.0. However, Spectron was officially deprecated on February 1, 2022, and is no longer actively maintained. Its primary differentiator was its tight integration with Electron, allowing control over both the Electron main process and renderer processes through WebdriverIO. Due to its deprecated status, new projects are advised to seek alternative testing solutions for Electron.
Common errors
-
Error: `app.start()` failed: `path` must be a string
cause The `path` option in the `Application` constructor is not correctly pointing to your Electron binary.fixEnsure `path: electronPath` correctly resolves to the Electron executable. If using `require('electron')`, ensure `electron` is installed as a dependency. For packaged apps, specify the absolute path to the main executable. -
Error: `app.start()` failed: spectron failed to start the application
cause This generic error often indicates an issue with how Spectron is trying to launch your Electron app, such as incorrect `args` pointing to the main Electron script or a problem within your Electron app's startup.fixVerify the `args` array in the `Application` constructor correctly points to your main Electron script (e.g., `path.join(__dirname, '..')`). Check your Electron app's `main.js` for any startup errors. Also, ensure Spectron and Electron versions are compatible according to the 'Version Map'. -
TypeError: Cannot read properties of undefined (reading 'isVisible')
cause This typically occurs when trying to access `this.app.browserWindow` or `this.app.client` before the application has successfully started, or if `this.app` is `undefined`.fixEnsure `await this.app.start()` completes successfully before attempting to interact with `this.app.browserWindow` or `this.app.client`. Also, check that `this.app` is properly initialized in your `beforeEach` hook.
Warnings
- breaking Spectron was officially deprecated on February 1, 2022. It is no longer actively maintained by the Electron team, meaning no new features, bug fixes, or security patches will be released. Existing applications should consider migrating to alternative testing solutions.
- breaking Spectron has strict version compatibility requirements with Electron. Using mismatched versions can lead to application launch failures or unexpected test behavior.
- breaking Upgrading from Spectron 1.x to 2.x/3.x introduced significant breaking changes, requiring review of the changelog for migration steps.
- gotcha Spectron relies on `chromedriver` and `webdriverio`. Configuration issues with these underlying tools can manifest as Spectron errors. Ensure `chromedriver` is compatible with your Electron version's Chromium and that `webdriverio` configurations are correct.
Install
-
npm install spectron -
yarn add spectron -
pnpm add spectron
Imports
- Application
const { Application } = require('spectron')import { Application } from 'spectron' - Application (CJS)
const { Application } = require('spectron') - electronPath
const electronPath = require('electron')import electronPath from 'electron'
Quickstart
import { Application } from 'spectron'
import assert from 'assert'
import electronPath from 'electron' // Require Electron from the binaries included in node_modules.
import path from 'path'
describe('Application launch', function () {
this.timeout(10000)
beforeEach(async function () {
this.app = new Application({
path: electronPath,
args: [path.join(__dirname, '..')]
})
await this.app.start()
})
afterEach(async function () {
if (this.app && this.app.isRunning()) {
await this.app.stop()
}
})
it('shows an initial window', async function () {
// Example assertion: check if the main window is visible
const isVisible = await this.app.browserWindow.isVisible()
assert.strictEqual(isVisible, true, 'Initial window should be visible')
// Example assertion: check window title
const title = await this.app.client.getTitle()
assert.strictEqual(title, 'Your Electron App Title', 'Window title should match')
})
it('should have a button and click it', async function() {
const button = await this.app.client.$('#my-button')
await button.click()
const text = await this.app.client.$('#status-text').getText()
assert.strictEqual(text, 'Button clicked!', 'Status text should update after click')
})
})