Skip to content

Browsers and devices

Every browser run picks one browser and one device. The default is Chromium · Desktop. Choose another combination to check that a flow works in Safari’s engine or on a phone-sized screen, without changing the test.

Value Engine Served by
chromium Chromium (Chrome, Edge) the playwright-mcp service
firefox Firefox (Gecko) the playwright-mcp-firefox service
webkit WebKit (Safari’s engine) the playwright-mcp-webkit service

Each browser has its own Playwright MCP server in docker-compose.yml, started with the same flags apart from --browser. The worker picks the server from the run’s browser using these settings:

Setting Default
PLAYWRIGHT_MCP_URL http://playwright-mcp:8931/mcp
PLAYWRIGHT_MCP_URL_FIREFOX http://playwright-mcp-firefox:8931/mcp
PLAYWRIGHT_MCP_URL_WEBKIT http://playwright-mcp-webkit:8931/mcp

Only the Chromium server publishes a port, 8931, and only on the host’s 127.0.0.1 for debugging. Firefox and WebKit aren’t published at all. All three sit on a separate browser network that only the backend and the workers join, so a page under test can’t reach the database, Redis or the platform UI (see The browser and your network). The URL’s path doesn’t matter: the worker always connects to the server’s /sse endpoint on that host and port. See Configuration.

Value Viewport (CSS pixels)
desktop the browser’s default desktop size
iphone 390 × 844
pixel 412 × 915
ipad 820 × 1180

A device preset resizes the browser window before the agent starts, so your responsive layout, breakpoints and mobile navigation are what the agent sees. It doesn’t change the user agent, touch support or pixel density. A site that detects phones by user agent will still serve its desktop version.

On a UI test’s page, open the target menu next to Run test (it shows the current choice, such as Chromium · Desktop), choose a browser and a device, then click Run test. The run page shows the target, for example WebKit · iPhone · Staging.

Every trigger takes browser and device. An unknown value returns 400.

Terminal window
# One test
curl -s -X POST "$PW/api/runs/trigger/TEST_ID?browser=webkit&device=iphone" \
-H "Authorization: Bearer $TOKEN"
# Every active test in a module, or in the whole project
curl -s -X POST "$PW/api/modules/MODULE_ID/run?browser=firefox&device=desktop" \
-H "Authorization: Bearer $TOKEN"
curl -s -X POST "$PW/api/modules/project/PROJECT_ID/run-all?browser=chromium&device=pixel" \
-H "Authorization: Bearer $TOKEN"

All three also accept environment_id. See UI tests for how to get $TOKEN.

The CI webhook takes browser and device in its JSON body and applies them to every test in the batch. To cover several targets, call it once per target, for example from a GitHub Actions matrix:

.github/workflows/browsers.yml
jobs:
plainwright:
runs-on: ubuntu-latest
strategy:
matrix:
target:
- { browser: chromium, device: desktop }
- { browser: webkit, device: iphone }
- { browser: firefox, device: desktop }
steps:
- name: Queue Plainwright tests
run: |
curl -fsS -X POST "${{ secrets.PLAINWRIGHT_URL }}/api/runs/webhook/${{ secrets.PLAINWRIGHT_PROJECT_ID }}" \
-H "X-Webhook-Secret: ${{ secrets.PLAINWRIGHT_WEBHOOK_SECRET }}" \
-H "Content-Type: application/json" \
-d '{"browser": "${{ matrix.target.browser }}", "device": "${{ matrix.target.device }}"}'

Each call returns its own batch_id and status_url. To wait for the verdict and fail the job on a failed gate, see GitHub Actions.

  • Retries of a failed run use the same browser, device and environment.
  • Visual baselines are kept per browser and device. The first passing run on a new combination saves its own baseline. See Visual regression.
  • Saved logins are captured in the browser you choose for the capture and restored into whichever browser a test runs in. Cookies and local storage usually carry over, but if a browser rejects a cookie, capture a separate saved login in that browser.
  • Site quality tests use the run’s browser and viewport too. The app runs them as Chromium · Desktop; trigger them through the API or CI to check a mobile viewport.
  • Scheduled runs always use Chromium · Desktop and the project URL.
  • API tests don’t use a browser, so the options don’t apply.

The browser servers run with --isolated: every run gets a fresh, in-memory browser profile. Cookies, local storage and logins never carry over from one run to the next, even on the same worker. Within a run, the page keeps its state from the first step to the last, because the worker holds one browser session open for the whole run.

To start a run already signed in, use a saved login rather than relying on leftovers from an earlier run.