name: Test on: push: branches: [main] pull_request: workflow_dispatch: inputs: run_macos_e2e: description: 'Run macOS E2E tests (Appium Mac2)' required: false default: 'false' type: choice options: - 'false' - 'true' permissions: contents: read pull-requests: read concurrency: group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.head_ref || github.ref }} cancel-in-progress: true jobs: unit-tests: name: Frontend Unit Tests runs-on: ubuntu-latest steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 1 - name: Setup Node.js 24.x uses: actions/setup-node@v4 with: node-version: 24.x cache: "yarn" - name: Cache node modules id: yarn-cache uses: actions/cache@v4 with: path: node_modules key: ${{ runner.os }}-test-${{ hashFiles('**/yarn.lock') }} restore-keys: | ${{ runner.os }}-test- ${{ runner.os }}-build- - name: Install dependencies if: steps.yarn-cache.outputs.cache-hit != 'true' run: yarn install --frozen-lockfile - name: Run tests with coverage run: yarn test:coverage env: NODE_ENV: test - name: Upload coverage reports if: always() uses: actions/upload-artifact@v4 with: name: coverage-report path: coverage retention-days: 7 rust-tests: name: Rust Tests + Quality runs-on: ubuntu-22.04 container: image: ghcr.io/tinyhumansai/openhuman_ci:rust-1.93.0 steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 1 - name: Cache Rust build artifacts uses: Swatinem/rust-cache@v2 with: workspaces: | . -> target app/src-tauri -> target cache-on-failure: true - name: Install system dependencies (cmake, ALSA, X11) run: apt-get update && apt-get install -y --no-install-recommends cmake libasound2-dev libxdo-dev libxtst-dev libx11-dev libevdev-dev && rm -rf /var/lib/apt/lists/* - name: Check formatting (cargo fmt) run: cargo fmt --all -- --check - name: Run clippy (core crate) run: cargo clippy -p openhuman - name: Test core crate (openhuman) run: cargo test -p openhuman - name: Build sidecar core binary run: cargo build --profile ci --target x86_64-unknown-linux-gnu --bin openhuman-core - name: Stage sidecar for Tauri shell tests run: | mkdir -p app/src-tauri/binaries cp target/x86_64-unknown-linux-gnu/ci/openhuman-core app/src-tauri/binaries/openhuman-core-x86_64-unknown-linux-gnu chmod +x app/src-tauri/binaries/openhuman-core-x86_64-unknown-linux-gnu - name: Test Tauri shell (OpenHuman) run: cargo test --manifest-path app/src-tauri/Cargo.toml e2e-linux: name: E2E (Linux / tauri-driver) runs-on: ubuntu-22.04 timeout-minutes: 60 steps: - name: Checkout code uses: actions/checkout@v4 with: fetch-depth: 1 submodules: recursive - name: Setup Node.js 24.x uses: actions/setup-node@v4 with: node-version: 24.x cache: "yarn" - name: Install Rust (rust-toolchain.toml) uses: dtolnay/rust-toolchain@1.93.0 - name: Install system dependencies run: | sudo apt-get update sudo apt-get install -y \ libgtk-3-dev libwebkit2gtk-4.1-dev libappindicator3-dev \ librsvg2-dev patchelf \ xvfb at-spi2-core dbus-x11 \ webkit2gtk-driver \ libasound2-dev libxdo-dev libxtst-dev libx11-dev libevdev-dev - name: Cargo.lock fingerprint (deps only) id: cargo-lock-fingerprint shell: bash run: | echo "hash=$(tail -n +8 Cargo.lock | openssl dgst -sha256 | awk '{print $2}')" >> "$GITHUB_OUTPUT" - name: Cache Cargo registry and build uses: actions/cache@v4 with: path: | ~/.cargo/registry ~/.cargo/git target key: ${{ runner.os }}-e2e-cargo-${{ steps.cargo-lock-fingerprint.outputs.hash }} restore-keys: | ${{ runner.os }}-e2e-cargo- - name: Install tauri-driver run: cargo install tauri-driver --version 2.0.5 - name: Install JS dependencies run: yarn install --frozen-lockfile - name: Ensure .env exists for E2E build run: | touch .env touch app/.env - name: Build E2E app run: yarn workspace openhuman-app test:e2e:build - name: Stage sidecar next to app binary run: | # Tauri resolves externalBin relative to the running binary's directory. # Copy the sidecar from binaries/ to target/debug/ so the app can find it. cp app/src-tauri/binaries/openhuman-core-x86_64-unknown-linux-gnu \ app/src-tauri/target/debug/openhuman-core-x86_64-unknown-linux-gnu chmod +x app/src-tauri/target/debug/openhuman-core-x86_64-unknown-linux-gnu echo "Sidecar staged next to app binary:" ls -la app/src-tauri/target/debug/openhuman-core-* app/src-tauri/target/debug/OpenHuman - name: Run E2E tests under Xvfb run: | export DISPLAY=:99 Xvfb :99 -screen 0 1280x1024x24 & sleep 2 # dbus session is required by webkit2gtk eval "$(dbus-launch --sh-syntax)" # Ensure XDG dirs exist for deep-link URL scheme registration on Linux mkdir -p ~/.local/share/applications export RUST_BACKTRACE=1 cd app # Core specs — must pass on Linux CI FAILED=0 for spec in \ test/e2e/specs/login-flow.spec.ts \ test/e2e/specs/smoke.spec.ts \ test/e2e/specs/navigation.spec.ts \ test/e2e/specs/telegram-flow.spec.ts; do SPEC_NAME=$(basename "$spec" .spec.ts) echo "=== Running $SPEC_NAME ===" bash scripts/e2e-run-spec.sh "$spec" "$SPEC_NAME" || { echo "FAILED: $SPEC_NAME" cat /tmp/tauri-driver-e2e-${SPEC_NAME}.log 2>/dev/null || true FAILED=1 } done # Extended specs (auth, billing, gmail, notion, payments) are skipped # on Linux CI — webkit2gtk text matching differences cause Settings # page navigation timeouts. Full suite runs on macOS locally. if [ "$FAILED" -eq 1 ]; then echo "Core E2E specs failed" exit 1 fi echo "Core E2E specs passed" # e2e-macos: # name: E2E (macOS / Appium) # if: github.event_name == 'workflow_dispatch' && github.event.inputs.run_macos_e2e == 'true' # runs-on: macos-latest # timeout-minutes: 90 # steps: # - name: Checkout code # uses: actions/checkout@v4 # with: # fetch-depth: 1 # submodules: recursive # - name: Setup Node.js 24.x # uses: actions/setup-node@v4 # with: # node-version: 24.x # cache: "yarn" # - name: Install Rust (rust-toolchain.toml) # uses: dtolnay/rust-toolchain@1.93.0 # - name: Install dependencies # run: yarn install --frozen-lockfile # - name: Ensure .env exists for E2E build # run: | # touch .env # touch app/.env # - name: Install Appium and mac2 driver # run: | # npm install -g appium # appium driver install mac2 # - name: Build E2E app bundle # run: yarn workspace openhuman-app test:e2e:build # - name: Run all E2E flows # run: yarn workspace openhuman-app test:e2e:all:flows