@@ -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
@@ -357,6 +357,63 @@ jobs:
357357 DESKTOP_INBOX_E2E_REPORT_PATH="$report_dir/desktop-inbox-http-report.json" \
358358 bun run test:desktop-inbox:e2e
359359
360+ # Desktop tools in the real Electron app against a local app with Redis and its realtime
361+ # server: chat switches, Stop, sign-out, approval and the flag-off foreground round trip.
362+ # The spec runs the recording proxy (the app's public origin) and the stand-in worker.
363+ - name : Verify desktop tools in the Electron app against a local app
364+ env :
365+ NEXT_PUBLIC_APP_URL : http://127.0.0.1:3020
366+ BETTER_AUTH_URL : http://127.0.0.1:3020
367+ REDIS_URL : redis://127.0.0.1:6379
368+ SIM_AGENT_API_URL : http://127.0.0.1:3022
369+ NEXT_PUBLIC_SOCKET_URL : http://127.0.0.1:3023
370+ SOCKET_SERVER_URL : http://127.0.0.1:3023
371+ NEXT_PUBLIC_FORCE_HOSTED : ' false'
372+ COPILOT_API_KEY : desktop-tools-e2e-ci-local-copilot-key
373+ COPILOT_TOOL_PERMISSIONS_ENABLED : ' true'
374+ MOTHERSHIP_SIM_TRANSPORT : direct
375+ INTERNAL_API_SECRET : desktop-tools-e2e-ci-local-secret-at-least-32-characters
376+ DISABLE_TELEMETRY : ' true'
377+ NEXT_TELEMETRY_DISABLED : ' 1'
378+ READY_TIMEOUT_SECONDS : 300
379+ run : |
380+ report_dir="$RUNNER_TEMP/e2e"
381+ mkdir -p "$report_dir"
382+ sudo apt-get update -q
383+ sudo apt-get install -yq xvfb libgtk-3-0t64 libnss3 libasound2t64 libgbm1 libxss1 \
384+ libxtst6 libatk-bridge2.0-0t64 libxkbcommon0 > /dev/null
385+ # Electron's Chromium sandbox needs unprivileged user namespaces, which Ubuntu 24.04 restricts.
386+ sudo sysctl -w kernel.apparmor_restrict_unprivileged_userns=0 || true
387+ (cd apps/desktop && bun run build)
388+ (cd apps/realtime && PORT=3023 SIM_DB_ROLE=realtime ALLOWED_ORIGINS="$NEXT_PUBLIC_APP_URL" \
389+ exec bun src/index.ts > "$report_dir/desktop-tools-realtime.log" 2>&1) &
390+ realtime_pid=$!
391+ (cd apps/sim && exec node ../../node_modules/next/dist/bin/next dev --hostname 127.0.0.1 \
392+ --port 3021 > "$report_dir/desktop-tools-next.log" 2>&1) &
393+ server_pid=$!
394+ finish() {
395+ kill "$server_pid" "$realtime_pid" 2>/dev/null || true
396+ wait "$server_pid" "$realtime_pid" 2>/dev/null || true
397+ }
398+ trap finish EXIT
399+ started=$SECONDS
400+ until curl --fail --silent --max-time 10 http://127.0.0.1:3021/api/health > /dev/null &&
401+ curl --fail --silent --max-time 10 http://127.0.0.1:3023/health > /dev/null; do
402+ kill -0 "$server_pid" 2>/dev/null || { tail -n 200 "$report_dir/desktop-tools-next.log"; exit 1; }
403+ kill -0 "$realtime_pid" 2>/dev/null || { tail -n 200 "$report_dir/desktop-tools-realtime.log"; exit 1; }
404+ [ $((SECONDS - started)) -lt "$READY_TIMEOUT_SECONDS" ] || { echo '::error::Local app did not become ready'; exit 1; }
405+ sleep 2
406+ done
407+ cd apps/desktop
408+ SIM_DESKTOP_E2E_SIM_URL=http://127.0.0.1:3021 \
409+ SIM_DESKTOP_E2E_PROXY_PORT=3020 \
410+ SIM_DESKTOP_E2E_AGENT_PORT=3022 \
411+ SIM_DESKTOP_E2E_DATABASE_URL="$DATABASE_URL" \
412+ SIM_DESKTOP_E2E_REDIS_URL="$REDIS_URL" \
413+ SIM_DESKTOP_E2E_AUTH_SECRET="$BETTER_AUTH_SECRET" \
414+ xvfb-run -a -s '-screen 0 1920x1200x24' bunx playwright test e2e/desktop-tools-live-sim.spec.ts \
415+ --output "$report_dir/desktop-tools-results"
416+
360417 - name : Upload end-to-end reports and server logs
361418 if : failure()
362419 uses : actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4
0 commit comments