Testland
Browse all skills & agents

cloud-grid-e2e

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.

Install with skills.sh (any agent)

npx skills add testland/qa --skill cloud-grid-e2e
View source

cloud-grid-e2e

Overview

A cloud grid is a hosted farm of real devices + browsers exposed through a W3C-compliant WebDriver endpoint. Point any WebDriver client (Selenium, WebdriverIO, Nightwatch) at the vendor's hub URL and the suite runs on combinations the local machine cannot host: real Safari on iOS, legacy browser versions, niche Android devices.

The three major vendors are isomorphic - the same suite moves between them by swapping four things:

ConcernBrowserStackSauce LabsLambdaTest
Auth env varsBROWSERSTACK_USERNAME + BROWSERSTACK_ACCESS_KEYSAUCE_USERNAME + SAUCE_ACCESS_KEYLT_USERNAME + LT_ACCESS_KEY
Hub URLhttps://hub-cloud.browserstack.com/wd/hubregional, e.g. https://ondemand.us-west-1.saucelabs.com:443/wd/hubhttps://hub.lambdatest.com/wd/hub
Vendor options dictbstack:optionssauce:optionsLT:Options
Local tunnelBrowserStackLocalSauce Connect ProxyLambdaTest Tunnel

Everything else is standard W3C capabilities (browserName, browserVersion, platformName) per w3.org/TR/webdriver2/ (opens in new window).

Vendor deep detail (full options tables, tunnel setup, REST artifact retrieval, CI matrix examples): references/browserstack.md · references/sauce-labs.md · references/lambdatest.md.

Composes with the sibling browser-matrix-strategy-reference for matrix planning.

When to use

  • Cross-browser regression across more breadth than Playwright's bundled engines support (real Safari iOS, legacy versions, niche Android devices).
  • Tier-1 browser matrix coverage backed by SLA.
  • Internal / localhost applications testable from the cloud via the vendor's tunnel binary.

For bundled-engine matrix (Chromium / Firefox / WebKit on the runner machine), use playwright-testing (references/browser-matrix.md). For a self-hosted grid (data residency, cost control), use the sibling selenium-grid-4-runner.

Choosing between the vendors: BrowserStack has the broadest real-device matrix and enterprise procurement; Sauce Labs suits Selenium-grid-centric parallel CI farms; LambdaTest is the cost-sensitive smaller-scale option. Full deltas in the per-vendor references.

How to use (the vendor-generic pattern)

  1. Export the vendor's username + access-key env vars from account settings.
  2. Point the WebDriver client at the vendor's hub URL.
  3. Build W3C capabilities and set the vendor options dict (bstack:options / sauce:options / LT:Options) on the Options object before creating the driver - set at minimum a project/build/session name triple so the dashboard groups sessions.
  4. Run the suite; report each session's pass / fail back to the vendor before driver.quit(), so dashboard metrics stay accurate.
  5. For localhost / internal targets, start the vendor's tunnel binary and flag the session as tunneled.
  6. In CI, run the browser matrix as jobs throttled to the plan's parallel-session limit.

Worked example (BrowserStack)

Run one Selenium suite on the grid end to end - build capabilities, create the remote driver, drive the test, report status, quit. Per browserstack.com/docs/automate/selenium (opens in new window):

import os
from selenium import webdriver

options = webdriver.SafariOptions()
options.browser_version = "17"

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

# Vendor caps must be set on Options BEFORE Remote(); driver.capabilities is a
# read-only result dict, so assigning to it afterwards is a no-op ([Selenium options]).
options.set_capability("bstack:options", bstack_options)

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=options,
)

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()

Every non-W3C capability - os, osVersion, projectName, buildName, sessionName, local - lives inside bstack:options; only the standard fields (browserName, browserVersion, platformName) sit at the top level (Selenium options (opens in new window)). Use "status":"failed","reason":"..." on failure.

The same shape on the other vendors: Sauce Labs reports status via driver.execute_script("sauce:job-result=passed") and LambdaTest via driver.execute_script("lambda-status=passed") - see the references.

