Chapter 16 · CI Integration and Docker
Chapter goals: Run the E2E suite in GitHub Actions, use the official container to guarantee environment consistency, and automatically retain traces and other diagnostic artifacts on failure.
16.1 CI in Three Steps
The official docs summarize CI integration as three steps:
- Make browsers runnable on the CI machine — use the official Docker image on Linux, or install system dependencies via CLI;
- Install Playwright —
pip install playwright && playwright install --with-deps; - Run tests —
pytest.
The --with-deps flag installs OS-level dependency libraries (libnss3, etc.) in one go — skipping it is the #1 reason for "works locally, breaks in CI with missing library" errors.
16.2 GitHub Actions Basic Workflow
Official example workflow (Python edition):
```yaml # .github/workflows/playwright.yml 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@v6
- name: Set up Python
uses: actions/setup-python@v6
with:
python-version: "3.13"
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Ensure browsers are installed
run: python -m playwright install --with-deps
- name: Run your tests
run: pytest --tracing retain-on-failure # Keep trace on failure
- name: Upload traces # Upload artifacts regardless of pass/fail
uses: actions/upload-artifact@v5
if: ${{ !cancelled() }}
with:
name: playwright-traces
path: test-results/
</template>
Two details worth digesting:
- **`--tracing retain-on-failure`** is a pytest-playwright flag: only failing cases write traces to disk; passing ones don't waste space;
- The upload step's <code v-pre>if: ${{ !cancelled() }}</code> ensures **traces are still uploaded even when the workflow is marked failed** — otherwise you only see a red X with no evidence.
## 16.3 Consistent Environments with the Official Container
Host environment drift (fonts, timezone, dependency versions) makes screenshot assertions fail mysteriously. The official image `mcr.microsoft.com/playwright/python` ships all browsers and system deps out of the box — run the job directly inside the container:
<template v-pre>
```yaml
jobs:
playwright:
timeout-minutes: 60
runs-on: ubuntu-latest
container:
image: mcr.microsoft.com/playwright/python:v1.61.0-noble # Match the pip-installed playwright version
options: --user 1001 # Non-root is safer
steps:
- uses: actions/checkout@v6
- name: Install dependencies
run: |
python -m pip install --upgrade pip
pip install -r requirements.txt
- name: Run tests
run: pytest --tracing retain-on-failure --screenshot only-on-failure
- name: Upload artifacts
uses: actions/upload-artifact@v5
if: ${{ !cancelled() }}
with:
name: playwright-artifacts
path: test-results/16.4 Handling Flaky Network Dependencies
For tests hitting external services, add retry and timeout guards:
- name: Run tests with retries
run: |
pip install pytest-rerunfailures
pytest -n auto --reruns 2 --reruns-delay 5 \
--timeout 30000 --tracing retain-on-failureThe combination of xdist parallelism (-n auto), automatic retry (--reruns 2), and trace retention gives CI a solid baseline.
16.5 Chapter Summary
- CI needs three things: browser installation (
--with-deps), test execution (pytest), artifact upload; --tracing retain-on-failure+if: ${{ !cancelled() }}ensures traces are always available for debugging;- Official Docker containers eliminate environment drift;
- Add
pytest-rerunfailuresfor transient network flakiness.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What does playwright install --with-deps do that plain playwright install does not?
2. Why use if: ${{ !cancelled() }} on the artifact upload step?
3. What is the primary benefit of running Playwright tests inside the official Docker container?
4. Which combination best handles transient network flakiness in CI?
🛠️ Hands-On Exercises
- Write a GitHub Actions workflow that runs the Playwright suite on push to main with
--tracing retain-on-failureand artifact upload. - Run the same workflow locally using the official Docker container (
mcr.microsoft.com/playwright/python) and compare results. - Introduce a flaky network dependency (mock a slow API); add
--reruns 2and observe how many cases survive the retry.
Proceed to Chapter 17: APIRequestContext and API Testing.