メインコンテンツにスキップ

フィクスチャ

はじめに

Playwright Testはテストフィクスチャのコンセプトに基づいています。テストフィクスチャは、各テストの環境を確立するために使用され、テストに必要なものだけを提供し、それ以外のものは提供しません。テストフィクスチャはテスト間で分離されています。フィクスチャを使用すると、共通のセットアップではなく、その意味に基づいてテストをグループ化できます。

組み込みフィクスチャ

最初のテストではすでにテストフィクスチャを使用しています。

import { test, expect } from '@playwright/test';

test('basic test', async ({ page }) => {
await page.goto('https://playwright.dokyumento.jp/');

await expect(page).toHaveTitle(/Playwright/);
});

{ page }引数は、Playwright Testにpageフィクスチャをセットアップし、それをテスト関数に提供するように指示します。

ここでは、ほとんどの場合に使用するであろう事前定義されたフィクスチャのリストを示します。

フィクスチャタイプ説明
pagePageこのテスト実行用の分離されたページ。
contextBrowserContextこのテスト実行用の分離されたコンテキスト。pageフィクスチャもこのコンテキストに属します。コンテキストの構成方法について学びます。
browserBrowserブラウザはリソースを最適化するためにテスト間で共有されます。ブラウザの構成方法について学びます。
browserNamestring現在テストを実行しているブラウザの名前。chromiumfirefox、またはwebkitのいずれか。
requestAPIRequestContextこのテスト実行用の分離されたAPIRequestContextインスタンス。

フィクスチャなし

ここでは、従来のテストスタイルとフィクスチャベースのテストスタイルで典型的なテスト環境のセットアップがどのように異なるかを示します。

TodoPageは、Page Object Modelパターンに従って、Webアプリケーションの「ToDoリスト」ページと対話するのに役立つクラスです。内部的にPlaywrightのpageを使用します。

TodoPageのコードを展開するにはクリックしてください
todo-page.ts
import type { Page, Locator } from '@playwright/test';

export class TodoPage {
private readonly inputBox: Locator;
private readonly todoItems: Locator;

constructor(public readonly page: Page) {
this.inputBox = this.page.locator('input.new-todo');
this.todoItems = this.page.getByTestId('todo-item');
}

async goto() {
await this.page.goto('https://demo.playwright.dev/todomvc/');
}

async addToDo(text: string) {
await this.inputBox.fill(text);
await this.inputBox.press('Enter');
}

async remove(text: string) {
const todo = this.todoItems.filter({ hasText: text });
await todo.hover();
await todo.getByLabel('Delete').click();
}

async removeAll() {
while ((await this.todoItems.count()) > 0) {
await this.todoItems.first().hover();
await this.todoItems.getByLabel('Delete').first().click();
}
}
}
todo.spec.ts
const { test } = require('@playwright/test');
const { TodoPage } = require('./todo-page');

test.describe('todo tests', () => {
let todoPage;

test.beforeEach(async ({ page }) => {
todoPage = new TodoPage(page);
await todoPage.goto();
await todoPage.addToDo('item1');
await todoPage.addToDo('item2');
});

test.afterEach(async () => {
await todoPage.removeAll();
});

test('should add an item', async () => {
await todoPage.addToDo('my item');
// ...
});

test('should remove an item', async () => {
await todoPage.remove('item1');
// ...
});
});

フィクスチャあり

フィクスチャには、before/afterフックに比べていくつかの利点があります。

  • フィクスチャは、セットアップとティアダウンを同じ場所にカプセル化するため、記述が容易になります。したがって、beforeフックで作成されたものをティアダウンするafterフックがある場合は、それらをフィクスチャに変換することを検討してください。
  • フィクスチャはテストファイル間で再利用可能です。一度定義すれば、すべてのテストで使用できます。Playwrightの組み込みpageフィクスチャは、このように機能します。したがって、複数のテストで使用されるヘルパー関数がある場合は、それをフィクスチャに変換することを検討してください。
  • フィクスチャはオンデマンドです。必要な数だけフィクスチャを定義でき、Playwright Testはテストに必要なものだけをセットアップし、それ以外のものはセットアップしません。
  • フィクスチャは構成可能です。複雑な動作を提供するために、互いに依存することができます。
  • フィクスチャは柔軟です。テストは、他のテストに影響を与えることなく、ニーズに合わせて環境を正確に調整するために、フィクスチャの任意の組み合わせを使用できます。
  • フィクスチャはグループ化を簡素化します。環境をセットアップするdescribeでテストをラップする必要がなくなり、代わりにその意味でテストをグループ化することができます。
