Spec-Zone.ru › Playwright

Фикстуры

Введение​

Playwright Test основано на концепции фикстур. Фикстуры используются для создания среды для каждого теста, предоставляя тесту все необходимое и ничего лишнего. Фикстуры изолированы между тестами. С фикстурами вы можете группировать тесты по их смыслу, а не по общему настройке.

Встроенные фикстуры​

Вы уже использовали фикстуры в своём первом тесте.

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

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

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

Аргумент { page } указывает Playwright Test на настройку фикстуры page и предоставление её вашей функции теста.

Вот список предопределённых фикстур, которые вы, скорее всего, будете использовать чаще всего:

Фикстура Тип Описание
page Page Изолированная страница для этого запуска теста.
context BrowserContext Изолированный контекст для этого запуска теста. Фикстура page также принадлежит этому контексту. Узнайте, как настроить контекст.
browser Браузер Браузеры используются совместно между тестами для оптимизации ресурсов. Узнайте, как настроить браузер.
browserName строка Название браузера, в котором в данный момент выполняется тест. Это может быть chromium, firefox или webkit.
request APIRequestContext Изолированный экземпляр APIRequestContext для этого запуска теста.

Без фикстур​

Вот как типичная настройка среды тестирования отличается между традиционным стилем тестирования и основанным на фикстурах.

TodoPage — это класс, который помогает взаимодействовать со страницей "списка дел" веб-приложения, следуя паттерну Page Object Model. Он использует Playwright's page внутри.

Нажмите, чтобы развернуть код для TodoPage
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();
    }
  }
}
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');
    // ...
  });
});

С фикстурами​

Фикстуры имеют ряд преимуществ по сравнению с перед/после хуками:

  • Фикстуры капсулируют настройку и завершение в одном месте, что упрощает написание.
  • Фикстуры многократно используемые между файлами тестов — вы можете определить их один раз и использовать во всех своих тестах. Именно так работает встроенная фикстура Playwright page.
  • Фикстуры по требованию — вы можете определить столько фикстур, сколько захотите, и Playwright Test настроит только те, которые необходимы вашему тесту, и ничего лишнего.
  • Фикстуры составные — они могут зависеть друг от друга для предоставления сложного поведения.
  • Фикстуры гибкие. Тесты могут использовать любые комбинации фикстур для настройки точной среды, необходимой им, без влияния на другие тесты.
  • Фикстуры упрощают группировку. Вам больше не нужно обёртывать тесты в describe для настройки среды, и вы можете свободно группировать свои тесты по их смыслу.
Нажмите, чтобы развернуть код для TodoPage
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();
    }
  }
}
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 объект, который будет её содержать.

Ниже мы создаём две фикстуры todoPage и settingsPage , которые следуют паттерну Page Object Model.

Нажмите, чтобы развернуть код для TodoPage и SettingsPage
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 похожа:

import type { Page } from '@playwright/test';

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

  async switchToDarkMode() {
    // ...
  }
}
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, фикстуры будут иметь правильный тип.

Ниже мы используем фикстуры todoPage и settingsPage , определённые выше.

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']);
});

Переопределение фикстур​

В дополнение к созданию своих собственных фикстур, вы также можете переопределить существующие фикстуры, чтобы они соответствовали вашим потребностям. Рассмотрим следующий пример, который переопределяет фикстуру page путём автоматического перехода к определённой baseURL:

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().

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

Фикстуры также можно переопределить, полностью заменив базовая фикстуру чем-то другим. Например, мы можем переопределить фикстуру 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'} , чтобы система запуска тестов настраивала эту фикстуру один раз на процесс-рабочий поток.

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, который доступен в каждом тесте/фикстуре для получения метаданных о выполняемом тесте.

import * as debug from 'debug';
import * as 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 поддерживает запуск нескольких проектов тестов, которые можно настроить отдельно. Вы можете использовать фикстуры "options", чтобы сделать ваши параметры конфигурации декларативными и с проверкой типов. Узнайте больше о параметризации тестов.

Ниже мы создадим параметр defaultItem в дополнение к фикстуре todoPage из других примеров. Этот параметр будет установлен в файле конфигурации. Обратите внимание на синтаксис кортежа и аргумент { option: true }.

Нажмите, чтобы развернуть код для TodoPage
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();
    }
  }
}
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 в файле конфигурации.

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,
});

Порядок выполнения​

