Skip to main content
A viewport is set in two places. The target fixes the size every attempt starts at, and a test resizes from inside its body. The agent works at whichever size is current and never resizes on its own.

One size per target

viewport on playwright(...) is the initial size of every attempt’s page. The default is 1280 by 720. A suite that has to hold at several sizes declares one target per size:
e2e.config.ts
Every test runs once per target and each run is its own result, tagged [desktop], [tablet], or [phone] in the terminal, the report, and JUnit output. Targets that declare the same command share one app process, so three sizes still start one dev server. Each worker owns a browser, so the browser count follows workers, not the number of sizes. --target phone runs one size; e2e list prints the test-target pairs a run would select. A retry starts a fresh attempt, and a fresh attempt starts at the target’s size again, whatever the failed attempt resized to.

Resize inside a test

web.setViewport resizes the page for the rest of the attempt:
Reach for this when one test walks through several sizes, or when a single test in a desktop suite needs a narrow layout. When the whole suite needs the size, a target is the better home: it is visible in the config, in the report, and in --target, and nothing in the test body has to remember to call it. The call records the new size on its own step in the report; later steps do not repeat it. There is no viewport matcher; a test that has to assert the size reads it from the page:

What the agent sees

Every observation the model receives is stamped with the size it was taken at, as viewport="390x844@1" in the observation header, and a screenshot is the viewport, never the full page. An agent.act() after a resize therefore reasons about the narrow layout: the hamburger button is in the tree and the full navigation is not. A node below the fold stays in the tree as long as the page renders it, and tap scrolls it into view on its own; scroll is for content the page has not rendered yet. The agent cannot resize. Its verbs are tap, type, press, select, scroll, navigate, and type_secret when the step has a credential, and none of them changes the page size. Resize in the test, then hand the step to the agent:
An instruction such as “switch to a phone-sized window” has no verb to land on and cannot succeed. Say what to do on the page, not how large the page should be.

Scoping a test to one size

platforms and requires cannot tell two browser targets apart: every Playwright target is platform web with the same capabilities, so a test scoped with them runs on the phone and the desktop alike. To run a test at one size only, either resize inside it with web.setViewport, or keep the size-specific tests in their own config and run them with --config.

Limits

The browser engine sets a size and nothing else about the device. A phone target is a narrow window in a desktop browser: no touch events, a device scale factor of 1 (the @1 in every observation), the browser’s own user agent, and no prefers-reduced-motion or color scheme emulation. Layouts that key off hover: none or pointer: coarse media queries see a desktop. Real touch, a real scale factor, and a real mobile browser are what the device engine provides on a simulator or emulator. A --video recording on a Playwright target is sized to the viewport the attempt started with. A resize mid-attempt does not change the recording’s dimensions.

Working with the browser

Routes, cookies, dialogs, downloads, and the rest of the web fixture.

Playwright reference

Every engine option and web method, with timeouts and errors.