Skip to content

test(e2e): make Playwright global-setup start on Windows#2212

Open
ABorakati wants to merge 1 commit into
getpaseo:mainfrom
ABorakati:fix/e2e-global-setup-windows
Open

test(e2e): make Playwright global-setup start on Windows#2212
ABorakati wants to merge 1 commit into
getpaseo:mainfrom
ABorakati:fix/e2e-global-setup-windows

Conversation

@ABorakati

Copy link
Copy Markdown
Contributor

Linked issue

Closes #2211

Type of change

  • Bug fix
  • New feature (with prior issue + design alignment)
  • Refactor / code improvement
  • Docs

What does this PR do

The Playwright e2e suite (packages/app/e2e) couldn't start on Windows — global-setup.ts crashed during setup before any test ran, because three steps assume POSIX:

  1. Metro is launched with spawn("npx", …). On Windows npx is a .cmd shim that Node's bare spawn can't launch → spawn npx ENOENT.
  2. tsx is located with execSync("which tsx"); which doesn't exist on Windows (it's where).
  3. The tsx daemon spawn hits the same .cmd problem, and a cold tsx start exceeds the 15s waitForServer timeout.

This routes the npx (Metro) and tsx (daemon) spawns through the shell on win32, uses where (first match) instead of which there, and raises the daemon startup timeout to 120s. Every change is process.platform === "win32"-gated, so macOS/Linux/CI behaviour is unchanged (the longer timeout is just a ceiling fast platforms never reach). One file, +14/-1.

How did you verify it

