🎯 What You Will Learn
Use built-in device profiles, custom viewports, touch, locale, timezone, color scheme, and screenshot checks.
- Configure built-in mobile device profiles
- Test custom viewport breakpoints
- Emulate touch, locale, timezone, and color scheme
- Write responsive assertions that check behavior instead of only pixels
Understand What Device Emulation Covers
Built-in profiles configure user agent, screen and viewport size, device scale factor, touch, and mobile behavior. They are useful browser emulations, not a substitute for every real-device check.
Add Mobile Device Projects
Spread built-in device descriptors into projects. Avoid overriding properties before the spread because the descriptor may replace them.
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{ name: 'desktop', use: { ...devices['Desktop Chrome'] } },
{ name: 'mobile-chrome', use: { ...devices['Pixel 7'] } },
{ name: 'mobile-safari', use: { ...devices['iPhone 13'] } },
],
});Test Responsive Navigation
Assert the control users receive at each breakpoint rather than checking only the numeric width.
import { test, expect } from '@playwright/test';
test('uses a mobile menu', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('button', { name: 'Open menu' })).toBeVisible();
await expect(page.getByRole('navigation')).toBeHidden();
});Test a Custom Breakpoint
Use page.setViewportSize for one targeted scenario or define the viewport in a project when many tests share it.
test('card grid collapses before 768px', async ({ page }) => {
await page.setViewportSize({ width: 767, height: 900 });
await page.goto('/products');
await expect(page.getByTestId('product-grid')).toHaveCSS(
'grid-template-columns',
/^d+(.d+)?px$/
);
});Exercise Touch-friendly Interactions
A mobile profile enables touch behavior, but tests should still use semantic actions and verify accessible controls.
- Open the page in a mobile project.
- Tap or click the visible menu control.
- Verify focus and the expanded state.
- Confirm the menu can be closed with the keyboard where applicable.
Emulate Locale, Timezone, and Color Scheme
Regional formatting and dark mode can reveal UI assumptions that viewport-only testing misses.
export default defineConfig({
use: {
locale: 'en-PH',
timezoneId: 'Asia/Manila',
colorScheme: 'dark',
},
});Capture Responsive Evidence
Use screenshot assertions for stable visual regions. Keep animations, clocks, and unpredictable data controlled.
test('mobile hero matches baseline', async ({ page }) => {
await page.goto('/');
await expect(page.getByRole('banner')).toHaveScreenshot('mobile-hero.png');
});Know When to Check a Real Device
Use a real phone or device lab for hardware behavior, installed-browser quirks, virtual keyboard effects, camera permissions, and performance under actual mobile constraints.
Emulation limit: A desktop browser emulating a phone profile does not reproduce every operating-system and hardware behavior.
Recap
- Built-in descriptors bundle more than a viewport size.
- Assert responsive behavior users can observe.
- Test locale, timezone, touch, and color scheme where relevant.
- Use real-device coverage for hardware and OS-specific risk.
Checkpoint: You have completed the workflow and have a repeatable reference for your next Playwright project.