Table of contents

How to Handle Mobile Device Emulation in Puppeteer?

Mobile device emulation is a crucial feature in Puppeteer that allows developers to test how their web applications behave on different mobile devices without actually owning those devices. This comprehensive guide will walk you through various techniques to effectively emulate mobile devices using Puppeteer.

Understanding Mobile Device Emulation

Mobile device emulation in Puppeteer involves simulating several key characteristics of mobile devices:

  • Viewport dimensions (screen width and height)
  • Device pixel ratio (for high-DPI screens)
  • User agent strings (to identify as mobile browsers)
  • Touch events (instead of mouse events)
  • Geolocation (for location-based testing)
  • Network conditions (to simulate mobile networks)

Basic Mobile Device Emulation

Setting Up Basic Mobile Emulation

The simplest way to emulate a mobile device is by using Puppeteer's built-in device descriptors:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({ headless: false });
  const page = await browser.newPage();

  // Emulate iPhone X
  await page.emulate(puppeteer.devices['iPhone X']);

  await page.goto('https://example.com');
  await page.screenshot({ path: 'mobile-view.png' });

  await browser.close();
})();

Available Device Presets

Puppeteer comes with numerous pre-configured device profiles:

const puppeteer = require('puppeteer');

// List all available devices
console.log(Object.keys(puppeteer.devices));

// Common mobile devices
const commonDevices = [
  'iPhone 6',
  'iPhone 6 Plus',
  'iPhone 7',
  'iPhone 8',
  'iPhone X',
  'iPhone XR',
  'iPhone 11',
  'iPhone 12',
  'Samsung Galaxy S9+',
  'Samsung Galaxy Tab S4',
  'iPad',
  'iPad Pro',
  'Pixel 2',
  'Pixel 2 XL'
];

// Use a specific device
const page = await browser.newPage();
await page.emulate(puppeteer.devices['iPhone 11']);

Custom Mobile Device Configuration

Manual Viewport and User Agent Setup

For more control, you can manually configure mobile device properties:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Set viewport for mobile device
  await page.setViewport({
    width: 375,
    height: 667,
    deviceScaleFactor: 2,
    isMobile: true,
    hasTouch: true,
    isLandscape: false
  });

  // Set mobile user agent
  await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1');

  await page.goto('https://example.com');

  await browser.close();
})();

Creating Custom Device Profiles

You can create your own device profiles for specific testing needs:

const customDevice = {
  name: 'Custom Mobile Device',
  userAgent: 'Mozilla/5.0 (Linux; Android 10; SM-G975F) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/91.0.4472.120 Mobile Safari/537.36',
  viewport: {
    width: 414,
    height: 896,
    deviceScaleFactor: 3,
    isMobile: true,
    hasTouch: true,
    isLandscape: false
  }
};

const page = await browser.newPage();
await page.emulate(customDevice);

Advanced Mobile Emulation Techniques

Handling Touch Events

Mobile devices use touch events instead of mouse events. Here's how to simulate touch interactions:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.emulate(puppeteer.devices['iPhone X']);
  await page.goto('https://example.com');

  // Simulate touch tap
  await page.touchscreen.tap(100, 200);

  // Simulate swipe gesture
  await page.touchscreen.swipe(100, 300, 300, 300);

  // Simulate pinch gesture (zoom)
  await page.touchscreen.pinch(200, 200, 1.5);

  await browser.close();
})();

Geolocation Emulation

Many mobile applications rely on geolocation. Here's how to emulate GPS coordinates:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.emulate(puppeteer.devices['iPhone X']);

  // Set geolocation to New York City
  await page.setGeolocation({
    latitude: 40.7128,
    longitude: -74.0060,
    accuracy: 100
  });

  // Grant geolocation permissions
  const context = browser.defaultBrowserContext();
  await context.overridePermissions('https://example.com', ['geolocation']);

  await page.goto('https://example.com');

  await browser.close();
})();

Network Throttling for Mobile

Mobile devices often have slower network connections. Simulate this with network throttling:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.emulate(puppeteer.devices['iPhone X']);

  // Simulate slow 3G network
  await page.emulateNetworkConditions({
    offline: false,
    downloadThroughput: 1.6 * 1024 * 1024 / 8, // 1.6 Mbps
    uploadThroughput: 750 * 1024 / 8, // 750 Kbps
    latency: 40 // 40ms latency
  });

  await page.goto('https://example.com');

  await browser.close();
})();

