skip to content

Device Descriptors

One named descriptor sets viewport, user agent, scale factor and touch together. Interviewers probe the boundary: this is emulation inside a desktop engine, not a real phone and not real Safari.

on this pageshow

explore

questions

5

In Playwright, what does spreading `devices['iPhone 15']` into a project's `use` block actually configure?

level: juniorimportance: must knowfreq 74%

answer

  1. One name, several context options
  2. Metrics, identity, input, plus an engine hint
  3. Screen and viewport are different numbers
  4. Scale factor drives devicePixelRatio
  5. Emulation, not a phone

basics

~20 s

A device descriptor is a bundle of browser context options under one name. Spreading it sets viewport, screen, userAgent, deviceScaleFactor, isMobile and hasTouch together, plus defaultBrowserType, which tells the test runner which engine to launch.

solid answer

~40 s

`devices` is a registry exported by `@playwright/test` (and by the `playwright` library) mapping a device name to a plain object of context options. In Playwright 1.63, `devices['iPhone 15']` carries a `viewport` 393 CSS pixels wide, a `screen` size, a `userAgent`, `deviceScaleFactor: 3`, `isMobile: true`, `hasTouch: true` and `defaultBrowserType: 'webkit'`. Spreading it into a project applies all of those to every context that project creates, so a hotel-booking search page lays out at phone width, `window.devicePixelRatio` reports 3, the `meta viewport` tag is honoured and touch events exist. `defaultBrowserType` is the odd key out: the page cannot observe it, and it exists only so the runner's `browserName` has something to fall back to. Nothing launches a phone — this is a desktop engine with its metrics overridden.

code

typescript · 8 lines
typescript
import { defineConfig, devices } from '@playwright/test';

export default defineConfig({
  projects: [
    { name: 'desktop', use: { ...devices['Desktop Chrome'] } },
    { name: 'phone', use: { ...devices['iPhone 15'] } },
  ],
});

go deeper

for a junior

Remember the shape: one name from the devices registry expands into several context options. Be able to list viewport, user agent, device scale factor and the touch flag without hesitating.

for a middle

Explain what each key changes in the page: media queries resolve against the viewport, devicePixelRatio drives image selection, the mobile flag decides whether the meta viewport tag is honoured, and the touch flag decides whether touch events exist.

for a senior

Show that you know what the bundle leaves out. Locale, timezone, permissions and storage are separate concerns, and a descriptor is emulation on a desktop engine, so say what a green mobile project does and does not evidence.

for a principal

Own the convention. Decide whether the team spreads registry entries or maintains its own profiles, and make sure project names describe the combination actually being run rather than implying a device the suite never touches.

