skip to content

What do `--device` and `--viewport-size` change when you run Playwright's codegen?

level: middleimportance: nice to knowfreq 28%

answer

  1. Both configure the recorder only
  2. One is a full descriptor
  3. One is only width and height
  4. Touch and user agent differ
  5. Nothing about it reaches the output

basics

~20 s

They configure the recording session only. --device applies a named descriptor, including viewport, user agent and touch, so you record the mobile layout; --viewport-size sets just the window dimensions. Neither appears in the generated script.

solid answer

~40 s

`npx playwright codegen --device="iPhone 13" https://tracker.example.com` records against the emulated device: the descriptor sets viewport, device scale factor, user agent and the mobile and touch flags, so the site serves its phone layout and the recorder picks locators out of that DOM. `--viewport-size=390,844` is the blunter option — it sizes the window and nothing else, with no touch or user-agent emulation, which is enough for a purely CSS-driven breakpoint. Both configure the recorder, not the output: the emitted script is a plain list of actions with no device in it, so where the recorded steps run is decided by your test project. The trap is recording a mobile-only control and then replaying it under a desktop configuration, where that element does not exist.

code

bash · 5 lines
bash
# full descriptor: viewport, user agent, touch and mobile flags
npx playwright codegen --device="iPhone 13" https://tracker.example.com/orders/42

# window size only, no touch or user-agent emulation
npx playwright codegen --viewport-size=390,844 https://tracker.example.com/orders/42

go deeper

for a junior

Know that both flags change the browser you record in, and that --device is the one that gives you a real phone-like context rather than just a narrow window.

for a middle

Explain the difference in what each sets: a descriptor brings viewport, user agent, scale factor and touch, while a viewport size brings dimensions alone, which matters when an app branches on touch.

for a senior

Anticipate the mismatch: a flow recorded under a phone descriptor targets elements that only exist in the mobile DOM, and it fails as a timeout when run without equivalent emulation.

for a principal

Decide how mobile coverage is organised at all — which flows are worth recording twice, and how emulation is expressed consistently so recordings and the suite that runs them agree.

Both flags shape the browser you record in. Neither leaves a trace in the code that comes out. ## What `--device` applies `--device="iPhone 13"` selects a named entry from Playwright's device registry and applies the whole descriptor to the recording context: - **viewport** dimensions and **device scale factor**; - a matching **user agent** string; - the **mobile** and **has touch** flags, so touch-dependent behaviour is exercised; - the browser engine the descriptor implies, which is why an iPhone descriptor is usually recorded under WebKit. The practical effect on a food-delivery order tracker: you get the phone layout — a bottom sheet for driver details instead of a sidebar, a hamburger instead of a nav bar — and every locator the recorder emits is derived from that DOM. ## What `--viewport-size` does `--viewport-size=390,844` takes a `width,height` pair and sets the window size, and that is all. No user agent change, no touch, no mobile flag. | flag | viewport | user agent | touch and mobile flags | | --- | --- | --- | --- | | `--device="iPhone 13"` | from the descriptor | from the descriptor | yes | | `--viewport-size=390,844` | as given | unchanged | no | So `--viewport-size` is the right tool when a layout switches purely on a CSS breakpoint, and `--device` is the right one when the application branches on touch support or sniffs the user agent. ## Why the generated script has no trace of it The recorder emits the actions you performed and the locators for the elements you touched — not the context you performed them in. There is no device line, no viewport line. Where and how the recorded steps are eventually run is decided in your test project's configuration, which the codegen CLI does not read and does not write to. Two consequences follow: 1. A script recorded on a phone descriptor and run under a desktop configuration executes against the desktop layout, which is exactly where recorded mobile flows fail. 2. Nothing about the recording pins a browser engine either, so the same output can be pointed at a different engine later without editing. ## The trap, concretely You record the "contact your driver" bottom sheet under `--device="iPhone 13"`. The generated `getByRole('button', { name: 'Contact driver' })` inside that sheet is correct — on a phone. Run it without mobile emulation and the sheet never renders; the button is not in the DOM, and the test fails on a timeout that reads like a flake but is a configuration mismatch. When you record with a device, make sure the place the script ends up runs with equivalent emulation. ## Working advice - Record mobile and desktop variants of a flow in separate runs; the DOM differs, so the locators differ, and one recording rarely serves both. - Prefer `--device` over a hand-typed viewport when you are chasing a mobile-specific behaviour — guessing the dimensions gets you the layout but not the touch behaviour. - Check the emitted locators after a mobile recording: the phone layout often relies on icon-only controls, which is precisely the case that pushes the generator into a positional CSS fallback.

  • When is `--viewport-size` enough, and when do you need `--device`?
    `--viewport-size` is enough when the layout you want is chosen purely by a CSS media query, since only dimensions matter. Reach for `--device` when the application branches on touch support or the user agent — a descriptor also sets the mobile and touch flags and the device scale factor, which a bare size cannot.

saying these in an interview costs you the question

  • Thinks --device only changes the window width
  • Believes the device is baked into the generated script
  • Assumes --viewport-size enables touch emulation
  • Thinks recorded mobile locators always work on desktop
  • Guesses device dimensions instead of naming a descriptor