Author and run E2E tests on a cloud browser grid - BrowserStack Automate, Sauce Labs, or LambdaTest. All three follow one pattern: username + access-key env vars, a W3C WebDriver hub URL, a vendor options dict inside the capabilities (bstack:options / sauce:options / LT:Options), a local tunnel binary for internal apps, session pass/fail reporting, and a CI matrix throttled to the plan's parallel-session limit. Worked example uses BrowserStack; per-vendor deltas live in references/. Use for cross-browser regression on real devices + browsers beyond the engines bundled on the local machine - distinct from a local matrix runner and from self-hosted Selenium Grid.
72
90%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Passed
No findings from the security scan
Deep reference for cloud-grid-e2e. Consult when tuning the full
bstack:options set, running BrowserStackLocal, scaling parallel sessions,
or pulling session artifacts via REST.
BrowserStack Automate is a hosted Selenium / Playwright / Cypress grid exposing 3000+ real device + browser combinations (iOS, Android, Windows, macOS) via a WebDriver-compatible endpoint. Per browserstack.com/docs/automate/selenium. The umbrella skill covers the Selenium-style invocation; Playwright + Cypress integrations follow a different (but similar) pattern documented separately by BrowserStack.
export BROWSERSTACK_USERNAME="your-username"
export BROWSERSTACK_ACCESS_KEY="<access-key-from-account-settings>"Hub: https://hub-cloud.browserstack.com/wd/hub.
Standard W3C fields - browserName, browserVersion, platformName (or
BrowserStack's non-standard os + osVersion) - plus a bstack:options
block:
{
"browserName": "Chrome",
"browserVersion": "latest",
"os": "Windows",
"osVersion": "11",
"bstack:options": {
"projectName": "My App",
"buildName": "PR-1234",
"sessionName": "Login flow on Chrome Windows",
"local": "false"
}
}Per BrowserStack docs (browserstack.com/automate/capabilities, Cloudflare-protected; cite by stable URL):
| Option | Purpose |
|---|---|
projectName | Group sessions by project (dashboard organisation) |
buildName | Group sessions by build / CI run |
sessionName | Human-readable session label |
local | "true" if testing localhost / internal via BrowserStackLocal |
debug | Enable visual debugging (screenshots + DOM) |
networkLogs | Capture HAR file |
consoleLogs | "errors" / "warnings" / "info" / "verbose" |
video | Default "true" - session video recording |
seleniumVersion | Pin a Selenium version (e.g., "4.21.0") |
driver.execute_script(
'browserstack_executor: {"action": "setSessionStatus", '
'"arguments": {"status":"passed","reason":"..."}}'
)Per browserstack.com/local-testing/automate - start the tunnel and set
bstack:options.local = "true" on the session:
./BrowserStackLocal --key "$BROWSERSTACK_ACCESS_KEY" --daemon start
./BrowserStackLocal --key "$BROWSERSTACK_ACCESS_KEY" --daemon stopOr via Docker:
docker run --name bstacklocal -d --rm \
browserstack/local --key "$BROWSERSTACK_ACCESS_KEY"Plans limit parallel sessions (typically 5-50). 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)Session reports include: session video, network HAR (if networkLogs: true), browser console logs (per consoleLogs level), Selenium logs, and
visual-debugging screenshots at each command. Retrieve via REST:
curl -u "$BROWSERSTACK_USERNAME:$BROWSERSTACK_ACCESS_KEY" \
"https://api.browserstack.com/automate/sessions/<session-id>.json"Feed failure videos + HAR to the from-CI-failure workflow in
bug-report-template (qa-bug-repro plugin) for triage.
# .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/ --bstackMatch 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.