docs: add titles for remaining examples (#22939)

Co-authored-by: Max Schmitt <max@schmitt.mx>
This commit is contained in:
Debbie O'Brien 2023-05-10 23:30:51 +02:00 committed by GitHub
parent 7e2a35ead4
commit 759d14b881
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
28 changed files with 128 additions and 247 deletions

View File

@ -223,8 +223,7 @@ The following example demonstrates creating and using a test fixture that covers
This example fixture creates an `AxeBuilder` object which is pre-configured with shared `withTags()` and `exclude()` configuration.
```js tab=js-ts
// axe-test.ts
```js tab=js-ts title="axe-test.ts"
import { test as base } from '@playwright/test';
import AxeBuilder from '@axe-core/playwright';

View File

@ -1666,8 +1666,7 @@ tests/
And the following `page-click.spec.ts` that uses `toHaveScreenshot()` call:
```js
// page-click.spec.ts
```js title="page-click.spec.ts"
import { test, expect } from '@playwright/test';
test.describe('suite', () => {

View File

@ -43,8 +43,7 @@ This is the **recommended** approach for tests **without server-side state**. Au
Create `auth.setup.ts` that will prepare authenticated browser state for all other tests.
```js
// auth.setup.ts
```js title="auth.setup.ts"
import { test as setup } from '@playwright/test';
const authFile = 'playwright/.auth/user.json';
@ -104,8 +103,7 @@ export default defineConfig({
Tests start already authenticated because we specified `storageState` in the config.
```js
// tests/example.spec.ts
```js title="tests/example.spec.ts"
import { test } from '@playwright/test';
test('test', async ({ page }) => {
@ -131,8 +129,7 @@ We will authenticate once per [worker process](./test-parallel.md#worker-process
Create `playwright/fixtures.ts` file that will [override `storageState` fixture](./test-fixtures.md#overriding-fixtures) to authenticate once per worker. Use [`property: TestInfo.parallelIndex`] to differentiate between workers.
```js
// playwright/fixtures.ts
```js title="playwright/fixtures.ts"
import { test as baseTest } from '@playwright/test';
import fs from 'fs';
import path from 'path';
@ -187,9 +184,7 @@ export const test = baseTest.extend<{}, { workerStorageState: string }>({
Now, each test file should import `test` from our fixtures file instead of `@playwright/test`. No changes are needed in the config.
```js
// tests/example.spec.ts
```js title="tests/example.spec.ts"
// Important: import our fixtures.
import { test, expect } from '../playwright/fixtures';
@ -319,8 +314,7 @@ We will send the API request with [APIRequestContext] and then save authenticate
In the [setup project](#basic-shared-account-in-all-tests):
```js
// auth.setup.ts
```js title="auth.setup.ts"
import { test as setup } from '@playwright/test';
const authFile = 'playwright/.auth/user.json';
@ -339,8 +333,7 @@ setup('authenticate', async ({ request }) => {
Alternatively, in a [worker fixture](#moderate-one-account-per-parallel-worker):
```js
// playwright/fixtures.ts
```js title="playwright/fixtures.ts"
import { test as baseTest, request } from '@playwright/test';
import fs from 'fs';
import path from 'path';
@ -396,8 +389,7 @@ export const test = baseTest.extend<{}, { workerStorageState: string }>({
We will authenticate multiple times in the setup project.
```js
// auth.setup.ts
```js title="auth.setup.ts"
import { test as setup } from '@playwright/test';
const adminFile = 'playwright/.auth/admin.json';
@ -445,8 +437,7 @@ setup('authenticate as user', async ({ page }) => {
After that, specify `storageState` for each test file or test group, **instead of** setting it in the config.
```js
// tests/example.spec.ts
```js title="tests/example.spec.ts"
import { test } from '@playwright/test';
test.use({ storageState: 'playwright/.auth/admin.json' });
@ -474,8 +465,7 @@ test.describe(() => {
Use multiple [BrowserContext]s and [Page]s with different storage states in the same test.
```js
// tests/example.spec.ts
```js title="tests/example.spec.ts"
import { test } from '@playwright/test';
test('admin and user', async ({ browser }) => {
@ -506,8 +496,7 @@ You can introduce fixtures that will provide a page authenticated as each role.
Below is an example that [creates fixtures](./test-fixtures.md#creating-a-fixture) for two [Page Object Models](./pom.md) - admin POM and user POM. It assumes `adminStorageState.json` and `userStorageState.json` files were created in the global setup.
```js
// playwright/fixtures.ts
```js title="playwright/fixtures.ts"
import { test as base, Page, Browser, Locator } from '@playwright/test';
// Page Object Model for the "admin" page.
@ -562,8 +551,9 @@ export const test = base.extend<MyFixtures>({
},
});
```
// tests/example.spec.ts
```js title="tests/example.spec.ts"
// Import test with our new fixtures.
import { test, expect } from './fixtures';

View File

@ -101,8 +101,7 @@ To have the extension loaded when running tests you can use a test fixture to se
First, add fixtures that will load the extension:
```js
// fixtures.ts
```js title="fixtures.ts"
import { test as base, expect, chromium, type BrowserContext } from '@playwright/test';
import path from 'path';
@ -142,8 +141,7 @@ export const test = base.extend<{
export const expect = test.expect;
```
```python
# conftest.py
```python title="conftest.py"
from typing import Generator
from pathlib import Path
from playwright.sync_api import Playwright, BrowserContext
@ -198,8 +196,7 @@ test('popup page', async ({ page, extensionId }) => {
});
```
```python
# test_foo.py
```python title="test_foo.py"
from playwright.sync_api import expect, Page
@ -216,8 +213,8 @@ def test_popup_page(page: Page, extension_id: str) -> None:
## Headless mode
By default, Chrome's headless mode in Playwright does not support Chrome extensions. To overcome this limitation, you can run Chrome's persistent context with a new headless mode by using the following code:
```js
// fixtures.ts
```js title="fixtures.ts"
// ...
const pathToExtension = path.join(__dirname, 'my-extension');
@ -232,8 +229,7 @@ const context = await chromium.launchPersistentContext('', {
// ...
```
```python
# conftest.py
```python title="conftest.py"
path_to_extension = Path(__file__).parent.joinpath("my-extension")
context = playwright.chromium.launch_persistent_context(
"",

View File

@ -20,8 +20,7 @@ Get started by installing Playwright and running the example file to see it in a
}>
<TabItem value="java">
```java
// src/main/java/org/example/App.java
```java title="src/main/java/org/example/App.java"
package org.example;
import com.microsoft.playwright.*;

View File

@ -125,8 +125,7 @@ python -m asyncio
You can use Playwright with [Pyinstaller](https://www.pyinstaller.org/) to create standalone executables.
```py
# main.py
```py title="main.py"
from playwright.sync_api import sync_playwright
with sync_playwright() as p:

View File

@ -11,8 +11,7 @@ Playwright provides APIs to **monitor** and **modify** network traffic, both HTT
You don't have to configure anything to mock network requests. Just define a custom [Route] that mocks network for a browser context.
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ context }) => {
@ -28,8 +27,7 @@ test('loads page without css', async ({ page }) => {
Alternatively, you can use [`method: Page.route`] to mock network in a single page.
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test('loads page without images', async ({ page }) => {

View File

@ -13,8 +13,7 @@ Page objects **simplify authoring** by creating a higher-level API which suits y
We will create a `PlaywrightDevPage` helper class to encapsulate common operations on the `playwright.dev` page. Internally, it will use the `page` object.
```js tab=js-js
// playwright-dev-page.js
```js tab=js-js title="playwright-dev-page.js"
const { expect } = require('@playwright/test');
exports.PlaywrightDevPage = class PlaywrightDevPage {
@ -46,8 +45,7 @@ exports.PlaywrightDevPage = class PlaywrightDevPage {
}
```
```js tab=js-ts
// playwright-dev-page.ts
```js tab=js-ts title="playwright-dev-page.ts"
import { expect, Locator, Page } from '@playwright/test';
export class PlaywrightDevPage {
@ -81,8 +79,7 @@ export class PlaywrightDevPage {
}
```
```js tab=js-library
// models/PlaywrightDevPage.js
```js tab=js-library title="models/PlaywrightDevPage.js"
class PlaywrightDevPage {
/**
* @param {import('playwright').Page} page
@ -109,8 +106,7 @@ module.exports = { PlaywrightDevPage };
Now we can use the `PlaywrightDevPage` class in our tests.
```js tab=js-js
// example.spec.js
```js tab=js-js title="example.spec.js"
const { test, expect } = require('@playwright/test');
const { PlaywrightDevPage } = require('./playwright-dev-page');
@ -138,8 +134,7 @@ test('should show Page Object Model article', async ({ page }) => {
});
```
```js tab=js-ts
// example.spec.ts
```js tab=js-ts title="example.spec.ts"
import { test, expect } from '@playwright/test';
import { PlaywrightDevPage } from './playwright-dev-page';
@ -167,8 +162,7 @@ test('should show Page Object Model article', async ({ page }) => {
});
```
```js tab=js-library
// example.spec.js
```js tab=js-library title="example.spec.js"
const { PlaywrightDevPage } = require('./playwright-dev-page');
// In the test
@ -192,8 +186,7 @@ await expect(playwrightDev.tocList).toHaveText([
Page object models wrap over a Playwright [Page].
```java
// models/SearchPage.java
```java title="models/SearchPage.java"
package models;
import com.microsoft.playwright;
@ -218,8 +211,7 @@ public class SearchPage {
}
```
```python async
# models/search.py
```python async title="models/search.py"
class SearchPage:
def __init__(self, page):
self.page = page
@ -233,8 +225,7 @@ class SearchPage:
await self.search_term_input.press("Enter")
```
```python sync
# models/search.py
```python sync title="models/search.py"
class SearchPage:
def __init__(self, page):
self.page = page
@ -292,8 +283,7 @@ searchPage.navigate();
searchPage.search("search query");
```
```python async
# test_search.py
```python async title="test_search.py"
from models.search import SearchPage
# in the test
@ -303,8 +293,7 @@ await search_page.navigate()
await search_page.search("search query")
```
```python sync
# test_search.py
```python sync title="test_search.py"
from models.search import SearchPage
# in the test

View File

@ -615,8 +615,7 @@ Use these to configure your app for tests.
For example, this could be used to setup App router in Vue.js:
```js
// src/component.spec.ts
```js title="src/component.spec.ts"
import { test } from '@playwright/experimental-ct-vue';
import { Component } from './mycomponent';
@ -629,8 +628,7 @@ test('should work', async ({ mount }) => {
});
```
```js
// playwright/index.ts
```js title="playwright/index.ts"
import { router } from '../router';
import { beforeMount } from '@playwright/experimental-ct-vue/hooks';
@ -641,8 +639,7 @@ beforeMount(async ({ app, hooksConfig }) => {
A similar configuration in Next.js would look like this:
```js
// src/component.spec.jsx
```js title="src/component.spec.jsx"
import { test } from '@playwright/experimental-ct-react';
import { Component } from './mycomponent';
@ -659,8 +656,7 @@ test('should work', async ({ mount }) => {
});
```
```js
// playwright/index.js
```js title="playwright/index.js"
import router from 'next/router';
import { beforeMount } from '@playwright/experimental-ct-react/hooks';
@ -805,8 +801,7 @@ WebServer is now considered "ready" if request to the specified url has any of t
Here is what a typical component test looks like:
```ts
// App.spec.tsx
```ts title="App.spec.tsx"
import { test, expect } from '@playwright/experimental-ct-react';
import App from './App';

View File

@ -127,8 +127,7 @@ Additionally, any network request made by the **Page** (including its sub-[Frame
Many Service Worker implementations simply execute the request from the page (possibly with some custom caching/offline logic omitted for simplicity):
```js
// filename: transparent-service-worker.js
```js title="transparent-service-worker.js"
self.addEventListener("fetch", (event) => {
// actually make the request
const responsePromise = fetch(event.request);
@ -180,8 +179,7 @@ When a Service Worker handles a page's request, the Service Worker can make 0 to
Consider the code snippets below to understand Playwright's view into the Request/Responses and how it impacts routing in some of these cases.
```js
// filename: complex-service-worker.js
```js title="complex-service-worker.js"
self.addEventListener("install", function (event) {
event.waitUntil(
caches.open("v1").then(function (cache) {

View File

@ -103,8 +103,7 @@ npx playwright test --grep "(?=.*@fast)(?=.*@slow)"
For example, you can run a group of tests just in Chromium by passing a callback.
```js
// example.spec.ts
```js title="example.spec.ts"
test.describe('chromium only', () => {
test.skip(({ browserName }) => browserName !== 'chromium', 'Chromium only!');
@ -127,8 +126,7 @@ test.describe('chromium only', () => {
To avoid running `beforeEach` hooks, you can put annotations in the hook itself.
```js
// example.spec.ts
```js title="example.spec.ts"
test.beforeEach(async ({ page, isMobile }) => {
test.fixme(isMobile, 'Settings page does not work in mobile yet');
@ -147,8 +145,7 @@ test('user profile', async ({ page }) => {
It's also possible to add custom metadata in the form of annotations to your tests. Annotations are key/value pairs accessible via [`test.info().annotations`](./api/class-testinfo#test-info-annotations). Many reporters show annotations, for example `'html'`.
```js
// example.spec.ts
```js title="example.spec.ts"
test('user profile', async ({ page }) => {
test.info().annotations.push({ type: 'issue', description: 'https://github.com/microsoft/playwright/issues/<some-issue>' });

View File

@ -85,8 +85,7 @@ You can access all the same [Fixtures] as the test function itself, and also the
**Usage**
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test.afterEach(async ({ page }, testInfo) => {
@ -123,8 +122,7 @@ You can use [`method: Test.afterAll`] to teardown any resources set up in `befor
**Usage**
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test.beforeAll(async () => {
@ -163,8 +161,7 @@ You can use [`method: Test.afterEach`] to teardown any resources set up in `befo
**Usage**
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test.beforeEach(async ({ page }, testInfo) => {
@ -551,8 +548,7 @@ Extends the `test` object by defining fixtures and/or options that can be used i
First define a fixture and/or an option.
```js tab=js-js
// my-test.js
```js tab=js-js title="my-test.js"
const base = require('@playwright/test');
const { TodoPage } = require('./todo-page');
@ -600,8 +596,7 @@ export const test = base.extend<Options & { todoPage: TodoPage }>({
Then use the fixture in the test.
```js
// example.spec.ts
```js title="example.spec.ts"
import { test } from './my-test';
test('test 1', async ({ todoPage }) => {

View File

@ -607,8 +607,7 @@ export default defineConfig({
Now you can use a relative path when navigating the page:
```js
// test.spec.ts
```js title="test.spec.ts"
import { test } from '@playwright/test';
test('test', async ({ page }) => {

View File

@ -20,8 +20,7 @@ export default defineConfig({
Alternatively, with [`method: Test.use`] you can override some options for a file.
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
// Run tests in this file with portrait-like viewport.

View File

@ -216,8 +216,7 @@ This includes any config that needs to be run before or after mounting the compo
}>
<TabItem value="react">
```js
// playwright/index.tsx
```js title="playwright/index.tsx"
import { beforeMount, afterMount } from '@playwright/experimental-ct-react/hooks';
import { BrowserRouter } from 'react-router-dom';
@ -233,8 +232,7 @@ This includes any config that needs to be run before or after mounting the compo
#### In your test file:
```js
// src/pages/ProductsPage.spec.tsx
```js title="src/pages/ProductsPage.spec.tsx"
import { test, expect } from '@playwright/experimental-ct-react';
import type { HooksConfig } from '@playwright/test';
import { ProductsPage } from './pages/ProductsPage';
@ -251,8 +249,7 @@ This includes any config that needs to be run before or after mounting the compo
<TabItem value="solid">
```js
// playwright/index.tsx
```js title="playwright/index.tsx"
import { beforeMount, afterMount } from '@playwright/experimental-ct-solid/hooks';
import { Router } from '@solidjs/router';
@ -268,8 +265,7 @@ This includes any config that needs to be run before or after mounting the compo
#### In your test file:
```js
// src/pages/ProductsPage.spec.tsx
```js title="src/pages/ProductsPage.spec.tsx"
import { test, expect } from '@playwright/experimental-ct-solid';
import type { HooksConfig } from '@playwright/test';
import { ProductsPage } from './pages/ProductsPage';
@ -286,8 +282,7 @@ This includes any config that needs to be run before or after mounting the compo
<TabItem value="vue3">
```js
// playwright/index.ts
```js title="playwright/index.ts"
import { beforeMount, afterMount } from '@playwright/experimental-ct-vue/hooks';
import { router } from '../src/router';
@ -303,8 +298,7 @@ This includes any config that needs to be run before or after mounting the compo
#### In your test file:
```js
// src/pages/ProductsPage.spec.ts
```js title="src/pages/ProductsPage.spec.ts"
import { test, expect } from '@playwright/experimental-ct-vue';
import type { HooksConfig } from '@playwright/test';
import ProductsPage from './pages/ProductsPage.vue';
@ -321,8 +315,7 @@ This includes any config that needs to be run before or after mounting the compo
<TabItem value="vue2">
```js
// playwright/index.ts
```js title="playwright/index.ts"
import { beforeMount, afterMount } from '@playwright/experimental-ct-vue2/hooks';
import Router from 'vue-router';
import { router } from '../src/router';
@ -340,8 +333,7 @@ This includes any config that needs to be run before or after mounting the compo
```
#### In your test file:
```js
// src/pages/ProductsPage.spec.ts
```js title="src/pages/ProductsPage.spec.ts"
import { test, expect } from '@playwright/experimental-ct-vue2';
import type { HooksConfig } from '@playwright/test';
import ProductsPage from './pages/ProductsPage.vue';
@ -567,8 +559,7 @@ export default defineConfig({
Pinia needs to be initialized in `playwright/index.{js,ts,jsx,tsx}`. If you do this inside a `beforeMount` hook, the `initialState` can be overwritten on a per-test basis:
```js
// playwright/index.ts
```js title="playwright/index.ts"
import { beforeMount, afterMount } from '@playwright/experimental-ct-vue/hooks';
import { createTestingPinia } from '@pinia/testing';
import type { StoreState } from 'pinia';
@ -596,8 +587,7 @@ Pinia needs to be initialized in `playwright/index.{js,ts,jsx,tsx}`. If you do t
#### In your test file:
```js
// src/pinia.spec.ts
```js title="src/pinia.spec.ts"
import { test, expect } from '@playwright/experimental-ct-vue';
import type { HooksConfig } from '@playwright/test';
import Store from './Store.vue';

View File

@ -202,8 +202,7 @@ export default defineConfig({});
Now we can use `toBeWithinRange` in the test.
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test('numeric ranges', () => {
@ -220,8 +219,7 @@ For TypeScript, also add the following to your [`global.d.ts`](https://www.types
You don't need it for JavaScript.
```js
// global.d.ts
```js title="global.d.ts"
export {};
declare global {

View File

@ -41,8 +41,7 @@ Here is how typical test environment setup differs between traditional test styl
<summary>Click to expand the code for the <code>TodoPage</code></summary>
<div>
```js tab=js-js
// todo-page.js
```js tab=js-js title="todo-page.js"
export class TodoPage {
/**
* @param {import('@playwright/test').Page} page
@ -83,8 +82,7 @@ export class TodoPage {
}
```
```js tab=js-ts
// todo-page.ts
```js tab=js-ts title="todo-page.ts"
import { Page, Locator } from '@playwright/test';
export class TodoPage {
@ -123,8 +121,7 @@ export class TodoPage {
</div>
</details>
```js
// todo.spec.js
```js title="todo.spec.ts"
const { test } = require('@playwright/test');
const { TodoPage } = require('./todo-page');
@ -168,8 +165,7 @@ Fixtures have a number of advantages over before/after hooks:
<summary>Click to expand the code for the <code>TodoPage</code></summary>
<div>
```js tab=js-js
// todo-page.js
```js tab=js-js title="todo-page.js"
export class TodoPage {
/**
* @param {import('@playwright/test').Page} page
@ -210,8 +206,7 @@ export class TodoPage {
}
```
```js tab=js-ts
// todo-page.ts
```js tab=js-ts title="todo-page.ts"
import { Page, Locator } from '@playwright/test';
export class TodoPage {
@ -249,8 +244,7 @@ export class TodoPage {
</div>
</details>
```js tab=js-js
// todo.spec.js
```js tab=js-js title="todo.spec.js"
const base = require('@playwright/test');
const { TodoPage } = require('./todo-page');
@ -277,8 +271,7 @@ test('should remove an item', async ({ todoPage }) => {
});
```
```js tab=js-ts
// example.spec.ts
```js tab=js-ts title="example.spec.ts"
import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';
@ -314,8 +307,7 @@ Below we create two fixtures `todoPage` and `settingsPage` that follow the [Page
<details>
<summary>Click to expand the code for the <code>TodoPage</code> and <code>SettingsPage</code></summary>
<div>
```js tab=js-js
// todo-page.js
```js tab=js-js title="todo-page.js"
export class TodoPage {
/**
* @param {import('@playwright/test').Page} page
@ -356,8 +348,7 @@ export class TodoPage {
}
```
```js tab=js-ts
// todo-page.ts
```js tab=js-ts title="todo-page.ts"
import { Page, Locator } from '@playwright/test';
export class TodoPage {
@ -395,8 +386,7 @@ export class TodoPage {
SettingsPage is similar:
```js tab=js-js
// settings-page.js
```js tab=js-js title="settings-page.js"
export class SettingsPage {
/**
* @param {import('@playwright/test').Page} page
@ -411,8 +401,7 @@ export class SettingsPage {
}
```
```js tab=js-ts
// settings-page.ts
```js tab=js-ts title="settings-page.ts"
import { Page } from '@playwright/test';
export class SettingsPage {
@ -428,8 +417,7 @@ export class SettingsPage {
</div>
</details>
```js tab=js-js
// my-test.js
```js tab=js-js title="my-test.js"
const base = require('@playwright/test');
const { TodoPage } = require('./todo-page');
const { SettingsPage } = require('./settings-page');
@ -458,8 +446,7 @@ exports.test = base.test.extend({
exports.expect = base.expect;
```
```js tab=js-ts
// my-test.ts
```js tab=js-ts title="my-test.ts"
import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';
import { SettingsPage } from './settings-page';
@ -547,8 +534,7 @@ export const test = base.extend({
Notice that in this example, the `page` fixture is able to depend on other built-in fixtures such as [`property: TestOptions.baseURL`]. We can now configure `baseURL` in the configuration file, or locally in the test file with [`method: Test.use`].
```js
// example.spec.ts
```js title="example.spec.ts"
test.use({ baseURL: 'https://playwright.dev' });
```
@ -572,8 +558,7 @@ Playwright Test uses [worker processes](./test-parallel.md) to run test files. S
Below we'll create an `account` fixture that will be shared by all tests in the same worker, and override the `page` fixture to login into this account for each test. To generate unique accounts, we'll use the [`property: WorkerInfo.workerIndex`] that is available to any test or fixture. Note the tuple-like syntax for the worker fixture - we have to pass `{scope: 'worker'}` so that test runner sets up this fixture once per worker.
```js tab=js-js
// my-test.js
```js tab=js-js title="my-test.js"
const base = require('@playwright/test');
exports.test = base.test.extend({
@ -613,8 +598,7 @@ exports.test = base.test.extend({
exports.expect = base.expect;
```
```js tab=js-ts
// my-test.ts
```js tab=js-ts title="my-test.ts"
import { test as base } from '@playwright/test';
type Account = {
@ -666,8 +650,7 @@ Automatic fixtures are set up for each test/worker, even when the test does not
Here is an example fixture that automatically attaches debug logs when the test fails, so we can later review the logs in the reporter. Note how it uses [TestInfo] object that is available in each test/fixture to retrieve metadata about the test being run.
```js tab=js-js
// my-test.js
```js tab=js-js title="my-test.js"
const debug = require('debug');
const fs = require('fs');
const base = require('@playwright/test');
@ -692,8 +675,7 @@ exports.test = base.test.extend({
});
```
```js tab=js-ts
// my-test.ts
```js tab=js-ts title="my-test.ts"
import * as debug from 'debug';
import * as fs from 'fs';
import { test as base } from '@playwright/test';
@ -768,8 +750,7 @@ Below we'll create a `defaultItem` option in addition to the `todoPage` fixture
<summary>Click to expand the code for the <code>TodoPage</code></summary>
<div>
```js tab=js-js
// todo-page.js
```js tab=js-js title="todo-page.js"
export class TodoPage {
/**
* @param {import('@playwright/test').Page} page
@ -810,8 +791,7 @@ export class TodoPage {
}
```
```js tab=js-ts
// todo-page.ts
```js tab=js-ts title="todo-page.ts"
import { Page, Locator } from '@playwright/test';
export class TodoPage {
@ -850,8 +830,7 @@ export class TodoPage {
</div>
</details>
```js tab=js-js
// my-test.js
```js tab=js-js title="my-test.js"
const base = require('@playwright/test');
const { TodoPage } = require('./todo-page');
@ -872,8 +851,7 @@ exports.test = base.test.extend({
exports.expect = base.expect;
```
```js tab=js-ts
// my-test.ts
```js tab=js-ts title="my-test.ts"
import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';

View File

@ -60,8 +60,7 @@ export default defineConfig({
Here is a global setup example that authenticates once and reuses authentication state in tests. It uses the `baseURL` and `storageState` options from the configuration file.
```js
// global-setup.ts/js
```js title="global-setup.ts"
import { chromium, FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
@ -105,8 +104,7 @@ test('test', async ({ page }) => {
You can make arbitrary data available in your tests from your global setup file by setting them as environment variables via `process.env`.
```js
// global-setup.ts/js
```js title="global-setup.ts"
import { FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {
@ -139,8 +137,7 @@ test('test', async ({ page }) => {
In some instances, it may be useful to capture a trace of failures encountered during the global setup. In order to do this, you must [start tracing](./api/class-tracing.md#tracing-start) in your setup, and you must ensure that you [stop tracing](./api/class-tracing.md#tracing-stop) if an error occurs before that error is thrown. This can be achieved by wrapping your setup in a `try...catch` block. Here is an example that expands the global setup example to capture a trace.
```js
// global-setup.ts/js
```js title="global-setup.ts"
import { chromium, FullConfig } from '@playwright/test';
async function globalSetup(config: FullConfig) {

View File

@ -181,8 +181,7 @@ Tests lists are discouraged and supported as a best-effort only. Some features s
You can put your tests in helper functions in multiple files. Consider the following example where tests are not defined directly in the file, but rather in a wrapper function.
```js
// feature-a.spec.ts
```js title="feature-a.spec.ts"
import { test, expect } from '@playwright/test';
export default function createTests() {
@ -191,7 +190,9 @@ export default function createTests() {
});
}
// feature-b.spec.ts
```
```js title="feature-b.spec.ts"
import { test, expect } from '@playwright/test';
export default function createTests() {
@ -206,8 +207,7 @@ export default function createTests() {
You can create a test list file that will control the order of tests - first run `feature-b` tests, then `feature-a` tests. Note how each test file is wrapped in a `test.describe()` block that calls the function where tests are defined. This way `test.use()` calls only affect tests from a single file.
```js
// test.list.ts
```js title="test.list.ts"
import { test } from '@playwright/test';
import featureBTests from './feature-b.spec.ts';
import featureATests from './feature-a.spec.ts';

View File

@ -7,8 +7,7 @@ You can either parameterize tests on a test level or on a project level.
## Parameterized Tests
```js
// example.spec.ts
```js title="example.spec.ts"
const people = ['Alice', 'Bob'];
for (const name of people) {
test(`testing with ${name}`, async () => {
@ -24,8 +23,7 @@ Playwright Test supports running multiple test projects at the same time. In the
We declare the option `person` and set the value in the config. The first project runs with the value `Alice` and the second with the value `Bob`.
```js tab=js-js
// my-test.js
```js tab=js-js title="my-test.js"
const base = require('@playwright/test');
exports.test = base.test.extend({
@ -35,8 +33,7 @@ exports.test = base.test.extend({
});
```
```js tab=js-ts
// my-test.ts
```js tab=js-ts title="my-test.ts"
import { test as base } from '@playwright/test';
export type TestOptions = {
@ -52,8 +49,7 @@ export const test = base.extend<TestOptions>({
We can use this option in the test, similarly to [fixtures](./test-fixtures.md).
```js
// example.spec.ts
```js title="example.spec.ts"
import { test } from './my-test';
test('test 1', async ({ page, person }) => {
@ -102,8 +98,7 @@ export default defineConfig<TestOptions>({
We can also use the option in a fixture. Learn more about [fixtures](./test-fixtures.md).
```js tab=js-js
// my-test.js
```js tab=js-js title="my-test.js"
const base = require('@playwright/test');
exports.test = base.test.extend({
@ -123,8 +118,7 @@ exports.test = base.test.extend({
});
```
```js tab=js-ts
// my-test.ts
```js tab=js-ts title="my-test.ts"
import { test as base } from '@playwright/test';
export type TestOptions = {
@ -158,8 +152,7 @@ You can use environment variables to configure tests from the command line.
For example, consider the following test file that needs a username and a password. It is usually a good idea not to store your secrets in the source code, so we'll need a way to pass secrets from outside.
```js
// example.spec.ts
```js title="example.spec.ts"
test(`example test`, async ({ page }) => {
// ...
await page.getByLabel('User Name').fill(process.env.USERNAME);
@ -266,8 +259,7 @@ See for example this CSV file, in our example `input.csv`:
Based on this we'll generate some tests by using the [csv-parse](https://www.npmjs.com/package/csv-parse) library from NPM:
```js
// foo.spec.ts
```js title="test.spec.ts"
import fs from 'fs';
import path from 'path';
import { test } from '@playwright/test';
@ -279,7 +271,7 @@ const records = parse(fs.readFileSync(path.join(__dirname, 'input.csv')), {
});
for (const record of records) {
test(`fooo: ${record.test_case}`, async ({ page }) => {
test(`foo: ${record.test_case}`, async ({ page }) => {
console.log(record.test_case, record.some_value, record.some_other_value);
});
}

View File

@ -6,8 +6,7 @@ Test runner notifies the reporter about various events during test execution. Al
You can create a custom reporter by implementing a class with some of the reporter methods. Make sure to export this class as default.
```js tab=js-js
// my-awesome-reporter.js
```js tab=js-js title="my-awesome-reporter.js"
// @ts-check
/** @implements {import('@playwright/test/reporter').Reporter} */
@ -36,8 +35,7 @@ class MyReporter {
module.exports = MyReporter;
```
```js tab=js-ts
// my-awesome-reporter.ts
```js tab=js-ts title="my-awesome-reporter.ts"
import { Reporter, FullConfig, Suite, TestCase, TestResult, FullResult } from '@playwright/test/reporter';
class MyReporter implements Reporter {

View File

@ -288,8 +288,7 @@ export default defineConfig({
You can create a custom reporter by implementing a class with some of the reporter methods. Learn more about the [Reporter] API.
```js
// my-awesome-reporter.ts
```js title="my-awesome-reporter.ts"
import { FullConfig, FullResult, Reporter, Suite, TestCase, TestResult } from '@playwright/test/reporter';
class MyReporter implements Reporter {

View File

@ -163,8 +163,7 @@ It is usually better to make your tests isolated, so they can be efficiently run
Playwright Test creates an isolated [Page] object for each test. However, if you'd like to reuse a single [Page] object between multiple tests, you can create your own in [`method: Test.beforeAll`] and close it in [`method: Test.afterAll`].
```js tab=js-js
// example.spec.js
```js tab=js-js title="example.spec.js"
// @ts-check
const { test } = require('@playwright/test');
@ -191,9 +190,7 @@ test('runs second', async () => {
});
```
```js tab=js-ts
// example.spec.ts
```js tab=js-ts title="example.spec.ts"
import { test, Page } from '@playwright/test';
test.describe.configure({ mode: 'serial' });

View File

@ -82,8 +82,7 @@ See [Running Tests](./running-tests.md) for general information on `pytest` opti
### Configure Mypy typings for auto-completion
```py
# test_my_application.py
```py title="test_my_application.py"
from playwright.sync_api import Page
def test_visit_admin_dashboard(page: Page):
@ -103,8 +102,7 @@ Slows down Playwright operations by 100 milliseconds.
### Skip test by browser
```py
# test_my_application.py
```py title="test_my_application.py"
import pytest
@pytest.mark.skip_browser("firefox")
@ -115,8 +113,7 @@ def test_visit_example(page):
### Run on a specific browser
```py
# conftest.py
```py title="conftest.py"
import pytest
@pytest.mark.only_browser("chromium")
@ -131,8 +128,7 @@ def test_visit_example(page):
pytest --browser-channel chrome
```
```python
# test_my_application.py
```python title="test_my_application.py"
def test_example(page):
page.goto("https://example.com")
```
@ -146,8 +142,7 @@ for that which allows you to set the base url from the config, CLI arg or as a f
pytest --base-url http://localhost:8080
```
```py
# test_my_application.py
```py title="test_my_application.py"
def test_visit_example(page):
page.goto("/admin")
# -> Will result in http://localhost:8080/admin
@ -155,8 +150,7 @@ def test_visit_example(page):
### Ignore HTTPS errors
```py
# conftest.py
```py title="conftest.py"
import pytest
@pytest.fixture(scope="session")
@ -169,8 +163,7 @@ def browser_context_args(browser_context_args):
### Use custom viewport size
```py
# conftest.py
```py title="conftest.py"
import pytest
@pytest.fixture(scope="session")
@ -186,8 +179,7 @@ def browser_context_args(browser_context_args):
### Device emulation
```py
# conftest.py
```py title="conftest.py"
import pytest
@pytest.fixture(scope="session")
@ -203,8 +195,7 @@ Or via the CLI `--device="iPhone 11 Pro"`
### Persistent context
```py
# conftest.py
```py title="conftest.py"
import pytest
from playwright.sync_api import BrowserType
from typing import Dict

View File

@ -5,8 +5,7 @@ title: "Visual comparisons"
Playwright Test includes the ability to produce and visually compare screenshots using `await expect(page).toHaveScreenshot()`. On first execution, Playwright test will generate reference screenshots. Subsequent runs will compare against the reference.
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
@ -59,8 +58,7 @@ npx playwright test --update-snapshots
Playwright Test uses the [pixelmatch](https://github.com/mapbox/pixelmatch) library. You can [pass various options](./test-assertions#page-assertions-to-have-screenshot-2) to modify its behavior:
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
@ -84,8 +82,7 @@ Apart from screenshots, you can use `expect(value).toMatchSnapshot(snapshotName)
Here we compare text content against the reference.
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {

View File

@ -43,8 +43,7 @@ Here is an example `tsconfig.json` that works with Playwright Test:
You can now import using the mapped paths:
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from '@playwright/test';
import { username, password } from '@myhelper/credentials';

View File

@ -76,8 +76,7 @@ export default defineConfig({
Now you can use a relative path when navigating the page:
```js
// test.spec.js
```js title="test.spec.ts"
import { test } from '@playwright/test';
test('test', async ({ page }) => {

View File

@ -68,8 +68,7 @@ Using the following, Playwright will run your WebView2 application as a sub-proc
<!-- source code is available here to verify that the examples are working https://github.com/mxschmitt/playwright-webview2-demo -->
```js
// webView2Test.ts
```js title="webView2Test.ts"
import { test as base } from '@playwright/test';
import fs from 'fs';
import os from 'os';
@ -114,8 +113,7 @@ export const test = base.extend({
export { expect } from '@playwright/test';
```
```js
// example.spec.ts
```js title="example.spec.ts"
import { test, expect } from './webView2Test';
test('test WebView2', async ({ page }) => {
@ -125,8 +123,7 @@ test('test WebView2', async ({ page }) => {
});
```
```java
// WebView2Process.java
```java title="WebView2Process.java"
package com.example;
import java.io.BufferedReader;
@ -200,8 +197,7 @@ public class WebView2Process {
}
```
```java
// TestExample.java
```java title="TestExample.java"
package com.example;
import com.microsoft.playwright.Browser;
@ -248,8 +244,7 @@ public class TestExample {
}
```
```python
# conftest.py
```python title="conftest.py"
import os
import socket
import tempfile
@ -331,8 +326,7 @@ def _find_free_port(port=9000, max_port=65535):
raise IOError("no free ports")
```
```python
# test_webview2.py
```python title="test_webview2.py"
from playwright.sync_api import Page, expect