@@ -123,8 +123,8 @@ jobs:
123123 http-e2e :
124124 name : End-to-end over real HTTP
125125 runs-on : ${{ (vars.CI_PROVIDER == '' || vars.CI_PROVIDER == 'blacksmith') && 'blacksmith-8vcpu-ubuntu-2404' || 'ubuntu-latest' }}
126- # Four suites, each starting its own dev app, run in sequence.
127- timeout-minutes : 30
126+ # Five suites, each starting its own dev app, run in sequence.
127+ timeout-minutes : 45
128128 services :
129129 postgres :
130130 image : pgvector/pgvector:pg17
@@ -433,6 +433,63 @@ jobs:
433433 DESKTOP_INBOX_E2E_REPORT_PATH="$report_dir/desktop-inbox-http-report.json" \
434434 bun run test:desktop-inbox:e2e
435435
436+ # Desktop tools in the real Electron app against a local app with Redis and its realtime
437+ # server: chat switches, Stop, sign-out, approval and the flag-off foreground round trip.
438+ # The spec runs the recording proxy (the app's public origin) and the stand-in worker.
439+ - name : Verify desktop tools in the Electron app against a local app
440+ env :
441+ NEXT_PUBLIC_APP_URL : http://127.0.0.1:3020
442+ BETTER_AUTH_URL : http://127.0.0.1:3020
443+ REDIS_URL : redis://127.0.0.1:6379
444+ SIM_AGENT_API_URL : http://127.0.0.1:3022
445+ NEXT_PUBLIC_SOCKET_URL : http://127.0.0.1:3023
446+ SOCKET_SERVER_URL : http://127.0.0.1:3023
447+ NEXT_PUBLIC_FORCE_HOSTED : ' false'
448+ COPILOT_API_KEY : desktop-tools-e2e-ci-local-copilot-key
449+ COPILOT_TOOL_PERMISSIONS_ENABLED : ' true'
450+ MOTHERSHIP_SIM_TRANSPORT : direct
451+ INTERNAL_API_SECRET : desktop-tools-e2e-ci-local-secret-at-least-32-characters
452+ DISABLE_TELEMETRY : ' true'
453+ NEXT_TELEMETRY_DISABLED : ' 1'
454+ READY_TIMEOUT_SECONDS : 300
455+ run : |
456+ report_dir="$RUNNER_TEMP/e2e"
457+ mkdir -p "$report_dir"
458+ sudo apt-get update -q
459+ sudo apt-get install -yq xvfb libgtk-3-0t64 libnss3 libasound2t64 libgbm1 libxss1 \
460+ libxtst6 libatk-bridge2.0-0t64 libxkbcommon0 > /dev/null
461+ # Electron's Chromium sandbox needs unprivileged user namespaces, which Ubuntu 24.04 restricts.
462+ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
463+ (cd apps/desktop && bun run build)
464+ (cd apps/realtime && PORT=3023 SIM_DB_ROLE=realtime ALLOWED_ORIGINS="$NEXT_PUBLIC_APP_URL" \
465+ exec bun src/index.ts > "$report_dir/desktop-tools-realtime.log" 2>&1) &
466+ realtime_pid=$!
467+ (cd apps/sim && exec node ../../node_modules/next/dist/bin/next dev --hostname 127.0.0.1 \
468+ --port 3021 > "$report_dir/desktop-tools-next.log" 2>&1) &
469+ server_pid=$!
470+ finish() {
471+ kill "$server_pid" "$realtime_pid" 2>/dev/null || true
472+ wait "$server_pid" "$realtime_pid" 2>/dev/null || true
473+ }
474+ trap finish EXIT
475+ started=$SECONDS
476+ until curl --fail --silent --max-time 10 http://127.0.0.1:3021/api/health > /dev/null &&
477+ curl --fail --silent --max-time 10 http://127.0.0.1:3023/health > /dev/null; do
478+ kill -0 "$server_pid" 2>/dev/null || { tail -n 200 "$report_dir/desktop-tools-next.log"; exit 1; }
479+ kill -0 "$realtime_pid" 2>/dev/null || { tail -n 200 "$report_dir/desktop-tools-realtime.log"; exit 1; }
480+ [ $((SECONDS - started)) -lt "$READY_TIMEOUT_SECONDS" ] || { echo '::error::Local app did not become ready'; exit 1; }
481+ sleep 2
482+ done
483+ cd apps/desktop
484+ SIM_DESKTOP_E2E_SIM_URL=http://127.0.0.1:3021 \
485+ SIM_DESKTOP_E2E_PROXY_PORT=3020 \
486+ SIM_DESKTOP_E2E_AGENT_PORT=3022 \
487+ SIM_DESKTOP_E2E_DATABASE_URL="$DATABASE_URL" \
488+ SIM_DESKTOP_E2E_REDIS_URL="$REDIS_URL" \
489+ SIM_DESKTOP_E2E_AUTH_SECRET="$BETTER_AUTH_SECRET" \
490+ xvfb-run -a -s '-screen 0 1920x1200x24' bunx playwright test e2e/desktop-tools-live-sim.spec.ts \
491+ --output "$report_dir/desktop-tools-results"
492+
436493 - name : Upload end-to-end reports and server logs
437494 if : failure()
438495 uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
0 commit comments