/** * ZCLAW Tauri E2E 测试配置 * * 专门用于测试 Tauri 桌面应用模式 * 测试完整的 ZCLAW 功能,包括 Kernel Client 和 Rust 后端集成 */ import { defineConfig, devices } from '@playwright/test'; import { spawn, ChildProcess } from 'child_process'; const TAURI_BINARY_PATH = './target/debug/desktop.exe'; const TAURI_DEV_PORT = 1420; /** * 启动 Tauri 开发应用 */ async function startTauriApp(): Promise { console.log('[Tauri Setup] Starting ZCLAW Tauri application...'); const isWindows = process.platform === 'win32'; const tauriScript = isWindows ? 'pnpm tauri dev' : 'pnpm tauri dev'; const child = spawn(tauriScript, [], { shell: true, cwd: './desktop', stdio: ['pipe', 'pipe', 'pipe'], env: { ...process.env, TAURI_DEV_PORT: String(TAURI_DEV_PORT) }, }); child.stdout?.on('data', (data) => { const output = data.toString(); if (output.includes('error') || output.includes('Error')) { console.error('[Tauri] ', output); } }); child.stderr?.on('data', (data) => { console.error('[Tauri Error] ', data.toString()); }); console.log('[Tauri Setup] Waiting for Tauri to initialize...'); return child; } /** * 检查 Tauri 应用是否就绪 */ async function waitForTauriReady(): Promise { const maxWait = 120000; // 2 分钟超时 const startTime = Date.now(); while (Date.now() - startTime < maxWait) { try { const response = await fetch(`http://localhost:${TAURI_DEV_PORT}`, { method: 'HEAD', timeout: 5000, }); if (response.ok) { console.log('[Tauri Setup] Tauri app is ready!'); return; } } catch { // 还没准备好,继续等待 } // 检查进程是否还活着 console.log('[Tauri Setup] Waiting for app to start...'); await new Promise((resolve) => setTimeout(resolve, 3000)); } throw new Error('Tauri app failed to start within timeout'); } export default defineConfig({ testDir: './specs', timeout: 180000, // Tauri 测试需要更长超时 expect: { timeout: 15000, }, fullyParallel: false, // Tauri 测试需要串行 forbidOnly: !!process.env.CI, retries: 0, reporter: [ ['html', { outputFolder: 'test-results/tauri-report' }], ['json', { outputFile: 'test-results/tauri-results.json' }], ['list'], ], use: { baseURL: `http://localhost:${TAURI_DEV_PORT}`, trace: 'on-first-retry', screenshot: 'only-on-failure', video: 'retain-on-failure', actionTimeout: 15000, navigationTimeout: 60000, }, projects: [ // Tauri Chromium WebView 测试 { name: 'tauri-webview', use: { ...devices['Desktop Chrome'], viewport: { width: 1280, height: 800 }, }, }, // Tauri 功能测试 { name: 'tauri-functional', testMatch: /tauri-.*\.spec\.ts/, use: { ...devices['Desktop Chrome'], viewport: { width: 1280, height: 800 }, }, }, // Tauri 设置测试 { name: 'tauri-settings', testMatch: /tauri-settings\.spec\.ts/, use: { ...devices['Desktop Chrome'], viewport: { width: 1280, height: 800 }, }, }, ], // 启动 Tauri 应用 webServer: { command: 'pnpm tauri dev', url: `http://localhost:${TAURI_DEV_PORT}`, reuseExistingServer: process.env.CI ? false : true, timeout: 180000, stdout: 'pipe', stderr: 'pipe', }, outputDir: 'test-results/tauri-artifacts', });