refactor(e2e): extract infrastructure into tests/e2e/infra/ module

- Move fixtures.ts, llm-judge.ts, results-db.ts to tests/e2e/infra/
- Deduplicate wdio.conf.js: use createTestFixture() instead of inline copy
- Replace __dirname paths with projectRoot-anchored paths
- Create test-mode-constants.ts (typed env var names, flag registry)
- Create scripts/preflight-check.sh (validates tauri-driver, display, Claude CLI)
- Create scripts/check-test-flags.sh (CI lint for AGOR_TEST flag drift)
- Rewrite tests/e2e/README.md with full documentation
- Update spec imports for moved infra files
This commit is contained in:
Hibryda 2026-03-18 03:06:57 +01:00
parent 538a31f85c
commit e76bc341f2
10 changed files with 235 additions and 191 deletions

View file

@ -1,68 +1,30 @@
import { spawn, execSync } from 'node:child_process';
import { spawn } from 'node:child_process';
import { createConnection } from 'node:net';
import { resolve, dirname, join } from 'node:path';
import { resolve, dirname } from 'node:path';
import { fileURLToPath } from 'node:url';
import { mkdirSync, writeFileSync, rmSync } from 'node:fs';
import { tmpdir } from 'node:os';
import { rmSync } from 'node:fs';
import { createTestFixture } from './infra/fixtures.ts';
const __dirname = dirname(fileURLToPath(import.meta.url));
const projectRoot = resolve(__dirname, '../..');
// Debug binary path (built with `cargo tauri build --debug --no-bundle`)
// Cargo workspace target dir is at v2/target/, not v2/src-tauri/target/
// Debug binary path (Cargo workspace target at repo root)
const tauriBinary = resolve(projectRoot, 'target/debug/agent-orchestrator');
let tauriDriver;
// ── Test Fixture (created eagerly so env vars are available for capabilities) ──
const fixtureRoot = join(tmpdir(), `agor-e2e-${Date.now()}`);
const fixtureDataDir = join(fixtureRoot, 'data');
const fixtureConfigDir = join(fixtureRoot, 'config');
const fixtureProjectDir = join(fixtureRoot, 'test-project');
// ── Test Fixture ──
// IMPORTANT: Must be created at module top-level (synchronously) because the
// capabilities object below references fixtureDataDir/fixtureConfigDir at eval time.
// tauri:options.env may not reliably set process-level env vars, so we also
// inject into process.env for tauri-driver inheritance.
const fixture = createTestFixture('agor-e2e');
mkdirSync(fixtureDataDir, { recursive: true });
mkdirSync(fixtureConfigDir, { recursive: true });
mkdirSync(fixtureProjectDir, { recursive: true });
// Create a minimal git repo for agent testing
execSync('git init', { cwd: fixtureProjectDir, stdio: 'ignore' });
execSync('git config user.email "test@agor.dev"', { cwd: fixtureProjectDir, stdio: 'ignore' });
execSync('git config user.name "Agor Test"', { cwd: fixtureProjectDir, stdio: 'ignore' });
writeFileSync(join(fixtureProjectDir, 'README.md'), '# Test Project\n\nA simple test project for Agor E2E tests.\n');
writeFileSync(join(fixtureProjectDir, 'hello.py'), 'def greet(name: str) -> str:\n return f"Hello, {name}!"\n');
execSync('git add -A && git commit -m "initial commit"', { cwd: fixtureProjectDir, stdio: 'ignore' });
// Write groups.json with one group containing the test project
writeFileSync(
join(fixtureConfigDir, 'groups.json'),
JSON.stringify({
version: 1,
groups: [{
id: 'test-group',
name: 'Test Group',
projects: [{
id: 'test-project',
name: 'Test Project',
identifier: 'test-project',
description: 'E2E test project',
icon: '\uf120',
cwd: fixtureProjectDir,
profile: 'default',
enabled: true,
}],
agents: [],
}],
activeGroupId: 'test-group',
}, null, 2),
);
// Inject env vars into process.env so tauri-driver inherits them
// (tauri:options.env may not reliably set process-level env vars)
process.env.AGOR_TEST = '1';
process.env.AGOR_TEST_DATA_DIR = fixtureDataDir;
process.env.AGOR_TEST_CONFIG_DIR = fixtureConfigDir;
process.env.AGOR_TEST_DATA_DIR = fixture.dataDir;
process.env.AGOR_TEST_CONFIG_DIR = fixture.configDir;
console.log(`Test fixture created at ${fixtureRoot}`);
console.log(`Test fixture created at ${fixture.rootDir}`);
export const config = {
// ── Runner ──
@ -78,10 +40,10 @@ export const config = {
// Single spec file — Tauri launches one app instance per session,
// and tauri-driver can't re-create sessions between spec files.
specs: [
resolve(__dirname, 'specs/agor.test.ts'),
resolve(__dirname, 'specs/agent-scenarios.test.ts'),
resolve(__dirname, 'specs/phase-b.test.ts'),
resolve(__dirname, 'specs/phase-c.test.ts'),
resolve(projectRoot, 'tests/e2e/specs/agor.test.ts'),
resolve(projectRoot, 'tests/e2e/specs/agent-scenarios.test.ts'),
resolve(projectRoot, 'tests/e2e/specs/phase-b.test.ts'),
resolve(projectRoot, 'tests/e2e/specs/phase-c.test.ts'),
],
// ── Capabilities ──
@ -91,11 +53,7 @@ export const config = {
'tauri:options': {
application: tauriBinary,
// Test isolation: fixture-created data/config dirs, disable watchers/telemetry
env: {
AGOR_TEST: '1',
AGOR_TEST_DATA_DIR: fixtureDataDir,
AGOR_TEST_CONFIG_DIR: fixtureConfigDir,
},
env: fixture.env,
},
}],
@ -199,7 +157,7 @@ export const config = {
}
// Clean up test fixture
try {
rmSync(fixtureRoot, { recursive: true, force: true });
rmSync(fixture.rootDir, { recursive: true, force: true });
console.log('Test fixture cleaned up.');
} catch { /* best-effort cleanup */ }
},
@ -207,7 +165,7 @@ export const config = {
// ── TypeScript (auto-compile via tsx) ──
autoCompileOpts: {
tsNodeOpts: {
project: resolve(__dirname, 'tsconfig.json'),
project: resolve(projectRoot, 'tests/e2e/tsconfig.json'),
},
},
};