diff --git a/.changeset/pr-89.md b/.changeset/pr-89.md new file mode 100644 index 0000000..8941469 --- /dev/null +++ b/.changeset/pr-89.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- Read the `apis` service-URL map from the binary's new `config.sessionData` bucket (SDK-6821 session.config split), with the flat `config.apis` as backward-compat fallback. Single-point change in `setConfig`; verified `npm run build` clean and the vitest suite shows zero new failures vs main (68 pre-existing environmental failures identical on both). diff --git a/packages/browserstack-service/src/cli/index.ts b/packages/browserstack-service/src/cli/index.ts index 618ca48..b1b3cc3 100644 --- a/packages/browserstack-service/src/cli/index.ts +++ b/packages/browserstack-service/src/cli/index.ts @@ -529,6 +529,9 @@ export class BrowserstackCLI { setConfig(response: StartBinSessionResponse) { try { this.config = JSON.parse(response.config) + // Binary now nests apis under config.sessionData; prefer it, fall back to the flat config.apis (SDK-6821 Phase 3) + const sessionData = this.config.sessionData as { apis?: unknown } | undefined + this.config.apis = sessionData?.apis ?? this.config.apis const redactedConfig = JSON.parse(response.config) CrashReporter.recursivelyRedactKeysFromObject(redactedConfig, ['user', 'username', 'key', 'accesskey', 'password']) this.logger.debug(`loadModules: config=${JSON.stringify(redactedConfig)}`) diff --git a/packages/browserstack-service/tests/cli/index.test.ts b/packages/browserstack-service/tests/cli/index.test.ts index b8465df..d4415b8 100644 --- a/packages/browserstack-service/tests/cli/index.test.ts +++ b/packages/browserstack-service/tests/cli/index.test.ts @@ -93,4 +93,30 @@ describe('BrowserstackCLI bootstrap error surfacing', () => { expect(loggerErrorSpy).toHaveBeenCalledWith('[Build] ERROR_ACCESS_DENIED: Access to BrowserStack denied due to incorrect credentials.') }) }) + + // SDK-6821: apis arrives under the sessionData bucket (flat kept for backward + // compat until every SDK migrates). The bucket-only case is the Phase-4 shape — + // the one a broken hoist cannot mask via the flat fallback. + describe('setConfig sessionData apis hoist (SDK-6821)', () => { + const setConfigWith = (config: Record) => + instance.setConfig({ config: JSON.stringify(config) } as any) + + it('resolves apis from sessionData alone (future caps-only echo)', () => { + setConfigWith({ sessionData: { apis: { automate: { api: 'https://api.browserstack.com' } } } }) + expect(instance.config.apis).toEqual({ automate: { api: 'https://api.browserstack.com' } }) + }) + + it('prefers sessionData.apis over a stale flat apis', () => { + setConfigWith({ + apis: { automate: { api: 'https://stale.example' } }, + sessionData: { apis: { automate: { api: 'https://fresh.example' } } } + }) + expect(instance.config.apis).toEqual({ automate: { api: 'https://fresh.example' } }) + }) + + it('keeps the flat apis when no bucket is present (old binary)', () => { + setConfigWith({ apis: { automate: { api: 'https://flat-only.example' } } }) + expect(instance.config.apis).toEqual({ automate: { api: 'https://flat-only.example' } }) + }) + }) })