Каждая фикстура имеет фазу настройки и завершения, разделённые вызовом 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 раздел:
    • browser настройка, так как она требуется autoWorkerFixture.
    • autoWorkerFixture настройка, так как автоматические фикстуры работника всегда устанавливаются до всего остального.
    • beforeAll выполняется.
  • first test раздел:
    • autoTestFixture настройка, так как автоматические фикстуры теста всегда устанавливаются перед тестом и beforeEach хуками.
    • page настройка, так как она требуется в beforeEach хуке.
    • beforeEach выполняется.
    • first test выполняется.
    • afterEach выполняется.
    • page разворачивание, так как это фикстура, связанная с тестом, и должна быть развернута после завершения теста.
    • autoTestFixture разворачивание, так как это фикстура, связанная с тестом, и должна быть развернута после завершения теста.
  • second test раздел:
    • autoTestFixture настройка, так как автоматические фикстуры теста всегда устанавливаются перед тестом и beforeEach хуками.
    • page настройка, так как она требуется в beforeEach хуке.
    • beforeEach выполняется.
    • workerFixture настройка, так как она требуется testFixture, которая требуется second test.
    • testFixture настройка, так как она требуется second test.
    • second test выполняется.
    • afterEach выполняется.
    • testFixture разворачивание, так как это фикстура, связанная с тестом, и должна быть развернута после завершения теста.
    • page разворачивание, так как это фикстура, связанная с тестом, и должна быть развернута после завершения теста.
    • autoTestFixture разворачивание, так как это фикстура, связанная с тестом, и должна быть развернута после завершения теста.
  • afterAll и раздел разворачивания работника:
    • afterAll выполняется.
    • workerFixture разворачивание, так как это фикстура, связанная с работником, и должна быть развернута один раз в конце.
    • autoWorkerFixture разворачивание, так как это фикстура, связанная с работником, и должна быть развернута один раз в конце.
    • browser разворачивание, так как это фикстура, связанная с работником, и должна быть развернута один раз в конце.

Несколько наблюдений:

  • page и autoTestFixture устанавливаются и разворачиваются для каждого теста, как фикстуры, связанные с тестом.
  • unusedFixture никогда не устанавливается, так как не используется ни одним тестом/хуком.
  • testFixture зависит от workerFixture и вызывает ее настройку.
  • workerFixture лениво устанавливается перед вторым тестом, но разворачивается один раз во время завершения работы работника, как фикстура, связанная с работником.
  • autoWorkerFixture устанавливается для beforeAll хука, но autoTestFixture нет.

Объединение пользовательских фикстур из нескольких модулей​

Вы можете объединять фикстуры тестов из нескольких файлов или модулей:

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);
import { test } from './fixtures';

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

Фикстуры в блоке​

Обычно пользовательские фикстуры отображаются как отдельные шаги в режиме пользовательского интерфейса, Просмотр трассировки и различных отчетах о тестировании. Они также появляются в сообщениях об ошибках от исполнителя тестов. Для часто используемых фикстур это может означать много шума. Вы можете остановить отображение шагов фикстур в пользовательском интерфейсе, «упаковав» их.

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() (если таковой имеется). Если вы хотите объявить хуки, которые выполняются до/после каждого теста глобально, вы можете объявить их как автоматические фикстуры следующим образом:

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('http://localhost:8000');
    await use();
    // This code runs after every test.
    console.log('Last URL:', page.url());
  }, { auto: true }],  // automatically starts for every test.
});

И затем импортируйте фикстуры во все свои тесты:

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

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

Добавление глобальных хуков beforeAll/afterAll​

test.beforeAll() и test.afterAll() хуки выполняются до/после всех тестов, объявленных в том же файле и в том же блоке test.describe(), один раз на процесс работника. Если вы хотите объявить хуки, которые выполняются до/после всех тестов во всех файлах, вы можете объявить их как автоматические фикстуры с scope: 'worker' следующим образом:

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.
});

И затем импортируйте фикстуры во все свои тесты:

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

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

Обратите внимание, что фикстуры все равно будут выполняться один раз на каждый процесс работника, но вам не нужно переопределять их в каждом файле.

© 2024 Microsoft
Licensed under the Apache License, Version 2.0.
https://playwright.dev/docs/test-fixtures

Spec-Zone.ru

Настройки Оффлайн Что нового Помощь О нас
Spec-Zone .ru
спецификации, руководства, описания, API