## What a device descriptor actually is Playwright ships a registry of named device profiles exported as `devices` — from `@playwright/test` for the test runner, and from the `playwright` package for the library API. Each entry is an ordinary JavaScript object whose keys are ordinary **browser context options**. There is no device driver behind the name: `devices['iPhone 15']` is data, and spreading it into a `use` block is exactly equivalent to typing those options out by hand. That framing tells you the ceiling straight away. A descriptor can set anything a browser context can set. It cannot install an operating system, a cellular radio, or the browser Apple ships. ## The keys one entry carries | key | shape | what the page observes | |---|---|---| | `viewport` | `{ width, height }` | the layout viewport CSS media queries resolve against | | `screen` | `{ width, height }` | `window.screen.width` and `height`, independent of the viewport | | `userAgent` | string | `navigator.userAgent` and the outgoing `User-Agent` header | | `deviceScaleFactor` | number | `window.devicePixelRatio`, which picks `2x` or `3x` image sources | | `isMobile` | boolean | whether the `meta viewport` tag is honoured; not supported in Firefox | | `hasTouch` | boolean | whether touch events exist and `locator.tap()` is permitted | | `defaultBrowserType` | engine name | the engine the test runner falls back to | In Playwright 1.63 the `iPhone 15` entry is a viewport 393 CSS pixels wide with `deviceScaleFactor: 3`, `isMobile: true`, `hasTouch: true` and `defaultBrowserType: 'webkit'`; the `Pixel 7` entry is 412 wide with `deviceScaleFactor: 2.625` and `defaultBrowserType: 'chromium'`. Entries are added and revised between releases, so treat the numbers as data you can read, not constants to memorise. Two keys reliably confuse people: - `screen` is **not** the viewport. On a phone entry the screen is the taller number, because a real handset gives part of the display to browser chrome. Code that reads `window.screen.height` for layout maths sees that larger value, while media queries see the viewport. - `defaultBrowserType` is **not** a context option. Nothing in the page can observe it. It exists purely so the test runner can pick an engine for you. ## What spreading it into a project does When a project spreads a descriptor, every context that project creates is built with those options. Concretely, for one test in a hotel-booking suite: 1. The runner resolves the project's options, so `browserName` falls back to the descriptor's `defaultBrowserType` unless you set `browserName` yourself. 2. A fresh context is created with the viewport, screen, user agent, scale factor, mobile flag and touch flag from the descriptor. 3. The page loads the search results at phone width, so the CSS that collapses the filter sidebar into a drawer is the branch under test, and `window.devicePixelRatio` reports the descriptor's value so your responsive image `srcset` picks the high-density asset. 4. Because `hasTouch` is on, `locator.tap()` is allowed and touch-only handlers on the room gallery fire; because `isMobile` is on, the page's `meta viewport` tag is respected instead of ignored. ## What a descriptor does not set A descriptor is deliberately narrow. It does **not** set locale, timezone, geolocation, colour scheme, permissions, cookies or storage — those are separate context options you compose alongside it. It does not choose a browser channel or launch flags. And it emulates: the engine underneath is the same desktop build you would run for a `Desktop Chrome` project, with its metrics and input surface overridden. ## Using one outside the test runner The same objects are available to the library API, so `browser.newContext({ ...devices['Pixel 7'] })` applies the identical options. The difference is that nothing reads `defaultBrowserType` for you — you decide which engine to launch, and the field is just a suggestion sitting in the object. ## Interview framing The answer an interviewer is listening for has three beats: a descriptor is a **named bundle of context options**; it covers **metrics, identity and input** (viewport, screen, user agent, scale factor, mobile and touch flags) plus an engine hint; and it is **emulation inside a desktop engine**, which is why it is cheap, deterministic and CI-friendly — and why it is not a phone.

  • What is the difference between the `screen` and `viewport` entries in a device descriptor?
    `viewport` is the layout viewport CSS media queries resolve against; `screen` is what `window.screen.width` and `height` report. On phone entries the screen is taller, mirroring the display area a real handset gives up to browser chrome, so code doing layout maths from `window.screen` sees a different number than the CSS does.
  • Can you use a device descriptor without the Playwright test runner?
    Yes. The same registry is exported by the `playwright` package, and the descriptor's context options apply when you spread it into a new context. The one part that does not carry over is `defaultBrowserType` — no fallback reads it there, so you choose and launch the engine yourself.
  • Does a device descriptor also set locale, timezone or colour scheme?
    No. Descriptors cover metrics, identity and input only: viewport, screen, user agent, scale factor, mobile flag and touch flag. Locale, timezone, geolocation, colour scheme and permissions are separate context options you compose alongside the spread, and none of them is implied by picking a phone.

Picking a descriptor is like choosing a preset on a camera: one name fills in half a dozen settings at once, and you can still turn any single dial afterwards.

saying these in an interview costs you the question

  • Says the descriptor launches or drives a real iPhone
  • Thinks it only changes the user agent string
  • Assumes viewport and screen hold the same value
  • Expects touch to work without hasTouch being set
  • Believes the descriptor also sets locale and timezone
open as a page

How does a Playwright device descriptor's `defaultBrowserType` decide which engine a project runs?

level: middleimportance: must knowfreq 58%

basics

~10 s

The test runner declares browserName as an option that falls back to defaultBrowserType, which itself defaults to chromium. A descriptor carrying defaultBrowserType 'webkit' therefore selects WebKit, unless the same use block sets browserName explicitly.

open as a page

In a Playwright `use` block, why is a `viewport` override ignored when written before the `...devices` spread?

level: middleimportance: should knowfreq 46%

basics

~10 s

Because the use block is one object literal and JavaScript applies its keys in source order. The spread comes later, so the descriptor's own viewport overwrites the earlier key and only one value survives.

open as a page

A Playwright test fails with 'The page does not support tap' on a mobile flow — what is missing?

level: seniorimportance: should knowfreq 51%

basics

~20 s

The context was built without hasTouch, which defaults to false. Playwright refuses locator.tap when there is no touchscreen. A hand-written viewport and user agent do not enable touch; a device descriptor sets hasTouch and isMobile together.

open as a page

What can a Playwright device descriptor not reproduce about a real phone, and what does a green mobile project prove?

level: principalimportance: should knowfreq 36%

basics

~20 s

A descriptor overrides metrics, user agent and input flags inside a desktop engine. It reproduces no phone hardware, no shipping mobile browser and no mobile OS, so a green run proves your responsive layout works, not that iOS does.

open as a page