Testland
Browse all skills & agents

browserstack-automate

Author and run E2E tests on BrowserStack Automate - cloud grid covering 3000+ real device + browser combinations. Covers BROWSERSTACK_USERNAME + ACCESS_KEY auth, hub URL https://hub-cloud.browserstack.com/wd/hub, W3C capabilities + bstack:options (projectName, buildName, sessionName), BrowserStackLocal for testing against localhost / internal environments, parallel session limits, and CI integration. Use for cross-browser regression on real devices + browsers - distinct from running a single test framework locally, and from a matrix runner limited to the browser engines bundled on the local machine.

Install with skills.sh (any agent)

npx skills add testland/qa --skill browserstack-automate
View source

browserstack-automate

Overview

BrowserStack Automate is a hosted Selenium / Playwright / Cypress grid that exposes 3000+ real device + browser combinations (iOS, Android, Windows, macOS) via a standard WebDriver-compatible endpoint. Per browserstack.com/docs/automate/selenium (opens in new window).

This skill wraps BrowserStack for Selenium-style invocation; Playwright + Cypress integrations follow a different (but similar) pattern documented separately by BrowserStack.

Composes with browser-matrix-strategy-reference (in the qa-compatibility plugin) for matrix planning.

When to use

  • Cross-browser regression across more breadth than Playwright's bundled engines support (real Safari iOS, IE11 legacy, niche Android devices, etc.).
  • Tier-1 browser matrix coverage backed by SLA.
  • Local-network applications testable from the cloud grid via BrowserStackLocal.

For bundled-engine matrix (Chromium / Firefox / WebKit on the runner machine), use browser-matrix-runner. For orchestration across local + cloud grids, use a dedicated grid-orchestration layer.

How to use

  1. Export BROWSERSTACK_USERNAME + BROWSERSTACK_ACCESS_KEY from account settings.
  2. Point any WebDriver client (Selenium, WebdriverIO, Nightwatch) at the hub URL https://hub-cloud.browserstack.com/wd/hub.
  3. Build W3C capabilities with a bstack:options block (set projectName, buildName, sessionName), then run one suite end to end - see Worked example.
  4. Report each session's pass / fail status back before driver.quit(), so the dashboard metrics stay accurate.
  5. For localhost / internal targets, tunnel via BrowserStackLocal (below). For the full CI matrix workflow, parallel-session scaling, the exhaustive bstack:options table, and REST session retrieval, see references/ci-and-scaling.md.

Authentication

Per BrowserStack Automate docs, set env vars:

export BROWSERSTACK_USERNAME="your-username"
export BROWSERSTACK_ACCESS_KEY="<access-key-from-account-settings>"

Hub URL

https://hub-cloud.browserstack.com/wd/hub

Connect any WebDriver client (Selenium, WebdriverIO, Nightwatch) to this URL with the standard RemoteWebDriver-style construction.

Capabilities (W3C)

