Skip to content

Latest commit

 

History

History
156 lines (124 loc) · 5.94 KB

File metadata and controls

156 lines (124 loc) · 5.94 KB
description Playwright device emulation for mobile, tablet, and responsive testing
mode subagent
tools
read write edit bash glob grep webfetch task
true
false
false
true
true
true
true
true

Playwright Device Emulation

Quick Reference

Device Presets

100+ built-in descriptors (viewport, userAgent, deviceScaleFactor, isMobile, hasTouch):

  • Landscape variant: append landscape (e.g., devices['iPhone 13 landscape'])
  • List all: node -e "const { devices } = require('playwright'); console.log(Object.keys(devices).join('\n'))"
Category Examples Viewport Scale Mobile
Desktop Chrome, Firefox, Safari, Edge 1280×720 1 No
iPhone 13/14/15, Pro Max 390×844, 428–430×926–932 3 Yes
iPad gen7, Mini, Pro 11 810×1080, 768×1024, 834×1194 2 Yes
Android Pixel 5/7, Galaxy S8/S9+/Tab S4 360–412×740–915 2.25–4.5 Yes

Configuration

// playwright.config.ts — test runner
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
  projects: [
    { name: 'Desktop Chrome', use: { ...devices['Desktop Chrome'] } },
    { name: 'Mobile Safari',  use: { ...devices['iPhone 13'] } },
    { name: 'Mobile Chrome',  use: { ...devices['Pixel 7'] } },
    { name: 'Tablet',         use: { ...devices['iPad Pro 11'] } },
  ],
});

// Library API
const { chromium, devices } = require('playwright');
const ctx = await (await chromium.launch()).newContext({ ...devices['iPhone 13'] });
await (await ctx.newPage()).goto('https://example.com');

Emulation Options

// Viewport / HiDPI
test.use({ viewport: { width: 1600, height: 1200 } });
await page.setViewportSize({ width: 375, height: 667 });
await browser.newContext({ viewport: { width: 2560, height: 1440 }, deviceScaleFactor: 2 });

// Geolocation
use: { geolocation: { longitude: -122.4194, latitude: 37.7749 }, permissions: ['geolocation'] }
await context.setGeolocation({ longitude: 48.8584, latitude: 2.2945 });

// Locale / Timezone — pairs: en-US/America/Los_Angeles, en-US/America/New_York,
//   en-GB/Europe/London, de-DE/Europe/Berlin, fr-FR/Europe/Paris, ja-JP/Asia/Tokyo,
//   zh-CN/Asia/Shanghai, hi-IN/Asia/Kolkata, pt-BR/America/Sao_Paulo, en-AU/Australia/Sydney
use: { locale: 'en-GB', timezoneId: 'Europe/London' }

// Color scheme / media
await page.emulateMedia({ colorScheme: 'dark', reducedMotion: 'reduce', forcedColors: 'active', media: 'print' });

// Permissions: geolocation, midi, midi-sysex, notifications, camera, microphone,
//   background-sync, ambient-light-sensor, accelerometer, gyroscope, magnetometer,
//   accessibility-events, clipboard-read, clipboard-write, payment-handler
await context.grantPermissions(['geolocation'], { origin: 'https://example.com' });
await context.clearPermissions();

// Offline / JS / User Agent
await context.setOffline(true);
test.use({ javaScriptEnabled: false, userAgent: 'Custom Bot/1.0' });

// Touch
const ctx = await browser.newContext({ ...devices['iPhone 13'], hasTouch: true });
await page.tap('.button');
await page.touchscreen.tap(200, 300);

Recipes

Responsive Breakpoint Testing

Breakpoints: mobile-sm 320×568, mobile-md 375×667, tablet 768×1024, laptop 1024×768, desktop 1280×800, desktop-lg 1920×1080.

for (const bp of breakpoints) {
  test(`layout at ${bp.name}`, async ({ browser }) => {
    const ctx = await browser.newContext({ viewport: { width: bp.width, height: bp.height } });
    const page = await ctx.newPage();
    await page.goto('https://example.com');
    await expect(page).toHaveScreenshot(`${bp.name}.png`);
    await ctx.close();
  });
}

Network Throttling (Chromium/CDP only)

const cdp = await page.context().newCDPSession(page);
await cdp.send('Network.emulateNetworkConditions', {
  offline: false, downloadThroughput: (500 * 1024) / 8,
  uploadThroughput: (500 * 1024) / 8, latency: 400, // Slow 3G
});

Dark Mode Visual Regression

for (const scheme of ['light', 'dark'] as const) {
  test(`visual regression (${scheme})`, async ({ browser }) => {
    const ctx = await browser.newContext({ colorScheme: scheme, viewport: { width: 1280, height: 720 } });
    const page = await ctx.newPage();
    await page.goto('https://example.com');
    await expect(page).toHaveScreenshot(`homepage-${scheme}.png`);
    await ctx.close();
  });
}

Integration

  • Chrome DevTools MCP: navigate in mobile emulation → npx chrome-devtools-mcp@latest --browserUrl http://127.0.0.1:9222 for Lighthouse mobile audit.
  • Stagehand: new Stagehand({ env: 'LOCAL', browserOptions: { ...devices['iPhone 13'] } })stagehand.act('tap the hamburger menu').

Related

  • playwright.md — core automation (cross-browser, forms, security, API testing)
  • playwright-cli.md — CLI-first Playwright for AI agents
  • browser-automation.md — tool selection decision tree
  • browser-benchmark.md — performance benchmarks
  • pagespeed.md — PageSpeed Insights integration
  • Maestro (t096) — native mobile E2E testing
  • iOS Simulator MCP (t097) — iOS simulator interaction