Responsive Testing

Device Emulation and Responsive Testing with APIs in 2026

Published April 5, 2026 · 13 min read

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

ApproachDevicesReal BrowsersInfrastructureCI Integration
Manual testingLimited by hardwareYesPhysical devicesNo
Browser DevToolsCustom viewportsEmulatedNoneNo
Playwright100+ presetsEmulated (accurate)Browser serversYes
BrowserStack3000+Real devicesCloud (paid)Yes
SnapAPI30+ presetsEmulated (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