TodoPageのコードを展開するにはクリックしてください
todo-page.ts
import type { Page, Locator } from '@playwright/test';

export class TodoPage {
private readonly inputBox: Locator;
private readonly todoItems: Locator;

constructor(public readonly page: Page) {
this.inputBox = this.page.locator('input.new-todo');
this.todoItems = this.page.getByTestId('todo-item');
}

async goto() {
await this.page.goto('https://demo.playwright.dev/todomvc/');
}

async addToDo(text: string) {
await this.inputBox.fill(text);
await this.inputBox.press('Enter');
}

async remove(text: string) {
const todo = this.todoItems.filter({ hasText: text });
await todo.hover();
await todo.getByLabel('Delete').click();
}

async removeAll() {
while ((await this.todoItems.count()) > 0) {
await this.todoItems.first().hover();
await this.todoItems.getByLabel('Delete').first().click();
}
}
}
example.spec.ts
import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';

// Extend basic test by providing a "todoPage" fixture.
const test = base.extend<{ todoPage: TodoPage }>({
todoPage: async ({ page }, use) => {
const todoPage = new TodoPage(page);
await todoPage.goto();
await todoPage.addToDo('item1');
await todoPage.addToDo('item2');
await use(todoPage);
await todoPage.removeAll();
},
});

test('should add an item', async ({ todoPage }) => {
await todoPage.addToDo('my item');
// ...
});

test('should remove an item', async ({ todoPage }) => {
await todoPage.remove('item1');
// ...
});

フィクスチャの作成

独自のフィクスチャを作成するには、test.extend()を使用して、それを含む新しいtestオブジェクトを作成します。

以下では、Page Object Modelパターンに従う2つのフィクスチャtodoPagesettingsPageを作成します。

TodoPageSettingsPageのコードを展開するにはクリックしてください
todo-page.ts
import type { Page, Locator } from '@playwright/test';

export class TodoPage {
private readonly inputBox: Locator;
private readonly todoItems: Locator;

constructor(public readonly page: Page) {
this.inputBox = this.page.locator('input.new-todo');
this.todoItems = this.page.getByTestId('todo-item');
}

async goto() {
await this.page.goto('https://demo.playwright.dev/todomvc/');
}

async addToDo(text: string) {
await this.inputBox.fill(text);
await this.inputBox.press('Enter');
}

async remove(text: string) {
const todo = this.todoItems.filter({ hasText: text });
await todo.hover();
await todo.getByLabel('Delete').click();
}

async removeAll() {
while ((await this.todoItems.count()) > 0) {
await this.todoItems.first().hover();
await this.todoItems.getByLabel('Delete').first().click();
}
}
}

SettingsPageも同様です

settings-page.ts
import type { Page } from '@playwright/test';

export class SettingsPage {
constructor(public readonly page: Page) {
}

async switchToDarkMode() {
// ...
}
}
my-test.ts
import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';
import { SettingsPage } from './settings-page';

// Declare the types of your fixtures.
type MyFixtures = {
todoPage: TodoPage;
settingsPage: SettingsPage;
};

// Extend base test by providing "todoPage" and "settingsPage".
// This new "test" can be used in multiple test files, and each of them will get the fixtures.
export const test = base.extend<MyFixtures>({
todoPage: async ({ page }, use) => {
// Set up the fixture.
const todoPage = new TodoPage(page);
await todoPage.goto();
await todoPage.addToDo('item1');
await todoPage.addToDo('item2');

// Use the fixture value in the test.
await use(todoPage);

// Clean up the fixture.
await todoPage.removeAll();
},

settingsPage: async ({ page }, use) => {
await use(new SettingsPage(page));
},
});
export { expect } from '@playwright/test';

