Back to Blog
Platform

Device Emulation Guide: Mobile, Tablet, and Desktop Profiles

How to emulate complete device identities including touch events, screen metrics, and mobile UA for authentic mobile and desktop profiles.

Introduction

A browser reveals its device through dozens of signals: screen dimensions, device pixel ratio, touch capabilities, device memory, GPU characteristics, input modalities, and more. These signals form a coherent picture of the physical device running the browser. A Pixel 7 has specific screen dimensions, a specific DPR, a specific number of touch points, a specific GPU, and specific memory. When these signals are consistent, the browser appears to be running on real hardware. When they conflict, the inconsistency is visible.

BotBrowser loads complete device profiles captured from real hardware. When a mobile profile is loaded on a desktop system, all device signals update consistently because they all come from the same source device. There is no mix-and-match, no manual configuration of individual properties, and no risk of signal conflicts.

Privacy Impact: Why Device Signals Matter

Device emulation is important for several reasons beyond just appearing as a mobile or desktop browser.

Tracking systems use device signals as part of their fingerprinting process. The combination of screen resolution, DPR, touch support, device memory, GPU renderer, and CPU core count creates a device-level fingerprint that persists across sessions. Controlling these signals is necessary for maintaining consistent browser identities and for studying how tracking systems use device characteristics.

E-commerce and content platforms serve different experiences based on the detected device. Mobile users may see different pricing, different layouts, and different content selections. Privacy researchers need device-accurate emulation to study these practices reliably.

For multi-account management, device diversity is important. Having every identity present as the same device model with identical screen dimensions is suspicious. Using a variety of device profiles, mixing desktop and mobile, different screen sizes, and different DPR values, creates natural variation.

Technical Background

Device Signals in the Browser

The browser exposes device characteristics through multiple APIs:

Screen dimensions: screen.width, screen.height, screen.availWidth, screen.availHeight report the physical display size. window.innerWidth and window.innerHeight report the viewport. window.outerWidth and window.outerHeight include browser chrome.

Device pixel ratio: window.devicePixelRatio reports the ratio between CSS pixels and physical pixels. Desktop displays typically have DPR of 1.0 or 1.25. Mobile devices range from 2.0 to 3.5 or higher. Retina MacBooks report 2.0.

Touch capabilities: navigator.maxTouchPoints reports the maximum simultaneous touch points (0 for desktop, 5-10 for mobile). The ontouchstart event handler availability on the window object indicates touch support. CSS media queries (pointer: coarse) and (hover: none) distinguish touch-primary from pointer-primary input.

Device memory: navigator.deviceMemory reports approximate RAM in GB. Mobile devices typically report 4-8 GB, desktops 8-16 GB.

Hardware concurrency: navigator.hardwareConcurrency reports the number of CPU cores available. Mobile devices typically report 4-8, desktops 4-16 or more.

Connection info: navigator.connection provides network type, effective type, downlink speed, and RTT. Mobile devices often report different network characteristics than desktop systems.

GPU: The WebGL renderer string identifies the graphics hardware. Mobile GPUs (Adreno, Mali, PowerVR, Apple GPU) differ completely from desktop GPUs (NVIDIA GeForce, AMD Radeon, Intel UHD).

Signal Consistency Requirements

These signals must be internally consistent. A browser reporting maxTouchPoints: 10 but (pointer: fine) and (hover: hover) contains a contradiction. A browser with a 412px screen width but 16 GB device memory and an NVIDIA GPU combines mobile screen dimensions with desktop hardware characteristics. These inconsistencies make it clear that individual signals have been spoofed rather than coming from a real device.

Common Approaches and Their Limitations

Chrome DevTools Device Emulation

Chrome DevTools Protocol provides device emulation through Emulation.setDeviceMetricsOverride. This sets viewport dimensions, DPR, and touch support. Playwright and Puppeteer expose this through their device emulation APIs.

Limitations:

  • Does not change navigator.platform or User-Agent data beyond what is explicitly set
  • WebGL renderer strings still report the desktop GPU
  • navigator.deviceMemory and navigator.hardwareConcurrency remain at desktop values
  • Touch emulation is surface-level, not engine-level
  • Font availability remains desktop-specific
  • Media queries may not fully align with the emulated device

Manual Property Overrides

You can override individual properties through JavaScript injection:

Object.defineProperty(navigator, 'maxTouchPoints', { get: () => 10 });
Object.defineProperty(navigator, 'deviceMemory', { get: () => 4 });

