On this page
- Choose a Playwright reporter
- What the HTML report does not provide
- Prerequisites
- Configure HTML and JUnit reporters
- Name Playwright tests with [TC-42] markers
- Upload screenshots, videos, and traces
- Upload the Playwright JUnit report
- Complete GitHub Actions workflow
- Use the EU region
- Migrating from the legacy Playwright plugin
- Troubleshooting
Playwright can create a readable HTML report for debugging and JUnit XML for CI tools. Generate
both in the same run, put a TestCollab case ID such as [TC-42] in each test title,
and upload the JUnit file with @testcollab/cli.
For CLI installation, authentication, and test-plan options, see TestCollab CLI: Install and First Run.
Choose a Playwright reporter
Playwright includes several reporters. You can configure more than one, so a single test run serves both people and automation.
| Reporter | Best use | Persistent file? |
|---|---|---|
list |
Readable, detailed progress in a local terminal or shorter CI run | No |
line |
Compact progress that rewrites one terminal line | No |
html |
Interactive inspection of failures, steps, screenshots, and traces for one run | Yes |
junit |
Machine-readable results for CI systems and TestCollab | Yes, when an output file is configured |
What the HTML report does not provide
The Playwright HTML report is excellent for diagnosing one run. In CI, it remains in the job workspace unless you publish it as an artifact. Even when retained, it is still a run-specific report rather than a shared test-management record.
Uploading JUnit results to TestCollab adds team-wide execution history, build and release traceability, and one plan where manual and automated cases can be reviewed together. Keep the HTML report for debugging and use TestCollab for the durable testing record.
Prerequisites
- A project that runs tests with
@playwright/test. - A TestCollab project and a test plan containing the automated cases.
- A TestCollab API token available as
TESTCOLLAB_TOKEN. - Each result-producing Playwright test named with its TestCollab case ID.
Configure HTML and JUnit reporters
Configure the reporters in playwright.config.ts. The example also retains evidence
for failures so Playwright can name it in the JUnit report.
import { defineConfig } from '@playwright/test';
export default defineConfig({
reporter: [
['list'],
['html', {
outputFolder: 'playwright-report',
open: 'never'
}],
['junit', {
outputFile: 'test-results/results.xml'
}]
],
use: {
screenshot: 'only-on-failure',
video: 'retain-on-failure',
trace: 'retain-on-failure'
}
});
If you do not want to edit the configuration file, select JUnit on the command line and set its output filename through the environment:
PLAYWRIGHT_JUNIT_OUTPUT_NAME=results.xml \
npx playwright test --reporter=junit
Do not use Playwright's --output option to name the XML file. That option selects the
test artifact directory, not the JUnit report path.
Name Playwright tests with [TC-42] markers
Place the TestCollab test case ID in the individual test title:
import { test, expect } from '@playwright/test';
test('[TC-42] customer can sign in', async ({ page }) => {
await page.goto('/login');
await page.getByLabel('Email').fill('customer@example.com');
await page.getByLabel('Password').fill('valid-password');
await page.getByRole('button', { name: 'Sign in' }).click();
await expect(page).toHaveURL(/dashboard/);
});
The CLI recognizes [TC-42], TC-42, id-42, and
testcase-42, case-insensitively. The marked case must be present in the target plan
and assigned to the user whose API token uploads the results.
Upload screenshots, videos, and traces
Playwright's JUnit reporter writes an [[ATTACHMENT|path]] line for each screenshot,
video, and trace recorded for a test. tc report reads those markers and attaches the
files to that test case's execution. No extra marker code is required.
<testcase name="[TC-42] customer can sign in">
<failure message="Expected dashboard URL" />
<system-out>
[[ATTACHMENT|test-results/customer-can-sign-in/test-failed-1.png]]
[[ATTACHMENT|test-results/customer-can-sign-in/trace.zip]]
</system-out>
</testcase>
Keep the report and its artifact files in the same job until tc report finishes.
Relative paths may resolve from the current working directory or the JUnit file's directory.
TestCollab accepts up to 10 files per case and 10 MB per file. Missing, oversized, or extra files
produce warnings and are skipped without failing the result upload.
Upload the Playwright JUnit report
export TESTCOLLAB_TOKEN="your-token"
npx @testcollab/cli report \
--project 123 \
--test-plan-id 456 \
--format junit \
--result-file ./test-results/results.xml
Replace 123 and 456 with your TestCollab project and test plan IDs.
Complete GitHub Actions workflow
The following workflow creates a test plan from a CI tag, runs Playwright, uploads JUnit results
to TestCollab, and keeps the HTML report as a GitHub artifact. Store
TESTCOLLAB_TOKEN as a repository secret and the three numeric IDs as repository
variables.
name: Playwright tests
on:
push:
branches: [main]
pull_request:
jobs:
test:
runs-on: ubuntu-latest
env:
TESTCOLLAB_TOKEN: ${{ secrets.TESTCOLLAB_TOKEN }}
TC_PROJECT_ID: ${{ vars.TC_PROJECT_ID }}
TC_CI_TAG_ID: ${{ vars.TC_CI_TAG_ID }}
TC_ASSIGNEE_ID: ${{ vars.TC_ASSIGNEE_ID }}
steps:
- name: Check out repository
uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: 22
cache: npm
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Create TestCollab test plan
run: |
npx @testcollab/cli createTestPlan \
--project "$TC_PROJECT_ID" \
--ci-tag-id "$TC_CI_TAG_ID" \
--assignee-id "$TC_ASSIGNEE_ID"
- name: Run Playwright tests
run: npx playwright test
- name: Upload Playwright results to TestCollab
if: always()
run: |
source tmp/tc_test_plan
npx @testcollab/cli report \
--project "$TC_PROJECT_ID" \
--test-plan-id "$TESTCOLLAB_TEST_PLAN_ID" \
--format junit \
--result-file ./test-results/results.xml
- name: Upload Playwright HTML report
if: always()
uses: actions/upload-artifact@v4
with:
name: playwright-html-report
path: playwright-report/
if-no-files-found: warn
retention-days: 14
The result and artifact steps use if: always(), so a Playwright assertion failure is
still recorded. The failed Playwright step continues to make the job fail.
Use the EU region
Add this option to every TestCollab CLI command for an EU account:
--api-url https://api-eu.testcollab.io
Migrating from the legacy Playwright plugin
New integrations should use Playwright's built-in JUnit reporter and tc report. This
avoids framework-specific TestCollab plugin code and uses the same result path as every other
JUnit-capable runner. Existing customers maintaining the retired approach can consult
Playwright integration (legacy plugin)
while migrating.
Troubleshooting
No JUnit file is created
Confirm the configured reporter includes junit and uses outputFile, or
set PLAYWRIGHT_JUNIT_OUTPUT_NAME when selecting the reporter on the command line.
A Playwright test is not matched
Open test-results/results.xml and check that the
<testcase name> contains the correct [TC-42] marker. Then confirm
that case is in the target plan.
An attachment is skipped
Read the warning in the CLI log. Verify the file still exists when tc report runs, is
no larger than 10 MB, and is one of the first 10 attachments named for that case.
Results are not uploaded after a failure
Keep test execution and result upload in separate CI steps, and put if: always() on
the upload. The reporter normally writes the XML before Playwright returns its failure exit code.