Local tunnel (internal / localhost apps)

Each vendor ships a tunnel binary that lets grid sessions reach hosts on your network. BrowserStack example:

# 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

Sauce Connect (./sc --tunnel-name ... + sauce:options.tunnelName) and LambdaTest Tunnel (./LT --tunnelName ... + LT:Options.tunnel: true) are in the references. For ephemeral CI: spawn → wait-for-ready with a bounded timeout → run tests → terminate.

CI wiring and parallel limits

Run the browser matrix as CI jobs, one combination per job, with the credentials in secrets and buildName/build set to the PR identifier:

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

All three vendors cap concurrent sessions by plan tier; queue overflow blocks subsequent sessions until earlier ones complete. Throttle the worker pool (ThreadPoolExecutor(max_workers=N) or the CI matrix max-parallel key) to the plan limit, and tier the matrix per browser-matrix-strategy-reference so full runs stay inside it.

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 build/project name capsSessions un-grouped in dashboardAlways set build to the CI run / PR identifier
No session-status updateDashboard pass/fail rate inaccurateAlways report status before quit
Tunnel binary not stoppedStale tunnels accumulateAlways stop the daemon after the run
Parallel exceeds plan limitSessions queue + timeoutMatch worker pool to plan
Polling for tunnel-ready without timeoutSuite hangs if the tunnel never connectsBounded wait + fail
Hardcoded vendor URL in testsSwitching grids requires code changesEnv-var-driven hub URL + a small caps abstraction
Treating vendors as drop-in interchangeableOptions dicts differ (bstack:options vs sauce:options vs LT:Options)Isolate vendor caps in one harness module

Limitations

  • Cost. Plan tiers limit parallel sessions; full-matrix runs on every PR are expensive - tier the matrix.
  • Setup latency. Real-device sessions take 5-30s to start; not optimal for short feedback loops.
  • Network shape. Cloud-grid latency is higher than local; some timing-sensitive tests behave differently.
  • Device matrices churn. Vendors add + retire devices; tests pinned to specific versions need periodic updates.
  • Internal networks require the tunnel. Adds setup + tunnel-stability concerns.
  • Cypress does not speak WebDriver. Cloud grids run Cypress via vendor-specific runners (or Cypress Cloud), not the hub URL pattern here.

References

BrowserStack Automate - vendor detail

View source (opens in new window)

BrowserStack Automate - vendor detail

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 (opens in new window). The umbrella skill covers the Selenium-style invocation; Playwright + Cypress integrations follow a different (but similar) pattern documented separately by BrowserStack.

Auth + hub URL

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

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

Capabilities (W3C)

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"
  }
}

Full bstack:options table

Per BrowserStack docs (browserstack.com/automate/capabilities, Cloudflare-protected; cite by stable URL):

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")

Session status

driver.execute_script(
    'browserstack_executor: {"action": "setSessionStatus", '
    '"arguments": {"status":"passed","reason":"..."}}'
)

BrowserStackLocal

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 stop

Or via Docker:

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

Parallel session limits

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)

Parsing results

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.

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.

Vendor-specific limitations

  • Real-device sessions have 5-30s startup latency; build wait + retry around setup rather than treating the dashboard as live.
  • BrowserStack adds + retires devices; tests pinned to specific versions may need updates.

LambdaTest - vendor detail

View source (opens in new window)

LambdaTest - vendor detail

Deep reference for cloud-grid-e2e. LambdaTest is a newer cloud-grid provider with strong real-device coverage and a SmartUI visual-testing add-on; like the others it exposes a W3C-compliant endpoint. Per lambdatest.com/support/docs/getting-started-with-lambdatest-automation (opens in new window) (Cloudflare-protected; cite by stable URL).

Auth + hub URL

export LT_USERNAME="your-username"
export LT_ACCESS_KEY="<access-key>"

Hub: https://hub.lambdatest.com/wd/hub. Capabilities can be generated from the dashboard (lambdatest.com/capabilities-generator).

Capabilities (W3C)

