-
Notifications
You must be signed in to change notification settings - Fork 9
fix(automate): name App Automate sessions per test instead of only at worker teardown (SDK-7270) #131
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
fix(automate): name App Automate sessions per test instead of only at worker teardown (SDK-7270) #131
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,5 @@ | ||
| --- | ||
| "@wdio/browserstack-service": patch | ||
| --- | ||
|
|
||
| - Fixed App Automate and Automate session names staying on the static `sessionName` capability instead of the test title, for suites that reload the session between tests or whose run ends before the WebdriverIO `after` hook. | ||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -25,6 +25,7 @@ interface TestResult { | |
|
|
||
| interface SessionData { | ||
| lastTestName: string | ||
| appliedName?: string // last name successfully PUT for this session, for de-duping | ||
| testResults: Map<string, TestResult> // testName -> TestResult | ||
| } | ||
|
|
||
|
|
@@ -95,6 +96,42 @@ export default class AutomateModule extends BaseModule { | |
| } | ||
|
|
||
| TestFramework.setState(instace, TestFrameworkConstants.KEY_AUTOMATE_SESSION_NAME, name) | ||
|
|
||
| // SDK-7270: name the session NOW, while it is still the live session, instead of | ||
| // relying solely on the onAfterExecute sweep at worker teardown. Sessions are closed | ||
| // as soon as the suite reloads them (`browser.reloadSession()` per test), and a worker | ||
| // that never reaches `after()` — interrupted run, hard exit, crash — never fires | ||
| // onAfterExecute at all, leaving every session on the creation-time `sessionName` | ||
| // capability. Restores the pre-9.27 behaviour, where the rename was issued per test. | ||
| await this.flushSessionName(sessionId) | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Medium] Skipped tests also fire
Failure scenario: a failed UNVERIFIED: whether this trips the WDIO Suggestion: pass a marker in Reviewer: fallback independent reviewer |
||
| } | ||
|
|
||
| /** | ||
| * PUT the session's current name if it has not already been applied. | ||
| * De-duped via `appliedName` so the onAfterExecute sweep does not re-send it. | ||
| */ | ||
| private async flushSessionName(sessionId: string): Promise<void> { | ||
| const testContextOptions = this.config.testContextOptions as TestContextOptions | ||
| if (testContextOptions.skipSessionName) { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Low] Unguarded
No new exposure — Note this guard is also unreachable from Reviewer: fallback independent reviewer |
||
| return | ||
| } | ||
|
|
||
| if (!sessionId) { | ||
| return | ||
| } | ||
|
|
||
| const sessionData = this.sessionMap.get(sessionId) | ||
| if (!sessionData || !sessionData.lastTestName || sessionData.appliedName === sessionData.lastTestName) { | ||
| return | ||
| } | ||
|
|
||
| const name = sessionData.lastTestName | ||
| await this.markSessionName(sessionId, name, { | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Medium] Awaited network round trip now on the per-test hot path, with no timeout Under Mocha with defaults This also makes the PR body's "no extra API calls in the steady state" inaccurate for the non-reload case — it holds only when consecutive titles repeat. Mitigating, and worth saying: this is parity with the legacy non-CLI path — Suggestion: bound it with Reviewer: fallback independent reviewer |
||
| user: this.config.userName as string, | ||
| key: this.config.accessKey as string | ||
| }) | ||
| sessionData.appliedName = name | ||
|
Collaborator
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. [Medium] This records attempted, not applied — so a failed PUT disarms the final sweep
Failure scenario: the reload-per-test shape this PR targets puts one test per session. Test A's Suggestion: have Reviewer: fallback independent reviewer |
||
| this.sessionMap.set(sessionId, sessionData) | ||
| } | ||
|
|
||
| async onAfterTest(args: Record<string, unknown>) { | ||
|
|
@@ -180,9 +217,8 @@ export default class AutomateModule extends BaseModule { | |
| } | ||
| } | ||
|
|
||
| if (!testContextOptions.skipSessionName) { | ||
| await this.markSessionName(sessionId, sessionData.lastTestName, { user: userName, key: accessKey }) | ||
| } | ||
| // Final sweep — a no-op for sessions already named per-test in onBeforeTest. | ||
| await this.flushSessionName(sessionId) | ||
|
|
||
| if (!testContextOptions.skipSessionStatus) { | ||
| await this.markSessionStatus(sessionId, sessionStatus, failureReason, { user: userName, key: accessKey }) | ||
|
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
[Medium] The reload clause is contradicted by this PR's own evidence
The note credits the fix to "suites that reload the session between tests or whose run ends before the WebdriverIO
afterhook." Row 1 of your own evidence table disproves the first clause: 9.33.1 (shipped code),after()reached → 3 renames, correct per-test titles — on a build you describe as the customer's exact reload-per-test shape.The mechanism agrees:
onReloadrefreshesKEY_FRAMEWORK_SESSION_ID(service.ts:809-812), so each reloaded session already got its ownsessionMapentry and the old sweep already PUT a name for every one. Reload alone was never a failure mode. The real cause is solely the second clause — the worker never reachingafter()(service.ts:584is the onlyEXECUTE/POSTtrigger; the customer log showsEXECUTEtrackEvent = 0).This matters because it's the customer-facing release note: users who reload per test but do reach
after()would read this as fixing something that was never broken for them.Suggestion: drop the reload clause here and in the internal note. Or substantiate it — it would hold only if the Automate REST API refuses to rename a terminated session, which is worth confirming either way since it's a useful fact.
Reviewer: fallback independent reviewer