On Windows 11, from packages/app, running a single spec (npx playwright test e2e/timeline-search.spec.ts --project="Desktop Chrome"):

  • Before: global-setup died immediately with spawn npx ENOENT. After shelling that spawn: Command failed: which tsx ('which' is not recognized). After fixing the tsx lookup + spawn: Paseo daemon did not start on 127.0.0.1:<port> within 15000ms.
  • After: the full stack boots — Metro, the daemon, and the relay all come up (daemon log shows Server listening on http://0.0.0.0:<port>, WebSocket server initialized on /ws, and the pairing offer is received) — and Playwright reaches the browser and runs the specs to green.

Full transparency: the pinned Chromium build download kept stalling on my machine, so I actually drove the run against system Chrome (E2E_BROWSER_CHANNEL=chrome via a local-only channel tweak that is not in this PR). That's a separate browser-install issue and irrelevant to this change — this PR only makes global-setup.ts able to start the harness; it doesn't touch browser selection.

Checklist

  • One focused change. Unrelated cleanups split out. (single file, global-setup.ts)
  • npm run typecheck passes
  • npm run lint passes (0 warnings, 0 errors on the changed file)
  • npm run format ran (Biome)
  • UI changes include screenshots or video for every affected platform — n/a, no UI change
  • Tests added or updated where it made sense — n/a; this is e2e-harness infra that unblocks the existing suite on Windows

@greptile-apps

greptile-apps Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Greptile Summary

This PR fixes three Windows-specific failures in packages/app/e2e/global-setup.ts that prevented the Playwright e2e suite from starting at all on Windows 11. The previous thread's concern about where tsx producing space-containing paths being passed to a shell-spawned process has already been addressed in this version — the code now passes the literal string "tsx" on win32 rather than a where-resolved absolute path.

  • shell: process.platform === \"win32\" added to both the Metro (npx) and daemon (tsx) spawns, allowing Node to resolve .cmd shims on Windows without ENOENT.
  • execSync(\"which tsx\") replaced with a platform-conditional that passes \"tsx\" directly on Windows, avoiding the missing-which error and the space-in-path hazard.
  • timeoutMs: 120000 added to the waitForServer call for the daemon — this is applied unconditionally on all platforms, not win32-only as the PR description states, raising the POSIX/CI failure-detection window from 15 s to 120 s.

Confidence Score: 5/5

Safe to merge — changes are scoped to e2e harness infrastructure, spawn fixes are correctly win32-gated, and the previous thread concern has been resolved.

All three Windows fixes are correctly isolated: shell true guards on Metro and daemon spawns are win32-conditional, and passing tsx by name sidesteps the space-in-path hazard. The daemon timeout change is unconditional but matches the existing Metro timeout and is not a functional defect.

No files require special attention.

Important Files Changed

Filename Overview
packages/app/e2e/global-setup.ts Added shell: win32 to Metro and daemon spawns, replaced which tsx with a platform-conditional, and raised the daemon startup timeout unconditionally from 15 s to 120 s. Fixes are correct; the timeout change is not win32-gated contrary to the PR description.

Flowchart

%%{init: {'theme': 'neutral'}}%%
flowchart TD
    A[globalSetup] --> B[startMetro]
    B -->|spawn npx expo start| C{win32?}
    C -->|yes| D[shell: true
npx resolves .cmd shim]
    C -->|no| E[shell: false
POSIX direct exec]
    D --> F[waitForMetro
timeoutMs: 120000]
    E --> F
    F --> G[startDaemon]
    G -->|resolve tsx| H{win32?}
    H -->|yes| I[tsxBin = 'tsx'
shell: true]
    H -->|no| J[tsxBin = which tsx
shell: false]
    I --> K[spawn tsx scripts/supervisor-entrypoint.ts]
    J --> K
    K --> L[waitForServer
timeoutMs: 120000
all platforms]
    L --> M[waitForPairingOffer]
Loading
%%{init: {'theme': 'base', 'themeVariables': {"darkMode": true, "background": "#0d1117", "primaryColor": "#21262d", "primaryTextColor": "#e6edf3", "primaryBorderColor": "#8b949e", "lineColor": "#8b949e", "textColor": "#e6edf3", "edgeLabelBackground": "#161b22", "actorBkg": "#21262d", "actorBorder": "#8b949e", "actorTextColor": "#e6edf3", "actorLineColor": "#8b949e", "signalColor": "#8b949e", "signalTextColor": "#e6edf3", "noteBkgColor": "#373320", "noteBorderColor": "#d4a72c", "noteTextColor": "#f0e6c0", "labelBoxBkgColor": "#21262d", "labelBoxBorderColor": "#8b949e", "labelTextColor": "#e6edf3", "loopTextColor": "#e6edf3", "activationBkgColor": "#30363d", "activationBorderColor": "#8b949e"}}}%%
flowchart TD
    A[globalSetup] --> B[startMetro]
    B -->|spawn npx expo start| C{win32?}
    C -->|yes| D[shell: true
npx resolves .cmd shim]
    C -->|no| E[shell: false
POSIX direct exec]
    D --> F[waitForMetro
timeoutMs: 120000]
    E --> F
    F --> G[startDaemon]
    G -->|resolve tsx| H{win32?}
    H -->|yes| I[tsxBin = 'tsx'
shell: true]
    H -->|no| J[tsxBin = which tsx
shell: false]
    I --> K[spawn tsx scripts/supervisor-entrypoint.ts]
    J --> K
    K --> L[waitForServer
timeoutMs: 120000
all platforms]
    L --> M[waitForPairingOffer]
Loading

Reviews (2): Last reviewed commit: "test(e2e): make Playwright global-setup ..." | Re-trigger Greptile

Comment thread packages/app/e2e/global-setup.ts Outdated
The e2e harness never started on Windows: `spawn("npx", …)` for Metro and
`execSync("which tsx")` for the daemon both assume POSIX. Route the npx/tsx
launches through the shell on win32 (bare spawn can't resolve a `.cmd` shim),
swap `which`→`where` there, and raise the daemon start timeout to 120s (a cold
`tsx` start on Windows exceeds the 15s default). All changes are win32-gated,
so POSIX/CI behavior is unchanged.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
@ABorakati
ABorakati force-pushed the fix/e2e-global-setup-windows branch from 12ee248 to 49a8414 Compare July 18, 2026 20:08
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

bug: Playwright e2e harness (global-setup.ts) can't start on Windows

1 participant