Playwright Mobile Emulation Tutorial: Complete Guide to Mobile and Responsive Testing

Introduction

Mobile traffic is a major part of modern web applications. A website can work perfectly on desktop and still fail on a smartphone because of a broken menu, incorrect viewport, oversized buttons, horizontal scrolling, or a form that is difficult to use.

This makes Playwright Mobile Emulation an important skill for QA Automation Engineers and SDETs.

In this playwright mobile emulation tutorial, you will learn how to simulate mobile browser environments using Playwright and TypeScript.

You will learn how to:

Playwright provides a device registry with selected desktop, tablet, and mobile configurations. A device profile can configure characteristics such as viewport, screen size, user agent, and touch support.


What Is Playwright Mobile Emulation?

Playwright mobile emulation allows you to simulate selected mobile browser characteristics on your development machine or CI server.

Instead of connecting a physical smartphone, Playwright can configure a browser context with mobile-oriented settings.

Conceptually:

Desktop Computer

       ↓

Playwright

       ↓

Mobile Browser Configuration

       ↓

Viewport + User Agent + Touch + Device Settings

       ↓

Web Application

For example:

import { test } from ‘@playwright/test’;

test(‘mobile homepage’, async ({ page }) => {

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

});

The test becomes mobile-oriented when the Playwright project uses a mobile device descriptor.

use: {

  …devices[‘iPhone 12’]

}

Playwright’s emulation system can also configure geolocation, locale, timezone, permissions, and color scheme.


Mobile Emulation vs Real Mobile Device Testing

Mobile emulation is powerful, but it is not the same as testing on physical devices.

Mobile emulationReal-device testing
Runs on desktop infrastructureRuns on physical hardware
FastUsually slower
Easy to automateRequires device infrastructure
Excellent for responsive UIBetter for hardware behavior
Lower costHigher cost
Good for CI/CDMore complex CI/CD
Does not reproduce every hardware conditionTests real device behavior

Use emulation for

  • Responsive layouts
  • Mobile navigation
  • Mobile forms
  • Viewport testing
  • Touch interactions
  • User-agent-specific behavior
  • Mobile browser automation

Use real devices for

  • Hardware sensors
  • Battery behavior
  • Device-specific performance
  • Camera integration
  • Real network conditions
  • OS-level behavior
  • Physical-device compatibility

A mature Playwright Mobile Testing strategy can use emulation for broad automated coverage and real devices for targeted validation.


Why Use Mobile Emulation in Playwright?

Playwright mobile device emulation is useful because it allows teams to test mobile behavior without maintaining a physical device lab for every test.

Key benefits

  • Fast execution
  • Easy CI/CD integration
  • Repeatable environments
  • Built-in device profiles
  • Multiple devices
  • Responsive viewport testing
  • Touch support
  • Geolocation
  • Permissions
  • Cross-browser projects

It also integrates naturally with the Playwright Testing Framework.


Playwright Mobile Emulation Project Setup

Create a Playwright TypeScript project:

npm init playwright@latest

Choose:

TypeScript

tests

Install Playwright browsers

You can also install Playwright in an existing project:

npm install -D @playwright/test

npx playwright install

A useful project structure is:

playwright-mobile/

├── tests/

│   ├── mobile-login.spec.ts

│   ├── mobile-products.spec.ts

│   └── mobile-checkout.spec.ts

├── pages/

│   ├── LoginPage.ts

│   ├── ProductPage.ts

│   └── CheckoutPage.ts

├── fixtures/

│   └── mobile.fixture.ts

├── playwright.config.ts

├── package.json

└── tsconfig.json

Playwright supports TypeScript directly, although its test runner does not perform full type checking; Playwright recommends running tsc –noEmit separately in CI.


Using Built-In Device Profiles

One of the easiest ways to start Playwright Device Emulation is to use a built-in device profile.

In playwright.config.ts:

import { defineConfig, devices } from ‘@playwright/test’;

export default defineConfig({

  projects: [

    {

      name: ‘Mobile Chrome’,

      use: {

        …devices[‘Pixel 5’]

      }

    },

    {

      name: ‘Mobile Safari’,

      use: {

        …devices[‘iPhone 12’]

      }

    }

  ]

});

Then run:

npx playwright test

Playwright projects allow the same test suite to run against different browsers and device configurations.

To run only the iPhone project:

npx playwright test –project=”Mobile Safari


Playwright iPhone Emulation

A Playwright iPhone emulation test can use a predefined device profile.

import { test, expect } from ‘@playwright/test’;

test(‘iPhone homepage test’, async ({ page }) => {

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

  await expect(

    page.getByRole(‘heading’).first()

  ).toBeVisible();

});