カスタムフィクスチャ名は文字またはアンダースコアで始まり、文字、数字、アンダースコアのみを含むことができます。

フィクスチャの使用

テスト関数の引数にフィクスチャを記述するだけで、テストランナーが処理します。フィクスチャはフックや他のフィクスチャでも利用できます。TypeScriptを使用する場合、フィクスチャは型安全になります。

以下では、上記で定義したtodoPagesettingsPageフィクスチャを使用します。

import { test, expect } from './my-test';

test.beforeEach(async ({ settingsPage }) => {
await settingsPage.switchToDarkMode();
});

test('basic test', async ({ todoPage, page }) => {
await todoPage.addToDo('something nice');
await expect(page.getByTestId('todo-title')).toContainText(['something nice']);
});

フィクスチャのオーバーライド

独自のフィクスチャを作成するだけでなく、既存のフィクスチャをオーバーライドしてニーズに合わせることもできます。baseURLに自動的に移動することでpageフィクスチャをオーバーライドする以下の例を検討してください。

import { test as base } from '@playwright/test';

export const test = base.extend({
page: async ({ baseURL, page }, use) => {
await page.goto(baseURL);
await use(page);
},
});

この例では、pageフィクスチャがtestOptions.baseURLなどの他の組み込みフィクスチャに依存できることに注意してください。これで、構成ファイルでbaseURLを構成したり、test.use()を使用してテストファイル内でローカルに構成したりできます。

example.spec.ts

test.use({ baseURL: 'https://playwright.dokyumento.jp' });

フィクスチャはオーバーライドすることもでき、これにより基本フィクスチャが完全に異なるものに置き換えられます。たとえば、testOptions.storageStateフィクスチャをオーバーライドして、独自のデータを提供することができます。

import { test as base } from '@playwright/test';

export const test = base.extend({
storageState: async ({}, use) => {
const cookie = await getAuthCookie();
await use({ cookies: [cookie] });
},
});

ワーカーースコープのフィクスチャ

Playwright Testはテストファイルを実行するためにワーカープロセスを使用します。テストフィクスチャが個々のテスト実行のためにセットアップされるのと同様に、ワーカーフィクスチャは各ワーカープロセスに対してセットアップされます。ここでは、サービスをセットアップしたり、サーバーを実行したりできます。Playwright Testは、ワーカーフィクスチャが一致し、したがって環境が同一である限り、できるだけ多くのテストファイルでワーカープロセスを再利用します。

以下では、同じワーカー内のすべてのテストで共有されるaccountフィクスチャを作成し、各テストでこのアカウントにログインするようにpageフィクスチャをオーバーライドします。一意のアカウントを生成するために、どのテストまたはフィクスチャでも利用できるworkerInfo.workerIndexを使用します。ワーカーフィクスチャのタプルライクな構文に注意してください。テストランナーがワーカーごとに一度このフィクスチャをセットアップするように{scope: 'worker'}を渡す必要があります。

my-test.ts
import { test as base } from '@playwright/test';

type Account = {
username: string;
password: string;
};

// Note that we pass worker fixture types as a second template parameter.
export const test = base.extend<{}, { account: Account }>({
account: [async ({ browser }, use, workerInfo) => {
// Unique username.
const username = 'user' + workerInfo.workerIndex;
const password = 'verysecure';

// Create the account with Playwright.
const page = await browser.newPage();
await page.goto('/signup');
await page.getByLabel('User Name').fill(username);
await page.getByLabel('Password').fill(password);
await page.getByText('Sign up').click();
// Make sure everything is ok.
await expect(page.getByTestId('result')).toHaveText('Success');
// Do not forget to cleanup.
await page.close();

// Use the account value.
await use({ username, password });
}, { scope: 'worker' }],

page: async ({ page, account }, use) => {
// Sign in with our account.
const { username, password } = account;
await page.goto('/signin');
await page.getByLabel('User Name').fill(username);
await page.getByLabel('Password').fill(password);
await page.getByText('Sign in').click();
await expect(page.getByTestId('userinfo')).toHaveText(username);

// Use signed-in page in the test.
await use(page);
},
});
export { expect } from '@playwright/test';

