Emulation
With Playwright you can test your app on any browser as well as emulate a real device such as a mobile phone or tablet. Simply configure the devices you would like to emulate and Playwright will simulate the browser behavior such as "userAgent", "screenSize", "viewport" and if it "hasTouch" enabled. You can also emulate the "geolocation", "locale" and "timezone" for all tests or for a specific test as well as set the "permissions" to show notifications or change the "colorScheme".
Devices
Playwright comes with a registry of device parameters using playwright.devices for selected desktop, tablet and mobile devices. It can be used to simulate browser behavior for a specific device such as user agent, screen size, viewport and if it has touch enabled. All tests will run with the specified device parameters.
- TypeScript
- JavaScript
- Library
// playwright.config.ts
import { type PlaywrightTestConfig, devices } from '@playwright/test'; // import devices
const config: PlaywrightTestConfig = {
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
{
name: 'Mobile Safari',
use: {
...devices['iPhone 12'],
},
},
],
};
export default config;
// playwright.config.js
// @ts-check
const { devices } = require('@playwright/test'); // require devices
/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
{
name: 'Mobile Safari',
use: {
...devices['iPhone 12'],
},
},
],
};
module.exports = config;
const { chromium, devices } = require('playwright');
const browser = await chromium.launch();
const iphone12 = devices['iPhone 12'];
const context = await browser.newContext({
...iphone12,
});
Viewport
The viewport is included in the device but you can override it for some tests with page.setViewportSize(viewportSize).
- TypeScript
- JavaScript
- Library
import { test, expect } from '@playwright/test';
// Run tests in this file with portrait-like viewport.
test.use({
viewport: { width: 600, height: 900 },
});
test('my portrait test', async ({ page }) => {
// ...
});
const { test, expect } = require('@playwright/test');
// Run tests in this file with portrait-like viewport.
test.use({
viewport: { width: 600, height: 900 },
});
test('my portrait test', async ({ page }) => {
// ...
});
// Create context with given viewport
const context = await browser.newContext({
viewport: { width: 1280, height: 1024 }
});
// Resize viewport for individual page
await page.setViewportSize({ width: 1600, height: 1200 });
// Emulate high-DPI
const context = await browser.newContext({
viewport: { width: 2560, height: 1440 },
deviceScaleFactor: 2,
});
The same works inside a describe block.
- TypeScript
- JavaScript
import { test, expect } from '@playwright/test';
test.describe('locale block', () => {
// Run tests in this describe block with portrait-like viewport.
test.use({ viewport: { width: 600, height: 900 } });
test('my portrait test', async ({ page }) => {
// ...
});
});
const { test, expect } = require('@playwright/test');
test.describe('locale block', () => {
// Run tests in this describe block with portrait-like viewport.
test.use({ viewport: { width: 600, height: 900 } });
test('my portrait test', async ({ page }) => {
// ...
});
});
Locale & Timezone
Emulate the user Locale and Timezone which can be set globally for all tests in the config and then overridden for particular tests.
- TypeScript
- JavaScript
- Library
import { test, expect } from '@playwright/test';
test.use({
locale: 'de-DE',
timezoneId: 'Europe/Berlin',
});
test('my test for de lang in Berlin timezone', async ({ page }) => {
// ...
});
const { test, expect } = require('@playwright/test');
test.use({
locale: 'de-DE',
timezoneId: 'Europe/Berlin',
});
test('my test for de lang in Berlin timezone', async ({ page }) => {
// ...
});
// Emulate locale and time
const context = await browser.newContext({
locale: 'de-DE',
timezoneId: 'Europe/Berlin',
});
Permissions
Allow app to show system notifications.
- TypeScript
- JavaScript
- Library
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
use: {
permissions: ['notifications'],
},
};
export default config;
// @ts-check
/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
use: {
permissions: ['notifications'],
},
};
module.exports = config;
const context = await browser.newContext({
permissions: ['notifications'],
});
Allow test to request current location.
- TypeScript
- JavaScript
- Library
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
use: {
permissions: ['geolocation'],
},
};
export default config;
// @ts-check
/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
use: {
permissions: ['geolocation'],
},
};
module.exports = config;
await context.grantPermissions(['geolocation']);
Allow notifications for a specific domain.
- TypeScript
- JavaScript
- Library
import type { PlaywrightTestConfig } from '@playwright/test';
const config: PlaywrightTestConfig = {
use: {
permissions: ['notifications'], {origin: 'https://skype.com'},
},
};
export default config;
// @ts-check
/** @type {import('@playwright/test').PlaywrightTestConfig} */
const config = {
use: {
permissions: ['notifications'], {origin: 'https://skype.com'},
},
};
module.exports = config;
await context.grantPermissions(['notifications'], {origin: 'https://skype.com'} );
Revoke all permissions with browserContext.clearPermissions().
// Library
await context.clearPermissions();
Geolocation
Create a test with "geolocation" permissions granted and geolocation set to a specific area.
- TypeScript
- JavaScript
- Library
import { test, expect } from '@playwright/test';
test.use({
geolocation: { longitude: 48.858455, latitude: 2.294474 },
permissions: ['geolocation'],
});
test('my test with geolocation', async ({ page }) => {
// ...
});
const { test, expect } = require('@playwright/test');
test.use({
geolocation: { longitude: 48.858455, latitude: 2.294474 },
permissions: ['geolocation'],
});
test('my test with geolocation', async ({ page }) => {
// ...
});
const context = await browser.newContext({
geolocation: { longitude: 48.858455, latitude: 2.294474 },
permissions: ['geolocation']
});
Change the location later:
await context.setGeolocation({ longitude: 29.979097, latitude: 31.134256 });
Note you can only change geolocation for all pages in the context.
Color Scheme and Media
Create a test that emulates the users "colorScheme". Supported values are 'light', 'dark', 'no-preference'. You can also emulate the media type with page.emulateMedia([options]).
- TypeScript
- JavaScript
- Library
import { test, expect } from '@playwright/test';
test.use({
colorScheme: 'dark' // or 'light'
});
test('my test with dark mode', async ({ page }) => {
// ...
});
const { test, expect } = require('@playwright/test');
test.use({
colorScheme: 'dark' // or 'light'
});
test('my test with dark mode', async ({ page }) => {
// ...
});
// Create context with dark mode
const context = await browser.newContext({
colorScheme: 'dark' // or 'light'
});
// Create page with dark mode
const page = await browser.newPage({
colorScheme: 'dark' // or 'light'
});
// Change color scheme for the page
await page.emulateMedia({ colorScheme: 'dark' });
// Change media for page
await page.emulateMedia({ media: 'print' });
User Agent
The User Agent is included in the device and therefore you will rarely need to change it however if you do need to test a different user agent you can override it with the userAgent property.
- TypeScript
- JavaScript
- Library
import { test, expect } from '@playwright/test';
test.use({ userAgent: 'My user agent'});
test('my user agent test', async ({ page }) => {
// ...
});
const { test, expect } = require('@playwright/test');
test.use({ userAgent: 'My user agent' });
test('my user agent test', async ({ page }) => {
// ...
});
const context = await browser.newContext({
userAgent: 'My user agent'
});
JavaScript Enabled
Emulate a user scenario where JavaScript is disabled.
- TypeScript
- JavaScript
- Library
import { test, expect } from '@playwright/test';
test.use({ javaScriptEnabled: false });
test('test with no JavaScript', async ({ page }) => {
// ...
});
const { test, expect } = require('@playwright/test');
test.use({ javaScriptEnabled: false });
test('test with no JavaScript', async ({ page }) => {
// ...
});
const context = await browser.newContext({
javaScriptEnabled: false
});