Playwright test metadata
probara tells the reporter more about a test, from the test body, a hook or a fixture. Import it
from the reporter’s package:
import { test } from '@playwright/test';import { probara } from '@probara/playwright-reporter';
test('pays with a card', async () => { probara.title('Pays with a saved card').suite(['Payments', 'Cards']).tags('smoke');});The helpers
Section titled “The helpers”| Helper | What it does | Repeated calls |
|---|---|---|
id(id | ids) | Links existing cases (linking) | Add up |
title(text) | Title of the case the report creates | The last one wins |
suite(title | titles) | Suite path of the case the report creates | The last one wins |
comment(text) | A comment, first in the notes of the result, before the error | The last one wins |
ignore() | Leaves this attempt out: it is not reported | — |
tags(...names) | Tags of the case the report creates | Add up, each once |
fields(record) | Fields of the case the report creates: system fields, custom fields, description | Merged by name |
parameters(record) | Parameters of the result, shown with it | Merged by name |
attach({ name, path | body, ... }) | Attaches a file (attachments) | Each one attaches |
step(action, expected?, data?) | A test.step title that declares a step of the new case (steps) | Each one declares a step |
Every synchronous helper returns probara, so calls chain; attach() returns a promise to await.
Each helper applies to the running attempt only: a retry starts empty.
Created cases only
Section titled “Created cases only”title, suite, tags, fields and the declared steps describe the case a report creates,
the first time a test is reported. An existing case never changes: Probara keeps what people wrote
there. The automation key never changes either
(keys), so a renamed title
still matches the same case.
import { test } from '@playwright/test';import { probara } from '@probara/playwright-reporter';
test('pays', async () => { probara .title('Pays with a saved card') .suite(['Payments', 'Cards']) .tags('smoke', 'payments') .fields({ description: 'A returning customer pays with the card saved in their profile.', severity: 'critical', priority: 'high', 'Risk area': 'Checkout', });});What Probara receives for that test:
[ { "automationKey": "payments.spec.ts > pays", "title": "Pays with a saved card", "suitePath": ["Payments", "Cards"], "case": { "description": "A returning customer pays with the card saved in their profile.", "tags": ["smoke", "payments"], "fields": { "severity": "critical", "priority": "high", "Risk area": "Checkout" } } }]Fields
Section titled “Fields”fields() takes names and values; numbers and booleans become strings.
| Name | What it sets |
|---|---|
description | The case description |
severity, priority, type, layer, behavior, status, is_flaky | The system fields, by the name of an option (high) |
preconditions, postconditions | The system text fields |
Any other name, such as 'Risk area' | The custom field of that name |
Probara resolves names and options when it creates the case. A field or an option it does not know is skipped and logged as a warning; the result is recorded all the same. A field with an empty value is skipped silently.
Title and suite
Section titled “Title and suite”The title of a created case is the test title, case ids removed, unless title() says otherwise.
Its suite path is the file and the describe titles (payments.spec.ts > Cards) unless suite()
gives one: suite('Payments'), or suite(['Payments', 'Cards']) for nested suites, created as
needed under suiteUlid.
Comment
Section titled “Comment”comment() writes a line first in the notes of the result, before the error and its stack:
import { test } from '@playwright/test';import { probara } from '@probara/playwright-reporter';
test('searches the catalog', async () => { probara.comment('Ran against the staging catalog');});[ { "automationKey": "search.spec.ts > searches the catalog", "notes": "Ran against the staging catalog" }]Parameters
Section titled “Parameters”parameters() records the values an attempt ran with, shown with its result, such as the user or
the data set of a data-driven test. They are never part of the key: the test is one case whatever
its parameters. When the case declares a parameter with the same name, the result is recorded on the
run case with those values, and Probara adds that run case if the run does not hold it yet. A
parameter the case does not declare stays on the result for display only. The Playwright project is
sent as a context parameter: it is shown on the result, and it never becomes a parameter of a case a report creates.
import { test } from '@playwright/test';import { probara } from '@probara/playwright-reporter';
for (const role of ['admin', 'viewer']) { test(`opens the dashboard as ${role}`, async () => { probara.parameters({ role, seats: 5 }); });}[ { "automationKey": "users.spec.ts > opens the dashboard as admin", "parameters": { "role": "admin", "seats": "5" } }, { "automationKey": "users.spec.ts > opens the dashboard as viewer", "parameters": { "role": "viewer", "seats": "5" } }]A test whose title holds the parameter, as above, is one case per value. Keep the title fixed and
pass the value with parameters() to get one case with every value in its history.
Ignore an attempt
Section titled “Ignore an attempt”ignore() leaves the running attempt out: it still runs, and Playwright reports it, but Probara
does not get it. The count in the log says how many were left out.
import { test } from '@playwright/test';import { probara } from '@probara/playwright-reporter';
test('tries the new checkout', async () => { probara.ignore();});
test('pays', async () => {});$ npx playwright test[probara] Sending 1 result of 1 test (1 passed, 0 failed, 0 skipped, 0 blocked); 1 ignored with probara.ignore()[probara] Recorded 1 result (1 new case, 0 unmatched) in R-1 (closed): https://app.probara.net/projects/SHOP/runs/R-1Where to call the helpers
Section titled “Where to call the helpers”- In the test body,
beforeEach,afterEach, or a test fixture: they apply to the running attempt. Not inbeforeAll,afterAllor a worker fixture, where no single test runs. - A helper never throws into the test. A wrong argument, or a call while no test runs, is a
[probara]warning on the test’s stderr, and the call is ignored.
A test fixture can set metadata for every test that uses it:
import { test as base } from '@playwright/test';import { probara } from '@probara/playwright-reporter';
export const test = base.extend<{ account: string }>({ account: async ({}, use) => { probara.parameters({ account: 'demo' }); await use('demo'); },});import { test } from './fixtures';
test('shows the account', async ({ account }) => { test.info().annotations.push({ type: 'note', description: account });});[{ "automationKey": "account.spec.ts > shows the account", "parameters": { "account": "demo" } }]How metadata travels
Section titled “How metadata travels”Playwright runs tests in worker processes and the reporter in the main one. The helpers send their
metadata as small attachments named _probara (application/vnd.probara.metadata+json), which
belong to one attempt, survive blob reports and merge-reports, and are never uploaded.
Playwright’s HTML report lists them with the attempt; on Playwright 1.42 each call also shows as an
attach step there. Case ids travel as probara_case annotations, which Playwright’s JUnit
reporter writes too.
Next: steps and attachments,
or map your qase.* calls in migrating from Qase.