diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index a941286..43e250b 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -83,3 +83,75 @@ jobs: - name: Build release binary run: cargo build --release --manifest-path cli/Cargo.toml --target ${{ matrix.target }} + + - name: Run Rust tests + run: cargo test --manifest-path cli/Cargo.toml --target ${{ matrix.target }} + + windows-integration: + name: Windows Integration Test + runs-on: windows-latest + needs: rust + + steps: + - name: Checkout repository + uses: actions/checkout@v4 + + - name: Setup pnpm + uses: pnpm/action-setup@v4 + with: + version: 9 + + - name: Setup Node.js + uses: actions/setup-node@v4 + with: + node-version: 22 + cache: pnpm + + - name: Setup Rust toolchain + uses: dtolnay/rust-toolchain@stable + with: + targets: x86_64-pc-windows-msvc + + - name: Cache Cargo dependencies + uses: actions/cache@v4 + with: + path: | + ~/.cargo/bin/ + ~/.cargo/registry/index/ + ~/.cargo/registry/cache/ + ~/.cargo/git/db/ + cli/target/ + key: windows-cargo-x86_64-pc-windows-msvc-${{ hashFiles('cli/Cargo.lock') }} + restore-keys: | + windows-cargo-x86_64-pc-windows-msvc- + + - name: Build Rust CLI + run: cargo build --release --manifest-path cli/Cargo.toml --target x86_64-pc-windows-msvc + + - name: Install npm dependencies + run: pnpm install + + - name: Build TypeScript + run: pnpm build + + - name: Copy CLI binary to bin directory + run: | + Copy-Item cli/target/x86_64-pc-windows-msvc/release/agent-browser.exe bin/agent-browser-win32-x64.exe + + - name: Test agent-browser install command + run: | + $env:PATH = "$pwd\bin;$env:PATH" + bin/agent-browser-win32-x64.exe install + shell: pwsh + + - name: Verify Chromium was installed + run: | + $playwrightPath = "$env:LOCALAPPDATA\ms-playwright" + if (Test-Path $playwrightPath) { + Write-Host "Playwright browsers installed at: $playwrightPath" + Get-ChildItem $playwrightPath -Recurse -Depth 2 | Select-Object -First 20 + } else { + Write-Error "Playwright browsers not found!" + exit 1 + } + shell: pwsh diff --git a/cli/src/connection.rs b/cli/src/connection.rs index bc50d32..2cfa83c 100644 --- a/cli/src/connection.rs +++ b/cli/src/connection.rs @@ -206,8 +206,13 @@ pub fn ensure_daemon(session: &str, headed: bool) -> Result<(), String> { { use std::os::windows::process::CommandExt; - let mut cmd = Command::new("node"); - cmd.arg(daemon_path) + // On Windows, use cmd.exe to run node to ensure proper PATH resolution. + // This handles cases where node.exe isn't directly in PATH but node.cmd is. + // Pass the entire command as a single string to /c to handle paths with spaces. + let cmd_string = format!("node \"{}\"", daemon_path.display()); + let mut cmd = Command::new("cmd"); + cmd.arg("/c") + .arg(&cmd_string) .env("AGENT_BROWSER_DAEMON", "1") .env("AGENT_BROWSER_SESSION", session); diff --git a/cli/src/install.rs b/cli/src/install.rs index 297af2b..f92c1fc 100644 --- a/cli/src/install.rs +++ b/cli/src/install.rs @@ -128,6 +128,16 @@ pub fn run_install(with_deps: bool) { } println!("\x1b[36mInstalling Chromium browser...\x1b[0m"); + + // On Windows, we need to use cmd.exe to run npx because npx is actually npx.cmd + // and Command::new() doesn't resolve .cmd files the way the shell does. + // Pass the entire command as a single string to /c to handle paths with spaces. + #[cfg(windows)] + let status = Command::new("cmd") + .args(["/c", "npx playwright install chromium"]) + .status(); + + #[cfg(not(windows))] let status = Command::new("npx") .args(["playwright", "install", "chromium"]) .status();