自動フィクスチャ

自動フィクスチャは、テストが直接リストしていなくても、各テスト/ワーカーに対してセットアップされます。自動フィクスチャを作成するには、タプル構文を使用し、{ auto: true }を渡します。

以下は、テストが失敗したときにデバッグログを自動的に添付し、後でレポーターでログを確認できるようにするフィクスチャの例です。実行中のテストに関するメタデータを取得するために、各テスト/フィクスチャで利用できるTestInfoオブジェクトをどのように使用しているかに注目してください。

my-test.ts
import debug from 'debug';
import fs from 'fs';
import { test as base } from '@playwright/test';

export const test = base.extend<{ saveLogs: void }>({
saveLogs: [async ({}, use, testInfo) => {
// Collecting logs during the test.
const logs = [];
debug.log = (...args) => logs.push(args.map(String).join(''));
debug.enable('myserver');

await use();

// After the test we can check whether the test passed or failed.
if (testInfo.status !== testInfo.expectedStatus) {
// outputPath() API guarantees a unique file name.
const logFile = testInfo.outputPath('logs.txt');
await fs.promises.writeFile(logFile, logs.join('\n'), 'utf8');
testInfo.attachments.push({ name: 'logs', contentType: 'text/plain', path: logFile });
}
}, { auto: true }],
});
export { expect } from '@playwright/test';

フィクスチャのタイムアウト

デフォルトでは、フィクスチャはテストのタイムアウト値を継承します。ただし、遅いフィクスチャ、特にワーカーースコープのフィクスチャの場合、個別のタイムアウトを設定すると便利です。これにより、全体のテストタイムアウトを短く保ち、遅いフィクスチャにはより多くの時間を与えることができます。

import { test as base, expect } from '@playwright/test';

const test = base.extend<{ slowFixture: string }>({
slowFixture: [async ({}, use) => {
// ... perform a slow operation ...
await use('hello');
}, { timeout: 60000 }]
});

test('example test', async ({ slowFixture }) => {
// ...
});

フィクスチャオプション

Playwright Testは、個別に構成できる複数のテストプロジェクトの実行をサポートしています。「オプション」フィクスチャを使用して、構成オプションを宣言的かつ型安全にすることができます。テストのパラメータ化について詳しく学びます。

以下では、他の例のtodoPageフィクスチャに加えて、defaultItemオプションを作成します。このオプションは構成ファイルで設定されます。タプル構文と{ option: true }引数に注目してください。

TodoPageのコードを展開するにはクリックしてください
todo-page.ts
import type { Page, Locator } from '@playwright/test';

export class TodoPage {
private readonly inputBox: Locator;
private readonly todoItems: Locator;

constructor(public readonly page: Page) {
this.inputBox = this.page.locator('input.new-todo');
this.todoItems = this.page.getByTestId('todo-item');
}

async goto() {
await this.page.goto('https://demo.playwright.dev/todomvc/');
}

async addToDo(text: string) {
await this.inputBox.fill(text);
await this.inputBox.press('Enter');
}

async remove(text: string) {
const todo = this.todoItems.filter({ hasText: text });
await todo.hover();
await todo.getByLabel('Delete').click();
}

async removeAll() {
while ((await this.todoItems.count()) > 0) {
await this.todoItems.first().hover();
await this.todoItems.getByLabel('Delete').first().click();
}
}
}
my-test.ts
import { test as base } from '@playwright/test';
import { TodoPage } from './todo-page';

// Declare your options to type-check your configuration.
export type MyOptions = {
defaultItem: string;
};
type MyFixtures = {
todoPage: TodoPage;
};

