GitHub Actions Project: CI/CD Pipeline for a Playwright Test Automation Repo

In this capstone project you will build a complete, production-style GitHub Actions pipeline for a Playwright test automation repository: fast PR checks, cross-browser regression, manual environment runs, artifacts, Dependabot and documentation.

Advertisement

📖 What You’ll Learn: the project requirements, the target workflow structure, a reusable Playwright workflow, a PR pipeline with lint, type checks and smoke tests, nightly cross-browser regression, manual runs against environments, Dependabot and README badges, and an evaluation rubric.


🎯 Project Brief

Build a production-style CI/CD pipeline in GitHub Actions for a Playwright + TypeScript test automation repository. When you finish, every pull request is tested automatically, results are easy to read, failures are easy to debug, and a nightly regression runs across browsers.

Time needed: 6 to 10 hours. Prerequisites: Modules 1 to 9 of this course and a Playwright project, ideally from the Playwright e-commerce framework project (any Playwright project works).


📋 Requirements

#RequirementLesson
1Lint and type-check on every PRworkflow syntax
2Smoke tests (Chromium) on every PR, required to mergebranch protection
3Full regression on main and nightly, across 3 browsersmatrix
4npm caching and artifacts for reports and tracescache and artifacts
5Secrets and per-environment URLssecrets and environments
6A reusable test workflow used by all pipelinesreusable workflows
7Manual run against a chosen environmentworkflow_dispatch
8Latest report published to GitHub Pages (non-sensitive project)deployment
9Dependabot for npm and GitHub Actionssecurity
10CI badge and run instructions in the READMEREADME

🗂️ Target Structure

.github/
├── workflows/
│   ├── pr.yml               # lint + smoke tests on pull requests
│   ├── regression.yml       # main + nightly, 3 browsers
│   ├── manual.yml           # workflow_dispatch against an environment
│   └── playwright-run.yml   # reusable workflow (workflow_call)
└── dependabot.yml

🔁 Step 1: The Reusable Test Workflow

# .github/workflows/playwright-run.yml
name: Playwright run (reusable)
on:
  workflow_call:
    inputs:
      project:   { type: string, default: chromium }
      grep:      { type: string, default: '' }
      base-url:  { type: string, required: true }
      artifact:  { type: string, default: playwright-report }

