What can a Playwright device descriptor not reproduce about a real phone, and what does a green mobile project prove?
answer
- Metrics change, the engine does not
- Same machine, same stack underneath
- Layout and input branches are reachable
- Hardware, network and OS chrome are not
- The engine build is not the shipped browser
basics
~20 sA 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.
solid answer
~40 sEmulation changes six values on a desktop engine build: viewport, screen, user agent, device pixel ratio, the mobile flag and the touch flag. Everything underneath — the layout and JavaScript engines, the network stack, the machine — is your CI runner. So the reachable set is real but bounded: responsive layout at a width, media-query and `devicePixelRatio` branches, user-agent branching, touch-versus-pointer code paths, mobile-only DOM. Out of reach: performance on handset hardware, radio network behaviour, address-bar collapse and safe-area insets, the on-screen keyboard shrinking the visual viewport, real gesture physics, and bugs specific to the browser your users installed — Playwright's WebKit is built from WebKit sources, not the branded Safari build. Claim the responsive and touch code paths on that engine family, and nothing more.
code
typescript · 9 linesimport { test, expect, devices } from '@playwright/test';
test.use({ ...devices['iPhone 15'] });
test('search collapses to the mobile filter drawer', async ({ page }) => {
await page.goto('/search?city=lisbon');
await expect(page.getByRole('button', { name: 'Filters' })).toBeVisible();
await expect(page.getByRole('navigation', { name: 'Filter sidebar' })).toBeHidden();
});go deeper
Hold on to the core fact: emulation changes sizes, identity and input flags on a desktop browser. Passing a mobile project means the layout and touch paths behaved, not that a phone was involved.
Be able to sort a defect into reachable or unreachable. Viewport, pixel ratio, user agent and touch branches are testable; hardware speed, radios and OS chrome are not, and knowing which is which saves wasted debugging.
Set expectations for the suite you operate. State plainly what a green mobile run evidences, keep timing and smoothness assertions out of emulated projects, and triage mobile escapes against the reachable set rather than adding descriptors reflexively.
Own the claim the organisation makes from a green pipeline. Decide where emulation's cheap always-on coverage ends, make that boundary visible in project names and documentation, and stop a passing suite being used as an argument that no other mobile verification is needed.
## What emulation is, precisely A device descriptor overrides a handful of values on a **desktop engine build**: the viewport and screen sizes, the user agent string, the device pixel ratio, whether the `meta viewport` tag is honoured, and whether a touchscreen exists. Everything else — the JavaScript engine, the layout engine, the networking stack, the process model, the machine — is whatever your CI runner already had. Nothing is virtualised and no phone is involved. That is a feature. It is why a mobile project costs roughly what a desktop project costs, runs deterministically, and produces the same traces and failures your desktop specs do. ## What it genuinely catches - Responsive layout at a given width: the search page collapsing its filter sidebar into a drawer, the room-detail gallery switching to a single column. - Media-query branches keyed on width, and anything keyed on `window.devicePixelRatio`, including `srcset` selecting the high-density room photo. - Server-side or client-side branching on the user agent string. - Touch-versus-pointer code paths, since `hasTouch` really does change what events the page receives. - Mobile-only DOM: a bottom nav bar, a sticky booking button, a drawer that only exists below a breakpoint. ## What it cannot reach | class of defect | why emulation misses it | |---|---| | performance and jank | your runner's CPU, GPU and memory are nothing like a handset's | | network behaviour on a radio | no cellular latency, loss or hand-off is reproduced | | OS chrome effects | address-bar collapse, safe-area insets and pull-to-refresh do not exist | | on-screen keyboard | focus in the guest-profile form does not shrink the visual viewport | | real gesture physics | scroll momentum, pinch-zoom and multi-touch are not the platform's | | shipping-browser bugs | the engine build is not the browser your users installed | | platform integrations | app links, push, biometric prompts and payment sheets are absent | ## The engine is not the shipped browser This is the beat most candidates miss. Playwright's WebKit is built from WebKit sources — often ahead of what has landed in the browser Apple ships — and Playwright deliberately does not drive the branded Safari build. Chromium is likewise not Android Chrome and not a system WebView. So an `iPhone 15` project is best described as *WebKit at iPhone metrics*, not *iOS Safari*. It is a good proxy for the rendering rules of that engine family and a poor proxy for a specific shipping version's quirks. ## What to claim from a green run Set the claim at the level the mechanism supports: 1. **Claim**: the mobile layout branch renders and the touch code paths work on this engine family. 2. **Claim**: no regression in the responsive behaviour we chose to assert. 3. **Do not claim**: iOS works, Safari works, the app is fast on a phone, the gestures feel right. The organisational value of stating it that way is that it stops a green pipeline from being used as an argument against every other kind of mobile verification. Emulation is the cheap, always-on layer that catches the regressions you can catch cheaply; real-hardware verification is a separate practice with its own cost and cadence, and the two answer different questions. ## How to keep the boundary visible - Name projects for what they are. `webkit-iphone-metrics` invites fewer wrong conclusions than `iPhone`. - Keep emulation-only assertions to things a viewport and an input flag can decide, and resist writing assertions about timing or smoothness in a mobile project. - When a mobile bug escapes to production, classify it: was it in the *reachable* set and simply not asserted, or in the *unreachable* set? Only the first kind is a gap in the suite; treating the second kind as one leads to piling more descriptors onto a problem descriptors cannot solve. - Write the boundary down next to the config, because the person who inherits the suite in a year will otherwise read a green `iPhone 15` project as a guarantee about iPhones. ## The one-sentence answer A descriptor changes metrics, identity and input flags inside a desktop engine, so a green mobile project is evidence about your responsive and touch code paths on that engine — and evidence about nothing that depends on real hardware, a real network, the phone OS, or the browser your users run.
- How would you name mobile projects so a green pipeline is not over-read?Name the combination, not the device: `webkit-iphone-metrics` rather than `iPhone`. The name is the only thing most readers see in a report, and it should say which engine ran and that the phone part is metrics. Anyone reading it then knows what the pass covers without opening the config.
- A mobile bug escapes to production. How do you decide whether the emulated suite should have caught it?Classify it against the reachable set. If it depended only on viewport, pixel ratio, user agent, touch or mobile-only DOM, it was catchable and the gap is a missing assertion. If it depended on hardware speed, the radio, OS chrome or a shipping-browser quirk, no descriptor would have found it and adding more descriptors is wasted effort.
- Why is Playwright's WebKit not a substitute for the browser Apple ships?It is built from WebKit sources, frequently ahead of what has landed in released Safari, and Playwright does not drive the branded build. That makes it a good proxy for the engine family's rendering and scripting rules, and a poor proxy for version-specific quirks of the browser your users actually run.
A device descriptor is a costume, not a transplant: the browser takes the phone's measurements and label while the body underneath stays your desktop engine.
saying these in an interview costs you the question
- Says a passing iPhone project proves iOS Safari works
- Expects emulation to surface performance or jank issues
- Thinks Playwright drives the installed Safari build
- Assumes the on-screen keyboard affects the emulated viewport
- Adds more descriptors to chase hardware-specific bugs