// Specify both option and fixture types.
export const test = base.extend<MyOptions & MyFixtures>({
// Define an option and provide a default value.
// We can later override it in the config.
defaultItem: ['Something nice', { option: true }],

// Our "todoPage" fixture depends on the option.
todoPage: async ({ page, defaultItem }, use) => {
const todoPage = new TodoPage(page);
await todoPage.goto();
await todoPage.addToDo(defaultItem);
await use(todoPage);
await todoPage.removeAll();
},
});
export { expect } from '@playwright/test';

これで、通常どおりtodoPageフィクスチャを使用し、構成ファイルでdefaultItemオプションを設定できます。

playwright.config.ts
import { defineConfig } from '@playwright/test';
import type { MyOptions } from './my-test';

export default defineConfig<MyOptions>({
projects: [
{
name: 'shopping',
use: { defaultItem: 'Buy milk' },
},
{
name: 'wellbeing',
use: { defaultItem: 'Exercise!' },
},
]
});

オプション値としての配列

オプションの値が配列の場合、たとえば[{ name: 'Alice' }, { name: 'Bob' }]の場合、値を提供するときにそれを追加の配列でラップする必要があります。これは例で示すのが最も良いでしょう。

type Person = { name: string };
const test = base.extend<{ persons: Person[] }>({
// Declare the option, default value is an empty array.
persons: [[], { option: true }],
});

// Option value is an array of persons.
const actualPersons = [{ name: 'Alice' }, { name: 'Bob' }];
test.use({
// CORRECT: Wrap the value into an array and pass the scope.
persons: [actualPersons, { scope: 'test' }],
});

test.use({
// WRONG: passing an array value directly will not work.
persons: actualPersons,
});

オプションのリセット

オプションをundefinedに設定することで、構成ファイルで定義された値にリセットできます。baseURLを設定する以下の構成を検討してください。

playwright.config.ts
import { defineConfig } from '@playwright/test';

export default defineConfig({
use: {
baseURL: 'https://playwright.dokyumento.jp',
},
});

これで、ファイルごとにbaseURLを構成し、単一のテストではオプトアウトできます。

intro.spec.ts
import { test } from '@playwright/test';

// Configure baseURL for this file.
test.use({ baseURL: 'https://playwright.dokyumento.jp/docs/intro' });

test('check intro contents', async ({ page }) => {
// This test will use "https://playwright.dokyumento.jp/docs/intro" base url as defined above.
});

test.describe(() => {
// Reset the value to a config-defined one.
test.use({ baseURL: undefined });

test('can navigate to intro from the home page', async ({ page }) => {
// This test will use "https://playwright.dokyumento.jp" base url as defined in the config.
});
});

値を完全にundefinedにリセットしたい場合は、ロングフォームのフィクスチャ表記を使用してください。

intro.spec.ts
import { test } from '@playwright/test';

// Completely unset baseURL for this file.
test.use({
baseURL: [async ({}, use) => use(undefined), { scope: 'test' }],
});

test('no base url', async ({ page }) => {
// This test will not have a base url.
});

実行順序

各フィクスチャには、フィクスチャ内のawait use()呼び出しの前後にセットアップフェーズとティアダウンフェーズがあります。セットアップは、それを必要とするテスト/フックが実行される前に実行され、ティアダウンは、フィクスチャがテスト/フックによって使用されなくなったときに実行されます。

フィクスチャは以下のルールに従って実行順序を決定します。

  • フィクスチャAがフィクスチャBに依存する場合:Bは常にAの前にセットアップされ、Aの後にティアダウンされます。
  • 非自動フィクスチャは、テスト/フックが必要とする場合にのみ、遅延実行されます。
  • テストースコープのフィクスチャは各テストの後にティアダウンされますが、ワーカーースコープのフィクスチャはテストを実行するワーカープロセスがティアダウンされたときにのみティアダウンされます。

次の例を考えてみましょう。

import { test as base } from '@playwright/test';