Standard W3C fields - browserName, browserVersion, platformName (or BrowserStack's non-standard os + osVersion) - plus a bstack:options block for BrowserStack-specific settings:

{
  "browserName": "Chrome",
  "browserVersion": "latest",
  "os": "Windows",
  "osVersion": "11",
  "bstack:options": {
    "projectName": "My App",
    "buildName": "PR-1234",
    "sessionName": "Login flow on Chrome Windows",
    "local": "false"
  }
}

The exhaustive bstack:options table (debug, networkLogs, consoleLogs, video, seleniumVersion, ...) is in references/ci-and-scaling.md.

Worked example

Run one Selenium suite on the grid end to end - build capabilities, create the remote driver, drive the test, report status, quit:

import os
from selenium import webdriver

caps = {
    "browserName": "Safari",
    "browserVersion": "17",
    "os": "OS X",
    "osVersion": "Sonoma",
    "bstack:options": {
        "projectName": "my-app",
        "buildName": os.environ.get("BUILD_TAG", "local-run"),
        "sessionName": "Checkout flow on Safari macOS",
        "local": "false",
    },
}

driver = webdriver.Remote(
    command_executor=(
        f"https://{os.environ['BROWSERSTACK_USERNAME']}:"
        f"{os.environ['BROWSERSTACK_ACCESS_KEY']}"
        f"@hub-cloud.browserstack.com/wd/hub"
    ),
    options=webdriver.SafariOptions(),  # base options
)
# inject capabilities
for k, v in caps.items():
    driver.capabilities[k] = v

driver.get("https://example.com")
# ... test ...

# mark the session pass / fail so the dashboard metrics are accurate
driver.execute_script(
    'browserstack_executor: {"action": "setSessionStatus", '
    '"arguments": {"status":"passed","reason":"Login redirected as expected"}}'
)
driver.quit()

(Modern WebDriver clients prefer constructing through options + a capabilities dict; consult the chosen client's docs.) Use "status":"failed","reason":"..." on failure - the session-status call drives the BrowserStack dashboard's pass / fail metrics + filtering.

Local testing (BrowserStackLocal)

To run tests against localhost / internal environments, start the tunnel and set bstack:options.local = "true" on the session:

# Download the BrowserStackLocal binary from browserstack.com
./BrowserStackLocal --key "$BROWSERSTACK_ACCESS_KEY" --daemon start
# Sessions with bstack:options.local = "true" now tunnel
./BrowserStackLocal --key "$BROWSERSTACK_ACCESS_KEY" --daemon stop

Or via Docker:

docker run --name bstacklocal -d --rm \
  browserstack/local --key "$BROWSERSTACK_ACCESS_KEY"

Anti-patterns

Anti-patternWhy it failsFix
Credentials in codeToken leakEnv vars / secret store
All tests on every browser comboSlow + expensive (plan-limited)Tier the matrix - see browser-matrix-strategy-reference
Missing buildNameSessions un-grouped in dashboardAlways set buildName to CI run / PR identifier
No session-status updateDashboard pass/fail rate inaccurateAlways set session status before quit
BrowserStackLocal not stoppedStale tunnels accumulateAlways daemon stop after test
Parallel exceeds plan limitSessions queue + timeoutMatch MAX_PARALLEL to plan
Treating real-device dashboard as liveBrowserStack sessions can have minute-level setup latencyBuild wait + retry around setup

Limitations

  • Cost. Plan tiers limit parallel sessions; full-matrix runs on every PR can be expensive - tier the matrix.
  • Setup latency. Real-device sessions have 5-30s startup; not optimal for short feedback loops.
  • Network shape. Cloud-grid latency is higher than local; some timing-sensitive tests behave differently.
  • Real-device matrix changes. BrowserStack adds + retires devices; tests pinned to specific versions may need updates.
  • Internal network requires BrowserStackLocal. Adds setup + tunnel-stability concerns.

References

BrowserStack Automate CI, scaling, and full capabilities

View source (opens in new window)

BrowserStack Automate CI, scaling, and full capabilities

Deep reference for browserstack-automate SKILL.md. Consult when wiring BrowserStack into CI, scaling parallel sessions to a plan limit, tuning the full bstack:options capability set, or pulling session artifacts via REST.

Full bstack:options table

Per BrowserStack docs (browserstack.com/automate/capabilities), bstack:options carries BrowserStack-specific settings:

OptionPurpose
projectNameGroup sessions by project (dashboard organisation)
buildNameGroup sessions by build / CI run
sessionNameHuman-readable session label
local"true" if testing localhost / internal via BrowserStackLocal
debugEnable visual debugging (screenshots + DOM)
networkLogsCapture HAR file
consoleLogs"errors" / "warnings" / "info" / "verbose"
videoDefault "true" - session video recording
seleniumVersionPin a Selenium version (e.g., "4.21.0")

Parallel session limits

BrowserStack plans limit parallel sessions (typically 5-50 per plan). Per their docs, queue overflow blocks subsequent sessions until earlier ones complete. Match the worker pool to the plan:

from concurrent.futures import ThreadPoolExecutor

MAX_PARALLEL = 5  # match plan

with ThreadPoolExecutor(max_workers=MAX_PARALLEL) as exe:
    for case in cases:
        exe.submit(run_case, case)

Parsing results

BrowserStack session reports include:

  • Session video (replay any failure)
  • Network HAR (if networkLogs: true)
  • Browser console logs (if consoleLogs: errors|warnings|info|verbose)
  • Selenium logs
  • Visual debugging (screenshots at each command)

Per the BrowserStack docs, retrieve sessions via REST API:

curl -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
  "https://api.browserstack.com/automate/sessions/<session-id>.json"

Feed failure videos + HAR to bug-report-from-failure (in the qa-defect-management plugin) for triage.

CI integration

# .github/workflows/cross-browser.yml
on: pull_request
jobs:
  bstack:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        browser:
          - { name: Chrome, version: latest, os: Windows, osVersion: "11" }
          - { name: Safari, version: "17", os: "OS X", osVersion: Sonoma }
          - { name: Firefox, version: latest, os: Windows, osVersion: "11" }
          - { name: Edge, version: latest, os: Windows, osVersion: "11" }
    steps:
      - uses: actions/checkout@v5
      - name: Run cross-browser tests
        env:
          BROWSERSTACK_USERNAME: ${{ secrets.BROWSERSTACK_USERNAME }}
          BROWSERSTACK_ACCESS_KEY: ${{ secrets.BROWSERSTACK_ACCESS_KEY }}
          BSTACK_BROWSER: ${{ matrix.browser.name }}
          BSTACK_VERSION: ${{ matrix.browser.version }}
          BSTACK_OS: ${{ matrix.browser.os }}
          BSTACK_OS_VERSION: ${{ matrix.browser.osVersion }}
          BUILD_TAG: pr-${{ github.event.pull_request.number }}
        run: pytest tests/e2e/ --bstack

Match the matrix breadth to a tiered plan - see browser-matrix-strategy-reference for how to tier the matrix so full runs stay within the plan's parallel-session limit.

Related skills

cypress-testing

Authors and improves Cypress E2E tests - installs Cypress, configures `cypress.config.ts`, authors `cy.*` command chains, refactors existing specs (`cy.wait(ms)` sleeps into assertions, repeated flows into `cy.session` custom commands), and debugs with the time-travel GUI; Cypress Cloud for parallel runs and recording. Use for both greenfield test authoring and improving hand-written specs already in the codebase. For automated refactor of raw Cypress Studio recordings specifically, use a dedicated codegen-review pass.

lambdatest-automate

Author and run E2E tests on LambdaTest - cloud grid for cross-browser + real-device testing with W3C WebDriver, Cypress, Playwright, and Appium support. Covers LT_USERNAME + LT_ACCESS_KEY auth, hub URL hub.lambdatest.com/wd/hub, W3C capabilities + LT:Options dict (build, name, project, smartUI, network, console, video, tunnel), LambdaTest Tunnel for internal apps. Use for cross-browser regression with LambdaTest as the cloud grid; complements BrowserStack + Sauce Labs.

playwright-testing

Authors and remediates Playwright E2E tests across Chromium, Firefox, WebKit - `npm init playwright@latest` scaffolding, `playwright.config.ts` browser projects, accessibility-first locators (`getByRole`/`getByLabelText`) to replace brittle CSS selectors, web-first assertions to eliminate `waitForTimeout` flakiness, Page Object pattern, trace viewer debugging, sharded parallel execution with merged HTML reporting, and GitHub Actions CI integration. Use for new test authoring, flakiness remediation, and CI setup; for reviewing codegen output specifically, use a dedicated codegen-review pass.

puppeteer-testing

Authors browser automation scripts using Puppeteer - Chrome / Chromium-only headless / headed automation, Page object via `page.*` API, network interception, PDF generation, screenshot capture, scraping. Distinct from Playwright (Puppeteer's older sibling, Chrome-only) - use Puppeteer for Chrome-only browser automation tasks (scraping, generating PDFs from HTML, screenshot pipelines) where Playwright's multi-browser support is unneeded overhead. Use when a project already depends on `puppeteer` / `puppeteer-core`, or when a Chrome-only script must emit PDFs, screenshots, or scraped data rather than assert on a page.

saucelabs-automate

Author and run E2E tests on Sauce Labs - cloud grid for cross-browser + real-device testing with W3C WebDriver, Cypress, Playwright, and Appium support. Covers SAUCE_USERNAME + SAUCE_ACCESS_KEY auth, regional hub URLs (us-west-1 / us-east-4 / eu-central-1), W3C capabilities, sauce:options dict (build, name, screenResolution, tunnelName), Sauce Connect Proxy for internal-environment testing. Use for cross-browser regression with Sauce Labs as the cloud grid; complements BrowserStack + LambdaTest as alternative providers.

selenium-testing

Authors Selenium WebDriver tests in any of its 6+ supported languages (Java, Python, JavaScript, C#, Ruby, Kotlin, PHP) - picks the appropriate language binding, configures WebDriver per browser, uses `By.*` locators with the team's accessibility-first preference where supported, runs locally + via Selenium Grid for distributed execution, parses results to JUnit XML. Use for legacy Selenium-locked stacks; new projects pick Playwright or Cypress.

testcafe-testing

Authors TestCafe E2E tests - `npm install testcafe`, fixture/test syntax, `Selector` API for queries, automatic-waits, no WebDriver required (TestCafe injects scripts via a proxy), supports any browser including remote / cloud farms. Use when the team prefers a no-WebDriver architecture and one of TestCafe's specific features (e.g., role-based auth) matters.

web-e2e-overview

Teaches web end-to-end testing from first principles: what browser-driven E2E covers and how it differs from unit and integration tests, a decision table for choosing between Playwright, Cypress, Selenium WebDriver, WebdriverIO, Puppeteer, TestCafe and the BrowserStack / Sauce Labs / LambdaTest cloud grids based on files already present in the repo, install and first-run commands for each, and the flakiness traps (fixed sleeps, CSS and XPath selectors, state shared between tests) that sink new suites. Use when a web application has no E2E coverage yet, when picking or replacing an E2E framework, or when a first browser test needs to go green end to end.

webdriverio-testing

Authors WebdriverIO E2E tests - `npm init wdio@latest` scaffolding, services architecture (sauce, browserstack, appium, devtools), reporters (spec, allure, junit), built-in Mocha/Jasmine/Cucumber framework integrations. WebdriverIO sits between Selenium (W3C protocol) and Playwright (modern API) - Selenium-protocol-compatible with rich plugin ecosystem. Use when the team needs WebDriver protocol + service-based device-farm integration.