From 88a9c37784252355c7ed0f8b8be89b3b18e3dafc Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Mon, 17 Aug 2026 16:16:03 +0530 Subject: [PATCH 1/7] fix(browserstack-service): honour BROWSERSTACK_LOCAL / BROWSERSTACK_LOCAL_IDENTIFIER (SDK-7075) The service resolved BrowserStack Local purely from the `wdio.conf.js` service options, so the SDK-wide `BROWSERSTACK_LOCAL` / `BROWSERSTACK_LOCAL_IDENTIFIER` env vars were silently dropped: no tunnel was launched and no `local` / `localIdentifier` capability reached the session, leaving every session with `isLocalEnabled: false`. Add `normalizeLocalEnvVariables()` and call it from the launcher constructor alongside the existing `normalizeTestReporting*` normalizers. The env var wins over `wdio.conf.js`, matching `updateConfigWithEnvVars` in browserstack-binary and `getObservabilityUser` / `getObservabilityKey` here. An identifier on its own still does not enable Local, mirroring `getLocalConfig()` in the binary. Co-Authored-By: Claude Opus 5 (1M context) --- .../sdk-7075-honour-local-env-vars-v8.md | 5 + .../browserstack-service/src/constants.ts | 6 + packages/browserstack-service/src/launcher.ts | 4 + packages/browserstack-service/src/util.ts | 31 +++- .../tests/launcher.test.ts | 132 +++++++++++++++++- 5 files changed, 176 insertions(+), 2 deletions(-) create mode 100644 .changeset/sdk-7075-honour-local-env-vars-v8.md diff --git a/.changeset/sdk-7075-honour-local-env-vars-v8.md b/.changeset/sdk-7075-honour-local-env-vars-v8.md new file mode 100644 index 0000000..9dca9d4 --- /dev/null +++ b/.changeset/sdk-7075-honour-local-env-vars-v8.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — and take precedence over `browserstackLocal` / `opts.localIdentifier` in `wdio.conf.js`, matching the other BrowserStack SDKs. An identifier on its own still does not enable Local. diff --git a/packages/browserstack-service/src/constants.ts b/packages/browserstack-service/src/constants.ts index 839033e..0f75ac9 100644 --- a/packages/browserstack-service/src/constants.ts +++ b/packages/browserstack-service/src/constants.ts @@ -129,6 +129,12 @@ export const BSTACK_A11Y_POLLING_TIMEOUT = 'BSTACK_A11Y_POLLING_TIMEOUT' // Whether session is a accessibility session export const BROWSERSTACK_ACCESSIBILITY = 'BROWSERSTACK_ACCESSIBILITY' +// Whether to route the session through a BrowserStack Local tunnel +export const BROWSERSTACK_LOCAL = 'BROWSERSTACK_LOCAL' + +// Identifier of the BrowserStack Local tunnel to bind the session to +export const BROWSERSTACK_LOCAL_IDENTIFIER = 'BROWSERSTACK_LOCAL_IDENTIFIER' + // Whether session is a test reporting session (new name) export const BROWSERSTACK_TEST_REPORTING = 'BROWSERSTACK_TEST_REPORTING' diff --git a/packages/browserstack-service/src/launcher.ts b/packages/browserstack-service/src/launcher.ts index 4db272e..1181eb4 100644 --- a/packages/browserstack-service/src/launcher.ts +++ b/packages/browserstack-service/src/launcher.ts @@ -44,6 +44,7 @@ import { mergeChromeOptions, normalizeTestReportingConfig, normalizeTestReportingEnvVariables, + normalizeLocalEnvVariables, isValidEnabledValue, isMultiRemoteCaps, validateSkipAppOverride @@ -98,6 +99,9 @@ export default class BrowserstackLauncherService implements Services.ServiceInst normalizeTestReportingConfig(this._options) normalizeTestReportingEnvVariables() + + //normalizing BrowserStack Local config from env variables + normalizeLocalEnvVariables(this._options) this.browserStackConfig = BrowserStackConfig.getInstance(_options, _config) if (Array.isArray(capabilities)) { capabilities diff --git a/packages/browserstack-service/src/util.ts b/packages/browserstack-service/src/util.ts index 11e1bdd..ce1d81f 100644 --- a/packages/browserstack-service/src/util.ts +++ b/packages/browserstack-service/src/util.ts @@ -47,7 +47,9 @@ import { APP_ALLY_ISSUES_ENDPOINT, TEST_REPORTING_PROJECT_NAME, CLI_DEBUG_LOGS_FILE, - WDIO_NAMING_PREFIX + WDIO_NAMING_PREFIX, + BROWSERSTACK_LOCAL, + BROWSERSTACK_LOCAL_IDENTIFIER } from './constants.js' import CrashReporter from './crash-reporter.js' import { BStackLogger } from './bstackLogger.js' @@ -1289,6 +1291,33 @@ export function normalizeTestReportingEnvVariables(){ } +/** + * Resolve BrowserStack Local settings from the environment onto the service options. + * + * `BROWSERSTACK_LOCAL` / `BROWSERSTACK_LOCAL_IDENTIFIER` are the SDK-wide env vars for Local + * (the `browserstackLocal` / `localIdentifier` entries of the binary's EnvCapsMapping). This + * service reads Local purely off the `wdio.conf.js` service options, so without this the env + * vars were silently dropped — no tunnel was launched and no `local` / `localIdentifier` + * capability reached the session (SDK-7075). + * + * The env var wins over `wdio.conf.js`, matching the binary's `updateConfigWithEnvVars` and + * `getObservabilityUser` / `getObservabilityKey` / `getObservabilityProject` below. + */ +export function normalizeLocalEnvVariables(_options: BrowserstackConfig & Options.Testrunner) { + if (!isUndefined(process.env[BROWSERSTACK_LOCAL])) { + _options.browserstackLocal = isTrue(process.env[BROWSERSTACK_LOCAL]) + } + + /** + * An identifier on its own must not turn Local on — enablement keys off `browserstackLocal` + * alone, the same way `getLocalConfig()` does in the binary. A stale + * `BROWSERSTACK_LOCAL_IDENTIFIER` left in a CI environment therefore stays inert. + */ + if (!isUndefined(process.env[BROWSERSTACK_LOCAL_IDENTIFIER])) { + _options.opts = { ..._options.opts, localIdentifier: process.env[BROWSERSTACK_LOCAL_IDENTIFIER] } + } +} + export function getObservabilityUser(options: BrowserstackConfig & Options.Testrunner, config: Options.Testrunner) { if (process.env.BROWSERSTACK_USERNAME) { return process.env.BROWSERSTACK_USERNAME diff --git a/packages/browserstack-service/tests/launcher.test.ts b/packages/browserstack-service/tests/launcher.test.ts index ec6b015..a01c969 100644 --- a/packages/browserstack-service/tests/launcher.test.ts +++ b/packages/browserstack-service/tests/launcher.test.ts @@ -2,7 +2,7 @@ import fs from 'node:fs' import os from 'node:os' import path from 'node:path' -import { describe, expect, it, vi, beforeEach } from 'vitest' +import { describe, expect, it, vi, beforeEach, afterEach } from 'vitest' // @ts-expect-error mock feature import { Local, mockStart } from 'browserstack-local' import got from 'got' @@ -617,6 +617,136 @@ describe('onPrepare', () => { }) }) +describe('onPrepare with BrowserStack Local env variables (SDK-7075)', () => { + const caps: any = [{}] + const config = { + user: 'foobaruser', + key: '12345678901234567890', + capabilities: [] + } + vi.spyOn(utils, 'launchTestSession').mockImplementation(() => {}) + vi.spyOn(utils, 'isBStackSession').mockImplementation(() => {return true}) + + beforeEach(() => { + delete process.env.BROWSERSTACK_LOCAL + delete process.env.BROWSERSTACK_LOCAL_IDENTIFIER + }) + + afterEach(() => { + delete process.env.BROWSERSTACK_LOCAL + delete process.env.BROWSERSTACK_LOCAL_IDENTIFIER + }) + + it('should start Local when BROWSERSTACK_LOCAL is set and the config says nothing', async () => { + process.env.BROWSERSTACK_LOCAL = 'true' + const service = new BrowserstackLauncher({ testObservability: false, percy: false } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeDefined() + expect(capabilities[0]['bstack:options']).toEqual({ local: true, 'testhubBuildUuid': buildHashedId, 'buildProductMap': productMap }) + }) + + it('should add the "localIdentifier" capability from BROWSERSTACK_LOCAL_IDENTIFIER', async () => { + process.env.BROWSERSTACK_LOCAL = 'true' + process.env.BROWSERSTACK_LOCAL_IDENTIFIER = 'local_identifier_TFnBzD' + const service = new BrowserstackLauncher({ testObservability: false, percy: false } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeDefined() + expect(capabilities[0]['bstack:options']).toEqual({ local: true, localIdentifier: 'local_identifier_TFnBzD', 'testhubBuildUuid': buildHashedId, 'buildProductMap': productMap }) + }) + + it('should add the "browserstack.localIdentifier" capability when no "bstack:options" is present', async () => { + process.env.BROWSERSTACK_LOCAL = 'true' + process.env.BROWSERSTACK_LOCAL_IDENTIFIER = 'local_identifier_TFnBzD' + const service = new BrowserstackLauncher({ testObservability: false, percy: false } as any, caps, config) + const capabilities = [{}] + + await service.onPrepare(config, capabilities) + + expect(capabilities[0]).toEqual({ 'browserstack.local': true, 'browserstack.localIdentifier': 'local_identifier_TFnBzD', 'browserstack.testhubBuildUuid': buildHashedId, 'browserstack.buildProductMap': productMap }) + }) + + it('should pass the identifier from BROWSERSTACK_LOCAL_IDENTIFIER to the Local binary', async () => { + process.env.BROWSERSTACK_LOCAL = 'true' + process.env.BROWSERSTACK_LOCAL_IDENTIFIER = 'local_identifier_TFnBzD' + const service = new BrowserstackLauncher({ testObservability: false, percy: false } as any, caps, config) + + await service.onPrepare(config, [{ 'bstack:options': {} }]) + + expect(mockStart).toHaveBeenCalledWith( + expect.objectContaining({ localIdentifier: 'local_identifier_TFnBzD' }), + expect.anything() + ) + }) + + it('should let BROWSERSTACK_LOCAL override browserstackLocal from the config', async () => { + process.env.BROWSERSTACK_LOCAL = 'true' + const service = new BrowserstackLauncher({ browserstackLocal: false, testObservability: false, percy: false } as any, caps, config) + + await service.onPrepare(config, [{ 'bstack:options': {} }]) + + expect(service.browserstackLocal).toBeDefined() + }) + + it('should let BROWSERSTACK_LOCAL=false override browserstackLocal from the config', async () => { + process.env.BROWSERSTACK_LOCAL = 'false' + const service = new BrowserstackLauncher({ browserstackLocal: true, testObservability: false, percy: false } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeUndefined() + expect(capabilities[0]['bstack:options']).not.toHaveProperty('local') + }) + + it('should let BROWSERSTACK_LOCAL_IDENTIFIER override opts.localIdentifier from the config', async () => { + process.env.BROWSERSTACK_LOCAL = 'true' + process.env.BROWSERSTACK_LOCAL_IDENTIFIER = 'from-env' + const service = new BrowserstackLauncher({ + browserstackLocal: true, + opts: { localIdentifier: 'from-config' }, + testObservability: false, + percy: false + } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(capabilities[0]['bstack:options']).toEqual({ local: true, localIdentifier: 'from-env', 'testhubBuildUuid': buildHashedId, 'buildProductMap': productMap }) + }) + + it('should not enable Local from BROWSERSTACK_LOCAL_IDENTIFIER alone', async () => { + process.env.BROWSERSTACK_LOCAL_IDENTIFIER = 'local_identifier_TFnBzD' + const service = new BrowserstackLauncher({ testObservability: false, percy: false } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeUndefined() + expect(capabilities[0]['bstack:options']).not.toHaveProperty('localIdentifier') + }) + + it('should keep honouring the config when no Local env variable is set', async () => { + const service = new BrowserstackLauncher({ + browserstackLocal: true, + opts: { localIdentifier: 'from-config' }, + testObservability: false, + percy: false + } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeDefined() + expect(capabilities[0]['bstack:options']).toEqual({ local: true, localIdentifier: 'from-config', 'testhubBuildUuid': buildHashedId, 'buildProductMap': productMap }) + }) +}) + describe('onComplete', () => { it('should do nothing if browserstack local is turned on, but not running', () => { const service = new BrowserstackLauncher({} as any, [{}] as any, {} as any) From 51fbefa443210cd18a2760b832e4eb34639d1d0e Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Mon, 17 Aug 2026 11:16:51 +0000 Subject: [PATCH 2/7] chore(changeset): auto-generate from PR template (patch) --- .changeset/pr-151.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pr-151.md diff --git a/.changeset/pr-151.md b/.changeset/pr-151.md new file mode 100644 index 0000000..cf1e655 --- /dev/null +++ b/.changeset/pr-151.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — matching the other BrowserStack SDKs. From e80df31a54eb10705186a383c35863b152cfa8aa Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Thu, 3 Sep 2026 17:26:49 +0530 Subject: [PATCH 3/7] fix(browserstack-service): only a literal false disables Local (SDK-7075) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `normalizeLocalEnvVariables()` resolved BROWSERSTACK_LOCAL with `isTrue()`, which matches only the literal string "true". Every other set value — `1`, `yes` — resolved to `false`, and because the env var takes precedence over `wdio.conf.js`, that silently switched OFF a tunnel `browserstackLocal: true` had switched on. Pre-fix the config won and the tunnel started, so this was a regression. It also inverted the cross-SDK parity the change exists to provide. The binary stores the raw env string (core/config/env.js getEnvCaps), coerces only 'true'/'false' (core/config/index.js updateConfigWithBooleanValues) and then truthiness-checks it in getLocalConfig(), so BROWSERSTACK_LOCAL=1 enables Local on every other SDK. `!isFalse()` reproduces those semantics exactly for every set value; the empty string is still caught by the existing isUndefined() guard, so an exported-but-empty var cannot disable a config-enabled tunnel. Tests: 8 new cases in launcher.test.ts (130 total, was 122). Non-vacuous — restoring isTrue() fails 3 of them ('1', 'yes', and the config-enabled-tunnel regression guard). 45/45 test files pass; tsc -p tsconfig.prod.json clean. Co-Authored-By: Claude Opus 5 (1M context) --- .../sdk-7075-honour-local-env-vars-v8.md | 2 +- packages/browserstack-service/src/util.ts | 13 ++++++- .../tests/launcher.test.ts | 39 +++++++++++++++++++ 3 files changed, 52 insertions(+), 2 deletions(-) diff --git a/.changeset/sdk-7075-honour-local-env-vars-v8.md b/.changeset/sdk-7075-honour-local-env-vars-v8.md index 9dca9d4..d5720ae 100644 --- a/.changeset/sdk-7075-honour-local-env-vars-v8.md +++ b/.changeset/sdk-7075-honour-local-env-vars-v8.md @@ -2,4 +2,4 @@ "@wdio/browserstack-service": patch --- -- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — and take precedence over `browserstackLocal` / `opts.localIdentifier` in `wdio.conf.js`, matching the other BrowserStack SDKs. An identifier on its own still does not enable Local. +- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — and take precedence over `browserstackLocal` / `opts.localIdentifier` in `wdio.conf.js`, matching the other BrowserStack SDKs. Only a literal `BROWSERSTACK_LOCAL=false` disables Local; any other set value enables it, so `BROWSERSTACK_LOCAL=1` behaves the same here as on every other SDK. An identifier on its own still does not enable Local. diff --git a/packages/browserstack-service/src/util.ts b/packages/browserstack-service/src/util.ts index ce1d81f..e18e211 100644 --- a/packages/browserstack-service/src/util.ts +++ b/packages/browserstack-service/src/util.ts @@ -1305,7 +1305,18 @@ export function normalizeTestReportingEnvVariables(){ */ export function normalizeLocalEnvVariables(_options: BrowserstackConfig & Options.Testrunner) { if (!isUndefined(process.env[BROWSERSTACK_LOCAL])) { - _options.browserstackLocal = isTrue(process.env[BROWSERSTACK_LOCAL]) + /** + * Only a literal `false` disables Local — any other set value enables it. This is the + * binary's semantics, not a looser reading of it: `updateConfigWithBooleanValues` + * coerces only `'true'`/`'false'` and leaves every other string as-is, and + * `getLocalConfig()` then truthiness-checks the result. So `BROWSERSTACK_LOCAL=1` + * enables Local on every other SDK, and must here too. + * + * Using `isTrue()` instead would resolve `1` / `yes` to `false` and — because the env + * var wins — would silently switch OFF a tunnel that `browserstackLocal: true` in + * `wdio.conf.js` had switched on. + */ + _options.browserstackLocal = !isFalse(process.env[BROWSERSTACK_LOCAL]) } /** diff --git a/packages/browserstack-service/tests/launcher.test.ts b/packages/browserstack-service/tests/launcher.test.ts index a01c969..a8888b3 100644 --- a/packages/browserstack-service/tests/launcher.test.ts +++ b/packages/browserstack-service/tests/launcher.test.ts @@ -720,6 +720,45 @@ describe('onPrepare with BrowserStack Local env variables (SDK-7075)', () => { expect(capabilities[0]['bstack:options']).toEqual({ local: true, localIdentifier: 'from-env', 'testhubBuildUuid': buildHashedId, 'buildProductMap': productMap }) }) + /** + * The binary coerces only 'true'/'false' and truthiness-checks the rest, so every + * other SDK enables Local on `BROWSERSTACK_LOCAL=1`. Resolving these to `false` here + * would both diverge from that and — since env wins — switch OFF a tunnel the config + * had switched on. + */ + it.each(['1', 'yes', 'TRUE', 'True'])('should enable Local for the set value %s', async (value) => { + process.env.BROWSERSTACK_LOCAL = value + const service = new BrowserstackLauncher({ testObservability: false, percy: false } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeDefined() + expect(capabilities[0]['bstack:options']).toHaveProperty('local', true) + }) + + it('should not let a non-"false" value switch off a config-enabled tunnel', async () => { + process.env.BROWSERSTACK_LOCAL = '1' + const service = new BrowserstackLauncher({ browserstackLocal: true, testObservability: false, percy: false } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeDefined() + expect(capabilities[0]['bstack:options']).toHaveProperty('local', true) + }) + + it.each(['false', 'FALSE', 'False'])('should disable Local for the literal %s', async (value) => { + process.env.BROWSERSTACK_LOCAL = value + const service = new BrowserstackLauncher({ browserstackLocal: true, testObservability: false, percy: false } as any, caps, config) + const capabilities = [{ 'bstack:options': {} }] + + await service.onPrepare(config, capabilities) + + expect(service.browserstackLocal).toBeUndefined() + expect(capabilities[0]['bstack:options']).not.toHaveProperty('local') + }) + it('should not enable Local from BROWSERSTACK_LOCAL_IDENTIFIER alone', async () => { process.env.BROWSERSTACK_LOCAL_IDENTIFIER = 'local_identifier_TFnBzD' const service = new BrowserstackLauncher({ testObservability: false, percy: false } as any, caps, config) From b10f1fcb97f45ffad804bfa9aed748787779a15e Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Thu, 3 Sep 2026 18:32:17 +0530 Subject: [PATCH 4/7] chore(changeset): drop the duplicate auto-generated changeset (SDK-7075) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit `.changeset/pr-151.md` (auto-generated by github-actions[bot] in 51fbefa from the PR template) and `.changeset/sdk-7075-honour-local-env-vars-v8.md` are both `patch` changesets for `@wdio/browserstack-service`, so `changeset version` would emit two near-identical bullets in the v8 CHANGELOG for one fix. Keep the hand-written one — it documents the env-over-config precedence and the false-only-disables semantics, which the generated copy omits. Co-Authored-By: Claude Opus 5 (1M context) --- .changeset/pr-151.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/pr-151.md diff --git a/.changeset/pr-151.md b/.changeset/pr-151.md deleted file mode 100644 index cf1e655..0000000 --- a/.changeset/pr-151.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@wdio/browserstack-service": patch ---- - -- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — matching the other BrowserStack SDKs. From 05f95b46e4437ce019c287f4a43546d1f73f121d Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:03:09 +0000 Subject: [PATCH 5/7] chore(changeset): auto-generate from PR template (patch) --- .changeset/pr-151.md | 5 +++++ 1 file changed, 5 insertions(+) create mode 100644 .changeset/pr-151.md diff --git a/.changeset/pr-151.md b/.changeset/pr-151.md new file mode 100644 index 0000000..cf1e655 --- /dev/null +++ b/.changeset/pr-151.md @@ -0,0 +1,5 @@ +--- +"@wdio/browserstack-service": patch +--- + +- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — matching the other BrowserStack SDKs. From 047ba25d5cafa948284c986c20e62735b2c5dab0 Mon Sep 17 00:00:00 2001 From: "github-actions[bot]" <41898282+github-actions[bot]@users.noreply.github.com> Date: Thu, 3 Sep 2026 13:24:48 +0000 Subject: [PATCH 6/7] chore(changeset): auto-generate from PR template (patch) --- .changeset/pr-151.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.changeset/pr-151.md b/.changeset/pr-151.md index cf1e655..d5720ae 100644 --- a/.changeset/pr-151.md +++ b/.changeset/pr-151.md @@ -2,4 +2,4 @@ "@wdio/browserstack-service": patch --- -- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — matching the other BrowserStack SDKs. +- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — and take precedence over `browserstackLocal` / `opts.localIdentifier` in `wdio.conf.js`, matching the other BrowserStack SDKs. Only a literal `BROWSERSTACK_LOCAL=false` disables Local; any other set value enables it, so `BROWSERSTACK_LOCAL=1` behaves the same here as on every other SDK. An identifier on its own still does not enable Local. From 46e012fc4b9b57ef43808218d9d3c71caeeb3214 Mon Sep 17 00:00:00 2001 From: Shivam Kumar Date: Thu, 3 Sep 2026 18:55:02 +0530 Subject: [PATCH 7/7] chore(changeset): keep only the bot-generated changeset (SDK-7075) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Reverses b10f1fc, which deleted the wrong one. `.changeset/pr-151.md` is generated by github-actions[bot] verbatim from the PR body's "Release notes (customer-facing)" section and is regenerated on every push — so deleting it does not stick, and holding a second hand-written changeset for the same package means `changeset version` emits two near-identical bullets in the v8 CHANGELOG for one fix. The full release note (env-over-config precedence, false-only-disables, identifier alone does not enable) now lives in that PR body section, so the generated changeset carries it. Co-Authored-By: Claude Opus 5 (1M context) --- .changeset/sdk-7075-honour-local-env-vars-v8.md | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 .changeset/sdk-7075-honour-local-env-vars-v8.md diff --git a/.changeset/sdk-7075-honour-local-env-vars-v8.md b/.changeset/sdk-7075-honour-local-env-vars-v8.md deleted file mode 100644 index d5720ae..0000000 --- a/.changeset/sdk-7075-honour-local-env-vars-v8.md +++ /dev/null @@ -1,5 +0,0 @@ ---- -"@wdio/browserstack-service": patch ---- - -- Fixed `BROWSERSTACK_LOCAL` and `BROWSERSTACK_LOCAL_IDENTIFIER` being ignored. Both env vars now configure BrowserStack Local — the tunnel is launched and the `local` / `localIdentifier` capabilities reach the session — and take precedence over `browserstackLocal` / `opts.localIdentifier` in `wdio.conf.js`, matching the other BrowserStack SDKs. Only a literal `BROWSERSTACK_LOCAL=false` disables Local; any other set value enables it, so `BROWSERSTACK_LOCAL=1` behaves the same here as on every other SDK. An identifier on its own still does not enable Local.