Skip to content

Mobile Emulation

CraftDriver supports mobile device emulation using Chrome's built-in mobile emulation feature. This allows you to test responsive designs and mobile-specific behavior.

Chrome / Chromium only. Mobile emulation maps to the goog:chromeOptions.mobileEmulation capability — a Chromium-specific extension to WebDriver. Firefox / geckodriver expose no equivalent API, so passing mobileEmulation together with browserName: 'firefox' throws a clear error at launch. For mobile testing on Firefox, use a real device or Firefox's responsive design mode manually.

Quick Start

typescript
import { Browser } from 'craftdriver';

const browser = await Browser.launch({
  browserName: 'chrome',
  mobileEmulation: 'iPhone 14',
});

await browser.navigateTo('https://example.com');
// Page loads with iPhone 14 viewport, touch events, and mobile user agent

Using Device Presets

CraftDriver includes presets for popular devices:

typescript
// Use preset by name
const browser = await Browser.launch({
  browserName: 'chrome',
  mobileEmulation: 'iPhone 14',
});

Available Presets

DeviceWidthHeightPixel RatioPlatform
iPhone 143908443iOS
iPhone 14 Pro Max4309323iOS
iPhone SE3756672iOS
Pixel 74129152.625Android
Pixel 7 Pro4128923.5Android
Samsung Galaxy S233607803Android
iPad Pro 1183411942iPadOS
iPad Mini76810242iPadOS

You can also access presets programmatically:

typescript
import { devices } from 'craftdriver';

console.log(devices['iPhone 14']);
// { deviceMetrics: { width: 390, height: 844, pixelRatio: 3, ... }, userAgent: '...' }

Custom Device Configuration

For custom devices or specific testing needs:

typescript
const browser = await Browser.launch({
  browserName: 'chrome',
  mobileEmulation: {
    deviceMetrics: {
      width: 320,
      height: 568,
      pixelRatio: 2,
      mobile: true, // Enable mobile mode
      touch: true, // Enable touch events
    },
    userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X) ...',
  },
});

Device Metrics Options

OptionTypeDefaultDescription
widthnumber-Viewport width in pixels
heightnumber-Viewport height in pixels
pixelRationumber-Device pixel ratio (e.g., 2 for Retina)
mobilebooleantrueEnable mobile mode
touchbooleantrueEnable touch event emulation

Using Chrome's Built-in Devices

Chrome has its own device database. You can use any device name Chrome recognizes:

typescript
const browser = await Browser.launch({
  browserName: 'chrome',
  mobileEmulation: {
    deviceName: 'Nexus 5', // Any device Chrome knows
  },
});

Note: Chrome's device names are case-sensitive. Check Chrome DevTools for available names.

What Gets Emulated

When mobile emulation is enabled:

  • Viewport: Set to device dimensions
  • Device Pixel Ratio: High DPI rendering
  • Touch Events: touchstart, touchend, touchmove work
  • User Agent: Reflects mobile browser
  • CSS Media Queries: @media (max-width: ...) respond correctly
  • navigator.maxTouchPoints: Reports touch capability

Examples

Test Responsive Breakpoints

typescript
import { Browser } from 'craftdriver';

const viewports = [
  { name: 'Mobile', width: 375, height: 667 },
  { name: 'Tablet', width: 768, height: 1024 },
  { name: 'Desktop', width: 1280, height: 800 },
];

for (const vp of viewports) {
  const browser = await Browser.launch({
    browserName: 'chrome',
    mobileEmulation: {
      deviceMetrics: { width: vp.width, height: vp.height, pixelRatio: 2 },
    },
  });

  await browser.navigateTo('https://example.com');
  await browser.screenshot({ path: `screenshot-${vp.name}.png` });
  await browser.quit();
}

Test Mobile Navigation Menu

typescript
const browser = await Browser.launch({
  browserName: 'chrome',
  mobileEmulation: 'iPhone 14',
});

await browser.navigateTo('https://example.com');

// Mobile hamburger menu should be visible
await browser.expect('#mobile-menu-button').toBeVisible();

// Desktop nav should be hidden
const desktopNav = await browser.find('#desktop-nav').isVisible();
expect(desktopNav).toBe(false);

// Open mobile menu
await browser.click('#mobile-menu-button');
await browser.expect('#mobile-menu').toBeVisible();

Combine With Network Mocking And Logs

Mobile emulation works alongside network mocking and browser log capture:

typescript
const browser = await Browser.launch({
  browserName: 'chrome',
  mobileEmulation: 'Pixel 7',
});

// Mock mobile-specific API
await browser.network.mock('**/api/mobile-config', {
  status: 200,
  body: { mobileOptimized: true },
});

await browser.navigateTo('https://example.com');

// Check for console errors
const errors = browser.logs.getErrors();
expect(errors).toHaveLength(0);

Learn more in Network Mocking And Request Waiting and Console Logs And JavaScript Errors.

Limitations

  • Chrome/Chromium only: Mobile emulation uses Chrome-specific capabilities
  • Not real device: Some mobile behaviors can't be emulated (e.g., actual Safari rendering)
  • Fixed at launch: Device configuration is set when the browser launches and can't be changed mid-session
  • No orientation change: To test landscape, specify a wider width than height in deviceMetrics

Released under the MIT License.