GeezerVison is showing github.com — SDK-8048: support BROWSERSTACK_ENV=preprod|staging for internal testing by AakashHotchandani · Pull Request #1217 · browserstack/browserstack-cypress-cli
Conversation
What is this about?
The cli hardcodes production hosts. Testing a cli change on preprod today means hand-editing bin/helpers/config.json plus the accessibility and observability constants.js files (the #1001 pattern), packing a tarball and shipping it through npm_dependencies. This came up while verifying #1206 (Cypress 16) on preprod for SDK-8048.
browserstack-binary (core/utils/environment-url.js) and browserstack-node-agent (src/bin/utils/constants.js, test-observability/constants.js) already switch hosts on BROWSERSTACK_ENV. This PR gives the cli the same switch:
BROWSERSTACK_ENV=preprod npx browserstack-cypress run ...
Unset, or any other value: production hosts, unchanged.
Related Jira task/s
Dependent PRs / release order
Automation cases to add
- None. Internal-only switch, off by default; unit-tested below.
Code changes to check
- Spread operator is not used.
- Syntax supported by older Node: no
?. / ??.
The change
bin/helpers/environmentUrl.js (new): getEnvironmentUrl(url) swaps the whole host from a preprod or staging map and keeps the path, so app-automate.browserstack.com and eds.browserstack.com:443 are left alone. Accepts preprod/pre-prod and staging/stag, case-insensitive. The preprod map mirrors the binary, plus the web accessibility host (accessibility-preprod.bsstag.com), which the binary has no explicit entry for.
bin/helpers/config.js: in the production config only (the BSTACK_CYPRESS_NODE_ENV dev path is untouched), maps uploadUrl, rails_host, dashboardUrl, turboScaleUrl, turboScaleAPIUrl before the derived URLs are built.
bin/accessibility-automation/constants.js: API_URL goes through the map.
bin/testObservability/helper/constants.js: apiUrl() falls back to the mapped collector. An explicit BROWSERSTACK_TEST_OBSERVABILITY_API_URL still wins, and setSystemEnvs still forwards the result to the remote reporter (A11 y 13909 forward observability api url #1214), so the machine posts to the same collector.
bin/testObservability/helper/helper.js: the printed Test Reporting build link uses the mapped host. On preprod it used to print the production automation.browserstack.com link.
Verification
Resolved hosts from the packed tarball:
|
unset |
BROWSERSTACK_ENV=preprod |
| rails |
api.browserstack.com |
api-preprod.bsstag.com |
| upload |
api-cloud.browserstack.com/... |
api-cloud-preprod.bsstag.com/... |
| dashboard |
automate.browserstack.com/... |
automate-preprod.bsstag.com/... |
| accessibility |
accessibility.browserstack.com/api |
accessibility-preprod.bsstag.com/api |
| collector (cli + remote reporter) |
collector-observability.browserstack.com |
collector-observability-preprod.bsstag.com |
Preprod E2E: branch tarball, config.json untouched, only BROWSERSTACK_ENV=preprod set. Cypress 15.21.1, OS X Ventura, Chrome 148, headed, testObservability: true, cli shipped via npm_dependencies + cache_dependencies: true:
| Run |
Upload |
Build |
Test Reporting |
Accessibility |
| a11y off |
✅ api-cloud-preprod |
✅ ee251f15 |
✅ build created; link printed on automation-preprod.bsstag.com |
n/a |
| a11y on |
✅ |
✅ a4fc1331 |
✅ same |
reached accessibility-preprod.bsstag.com; it refused the test account's plan ("You cannot run automation builds on the current plan"), an account entitlement, not routing |
Not covered: staging (devtestops) hosts are mapped from the binary's list and were not run end to end; Windows terminals.
Unit tests: 6 new (test/unit/bin/helpers/environmentUrl.js). Full suite: branch 751 passing / 16 failing, untouched origin/master 745 passing / 16 failing, the same 16 tests on both, so none are new.
🤖 Generated with Claude Code
Summary by CodeRabbit
- Improvements
- Automation and observability services now use the appropriate hosts in supported preproduction and staging environments, while production defaults remain unchanged.
- Custom observability API URLs continue to take precedence over environment-based defaults.
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
The cli hardcodes production hosts, so testing a cli change on preprod means
hand-editing config.json and the accessibility/observability constants (the
PR #1001 pattern). browserstack-binary and browserstack-node-agent already
switch on BROWSERSTACK_ENV; do the same here.
- bin/helpers/environmentUrl.js: exact-host map for preprod and staging,
mirroring browserstack-binary core/utils/environment-url.js, plus the
web accessibility host (accessibility-preprod.bsstag.com).
- Applied to the automate hosts (config.js, production config only), the
accessibility API, the observability collector default (an explicit
BROWSERSTACK_TEST_OBSERVABILITY_API_URL still wins and is forwarded to the
remote reporter as before) and the printed Test Reporting build link.
- Unset or any other value: production hosts, unchanged.
Co-Authored-By: Claude Opus 5.5 <[email protected]>
coderabbitai
Bot
commented
Nov 12, 2026
•
edited
Loading
Uh oh!
There was an error while loading. Please reload this page.
|

No actionable comments were generated in the recent review.
Walkthrough
-
The change adds a shared helper that maps production URL hosts to preprod or staging hosts based on BROWSERSTACK_ENV. Production configuration, accessibility automation, and observability URL paths use the helper.
Changes: Environment URL Selection
| Layer / File(s) |
Summary |
Environment URL mapping bin/helpers/environmentUrl.js, test/unit/bin/helpers/environmentUrl.js |
The helper recognizes preprod and staging selector values and rewrites exact mapped hosts. Tests cover selector handling, URL preservation, unmatched hosts, and observability URL overrides. |
Production configuration and accessibility URLs bin/helpers/config.js, bin/accessibility-automation/constants.js |
Production configuration applies the helper to five URL fields. The accessibility API URL uses the helper with the production URL as its base. |
Observability URLs bin/testObservability/helper/constants.js, bin/testObservability/helper/helper.js |
The observability collector default and build-report link use environment-mapped URLs. An explicit API URL override takes precedence. |
Estimated code review effort: 3 (Moderate) | ~20 minutes
Change: Feature
Suggested reviewers: 07souravkunda, avinash-bharti
Merge Risk: Minimal · up to c9618
-
This adds an internal-only environment switch for preprod and staging testing. Behavior is unchanged when the variable is unset. No actionable merge-blocking risk was found.
Security architecture risk: Low · up to c9618
-
The switch can redirect account credentials and test data to nonproduction services, but selects only fixed destinations through an explicit environment setting. No introduced exploit path was established. Backend credential isolation and server-selected upload destinations remain unverified.
Retained concerns
No architecture-level concerns identified.
Security review details
-
Security Blast Radius
- inferred — Selected nonproduction endpoints can receive supplied BrowserStack credentials, test archives, and build metadata. Consequences of a destination compromise would follow the permissions of those credentials, potentially extending beyond the current build; backend credential scope and tenant isolation were not established.
Trust Boundaries and Controls
- observed — The new selector chooses only between hardcoded host maps, using exact parsed-hostname equality rather than substring matching. It cannot itself specify an arbitrary destination. Existing explicit collector overrides remain a separate, higher-precedence capability with HTTPS validation and rejection of userinfo, query strings, and fragments.
Resilience and Maintainability Implications
- inferred — For a stable process selector and no distinct remote override, build creation, event submission, stop requests, and the forwarded reporter URL resolve to the same collector. Existing creation-failure handling clears build identity, while event and stop paths retain their identity guards. No request-failure-driven fallback to production is introduced in these paths; backend recovery and reporter execution remain unverified.
Hardening Proposals
- proposed — Before broader internal rollout, use environment-scoped credentials and verify that backend-selected upload URLs belong to the intended environment. Treat the selector as routing convenience, not proof of production/nonproduction isolation.
Pre-merge checks: 4
-
| Check name |
Status |
Explanation |
| Description Check |
 |
Check skipped - CodeRabbit’s high-level summary is enabled. |
| Title check |
 |
The title names the main change: adding support for BROWSERSTACK_ENV=preprod|staging, which switches CLI hosts for internal testing. The changeset adds getEnvironmentUrl and applies it to production c… |
| Linked Issues check |
 |
Check skipped because no linked issues were found for this pull request. |
| Out of Scope Changes check |
 |
Check skipped because no linked issues were found for this pull request. |
Full details: Title check
-
Explanation
The title names the main change: adding support for BROWSERSTACK_ENV=preprod|staging, which switches CLI hosts for internal testing. The changeset adds getEnvironmentUrl and applies it to production config URLs, the accessibility API URL, the observability collector URL, and the printed build link. The title includes a ticket prefix (SDK-8048), which is acceptable and does not make it vague.
Finishing Touches
-
Generate unit tests (beta)
-
- Commit to this branch
- Create a new PR
- Autofix · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts
A rabbit checks the host at dawn, Preprod and staging greet the lawn. Paths stay put as hosts exchange, A collector follows the range. The build link hops along its way.
Recent review info
-
Run configuration
-
- Source mode: Default branch
- Repository: browserstack/browserstack-cypress-cli
- Branch: master
- File: .coderabbit.yaml
- Commit: aedf9e9
- Layers: Repository YAML (base), Central YAML (inherited), Organization UI (inherited), Workspace UI (inherited); Enforced overrides: Organization
- Review profile: ASSERTIVE
- Plan: Enterprise
- Run ID:
467a5744-6614-4ae7-85d9-849b10de416c
Commits
-
Reviewing files that changed from the base of the PR and between aedf9e9 and c961827.
Files selected for processing: 6
-
bin/accessibility-automation/constants.js
bin/helpers/config.js
bin/helpers/environmentUrl.js
bin/testObservability/helper/constants.js
bin/testObservability/helper/helper.js
test/unit/bin/helpers/environmentUrl.js
Included review availability: This review used your included allowance. Your plan provides up to 12 included reviews per hour; 11 remain after this review.
Recent review details
-
Additional context used
-
Skipped guideline sources: 1
-
Couldn't be fetched: 1 source
a configured source
On a public repository, sources from your configuration are shown without their names.
Additional comments: 6
-
bin/helpers/environmentUrl.js: 1
-
1-55: LGTM!
test/unit/bin/helpers/environmentUrl.js: 1
-
1-66: LGTM!
bin/helpers/config.js: 1
-
2-2: LGTM!
Also applies to: 14-18
bin/accessibility-automation/constants.js: 1
-
1-4: LGTM!
bin/testObservability/helper/constants.js: 1
-
2-2: LGTM!
Also applies to: 41-43
bin/testObservability/helper/helper.js: 1
-
18-18: LGTM!
Also applies to: 118-118
|
Sorry, something went wrong.
Uh oh!
There was an error while loading. Please reload this page.
Reviewers
rounak610
Awaiting requested review from rounak610
rounak610 is a code owner automatically assigned from browserstack/sdk-dev
vivianludrick
Awaiting requested review from vivianludrick
vivianludrick is a code owner automatically assigned from browserstack/sdk-dev
At least 1 approving review is required to merge this pull request.
Uh oh!
There was an error while loading. Please reload this page.
Assignees
No one assigned
Milestone
No milestone
Development
Successfully merging this pull request may close these issues.
Uh oh!
There was an error while loading. Please reload this page.
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.
|