{
  "browserName": "Chrome",
  "browserVersion": "latest",
  "platformName": "Windows 11",
  "LT:Options": {
    "user": "$LT_USERNAME",
    "accessKey": "$LT_ACCESS_KEY",
    "build": "PR-1234",
    "name": "Login flow on Chrome Windows",
    "project": "my-app"
  }
}

Full LT:Options table

OptionPurpose
user / accessKeyCredentials (alternative to env vars)
buildCI build / PR identifier
nameSession label
projectGroup sessions by project (dashboard)
selenium_versionPin Selenium version
w3cEnable W3C mode (default true)
consoleConsole-log level: "errors" / "warnings" / "info" / "verbose"
networkCapture HAR file
videoSession recording
visualPer-step screenshots
tunnel / tunnelNameLambdaTest Tunnel for internal apps
smartUI.projectLink to SmartUI visual-regression project

Python example

import os
from selenium import webdriver

options = webdriver.EdgeOptions()
options.browser_version = "latest"
options.platform_name = "Windows 11"

lt_options = {
    "user": os.environ["LT_USERNAME"],
    "accessKey": os.environ["LT_ACCESS_KEY"],
    "build": os.environ.get("BUILD_TAG", "local"),
    "name": "Checkout on Edge",
    "project": "my-app",
    "console": "errors",
    "network": True,
    "video": True,
}

# Vendor caps must be set on Options BEFORE Remote() ([Selenium options]).
options.set_capability("LT:Options", lt_options)

driver = webdriver.Remote(
    command_executor="https://hub.lambdatest.com/wd/hub",
    options=options,
)

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

# report pass / fail; LambdaTest's JS-executor pattern is "lambda-<command>=..."
failed = False
driver.execute_script("lambda-status=" + ("failed" if failed else "passed"))
driver.quit()

LambdaTest Tunnel

Per lambdatest.com/support/docs/lambda-tunnel - start the tunnel, then set LT:Options.tunnel: true and tunnelName: "my-tunnel":

./LT --user $LT_USERNAME --key $LT_ACCESS_KEY --tunnelName "my-tunnel"

SmartUI integration

SmartUI handles visual regression alongside the functional test (paid add-on; alternative to Percy / Chromatic in qa-visual-regression):

driver.execute_script("smartui.takeScreenshot=login-page")

Screenshots compare against a baseline; differences are flagged in the SmartUI dashboard. Approve the initial baseline or false positives flood reports.

Parsing results

Session reports: video (video: true), network HAR (network: true), console logs (console level), per-step screenshots (visual: true), SmartUI diffs (if configured). REST:

curl -u "$LT_USERNAME:$LT_ACCESS_KEY" \
  "https://api.lambdatest.com/automation/api/v1/sessions/<session-id>"

CI integration

on: pull_request
jobs:
  lambdatest:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        browser:
          - { name: Chrome, version: latest, platform: "Windows 11" }
          - { name: Firefox, version: latest, platform: "Windows 11" }
          - { name: Safari, version: "17", platform: "macOS Sonoma" }
    steps:
      - uses: actions/checkout@v6
      - name: Run on LambdaTest
        env:
          LT_USERNAME: ${{ secrets.LT_USERNAME }}
          LT_ACCESS_KEY: ${{ secrets.LT_ACCESS_KEY }}
          LT_BROWSER: ${{ matrix.browser.name }}
          LT_VERSION: ${{ matrix.browser.version }}
          LT_PLATFORM: ${{ matrix.browser.platform }}
          BUILD_TAG: pr-${{ github.event.pull_request.number }}
        run: pytest tests/e2e/ --lambdatest

Vendor-specific anti-patterns

Anti-patternWhy it failsFix
Confusing tunnel (boolean) with tunnelName (string)Tunnel won't activateSet both when using tunnel
Missing project fieldDashboard organisation suffersAlways set project
Non-W3C mode (w3c: false)Parity issues; future versions remove itKeep w3c: true (default)
SmartUI baseline never approvedFalse positives flood reportsApprove initial baseline; audit changes