This changes the JavaScript-visible values but does not affect the actual behavior of the browser. CSS media queries, rendering pipeline behavior, and HTTP headers are unaffected by JavaScript property overrides.

Viewport-Only Approaches

Setting a mobile viewport size (e.g., 412x915) through the automation framework changes the layout but does not change any other device signal. The browser still reports desktop screen dimensions, desktop DPR, zero touch points, and desktop GPU information.

BotBrowser's Approach

BotBrowser profiles are captured from real devices, meaning all device signals come from the same physical hardware. When loaded on any system, these signals are applied together at the engine level, ensuring complete internal consistency.

Profile-Based Device Identity

Each profile contains a snapshot of the device's characteristics:

  • Screen dimensions (width, height, available width, available height)
  • Device pixel ratio
  • Touch capabilities (maxTouchPoints, touch event support)
  • Device memory
  • Hardware concurrency
  • GPU renderer and vendor strings
  • Platform-specific navigator properties
  • Window chrome dimensions (for calculating outer dimensions)

All of these signals are applied as a unit, not individually. This eliminates the risk of signal conflicts.

Engine-Level Touch Support

When a mobile profile is loaded, touch support is enabled at the Chromium engine level, not through JavaScript injection:

  • navigator.maxTouchPoints returns the device's actual value
  • ontouchstart is natively available on the window object
  • CSS media queries (pointer: coarse) and (hover: none) evaluate correctly in the style engine
  • Touch event constructors and properties behave exactly as they do on the real device
  • The InputDeviceCapabilities API reports touch correctly

Desktop, Mobile, and Tablet Profiles

BotBrowser supports profiles from all device categories:

Desktop profiles: Large screens (1920x1080, 2560x1440), DPR of 1.0-2.0, zero touch points, fine pointer, desktop GPU, 8-16 GB memory.

Mobile profiles: Small screens (412x915, 390x844), DPR of 2.0-3.5, touch support with 5-10 points, coarse pointer, mobile GPU, 4-8 GB memory.

Tablet profiles: Medium screens (1024x1366, 820x1180), DPR of 2.0, touch support, sometimes both coarse and fine pointer, mobile or integrated GPU.

Window and Screen Configuration

BotBrowser provides fine-grained control over window and screen properties through CLI flags:

# Use the profile's captured dimensions (default for headless)
--bot-config-window=profile
--bot-config-screen=profile

# Specific dimensions
--bot-config-window=1920x1080
--bot-config-screen=2560x1440

# Full JSON customization
--bot-config-window='{"innerWidth":1920,"innerHeight":1080,"devicePixelRatio":2}'

Configuration and Usage

Mobile Device Profile

chrome --bot-profile="/profiles/pixel7-chrome-130.enc" \
       --user-data-dir="$(mktemp -d)"

Playwright Integration

const { chromium } = require('playwright-core');

(async () => {
  const browser = await chromium.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/profiles/pixel7-chrome-130.enc',
    ],
    headless: true,
  });

  // Important: do not set viewport - let the profile control it
  const context = await browser.newContext();
  const page = await context.newPage();

  const metrics = await page.evaluate(() => ({
    screenWidth: screen.width,
    screenHeight: screen.height,
    innerWidth: window.innerWidth,
    innerHeight: window.innerHeight,
    dpr: devicePixelRatio,
    touchPoints: navigator.maxTouchPoints,
    touchStart: 'ontouchstart' in window,
    pointer: matchMedia('(pointer: coarse)').matches ? 'coarse' : 'fine',
    hover: matchMedia('(hover: none)').matches ? 'none' : 'hover',
    memory: navigator.deviceMemory,
    cores: navigator.hardwareConcurrency,
  }));

  console.log('Device metrics:', metrics);
  await browser.close();
})();

Puppeteer with Desktop Profile

const puppeteer = require('puppeteer-core');

(async () => {
  const browser = await puppeteer.launch({
    executablePath: '/path/to/botbrowser/chrome',
    args: [
      '--bot-profile=/profiles/win11-desktop-1080p.enc',
    ],
    headless: true,
    defaultViewport: null, // Let the profile control viewport
  });

  const page = await browser.newPage();
  await page.goto('https://example.com');
  await browser.close();
})();

Custom Window Size with Profile

# Override just the window size, keep everything else from the profile
chrome --bot-profile="/profiles/win11-chrome-130.enc" \
       --bot-config-window=1440x900 \
       --bot-config-screen=1920x1080

Verification

