Skip to content

Docs: ci.md recommends a job timeout with no globalTimeout, so an over-running suite is cancelled with no report #42533

Description

Summary

The recommended GitHub Actions workflow in docs/src/ci.md sets a job-level timeout-minutes but never mentions globalTimeout, which defaults to no timeout. When a suite grows past the job timeout, the runner kills the job, the run's conclusion is cancelled rather than failure, and the report upload step in that same example is skipped by its own if: ${{ !cancelled() }} guard. So you get no report on precisely the runs where you most need one, and nothing in the run distinguishes it from a job somebody cancelled by hand.

I would like to add a short note about this to ci.md, and I am filing this first per CONTRIBUTING.

The current state of the docs

docs/src/ci.md, "On push/pull_request":

jobs:
  test:
    timeout-minutes: 60
    ...
    - name: Run Playwright tests
      run: npx playwright test
    - uses: actions/upload-artifact@v5
      if: ${{ !cancelled() }}

globalTimeout appears zero times in ci.md. It is documented in test-timeouts-js.md, where the default is listed as "no timeout", but that page does not connect it to a CI job timeout.

So a reader who follows the CI guide exactly ends up with a hard runner kill as the only bound on their run, and nothing tells them what that costs.

What actually happens

Some numbers from a repository where this ran unnoticed for two months, with a 20 minute job timeout and a suite that had grown past it:

  • 164 nightly runs. 7 succeeded, 76 failed, 81 ended cancelled, the last 60-plus consecutively.
  • Every cancelled run produced zero artifacts. The upload step reported success in the ones that were not guarded by !cancelled(), because there was simply nothing on disk to upload.
  • After setting globalTimeout below the job timeout, the same suite completed in 29 minutes, reported failure with 12 of 147 tests failing, and produced an 83 MB report.

The suite had needed 29 minutes for a while. The 20 minute limit had been killing it nightly, and because a kill is not a failure, nothing said so.

Why it seems worth a line in the docs

GitHub code search reports roughly 163,000 playwright.config.ts files, of which about 1,700 set globalTimeout. That is around one percent. Around 3,200 workflows run npx playwright test on a cron schedule, which is the case where nobody is watching the run live and the missing report matters most.

The ordering is the useful part, and it is not obvious: globalTimeout set below the job's timeout-minutes makes Playwright stop itself first. It exits non-zero, the reporters finish, the HTML report and results.json are written, and the run reads as an ordinary test failure. The runner timeout then only has to cover the install and upload steps around the run.

Proposed change

A short note in ci.md near the GitHub Actions example, along the lines of:

The timeout-minutes above is a hard kill, not a test failure. If your suite outgrows it, the runner stops the process mid-run, the job's conclusion is cancelled, and no report is written. Setting globalTimeout below it lets Playwright stop itself first, so an over-running suite fails with a full report instead.

Happy to open the PR if this is something you would take, in ci.md alone or in both pages. I have no preference on wording and will follow whatever the team prefers.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions