1"use strict";(self.webpackChunkplaywright_dev=self.webpackChunkplaywright_dev||[]).push([["1397"],{75466(e,t,n){n.r(t),n.d(t,{metadata:()=>s,default:()=>u,frontMatter:()=>o,contentTitle:()=>c,toc:()=>h,assets:()=>d});var s=JSON.parse('{"id":"emulation","title":"Emulation","description":"Introduction","source":"@site/docs/emulation.mdx","sourceDirName":".","slug":"/emulation","permalink":"/docs/next/emulation","draft":false,"unlisted":false,"tags":[],"version":"current","frontMatter":{"id":"emulation","title":"Emulation"},"sidebar":"docs","previous":{"title":"Configuration (use)","permalink":"/docs/next/test-use-options"},"next":{"title":"Fixtures","permalink":"/docs/next/test-fixtures"}}'),i=n(74848),a=n(28453),r=n(13554),l=n(41647);n(83137);let o={id:"emulation",title:"Emulation"},c,d={},h=[{value:"Introduction",id:"introduction",level:2},{value:"Devices",id:"devices",level:2},{value:"Viewport",id:"viewport",level:2},{value:"isMobile",id:"ismobile",level:2},{value:"Locale & Timezone",id:"locale--timezone",level:2},{value:"Permissions",id:"permissions",level:2},{value:"Geolocation",id:"geolocation",level:2},{value:"Color Scheme and Media",id:"color-scheme-and-media",level:2},{value:"User Agent",id:"user-agent",level:2},{value:"Offline",id:"offline",level:2},{value:"JavaScript Enabled",id:"javascript-enabled",level:2}];function p(e){let t={a:"a",admonition:"admonition",code:"code",h2:"h2",h6:"h6",p:"p",pre:"pre",strong:"strong",...(0,a.R)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(t.h2,{id:"introduction",children:"Introduction"}),"\n",(0,i.jsxs)(t.p,{children:["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 ",(0,i.jsx)(t.code,{children:'"userAgent"'}),", ",(0,i.jsx)(t.code,{children:'"screenSize"'}),", ",(0,i.jsx)(t.code,{children:'"viewport"'})," and if it ",(0,i.jsx)(t.code,{children:'"hasTouch"'})," enabled. You can also emulate the ",(0,i.jsx)(t.code,{children:'"geolocation"'}),", ",(0,i.jsx)(t.code,{children:'"locale"'})," and ",(0,i.jsx)(t.code,{children:'"timezone"'})," for all tests or for a specific test as well as set the ",(0,i.jsx)(t.code,{children:'"permissions"'})," to show notifications or change the ",(0,i.jsx)(t.code,{children:'"colorScheme"'}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"devices",children:"Devices"}),"\n",(0,i.jsxs)(t.p,{children:["Playwright comes with a ",(0,i.jsx)(t.a,{href:"https://github.com/microsoft/playwright/blob/main/packages/isomorphic/deviceDescriptorsSource.json",children:"registry of device parameters"})," using ",(0,i.jsx)(t.a,{href:"/docs/next/api/class-playwright#playwright-devices",children:"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."]}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig, devices } from '@playwright/test'; // import devices\n\nexport default defineConfig({\n projects: [\n {\n name: 'chromium',\n use: {\n ...devices['Desktop Chrome'],\n },\n },\n {\n name: 'Mobile Safari',\n use: {\n ...devices['iPhone 13'],\n },\n },\n ],\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"const { chromium, devices } = require('playwright');\nconst browser = await chromium.launch();\n\nconst iphone13 = devices['iPhone 13'];\nconst context = await browser.newContext({\n ...iphone13,\n});\n"})})})]}),"\n",(0,i.jsx)("img",{height:"1582",width:"916",alt:"playwright.dev website emulated for iPhone 13",src:"https://user-images.githubusercontent.com/13063165/220411073-76fe59f9-9a2d-463d-8e30-c19a7deca133.png"}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"}),': Pre-configured devices assume a specific platform. For example, "Desktop Chrome" will provide a Windows-specific user agent string.']}),"\n",(0,i.jsx)(t.p,{children:"If you would like to use the user agent specific to the platform that is running the tests, we recommend unsetting the user agent property."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"const context = await browser.newContext({\n ...devices['Desktop Chrome'],\n userAgent: undefined,\n});\n"})}),"\n",(0,i.jsx)(t.h2,{id:"viewport",children:"Viewport"}),"\n",(0,i.jsxs)(t.p,{children:["The viewport is included in the device but you can override it for some tests with ",(0,i.jsx)(t.a,{href:"/docs/next/api/class-page#page-set-viewport-size",children:"page.setViewportSize()"}),"."]}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig, devices } from '@playwright/test';
1\n\nexport default defineConfig({\n projects: [\n {\n name: 'chromium',\n use: {\n ...devices['Desktop Chrome'],\n // It is important to define the `viewport` property after destructuring `devices`,\n // since devices also define the `viewport` for that device.\n viewport: { width: 1280, height: 720 },\n },\n },\n ]\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"// Create context with given viewport\nconst context = await browser.newContext({\n viewport: { width: 1280, height: 1024 }\n});\n"})})})]}),"\n",(0,i.jsx)(t.p,{children:"Test file:"}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.use({\n viewport: { width: 1600, height: 1200 },\n});\n\ntest('my test', async ({ page }) => {\n // ...\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"// Create context with given viewport\nconst context = await browser.newContext({\n viewport: { width: 1280, height: 1024 }\n});\n\n// Resize viewport for individual page\nawait page.setViewportSize({ width: 1600, height: 1200 });\n\n// Emulate high-DPI\nconst context = await browser.newContext({\n viewport: { width: 2560, height: 1440 },\n deviceScaleFactor: 2,\n});\n"})})})]}),"\n",(0,i.jsx)(t.p,{children:"The same works inside a test file."}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.describe('specific viewport block', () => {\n test.use({ viewport: { width: 1600, height: 1200 } });\n\n test('my test', async ({ page }) => {\n // ...\n });\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"// Create context with given viewport\nconst context = await browser.newContext({\n viewport: { width: 1600, height: 1200 }\n});\nconst page = await context.newPage();\n"})})})]}),"\n",(0,i.jsx)(t.h2,{id:"ismobile",children:"isMobile"}),"\n",(0,i.jsx)(t.p,{children:"Whether the meta viewport tag is taken into account and touch events are enabled."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig, devices } from '@playwright/test';\n\nexport default defineConfig({\n projects: [\n {\n name: 'chromium',\n use: {\n ...devices['Desktop Chrome'],\n // It is important to define the `isMobile` property after destructuring `devices`,\n // since devices also define the `isMobile` for that device.\n isMobile: false,\n },\n },\n ]\n});\n"})}),"\n",(0,i.jsx)(t.h2,{id:"locale--timezone",children:"Locale & Timezone"}),"\n",(0,i.jsx)(t.p,{children:"Emulate the browser Locale and Timezone which can be set globally for all tests in the config and then overridden for particular tests."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig } from '@playwright/test';\n\nexport default defineConfig({\n use: {\n // Emulates the browser locale.\n locale: 'en-GB',\n\n // Emulates the browser timezone.\n timezoneId: '
1Europe/Paris',\n },\n});\n"})}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.use({\n locale: 'de-DE',\n timezoneId: 'Europe/Berlin',\n});\n\ntest('my test for de lang in Berlin timezone', async ({ page }) => {\n await page.goto('https://www.bing.com');\n // ...\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"const context = await browser.newContext({\n locale: 'de-DE',\n timezoneId: 'Europe/Berlin',\n});\n"})})})]}),"\n",(0,i.jsx)("img",{height:"1824",width:"2788",alt:"Bing in german lang and timezone",src:"https://user-images.githubusercontent.com/13063165/220416571-ccc96ab1-44bb-4579-8430-64502fc24a15.png"}),"\n",(0,i.jsx)(t.h6,{id:""}),"\n",(0,i.jsxs)(t.p,{children:["Note that this only affects the browser timezone and locale, not the test runner timezone. To set the test runner timezone, you can use the ",(0,i.jsxs)(t.a,{href:"https://nodejs.org/api/cli.html#tz",children:[(0,i.jsx)(t.code,{children:"TZ"})," environment variable"]}),"."]}),"\n",(0,i.jsx)(t.h2,{id:"permissions",children:"Permissions"}),"\n",(0,i.jsx)(t.p,{children:"Allow app to show system notifications."}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig } from '@playwright/test';\n\nexport default defineConfig({\n use: {\n // Grants specified permissions to the browser context.\n permissions: ['notifications'],\n },\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"const context = await browser.newContext({\n permissions: ['notifications'],\n});\n"})})})]}),"\n",(0,i.jsx)(t.p,{children:"Allow notifications for a specific domain."}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test } from '@playwright/test';\n\ntest.beforeEach(async ({ context }) => {\n // Runs before each test and signs in each page.\n await context.grantPermissions(['notifications'], { origin: 'https://skype.com' });\n});\n\ntest('first', async ({ page }) => {\n // page has notifications permission for https://skype.com.\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"await context.grantPermissions(['notifications'], { origin: 'https://skype.com' });\n"})})})]}),"\n",(0,i.jsxs)(t.p,{children:["Revoke all permissions with ",(0,i.jsx)(t.a,{href:"/docs/next/api/class-browsercontext#browser-context-clear-permissions",children:"browserContext.clearPermissions()"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"// Library\nawait context.clearPermissions();\n"})}),"\n",(0,i.jsx)(t.h2,{id:"geolocation",children:"Geolocation"}),"\n",(0,i.jsxs)(t.p,{children:["Grant ",(0,i.jsx)(t.code,{children:'"geolocation"'})," permissions and set geolocation to a specific area."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig } from '@playwright/test';\n\nexport default defineConfig({\n use: {\n // Context geolocation\n geolocation: { longitude: 12.492507, latitude: 41.889938 },\n permissions: ['geolocation'],\n },\n});\n"})}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.use({\n geolocation: { longitude: 41.890221, latitude: 12.492348 },\n permissions: ['geolocation'],\n});\n\ntest('my test with geolocation', async ({ page }) =>
1 {\n // ...\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"const context = await browser.newContext({\n geolocation: { longitude: 41.890221, latitude: 12.492348 },\n permissions: ['geolocation']\n});\n\n"})})})]}),"\n",(0,i.jsx)("img",{height:"1824",width:"2788",alt:"geolocation for italy on bing maps",src:"https://user-images.githubusercontent.com/13063165/220417670-bb22d815-f5cd-47c4-8562-0b88165eac27.png"}),"\n",(0,i.jsx)(t.p,{children:"Change the location later:"}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.use({\n geolocation: { longitude: 41.890221, latitude: 12.492348 },\n permissions: ['geolocation'],\n});\n\ntest('my test with geolocation', async ({ page, context }) => {\n // overwrite the location for this test\n await context.setGeolocation({ longitude: 48.858455, latitude: 2.294474 });\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"await context.setGeolocation({ longitude: 48.858455, latitude: 2.294474 });\n"})})})]}),"\n",(0,i.jsxs)(t.p,{children:[(0,i.jsx)(t.strong,{children:"Note"})," you can only change geolocation for all pages in the context."]}),"\n",(0,i.jsx)(t.h2,{id:"color-scheme-and-media",children:"Color Scheme and Media"}),"\n",(0,i.jsxs)(t.p,{children:["Emulate the users ",(0,i.jsx)(t.code,{children:'"colorScheme"'}),". Supported values are 'light' and 'dark'. You can also emulate the media type with ",(0,i.jsx)(t.a,{href:"/docs/next/api/class-page#page-emulate-media",children:"page.emulateMedia()"}),"."]}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig } from '@playwright/test';\n\nexport default defineConfig({\n use: {\n colorScheme: 'dark',\n },\n});\n"})}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.use({\n colorScheme: 'dark' // or 'light'\n});\n\ntest('my test with dark mode', async ({ page }) => {\n // ...\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"// Create context with dark mode\nconst context = await browser.newContext({\n colorScheme: 'dark' // or 'light'\n});\n\n// Create page with dark mode\nconst page = await browser.newPage({\n colorScheme: 'dark' // or 'light'\n});\n\n// Change color scheme for the page\nawait page.emulateMedia({ colorScheme: 'dark' });\n\n// Change media for page\nawait page.emulateMedia({ media: 'print' });\n"})})})]}),"\n",(0,i.jsx)("img",{height:"1824",width:"2788",alt:"playwright web in dark mode",src:"https://user-images.githubusercontent.com/13063165/220411638-55d2b051-4678-4da7-9f0b-ed22f5a3c47c.png"}),"\n",(0,i.jsx)(t.h2,{id:"user-agent",children:"User Agent"}),"\n",(0,i.jsxs)(t.p,{children:["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 ",(0,i.jsx)(t.code,{children:"userAgent"})," property."]}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.use({ userAgent: 'My user agent' });\n\ntest('my user agent test', async ({ page }) =>
1 {\n // ...\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"const context = await browser.newContext({\n userAgent: 'My user agent'\n});\n"})})})]}),"\n",(0,i.jsx)(t.h2,{id:"offline",children:"Offline"}),"\n",(0,i.jsx)(t.p,{children:"Emulate the network being offline."}),"\n",(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="playwright.config.ts"',children:"import { defineConfig } from '@playwright/test';\n\nexport default defineConfig({\n use: {\n offline: true\n },\n});\n"})}),"\n",(0,i.jsx)(t.admonition,{type:"note",children:(0,i.jsxs)(t.p,{children:["Offline emulation only affects requests that go through the browser's regular network stack, such as page navigations, ",(0,i.jsx)(t.code,{children:"fetch()"}),", ",(0,i.jsx)(t.code,{children:"XMLHttpRequest"})," and WebSockets. It does not affect WebRTC traffic: established ",(0,i.jsx)(t.code,{children:"RTCPeerConnection"}),"s keep sending and receiving media over UDP. To test WebRTC connection loss, interrupt the connection outside the browser, for example by stopping the TURN server or using an OS-level firewall."]})}),"\n",(0,i.jsx)(t.h2,{id:"javascript-enabled",children:"JavaScript Enabled"}),"\n",(0,i.jsx)(t.p,{children:"Emulate a user scenario where JavaScript is disabled."}),"\n",(0,i.jsxs)(r.A,{groupId:"js-flavor",defaultValue:"test",values:[{label:"Test",value:"test"},{label:"Library",value:"library"}],children:[(0,i.jsx)(l.A,{value:"test",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",metastring:'title="tests/example.spec.ts"',children:"import { test, expect } from '@playwright/test';\n\ntest.use({ javaScriptEnabled: false });\n\ntest('test with no JavaScript', async ({ page }) => {\n // ...\n});\n"})})}),(0,i.jsx)(l.A,{value:"library",children:(0,i.jsx)(t.pre,{children:(0,i.jsx)(t.code,{className:"language-js",children:"const context = await browser.newContext({\n javaScriptEnabled: false\n});\n"})})})]})]})}function u(e={}){let{wrapper:t}={...(0,a.R)(),...e.components};return t?(0,i.jsx)(t,{...e,children:(0,i.jsx)(p,{...e})}):p(e)}}}]);
Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.