Testing responsive designs across devices is tedious when done manually. Playwright provides device emulation with 100+ presets, but managing browser infrastructure at scale is complex. This guide covers Playwright's device emulation, automated responsive testing pipelines, and how SnapAPI's device presets let you capture screenshots across 30+ devices with a single API call.
Playwright Device Emulation
Playwright includes device descriptors for 100+ devices — phones, tablets, and desktops with accurate viewport sizes, user agents, and device scale factors:
import { chromium, devices } from 'playwright';
async function captureOnDevice(url, deviceName) {
const device = devices[deviceName];
const browser = await chromium.launch();
const context = await browser.newContext({ ...device });
const page = await context.newPage();
await page.goto(url, { waitUntil: 'networkidle' });
await page.screenshot({
path: `screenshots/${deviceName.replace(/\s/g, '-')}.png`,
fullPage: true,
});
await browser.close();
}
// Capture on multiple devices
const testDevices = [
'iPhone 14 Pro',
'iPhone SE',
'Pixel 7',
'iPad Pro 11',
'Galaxy S23',
'Desktop Chrome',
];
for (const device of testDevices) {
await captureOnDevice('https://yourapp.com', device);
console.log(`Captured: ${device}`);
}
Automated Responsive Testing Pipeline
Build a CI-integrated pipeline that captures screenshots across breakpoints and compares them against golden references:
import { chromium, devices } from 'playwright';
import pixelmatch from 'pixelmatch';
import { PNG } from 'pngjs';
import fs from 'fs';
const BREAKPOINTS = [
{ name: 'mobile', width: 375, height: 812 },
{ name: 'tablet', width: 768, height: 1024 },
{ name: 'laptop', width: 1366, height: 768 },
{ name: 'desktop', width: 1920, height: 1080 },
];
async function responsiveTest(url, pageName) {
const browser = await chromium.launch();
const results = [];
for (const bp of BREAKPOINTS) {
const context = await browser.newContext({
viewport: { width: bp.width, height: bp.height },
deviceScaleFactor: bp.width <= 768 ? 2 : 1,
});
const page = await context.newPage();
await page.goto(url, { waitUntil: 'networkidle' });
const screenshot = await page.screenshot({ fullPage: true });
const currentPath = `screenshots/${pageName}-${bp.name}.png`;
const goldenPath = `golden/${pageName}-${bp.name}.png`;
fs.writeFileSync(currentPath, screenshot);
// Compare with golden reference
if (fs.existsSync(goldenPath)) {
const current = PNG.sync.read(screenshot);
const golden = PNG.sync.read(fs.readFileSync(goldenPath));
const diff = new PNG({ width: current.width, height: current.height });
const mismatch = pixelmatch(
current.data, golden.data, diff.data,
current.width, current.height,
{ threshold: 0.1 }
);
const diffPercent = (mismatch / (current.width * current.height)) * 100;
results.push({
breakpoint: bp.name,
diffPercent: diffPercent.toFixed(2),
passed: diffPercent < 1,
});
}
await context.close();
}
await browser.close();
return results;
}
SnapAPI Device Presets
SnapAPI includes 30+ device presets — pass a device parameter and get accurate emulation without managing Playwright infrastructure:
import SnapAPI from 'snapapi-js';
const snap = new SnapAPI('sk_live_your_key');
// Capture on multiple devices in parallel
const devices = [
'iPhone 14 Pro', 'iPhone SE', 'Pixel 7',
'iPad Pro 11', 'Galaxy S23', 'desktop',
];
const screenshots = await Promise.all(
devices.map(device =>
snap.screenshot({
url: 'https://yourapp.com',
device,
full_page: true,
format: 'png',
})
)
);
screenshots.forEach((shot, i) => {
console.log(`${devices[i]}: ${shot.url}`);
});
// List all available device presets
const availableDevices = await snap.listDevices();
console.log(availableDevices);
// ["iPhone 14 Pro", "iPhone 14", "iPhone SE", "iPad Pro 11",
// "iPad Mini", "Pixel 7", "Galaxy S23", "Galaxy Tab S8", ...]
Approach Comparison
| Approach | Devices | Real Browsers | Infrastructure | CI Integration |
|---|---|---|---|---|
| Manual testing | Limited by hardware | Yes | Physical devices | No |
| Browser DevTools | Custom viewports | Emulated | None | No |
| Playwright | 100+ presets | Emulated (accurate) | Browser servers | Yes |
| BrowserStack | 3000+ | Real devices | Cloud (paid) | Yes |
| SnapAPI | 30+ presets | Emulated (accurate) | None (API call) | Yes |
Test Responsive Designs Across 30+ Devices — One API Call
SnapAPI captures screenshots on any device preset. No browser infrastructure, no device farms. Plus scraping, extraction, PDFs, and AI analysis in the same API.
Start Free — 200 Captures/Month