jobs:
  run:
    runs-on: ubuntu-latest
    timeout-minutes: 45
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with:
          node-version: lts/*
          cache: npm
      - run: npm ci
      - run: npx playwright install --with-deps ${{ inputs.project }}
      - name: Run tests
        run: npx playwright test --project=${{ inputs.project }} ${{ inputs.grep != '' && format('--grep {0}', inputs.grep) || '' }}
        env:
          BASE_URL: ${{ inputs.base-url }}
          TEST_PASSWORD: ${{ secrets.TEST_PASSWORD }}
      - uses: actions/upload-artifact@v4
        if: ${{ !cancelled() }}
        with:
          name: ${{ inputs.artifact }}
          path: |
            playwright-report/
            test-results/
          retention-days: 14

📝 Note: Callers pass secrets with secrets: inherit so secrets.TEST_PASSWORD is available inside the reusable workflow.


✅ Step 2: Pull Request Pipeline

# .github/workflows/pr.yml
name: PR checks
on:
  pull_request:
    branches: [ main ]
concurrency:
  group: pr-${{ github.event.pull_request.number }}
  cancel-in-progress: true
permissions:
  contents: read

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-node@v4
        with: { node-version: lts/*, cache: npm }
      - run: npm ci
      - run: npx tsc --noEmit
      - run: npm run lint

  smoke:
    needs: lint
    uses: ./.github/workflows/playwright-run.yml
    with:
      project: chromium
      grep: '@smoke'
      base-url: https://www.saucedemo.com
      artifact: smoke-report
    secrets: inherit

Make lint and smoke / run required status checks in your ruleset.


🌙 Step 3: Regression on main and Nightly

# .github/workflows/regression.yml
name: Regression
on:
  push:
    branches: [ main ]
  schedule:
    - cron: '30 20 * * *'          # 02:00 IST

jobs:
  regression:
    strategy:
      fail-fast: false
      matrix:
        project: [ chromium, firefox, webkit ]
    uses: ./.github/workflows/playwright-run.yml
    with:
      project: ${{ matrix.project }}
      base-url: https://www.saucedemo.com
      artifact: regression-report-${{ matrix.project }}
    secrets: inherit

🎛️ Step 4: Manual Run Against an Environment

# .github/workflows/manual.yml
name: Manual test run
on:
  workflow_dispatch:
    inputs:
      target:  { type: environment, description: 'Environment to test' }
      project: { type: choice, options: [ chromium, firefox, webkit ], default: chromium }
      grep:    { type: string, description: 'Tag filter, e.g. @smoke', default: '' }

jobs:
  info:
    runs-on: ubuntu-latest
    environment: ${{ inputs.target }}
    outputs:
      base-url: ${{ vars.BASE_URL }}
    steps:
      - run: echo "Testing ${{ vars.BASE_URL }}"

  run:
    needs: info
    uses: ./.github/workflows/playwright-run.yml
    with:
      project: ${{ inputs.project }}
      grep: ${{ inputs.grep }}
      base-url: ${{ needs.info.outputs.base-url }}
      artifact: manual-report
    secrets: inherit

Create environments qa and staging, each with a BASE_URL variable, and trigger runs from the Actions tab or with gh workflow run manual.yml -f target=qa -f grep=@smoke.


🤖 Step 5: Dependabot and README

# .github/dependabot.yml
version: 2
updates:
  - package-ecosystem: npm
    directory: "/"
    schedule: { interval: weekly }
    groups:
      playwright: { patterns: [ "@playwright/*" ] }
  - package-ecosystem: github-actions
    directory: "/"
    schedule: { interval: monthly }

Add the badges for pr.yml and regression.yml to the README and document how to run tests locally and in CI.


🌐 Step 6 (Optional): Publish the Latest Report

Add a job to regression.yml that downloads the Chromium report artifact and deploys it with actions/upload-pages-artifact and actions/deploy-pages (see deployment). Only for public, non-sensitive projects.


✅ Acceptance Checklist

  • [ ] A PR with a failing smoke test cannot be merged
  • [ ] Lint and type errors fail the PR
  • [ ] Regression runs on main and nightly in 3 browsers; one browser failing does not cancel the others
  • [ ] Reports and traces downloadable for every run
  • [ ] No secrets in YAML; manual runs choose an environment
  • [ ] npm cache hit on repeat runs
  • [ ] Dependabot PRs appear and run the PR pipeline
  • [ ] README shows green badges

🏅 Evaluation Rubric

CriterionWeight
Correct triggers and required checks20%
Reuse (reusable workflow, no copy-paste)20%
Speed (cache, concurrency, smoke vs regression split)15%
Debuggability (artifacts, traces, summaries)15%
Security (secrets, permissions, Dependabot)15%
Documentation (README, badges)15%

❓ FAQ

🤔 Do I need a Playwright project for this?

Yes, any Playwright project works. The e-commerce framework from the Playwright course is ideal.

🤔 Why split smoke and regression?

Smoke tests give fast feedback on every PR; the slower full regression runs on main and nightly across all browsers.

🤔 Why use a reusable workflow?

All pipelines share one definition of how tests run, so a change (for example a new Node version) is made once.

🤔 How do I add this project to my CV?

Link the repository, mention the pipelines (PR gate, cross-browser nightly, manual environment runs) and show the green badges.


🎯 Next Steps

🎬 Learn Git and GitHub step by step: watch the series on YouTube!

Subscribe to SqaToolsByDY • Practice on sqatools.in

Leave a Comment