Testing Responsive Design

Viewport Testing Across Multiple Devices

Test your responsive design across multiple device sizes:

const puppeteer = require('puppeteer');

const devices = ['iPhone 6', 'iPhone X', 'iPad', 'Samsung Galaxy S9+'];

(async () => {
  const browser = await puppeteer.launch();

  for (const deviceName of devices) {
    const page = await browser.newPage();
    await page.emulate(puppeteer.devices[deviceName]);

    await page.goto('https://example.com');
    await page.screenshot({ 
      path: `screenshot-${deviceName.replace(/\s+/g, '-')}.png` 
    });

    await page.close();
  }

  await browser.close();
})();

Orientation Testing

Test both portrait and landscape orientations:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  // Test portrait orientation
  await page.setViewport({
    width: 375,
    height: 667,
    deviceScaleFactor: 2,
    isMobile: true,
    hasTouch: true,
    isLandscape: false
  });

  await page.goto('https://example.com');
  await page.screenshot({ path: 'portrait.png' });

  // Test landscape orientation
  await page.setViewport({
    width: 667,
    height: 375,
    deviceScaleFactor: 2,
    isMobile: true,
    hasTouch: true,
    isLandscape: true
  });

  await page.goto('https://example.com');
  await page.screenshot({ path: 'landscape.png' });

  await browser.close();
})();

Best Practices for Mobile Device Emulation

1. Use Realistic Device Profiles

Always use realistic device profiles that match actual devices your users might have:

// Good: Using actual device specifications
await page.emulate(puppeteer.devices['iPhone 12']);

// Better: Custom profile matching your target audience
const targetDevice = {
  userAgent: 'Mozilla/5.0 (iPhone; CPU iPhone OS 15_0 like Mac OS X)...',
  viewport: {
    width: 390,
    height: 844,
    deviceScaleFactor: 3,
    isMobile: true,
    hasTouch: true
  }
};

2. Test Performance on Mobile

Mobile devices have limited resources. Monitor performance during testing:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.emulate(puppeteer.devices['iPhone X']);

  // Start performance monitoring
  await page.tracing.start({ path: 'trace.json' });

  await page.goto('https://example.com');

  // Get performance metrics
  const metrics = await page.metrics();
  console.log('Performance metrics:', metrics);

  await page.tracing.stop();

  await browser.close();
})();

3. Handle Mobile-Specific Events

Remember that mobile devices behave differently from desktop browsers:

// Wait for mobile-specific events
await page.waitForSelector('.mobile-menu', { visible: true });

// Handle touch-specific interactions
await page.touchscreen.tap(100, 200);

// Check for mobile-specific CSS classes
const isMobile = await page.evaluate(() => {
  return window.getComputedStyle(document.body).getPropertyValue('content').includes('mobile');
});

Python Implementation with Pyppeteer

For Python developers, you can achieve similar mobile device emulation using Pyppeteer:

import asyncio
from pyppeteer import launch

async def mobile_emulation():
    browser = await launch(headless=False)
    page = await browser.newPage()

    # Set mobile viewport
    await page.setViewport({
        'width': 375,
        'height': 667,
        'deviceScaleFactor': 2,
        'isMobile': True,
        'hasTouch': True,
        'isLandscape': False
    })

    # Set mobile user agent
    await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1')

    await page.goto('https://example.com')
    await page.screenshot({'path': 'mobile-view.png'})

    await browser.close()

asyncio.run(mobile_emulation())

Integration with Testing Frameworks

Jest Integration

Integrate mobile device emulation with Jest for automated testing:

const puppeteer = require('puppeteer');

describe('Mobile Device Tests', () => {
  let browser;
  let page;

  beforeAll(async () => {
    browser = await puppeteer.launch();
  });

  beforeEach(async () => {
    page = await browser.newPage();
    await page.emulate(puppeteer.devices['iPhone X']);
  });

  afterEach(async () => {
    await page.close();
  });

  afterAll(async () => {
    await browser.close();
  });

  test('should display mobile navigation', async () => {
    await page.goto('https://example.com');
    const mobileNav = await page.$('.mobile-nav');
    expect(mobileNav).toBeTruthy();
  });
});

