# Playwright

Playwright is a popular end-to-end testing framework for web applications.

Namespace provides high-performance caching for [Playwright](https://playwright.dev) test runs. By using [Cache Volumes](/content/docs/solutions/github-actions/caching.md#using-a-cache-volume/index.html), you can cache Playwright's browser binaries and system dependencies across workflow runs, significantly reducing test setup time.

Making full use of the CPUs on our high-performance [Compute Platform](/content/docs/architecture/compute.md) reduces test times by running tests faster and in parallel.

## Getting started

### 1. Enable caching on your runner profile

Go to your [runner profile configuration](https://cloud.namespace.so/workspace/actions/profiles) and enable caching.

### 2. Add the cache action to your workflow

Use [`namespacelabs/nscloud-cache-action`](/content/docs/reference/github-actions/nscloud-cache-action/index.html) to cache Playwright browsers and apt packages:

```yaml theme={null}
- name: Set up cache
  uses: namespacelabs/nscloud-cache-action@v1
  with:
    cache: |
      playwright
      apt
```

The `playwright` cache mode stores downloaded browsers, and `apt` caches system packages so that `playwright install --with-deps` runs faster on subsequent runs.

### 3. Cache npm dependencies

In addition to Playwright browsers, you can also cache your package manager's dependencies:

**npm**

For npm, add the `npm` cache mode:

```yaml theme={null}
- name: Set up cache
  uses: namespacelabs/nscloud-cache-action@v1
  with:
    cache: |
      playwright
      apt
      npm
```

**pnpm**

For pnpm, add the `pnpm` cache mode:

```yaml theme={null}
- name: Set up cache
  uses: namespacelabs/nscloud-cache-action@v1
  with:
    cache: |
      playwright
      apt
      pnpm
```

**yarn**

For yarn, add the `yarn` cache mode:

```yaml theme={null}
- name: Set up cache
  uses: namespacelabs/nscloud-cache-action@v1
  with:
    cache: |
      playwright
      apt
      yarn
```

### 4. Install and run Playwright as usual

After setting up the cache, install dependencies and run Playwright as you normally would:

```yaml theme={null}
- name: Install dependencies
  run: npm ci

- name: Install Playwright browsers
  run: npx playwright install --with-deps

- name: Run Playwright tests
  run: npx playwright test
```

## What gets cached

| Cache | What's cached |
| - | - |
| Playwright | Browser binaries downloaded by Playwright (Chromium, Firefox, WebKit) |
| APT | System packages installed via apt, including browser dependencies |
| npm / pnpm / yarn | Package manager cache for faster dependency installation |

See the [`nscloud-cache-action`](/content/docs/reference/github-actions/nscloud-cache-action/index.html) documentation for all available cache modes and configuration options.

## Next steps

### Increase the number of workers

Playwright's default configuration uses only 1 worker when it detects a CI environment. To make better use of the available cores, you can increase this for faster test execution. A good starting point is 75% of the available cores—adjust this depending on your workload:

```yaml theme={null}
- name: Run Playwright tests
  run: npx playwright test --workers 75%
```

You can also [configure this in your Playwright configuration](https://playwright.dev/docs/test-parallel#limit-workers).

### Upload test reports

Use [`namespace-actions/upload-artifact`](/content/docs/reference/github-actions/upload-artifact/index.html) to upload Playwright's HTML report for easy debugging:

```yaml theme={null}
- uses: namespace-actions/upload-artifact@v1
  if: ${{ !cancelled() }}
  with:
    name: playwright-report
    path: playwright-report/
    retention-days: 30
```

The `if: ${{ !cancelled() }}` condition ensures the report is uploaded even when tests fail.

## Full example

Here's a complete workflow using Namespace runners with caching:

```yaml theme={null}
name: Playwright Tests

on:
  push:
    branches: [main]
  pull_request:

jobs:
  test:
    timeout-minutes: 60
    runs-on: namespace-profile-playwright
    steps:
      - uses: namespacelabs/nscloud-checkout-action@v7

- uses: actions/setup-node@v6
        with:
          node-version: lts/*
          package-manager-cache: false # Use Namespace toolchain caching instead
          cache: ""

- name: Set up cache
        uses: namespacelabs/nscloud-cache-action@v1
        with:
          cache: |
            playwright
            apt
            npm

- name: Install dependencies
        run: npm ci

- name: Install Playwright browsers
        run: npx playwright install --with-deps

- name: Run Playwright tests
        run: npx playwright test --workers 75%

- uses: namespace-actions/upload-artifact@v1
        if: ${{ !cancelled() }}
        with:
          name: playwright-report
          path: playwright-report/
          retention-days: 30
```

View the full example repository at [namespace-integration-demos/playwright](https://github.com/namespace-integration-demos/playwright).

## Advanced: pre-install browsers and system dependencies

For the fastest and most consistent job startup, pre-install Playwright's browsers and system dependencies directly into your runner profile with a [custom base image](/content/docs/solutions/github-actions/custom-base-images.md). This removes the browser download and `apt-get` install from every job, so workflows start running tests immediately:

```dockerfile theme={null}
ARG NAMESPACE_BASE_IMAGE_REF=""
FROM ${NAMESPACE_BASE_IMAGE_REF} AS base

RUN npx -y playwright@1.49.0 install --with-deps chromium
```

Pin the Playwright version to match your `package.json`; if the versions diverge, Playwright will re-download the matching browser at runtime. With this in place, your workflow can drop `--with-deps` and run plain `npx playwright install` (or skip the install step entirely if the versions match).