Configuration:

import { defineConfig, devices } from ‘@playwright/test’;

export default defineConfig({

  projects: [

    {

      name: ‘iPhone’,

      use: {

        …devices[‘iPhone 12’]

      }

    }

  ]

});

The device descriptor handles several mobile browser characteristics for you.


Playwright Android Emulation

You can similarly create a Playwright Android emulation project.

import { defineConfig, devices } from ‘@playwright/test’;

export default defineConfig({

  projects: [

    {

      name: ‘Android’,

      use: {

        …devices[‘Pixel 5’]

      }

    }

  ]

});

Then:

npx playwright test –project=Android

This is useful for validating mobile layouts against a Chromium-based mobile configuration.


Custom Viewport and Screen Sizes

Sometimes a predefined device isn’t enough.

You can create a custom mobile viewport:

import { defineConfig } from ‘@playwright/test’;

export default defineConfig({

  use: {

    viewport: {

      width: 390,

      height: 844

    }

  }

});

Or override it for a particular test:

import { test } from ‘@playwright/test’;

test(‘custom mobile viewport’, async ({ page }) => {

  await page.setViewportSize({

    width: 390,

    height: 844

  });

  await page.goto(‘/’);

  // assertions

});

Viewport testing is useful for checking breakpoints such as:

320px

375px

390px

414px

768px

The goal isn’t to test every possible width. Select widths that represent your application’s important responsive breakpoints.


Device Scale Factor and Mobile Settings

A device configuration can include settings such as:

  • Viewport
  • Screen size
  • Device scale factor
  • User agent
  • Touch support

Playwright’s device descriptors bundle selected mobile parameters so you don’t have to configure each one manually.

A custom configuration can look like:

use: {

  viewport: {

    width: 390,

    height: 844

  },

  deviceScaleFactor: 3,

  isMobile: true,

  hasTouch: true

}

Use custom settings only when they represent a meaningful test requirement.


Touch Events and Mobile User Interactions

Mobile applications often use touch-oriented interactions.

Playwright allows touch support through hasTouch.

import { test, expect } from ‘@playwright/test’;

test.use({

  hasTouch: true

});

test(‘mobile touch interaction’, async ({ page }) => {

  await page.goto(‘/products’);

  const button = page.getByRole(‘button’, {

    name: ‘Add to Cart’

  });

  await button.tap();

  await expect(

    page.getByText(/added to cart/i)

  ).toBeVisible();

});

The hasTouch option specifies whether the viewport supports touch events.

Important

Don’t replace every click() with tap().

Use tap() when you specifically want to validate touch-oriented behavior.


User Agent and Mobile Browser Emulation

Some applications change behavior based on the user agent.

You can configure one explicitly:

import { test } from ‘@playwright/test’;

test.use({

  userAgent:

    ‘Mozilla/5.0 (Linux; Android 13; Pixel 7) AppleWebKit/537.36 Chrome/120 Mobile Safari/537.36’

});

test(‘mobile user agent test’, async ({ page }) => {

  await page.goto(‘/’);

  // assertions

});

However, manually creating user-agent strings should generally be avoided when a built-in device descriptor already represents your intended environment.

A device descriptor gives you a more coherent configuration than changing only the user agent.


Geolocation and Permissions

Mobile websites sometimes depend on location.

Examples include:

  • Food delivery
  • Maps
  • Ride booking
  • Local shopping
  • Weather
  • Location-based promotions

Configure geolocation:

import { defineConfig } from ‘@playwright/test’;

export default defineConfig({

  use: {

    geolocation: {

      latitude: 12.9716,

      longitude: 77.5946

    },

    permissions: [‘geolocation’]

  }

});

Playwright supports context-level geolocation and permissions.

Test:

import { test, expect } from ‘@playwright/test’;

test(‘location-based content’, async ({ page }) => {

  await page.goto(‘/nearby’);

  await expect(

    page.getByText(/nearby stores/i)

  ).toBeVisible();

});

For production-quality tests, use non-sensitive test coordinates and avoid depending on unpredictable real-world location data.


Responsive Web Testing with Playwright

Responsive testing verifies that the UI adapts correctly to different screen dimensions.

Consider:

Desktop

   ↓

Tablet

   ↓

Mobile

A responsive test can validate:

  • Navigation changes
  • Mobile menu
  • Column stacking
  • Button sizing
  • Text wrapping
  • Product cards
  • Images
  • Forms
  • Horizontal overflow

Example:

import { test, expect } from ‘@playwright/test’;