Verify device emulation by checking the full range of device signals:

const page = await context.newPage();
await page.goto('https://example.com');

const deviceCheck = await page.evaluate(() => ({
  // Screen
  screen: {
    width: screen.width,
    height: screen.height,
    availWidth: screen.availWidth,
    availHeight: screen.availHeight,
  },
  // Window
  window: {
    innerWidth: window.innerWidth,
    innerHeight: window.innerHeight,
    outerWidth: window.outerWidth,
    outerHeight: window.outerHeight,
    dpr: window.devicePixelRatio,
  },
  // Touch
  touch: {
    maxTouchPoints: navigator.maxTouchPoints,
    ontouchstart: 'ontouchstart' in window,
    pointerCoarse: matchMedia('(pointer: coarse)').matches,
    hoverNone: matchMedia('(hover: none)').matches,
  },
  // Hardware
  hardware: {
    deviceMemory: navigator.deviceMemory,
    hardwareConcurrency: navigator.hardwareConcurrency,
  },
}));

console.log('Device verification:', JSON.stringify(deviceCheck, null, 2));
Device Profile Signal Categories Display screen.width/height devicePixelRatio inner/outerWidth colorDepth Input maxTouchPoints pointer: coarse/fine hover: none/hover ontouchstart Hardware deviceMemory hardwareConcurrency WebGL GPU connection type BotBrowser Profile: All signals from one device Internal consistency guaranteed Every signal comes from the same source device capture. No manual configuration. No signal conflicts.

Best Practices

  • Always use defaultViewport: null in Playwright and Puppeteer. This lets the profile control viewport dimensions. Framework viewport settings override profile values, breaking consistency.
  • Choose device profiles that match your use case. For general web automation, use common device models. For mobile testing, use profiles from popular phone models.
  • Do not mix manual overrides with profiles. Let the profile control the full device identity. Manual overrides (like setting a custom viewport on a mobile profile) risk creating signal inconsistencies.
  • Verify all signal categories. Check screen, touch, hardware, and GPU signals together, not individually.
  • Use --bot-config-window and --bot-config-screen for controlled overrides. When you need specific dimensions, these flags adjust the display properties while keeping all other signals consistent.
  • Match device to use case. For e-commerce testing, use consumer phone profiles. For enterprise testing, use desktop profiles with typical office monitor resolutions.

Frequently Asked Questions

Does BotBrowser generate actual touch events?

BotBrowser enables touch support at the engine level, meaning maxTouchPoints, ontouchstart, and CSS media queries all report correctly. To generate touch event sequences (tap, swipe, pinch), use your automation framework's touch input APIs. Playwright provides page.touchscreen.tap() and Puppeteer provides similar methods.

What happens if I set a viewport in Playwright with a mobile profile?

Setting a viewport through Playwright or Puppeteer overrides the profile's window dimensions. This can create inconsistencies between innerWidth/innerHeight (set by the framework) and screen.width/screen.height (set by the profile). Use defaultViewport: null to avoid this.

Can I customize screen dimensions while keeping other device signals?

Yes. Use --bot-config-window and --bot-config-screen to override display dimensions while keeping touch, memory, GPU, and other signals from the profile.

How does devicePixelRatio work with screenshots?

When taking screenshots, the actual pixel dimensions of the image are width * devicePixelRatio by height * devicePixelRatio. A 412px wide mobile viewport with DPR 2.625 produces screenshots that are 1081 pixels wide.

Do tablet profiles have touch support?

Yes. Tablet profiles include touch support (typically maxTouchPoints: 10) along with tablet-appropriate screen dimensions and DPR values.

Can I use different device profiles for different contexts in the same browser?

Device characteristics are set at the browser instance level through the profile. Different contexts within the same browser share the same device signals. For different device identities, launch separate browser instances with different profiles.

What GPU strings do mobile profiles report?

Mobile profiles report the GPU from the source device. Common examples include "Adreno (TM) 730" for Qualcomm-based devices, "Mali-G710" for Samsung Exynos devices, and "Apple GPU" for iPhones.

Summary

Device emulation in BotBrowser provides complete, consistent device identities through profiles captured from real hardware. All device signals, from screen dimensions and touch capabilities to GPU strings and device memory, come from the same source device, ensuring internal consistency without manual configuration.

For related topics, see Android Emulation for mobile-specific emulation, Screen and Window Fingerprinting for screen signal details, and Cross-Platform Profiles for running profiles across operating systems.

#device#emulation#touch#mobile#platform