How to Run Playwright and Puppeteer Tests on BrowserStack
Configure Playwright or Puppeteer to run on BrowserStack Automate, choose browser and OS targets, handle parallel runs, and troubleshoot remote test results.
To run tests on BrowserStack, use BrowserStack Automate with the setup route for your framework: Playwright’s documented sample repository and environment variables, or Puppeteer’s remote Chrome DevTools Protocol (CDP) connection. Choose browser and operating system targets from the framework-specific support table. For Puppeteer, explicitly report each session’s pass or fail status with BrowserStack’s executor command; a successful connection alone does not report the test result.
This guide covers both routes, parallel runs, private applications, diagnostics, and common failures. The examples use JavaScript and Node.js because that is how the cited BrowserStack samples are configured. Browser, OS, and framework support changes over time, so treat the linked live support tables as authoritative.
1. Choose the BrowserStack route for your framework
| Question | Playwright | Puppeteer |
|---|---|---|
| How does the documented route connect? | Clone BrowserStack’s Playwright sample, install its dependencies, set credentials, and run the sample script. | Connect using puppeteer.connect() to BrowserStack’s CDP endpoint with encoded browser and OS capabilities. |
| How do you adapt an existing suite? | Use BrowserStack’s sample as a starting point and map your project’s test setup to the documented integration pattern. | Connect individual scripts to the endpoint, or use BrowserStack’s Node SDK guide for an existing Jest-based suite. |
| How do browser names work? | Use the Playwright support table; branded Chrome and Edge targets differ from Playwright’s bundled Chromium, Firefox, and WebKit identifiers. | Use the Puppeteer support table and its supported capability names and values. |
| How is pass or fail reported? | Follow the sample’s result reporting and inspect the Automate session in the dashboard. | Assertions run on the client; send an executor command from the test to mark the remote session passed or failed. |
BrowserStack hosts the browser and operating system session. Your test runner and assertions remain part of your project’s workflow. Start with the route that matches the framework already used by your tests; do not copy capability names from one framework’s table into the other.
2. Run the documented Playwright sample
BrowserStack’s parallel Playwright guide documents a sample repository flow. This is a sample-project command sequence, not a universal command for every Playwright repository.
- Clone BrowserStack’s Playwright sample repository and enter its directory.
- Install the repository’s dependencies using its package manager and lockfile.
- Set
BROWSERSTACK_USERNAMEandBROWSERSTACK_ACCESS_KEYin the environment used to run the test. - Run the documented sample script with
node parallel_test.js. - Open the BrowserStack Automate dashboard and inspect the completed sessions and their results.
git clone https://github.com/browserstack/playwright-browserstack
cd playwright-browserstack
npm install
# Set these in your shell or CI secret environment; do not commit credentials.
export BROWSERSTACK_USERNAME="YOUR_USERNAME"
export BROWSERSTACK_ACCESS_KEY="YOUR_ACCESS_KEY"
node parallel_test.js
On Windows PowerShell, set the variables for the current session with $env:BROWSERSTACK_USERNAME="YOUR_USERNAME" and $env:BROWSERSTACK_ACCESS_KEY="YOUR_ACCESS_KEY", then run the same Node command. In CI, add both values as protected secrets and expose them to the job that launches tests.
Pick Playwright browser and OS targets
Before expanding the sample into a matrix, consult BrowserStack’s Playwright supported versions, browsers, and OS table. It lists supported Playwright framework versions, OS values, browser names and versions, and device names. Pay attention to the distinction between branded Chrome or Edge and Playwright’s bundled browser identifiers. Availability changes, so do not assume a browser version or operating system from an old example remains supported.
Choose a small set of targets that represents the browsers and operating systems your users actually rely on. Add targets for known compatibility risks, critical customer segments, or release requirements. Record the selected combinations alongside the project’s supported-browser policy so that failures can be interpreted against an intentional test matrix.
3. Connect Puppeteer to BrowserStack Automate
The BrowserStack Puppeteer sample connects to the remote browser through the CDP endpoint wss://cdp.browserstack.com/puppeteer. It does not launch a remote browser locally. The connection URL carries encoded capabilities that select a supported browser, browser version, OS, and OS version.
Set BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY in the environment. The following is a runnable-shaped Node.js example of the documented connection and status-reporting pattern; use the exact capability names and values from the current Puppeteer support table and align the target page and assertions with your application.
import puppeteer from 'puppeteer';
const username = process.env.BROWSERSTACK_USERNAME;
const accessKey = process.env.BROWSERSTACK_ACCESS_KEY;
if (!username || !accessKey) {
throw new Error('Set BROWSERSTACK_USERNAME and BROWSERSTACK_ACCESS_KEY');
}
const capabilities = {
browser: 'chrome',
browser_version: 'latest',
os: 'Windows',
os_version: '11',
name: 'Puppeteer remote smoke test'
};
const encodedCapabilities = Buffer
.from(JSON.stringify(capabilities))
.toString('base64');
const endpoint = `wss://${username}:${accessKey}@cdp.browserstack.com/puppeteer?caps=${encodedCapabilities}`;
const browser = await puppeteer.connect({ browserWSEndpoint: endpoint });
let passed = false;
let page;
try {
page = await browser.newPage();
await page.goto('https://example.com', { waitUntil: 'domcontentloaded' });
const title = await page.title();
if (!title.includes('Example Domain')) {
throw new Error(`Unexpected page title: ${title}`);
}
passed = true;
} finally {
if (page) {
const status = passed ? 'passed' : 'failed';
const reason = passed ? 'Assertions passed' : 'Test failed; inspect client logs';
const command = `browserstack_executor: ${JSON.stringify({
action: 'setSessionStatus',
arguments: { status, reason }
})}`;
try {
await page.evaluate(command => window.browserstack_executor(command), command);
} finally {
await browser.close();
}
} else {
await browser.close();
}
}
The executor call is essential to the documented Puppeteer workflow: because assertions execute on the client side, BrowserStack cannot infer their result just from the remote browser session. The example attempts to report failure as well as success when a page was created. Preserve this status update in your own cleanup logic, including when assertions throw. See BrowserStack’s Puppeteer sample build quickstart for the current sample details.
Use the Node SDK for an existing Jest suite
For an existing Jest-based Puppeteer suite, BrowserStack documents an SDK integration route. Its guide describes installing browserstack-node-sdk as a development dependency, running npx setup to generate browserstack.yml, selecting supported platforms in that configuration, then running the suite through the SDK. The guide lists Node.js 14 or later and npm as prerequisites; verify the live integration guide for current requirements and commands before wiring this into CI.
npm install --save-dev browserstack-node-sdk
npx setup
# Edit the generated browserstack.yml with supported platform targets.
# Run the Jest suite using the command specified by the current SDK guide.
The SDK setup is an integration alternative for the documented Jest use case; it is not a substitute for checking which browser and OS combinations Puppeteer Automate currently supports.
4. Configure a useful browser matrix and parallel runs
A matrix is a collection of browser and OS combinations. In the Puppeteer sample, each capability entry represents a remote session; the Playwright sample supports running sessions in parallel. Parallelism can reduce elapsed time when sessions actually run concurrently, but the account’s allowed concurrency governs that limit.
- List the browsers and operating systems your product officially supports.
- Choose representative combinations from the relevant framework’s live support table.
- Keep a fast, small smoke matrix for frequent changes and run broader coverage when the release process calls for it.
- Check your BrowserStack account’s concurrency entitlement; do not equate the number of configured targets with simultaneous sessions.
- Inspect each session separately when a matrix job reports mixed results.
Do not hard-code a claimed maximum concurrency or assume that adding matrix entries makes a build faster. Actual elapsed time depends on the account limit, suite duration, and queued or available sessions; the research does not establish a benchmark or pricing for these runs.
5. Test a private or locally hosted application
For a private site or an app hosted on a developer’s machine, BrowserStack’s Puppeteer getting-started material says to establish a secure Local Testing tunnel before the remote session accesses the app. The tunnel provides the remote browser with a path to the otherwise inaccessible application.
Follow BrowserStack’s dedicated Local Testing instructions for the current setup, download, flags, and lifecycle. The applicable command depends on the environment; do not copy a tunnel invocation from another setup without checking that guide. Confirm the tunnel is connected before starting the browser session, and keep its process alive for the full test run.
6. Diagnose results and failed sessions
BrowserStack provides debugging artifacts such as logs, console output, video, and network information through the dashboard or API. Start with the session’s artifacts and separate a test assertion failure from a browser launch, connection, tunnel, or page-load failure.
- Open the failed session in the Automate dashboard and confirm the selected browser and OS target.
- Read the test output and client-side logs to identify the first failed assertion or exception.
- Check console and network details for application errors, missing resources, authentication redirects, or blocked requests.
- Review session video and logs to see whether navigation completed and whether the expected UI appeared.
- For Puppeteer, check that the executor status command ran even on assertion failure.
- For private apps, verify Local Testing was connected throughout the session.
These artifacts answer different questions: test output describes the assertion; browser logs and network data provide context; video helps reconstruct what appeared in the remote session. Use the BrowserStack overview pages for the relevant framework: Playwright Automate and Puppeteer Automate.
7. Common errors and fixes
| Symptom | Likely cause | What to check or fix |
|---|---|---|
| Authentication or WebSocket connection is rejected | Credentials are missing, misspelled, or not present in the process environment. | Check both environment variable names in the same shell or CI job that starts Node. Confirm the account credentials and avoid printing the access key in logs. |
| The remote browser cannot be created | A browser, OS, version, or capability value is unsupported or incorrectly named. | Copy current values from the Puppeteer or Playwright support page for the framework in use; do not reuse a target from the other framework’s table. |
| Playwright sample command or files are missing | The command was run outside the sample repository, or the local project was assumed to have BrowserStack’s sample script. | For the documented sample route, enter the cloned repository, install its dependencies, and run its documented script. Adapt other projects using their own scripts and the current integration guide. |
| Puppeteer session shows an incorrect or unset result | Assertions ran on the client, but no executor status update was sent, or cleanup skipped it after an exception. | Send the BrowserStack executor command on both success and failure paths, and inspect client logs if the test itself threw. |
| Remote browser loads a public page but not a private app | The app is inaccessible from BrowserStack, or the Local Testing tunnel is not connected. | Follow the dedicated Local Testing instructions and establish the secure tunnel before the session. |
| Runs queue or take longer than expected | The requested sessions exceed the account’s parallel allowance, or the chosen matrix is larger than necessary. | Check account concurrency entitlements and prioritize representative targets. Configured sessions do not guarantee simultaneous execution. |
| Test passes locally but fails remotely | The remote OS/browser differs, timing or resource behavior differs, or an application dependency is unavailable. | Review the session video, browser console, network information, and exact target. Make waits depend on the required page condition rather than assuming a local timing. |
| Dashboard does not explain the assertion failure | The assertion and its context exist only in client-side test output. | Preserve runner output in CI and correlate its test name with the Automate session; inspect BrowserStack artifacts for browser-side context. |
8. Performance, reliability, and cost considerations
- Matrix size: Each additional browser and OS combination adds coverage and sessions. Select targets based on supported audiences and risk instead of testing every possible combination on every change.
- Parallelism: Parallel sessions may reduce elapsed time, while actual concurrency is bounded by account entitlements. Check the account and observe queue behavior for your workload.
- Reliability: Keep credentials in environment secrets, use supported capability values, keep Local Testing alive when needed, and report Puppeteer session status in cleanup paths.
- Failure triage: Preserve client test output and correlate it with dashboard session IDs and browser artifacts. This helps distinguish application failures from remote setup failures.
- Cost: The research sources do not establish current BrowserStack pricing or account concurrency terms. Check the current plan and account details before choosing matrix size or estimating spend.
9. Or skip the browser setup
If your task is to capture a page image or PDF rather than execute browser assertions across remote browser and OS targets, ScreenshotNeo is an alternative to try first. It is a website screenshot API and MCP server for developers: one GET request returns a PNG, JPEG, WebP, or PDF. See the ScreenshotNeo API documentation.
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo accepts cookie and consent banners as a visitor and removes more than 60 known consent platforms, newsletter popups, and chat widgets before capture; each cleanup step can be turned off. Bot checks and CAPTCHAs, blank pages, timeouts, failed loads, and cache hits cost nothing, and response headers report the page verdict and billing status. Its MCP server offers take_screenshot, get_page_info, and capture_pdf for Claude, Cursor, and other MCP clients. The free plan includes 1,000 shots a month without a card; paid plans start at $5 for 3,000 shots. Plans include every feature. These screenshots do not replace BrowserStack test sessions when you need browser-specific assertions across an OS matrix.
Sign up for 1,000 free ScreenshotNeo screenshots a month, with no card required.
10. Frequently asked questions
Can Playwright and Puppeteer use the same BrowserStack capabilities?
No. Choose values from the support table for the framework you are running; browser naming and configuration differ.
Does Puppeteer automatically mark a BrowserStack session passed when assertions pass?
No. The documented Puppeteer workflow runs assertions on the client, so send the executor status command to record pass or fail.
Can I run BrowserStack tests against a localhost URL?
Use BrowserStack Local Testing for private or locally hosted applications, and follow its current tunnel instructions before starting the session.
Where do I find the current supported browser list?
Use the live framework-specific Playwright or Puppeteer support table.
Does ScreenshotNeo run Playwright or Puppeteer test suites?
No. ScreenshotNeo returns page screenshots or PDFs; use BrowserStack Automate when you need remote browser test execution and assertions.


