๐ Module 10 โ CI/CD Integration
Running tests locally is great. Running them reliably in CI (GitHub Actions, GitLab CI, Jenkins, Azure DevOps) is what makes automation production-ready.
โ Goals of CI for Playwrightโ
- ๐ Run tests automatically on every push / pull request
- ๐งช Run on Linux (fast + consistent) with installed browsers
- ๐งฉ Capture reports, traces, screenshots, videos as artifacts
- ๐ก๏ธ Handle flakiness with retries, timeouts, and trace-on-retry
- โ Fail the pipeline only when tests truly fail (not due to environment issues)
โ Ready-to-Use: GitHub Actions Workflowโ
Create this file in your repo root (outside playwright-tests/):
.github/workflows/playwright.yml
Paste the following:
name: Playwright Tests
on:
push:
branches: [ main, master ]
pull_request:
branches: [ main, master ]
jobs:
test:
timeout-minutes: 60
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: lts/*
- name: Install dependencies
working-directory: playwright-tests
run: npm ci
- name: Install Playwright Browsers
working-directory: playwright-tests
run: npx playwright install --with-deps
- name: Run Playwright tests
working-directory: playwright-tests
run: npx playwright test --project=chromium
- name: Upload Playwright Report
uses: actions/upload-artifact@v4
if: always()
with:
name: playwright-report
path: playwright-tests/playwright-report/
retention-days: 30
- name: Upload Test Results (traces/videos)
uses: actions/upload-artifact@v4
if: always()
with:
name: test-results
path: playwright-tests/test-results/
retention-days: 30
โ What this does:
- โ Installs Node + dependencies
- โ Installs Playwright browsers + OS dependencies
- โ Runs tests on Chromium in CI
- โ Uploads HTML report + traces/videos/screenshots even if tests fail
โ
Recommended playwright.config.js Settings for CIโ
Make sure your config is optimized for reliability:
module.exports = defineConfig({
testDir: './tests',
fullyParallel: true,
forbidOnly: !!process.env.CI,
retries: process.env.CI ? 2 : 1,
workers: process.env.CI ? 1 : 2,
reporter: [
['html', { open: 'never' }],
['list']
],
use: {
baseURL: 'https://practicetestautomation.com',
headless: true,
viewport: { width: 1280, height: 720 },
actionTimeout: 10000,
navigationTimeout: 30000,
screenshot: 'only-on-failure',
trace: 'on-first-retry',
video: 'on-first-retry',
},
timeout: 30000,
expect: { timeout: 5000 },
projects: [
{ name: 'chromium', use: { ...devices['Desktop Chrome'] } },
{ name: 'firefox', use: { ...devices['Desktop Firefox'] } },
{ name: 'webkit', use: { ...devices['Desktop Safari'] } },
],
});
โ Viewing CI Artifactsโ
- After a workflow run completes โ go to Actions tab in GitHub
- Click the failed/passed run
- Scroll down to Artifacts โ download
playwright-reportortest-results - Open
index.htmllocally, or usenpx playwright show-traceon the downloadedtrace.zip
โ Best Practices for CI Stabilityโ
- โ Keep tests independent (no shared state between tests)
- โ
Use
data-testidfor stable locators in your app - โ
Prefer
getByRole()/getByLabel()over brittle CSS/XPath - โ Use API calls to create test data before UI tests (faster + more reliable)
- โ
Add
waitForURL()/waitForResponse()instead of arbitrarywaitForTimeout() - โ Run only Chromium in CI first (fast feedback), expand to Firefox/WebKit later
โ Troubleshooting CI Failuresโ
| Symptom | Fix |
|---|---|
| Browsers fail to install in CI | Use npx playwright install --with-deps (already included above) |
| Tests pass locally but fail in CI | Check timezone, locale, network, rate limits, CAPTCHA; add retries + traces |
| HTML report not generated | Ensure working-directory: playwright-tests is set correctly in steps |
| Artifacts too large | Keep retention-days reasonable; avoid video: 'on' unless needed |
๐ฏ Summary: With Module 9 (Debugging) + Module 10 (CI/CD), your course now takes learners from local scripting โ professional test automation โ production CI pipelines ๐
๐ Keep Goingโ
Apply what you learned in this module:
- ๐งช Practice Exercises โ hands-on tasks to build real skills
- ๐๏ธ Real Projects โ real-world automation examples