How to Run BrowserStack & Sauce Labs Tests in CI
BrowserStack and Sauce Labs run browsers in their cloud, so the CI work is credentials and - for testing a locally served app - a secure tunnel back to the runner.
Both services execute your WebDriver/Playwright tests on remote browsers, so you do not install browsers on the runner. In CI you provide the access credentials as secrets and, when testing an app served on the runner (localhost), start the local tunnel (BrowserStack Local / Sauce Connect) so the remote browser can reach it.
Why it fails in CI
Missing credentials (BROWSERSTACK_USERNAME/BROWSERSTACK_ACCESS_KEY or SAUCE_USERNAME/SAUCE_ACCESS_KEY) fail authentication. When your app is served only on the runner’s localhost, the remote cloud browser cannot reach it without a tunnel, so tests time out connecting. Forked PRs cannot read the secrets.
Install & run it reliably
Set credentials from secrets and start the tunnel before tests when targeting a local app. The official setup actions handle the tunnel binary.
# BrowserStack Local tunnel for a localhost app
- uses: browserstack/github-actions/setup-local@master
with:
local-testing: start
local-identifier: ${{ github.run_id }}
- run: npm test
env:
BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
# Sauce Labs: use saucelabs/sauce-connect-action similarlyCache & speed
No local browser binaries to cache - the browsers run in the cloud, so cache only node_modules/~/.npm. Use a unique tunnel identifier per run (e.g. github.run_id) so concurrent CI jobs do not collide on one tunnel, and parallelize across the provider’s grid rather than relaunching browsers locally.
Common errors
- Auth/401 errors → set the username and access-key secrets for the provider.
- Remote browser cannot reach
localhost→ start BrowserStack Local / Sauce Connect. - Tunnel collisions between concurrent jobs → use a unique
local-identifier/tunnel name per run. - Forked PR has no credentials → gate cross-browser jobs to same-repo runs.
Key takeaways
- Provide the provider username + access-key secrets.
- Start the local tunnel (BrowserStack Local / Sauce Connect) for localhost apps.
- Use a unique tunnel identifier per run; no local browsers to cache.