[Bug]: test.slow(callback) does not extend the timeout of the test it runs in when the callback only uses worker fixtures

Open
#42,808 0 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
35/100
Issue type
Bug
Clarity
Clearly specified
Activity status
Active
Tech stack
typescript
Domain
testing

Research direction

Start with workerMain.ts and _runAllHooksForSuite, then trace how TimeoutManager.slow() selects the running slot. Reproduce with playwright.config.ts and a.spec.ts from the report; done means worker-only test.slow() callbacks give affected tests a 3000ms timeout and the regression is covered by tests.

Written by the indexing model from the issue text.

Description

Version

1.64.0-next (main @ 07f1a6154); also affects 1.59 through 1.63

Steps to reproduce

playwright.config.ts:

export default { timeout: 1000 };

a.spec.ts (this is the documented form from the test.slow docs, "You can mark all tests in a file or test.describe group as slow ... by passing a callback"):

import { test } from '@playwright/test';

test.slow(({ browserName }) => browserName === 'chromium', 'all tests are slow in chromium');

test('first', async ({}) => {
  console.log('first timeout=' + test.info().timeout);
  await new Promise(r => setTimeout(r, 1500));
});

test('second', async ({}) => {
  console.log('second timeout=' + test.info().timeout);
  await new Promise(r => setTimeout(r, 1500));
});
npx playwright test --workers=1
Expected behavior

Both tests run with a 3000ms timeout and pass.

Actual behavior
first timeout=1000
  1) a.spec.ts:5:5 › first ─── Test timeout of 1000ms exceeded.
second timeout=1000
  2) a.spec.ts:10:5 › second ─ Test timeout of 1000ms exceeded.
  2 failed

The first test never gets the extended timeout. When it fails, the worker restarts, the modifier re-runs for the next test and again does not apply, so every test in the file fails at the base timeout. The same happens with test.slow(() => true).

If the tests do not time out, the second and later tests do get 3000ms (the slow annotation is inherited by subsequent tests in the suite), which hides the problem until a test really needs the extra time.

Additional context
  • A modifier callback whose fixtures are all worker-scoped (browserName, or no fixtures at all) is classified as a beforeAll-style hook and runs in its own time slot (workerMain.ts, _runAllHooksForSuite).
  • TimeoutManager.slow() triples the currently running slot (this._running.slot) instead of the test's default slot, so the modifier's private slot is tripled and the test's timeout is untouched.
  • Since #39596 (test.slow() idempotency, 1.59) the _slow flag is set on that first call, so the inherited annotation or a later test.slow() in the test body is a no-op.

The same mechanism affects test.slow() called from a fixture that has its own { timeout }: the fixture slot is tripled, the test slot is not, and a subsequent test.slow() in the test body silently does nothing.

I intend to work on this and will send a PR.

Environment
- Operating System: macOS (Darwin 25.6.0)
- Node.js: 24.8.0
- Browser: Chromium (bundled r1246)
- Playwright: main @ 07f1a6154
Dominant language
TypeScript
Stars
96.4k
Forks
6.5k
Avg merge
1d 7h
Merged PRs (30d)
170

Contributor guide

Open the contributing guide

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from microsoft/playwright

All issues in microsoft/playwright

Similar issues

More TypeScript issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.