Repository navigation
Conversation
…flow does Mocha attaches a beforeEach/afterEach declared outside any describe to its root suite, which has no file, so the CLI flow sent these hooks with no path. The binary threw on the missing path and dropped their HookRunStarted/Finished events while the test still referenced the hook id, leaving a never-closed hook that timed the build out. The non-CLI flow falls back to the current suite file (set in beforeSuite); the CLI mocha framework now does the same for hooks and test data. 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
|
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the SDK PR Review Agent has run on the current head commit (any verdict — the gate only requires that the review ran). A native reviewer approval is separately required by branch protection before merge. |
1 similar comment
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the SDK PR Review Agent has run on the current head commit (any verdict — the gate only requires that the review ran). A native reviewer approval is separately required by branch protection before merge. |
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the SDK PR Review Agent has run on the current head commit (any verdict — the gate only requires that the review ran). A native reviewer approval is separately required by branch protection before merge. |
2 similar comments
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the SDK PR Review Agent has run on the current head commit (any verdict — the gate only requires that the review ran). A native reviewer approval is separately required by branch protection before merge. |
|
🔴 SDK PR Review gate is red. Pending:
It turns green once the SDK PR Review Agent has run on the current head commit (any verdict — the gate only requires that the review ran). A native reviewer approval is separately required by branch protection before merge. |
|
✅ Good to go
Change map (generated deterministically from the diff)graph LR
subgraph nwdio_service["wdio-service"]
npackages_browserstack_service_src_cli_frameworks_wdioMochaTestFramework_ts["wdioMochaTestFramework.ts<br/>~35 lines"]
npackages_browserstack_service_tests_cli_wdioMochaTestFramework_test_ts["wdioMochaTestFramework.test.ts<br/>~35 lines"]
npackages_browserstack_service_src_service_ts["service.ts<br/>~30 lines"]
npackages_browserstack_service_tests_service_test_ts["service.test.ts<br/>~30 lines"]
n_changeset_pr_308_md["pr-308.md<br/>~5 lines"]
end
↻ 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 run on the current head commit (verdict: This gate confirms a review ran on the latest commit. The verdict itself is advisory — read the findings and use your judgement; it does not block merge. A native GitHub reviewer approval is still separately required by branch protection before this PR can merge. |
1 similar comment
|
🟢 SDK PR Review gate is green — the SDK PR Review Agent has run on the current head commit (verdict: This gate confirms a review ran on the latest commit. The verdict itself is advisory — read the findings and use your judgement; it does not block merge. A native GitHub reviewer approval is still separately required by branch protection before this PR can merge. |
|
RUN_TESTS |
|
[SDK Wdio Test] TRA build state: passed | Stability 100% — verdict: success. Passed: 53, Failed: 0, Aggregate: 53. TRA: https://observability.browserstack.com/builds/hcxsuc5bw18wcbhsfvw9yvpvhiyclsjvczsngom7 |
wdio registers its beforeSuite as a root beforeAll only after the spec files load, so a before() declared outside any describe runs ahead of it. The suite file the CLI mocha framework falls back to was still unset at that point and the hook went out with no path, which the binary throws on. Seed the fallback from the worker's spec in before(), converted from the file URL the runner hands over the same way MochaAdapter does for suite.file. beforeSuite still updates it, but no longer clears it when a suite has no file. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
|
🟢 SDK PR Review gate is green — the SDK PR Review Agent has run on the current head commit (verdict: This gate confirms a review ran on the latest commit. The verdict itself is advisory — read the findings and use your judgement; it does not block merge. A native GitHub reviewer approval is still separately required by branch protection before this PR can merge. |
|
🟢 SDK PR Review gate is green — the SDK PR Review Agent has run on the current head commit (verdict: This gate confirms a review ran on the latest commit. The verdict itself is advisory — read the findings and use your judgement; it does not block merge. A native GitHub reviewer approval is still separately required by branch protection before this PR can merge. |
What is this about?
On the CLI flow, a Mocha
before/beforeEach/afterEachdeclared outside anydescribereaches the BrowserStack binary with no file path. Every test passes, yet the build ends as timed out on Test Reporting & Analytics.Mocha attaches such hooks to its root suite, and the root suite has no
file. The CLI mocha framework read onlytest.file, so these hooks went out withouttest_file_path/test_location. The binary could not build the hook's file details, so it dropped the hook'sHookRunStarted/HookRunFinishedevents. The test'sTestRunFinishedstill referenced the hook id, so TRA kept a hook open that never closed. The build timeout then marked the whole build timed out.The non-CLI flow never had this. Its insights handler falls back to the current suite file (
test.file || this._suiteFile, fed frombeforeSuite). This PR gives the CLI flow the same behaviour:WdioMochaTestFramework.setSuiteFile().beforeSuitefeeds it on the CLI flow, the same call the non-CLI flow makes on its insights handler.trackHookEventsandgetTestDatausetest.file || this._suiteFile. ThegetTestDatafallback was already there, commented out.Root-level
before.MochaAdapterregisters wdio'sbeforeSuiteas a rootbeforeAllonly after the spec files have loaded, so a root-levelbeforeruns ahead of it, while the suite file is still unset. The service'sbefore()hook runs before Mocha starts, so it now seeds the suite file from the worker's spec. The runner hands specs over asfile://URLs; they are converted the same wayMochaAdapterconverts them forsuite.file.beforeSuitestill updates the file, but a suite with no file no longer clears it. A root-levelbeforeon the non-CLI flow has no file either; there the hook events don't go through the binary, so nothing breaks.Hooks declared inside a
describekeep their own file, and nothing else changes.When it shows up: CLI-flow hooks only started carrying ids in 9.30. Before that they were not reported at all. So suites with root-level hooks have hit this since 9.30.
Paired binary hardening (the binary also stops throwing on a hook with no file, which covers already-released SDK versions): browserstack/browserstack-binary#1988.
Verification
End to end, on real BrowserStack sessions. The sample spec has a root-level
beforeEach/afterEach, abefore/afterin one describe, and its ownbeforeEachin a second describe. It runs 2 tests, both passing in every run.@wdio/browserstack-serviceThe "to" argument must be of type stringbeforeEach/afterEachstart + finishtest/specs/root-hooks.spec.json all 8 hooksA second sample adds a root-level
beforeandafterto the same spec (10 hooks in all):@wdio/browserstack-servicebeforebeforeseed (earlier head)HookRunStarted/HookRunFinishednever sent, still referenced by the first test'sTestRunFinishedtest/specs/root-before.spec.js; every one of the 10 hooks carries the spec fileUnit tests:
tests/cli/wdioMochaTestFramework.test.ts(+3):tests/service.test.ts(+3):beforeSuitehands the suite file to the CLI mocha framework;before()seeds it from the worker's spec (afile://URL, decoded to the path);before()tests fail without the seed. Both files pass in full on Node 22: 157/157 and 37/37. eslint andtsc --noEmitare clean.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)
before/beforeEach/afterEachhook is declared outside anydescribeblock.Release notes (internal): (required — engineer-facing; what actually changed / why)
test.file || this._suiteFile, fed frombeforeSuite), matching the non-CLI insights handler.service.before()seeds that file from the worker's spec, because a root-levelbeforeruns ahead of the firstbeforeSuite. A suite with no file no longer clears it.TestRunFinished's reference to them left a never-closed hook that timed the build out.Checklist
PR Validations
Run Tests: Comment RUN_TESTS to trigger sanity tests.
🤖 Generated with Claude Code