The self-hosted CI runner packs several jobs onto the shared host network
(capacity 4). The UI suite pinned the fixture server to 127.0.0.1:3107 and set
reuseExistingServer: true, so overlapping runs fought over the bind: one job
won it, and every browser in the other got "connection refused" on all four
projects. Pass one random high port per run through the environment (shared by
the main process and its worker) and only reuse an existing server outside CI.
Verified with the full ui suite: 150 passed, 2 skipped.
Replace platform: 'node' (incompatible with iife browser bundle) with
explicit aliases for node:async_hooks, node:crypto, node:fs/promises,
node:path pointing at e2e/ui/node-stubs.mjs. Provides shape-compatible
exports so esbuild can bundle the UI fixture without failing on Node
built-ins. Increase webServer timeout to 120s for reliable startup.
Add firefox and webkit projects alongside chromium (desktop/mobile),
and enable reuseExistingServer so the fixture server isn't restarted
per run. Chromium/Firefox/WebKit browsers installed via
npx playwright install.