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 والخطافات في كل عامل حتى تقع 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(…)). يُضاف سبب التخطّي إلى النتيجة كـ 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} من وسائط الدالة؛ ويمكن تمرير دالة تُرجع العنوان. في نموذج الاستدعاء لا تُملأ {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();
  });
}

أو استدعِ tracera.testCase(row.id, row.name) داخل الاختبار بدل annotations.

fixtures مخصصة

وسّع test القياسي من Playwright كالمعتاد:

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