6.4 KiB
E2E Test Parallel Execution Feasibility
Author: assistant-engineer-2 Date: 2026-04-21 Purpose: Investigate whether Assistant E2E tests and Skills E2E tests can run in parallel
Executive Summary
Conclusion: ❌ Cannot run in parallel (current architecture)
Reason: Shared singleton Electron app instance + shared database + explicit workers: 1 configuration
Recommendation: Keep sequential execution. If parallel needed in future, requires architectural refactoring (see Solutions section).
Current Architecture Analysis
1. Playwright Configuration
File: playwright.config.ts
fullyParallel: false, // Electron tests share one app instance
workers: 1, // Must be 1: tests share a singleton Electron app instance
Critical constraint: Playwright explicitly enforces workers: 1 with comment explaining singleton architecture.
2. Electron App Singleton Pattern
File: tests/e2e/fixtures.ts:26-28
// Singleton – one app per test worker
let app: ElectronApplication | null = null;
let mainPage: Page | null = null;
Design: One Electron app instance shared across ALL test files in the worker. The app:
- Launches once at worker startup
- Persists across all
test.describe()blocks - Closes only when worker exits
- Reuses same
BrowserWindowand renderer process
Rationale (from tests/e2e/README.md:48-50):
One Electron instance shared across all tests. Restarting costs ~25-30 seconds, so tests reuse the same app process.
3. Shared Resources
3.1 Database
Path resolution (src/process/utils/utils.ts:getDataPath() + backend --data-dir):
return path.join(getDataPath(), 'aionui.db');
userData directory (src/process/utils/configureChromium.ts:18-26):
- Dev mode:
~/Library/Application Support/AionUi-Dev/(macOS) - Database:
{userData}/config/aionui.db - Shared by all E2E tests
Conflict scenario: If Assistant tests and Skills tests run in parallel workers:
- Both access same
aionui.dbfile - SQLite allows multiple readers, but writes lock the entire database
- Test data pollution: Assistant test creates custom assistant → Skills test sees it
3.2 Extension State File
File: tests/e2e/fixtures.ts:29-30
const e2eStateSandboxDir = fs.mkdtempSync(path.join(os.tmpdir(), 'aionui-e2e-state-'));
const e2eStateFile = path.join(e2eStateSandboxDir, 'extension-states.json');
Environment variable (L113):
AIONUI_EXTENSION_STATES_FILE: process.env.AIONUI_EXTENSION_STATES_FILE || e2eStateFile;
Current isolation: Each worker creates unique temp directory → no conflict (✅ parallel-safe for this resource)
3.3 Network Ports
CDP disabled (tests/e2e/fixtures.ts:117):
AIONUI_CDP_PORT: '0';
Result: No port binding conflicts → parallel-safe (✅)
Why Parallel Execution Fails
| Resource | Isolation Level | Conflict Type | Impact |
|---|---|---|---|
| Electron app instance | Worker-scoped | Single instance | 2 workers → 2 apps compete for userData |
| SQLite database | Global (userData) | File lock + data pollution | Write contention + test interference |
| Extension state file | Worker temp dir | ✅ No conflict | - |
| Network ports | None (CDP disabled) | ✅ No conflict | - |
Critical bottleneck: workers: 1 enforced + shared aionui.db → parallel execution impossible without refactoring.
Solutions (Future Work)
Option 1: Multi-Instance Mode (Recommended)
Approach: Isolate userData per worker using environment variables
Implementation:
- Extend
AIONUI_E2E_TESTto include worker ID:AIONUI_E2E_TEST_WORKER_ID: process.env.PLAYWRIGHT_WORKER_INDEX || '0'; - Modify
getDevAppName()to return worker-specific name:const workerId = process.env.AIONUI_E2E_TEST_WORKER_ID || '0'; return `AionUi-E2E-Worker-${workerId}`; - Each worker gets isolated:
~/Library/Application Support/AionUi-E2E-Worker-0/config/aionui.db~/Library/Application Support/AionUi-E2E-Worker-1/config/aionui.db
- Update
playwright.config.ts:workers: 2, // or process.env.CI ? 1 : 2 fullyParallel: true
Cost: ~50-60 seconds total (2 workers × 25-30s startup), but parallel → net time ≈ 30s
Option 2: Test Sharding
Approach: Run Assistant and Skills tests in separate Playwright invocations
Implementation:
# Sequential npm scripts
bun run test:e2e:assistants # Matches tests/e2e/specs/assistant-*.e2e.ts
bun run test:e2e:skills # Matches tests/e2e/specs/skills-*.e2e.ts
Pros: No code changes, explicit separation Cons: Still sequential, no speedup
Option 3: Database Isolation Per Test File
Approach: Pass unique database path via environment variable per spec
Complexity: High (requires main process to read AIONUI_DATABASE_PATH, conflicts with userData convention)
Not recommended: Breaks Electron's standard paths, hard to maintain
Recommendation for Gate 3 Implementation
Keep sequential execution:
- Assistant tests and Skills tests run in same worker (current
workers: 1) - Total runtime = sum of both modules (~2-5 minutes typical)
- No risk of test interference
If parallel needed later:
- Implement Option 1 (Multi-Instance Mode) as part of separate infrastructure task
- Requires changes to:
src/common/platform/index.ts(getDevAppName)tests/e2e/fixtures.ts(worker ID injection)playwright.config.ts(workers count)
- Estimated effort: 2-3 hours implementation + testing
References
playwright.config.ts:8-10— Singleton architecture commenttests/e2e/fixtures.ts:26-28— App singleton declarationtests/e2e/README.md:42-50— Shared instance design rationalesrc/process/utils/utils.ts—getDataPath()database directory resolutionsrc/process/utils/configureChromium.ts:18-26— userData isolation in dev modesrc/common/platform/index.ts—getDevAppName()implementation