perf(ci): shard cloud parity across 2 BrowserStack sessions via CDP#367
Merged
Conversation
Connect the Parity (Cloud) job to remote Chrome directly over CDP (wss://cdp.browserstack.com/playwright) instead of browserstack-node-sdk, and shard specs across up to 2 parallel sessions (falling back to fewer when the plan is busy). This roughly halves parity wall-clock. - config/playwright.parity-cloud.config.ts: SDK launch -> CDP connectOptions; workers from CIWORKERS; fullyParallel; trace off (wsEndpoint embeds the key). - config/browserstack-cdp.ts: shared CDP endpoint builder + localIdentifier. - config/browserstack-local-tunnel.ts: globalSetup starts/stops a BrowserStack Local tunnel so the remote browser reaches the local dev server; no-op without credentials. - scripts/browserstack-wait.sh: grab up to BSTACK_SESSIONS_REQUIRED (default 2) sessions, export CIWORKERS, retry on queue-size-exceeded. - package.json: add browserstack-local dep; test:parity-cloud no longer wraps the SDK. Perf job keeps the SDK (browserstack.yml). - azure-pipelines.yml: run parity via browserstack-wait.sh with 2 sessions and a per-build BSTACK_LOCAL_IDENTIFIER. - TESTING.md: document the CDP/sharded parity setup. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Contributor
There was a problem hiding this comment.
Pull request overview
This PR speeds up the Parity (Cloud) Azure Pipelines job by switching it from an SDK-managed single BrowserStack session to direct CDP connections with Playwright, enabling the parity specs to shard across up to 2 parallel BrowserStack sessions while keeping the Local tunnel approach (remote browser still reaches the local Vite dev server).
Changes:
- Replace
browserstack-node-sdkusage in cloud parity with PlaywrightconnectOptions.wsEndpoint(CDP) and drive worker count viaCIWORKERS. - Add a
browserstack-wait.shhelper to poll plan capacity, pick an available session count, exportCIWORKERS, and retry on queue contention. - Add shared BrowserStack CDP helpers + a Playwright
globalSetupto start/stop abrowserstack-localtunnel; update CI + docs accordingly.
Reviewed changes
Copilot reviewed 7 out of 8 changed files in this pull request and generated 2 comments.
Show a summary per file
| File | Description |
|---|---|
| TESTING.md | Documents the new CDP + sharded parity-cloud setup and session-wait invocation. |
| scripts/browserstack-wait.sh | New capacity-polling wrapper that selects an available session count and exports CIWORKERS. |
| pnpm-lock.yaml | Locks the added browserstack-local dependency. |
| package.json | Updates parity-cloud script to run Playwright directly; adds browserstack-local. |
| config/playwright.parity-cloud.config.ts | Switches parity-cloud to CDP wsEndpoint, enables parallel workers, and wires in globalSetup. |
| config/browserstack-local-tunnel.ts | New Playwright globalSetup to manage the BrowserStack Local tunnel lifecycle. |
| config/browserstack-cdp.ts | New shared helpers to build the CDP endpoint and keep localIdentifier consistent. |
| azure-pipelines.yml | Runs parity-cloud via the wait script, sets sessions required + per-build local identifier. |
Files not reviewed (1)
- pnpm-lock.yaml: Generated file
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
…parity artifacts Address Copilot review on #367: - browserstack-wait.sh: fail fast when BSTACK_SESSIONS_MIN exceeds the (capped) preferred count, which would otherwise silently grant fewer than the requested minimum. - Add scripts/redact-secrets.ts and a ParityCloud pipeline step that scrubs BROWSERSTACK_ACCESS_KEY/USERNAME (raw + URL-encoded) from the test-results report/JUnit before they are published/uploaded, since the CDP wsEndpoint embeds the access key. Co-authored-by: Copilot App <223556219+Copilot@users.noreply.github.com>
Bundle Size ChangesDecreases
Sizes rounded to nearest KB. Run |
Lab - Static SiteBuild 20260706.9 - merge @ ca7c72f |
ryantrem
approved these changes
Jul 6, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Why
The Parity (Cloud) job runs all parity scenes serially on a single BrowserStack session behind the
browserstack-node-sdk-managed tunnel. This is a small, focused subset of #302 that targets the two biggest, lowest-risk wins without the large surface area of that PR (which also replaced the tunnel with a public static site + 233 scene-URL rewrites).What changed
connectOptions.wsEndpoint(wss://cdp.browserstack.com/playwright) — nobrowserstack-node-sdk, nobrowserstack.yml. Each Playwright worker is its own cloud session, so specs shard across workers.scripts/browserstack-wait.shgrabs up toBSTACK_SESSIONS_REQUIRED(default 2) sessions from the plan, falls back to fewer when the plan is busy, exportsCIWORKERS, and retries on queue-size-exceeded.globalSetup(config/browserstack-local-tunnel.ts) so the remote browser still reaches the local Vite dev server. Specs keep usinggoto("/sceneN.html")unchanged.config/browserstack.yml+ tunnel.Files
config/playwright.parity-cloud.config.ts— SDK launch → CDPconnectOptions; workers fromCIWORKERS;fullyParallel;trace: "off"(the wsEndpoint embeds the access key).config/browserstack-cdp.ts(new) — shared CDP endpoint builder +localIdentifier.config/browserstack-local-tunnel.ts(new) — globalSetup that starts/stops the Local tunnel; no-op without credentials.scripts/browserstack-wait.sh(new) — session grabber (default 2).package.json— addbrowserstack-localdep;test:parity-cloudno longer wraps the SDK.azure-pipelines.yml— run parity viabrowserstack-wait.shwithBSTACK_SESSIONS_REQUIRED=2and a per-buildBSTACK_LOCAL_IDENTIFIER.TESTING.md— document the CDP/sharded setup.Expected impact
At 2 sessions the parity job should be roughly 2× faster, with no changes to engine
src, scenes, or goldens.Verification
playwright test --list(local-fallback and CDP with creds → 213 tests).bash -n scripts/browserstack-wait.shclean;azure-pipelines.ymlvalid YAML.prettier --checkclean on changed files; confirmed Playwright 1.58 runs the function returned byglobalSetupas teardown, so the tunnel is stopped.Notes / follow-ups
src), so parity/bundle guardrails aren't required by repo rules; perf is never run by agents.traceis forced off. A dedicated secret-redaction step for published reports (as in perf(ci): cut cloud parity time — public static site + sharded BrowserStack (CDP) #302) could be a later hardening follow-up.Co-authored-by: Copilot 223556219+Copilot@users.noreply.github.com