fix(observability): disable observability throughout the run when build-start is blocked - #77
Conversation
…ld-start is blocked When the Test Observability build-start returns success:false (e.g. an unsupported framework blocked at ingestion), the SDK left two paths still advertising observability: 1. testHub/utils.ts: shouldProcessEventForTesthub's fallback used raw Boolean(...), so BROWSERSTACK_OBSERVABILITY='false' read truthy and events kept flowing. Use the isTrue(...) chain (consistent with the guards above) so 'false' reads as off. 2. launcher.ts (classic flow): the Automate session-start caps still carried buildProductMap.observability:true and a testhubBuildUuid, because getProductMap reads the static config and testhubBuildUuid was stamped from build_hashed_id (which the ingest returns even on a block). Fold the blocked outcome into config so buildProductMap reports observability:false, and only stamp testhubBuildUuid when a TestHub product (observability or accessibility) actually succeeded. Mirrors the existing accessibility fold-back; scoped to the classic flow (the CLI/gRPC flow owns its own build-start). Adds unit tests for both paths. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Test note: the new unit tests pass — |
kamal-kaur04
left a comment
There was a problem hiding this comment.
Claude Code Review
Verdict:
Summary: 0 critical · 1 warning · 1 suggestion across 4 files reviewed.
The core fix is precise and well-targeted: isTrue(...) correctly replaces the truthy-string bug in shouldProcessEventForTesthub, and the testhubBuildUuid/buildProductMap fold-back in launcher.ts correctly distinguishes "observability blocked but accessibility succeeded" from "observability blocked, nothing else succeeded" — I traced both through the real (non-mocked) code paths, not just the tests. The one open question is whether the Boolean(buildStartResponse) scoping gate is airtight for every reason buildStartResponse can be falsy, not just the CLI/gRPC case it's commented to cover — see the inline note.
CI is green (Lint, CodeQL, Semgrep, Build & test on Node 18/20/22), corroborating the author's own local test-note comment.
See inline comments below for full detail.
Generated by Automated SDK PR review.
…-start; robust test cleanup - launcher.ts: key the observability fold-back on whether the classic build-start was ATTEMPTED (classicBuildStartAttempted) rather than on buildStartResponse being truthy. This also covers a transport/parse failure, where launchTestSession's error handler returns null and the env flag is left unset — previously the fold never fired and buildProductMap.observability could still report true with no TestHub build created (review finding #1). CLI/gRPC flow stays excluded. - launcher.test.ts: shared onPrepare mock now simulates a successful build-start (env 'true'); added an afterEach that resets the env flag + launchTestSession/getProductMap mocks, so per-test overrides can't leak on assertion failure (review finding #2). Added a transport-error test. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
Thanks for the review — both findings addressed in #1 (launcher.ts:447 — #2 (test cleanup): moved restoration out of the test body into an Full |
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the latest SDK PR Review Agent run reports GTG on the current head commit. A native reviewer approval is separately required by branch protection before merge. |
|
✅ Good to go
↻ This verdict comment is the review anchor — it's updated in place on each run (the gate posts its status separately). — SDK PR Review Agent |
|
🟢 SDK PR Review gate is green — the SDK PR Review Agent has given a GTG for this PR (the A native GitHub reviewer approval is still separately required by branch protection before this PR can merge — this check does not substitute for that. |
kamal-kaur04
left a comment
There was a problem hiding this comment.
Claude Code Review — re-review (incremental)
Verdict: ✅ Good to go
Both findings from the prior round are verified as genuinely fixed on the current head commit (6eebf94):
- Finding #1 (
launcher.ts) — the observability fold-back now keys onclassicBuildStartAttempted(whether the classic build-start was attempted) instead ofBoolean(buildStartResponse), so a transport/parse failure (wherelaunchTestSession's error handler returnsnull) now also folds observability off. TheBoolean(this._options.testObservability)term is unchanged, so accessibility-/percy-only sessions still don't over-fire. CLI/gRPC flow exclusion is unchanged. - Finding #2 (
launcher.test.ts) — mock/env restoration now runs in anafterEach, which fires even if an earlier assertion in the test throws; a new transport-error unit test exercises the exact gap finding #1 covered. The sharedonPreparemock's default change (env'true') was checked against the pre-existingsamsungGalaxy/testhubBuildUuidassertions later in the same describe block and the two "should launch testhub build" tests — no masked regression found.
CI is green (Build & test passing on Node 18.20, 20, 22). The src/cli/index.ts gRPC/binary-delegation event-emission gap remains out of scope for this PR by design (scoped in the PR body and code comments) and is now documented by a dedicated test — tracked as separate follow-up work, not a blocker here.
No new or remaining findings.
| File | Status | Reason |
|---|---|---|
| packages/browserstack-service/src/launcher.ts | All Clear | Both prior findings verified fixed; guard re-derived, no over-fire |
| packages/browserstack-service/src/testHub/utils.ts | All Clear | isTrue(...) fallback change reviewed, no issues |
| packages/browserstack-service/tests/launcher.test.ts | All Clear | afterEach + shared mock change checked against existing assertions, no masked regression |
| packages/browserstack-service/tests/observability-build-start-success-false.test.ts | All Clear | Documentation-only tests, no issues |
This is a recommendation only — no merge decision submitted; kamal is the human reviewer of record.
— SDK PR Review Agent
|
🟢 SDK PR Review gate is green — the SDK PR Review Agent has given a GTG for this PR (the A native GitHub reviewer approval is still separately required by branch protection before this PR can merge — this check does not substitute for that. |
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the latest SDK PR Review Agent run reports GTG on the current head commit. A native reviewer approval is separately required by branch protection before merge. |
A statically-skipped test (it.skip) is reported from the reporter's onTestSkip hook, which wdio does not await. Its report is queued on the shared reportChain, but onTestSkip fires at suite-end — after afterHook's reportSuiteSkipped await has already passed — so the chain's TestRunFinished tail was never awaited and got dropped at worker teardown, leaving the test orphaned "in progress" on the dashboard (skipped count short by one). Drain the skip-report chain in the awaited after() hook (alongside the existing deferred-finish flush, before onWorkerEnd shuts the batcher) so the TestRunFinished lands while the session is still open. Hook-skip cascades were unaffected (they report via reportSuiteSkipped inside the awaited afterHook). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the latest SDK PR Review Agent run reports GTG on the current head commit. A native reviewer approval is separately required by branch protection before merge. |
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the latest SDK PR Review Agent run reports GTG on the current head commit. A native reviewer approval is separately required by branch protection before merge. |
What is this about?
When the Test Observability build-start returns
success:false(e.g. an unsupported framework blocked at ingestion), observability was not fully disabled for the rest of the run. Two paths still advertised it:Event gate (
src/testHub/utils.ts) —shouldProcessEventForTesthub's fallback used rawBoolean(process.env[...]), soBROWSERSTACK_OBSERVABILITY='false'read as truthy and TestHub events kept flowing for an observability-only session. Now uses theisTrue(...)chain (consistent with the guards above it), so'false'reads as off.Automate session-start caps (
src/launcher.ts, classic flow) — the session still carriedbuildProductMap.observability: trueand atesthubBuildUuid, becausegetProductMapreads the static config andtesthubBuildUuidwas stamped frombuild_hashed_id(which ingest returns even on a block). This keeps the session counted as an SDK observability session even though no TestHub build was created. Now: the blocked outcome is folded into config sobuildProductMapreportsobservability:false, andtesthubBuildUuidis stamped only when a TestHub product (observability or accessibility) actually succeeded. Mirrors the existing accessibility fold-back; scoped to the classic flow (the CLI/gRPC flow owns its own build-start).Verified end-to-end (serenity-js/webdriverio → prod, blocked as
WebdriverIO-@serenity-js/webdriverio): before, the session caps hadobservability:true+ atesthubBuildUuid; after,observability:false+ notesthubBuildUuid, while the Automate build/session still ran.Related Jira task/s
Release (mandatory for every PR — required for the
ready-for-reviewlabel)Version bump: (required — tick exactly one)
Release notes type: (optional)
Release notes (customer-facing): (optional but encouraged)
Release notes (internal): (required — engineer-facing; what actually changed / why)
shouldProcessEventForTesthubfallback now evaluates the product env flags withisTrue(...)instead of rawBoolean(...), soBROWSERSTACK_OBSERVABILITY='false'suppresses events (previouslyBoolean('false')was truthy).browserStackConfig.testObservability.enabled=false(sogetProductMap/buildProductMapreportsobservability:false) and only stampstesthubBuildUuidwhen observability or accessibility succeeded — preventing orphan-linking the Automate session to a TestHub build that was never created. gRPC/CLI flow untouched.tests/observability-build-start-success-false.test.ts, and anonPreparecase intests/launcher.test.ts).Checklist
PR Validations
Run Tests: Comment RUN_TESTS to trigger sanity tests.