From fddde2a837ac0317d80f4ee8ab9b4cad1eec5df9 Mon Sep 17 00:00:00 2001 From: Harshit Date: Thu, 10 Sep 2026 00:54:07 +0530 Subject: [PATCH 1/4] fix(SDK-4165): keep buildIdentifier when BROWSERSTACK_BUILD_NAME is set MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit _handleBuildIdentifier skipped buildIdentifier resolution whenever BROWSERSTACK_BUILD_NAME was set, even though a buildName was available. The skip also deleted buildIdentifier from the capabilities only — this ._buildIdentifier kept the unresolved '#${BUILD_NUMBER}' template, which onPrepare forwards to TestHub as build_identifier. Consequence: successive runs sharing a build name were never disambiguated, so their sessions collapsed into a single build. The guard now keys solely on the absence of a buildName, which is what its own warning always claimed and what the binary's handleBuildIdentifier already does (its BROWSERSTACK_BUILD_NAME skip is commented out). The skip path additionally clears _buildIdentifier so the raw template is never reported as a value. Co-Authored-By: Claude Opus 5 (1M context) --- packages/browserstack-service/src/launcher.ts | 5 ++- .../tests/launcher.test.ts | 35 ++++++++++++++++++- 2 files changed, 38 insertions(+), 2 deletions(-) diff --git a/packages/browserstack-service/src/launcher.ts b/packages/browserstack-service/src/launcher.ts index 390e4e80..5f327bd0 100644 --- a/packages/browserstack-service/src/launcher.ts +++ b/packages/browserstack-service/src/launcher.ts @@ -1154,8 +1154,11 @@ export default class BrowserstackLauncherService implements Services.ServiceInst return } - if ((!this._buildName || process.env.BROWSERSTACK_BUILD_NAME) && this._buildIdentifier) { + if (!this._buildName) { this._updateCaps(capabilities, 'buildIdentifier') + // drop it here too: the raw '${BUILD_NUMBER}'/'${DATE_TIME}' template is never a + // usable value, and onPrepare forwards this field to TestHub as build_identifier + this._buildIdentifier = undefined BStackLogger.warn('Skipping buildIdentifier as buildName is not passed.') return } diff --git a/packages/browserstack-service/tests/launcher.test.ts b/packages/browserstack-service/tests/launcher.test.ts index 292cae42..4cf314ee 100644 --- a/packages/browserstack-service/tests/launcher.test.ts +++ b/packages/browserstack-service/tests/launcher.test.ts @@ -1329,7 +1329,7 @@ describe('_handleBuildIdentifier', () => { expect(caps[0]).toMatchObject(updatedcaps[0]) }) - it('should delete buildIdentifier if BROWSERSTACK_BUILD_NAME is defined as env var', async() => { + it('should delete buildIdentifier if buildName is absent from caps even when BROWSERSTACK_BUILD_NAME is set', async() => { process.env.BROWSERSTACK_BUILD_NAME = 'browserstack wdio build' const caps: any = [{ 'bstack:options': { @@ -1348,6 +1348,39 @@ describe('_handleBuildIdentifier', () => { delete process.env.BROWSERSTACK_BUILD_NAME }) + it('should still resolve buildIdentifier when buildName is in caps and BROWSERSTACK_BUILD_NAME is set', async() => { + process.env.BROWSERSTACK_BUILD_NAME = 'browserstack wdio build' + const caps: any = [{ + 'bstack:options': { + buildName: 'browserstack wdio build', + buildIdentifier: '#${BUILD_NUMBER}' + } + }] + const service = new BrowserstackLauncher(options as any, caps, config) + + vi.spyOn(utils, 'getCiInfo').mockReturnValueOnce(null) + vi.spyOn(service, '_getLocalBuildNumber').mockReturnValueOnce('3') + vi.spyOn(service, '_updateLocalBuildCache').mockImplementation(() => {}) + service._handleBuildIdentifier(caps) + + expect(caps[0]['bstack:options']?.buildIdentifier).toEqual('#3') + delete process.env.BROWSERSTACK_BUILD_NAME + }) + + it('should not retain an unresolved buildIdentifier template when the identifier is skipped', async() => { + const caps: any = [{ + 'bstack:options': { + buildIdentifier: '#${BUILD_NUMBER}' + } + }] + const service = new BrowserstackLauncher(options as any, caps, config) + + service._handleBuildIdentifier(caps) + + // onPrepare forwards this to TestHub as build_identifier; the raw template must not leak + expect(service._buildIdentifier).toBeUndefined() + }) + it('should not evaluate buildIdentifier if buildIdentifier is not present in the caps', async() => { const caps: any = [{}] const updatedcaps: any = [{ 'browserstack.wdioService': pkg.version }] From ce459fd7cd0d310ac233559b6cce01f6a221e16b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Wed, 9 Sep 2026 19:25:22 +0000 Subject: [PATCH 2/4] chore(changeset): auto-generate from PR template (patch) --- .changeset/pr-192.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pr-192.md diff --git a/.changeset/pr-192.md b/.changeset/pr-192.md new file mode 100644 index 00000000..387b643b --- /dev/null +++ b/.changeset/pr-192.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- Fixed `buildIdentifier` being ignored when the `BROWSERSTACK_BUILD_NAME` environment variable is set. Successive runs that share a build name are now reported as separate builds (`my-build #1`, `my-build #2`) instead of merging into one. From d3521bd6a7ab36a9393d86c689c8c1fcfabf694b Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Tue, 29 Sep 2026 14:31:35 +0000 Subject: [PATCH 3/4] chore(changeset): auto-generate from PR template (patch) --- .changeset/pr-254.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pr-254.md diff --git a/.changeset/pr-254.md b/.changeset/pr-254.md new file mode 100644 index 00000000..8eedc630 --- /dev/null +++ b/.changeset/pr-254.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- Drop branch for #253: resolves the `sdk_v9_pre_prod` conflict with #251 (SDK-4748) by taking #251's `launcher.ts` (it already contains the SDK-4165 fix) and adds two `_handleBuildIdentifier` tests (BUILD_NUMBER resolution with `BROWSERSTACK_BUILD_NAME` set; no unresolved template retained). Test-only net of `sdk_v9_pre_prod`. From 1da4d197caba1dcf917869bb1f6f5323dc6605a3 Mon Sep 17 00:00:00 2001 From: Harshit Date: Tue, 29 Sep 2026 20:02:15 +0530 Subject: [PATCH 4/4] chore: drop the auto-generated changeset (PR is labelled skip-changeset) Co-Authored-By: Claude Opus 5.5 --- .changeset/pr-254.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/pr-254.md diff --git a/.changeset/pr-254.md b/.changeset/pr-254.md deleted file mode 100644 index 8eedc630..00000000 --- a/.changeset/pr-254.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@wdio/browserstack-service": patch ---- - -- Drop branch for #253: resolves the `sdk_v9_pre_prod` conflict with #251 (SDK-4748) by taking #251's `launcher.ts` (it already contains the SDK-4165 fix) and adds two `_handleBuildIdentifier` tests (BUILD_NUMBER resolution with `BROWSERSTACK_BUILD_NAME` set; no unresolved template retained). Test-only net of `sdk_v9_pre_prod`.