From ae321ad1084f904410b9f363ad2909734ca1ceda Mon Sep 17 00:00:00 2001 From: Hibryda Date: Wed, 18 Mar 2026 03:58:21 +0100 Subject: [PATCH] fix(e2e): use dedicated port 9750 for tauri-driver (avoid conflicts) - tauri-driver spawned with --port 9750 (was default 4444) - Pre-check: fail fast if port already in use (clear error message) - TCP readiness probe uses the dedicated port - Follows project port convention (9000-9999 range) --- tests/e2e/README.md | 2 +- tests/e2e/wdio.conf.js | 78 +++++++++++++++++++++++++----------------- 2 files changed, 47 insertions(+), 33 deletions(-) diff --git a/tests/e2e/README.md b/tests/e2e/README.md index 3e29669..37c434a 100644 --- a/tests/e2e/README.md +++ b/tests/e2e/README.md @@ -22,7 +22,7 @@ xvfb-run --auto-servernum npm run test:e2e | Tool | Required | Install | |------|----------|---------| -| tauri-driver | Yes | `cargo install tauri-driver` | +| tauri-driver | Yes | `cargo install tauri-driver` (runs on port 9750) | | Debug binary | Yes | `cargo tauri build --debug --no-bundle` | | X11/Wayland | Yes (Linux) | Use `xvfb-run` in CI | | Claude CLI | Optional | LLM-judged tests skip if absent | diff --git a/tests/e2e/wdio.conf.js b/tests/e2e/wdio.conf.js index 892c074..e307fe0 100644 --- a/tests/e2e/wdio.conf.js +++ b/tests/e2e/wdio.conf.js @@ -24,6 +24,12 @@ process.env.AGOR_TEST = '1'; process.env.AGOR_TEST_DATA_DIR = fixture.dataDir; process.env.AGOR_TEST_CONFIG_DIR = fixture.configDir; +// ── Port ── +// Unique port for this project's tauri-driver (avoids conflict with other +// Tauri apps or WebDriver instances on the same machine). +// Range 9000-9999 per project convention. See CLAUDE.md port table. +const TAURI_DRIVER_PORT = 9750; + console.log(`Test fixture created at ${fixture.rootDir}`); export const config = { @@ -31,9 +37,9 @@ export const config = { runner: 'local', maxInstances: 1, // Tauri doesn't support parallel sessions - // ── Connection (external tauri-driver on port 4444) ── + // ── Connection (tauri-driver on dedicated port) ── hostname: 'localhost', - port: 4444, + port: TAURI_DRIVER_PORT, path: '/', // ── Specs ── @@ -120,45 +126,53 @@ export const config = { }, /** - * Spawn tauri-driver before the session. - * tauri-driver bridges WebDriver protocol to WebKit2GTK's inspector. - * Uses TCP probe to confirm port 4444 is accepting connections. + * Spawn tauri-driver on a dedicated port before the session. + * First checks that the port is free (fails fast if another instance is running). + * Uses TCP probe to confirm readiness after spawn. */ beforeSession() { return new Promise((res, reject) => { - tauriDriver = spawn('tauri-driver', [], { - stdio: ['ignore', 'pipe', 'pipe'], - }); - - tauriDriver.on('error', (err) => { + // Fail fast if port is already in use (another tauri-driver or stale process) + const preCheck = createConnection({ port: TAURI_DRIVER_PORT, host: 'localhost' }, () => { + preCheck.destroy(); reject(new Error( - `Failed to start tauri-driver: ${err.message}. ` + - 'Install it with: cargo install tauri-driver' + `Port ${TAURI_DRIVER_PORT} already in use. Kill the existing process: ` + + `lsof -ti:${TAURI_DRIVER_PORT} | xargs kill` )); }); + preCheck.on('error', () => { + preCheck.destroy(); + // Port is free — spawn tauri-driver + tauriDriver = spawn('tauri-driver', ['--port', String(TAURI_DRIVER_PORT)], { + stdio: ['ignore', 'pipe', 'pipe'], + }); - // TCP readiness probe — poll port 4444 until it accepts a connection - const maxWaitMs = 10_000; - const intervalMs = 200; - const deadline = Date.now() + maxWaitMs; + tauriDriver.on('error', (err) => { + reject(new Error( + `Failed to start tauri-driver: ${err.message}. ` + + 'Install it with: cargo install tauri-driver' + )); + }); - function probe() { - if (Date.now() > deadline) { - reject(new Error('tauri-driver did not become ready within 10s')); - return; + // TCP readiness probe — poll until port accepts connections + const deadline = Date.now() + 10_000; + function probe() { + if (Date.now() > deadline) { + reject(new Error(`tauri-driver did not become ready on port ${TAURI_DRIVER_PORT} within 10s`)); + return; + } + const sock = createConnection({ port: TAURI_DRIVER_PORT, host: 'localhost' }, () => { + sock.destroy(); + console.log(`tauri-driver ready on port ${TAURI_DRIVER_PORT}`); + res(); + }); + sock.on('error', () => { + sock.destroy(); + setTimeout(probe, 200); + }); } - const sock = createConnection({ port: 4444, host: 'localhost' }, () => { - sock.destroy(); - res(); - }); - sock.on('error', () => { - sock.destroy(); - setTimeout(probe, intervalMs); - }); - } - - // Give it a moment before first probe - setTimeout(probe, 300); + setTimeout(probe, 300); + }); }); },