@pw-studio/cli
v0.1.0-20261015112000-5b9775
Published
Playwright Studio CLI (pws) and Playwright reporter
Readme
@pw-studio/cli
Duration-aware sharding for Playwright. pws test wraps playwright test: it records how long
every test file takes and splits the files across shards so each shard finishes at about the same
time, instead of Playwright's alphabetical split.
Getting started
Add the CLI next to
@playwright/test(1.50 or newer):npm install --save-dev @pw-studio/cliInstall the Playwright Studio GitHub App on your repository, copy the project secret from the dashboard and store it as a CI secret named
PWS_SECRET.In CI, replace
playwright testwithpws testand pass the secret (see GitHub Actions). Commit and push: this first run has no history yet, so it splits files evenly and records how long each one takes.To see duration-aware sharding in action, push another commit. Re-running the first workflow is not enough: a run keeps the plan it started with (see Plans), so only a new run uses the timings recorded in step 3. An empty commit works:
git commit --allow-empty -m "Shard with recorded timings" && git push
Usage
pws test # runs everything, records timings in CI
pws test --shard=1/4 # runs the files the studio assigned to shard 1 of 4
pws test tests/checkout -- --grep smoke --workers 2Test file filters go before --; any other Playwright argument goes after it and is passed on
unchanged. Your configured reporters are kept. pws test --help lists every flag.
GitHub Actions
jobs:
test:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
shard: [1, 2, 3, 4]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx playwright install --with-deps
- run: npx pws test --shard=${{ matrix.shard }}/${{ strategy.job-total }}
env:
PWS_SECRET: ${{ secrets.PWS_SECRET }}Plans
The first shard of a run to start computes the plan and every other shard of that run gets the same one. The plan is fixed from then on: re-running the workflow ("Re-run failed jobs" or "Re-run all jobs") reuses it, even if timings were recorded since. Push a new commit to get a fresh plan.
The run id is taken from GitHub Actions, GitLab CI, Buildkite or CircleCI automatically; elsewhere
set PWS_RUN_ID to a value shared by every shard of the run.
Timings are kept per kind of machine, identified as <platform>-<arch>-<cpus>cpu (e.g.
linux-x64-16cpu), so a fast runner's durations never skew a slow runner's plan. Local runs (no
run id) record nothing, and --shard needs a run id.
Settings
| Setting | Flag | Env | Default |
| -------------- | ----------- | ----------------- | ----------------------------------- |
| Project secret | | PWS_SECRET | required to shard and record |
| Server | --pws-url | PWS_URL | https://api.pw.studio |
| Run id | | PWS_RUN_ID | detected from CI, else none (local) |
| CI attempt | | PWS_RUN_ATTEMPT | GITHUB_RUN_ATTEMPT, else 1 |
If the studio cannot be reached while sharding, pws exits with code 1 rather than risk skipping or
duplicating tests across shards.
Reporter only
To record timings in CI without the wrapper, add the reporter to playwright.config.ts:
reporter: [["list"], ["@pw-studio/cli/reporter"]],License
MIT