Comparison with Other Tools

While Puppeteer excels at mobile device emulation, you might also consider Playwright for device emulation, which offers similar capabilities with additional browser support. For comprehensive testing across multiple browsers, setting up Playwright for multiple browsers provides broader coverage.

Troubleshooting Common Issues

Device Detection Problems

If websites don't recognize your emulated device:

// Ensure all mobile indicators are set
await page.setViewport({
  width: 375,
  height: 667,
  deviceScaleFactor: 2,
  isMobile: true,        // Critical for mobile detection
  hasTouch: true,        // Enable touch events
  isLandscape: false
});

// Set comprehensive mobile user agent
await page.setUserAgent('Mozilla/5.0 (iPhone; CPU iPhone OS 14_4 like Mac OS X) AppleWebKit/605.1.15 (KHTML, like Gecko) Version/14.0.3 Mobile/15E148 Safari/604.1');

Performance Issues

Large viewport sizes can cause performance problems:

// Optimize for performance
await page.setViewport({
  width: 375,
  height: 667,
  deviceScaleFactor: 1, // Reduce for better performance
  isMobile: true,
  hasTouch: true
});

// Disable images for faster loading
await page.setRequestInterception(true);
page.on('request', (req) => {
  if (req.resourceType() === 'image') {
    req.abort();
  } else {
    req.continue();
  }
});

Advanced Configuration Options

Memory Management for Mobile Testing

Mobile devices have limited memory. Configure Puppeteer to simulate these constraints:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch({
    args: [
      '--memory-pressure-off',
      '--max-old-space-size=512' // Limit memory usage
    ]
  });

  const page = await browser.newPage();
  await page.emulate(puppeteer.devices['iPhone X']);

  // Monitor memory usage
  const client = await page.target().createCDPSession();
  await client.send('Runtime.enable');

  const memoryUsage = await client.send('Runtime.getHeapUsage');
  console.log('Memory usage:', memoryUsage);

  await browser.close();
})();

Battery and Power Management

Some mobile-specific features require battery status emulation:

const puppeteer = require('puppeteer');

(async () => {
  const browser = await puppeteer.launch();
  const page = await browser.newPage();

  await page.emulate(puppeteer.devices['iPhone X']);

  // Override battery API
  await page.evaluateOnNewDocument(() => {
    Object.defineProperty(navigator, 'getBattery', {
      value: () => Promise.resolve({
        charging: false,
        chargingTime: Infinity,
        dischargingTime: 3600,
        level: 0.5
      })
    });
  });

  await page.goto('https://example.com');

  await browser.close();
})();

Conclusion

Mobile device emulation in Puppeteer is a powerful feature that enables comprehensive testing of responsive web applications. By combining viewport settings, user agent strings, touch events, and network throttling, you can create realistic mobile testing environments. Remember to use actual device specifications, test across multiple devices and orientations, and integrate mobile testing into your continuous integration pipeline for the best results.

The key to successful mobile device emulation is understanding that it's not just about changing screen size—it's about creating a comprehensive mobile environment that accurately reflects how your users will experience your application on their devices.

Try WebScraping.AI for Your Web Scraping Needs

Looking for a powerful web scraping solution? WebScraping.AI provides an LLM-powered API that combines Chromium JavaScript rendering with rotating proxies for reliable data extraction.

Key Features:

  • AI-powered extraction: Ask questions about web pages or extract structured data fields
  • JavaScript rendering: Full Chromium browser support for dynamic content
  • Rotating proxies: Datacenter and residential proxies from multiple countries
  • Easy integration: Simple REST API with SDKs for Python, Ruby, PHP, and more
  • Reliable & scalable: Built for developers who need consistent results

Getting Started:

Get page content with AI analysis:

curl "https://api.webscraping.ai/ai/question?url=https://example.com&question=What is the main topic?&api_key=YOUR_API_KEY"

Extract structured data:

curl "https://api.webscraping.ai/ai/fields?url=https://example.com&fields[title]=Page title&fields[price]=Product price&api_key=YOUR_API_KEY"

Try in request builder

Related Questions

Get Started Now

WebScraping.AI provides rotating proxies, Chromium rendering and built-in HTML parser for web scraping
Icon