Vendor-specific limitations

  • Smaller real-device matrix than BrowserStack (improving).
  • SmartUI requires additional licensing.
  • Thinner docs on edge cases than the older competitors.
  • Pricing is per-parallel-session vs per-minute; cost analysis depends on workload shape.

Sauce Labs - vendor detail

View source (opens in new window)

Sauce Labs - vendor detail

Deep reference for cloud-grid-e2e. Sauce Labs is one of the original cloud-grid providers, with a W3C-compliant WebDriver endpoint covering desktop + mobile browser combinations and strong Cypress / Playwright / Appium support. Per docs.saucelabs.com/dev/test-configuration-options (opens in new window).

Also worth knowing: running the same suite on Sauce + a second grid is a practical way to catch grid-specific flakes.

Auth + hub URLs (regional)

export SAUCE_USERNAME="oauth-...-..."
export SAUCE_ACCESS_KEY="<access-key-from-user-settings>"
US-West:    https://ondemand.us-west-1.saucelabs.com:443/wd/hub
US-East:    https://ondemand.us-east-4.saucelabs.com:443/wd/hub
EU-Central: https://ondemand.eu-central-1.saucelabs.com:443/wd/hub

Pick the region closest to your CI runner for lower latency. Each region has its own device matrix + availability; mixing regions in one run adds flake.

Capabilities (W3C)

{
  "browserName": "chrome",
  "browserVersion": "latest",
  "platformName": "Windows 11",
  "sauce:options": {
    "build": "PR-1234",
    "name": "Login flow on Chrome Windows",
    "username": "$SAUCE_USERNAME",
    "accessKey": "$SAUCE_ACCESS_KEY",
    "screenResolution": "1920x1080",
    "tunnelName": "my-internal-tunnel",
    "extendedDebugging": true,
    "capturePerformance": true,
    "recordVideo": true,
    "recordScreenshots": true,
    "tags": ["smoke", "e2e", "auth"]
  }
}
sauce:options fieldPurpose
username / accessKeyCredentials (can also be in URL)
buildGroup sessions by CI build
nameSession label in dashboard
screenResolutionDefault 1024x768; common: 1920x1080
tunnelNameSauce Connect tunnel reference (preferred over deprecated tunnelIdentifier)
extendedDebuggingEnable HAR + console + Selenium logs
capturePerformanceBrowser performance metrics
recordVideo / recordScreenshotsSession capture
tagsFree-form tags for filtering

browserVersion accepts "latest", "latest-1", etc. - version-relative pinning works across release cycles.

Python example

import os
from selenium import webdriver

options = webdriver.FirefoxOptions()
options.browser_version = "latest"
options.platform_name = "Windows 11"

sauce_options = {
    "build": os.environ.get("BUILD_TAG", "local"),
    "name": "Checkout flow Firefox",
    "username": os.environ["SAUCE_USERNAME"],
    "accessKey": os.environ["SAUCE_ACCESS_KEY"],
    "screenResolution": "1920x1080",
    "extendedDebugging": True,
}

# Vendor caps must be set on Options BEFORE Remote() ([Selenium options]).
options.set_capability("sauce:options", sauce_options)

driver = webdriver.Remote(
    command_executor="https://ondemand.us-west-1.saucelabs.com:443/wd/hub",
    options=options,
)

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

Session status

driver.execute_script("sauce:job-result=" + ("passed" if not failed else "failed"))

Or via REST API: PUT /rest/v1/{username}/jobs/{session_id}.

Sauce Connect Proxy

Per docs.saucelabs.com/secure-connections/sauce-connect-5 (opens in new window):

# Download Sauce Connect 5 from saucelabs.com
./sc \
  --username $SAUCE_USERNAME \
  --access-key $SAUCE_ACCESS_KEY \
  --tunnel-name "my-internal-tunnel" \
  --region us-west-1

Then set sauce:options.tunnelName: "my-internal-tunnel" in capabilities. Tunnel cleans up on Ctrl+C. For ephemeral CI: spawn → wait-for-ready → run tests → terminate. SC tunnel setup adds 10-30s to test start.

