This blog post explains how to run Playwright UI tests in CI (Continuous Integration) using GitHub Actions.
Before you start, you need to have a basic knowledge of GitHub Actions, Playwright, and the Playwright Trace Viewer to better understand this blog. If you are not familiar with any of these topics, below are links to our blogs that explain each one:
By the end of this blog, you will be able to set up a CI workflow that automatically runs your Playwright UI tests whenever you push code to your repository. You will also learn how to get Playwright trace reports when tests fail, making it easier to debug and fix errors.
π€ Why run tests on CI?
Tests are run on CI to ensure the code works properly in a clean and isolated environment every time a change is made. Here are some reasons:
1. Early bug detection:
CI runs tests automatically on every push or PR, so you find problems right when they're introduced, not days or weeks later when the context is gone and fixes are harder.
2. No more "Works on my machine":
CI runs your tests in a clean environment every time. If tests pass there, it means your code works in a standard setup, not just on your own computer.
3. Protect the main branch:
Tests on CI act like a gatekeeper. If something breaks, it doesn't get merged. This keeps the main (or master) branch deployable and stable.
4. Confidence to refactor and move fast:
When tests run automatically, you can refactor aggressively. If CI is green, you didn't break existing behavior. That confidence significantly speeds things up.
5. Better collaboration:
CI gives everyone on the team the same test results. This helps avoid confusion and makes it clear whether the code is working or not.
6. Automated process:
CI systems enable developers to save time and effort on testing.
π About the Project
In this blog, I have taken a simple application with a frontend built using Vue.js and a backend built using json-server(a fake REST API). The GitHub repository is available at: https://github.com/nabim777/momo-restro-list.git
This is a basic application that includes login and logout functionality. E2E tests are written using Playwright to verify the login feature. You can find the test scenarios here
π οΈ Running App Locally
Before setting up CI, let's run the application and tests locally.
1. Install dependencies
npm ci
2. Start the frontend and backend servers
npm run serve # Start frontend
npm run backend # Start backend
π§ͺ Running UI Tests Locally
NOTE: Make sure both the frontend and backend are running before running the tests.
To run the UI tests locally, use the following command:
npx playwright install chromium
npm run test:e2e tests
βοΈ Setting Up CI in GitHub Actions
After verifying the app locally, the next step is to set up CI using GitHub Actions. First, create a file named ci.yml in your project using the following folder structure:
π¦momo-restro-list
β π.github
β β£ πworkflows
β β β πci.yml
Then, add the following code to the ci.yml file.
name: CI
on:
push:
branches:
- master
pull_request:
branches:
- master
workflow_dispatch:
jobs:
e2e-UI-tests:
runs-on: ubuntu-latest
steps:
- name: Checkout repo code
uses: actions/checkout@v6
- name: Set up node
uses: actions/setup-node@v6
with:
node-version: 24.x
- name: Install dependencies
run: |
npm ci
npx playwright install chromium
- name: JS lint
run: |
npm run lint || (echo "Linting failed! Please run 'npm run lint:fix' to fix the errors." && exit 1)
- name: Run the project
run: |
npm run serve &
npm run backend &
- name: Wait for services
run: |
sudo apt-get install wait-for-it -y
wait-for-it -h localhost -p 8080 -t 10
wait-for-it -h localhost -p 3000 -t 10
- name: Run UI tests
id: test-ui
run: npm run test:e2e tests
- name: Upload trace results
if: ${{ failure() && steps.test-ui.conclusion == 'failure' }}
uses: actions/upload-artifact@v6
with:
path: |
trace-results/*.zip
retention-days: 30
π What does this workflow do?
This GitHub Actions file runs when you push to the master branch or create a pull request to master.
It has one job called e2e-UI-tests with these steps:
- Checkout repo code - Gets the project code from GitHub.
- Set up node - Installs Node.js version 24.
- Install dependencies - Installs the project dependencies and Playwright browsers.
- JS lint - Runs the linter to check for code quality issues. If linting fails, it will print a custom error message and exit with a failure status.
- Run the project - Starts the Vue app and the backend using json-server.
- Wait for services - Waits for the frontend (port 8080) and backend (port 3000) to be ready.
- Run UI tests - Runs the UI tests using Playwright.
- Upload trace results - If the UI tests fail, it uploads the Playwright trace results as an artifact that can be downloaded from the GitHub Actions interface. The trace files will be retained for 30 days.
π₯ How to Download and View Trace Files?
If your tests fail in CI, you can download the trace files to see what went wrong:
- Go to your GitHub repository
- Click on the Actions tab
- Select the failed workflow run
- Scroll down to the Artifacts section at the bottom of the page
- Click on the artifact name to download the trace files (they will be in a
.zipfile) - Extract the downloaded
.zipfile - Open the trace file using one of these methods:
- Drag and drop the trace file into trace.playwright.dev
- Or run this command locally:
npx playwright show-trace path/to/trace.zip
The trace viewer will show you step-by-step what happened during the test, including screenshots, network requests, and console logs.
π Conclusion
Using GitHub Actions to run your Playwright tests means your app is tested automatically in a clean environment every time you make changes. It helps find bugs early, makes teamwork easier, and keeps your project stable.
CI tests turn "hope it works" into "we know it works."

Top comments (0)