Playwright JS

npm install @tracera/playwright

Требуются Node.js ≥ 22.19 и Playwright ≥ 1.40 (см. Адаптеры автотестов). @tracera/playwright на npm.

В playwright.config.ts:

import '@tracera/playwright/register';
import { defineConfig } from '@playwright/test';

export default defineConfig({
  reporter: [['@tracera/playwright/reporter']],
  use: {
    screenshot: 'only-on-failure',
    video: 'retain-on-failure',
    trace: 'retain-on-failure', // or "on-first-retry"
  },
});

import "@tracera/playwright/register" оборачивает test.step и хуки в каждом процессе Playwright, чтобы tracera.comment и tracera.error попадали в нужный шаг.

Включите screenshot, video и trace один раз в конфиге — артефакты Playwright автоматически попадают в результат Tracera.

Переменные окружения, режим прогона и повторы: Адаптеры автотестов.

Ключ Env при повторе: PLAYWRIGHT_RETRY.

Привязка testCaseId и autotestName

test и expect импортируйте из @playwright/test, tracera и annotations — из @tracera/playwright. Имена в annotations — литералы (без {param}).

При объявлении (предпочтительно):

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

test('login', { annotation: annotations(42, 'e2e/login') }, async ({ page }) => {
  await page.goto('/login');
  await expect(page.getByRole('button', { name: 'Sign in' })).toBeVisible();
});

Внутри теста (необязательно, если annotations уже привязали кейс):

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

test('login', async ({ page }) => {
  tracera.testCase(42, 'e2e/login');
  await page.goto('/login');
  await expect(page.getByRole('button', { name: 'Sign in' })).toBeVisible();
});

Пропуск

Используйте штатный skip Playwright (test.skip, testInfo.skip(…)). Skip reason добавляется в результат как comment.

import { test } from '@playwright/test';
import { annotations } from '@tracera/playwright';

test('login', { annotation: annotations(42, 'e2e/login') }, async ({}, testInfo) => {
  testInfo.skip(!process.env.READY, 'env not ready');
});

Шаги

Используйте Playwright test.step — шаг попадает в секцию Тест. Так же можно использовать tracera.step: вызов tracera.step(title, fn), декоратор @tracera.step("…") на методе класса или tracera.step("…")(fn). В заголовке декоратора {name} / {0} подставляются из аргументов метода; вместо строки можно передать функцию, которая вернёт заголовок. В вызове tracera.step(title, fn) плейсхолдеры {name} / {0} не подставляются — передайте уже готовую строку. Асинхронные методы и Promise ожидаются до завершения. Шаги внутри test.beforeEach попадают в Предусловие результата; шаги внутри test.afterEach — в Постусловие результата. Хуки уровня suite (test.beforeAll / test.afterAll) не попадают в отчёт.

import { test } from '@playwright/test';
import { annotations } from '@tracera/playwright';

test.beforeEach(async ({ page }) => {
  await test.step('open shop', async () => {
    await page.goto('/shop');
  });
});

test('checkout', { annotation: annotations(10, 'e2e/checkout') }, async ({ page }) => {
  await test.step('add to cart', async () => {
    await page.getByRole('button', { name: 'Add' }).click();
  });
});

test.afterEach(async ({ page }) => {
  await test.step('cleanup', async () => {
    await page.goto('/cart/clear');
  });
});

Комментарии, ошибки и вложения

Комментарии, ошибки и вложения: Адаптеры автотестов.

import { test } from '@playwright/test';
import { tracera, annotations } from '@tracera/playwright';

test('login', { annotation: annotations(42, 'e2e/login') }, async ({ page }, testInfo) => {
  tracera.comment('result-level note');
  tracera.error('result-level error text');

  await test.step('open login', async () => {
    await page.goto('/login');
    tracera.comment('landed on login');
  });

  await testInfo.attach('suite-log.txt', {
    body: 'finished login flow',
    contentType: 'text/plain',
  });
});

Для добавления файлов к результату используйте testInfo.attach. Playwright сам прикрепляет скриншоты, видео и Playwright trace — в Tracera изображения открываются в лайтбоксе, видео — во встроенном плеере, а trace — в Trace Viewer.

Параметризованные тесты

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

const rows = [
  { id: 42, name: 'e2e/login-ok', path: '/login' },
  { id: 43, name: 'e2e/login-sso', path: '/login/sso' },
];

for (const row of rows) {
  test(row.name, { annotation: annotations(row.id, row.name) }, async ({ page }) => {
    await test.step('open', async () => {
      await page.goto(row.path);
    });
    await expect(page.getByRole('button', { name: 'Sign in' })).toBeVisible();
  });
}

Вместо annotations можно вызвать tracera.testCase(row.id, row.name) в тесте.

Свои фикстуры

Расширяйте стандартный Playwright test как обычно:

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

export const test = base.extend<{ asUser: void }>({
  asUser: [
    async ({ page }, use) => {
      await page.goto('/login');
      await page.getByLabel('Email').fill('user@example.com');
      await page.getByRole('button', { name: 'Sign in' }).click();
      await use();
    },
    { auto: true },
  ],
});

test('dashboard', async ({ page }) => {
  tracera.testCase(99, 'e2e/dashboard');
  await expect(page.getByRole('heading', { name: 'Dashboard' })).toBeVisible();
});