Parsing results

Session reports include: video (always - recordVideo: true default), network HAR (if extendedDebugging), browser console logs, Selenium logs, per-command screenshots (if recordScreenshots), performance metrics (if capturePerformance). Retrieve via REST (docs.saucelabs.com/dev/api):

curl -u "$SAUCE_USERNAME:$SAUCE_ACCESS_KEY" \
  "https://api.us-west-1.saucelabs.com/rest/v1/$SAUCE_USERNAME/jobs/<session-id>"

CI integration

on: pull_request
jobs:
  sauce:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        browser:
          - { name: chrome, version: latest, platform: "Windows 11" }
          - { name: safari, version: "17", platform: "macOS 14" }
          - { name: edge, version: latest, platform: "Windows 11" }
    steps:
      - uses: actions/checkout@v6
      - name: Run on Sauce Labs
        env:
          SAUCE_USERNAME: ${{ secrets.SAUCE_USERNAME }}
          SAUCE_ACCESS_KEY: ${{ secrets.SAUCE_ACCESS_KEY }}
          SAUCE_BROWSER: ${{ matrix.browser.name }}
          SAUCE_VERSION: ${{ matrix.browser.version }}
          SAUCE_PLATFORM: ${{ matrix.browser.platform }}
          BUILD_TAG: pr-${{ github.event.pull_request.number }}
        run: pytest tests/e2e/ --sauce

Vendor-specific anti-patterns

Anti-patternWhy it failsFix
Hardcoded regionCross-region latency adds 100ms+ per commandMatch region to CI runner location
tunnelIdentifier (deprecated)Newer SC versions emit warningsUse tunnelName
Mixed regions in one test runIncreases flakePick one region per run
recordVideo: false to "save money"Failed-session debugging hardKeep video for failed sessions at minimum

Vendor-specific limitations

  • Video / artifact retention is short on free / lower tiers (often 7 days); paid plans extend.

Related skills

browser-matrix-strategy-reference

Pure-reference for designing and reviewing a browser / OS / device test matrix from traffic data - the T1/T2/T3 tier-membership heuristics (T1 >=5% traffic, T2 1-5% or statutory, T3 <1% with customer demand), the traffic-share sources (own analytics, StatCounter, MDN browser-compat-data), a worked matrix template with tier-change log, the matrix review checklist (staleness, T1 oversize, below-threshold T1 entries, missing real-device coverage), how to justify dropping a legacy browser (IE11, old iOS Safari), and the compatibility budget (tier caps, CI cost formula, published support statement) in references/compatibility-budget.md. Use when designing an initial matrix, capping or publishing a support policy, running a quarterly re-tier review, or making the case to drop a browser. This is the WHAT-to-test strategy reference - to execute the matrix use playwright-testing browser projects (bundled engines), selenium-grid-4-runner (self-hosted), or cloud-grid-e2e (managed grids).

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.

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, mobile-web emulation via the `devices` catalog (viewport / DPR / touch per-device projects), the cross-browser matrix with branded channels (chrome / msedge) in references/browser-matrix.md, and GitHub Actions CI integration. Use for new test authoring, flakiness remediation, mobile-breakpoint regression, cross-browser matrix setup, and CI setup; for reviewing codegen output specifically, use a dedicated codegen-review pass.

selenium-grid-4-runner

Author and operate Selenium Grid 4 - self-hosted distributed WebDriver. Covers the six-component architecture (Router / Distributor / Session Map / Event Bus / New Session Queue / Node), standalone vs hub-and-node modes, the Docker-image stack (selenium/standalone-chrome, selenium/hub, selenium/node-chrome), node registration, session-queue tuning, and observability. Use for self-hosted cross-browser testing when data residency or cost-control require an on-prem grid. This is the self-hosted execution RUNNER - for the zero-infra alternative use playwright-testing browser projects (bundled engines); for managed cloud grids use cloud-grid-e2e (BrowserStack / Sauce Labs / LambdaTest); to decide WHICH browsers and tiers to run use browser-matrix-strategy-reference.

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.

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.