Playwright

Mobile Device and Responsive Testing

Thirdy Gayares
16 min read

🎯 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
Prerequisites: A Playwright Test project and a responsive application route to exercise.

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.

playwright.config.ts
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.

tests/navigation.spec.ts
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.

tests/breakpoints.spec.ts
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.

  1. Open the page in a mobile project.
  2. Tap or click the visible menu control.
  3. Verify focus and the expanded state.
  4. 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.

playwright.config.ts
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.

tests/visual.spec.ts
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.

Official Resources

About the Author

TG

Thirdy Gayares

Passionate developer creating custom solutions for everyone. I specialize in building user-friendly tools that solve real-world problems while maintaining the highest standards of security and privacy.