July 26, 2026
How to Run Playwright Tests in Jenkins
Learn how to run Playwright tests in Jenkins with a practical CI pipeline, browser setup, reports, artifacts, and failure handling for stable Jenkins browser tests.
If you want browser tests to matter, they have to run where your delivery process actually lives. For many teams, that means Jenkins. The moment Playwright leaves a laptop and enters a CI pipeline, the real work starts: browser installation, headless execution, reporting, artifacts, retries, and making failures useful instead of noisy.
This article walks through how to run Playwright tests in Jenkins in a way that is operationally sane. I am not trying to sell you on Playwright or Jenkins, both are useful tools. The point is to get reliable Jenkins browser tests that can survive normal engineering churn, not just a demo that passes once on a clean machine.
A browser test suite that is hard to run is not a quality gate, it is future cleanup work.
What you need before you start
Playwright is a browser automation library with a strong built-in testing story. Jenkins is a CI server that can run jobs on demand or from source control events. The basic integration is straightforward, but the details matter because browser tests have a few extra failure modes that unit tests do not.
Before wiring anything into Jenkins, make sure you have:
- A Playwright test project already working locally
- Node.js available on the Jenkins agent, or a container image with Node preinstalled
- A repository that stores tests with the application code or in a dedicated test repo
- Enough CPU and memory on the agent to run browsers without starving the machine
- A decision about where test reports and screenshots should live after the job finishes
If you need the baseline Playwright project structure, the official docs are the right starting point, especially the Playwright introduction. For Jenkins concepts and pipeline syntax, keep the Jenkins documentation open while you build the job.
The simplest path, install dependencies and run tests
At its core, running Playwright tests in Jenkins is just the same as running them on your laptop, with two additions, install browsers and publish the outputs.
A typical Playwright project uses npm scripts like this:
{ “scripts”: { “test:e2e”: “playwright test”, “test:e2e:headed”: “playwright test –headed” } }
In CI, you usually run headless tests. Playwright will launch browsers as part of the test run, but the browser binaries still need to be available on the agent. That means your pipeline should do three things in order:
- Install dependencies
- Install Playwright browsers if the agent image does not already include them
- Run the test suite and collect artifacts
A minimal Jenkins pipeline looks like this:
groovy pipeline { agent any
stages { stage(‘Install’) { steps { sh ‘npm ci’ sh ‘npx playwright install –with-deps’ } }
stage('Test') {
steps {
sh 'npm run test:e2e'
}
} } }
That works, but it is not yet a production-grade Playwright CI pipeline. It installs browsers every run, does not preserve reports, and gives you little to inspect when something fails.
A better Jenkins pipeline for Playwright
A practical pipeline should optimize for the questions you ask after a failure:
- Which test failed?
- Was it a product defect or infrastructure issue?
- What did the page look like?
- Can I reproduce it locally?
- Did the browser crash, time out, or hit a selector problem?
To answer those questions, wire up reporting and artifacts from the beginning.
Recommended Playwright config
Use the Playwright config to generate machine-readable and human-readable outputs. The built-in HTML report is usually enough for day-to-day debugging, and traces are invaluable when you need to inspect timing or DOM state.
import { defineConfig } from '@playwright/test';
export default defineConfig({ reporter: [[‘html’], [‘junit’, { outputFile: ‘test-results/junit.xml’ }]], use: { trace: ‘on-first-retry’, screenshot: ‘only-on-failure’, video: ‘retain-on-failure’ } });
This configuration makes a few opinionated tradeoffs:
- HTML report, useful for developers reading a failed run
- JUnit XML, useful for Jenkins test trend views and integrations
- Traces only on retries, enough to debug flakes without generating too much data
- Screenshots and video only on failure, so failed runs carry evidence
That last point matters. If your browser tests fail and you have no trace or screenshot, Jenkins becomes a failure notification system, not a diagnosis system.
Jenkinsfile with artifacts and post actions
A more complete pipeline can look like this:
groovy pipeline { agent any
environment { CI = ‘true’ }
stages { stage(‘Checkout’) { steps { checkout scm } }
stage('Install') {
steps {
sh 'npm ci'
sh 'npx playwright install --with-deps'
}
}
stage('Run Playwright tests') {
steps {
sh 'npm run test:e2e'
}
} }
post { always { junit ‘test-results/junit.xml’ archiveArtifacts artifacts: ‘playwright-report/, test-results/’, allowEmptyArchive: true } } }
This pipeline does a few important things.
First, it records test results in a format Jenkins understands. Second, it archives Playwright reports and test outputs so a failure does not disappear when the build log scrolls away. Third, it treats the browser artifacts as first-class debugging input, not optional extras.
Containerize the agent when you can
One of the cleanest ways to run Playwright tests in Jenkins is to avoid depending on whatever happens to be installed on the agent. If you use ephemeral agents or Docker-based executors, you reduce drift between local and CI environments.
Playwright publishes official Docker images, which are useful when you want a known browser environment instead of assembling dependencies piecemeal. The tradeoff is obvious, containers are one more moving part, but in practice they often reduce the total amount of machine setup you need to own.
A container-based stage can look like this:
groovy pipeline { agent { docker { image ‘mcr.microsoft.com/playwright:v1.55.0-jammy’ args ‘–ipc=host’ } }
stages { stage(‘Test’) { steps { sh ‘npm ci’ sh ‘npm run test:e2e’ } } } }
The exact image tag should match the Playwright version in your project. Pinning versions matters because browser automation is sensitive to drift. If your test code uses one Playwright release and your container has another, you can lose time to mismatched expectations, selector behavior, or browser dependencies.
When not to containerize
Containers are not mandatory. If your Jenkins environment already uses well-managed Linux agents, and if the agent image is stable and reproducible, you may prefer bare-metal or VM-based execution. The deciding factor is not ideology, it is whether your team can keep the runtime predictable.
If agents are snowflakes, use containers. If the container setup becomes more complex than the problems it removes, simplify the agent instead.
Browser installation and caching strategy
A common mistake is reinstalling everything from scratch on every run. That is simple, but it can slow the pipeline and make browser tests look more expensive than they are.
The usual options are:
- Install browsers on each run, simplest but slowest
- Prebake browsers into the agent image, faster but requires image maintenance
- Use a cache for npm and Playwright binaries, a middle ground if your infrastructure supports it
The right choice depends on your Jenkins setup. For shared agents, caching npm dependencies and Playwright browsers can cut unnecessary work. For ephemeral agents, prebuilt images often give better predictability than ad hoc installation steps.
One thing to avoid, mixing version sources. If your pipeline sometimes installs browsers from the agent, sometimes from a cache, and sometimes from a container image, you have created a debugging puzzle. Keep browser versions tied to the repository or the container image, not to whatever happened to be on the machine.
Reporting, artifacts, and trace files
Reports are not a nice-to-have in CI. They are the difference between an actionable failure and a vague red build.
Playwright gives you several useful outputs:
- HTML report for interactive inspection
- JUnit XML for Jenkins test result parsing
- Trace files for step-by-step debugging
- Screenshots and videos for visual context
In Jenkins, archive them all, but not forever. Design your retention policy intentionally. Browser artifacts can get large, so keep enough history to debug recurrent problems without letting storage become an uncontrolled side cost.
A useful pattern is to archive:
playwright-report/for the HTML reporttest-results/for JUnit, traces, screenshots, and videos- Optional custom logs from application startup or test fixtures
If your flaky test triage starts with, “I wish I had the trace,” you already know where the process is thin.
Handling flaky tests in Jenkins browser tests
Flaky tests are not just annoying, they distort trust in the pipeline. Once people start ignoring red builds, the whole CI signal degrades.
With Playwright, some flake control is built in. You can use retries, but retries should be a diagnostic tool, not a permanent excuse. A retry can hide a race condition long enough to ship the same bug again.
A sensible retry configuration might look like this:
import { defineConfig } from '@playwright/test';
export default defineConfig({ retries: process.env.CI ? 2 : 0, workers: process.env.CI ? 2 : undefined });
This is conservative. Retries are lower in CI than locally because CI noise is usually where flakiness shows up. But you should still fix root causes, which usually fall into a few buckets:
- Unstable selectors, use role-based or text-based locators where possible
- Shared test data, isolate accounts or reset state per run
- Timing assumptions, wait for a state change rather than an arbitrary timeout
- External dependencies, stub or control non-essential services
- Too much parallelism, which can overwhelm the application or the CI agent
Playwright’s auto-waiting helps, but it is not magic. A locator that is technically actionable can still be semantically wrong. If your tests click the wrong element quickly and consistently, automation will simply fail fast with confidence.
Test selection, parallelism, and CI cost
Not every test needs to run on every push. For many teams, the useful split is:
- Smoke tests on each pull request
- A broader end-to-end suite on merge to main
- Scheduled runs for the expensive or environment-heavy paths
That is a practical tradeoff, not a purity test. Browser tests are valuable, but they do consume CI time and agent capacity. If you run the entire suite on every commit, you may create long feedback loops that slow delivery without improving signal.
Playwright supports projects and test filtering, so you can shape the suite by browser, tag, or feature area. Jenkins then becomes the orchestrator for when and how those slices run.
For example, you might run smoke tests on pull requests and the full suite nightly:
groovy stage(‘Smoke’) { steps { sh ‘npm run test:e2e – –grep @smoke’ } }
Choose the smallest suite that still catches the mistakes you care about before merge.
Debugging failed runs effectively
When a Playwright job fails in Jenkins, your first question should not be “How do I make it green again?” It should be “What exactly failed, and is that failure trustworthy?”
A disciplined debug flow is:
- Open the JUnit result or Jenkins test summary
- Inspect the Playwright HTML report
- Review the trace for the failed step
- Check screenshot or video if available
- Determine whether the failure is deterministic
Some failures are application defects, such as a modal that never closes. Others are test issues, such as a locator that matches multiple elements. Infrastructure failures look different again, for example browser startup problems, missing system packages, or low memory on the agent.
This is where having artifacts in Jenkins pays off. A test runner with no report forces everyone to read raw logs. That is tolerable for a handful of tests, but it does not scale to a serious browser suite.
Security and maintenance concerns
CI jobs often need access to secrets, test accounts, and sometimes service endpoints. Keep that surface area narrow.
A few practical rules:
- Use dedicated test accounts, not personal credentials
- Store secrets in Jenkins credentials, not in the repository
- Do not print tokens or session data to logs
- Keep test environments isolated from production data whenever possible
- Version the Playwright runtime along with your test code
Maintenance matters as much as execution. Browser test suites age in place, and the biggest source of cost is often not runtime, but review time, reruns, and ownership concentration. If only one person knows how the Jenkinsfile works, the pipeline is already fragile.
A note on alternatives
If your team does not want to own browser infrastructure, framework upgrades, and CI wiring, a managed platform can be a simpler option. For example, Endtest vs Playwright is worth reading if you are evaluating whether your team wants to maintain a coded Playwright stack or use a managed, low-code platform with agentic AI assistance. I would still treat that as a selection question, not an ideology. Code gives control, managed tooling reduces infrastructure burden.
The useful question is not “Which tool is better in the abstract?” It is “Who owns failures, browser versions, and maintenance over the next year?” If the answer is unclear, the tool choice will show that ambiguity quickly.
A practical checklist for production use
Before you call your Jenkins browser tests done, check the following:
- Playwright version is pinned
- Browser binaries are installed reproducibly
- Jenkins archives HTML reports, JUnit, and failure artifacts
- Traces and screenshots are enabled for failed runs
- Retries are limited and used intentionally
- Test data and authentication are isolated
- The suite is split into sensible CI stages
- Failure output is readable by someone who did not write the test
If these points are true, you are close to a sustainable setup.
Conclusion
To run Playwright tests in Jenkins well, you need more than a shell command in a pipeline. You need a predictable browser environment, useful artifacts, and a plan for flaky tests and maintenance. That is what turns Playwright from a local automation library into a dependable CI signal.
The best setup is the one your team can keep healthy. For some teams that means a carefully managed Jenkins pipeline with Playwright reports, traces, and pinned browser images. For others, it means using a managed platform and spending less time owning the infrastructure layer. Either way, the standard is the same, browser tests should tell you something you can act on.