Repository navigation
feat(lib): route Automate, App Automate, Accessibility and Observability to the account's GRR region - #489
feat(lib): route Automate, App Automate, Accessibility and Observability to the account's GRR region#489SavioBS629 wants to merge 29 commits into
Conversation
…ity to the account's GRR region Add src/lib/regional-host.ts, which probes each product's US, EU and IN hosts in order and keeps the first that accepts the caller's credentials, the same approach tm-base-url.ts uses for Test Management. A GRR account is rejected by every region except its own, so it lands on its regional host; a non-GRR account is served by the US host and never reaches the others. If every region refuses, the call fails rather than falling back to the US host. Hosts routed: - Automate / App Automate REST: api-<region>-only.browserstack.com - App Automate uploads and Espresso/XCUITest builds: api-cloud (US) or api-<region>-only - App Automate hub: hub-<region>-only.browserstack.com - Accessibility: api-accessibility-<region>, accessibility-<region> - Test Reporting & Analytics / RCA / build insights / self-heal: api-observability-<region>, api-automation-<region> The region is cached per product in stdio mode only; remote mode probes on every call so one user's region cannot reach another (rules/multi-tenant-safety.md). BROWSERSTACK_AUTOMATION_BASE_URL still overrides the api-automation host for non-prod targets. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
Important Review skippedAuto reviews are disabled on this repository. Please check the settings in the CodeRabbit UI or the
|
When every regional probe fails (bad credentials, no access to the product, a network failure), use the US host instead of throwing, so the tool behaves as it did before region routing and the product's own error reaches the user. The fallback is logged and not cached, so the next call probes again. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… of probing Replace the per-product host probe with a startup flag. BROWSERSTACK_GRR_REGION is read once in config.ts: - unset or "us": every host stays on its US default, as before; Test Management keeps its existing probe - "eu" / "in": Automate, App Automate (REST, uploads, builds, hub), Accessibility and Test Reporting/RCA/build insights/self-heal use that region's hosts, and Test Management goes straight to test-management-<region> without probing - any other value fails at startup, so a typo cannot quietly route a GRR account to the US No extra requests are made in any region, and getRegionalHost is now a synchronous, config-free lookup, so remote mode needs no cache. The flag is documented in llms-install.md. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Resolves the one conflict, in src/tools/automate-utils/fetch-screenshots.ts: the GRR change added the regional-host import where browserstack#488 added the log and screenshot size caps. Both are kept; the screenshot fetch uses the regional host and the size caps together. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The capability registry took tra's host from its index, which declares only
the US host, so an EU deployment sent every invokeCapability call for tra to
api-observability.browserstack.com and the EU account was rejected there.
Resolve tra through the same getRegionalHost("observabilityApi") lookup the
hand-written Test Reporting tools use, next to tm in the registry's built-in
map. Unset or "us" returns the host the index already declares, and
CAPABILITY_REGISTRY_BASE_URL_TRA and per-environment overrides still win.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Test Management is the one product that probes its regional hosts. Instead of skipping the probe when the flag is set, probe in the flag's order: the configured region first, then the rest in their standard order (unset/us: us, eu, in; eu: eu, us, in; in: in, us, eu). A correct flag still answers on the first request, and a missing or wrong flag still finds the account's region, because the other regions reject it. The order comes from regionPreference() in regional-host.ts, derived from the region host table rather than hardcoded per region. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…TACK_GRR_REGION lookup Replace the TM-only probe ordering with one path for every product: when BROWSERSTACK_GRR_REGION is set, Test Management (tools and the tm capability), the tra capability, Automate, App Automate, Accessibility and Test Reporting all take their host from getRegionalHost() - a lookup on the env flag, with no probing and nothing to cache. The flag now stays undefined when unset, so "not configured" is distinct from "us". Only in that case does Test Management keep its existing US -> EU -> IN probe, so EU/IN accounts that never set the flag keep working as on main. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…REGION is eu or in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…s eu or in Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
… resolved TM host Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…to the regional host Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Routes main's new Accessibility code by BROWSERSTACK_GRR_REGION: App Accessibility API and dashboard hosts, App Automate build lookups, the website-scanner call, and getAutomationBaseUrl. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…_REGION Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…overy With BROWSERSTACK_GRR_REGION set to eu or in, tra no longer probes its base_urls, and devicecontrol and mobiledevicecontrol (hub and api hosts) use the region's hosts. Unset keeps the existing discovery and declared hosts. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…outing # Conflicts: # src/tools/accessiblity-utils/app-report-fetcher.ts
…bility by region Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarve-shreyas
left a comment
There was a problem hiding this comment.
Review of the GRR region routing. Inline comments cover lines in the diff; three issues are outside it:
- AI-TFA / RCA collaboration tools are not routed (
src/tools/tfa-rca-utils/constants.ts:6).submit-turn,trigger-report,build-failure-themesandtfa-rca-collaborationstill get their host fromO11Y_TFA_RCA_BASE_URL, which defaults to USapi-automation.browserstack.com, andgetRegionalHostnever reaches them. Witheu, the build data and turn text go to the US host and either fail with 401/404 or put GRR data in the US. The PR description says TRA/RCA are routed, so this looks like a gap. - Dashboard-link parsing is inconsistent (
src/tools/accessiblity-utils/report-fetcher.ts:~207,app-report-fetcher.ts:654/660).manualReportIdFromDashboardLink/buildIdFromDashboardLinkaccept only the regional app-accessibility host, so a US link pasted undereuused to resolve and now doesn't. Theautomate.browserstack.com/APP_AUTOMATE_HOSTchecks still accept only US hostnames, so EU dashboard links are never recognised either. Accepting every known regional host would fix both. - Duplicated host-kind selection (
src/lib/regional-host.ts:~177).automateApiandappAutomateApipoint to the same table, and thesessionType === Automate ? ... : ...ternary is repeated in about 7 files (fetch-screenshots, video, selfheal, list-session-ids, resolve-hashed-build-id…). Some call sites also usegetRegionalHost("automationApi")wheregetAutomationBaseUrl()exists. A singlehostForSession(sessionType)helper would keep them from drifting.
- Route the AI-TFA/RCA collaboration host by region - Compare host overrides by origin, so a trailing slash is not an override - Keep the Test Management probe for us, matching the other products - Apply the region to the tm capability at the same point as the others - Ignore the process-wide region in remote mode - Accept App Accessibility links from any region - One sessionApiHost helper instead of repeated host selection Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Look up the account's region once per server config from a user profile token minted with the configured username and access key, and use it for routing, telemetry fields and the feedback tool. BROWSERSTACK_GRR_REGION is used when the lookup fails. - Each tool call runs in its account's region, so concurrent calls for different accounts route independently in hosted mode. - Telemetry outside a tool call waits for the lookup; when it fails and no region is configured, only usage fields are sent. - BrowserStackMcpServer.create() resolves the region before building the server, so the tool list and instructions match it. The local entry point uses it. - submitFeedback declines at call time when the account's region is EU or IN. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
The account's region from BrowserStack auth is now the only source, so BROWSERSTACK_GRR_REGION is removed. When the lookup fails, hosts keep their US defaults (Test Management still probes each region) and telemetry sends only usage fields. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Keep only an answer from BrowserStack auth. After a failure the region is "unknown" for 30 seconds, then the next call looks up again, so a network blip no longer fixes an account to the default hosts for the life of the server. Also drop BROWSERSTACK_GRR_REGION from the install guide, since it was removed. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarve-shreyas
left a comment
There was a problem hiding this comment.
Re-reviewed the commits since my last review (24266f6…1efef0d, excluding the upstream/main merge).
Thanks. These are resolved:
- The
usflag no longer disables the TM probe; the flag itself is gone and the region now comes from the account. - The override check now compares origins (
hostOverride). tmis inREGIONAL_HOSTS, andweb_accessibilityis now covered too.- Multi-tenant: the region is looked up per account and scoped per call through
AsyncLocalStorage. sessionApiHost()plus default host params remove the duplicated ternaries.- TFA/RCA collaboration now routes through
getO11yBaseUrl()→hostFor("automationApi", region). This was item 1 of my previous summary. - I accept the decision to keep Percy, askBrowserStackAI, App Live upload, load testing and the US telemetry endpoint out of scope, since they're listed under "Not routed yet".
New, inline: an account whose region lookup fails is routed to US hosts and keeps feedback enabled, while telemetry treats it as restricted. There's also a question about how the region cache behaves in the hosted wrapper.
Still open from the last review (item 2, outside the diff): only the App Accessibility links were switched to isRegionalHostname. report-fetcher.ts:207 (automate.browserstack.com) and app-report-fetcher.ts:651 (APP_AUTOMATE_HOST) still accept only US hostnames, so EU/IN Automate and App Automate dashboard links still aren't recognised. If those dashboards have regional hosts, adding them to HOSTS and using isRegionalHostname would close this.
|
@SavioBS629 I re-reviewed up to 1efef0d (#489 (review)). Most of the earlier points are resolved, thanks! Three new points:
Also still open from last time: Automate and App Automate dashboard-link parsing ( |
Telemetry is now off for accounts in the EU or IN region. When the account's region can't be looked up, rows still carry usage fields only. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
IN accounts keep the default hosts, as before this change, and Test Management and capability discovery still probe for them. They are still treated as region-restricted for telemetry and submitFeedback. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Calls that need the account's region now return an error asking the user to retry instead of using the default hosts. Test Management still finds the region by probing. submitFeedback is also unavailable in this case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Servers built per request for the same account now reuse one lookup. The region is kept for an hour, a failed lookup is retried after 5 seconds, and region values are matched in any case. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
sarve-shreyas
left a comment
There was a problem hiding this comment.
Re-reviewed df5fef1…1851231.
Resolved from my last review:
- Fail-open on unknown region.
assertRegionKnown()/routedRegion()now refuse with a retry message instead of falling back to US, TM still probes, and a 5s retry window fits the message. - Feedback for unknown accounts.
feedbackEnabled()now usesisRestrictedRegion. - Region cache in hosted mode. It's keyed on a credential hash, bounded, and has a TTL, so servers built per request share one lookup.
- Region value casing.
regionFromTokenlowercases the value, so"EU"resolves.
New, inline: the known region is dropped when a refresh fails after the TTL, which now fails closed. IN accounts route to US, and the PR description doesn't say so. A startup-only nit on submitFeedback.
Still open (outside the diff): Automate and App Automate dashboard-link parsing (report-fetcher.ts:207, app-report-fetcher.ts:651) still accepts only US hostnames.
A failed refresh no longer drops an account's known region, so an auth outage doesn't stop tools for accounts already looked up. submitFeedback stays listed when the region is unknown at startup, and each call decides whether it can send. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
On the Automate and App Automate dashboard-link parsing ( |
sarve-shreyas
left a comment
There was a problem hiding this comment.
Re-reviewed 390c066. No new issues; everything from my earlier rounds is either fixed or explicitly deferred:
- Region kept on a failed refresh:
accountRegionserves the last known region while a refresh runs and when it fails, and resetsfailedAtonce a refresh succeeds. Only accounts that have never been looked up get the retry error. - Startup with an unknown region:
feedbackListed()keepssubmitFeedbacklisted. The call check (feedbackEnabled()) andwithFeedbackHintstill decline or hide the hint while the region is unknown, so this is consistent. - Deferred, as listed in the description under "Not routed yet": IN routing, Automate and App Automate dashboard links, and switching the hosted server to
create().
Looks good from my side.
sarve-shreyas
left a comment
There was a problem hiding this comment.
Approving at 390c066. The deferred items (IN routing, Automate and App Automate dashboard links, and the hosted server switching to create()) are tracked under "Not routed yet".
When BrowserStack auth can't be reached or names a region not known here, the region is taken from the first Test Management host that accepts the account, trying the regional hosts first. A probed region is asked of auth again after five minutes. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Summary
Routes EU accounts to BrowserStack's EU hosts automatically. Nothing to configure: the server reads the account's region from BrowserStack auth, using the username and access key it already has.
Routed
tmcapability)devicecontrol/mobiledevicecontrolcapabilitiesapp_accessibility/web_accessibilitycapabilities)tracapability)Hosts resolve in one place (
src/lib/regional-host.ts). ExplicitCAPABILITY_REGISTRY_BASE_URL_*,BROWSERSTACK_AUTOMATION_BASE_URLandO11Y_TFA_RCA_BASE_URLoverrides still win.No telemetry is sent for EU and IN accounts, and
submitFeedbackisn't offered to them. While the region is unknown, telemetry sends only usage fields (no error text or free-text inputs) andsubmitFeedbackdeclines.For library users
BrowserStackMcpServer.create(config)looks up the region before building the server, so the tool list matches the account.new BrowserStackMcpServer(config)still routes every call by region, but lists tools as for a US account.Not routed yet
askBrowserStackAIand theloadtestingcapabilityTesting
npm run buildpasses. Unit tests cover the region lookup (token parsing, one lookup per account, expiry, failure), per-call routing for concurrent accounts, each product's regional host, telemetry fields andsubmitFeedback. Verified end to end against an EU account: local stdio, and hosted with OAuth,AccessTokenandbrowserstack-*header sign-in all reached the EU hosts directly.Squash on merge.
🤖 Generated with Claude Code