Overview
The electron() preset automatically sets up an Electron application with TestDriver and Dashcam recording. Perfect for testing desktop apps built with Electron.
Recommended Pattern (v7.1+): Use TestDriver() hook + provision.electron() for more flexibility:import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'my test' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({
appPath: './dist/my-app'
});
// ...
});
The electron() preset is still supported but the direct API provides better control and clearer lifecycle management.
Quick Start
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'electron app test' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/my-app' });
await testdriver . find ( 'main window' ). click ();
await testdriver . find ( 'File menu' ). click ();
await testdriver . find ( 'New Document' ). click ();
});
Signature
electron ( context , options ): Promise < ElectronResult >
Parameters
Vitest test context - automatically passed to your test function
Configuration options for Electron Path to your Electron application executable or main file
Additional command-line arguments to pass to Electron
Enable Dashcam test recording
os
'linux' | 'mac' | 'windows'
default: "linux"
Target operating system for the test
Returns
TestDriver instance ready to use
Alias for testdriver (semantic clarity for Electron apps)
Dashcam instance for test recording (if enabled)
Examples
Basic Electron App
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'opens main window' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/my-electron-app' });
await testdriver . assert ( 'Main window is visible' );
await testdriver . find ( 'Welcome message' ). click ();
});
With Command-Line Arguments
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'app with debug mode' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({
appPath: './dist/app' ,
args: [
'--enable-logging' ,
'--debug' ,
'--user-data-dir=/tmp/test-data'
]
});
await testdriver . find ( 'Debug panel' ). click ();
await testdriver . assert ( 'Debug information is visible' );
});
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'file menu operations' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/editor-app' });
// Open File menu
await testdriver . find ( 'File' ). click ();
await testdriver . find ( 'New File' ). click ();
// Verify new file created
await testdriver . assert ( 'Untitled document is open' );
// Save file
await testdriver . find ( 'File' ). click ();
await testdriver . find ( 'Save As' ). click ();
await testdriver . type ( 'test-document.txt' );
await testdriver . pressKeys ([ 'enter' ]);
await testdriver . assert ( 'File saved successfully' );
});
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'windows electron app' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true , os: 'windows' });
await testdriver . provision . electron ({
appPath: 'C: \\ Program Files \\ MyApp \\ MyApp.exe'
});
await testdriver . find ( 'Start button' ). click ();
});
test ( 'mac electron app' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true , os: 'mac' });
await testdriver . provision . electron ({
appPath: '/Applications/MyApp.app/Contents/MacOS/MyApp'
});
await testdriver . find ( 'Start button' ). click ();
});
Preferences and Settings
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'configure app settings' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/my-app' });
// Open preferences
await testdriver . find ( 'Settings' ). click ();
// Change theme
await testdriver . find ( 'Appearance' ). click ();
await testdriver . find ( 'Dark mode toggle' ). click ();
// Verify change
await testdriver . assert ( 'Dark mode is enabled' );
// Save settings
await testdriver . find ( 'Save button' ). click ();
await testdriver . assert ( 'Settings saved' );
});
Window Management
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'multiple windows' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/multi-window-app' });
// Open new window
await testdriver . find ( 'File' ). click ();
await testdriver . find ( 'New Window' ). click ();
// Switch between windows
await testdriver . find ( 'second window' ). click ();
await testdriver . assert ( 'Second window is focused' );
// Close window
await testdriver . find ( 'Close button' ). click ();
await testdriver . assert ( 'Window closed' );
});
import { test } from 'vitest' ;
import { TestDriver } from 'testdriverai/vitest/hooks' ;
test ( 'form submission' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/form-app' });
// Fill form
await testdriver . find ( 'Name input' ). type ( 'John Doe' );
await testdriver . find ( 'Email input' ). type ( '[email protected] ' );
await testdriver . find ( 'Phone input' ). type ( '555-1234' );
// Select dropdown
await testdriver . find ( 'Country dropdown' ). click ();
await testdriver . find ( 'United States' ). click ();
// Check checkbox
await testdriver . find ( 'Terms and conditions' ). click ();
// Submit
await testdriver . find ( 'Submit button' ). click ();
await testdriver . assert ( 'Form submitted successfully' );
// Dashcam captures entire interaction
});
What It Does
When you call electron(), it automatically:
Initializes TestDriver - Creates and connects to sandbox
Sets up Dashcam - Authenticates and starts recording (if enabled)
Launches Electron - Starts your app with specified arguments
Waits for Ready - Ensures app is focused and windows are loaded
Returns Instances - Provides ready-to-use testdriver, app alias, and dashcam
At test end:
Dashcam automatically stops and saves replay URL
TestDriver automatically disconnects
All cleanup is handled for you
Common Patterns
IPC Communication Testing
test ( 'ipc events' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/ipc-app' });
// Trigger IPC event from renderer
await testdriver . find ( 'Send Message button' ). click ();
// Verify main process response
await testdriver . assert ( 'Response received from main process' );
});
Notification Testing
test ( 'system notifications' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/notification-app' });
await testdriver . find ( 'Show Notification' ). click ();
await testdriver . assert ( 'System notification appears' );
});
Tray Icon Interaction
test ( 'system tray' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/tray-app' });
// Click tray icon
await testdriver . find ( 'app tray icon' ). click ();
// Interact with tray menu
await testdriver . find ( 'Show Window' ). click ();
await testdriver . assert ( 'Main window appears' );
});
Auto-Update Flow
test ( 'app update' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({
appPath: './dist/updatable-app' ,
args: [ '--check-updates' ]
});
await testdriver . find ( 'Check for Updates' ). click ();
await testdriver . assert ( 'Checking for updates message' );
// Assuming update is available
await testdriver . find ( 'Download Update' ). click ();
await testdriver . assert ( 'Update downloaded' );
});
Development Paths
Common Development Paths
// Electron Forge
appPath : './out/my-app-linux-x64/my-app'
// Electron Builder
appPath : './dist/linux-unpacked/my-app'
// Direct execution
appPath : './node_modules/.bin/electron'
args : [ './main.js' ]
// Packaged app (Windows)
appPath : 'C: \\ Program Files \\ MyApp \\ MyApp.exe'
// Packaged app (macOS)
appPath : '/Applications/MyApp.app/Contents/MacOS/MyApp'
// Packaged app (Linux)
appPath : '/opt/MyApp/my-app'
Using with provision()
The electron() preset can also be called via the unified provision() function:
import { provision } from 'testdriverai/presets' ;
test ( 'using provision' , async ( context ) => {
const { app } = await provision ( 'electron' , {
appPath: './dist/my-app'
}, context );
// Same functionality as electron() directly
});
Error Handling
test ( 'handles missing app path' , async ( context ) => {
try {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: '/nonexistent/path' });
} catch ( error ) {
// Cleanup still happens automatically
expect ( error . message ). toContain ( 'appPath' );
}
});
test ( 'handles app crashes' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({ appPath: './dist/my-app' });
try {
// Trigger something that might crash
await testdriver . find ( 'Crash button' ). click ();
} catch ( error ) {
// Dashcam still saves replay of crash
console . error ( 'App crashed:' , error );
}
});
Debugging Tips
Enable Electron DevTools - Pass --enable-logging in args
Use Dashcam - Review test recordings to see what happened
Custom User Data - Use --user-data-dir for isolated testing
Remote Debugging - Use --remote-debugging-port=9222
test ( 'with debugging enabled' , async ( context ) => {
const testdriver = TestDriver ( context , { headless: true });
await testdriver . provision . electron ({
appPath: './dist/my-app' ,
args: [
'--enable-logging' ,
'--remote-debugging-port=9222' ,
'--user-data-dir=/tmp/test-profile'
]
});
// Test with full debugging capabilities
});
See Also