test(‘responsive navigation’, async ({ page }) => {

  await page.goto(‘/’);

  const menuButton = page.getByRole(‘button’, {

    name: /menu/i

  });

  await expect(menuButton).toBeVisible();

  await menuButton.click();

  await expect(

    page.getByRole(‘navigation’)

  ).toBeVisible();

});

This is more useful than simply checking that the browser window is small.


Real-World Mobile Login Example

A mobile login test might look like:

import { test, expect } from ‘@playwright/test’;

test(‘mobile user login’, async ({ page }) => {

  await page.goto(‘/login’);

  await page.getByLabel(‘Email’)

    .fill(process.env.TEST_USERNAME!);

  await page.getByLabel(‘Password’)

    .fill(process.env.TEST_PASSWORD!);

  await page.getByRole(‘button’, {

    name: ‘Login’

  }).tap();

  await expect(page).toHaveURL(/dashboard/);

});

This validates both authentication and the mobile presentation of the login workflow.


Mobile Navigation, Menus, Forms, and Touch Interactions

A mobile e-commerce site may have a hamburger menu.

test(‘mobile navigation menu’, async ({ page }) => {

  await page.goto(‘/’);

  await page.getByRole(‘button’, {

    name: /menu/i

  }).tap();

  await expect(

    page.getByRole(‘navigation’)

  ).toBeVisible();

});

For a mobile form:

test(‘mobile checkout form’, async ({ page }) => {

  await page.goto(‘/checkout’);

  await page.getByLabel(‘First name’)

    .fill(‘Test’);

  await page.getByLabel(‘Last name’)

    .fill(‘User’);

  await page.getByLabel(‘Postal code’)

    .fill(‘560001’);

  await expect(

    page.getByRole(‘button’, {

      name: /place order/i

    })

  ).toBeVisible();

});


Page Object Model for Mobile Tests

Mobile tests should use the same maintainable framework principles as desktop tests.

Create:

pages/MobileProductPage.ts

import { Page } from ‘@playwright/test’;

export class ProductPage {

  constructor(private page: Page) {}

  async open(productId: string) {

    await this.page.goto(`/products/${productId}`);

  }

  async addToCart() {

    await this.page.getByRole(‘button’, {

      name: /add to cart/i

    }).tap();

  }

  async openCart() {

    await this.page.getByRole(‘link’, {

      name: /cart/i

    }).tap();

  }

}

Test:

import { test, expect } from ‘@playwright/test’;

import { ProductPage } from ‘../pages/MobileProductPage’;

test(‘mobile product purchase flow’, async ({ page }) => {

  const product = new ProductPage(page);

  await product.open(‘1001’);

  await product.addToCart();

  await product.openCart();

  await expect(

    page.getByRole(‘heading’, {

      name: /shopping cart/i

    })

  ).toBeVisible();

});

The same Page Object can often support desktop and mobile if the underlying application behavior is the same.


Mobile Emulation with Fixtures and Test Projects

Playwright fixtures are useful for reusable mobile setup.

You can define projects:

import { defineConfig, devices } from ‘@playwright/test’;

export default defineConfig({

  projects: [

    {

      name: ‘iPhone’,

      use: {

        …devices[‘iPhone 12’]

      }

    },

    {

      name: ‘Android’,

      use: {

        …devices[‘Pixel 5’]

      }

    }

  ]

});

Playwright projects are specifically designed to run the same tests using different configurations, including mobile devices.

You can also create custom fixtures when your mobile test suite requires reusable setup.

For example:

import { test as base } from ‘@playwright/test’;

export const test = base.extend({

  mobileReady: async ({ page }, use) => {

    await page.goto(‘/’);

    await use(page);

  }

});

Then:

test(‘mobile home page’, async ({

  mobileReady

}) => {

  // test mobile page

});


Screenshots, Videos, Trace Viewer, and Reporting

Mobile failures are often visual.

Configure failure artifacts:

import { defineConfig } from ‘@playwright/test’;

export default defineConfig({

  use: {

    screenshot: ‘only-on-failure’,

    video: ‘retain-on-failure’,

    trace: ‘retain-on-failure’

  },

  reporter: [

    [‘html’],

    [‘list’]

  ]

});

Run:

npx playwright test

Then:

npx playwright show-report

Trace Viewer can help identify:

  • Incorrect viewport
  • Wrong locator
  • Mobile menu not opening
  • Navigation failure
  • Unexpected redirect
  • Timing problems
  • Application errors

For visual validation, you can also use:

await expect(page).toHaveScreenshot(‘mobile-home.png’, {

  fullPage: true

});

This combines Playwright Mobile Testing with visual regression testing.


