import { test, expect } from '@playwright/test';
test('example test', async ({ page }) => {
await page.goto('https://example.com');
await expect(page).toHaveTitle(/Example/);
});
Playwright has quickly become one of the most popular tools for end-to-end testing of modern web applications. It’s fast, works across all major browsers, and comes with a powerful built-in test runner and reporting system.
Playwright supports some reporting by default, most readily available as a console output, JSON, or HTML report, which can be generated at the end of a test run. But those default reports are often difficult to access quickly, and if they are the only reports you use to report on the Playwright test suites, you’re missing a big part of the picture. Over time, you need to answer questions like:
- Which test runs and test executions are failing most often?
- Which tests are flaky?
- How does test performance compare across different branches or pipelines?
- How do automated Playwright tests fit into the rest of your testing (manual test cases, exploratory sessions, etc.) to deliver satisfactory test coverage for a given release?
That’s where Playwright reporting with Testmo comes in. In this guide, we will walk through:
- How Playwright works and how its reporting system fits together
- How to set up a Playwright environment using Docker
- How to write your first Playwright browser test using built-in assertions
- How to generate Playwright reports (with built-in HTML and JUnit/XML reporters)
- How to submit Playwright test results to Testmo using the Testmo CLI
- How to integrate Playwright and Testmo in your CI pipelines to get detailed information and real-time reporting
Whether you are a new Testmo user wanting to get started with Playwright or a Playwright user evaluating Testmo as your test management tool, this guide will walk you through a complete workflow of reporting with Playwright, including advanced Playwright reporting in Testmo.
What Is Playwright
Playwright is an open-source testing framework from Microsoft for automating modern web browsers. It supports Chromium, Firefox, and WebKit, and provides:
- A simple API for interacting with web pages (
page.goto,page.click, etc.) - First-class support for JavaScript, TypeScript, Python, .NET, and Java
- Built-in reporters (HTML, list, dot, JSON, JUnit) and test artifacts (screenshots, traces, videos), with the ability to extend functionality with custom reports
In this guide, we’ll focus on:
- TypeScript with Node.js
- Generating HTML and JUnit/XML reports
- Sending those automation reports to Testmo via the Testmo CLI
- Automating this process on your CI pipeline
By the end, you’ll have:
- A small Playwright project running in Docker
- A first Playwright browser test with built-in assertions
- A working Playwright reporting setup (HTML + JUnit)
- A simple command to submit Playwright test results to Testmo
- A GitHub Action workflow that integrates everything
Understanding How Playwright Works
If you’re new to Playwright, there are a few core concepts to understand before we talk about generating reports. If you’re already familiar with Playwright, feel free to skip to the next section.
Core Playwright components
Playwright’s main elements are:
- Test files (*.spec.ts):
These files contain your test cases. Each test is defined using thetestfunction from@playwright/test. - Playwright Test runner:
This is the built-in testing framework. You run it withnpx playwright testor an npm script. The test runner discovers test files, runs them, and produces test results. - Browser, context, and page:
- A browser instance: Chromium, Firefox, WebKit
- Browser contexts: one or more isolated browser profiles
- A page: a single browser tab
In your tests, Playwright lets you work primarily with a page object, which is passed into tests as a fixture:
- Configuration file (playwright.config.ts):
This is where you define global settings: test directory, timeouts, browser options, and—importantly for this guide—reporters for Playwright reporting.
How Playwright automation reports work
When you run npx playwright test, the test runner:
- Discovers and executes tests
- Collects test results (pass/fail, duration, errors, retries, etc.)
- Sends those results to one or more reporters
A reporter is just a module that receives structured test events and turns them into something useful:
- List reporter, line reporter, dot reporter: Print progress and results to the command line.
- HTML reporter: Generates an interactive HTML report (index.html) you can open in your browser.
- JSON reporter: outputs test results in a structured JSON format, useful for programmatic analysis of test failures.
- JUnit reporter: Writes an XML file in the JUnit format, which is widely used in the industry to integrate with other software testing, like Testmo.
Playwright lets you configure multiple reporters at once. That means you can:
- Use the HTML report locally for debugging and visual exploration
Use the JUnit/XML report as the structured output to send to Testmo
We’ll configure exactly that in this guide.
Basic structure of a Playwright test
Most tests follow this pattern:
import { test, expect } from '@playwright/test';
test('descriptive test name', async ({ page }) => {
await page.goto('https://your-app.example/');
// Interact with the page
await page.click('text=Log in');
await page.fill('#email', '[email protected]');
await page.fill('#password', 'password123');
await page.click('button[type=submit]');
// Assert expected result
await expect(page).toHaveURL(/dashboard/);
});
Organising tests into suites
Playwright uses test files as suites, and you can group tests logically:- By feature (
tests/login.spec.ts,tests/cart.spec.ts) - By workflow (
tests/checkout.spec.ts) - By area (e.g.,
tests/admin/*.spec.ts)
- Map Playwright tests to Testmo test cases or sections.
- Filter and interpret Playwright reporting by area (e.g., which feature has more failures).
How to Set Up Your Playwright Environment for Testing & Reporting
In this section, we’ll set up a small example project with the following structure:
- A project directory for your code and test files
- A Docker-based development environment
You can find the full repository on GitHub, where you have access to all the files we'll create for this guide.
Configuring the project directory
Let’s call the project ‘example-playwright-reporting’:
example-playwright-reporting
Inside this directory, we’ll store our test scripts, playwright.config.js configuration settings, and reporting setup.
Setting up the Docker environment
Docker gives you a clean, reproducible environment with Node.js and browsers installed, without cluttering your main machine.
Step 1: Create the Docker Compose config
Inside a dev directory, create docker-compose.yml:
# dev/docker-compose.yml
services:
node:
image: mcr.microsoft.com/playwright:v1.57.0-noble #use the latest release
working_dir: /project
volumes:
- ./../:/project
command: tail -f /dev/null
- Uses the official Playwright Docker image (Node.js + browsers preinstalled).
- Mounts your project folder into the container at
/project. - Keeps the container running so you can attach a shell and run commands.
Step 2: Start the dev container
From thedev directory, run:
docker compose up -d
node container:
docker compose exec node bash
Step 3: Initialize the Node.js project and install Playwright
From/project inside the container:
npm init -y
npm install --save-dev @playwright/test
npx playwright install --with-deps
This will:
- Create a basic
package.json - Install the Playwright test runner
- Install browser binaries and dependencies (Chromium, Firefox, WebKit)
Your First Playwright Test Script
Now that the environment is ready, let’s create our first simple browser test. Playwright uses a test runner syntax similar to Jest or Mocha. For our example, let’s script a test that:- Navigates to Testmo.com
- Searches for the trial button
- Clicks on it
- Asserts that it opens the trial signup page
tests directory and add tests/testmo.spec.ts:
import { test, expect } from '@playwright/test';
test('HomePage: "Try Testmo Free" button opens trial signup window', async ({ page }) => {
// Go to Testmo homepage
await page.goto('https://www.testmo.com/');
// Accept cookies if the banner appears
const acceptButton = page.getByRole('button', { name: 'Accept all' });
if (await acceptButton.isVisible()) {
await acceptButton.click();
}
// Click the "Try Testmo Free" button and wait for the new page to open
const newPagePromise = page.waitForEvent('popup');
await page.getByRole('link', { name: 'Try Testmo Free', exact: true }).click();
const newPage = await newPagePromise;
// Assert that the new page has the correct URL
await expect(newPage).toHaveURL(/trial/);
});
Configuring playwright.config.ts for Testing & Reporting
Before we generate reports, let’s configure the Playwright test runner.
Create playwright.config.ts in the project root:
// playwright.config.ts
import { defineConfig, devices } from '@playwright/test';
export default defineConfig({
testDir: './tests',
// Use built-in reporters: list for console, HTML, and JUnit for CI/Testmo
reporter: [
['list'],
['html', { outputFolder: 'playwright-report', open: 'never' }],
['junit', { outputFile: 'results/junit/results.xml' }],
],
use: {
browserName: 'chromium',
headless: true,
screenshot: 'only-on-failure',
trace: 'retain-on-failure',
},
// Example of running tests on a desktop Chrome-like configuration
projects: [
{
name: 'chromium',
use: { ...devices['Desktop Chrome'] },
},
],
});
- A list reporter for readable CLI output
- An HTML report in
playwright-report/index.html - A JUnit/XML report at
results/junit/results.xmlready to be consumed by CI or Testmo
Generate a Playwright HTML Report (Step-by-Step)
The HTML report is perfect for local debugging and for quickly exploring test results, errors, and artifacts such as screenshots.Step 1: Add a test script to package.json
Open package.json and add:
{
"scripts": {
"test": "playwright test",
"test:report": "playwright show-report"
}
}
Step 2: Run the tests
Inside your dev container (or locally):
npm run test
- Run all tests in
./tests - Use the reporters defined in
playwright.config.ts - Generate the HTML report in
playwright-report/
Step 3: View the HTML report
Now open the HTML report with:npm run test:report
playwright-report/index.html in your browser, where you can:
- See a summary of test runs
- Drill down into individual tests
- Inspect stack traces, console logs, screenshots, and traces
Generate a JUnit/XML Report for CI and Testmo
Now let’s look at the JUnit reporter, which is the key piece for integrating with Testmo. We already configured the JUnit reporter inplaywright.config.ts:
reporter: [
['list'],
['html', { outputFolder: 'playwright-report', open: 'never' }],
['junit', { outputFile: 'results/junit/results.xml' }],
],
playwright test, Playwright will generate:
- Human-friendly output in the terminal (list reporter)
- An HTML report
- A JUnit XML file at
results/junit/results.xml
Step 1: Run tests with JUnit reporter
Run:npm run test
After the run finishes, you should see:
- results/junit/results.xml (JUnit/XML test report)
- playwright-report/ (HTML report)
This XML file will be our main input to Testmo.
How to Report Playwright Test Results to Testmo
Now for the key piece: sending your Playwright test results to Testmo so you get:
- Real-time reporting for test automation results across sources and pipelines
- History and data of Playwright suites over time
- Flaky/slow test analysis
- Centralised views across CI pipelines and environments
We’ll use the Testmo CLI (@testmo/testmo-cli) and the JUnit/XML report we just generated to submit new test results to Testmo automatically.
Step 1: Install the Testmo CLI
Inside your project:
npm install --save-dev @testmo/testmo-cli
testmo command to your node_modules.
Step 2: Configure Testmo environment variables
You’ll need:- Your Testmo instance URL, e.g.
https://your-company.testmo.net - An API access token from your Testmo user profile
export TESTMO_URL="https://your-company.testmo.net"
export TESTMO_TOKEN="your-api-token"
Note: In CI, use secure environment variables or secrets rather than hard-coded values.
Step 3: Run Playwright tests and upload the JUnit/XML report
First, ensure your JUnit/XML report exists:
npm run test
Now use the Testmo CLI to create a test run and upload results:
npx testmo automation:run:submit \
--instance "$TESTMO_URL" \
--project-id 1 \
--name "Playwright test run" \
--source "playwright" \
--results "results/junit/results.xml"
- Creates a new automation run in Testmo (in project ID 1)
- Uploads all tests from
results/junit/results.xml - Marks the run as completed
Step 4: Use the Testmo CLI to trigger your Playwright tests
A more convenient approach is to let Testmo execute your test command and collect results in one step. With this, Testmo CLI launches your automation tool, captures the output, records the full test time, and finally, after your automation tool exits, collects the result files. It gives you another level of detailed information about your automated test run that you might miss by running the commands separately. Add a script inpackage.json:
{
"scripts": {
"test": "playwright test",
"test:junit": "playwright test",
"test:testmo": "npx testmo automation:run:submit --instance $TESTMO_URL --project-id 1 --name 'Playwright CI run' --source 'playwright' --results 'results/junit/results.xml' -- npx playwright test"
}
}
Note: It's important to include a space between the -- dashes and your automation tool command line.
And run it like this:
npm run test:testmo
Notice the -- at the end:
- Everything after
--is the command Testmo will run (npx playwright test). - Testmo will:
- Launch Playwright tests
- Wait for them to complete
- Read the JUnit report from
results/junit/results.xml - Upload results and mark the run as finished
This setup works both locally and in CI or other build systems.

How to integrate Playwright and Testmo in your CI pipelines
In most real projects, you don’t just run Playwright locally: you run tests automatically on each commit or pull request via a CI pipeline. The pattern we just used works very well in CI.
GitHub Actions with Playwright and Testmo
Here’s a minimal GitHub Actions workflow that:
- Checks out your repository
- Installs Node.js and dependencies
- Installs Playwright browsers
- Runs Playwright tests with JUnit reporting
- Submits results to Testmo
# .github/workflows/playwright-test.yml
name: Playwright Tests
on:
push:
pull_request:
jobs:
test:
runs-on: ubuntu-latest
steps:
- name: Check out repository
uses: actions/checkout@v6
- name: Set up Node.js
uses: actions/setup-node@v6
with:
node-version: 24
- name: Install dependencies
run: npm ci
- name: Install Playwright browsers
run: npx playwright install --with-deps
- name: Run Playwright tests and submit to Testmo
env:
TESTMO_URL: ${{ secrets.TESTMO_URL }}
TESTMO_TOKEN: ${{ secrets.TESTMO_TOKEN }}
run: |
npm test:testmo
With this in place, every push or PR will:
- Run your Playwright test suite
- Generate HTML + JUnit reports
- Upload the JUnit report to Testmo
- Give you a centralized Playwright reporting view across all CI runs
Other Third-Party Reporting Tools
While we focused on using built-in reporters and Testmo to generate reports on Playwright tests in this article, there are a number of other tools you could use for Playwright reporting depending on your use case.
Other common reporting tools include:
- Allure reports: best for fine-grained customizability around visualizing automation report results
- Monocart: which generates an HTML report and shows suites/cases/steps with tree style, markdown annotations, and custom columns
Next Steps
If you’d like to go further, your next steps could include:
- Adding more complex Playwright workflows and test suites
- Running Playwright tests in parallel across multiple CI agents or cloud browsers
- Exploring Testmo’s advanced automation reporting features and Playwright test management resources
But with the setup in this guide, you already have a solid first workflow: write Playwright tests, generate reports, send everything to Testmo for unified reporting, and automate the entire workflow in your CI.
Happy Testing!
PS: We regularly publish original software testing & QA research, including free guides, reports and news. To receive our next postings, you can subscribe to updates. You can also follow us on Twitter and Linkedin.





