diff --git a/.changeset/chilled-books-burn.md b/.changeset/chilled-books-burn.md new file mode 100644 index 000000000..de1c370f2 --- /dev/null +++ b/.changeset/chilled-books-burn.md @@ -0,0 +1,5 @@ +--- +'@web/test-runner-browserstack': minor +--- + +Allow to disable the local proxy for CI environments diff --git a/docs/docs/test-runner/browser-launchers/browserstack.md b/docs/docs/test-runner/browser-launchers/browserstack.md index 52cc49ce1..442078f77 100644 --- a/docs/docs/test-runner/browser-launchers/browserstack.md +++ b/docs/docs/test-runner/browser-launchers/browserstack.md @@ -70,6 +70,16 @@ export default { os_version: '7', }, }), + + browserstackLauncher({ + capabilities: { + ...sharedCapabilities, + browserName: 'Chrome', + os: 'Windows', + os_version: '10', + }, + local: false, // disables the local proxy + }), ], }; ``` @@ -81,3 +91,5 @@ The Browserstack launcher takes two properties, `capabilities` and `localOptions `capabilities` are the selenium capabilities used to configure the browser to launch in Browserstack. You can generate most of these on the Saucelabs. It must contain a `browserstack.user` and `browserstack.key` property to authenticate with Browserstack, as well as `name`, `build` and `project` to identify the test run. `localOptions` are options to configure the [browserstack-local](https://www.npmjs.com/package/browserstack-local) proxy. For most use cases, you don't need to configure this property. + +`local` is a property which, when set to `false`, disables the local proxy entirely. This can be particularly helpful in CI environment where you may not need to proxy local resources through Browserstack. diff --git a/packages/test-runner-browserstack/src/browserstackLauncher.ts b/packages/test-runner-browserstack/src/browserstackLauncher.ts index bf86abff8..6a19f5db1 100644 --- a/packages/test-runner-browserstack/src/browserstackLauncher.ts +++ b/packages/test-runner-browserstack/src/browserstackLauncher.ts @@ -11,15 +11,14 @@ import { export interface BrowserstackLauncherArgs { capabilities: Record; localOptions?: Partial; + local?: boolean } const REQUIRED_CAPABILITIES = ['name', 'browserstack.user', 'browserstack.key', 'project', 'build']; -const localIp = internalIp.v4.sync() as string; -if (!localIp) { - throw new Error('Can not determine the local IP.'); -} export class BrowserstackLauncher extends WebdriverLauncher { + private localIp?: string; + constructor( private capabilities: Record, public name: string, @@ -34,19 +33,35 @@ export class BrowserstackLauncher extends WebdriverLauncher { user: capabilities['browserstack.user'] as string, key: capabilities['browserstack.key'] as string, }); + + if (this.capabilities['browserstack.local']) { + this.localIp = internalIp.v4.sync() as string; + if (!this.localIp) { + throw new Error('Can not determine the local IP.'); + } + } } async initialize(config: TestRunnerCoreConfig) { - await registerBrowserstackLocal( - this, - this.capabilities['browserstack.key'] as string, - this.localOptions, - ); + if (this.capabilities['browserstack.local']) { + await registerBrowserstackLocal( + this, + this.capabilities['browserstack.key'] as string, + this.localOptions, + ); + } await super.initialize(config); } startSession(sessionId: string, url: string) { - return super.startSession(sessionId, url.replace(/(localhost|127\.0\.0\.1)/, localIp)); + if (url.includes('localhost') || url.includes('127.0.0.1')) { + if (!this.localIp) { + throw new Error('If you want to use a local domain, make sure to enable the browserstack.local capability.'); + } + url = url.replace(/(localhost|127\.0\.0\.1)/, this.localIp) + } + + return super.startSession(sessionId, url); } async startDebugSession() { @@ -55,7 +70,9 @@ export class BrowserstackLauncher extends WebdriverLauncher { stop() { const stopPromise = super.stop(); - unregisterBrowserstackLocal(this); + if (this.capabilities['browserstack.local']) { + unregisterBrowserstackLocal(this); + } return stopPromise; } } @@ -79,7 +96,7 @@ export function browserstackLauncher(args: BrowserstackLauncherArgs): BrowserLau const capabilities = { ...args.capabilities }; capabilities['timeout'] = 300; - capabilities['browserstack.local'] = true; + capabilities['browserstack.local'] = args.local ?? true; capabilities['browserstack.localIdentifier'] = localId; // we need to allow popups since we open new windows