const test = base.extend<{
testFixture: string,
autoTestFixture: string,
unusedFixture: string,
}, {
workerFixture: string,
autoWorkerFixture: string,
}>({
workerFixture: [async ({ browser }) => {
// workerFixture setup...
await use('workerFixture');
// workerFixture teardown...
}, { scope: 'worker' }],

autoWorkerFixture: [async ({ browser }) => {
// autoWorkerFixture setup...
await use('autoWorkerFixture');
// autoWorkerFixture teardown...
}, { scope: 'worker', auto: true }],

testFixture: [async ({ page, workerFixture }) => {
// testFixture setup...
await use('testFixture');
// testFixture teardown...
}, { scope: 'test' }],

autoTestFixture: [async () => {
// autoTestFixture setup...
await use('autoTestFixture');
// autoTestFixture teardown...
}, { scope: 'test', auto: true }],

unusedFixture: [async ({ page }) => {
// unusedFixture setup...
await use('unusedFixture');
// unusedFixture teardown...
}, { scope: 'test' }],
});

test.beforeAll(async () => { /* ... */ });
test.beforeEach(async ({ page }) => { /* ... */ });
test('first test', async ({ page }) => { /* ... */ });
test('second test', async ({ testFixture }) => { /* ... */ });
test.afterEach(async () => { /* ... */ });
test.afterAll(async () => { /* ... */ });

通常、すべてのテストがパスし、エラーがスローされない場合、実行順序は以下のとおりです。

  • ワーカーのセットアップとbeforeAllセクション
    • autoWorkerFixtureが必要とするため、browserのセットアップ。
    • 自動ワーカーフィクスチャは常に他の何よりも先にセットアップされるため、autoWorkerFixtureのセットアップ。
    • beforeAllが実行されます。
  • first testセクション
    • 自動テストフィクスチャは常にテストとbeforeEachフックの前にセットアップされるため、autoTestFixtureのセットアップ。
    • beforeEachフックで必要とされるため、pageのセットアップ。
    • beforeEachが実行されます。
    • first testが実行されます。
    • afterEachが実行されます。
    • テストースコープのフィクスチャであり、テスト終了後にティアダウンされる必要があるため、pageのティアダウン。
    • テストースコープのフィクスチャであり、テスト終了後にティアダウンされる必要があるため、autoTestFixtureのティアダウン。
  • second testセクション
    • 自動テストフィクスチャは常にテストとbeforeEachフックの前にセットアップされるため、autoTestFixtureのセットアップ。
    • beforeEachフックで必要とされるため、pageのセットアップ。
    • beforeEachが実行されます。
    • second testが必要とするtestFixtureが必要とするため、workerFixtureのセットアップ。
    • second testが必要とするため、testFixtureのセットアップ。
    • second testが実行されます。
    • afterEachが実行されます。
    • テストースコープのフィクスチャであり、テスト終了後にティアダウンされる必要があるため、testFixtureのティアダウン。
    • テストースコープのフィクスチャであり、テスト終了後にティアダウンされる必要があるため、pageのティアダウン。
    • テストースコープのフィクスチャであり、テスト終了後にティアダウンされる必要があるため、autoTestFixtureのティアダウン。
  • afterAllとワーカーのティアダウンセクション
    • afterAllが実行されます。
    • ワーカーースコープのフィクスチャであり、最後に一度ティアダウンされる必要があるため、workerFixtureのティアダウン。
    • ワーカーースコープのフィクスチャであり、最後に一度ティアダウンされる必要があるため、autoWorkerFixtureのティアダウン。
    • ワーカーースコープのフィクスチャであり、最後に一度ティアダウンされる必要があるため、browserのティアダウン。

いくつかの考察

  • pageautoTestFixtureは、テストースコープのフィクスチャとして、各テストごとにセットアップおよびティアダウンされます。
  • unusedFixtureは、どのテスト/フックでも使用されないため、決してセットアップされません。
  • testFixtureworkerFixtureに依存し、そのセットアップをトリガーします。
  • workerFixtureは、2番目のテストの前に遅延セットアップされますが、ワーカーースコープのフィクスチャとして、ワーカーシャットダウン中に一度ティアダウンされます。
  • autoWorkerFixturebeforeAllフックのためにセットアップされますが、autoTestFixtureはセットアップされません。