Cross-Device Testing and Parallel Execution

Create multiple projects:

projects: [

  {

    name: ‘iPhone’,

    use: {

      …devices[‘iPhone 12’]

    }

  },

  {

    name: ‘Android’,

    use: {

      …devices[‘Pixel 5’]

    }

  },

  {

    name: ‘Desktop’,

    use: {

      …devices[‘Desktop Chrome’]

    }

  }

]

Playwright can run projects concurrently subject to the configured worker limits.

Run everything:

npx playwright test

Run one device:

npx playwright test –project=iPhone

For large suites, parallel execution can significantly reduce total runtime.

However, tests must not share mutable state such as the same shopping cart or user account unless the test design intentionally handles it.


Playwright Mobile Emulation with CI/CD

Mobile tests should run automatically in CI.

Example GitHub Actions workflow:

name: Playwright Mobile Tests

on:

  push:

    branches: [main]

  pull_request:

jobs:

  mobile-tests:

    runs-on: ubuntu-latest

    steps:

      – name: Checkout

        uses: actions/checkout@v6

      – name: Setup Node.js

        uses: actions/setup-node@v6

        with:

          node-version: lts/*

      – name: Install dependencies

        run: npm ci

      – name: Install Playwright browsers

        run: npx playwright install –with-deps

      – name: Type check

        run: npx tsc –noEmit

      – name: Run mobile tests

        run: npx playwright test –project=iPhone

      – name: Upload report

        if: ${{ !cancelled() }}

        uses: actions/upload-artifact@v5

        with:

          name: playwright-mobile-report

          path: playwright-report/

Playwright’s CI guidance recommends installing browser dependencies in the CI environment and supports collecting test reports as artifacts.

You can expand the workflow to Android:

npx playwright test –project=Android

or execute both projects in the same pipeline.


Real-World E-Commerce Playwright Mobile Automation Project

A strong portfolio project can be an E-Commerce Playwright Mobile Automation Project.

Recommended structure

ecommerce-mobile/

├── pages/

│   ├── LoginPage.ts

│   ├── HomePage.ts

│   ├── ProductPage.ts

│   ├── CartPage.ts

│   └── CheckoutPage.ts

├── tests/

│   ├── mobile-login.spec.ts

│   ├── mobile-products.spec.ts

│   ├── mobile-cart.spec.ts

│   └── mobile-checkout.spec.ts

├── fixtures/

│   └── mobile.fixture.ts

├── playwright.config.ts

└── package.json

Test 1: Mobile login

Validate:

  • Login form
  • Mobile keyboard behavior
  • Login button
  • Error messages
  • Redirect to dashboard

Test 2: Product listing

Validate:

  • Product cards
  • Responsive layout
  • Product images
  • Category filters
  • Search

Test 3: Product details

Validate:

  • Product information
  • Price
  • Image
  • Add-to-cart button
  • Touch interaction

Test 4: Shopping cart

Validate:

  • Cart item
  • Quantity
  • Price
  • Remove action
  • Total

Test 5: Checkout

Validate:

  • Address form
  • Shipping options
  • Payment fields
  • Order summary
  • Confirmation

Test 6: Multiple devices

Run:

iPhone

Android

Desktop

Test 7: Screenshots

Capture important screens:

await expect(page).toHaveScreenshot(

  ‘mobile-product.png’

);

Test 8: Debugging

Collect:

Screenshots

Videos

Traces

HTML reports

Test 9: CI/CD

Run the complete project through GitHub Actions.

This portfolio project demonstrates:

Playwright + TypeScript + Mobile Emulation + Responsive Testing + POM + Fixtures + Visual Testing + CI/CD + Reporting.


Common Playwright Mobile Emulation Errors and Solutions

ProblemCauseSolution
Desktop layout appearsMobile project not selectedCheck –project
Mobile menu missingIncorrect breakpointVerify viewport
Touch test failsTouch not enabledUse device profile or hasTouch
Geolocation deniedPermission missingAdd permissions: [‘geolocation’]
Wrong responsive layoutIncorrect viewportCheck width/height
User-agent behavior wrongCustom UA mismatchPrefer device descriptors
Screenshot mismatchDifferent environmentStandardize browser/OS
CI mobile test failsBrowser dependency issueRun playwright install –with-deps
Test is flakyShared state/timingIsolate data and use assertions
Element is off-screenResponsive layoutUse locator-based interactions

Playwright Mobile Testing Best Practices

Follow these practices for reliable mobile automation.

1. Prefer built-in device profiles

Start with:

devices[‘iPhone 12’]

or:

devices[‘Pixel 5’]

before creating custom settings.

2. Test important breakpoints

Don’t test hundreds of viewport sizes.

Focus on business-critical responsive breakpoints.

3. Test behavior, not just dimensions

Check:

  • Navigation
  • Forms
  • Buttons
  • Menus
  • Product cards
  • Checkout

4. Use accessible locators

Prefer:

page.getByRole(‘button’)

over brittle CSS selectors.

5. Use Page Object Model

Keep mobile interaction logic reusable.

6. Isolate test data

Avoid shared carts and accounts.

7. Use screenshots strategically

Visual testing is valuable for important mobile layouts.

8. Capture traces on failures

This makes CI failures easier to investigate.

9. Use CI for regression testing

Run mobile projects on every important pull request.

10. Don’t treat emulation as a replacement for real devices

Use physical devices when hardware-specific behavior matters.


Playwright Mobile Emulation Interview Questions with Answers

1. What is Playwright mobile emulation?

It is the process of configuring Playwright to simulate selected mobile browser characteristics such as viewport, user agent, screen size, and touch support.

2. How do I use mobile emulation in Playwright?

Use a built-in device descriptor:

use: {

  …devices[‘iPhone 12’]

}

3. What is a Playwright device profile?

A device profile is a predefined set of browser-context settings representing a selected device configuration.

4. Can Playwright emulate an iPhone?

Yes. Playwright includes selected mobile device descriptors such as iPhone profiles.

5. Can Playwright emulate Android?

Yes. You can use an Android-oriented device profile such as Pixel 5.

6. What is hasTouch?

hasTouch indicates whether the emulated viewport supports touch events.

hasTouch: true

7. Can Playwright test geolocation?

Yes.

geolocation: {

  latitude: 12.9716,

  longitude: 77.5946

},

permissions: [‘geolocation’]

8. Is Playwright mobile emulation the same as real-device testing?

No. Emulation reproduces browser/device characteristics but does not reproduce every hardware and operating-system condition of a physical device.

9. How do you test multiple mobile devices?

Create multiple Playwright projects using different device descriptors.

10. How do you debug mobile test failures?

Use:

HTML Report

Screenshots

Videos

Trace Viewer

Console logs

Then check the viewport, device configuration, locators, application state, and test data.


Learning Roadmap for Beginners

If you are new to Playwright Mobile Emulation, follow this sequence.

Step 1: Learn Playwright basics

Understand:

  • Locators
  • Assertions
  • Browser
  • Context
  • Page
  • Auto-waiting

Step 2: Learn Playwright TypeScript

Practice:

  • Classes
  • Interfaces
  • Async/await
  • Modules
  • Types

Step 3: Learn device profiles

Start with:

iPhone

Android

Tablet

Step 4: Learn responsive testing

Practice different:

Viewport widths

Navigation layouts

Forms

Product cards

Step 5: Learn mobile interactions

Practice:

tap()

Touch support

Mobile menus

Scrolling

Step 6: Learn advanced emulation

Study:

  • User agent
  • Geolocation
  • Permissions
  • Locale
  • Timezone
  • Color scheme

Step 7: Learn framework architecture

Add:

Step 8: Learn CI/CD

Practice:

Step 9: Build the e-commerce project

Publish a sanitized version on GitHub.

This gives you a portfolio project demonstrating real-world Playwright Responsive Testing and mobile automation skills.


FAQs: Playwright Mobile Emulation Tutorial

What is Playwright mobile emulation?

Playwright mobile emulation simulates selected mobile browser characteristics such as viewport, screen size, user agent, and touch support.

How do I use mobile emulation in Playwright?

Configure a device project:

projects: [

  {

    name: ‘iPhone’,

    use: {

      …devices[‘iPhone 12’]

    }

  }

]

Does Playwright support iPhone emulation?

Yes. Playwright provides selected iPhone device descriptors.

Does Playwright support Android emulation?

Yes. Android-oriented device profiles are available through Playwright’s device registry.

Can Playwright emulate touch?

Yes. Device profiles can enable touch support, and you can configure hasTouch explicitly.

Can Playwright emulate GPS?

Yes. Use geolocation and grant the appropriate permission.

Is mobile emulation enough for mobile testing?

It is excellent for automated responsive and browser-level testing, but real devices remain important for hardware- and OS-specific validation.

Can Playwright mobile tests run in CI/CD?

Yes. Mobile device projects can run in CI just like other Playwright projects.

Can I perform visual testing on mobile?

Yes. You can combine mobile device projects with Playwright screenshot assertions.

Leave a Comment

Your email address will not be published. Required fields are marked *