diff --git a/.changeset/pr-192.md b/.changeset/pr-192.md new file mode 100644 index 0000000..387b643 --- /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. diff --git a/packages/browserstack-service/src/launcher.ts b/packages/browserstack-service/src/launcher.ts index 390e4e8..5f327bd 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 292cae4..4cf314e 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 }]