複数のモジュールからカスタムフィクスチャを結合する

複数のファイルまたはモジュールからテストフィクスチャをマージできます。

fixtures.ts
import { mergeTests } from '@playwright/test';
import { test as dbTest } from 'database-test-utils';
import { test as a11yTest } from 'a11y-test-utils';

export const test = mergeTests(dbTest, a11yTest);
test.spec.ts
import { test } from './fixtures';

test('passes', async ({ database, page, a11y }) => {
// use database and a11y fixtures.
});

ボックスフィクスチャ

通常、カスタムフィクスチャはUIモード、トレースビューア、およびさまざまなテストレポートで個別のステップとして報告されます。また、テストランナーからのエラーメッセージにも表示されます。頻繁に使用されるフィクスチャの場合、これは多くのノイズを意味する可能性があります。フィクスチャを「ボックス化」することで、UIにフィクスチャステップが表示されないようにすることができます。

import { test as base } from '@playwright/test';

export const test = base.extend({
helperFixture: [async ({}, use, testInfo) => {
// ...
}, { box: true }],
});

これは、興味のないヘルパーフィクスチャに役立ちます。たとえば、いくつかの共通データをセットアップする自動フィクスチャは、テストレポートから安全に非表示にできます。

カスタムフィクスチャタイトル

通常のフィクスチャ名ではなく、テストレポートやエラーメッセージに表示されるカスタムタイトルをフィクスチャに付けることができます。

import { test as base } from '@playwright/test';

export const test = base.extend({
innerFixture: [async ({}, use, testInfo) => {
// ...
}, { title: 'my fixture' }],
});

グローバルなbeforeEach/afterEachフックを追加する

test.beforeEach()およびtest.afterEach()フックは、同じファイルおよび同じtest.describe()ブロック(もしあれば)で宣言された各テストの前後に実行されます。各テストの前後でグローバルに実行されるフックを宣言したい場合は、次のように自動フィクスチャとして宣言できます。

fixtures.ts
import { test as base } from '@playwright/test';

export const test = base.extend<{ forEachTest: void }>({
forEachTest: [async ({ page }, use) => {
// This code runs before every test.
await page.goto('https://:8000');
await use();
// This code runs after every test.
console.log('Last URL:', page.url());
}, { auto: true }], // automatically starts for every test.
});

そして、すべてのテストでフィクスチャをインポートします。

mytest.spec.ts
import { test } from './fixtures';
import { expect } from '@playwright/test';

test('basic', async ({ page }) => {
expect(page).toHaveURL('https://:8000');
await page.goto('https://playwright.dokyumento.jp');
});

グローバルなbeforeAll/afterAllフックを追加する

test.beforeAll()およびtest.afterAll()フックは、同じファイルおよび同じtest.describe()ブロック(もしあれば)で宣言されたすべてのテストの前後に、ワーカープロセスごとに一度実行されます。すべてのファイル内のすべてのテストの前後で実行されるフックを宣言したい場合は、次のようにscope: 'worker'を持つ自動フィクスチャとして宣言できます。

fixtures.ts
import { test as base } from '@playwright/test';

export const test = base.extend<{}, { forEachWorker: void }>({
forEachWorker: [async ({}, use) => {
// This code runs before all the tests in the worker process.
console.log(`Starting test worker ${test.info().workerIndex}`);
await use();
// This code runs after all the tests in the worker process.
console.log(`Stopping test worker ${test.info().workerIndex}`);
}, { scope: 'worker', auto: true }], // automatically starts for every worker.
});

そして、すべてのテストでフィクスチャをインポートします。

mytest.spec.ts
import { test } from './fixtures';
import { expect } from '@playwright/test';

test('basic', async ({ }) => {
// ...
});

フィクスチャは引き続きワーカープロセスごとに一度実行されますが、すべてのファイルで再宣言する必要はありません。