diff --git a/docs/src/emulation.md b/docs/src/emulation.md
index 786f184209..12b7a9d6f0 100644
--- a/docs/src/emulation.md
+++ b/docs/src/emulation.md
@@ -3,37 +3,69 @@ id: emulation
title: "Emulation"
---
-Playwright allows overriding various parameters of the device where the browser is running:
-- viewport size, device scale factor, touch support
-- locale, timezone
-- color scheme
-- geolocation
-
-Most of these parameters are configured during the browser context construction, but some of them such as viewport size
-can be changed for individual pages.
-
-
-
-## Playwright Test vs. Library
-* langs: js
-
-:::caution
-This guide is for [Playwright Library](./library.md), if you are using Playwright Test (`@playwright/test`) see [here](./test-configuration.md).
-:::
+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
-* langs: js, python, csharp
+* langs: js, csharp, python
-Playwright comes with a registry of device parameters for selected mobile devices. It can be used to simulate browser
-behavior on a mobile device:
+Playwright comes with a [registry of device parameters](https://github.com/microsoft/playwright/blob/main/packages/playwright-core/src/server/deviceDescriptorsSource.json) using [`property: 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.
-```js
+```js tab=js-ts
+// 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;
+```
+
+```js tab=js-js
+// 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;
+```
+
+```js tab=js-library
const { chromium, devices } = require('playwright');
const browser = await chromium.launch();
-const pixel2 = devices['Pixel 2'];
+const iphone12 = devices['iPhone 12'];
const context = await browser.newContext({
- ...pixel2,
+ ...iphone12,
});
```
@@ -42,10 +74,10 @@ import asyncio
from playwright.async_api import async_playwright
async def run(playwright):
- pixel_2 = playwright.devices['Pixel 2']
+ iphone_12 = playwright.devices['iPhone 12']
browser = await playwright.webkit.launch(headless=False)
context = await browser.new_context(
- **pixel_2,
+ **iphone_12,
)
async def main():
@@ -58,10 +90,10 @@ asyncio.run(main())
from playwright.sync_api import sync_playwright
def run(playwright):
- pixel_2 = playwright.devices['Pixel 2']
+ iphone_12 = playwright.devices['iPhone 12']
browser = playwright.webkit.launch(headless=False)
context = browser.new_context(
- **pixel_2,
+ **iphone_12,
)
with sync_playwright() as playwright:
@@ -81,61 +113,43 @@ class Program
{
Headless: False
});
- var pixel2 = playwright.Devices["Pixel 2"];
- await using var context = await browser.NewContextAsync(pixel2);
+ var iphone12 = playwright.Devices["iPhone 12"];
+ await using var context = await browser.NewContextAsync(iphone12);
}
}
```
-All pages created in the context above will share the same device parameters.
+## Viewport
-### API reference
-- [`property: Playwright.devices`]
-- [`method: Browser.newContext`]
+The viewport is included in the device but you can override it for some tests with [`method: Page.setViewportSize`].
-
+```js tab=js-ts
+import { test, expect } from '@playwright/test';
-## User agent
+// Run tests in this file with portrait-like viewport.
+test.use({
+ viewport: { width: 600, height: 900 },
+});
-All pages created in the context above will share the user agent specified:
-
-```js
-const context = await browser.newContext({
- userAgent: 'My user agent'
+test('my portrait test', async ({ page }) => {
+ // ...
});
```
-```java
-BrowserContext context = browser.newContext(new Browser.NewContextOptions()
- .setUserAgent("My user agent"));
+```js tab=js-js
+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 }) => {
+ // ...
+});
```
-```python async
-context = await browser.new_context(
- user_agent='My user agent'
-)
-```
-
-```python sync
-context = browser.new_context(
- user_agent='My user agent'
-)
-```
-
-```csharp
-var context = await browser.NewContextAsync(new BrowserNewContextOptions { UserAgent = "My User Agent" });
-```
-
-### API reference
-- [`method: Browser.newContext`]
-
-
-
-## Viewport
-
-Create a context with custom viewport size:
-
-```js
+```js tab=js-library
// Create context with given viewport
const context = await browser.newContext({
viewport: { width: 1280, height: 1024 }
@@ -150,6 +164,33 @@ const context = await browser.newContext({
deviceScaleFactor: 2,
});
```
+The same works inside a describe block.
+
+```js tab=js-ts
+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 }) => {
+ // ...
+ });
+});
+```
+
+```js tab=js-js
+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 }) => {
+ // ...
+ });
+});
+```
```java
// Create context with given viewport
@@ -213,16 +254,37 @@ await using var context = await browser.NewContextAsync(new()
DeviceScaleFactor = 2
});
```
+## Locale & Timezone
-### API reference
-- [`method: Browser.newContext`]
-- [`method: Page.setViewportSize`]
+Emulate the user Locale and Timezone which can be set globally for all tests in the config and then overridden for particular tests.
-
+```js tab=js-ts
+import { test, expect } from '@playwright/test';
-## Locale & timezone
+test.use({
+ locale: 'de-DE',
+ timezoneId: 'Europe/Berlin',
+});
-```js
+test('my test for de lang in Berlin timezone', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-js
+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 }) => {
+ // ...
+});
+```
+
+```js tab=js-library
// Emulate locale and time
const context = await browser.newContext({
locale: 'de-DE',
@@ -260,17 +322,34 @@ await using var context = await browser.NewContextAsync(new()
TimezoneId = "Europe/Berlin"
});
```
-
-### API reference
-- [`method: Browser.newContext`]
-
-
-
## Permissions
-Allow all pages in the context to show system notifications:
+Allow app to show system notifications.
-```js
+```js tab=js-js
+// @ts-check
+
+/** @type {import('@playwright/test').PlaywrightTestConfig} */
+const config = {
+ use: {
+ permissions: ['notifications'],
+ },
+};
+
+module.exports = config;
+```
+
+```js tab=js-ts
+import type { PlaywrightTestConfig } from '@playwright/test';
+const config: PlaywrightTestConfig = {
+ use: {
+ permissions: ['notifications'],
+ },
+};
+export default config;
+```
+
+```js tab=js-library
const context = await browser.newContext({
permissions: ['notifications'],
});
@@ -293,9 +372,32 @@ context = browser.new_context(
)
```
-Grant all pages in the existing context access to current location:
+Allow test to request current location.
-```js
+```js tab=js-js
+// @ts-check
+
+/** @type {import('@playwright/test').PlaywrightTestConfig} */
+const config = {
+ use: {
+ permissions: ['geolocation'],
+ },
+};
+
+module.exports = config;
+```
+
+```js tab=js-ts
+import type { PlaywrightTestConfig } from '@playwright/test';
+const config: PlaywrightTestConfig = {
+ use: {
+ permissions: ['geolocation'],
+ },
+};
+export default config;
+```
+
+```js tab=js-library
await context.grantPermissions(['geolocation']);
```
@@ -315,9 +417,32 @@ context.grant_permissions(['geolocation'])
await context.GrantPermissionsAsync(new[] { "geolocation" });
```
-Grant notifications access from a specific domain:
+Allow notifications for a specific domain.
-```js
+```js tab=js-js
+// @ts-check
+
+/** @type {import('@playwright/test').PlaywrightTestConfig} */
+const config = {
+ use: {
+ permissions: ['notifications'], {origin: 'https://skype.com'},
+ },
+};
+
+module.exports = config;
+```
+
+```js tab=js-ts
+import type { PlaywrightTestConfig } from '@playwright/test';
+const config: PlaywrightTestConfig = {
+ use: {
+ permissions: ['notifications'], {origin: 'https://skype.com'},
+ },
+};
+export default config;
+```
+
+```js tab=js-library
await context.grantPermissions(['notifications'], {origin: 'https://skype.com'} );
```
@@ -338,9 +463,10 @@ context.grant_permissions(['notifications'], origin='https://skype.com')
await context.GrantPermissionsAsync(new[] { "notifications" }, origin: "https://skype.com");
```
-Revoke all permissions:
+Revoke all permissions with [`method: BrowserContext.clearPermissions`].
```js
+// Library
await context.clearPermissions();
```
@@ -359,23 +485,42 @@ context.clear_permissions()
```csharp
await context.ClearPermissionsAsync();
```
-
-### API reference
-- [`method: Browser.newContext`]
-- [`method: BrowserContext.grantPermissions`]
-- [`method: BrowserContext.clearPermissions`]
-
-
-
## Geolocation
-Create a context with `"geolocation"` permissions granted:
+Create a test with `"geolocation"` permissions granted and geolocation set to a specific area.
-```js
+```js tab=js-ts
+import { test, expect } from '@playwright/test';
+
+test.use({
+ geolocation: { longitude: 48.858455, latitude: 2.294474 },
+ permissions: ['geolocation'],
+});
+
+test('my test with geolocation', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-js
+const { test, expect } = require('@playwright/test');
+
+test.use({
+ geolocation: { longitude: 48.858455, latitude: 2.294474 },
+ permissions: ['geolocation'],
+});
+
+test('my test with geolocation', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-library
const context = await browser.newContext({
geolocation: { longitude: 48.858455, latitude: 2.294474 },
permissions: ['geolocation']
});
+
```
```java
@@ -429,18 +574,35 @@ await context.SetGeolocationAsync(new Geolocation() { Longitude = 48.858455f, La
```
**Note** you can only change geolocation for all pages in the context.
+## Color Scheme and Media
-### API reference
-- [`method: Browser.newContext`]
-- [`method: BrowserContext.setGeolocation`]
+Create a test that emulates the users `"colorScheme"`. Supported values are 'light', 'dark', 'no-preference'. You can also emulate the media type with [`method: Page.emulateMedia`].
-
+```js tab=js-ts
+import { test, expect } from '@playwright/test';
-## Color scheme and media
+test.use({
+ colorScheme: 'dark' // or 'light'
+});
-Create a context with dark or light mode. Pages created in this context will follow this color scheme preference.
+test('my test with dark mode', async ({ page }) => {
+ // ...
+});
+```
-```js
+```js tab=js-js
+const { test, expect } = require('@playwright/test');
+
+test.use({
+ colorScheme: 'dark' // or 'light'
+});
+
+test('my test with dark mode', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-library
// Create context with dark mode
const context = await browser.newContext({
colorScheme: 'dark' // or 'light'
@@ -535,7 +697,82 @@ await page.EmulateMediaAsync(new()
Media = Media.Print
});
```
+## User Agent
-### API reference
-- [`method: Browser.newContext`]
-- [`method: Page.emulateMedia`]
\ No newline at end of file
+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.
+
+```js tab=js-ts
+import { test, expect } from '@playwright/test';
+
+test.use({ userAgent: 'My user agent'});
+
+test('my user agent test', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-js
+const { test, expect } = require('@playwright/test');
+
+test.use({ userAgent: 'My user agent' });
+
+test('my user agent test', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-library
+const context = await browser.newContext({
+ userAgent: 'My user agent'
+});
+```
+
+```java
+BrowserContext context = browser.newContext(new Browser.NewContextOptions()
+ .setUserAgent("My user agent"));
+```
+
+```python async
+context = await browser.new_context(
+ user_agent='My user agent'
+)
+```
+
+```python sync
+context = browser.new_context(
+ user_agent='My user agent'
+)
+```
+
+```csharp
+var context = await browser.NewContextAsync(new BrowserNewContextOptions { UserAgent = "My User Agent" });
+```
+## JavaScript Enabled
+
+Emulate a user scenario where JavaScript is disabled.
+
+```js tab=js-ts
+import { test, expect } from '@playwright/test';
+
+test.use({ javaScriptEnabled: false });
+
+test('test with no JavaScript', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-js
+const { test, expect } = require('@playwright/test');
+
+test.use({ javaScriptEnabled: false });
+
+test('test with no JavaScript', async ({ page }) => {
+ // ...
+});
+```
+
+```js tab=js-library
+const context = await browser.newContext({
+ javaScriptEnabled: false
+});
+```
\ No newline at end of file
diff --git a/docs/src/test-configuration-js.md b/docs/src/test-configuration-js.md
index aa2ebbd943..820cdf2789 100644
--- a/docs/src/test-configuration-js.md
+++ b/docs/src/test-configuration-js.md
@@ -5,7 +5,7 @@ title: "Configuration"
Playwright Test provides options to configure the default `browser`, `context` and `page` fixtures. For example there are options for `headless`, `viewport` and `ignoreHTTPSErrors`. You can also record a video or a trace for the test or capture a screenshot at the end.
-Finally, there are plenty of testing options like `timeout` or `testDir` that configure how your tests are collected and executed.
+There are plenty of testing options like `timeout` or `testDir` that configure how your tests are collected and executed.
You can specify any options globally in the configuration file, and most of them locally in a test file.
@@ -13,7 +13,7 @@ See the full list of [test options][TestOptions] and all [configuration properti
## Global configuration
-Create `playwright.config.js` (or `playwright.config.ts`) and specify options in the [`property: TestConfig.use`] section.
+Create a `playwright.config.js` (or `playwright.config.ts`) and specify options in the [`property: TestConfig.use`] section.
```js tab=js-js
// @ts-check
@@ -47,7 +47,7 @@ export default config;
Now run tests as usual, Playwright Test will pick up the configuration file automatically.
```bash
-npx playwright test --browser=firefox
+npx playwright test
```
If you put your configuration file in a different place, pass it with `--config` option.
@@ -58,15 +58,13 @@ npx playwright test --config=tests/my.config.js
## Local configuration
-With [`method: Test.use`] you can override some options for a file or a [`method: Test.describe#1`] block.
+You can override some options for a file or describe block.
```js tab=js-js
// example.spec.js
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 }) => {
// ...
});
@@ -75,10 +73,8 @@ test('my portrait test', async ({ page }) => {
```js tab=js-ts
// example.spec.ts
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 }) => {
// ...
});
@@ -89,11 +85,9 @@ The same works inside describe.
```js tab=js-js
// example.spec.js
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 }) => {
// ...
});
@@ -103,11 +97,9 @@ test.describe('locale block', () => {
```js tab=js-ts
// example.spec.ts
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 }) => {
// ...
});
@@ -116,7 +108,9 @@ test.describe('locale block', () => {
## Basic options
-These are commonly used options for various scenarios. You usually set them globally in [configuration file](#global-configuration).
+Normally you would start with emulating a device, for example Desktop Chromium. See our [Emulation](./emulation.md) guide to learn more.
+
+Here are some of the commonly used options for various scenarios. You usually set them globally in the [configuration file](#global-configuration).
- `actionTimeout` - Timeout for each Playwright action in milliseconds. Defaults to `0` (no timeout). Learn more about [various timeouts](./test-timeouts.md).
- `baseURL` - Base URL used for all pages in the context. Allows navigating by using just the path, for example `page.goto('/settings')`.
@@ -126,6 +120,11 @@ These are commonly used options for various scenarios. You usually set them glob
- `headless` - Whether to run the browser in headless mode.
- `viewport` - Viewport used for all pages in the context.
- `storageState` - Populates context with given storage state. Useful for easy authentication, [learn more](./auth.md).
+- `colorScheme` - Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`.
+- `geolocation` - Context geolocation.
+- `locale` - [Emulates](./emulation.md) the user locale, for example `en-GB`, `de-DE`, etc.
+- `permissions` - A list of permissions to grant to all pages in the context.
+- `timezoneId` - Changes the timezone of the context.
```js tab=js-js
// @ts-check
@@ -231,111 +230,6 @@ Running 1 test using 1 worker
✓ [firefox] › example.spec.ts:3:1 › basic test (2s)
```
-## Emulation
-
-Playwright can [emulate different environments](./emulation.md) like mobile device, locale or timezone.
-
-Here is an example configuration that runs tests in "Pixel 4" and "iPhone 11" emulation modes. Note that it uses the [projects](./test-advanced.md#projects) feature to run the same set of tests in multiple configurations.
-
-```js tab=js-js
-// playwright.config.js
-// @ts-check
-const { devices } = require('@playwright/test');
-
-/** @type {import('@playwright/test').PlaywrightTestConfig} */
-const config = {
- projects: [
- // "Pixel 4" tests use Chromium browser.
- {
- name: 'Pixel 4',
- use: {
- browserName: 'chromium',
- ...devices['Pixel 4'],
- },
- },
-
- // "iPhone 11" tests use WebKit browser.
- {
- name: 'iPhone 11',
- use: {
- browserName: 'webkit',
- ...devices['iPhone 11'],
- },
- },
- ],
-};
-
-module.exports = config;
-```
-
-```js tab=js-ts
-// playwright.config.ts
-import { type PlaywrightTestConfig, devices } from '@playwright/test';
-
-const config: PlaywrightTestConfig = {
- projects: [
- // "Pixel 4" tests use Chromium browser.
- {
- name: 'Pixel 4',
- use: {
- browserName: 'chromium',
- ...devices['Pixel 4'],
- },
- },
-
- // "iPhone 11" tests use WebKit browser.
- {
- name: 'iPhone 11',
- use: {
- browserName: 'webkit',
- ...devices['iPhone 11'],
- },
- },
- ],
-};
-export default config;
-```
-
-You can specify options separately instead of using predefined devices. There are also more options such as locale, geolocation, and timezone which can be configured.
-
-- `colorScheme` - Emulates `'prefers-colors-scheme'` media feature, supported values are `'light'`, `'dark'`, `'no-preference'`.
-- `deviceScaleFactor` - Specify device scale factor (can be thought of as dpr). Defaults to `1`.
-- `geolocation` - Context geolocation.
-- `hasTouch` - Specifies if device supports touch events.
-- `isMobile` - Whether the `meta viewport` tag is taken into account and touch events are enabled.
-- `javaScriptEnabled` - Whether or not to enable JavaScript in the context.
-- `locale` - User locale, for example `en-GB`, `de-DE`, etc.
-- `permissions` - A list of permissions to grant to all pages in the context.
-- `timezoneId` - Changes the timezone of the context.
-- `userAgent` - Specific user agent to use in the context.
-
-```js tab=js-js
-// @ts-check
-
-/** @type {import('@playwright/test').PlaywrightTestConfig} */
-const config = {
- use: {
- locale: 'fr-FR',
- geolocation: { longitude: 48.858455, latitude: 2.294474 },
- permissions: ['geolocation'],
- },
-};
-
-module.exports = config;
-```
-
-```js tab=js-ts
-import type { PlaywrightTestConfig } from '@playwright/test';
-const config: PlaywrightTestConfig = {
- use: {
- locale: 'fr-FR',
- geolocation: { longitude: 48.858455, latitude: 2.294474 },
- permissions: ['geolocation'],
- },
-};
-export default config;
-```
-
## Network
Available options to configure networking: