模拟
介绍
¥Introduction
使用 Playwright,你可以在任何浏览器上测试你的应用,也可以模拟真实的设备,例如手机或平板电脑。只需配置你想要模拟的设备,Playwright 将模拟浏览器行为,例如 "userAgent"、"screenSize"、"viewport" 以及是否启用了 "hasTouch"。你还可以为所有测试或特定测试模拟 "geolocation"、"locale" 和 "timezone",以及设置 "permissions" 以显示通知或更改 "colorScheme"。
¥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 为选定的台式机、平板电脑和移动设备提供了使用 playwright.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.
- Test
- Library
import { defineConfig, devices } from '@playwright/test'; // import devices
export default defineConfig({
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
},
},
{
name: 'Mobile Safari',
use: {
...devices['iPhone 13'],
},
},
],
});
const { chromium, devices } = require('playwright');
const browser = await chromium.launch();
const iphone13 = devices['iPhone 13'];
const context = await browser.newContext({
...iphone13,
});
视口
¥Viewport
视口包含在设备中,但你可以使用 page.setViewportSize() 覆盖它以进行某些测试。
¥The viewport is included in the device but you can override it for some tests with page.setViewportSize().
- Test
- Library
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
// It is important to define the `viewport` property after destructuring `devices`,
// since devices also define the `viewport` for that device.
viewport: { width: 1280, height: 720 },
},
},
]
});
// Create context with given viewport
const context = await browser.newContext({
viewport: { width: 1280, height: 1024 }
});
测试文件:
¥Test file:
- Test
- Library
import { test, expect } from '@playwright/test';
test.use({
viewport: { width: 1600, height: 1200 },
});
test('my 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 test file.
- Test
- Library
import { test, expect } from '@playwright/test';
test.describe('specific viewport block', () => {
test.use({ viewport: { width: 1600, height: 1200 } });
test('my test', async ({ page }) => {
// ...
});
});
// Create context with given viewport
const context = await browser.newContext({
viewport: { width: 1600, height: 1200 }
});
const page = await context.newPage();
isMobile
是否考虑元视口标签并启用触摸事件。
¥Whether the meta viewport tag is taken into account and touch events are enabled.
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'chromium',
use: {
...devices['Desktop Chrome'],
// It is important to define the `isMobile` property after destructuring `devices`,
// since devices also define the `isMobile` for that device.
isMobile: false,
},
},
]
});
区域设置和时区
¥Locale & Timezone
模拟浏览器的语言环境和时区,这些设置可以在配置中为所有测试全局设置,然后针对特定测试进行覆盖。
¥Emulate the browser Locale and Timezone which can be set globally for all tests in the config and then overridden for particular tests.
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// Emulates the browser locale.
locale: 'en-GB',
// Emulates the browser timezone.
timezoneId: 'Europe/Paris',
},
});
- Test
- 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 }) => {
await page.goto('https://www.bing.com');
// ...
});
const context = await browser.newContext({
locale: 'de-DE',
timezoneId: 'Europe/Berlin',
});
请注意,这仅影响浏览器时区和语言环境,而不影响测试运行器时区。要设置测试运行器时区,你可以使用 TZ 环境变量。
¥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 TZ environment variable.
权限
¥Permissions
允许应用显示系统通知。
¥Allow app to show system notifications.
- Test
- Library
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// Grants specified permissions to the browser context.
permissions: ['notifications'],
},
});
const context = await browser.newContext({
permissions: ['notifications'],
});
允许特定域的通知。
¥Allow notifications for a specific domain.
- Test
- Library
import { test } from '@playwright/test';
test.beforeEach(async ({ context }) => {
// Runs before each test and signs in each page.
await context.grantPermissions(['notifications'], { origin: 'https://skype.com' });
});
test('first', async ({ page }) => {
// page has notifications permission for https://skype.com.
});
await context.grantPermissions(['notifications'], { origin: 'https://skype.com' });
使用 browserContext.clearPermissions() 撤销所有权限。
¥Revoke all permissions with browserContext.clearPermissions().
// Library
await context.clearPermissions();
地理定位
¥Geolocation
授予 "geolocation" 权限并将地理位置设置为特定区域。
¥Grant "geolocation" permissions and set geolocation to a specific area.
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
// Context geolocation
geolocation: { longitude: 12.492507, latitude: 41.889938 },
permissions: ['geolocation'],
},
});
- Test
- Library
import { test, expect } from '@playwright/test';
test.use({
geolocation: { longitude: 41.890221, latitude: 12.492348 },
permissions: ['geolocation'],
});
test('my test with geolocation', async ({ page }) => {
// ...
});
const context = await browser.newContext({
geolocation: { longitude: 41.890221, latitude: 12.492348 },
permissions: ['geolocation']
});
稍后更改位置:
¥Change the location later:
- Test
- Library
import { test, expect } from '@playwright/test';
test.use({
geolocation: { longitude: 41.890221, latitude: 12.492348 },
permissions: ['geolocation'],
});
test('my test with geolocation', async ({ page, context }) => {
// overwrite the location for this test
await context.setGeolocation({ longitude: 48.858455, latitude: 2.294474 });
});
await context.setGeolocation({ longitude: 48.858455, latitude: 2.294474 });
请注意,你只能更改上下文中所有页面的地理位置。
¥Note you can only change geolocation for all pages in the context.
配色方案和媒体
¥Color Scheme and Media
模拟用户 "colorScheme"。支持的值是 'light' 和 'dark'。你还可以使用 page.emulateMedia() 模拟媒体类型。
¥Emulate the users "colorScheme". Supported values are 'light' and 'dark'. You can also emulate the media type with page.emulateMedia().
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
colorScheme: 'dark',
},
});
- Test
- Library
import { test, expect } from '@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
用户代理包含在设备中,因此你很少需要更改它,但是如果你确实需要测试不同的用户代理,你可以使用 userAgent 属性覆盖它。
¥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.
- Test
- Library
import { test, expect } from '@playwright/test';
test.use({ userAgent: 'My user agent' });
test('my user agent test', async ({ page }) => {
// ...
});
const context = await browser.newContext({
userAgent: 'My user agent'
});
离线
¥Offline
模拟网络离线。
¥Emulate the network being offline.
import { defineConfig } from '@playwright/test';
export default defineConfig({
use: {
offline: true
},
});
启用 JavaScript
¥JavaScript Enabled
模拟禁用 JavaScript 的用户场景。
¥Emulate a user scenario where JavaScript is disabled.
- Test
- Library
import { test, expect } from '@playwright/test';
test.use({ javaScriptEnabled: false });
test('test with no JavaScript', async ({ page }) => {
// ...
});
const context = await browser.newContext({
javaScriptEnabled: false
});