Some links on this page are affiliate links: if you buy through them we may earn a commission, at no extra cost to you.
Playwright’s “global setup timeout” is usually a misleading description. A run that stops after 30 seconds may be hitting the default test timeout, a five-second assertion timeout, a fixture or hook budget, or an operation-specific wait—not globalTimeout. Debug mode appears to fix the problem because npx playwright test --debug sets the default timeout to zero. That removes the symptom while you investigate; it does not identify the stalled operation.
First, identify which timeout actually fired
Read the complete error, including the file, line number, and operation named in the call log. Playwright has independent timeout scopes, so changing one does not extend the others.
| Scope | Documented default or behavior | What to inspect |
|---|---|---|
| Test | 30,000 ms by default, including the test body, fixture setup, and beforeEach |
Project/config timeout, test.setTimeout, hooks, and fixtures |
| Assertion | 5,000 ms by default | The assertion’s timeout or expect.timeout |
| Whole run | globalTimeout is unlimited (disabled) unless configured |
Config and --global-timeout |
| Action or navigation | No timeout by default | Per-call timeout, use.actionTimeout, and navigationTimeout |
| Fixture | Normally shares the test timeout; a fixture can have its own larger timeout | Fixture options and setup/teardown duration |
| Debug mode | Default timeout becomes 0 (no timeout) | Whether the apparent fix is only a changed run mode |
These are rolling-documentation defaults, not a guarantee about your installed Playwright version or resolved configuration. Check the version in the repository and print or inspect the effective configuration before changing values. The official timeout reference is at Playwright’s timeout documentation.
Do these 3 things before closing this tab:
1Scan for outdated or missing drivers - takes under a minute2Clear out junk files and repair common Windows errors3Fix the driver behind crashes, sound loss and screen glitches“Global setup” can mean two different designs
A configuration-level globalSetup callback
A config entry such as globalSetup: require.resolve('./global-setup') loads a module whose default export is one function. Playwright calls that function once before the test projects. It receives the full config object and may return a teardown function; you can also use globalTeardown.
#1 Best Overall
This callback is outside ordinary test execution. It does not appear as a test in the HTML report, does not get the normal setup-project trace, and does not provide test fixtures in the same way a test file does. Consequently, a browser launch, login request, file operation, or external service wait can look like a silent “global setup session” hang. Add explicit logging around every awaited phase:
import type { FullConfig } from '@playwright/test';
export default async function globalSetup(config: FullConfig) {
console.log('[setup] starting');
const started = Date.now();
await createAuthenticatedState();
console.log(`[setup] state ready in ${Date.now() - started} ms`);
}
Log before and after each await, include the URL or resource being accessed, and make failures reject with the original error. The log tells you which operation failed to complete; Playwright’s generic timeout message cannot infer an application-specific network delay, authentication defect, deadlock, or bug.
A setup project used through dependencies
A setup project is a normal Playwright project containing setup tests. Other projects list its name in dependencies, so the runner completes setup before starting dependent projects. The Projects guide recommends this pattern when you need standard runner behavior: setup tests appear in reports and the trace viewer records them.
PC Slower Than It Used to Be?
A free scan shows the junk files, broken settings and background clutter dragging Windows down - then fixes them in one click.Free scan · Windows 10 & 11Crashes, No Sound, or Screen Glitches?
Random freezes, missing sound and display glitches usually trace back to one bad driver. Find and replace yours safely.Free scan · under a minuteimport { defineConfig } from '@playwright/test';
export default defineConfig({
projects: [
{
name: 'setup',
testMatch: /.*\.setup\.ts/,
},
{
name: 'chromium',
use: { browserName: 'chromium' },
dependencies: ['setup'],
},
],
});
import { test as setup } from '@playwright/test';
setup('authenticate', async ({ page }) => {
await page.goto('https://example.test/login');
await page.getByLabel('Email').fill(process.env.TEST_EMAIL!);
await page.getByLabel('Password').fill(process.env.TEST_PASSWORD!);
await page.getByRole('button', { name: 'Sign in' }).click();
await page.context().storageState({ path: 'playwright/.auth/user.json' });
});
This design does not make slow code faster. It makes the work observable and lets you use fixtures, traces, retries, and normal project controls to locate the wait.
Rank #2
- HTML CSS Design and Build Web Sites
- Comes with secure packaging
- It can be a gift option
Why --debug seems to cure the timeout
Run:
npx playwright test --debug
The command opens Playwright Inspector, runs headed with one worker, stops after one failure, and sets the default timeout to zero. Inspector lets you step through actions and view actionability logs; its purpose is investigation, not a production timeout policy. The debugging guide describes Inspector as a GUI for debugging Playwright tests: playwright.dev/docs/debug.
If the test now “works,” compare the behavior carefully. A page may eventually load, a locator may become actionable after an unusually long delay, or setup may be waiting for a service that is unavailable intermittently. Rerun without debug using the original command and timeout after each change. Otherwise you may ship a test that only passes because its limit was removed.
Check the command line and project graph
--no-deps intentionally skips project dependencies. If authentication or data creation is a setup project, this flag bypasses it rather than diagnosing it:
npx playwright test --no-deps
Remove the flag when verifying setup execution. In a dependency-based design, the report should contain the setup project before dependent projects. If it does not, check the project name spelling, dependencies array, testMatch, and the selected project filters.
Rank #3
Set the smallest timeout that matches the slow operation
Test and hook budget
Use a project or test timeout when the complete test—including fixtures and hooks—legitimately needs more time:
import { test } from '@playwright/test';
test('slow setup scenario', async ({ page }) => {
test.setTimeout(120_000);
await page.goto('https://example.test');
});
Do not inflate every test to accommodate one slow fixture. A large global test timeout hides regressions and delays feedback.
Fixture-specific budget
Playwright supports a separate timeout for a slow fixture. Keep ordinary tests at their normal limit while granting only the fixture the additional budget. Consult the fixture-timeout example in the official docs: playwright.dev/docs/test-fixtures.
The Tool Desk
Outbyte Driver Updater FREEFix the driver behind crashes, sound loss and screen glitchesFind Drivers →Outbyte PC Repair FREEClear out junk files and repair common Windows errorsFree Scan →Assertion, action, and navigation limits
Increase an assertion timeout only when the expected eventual consistency requires it. Set an action or navigation timeout when you want an explicit upper bound; remember that actions and navigations otherwise have no default timeout. A navigation that never resolves should be investigated for redirects, service-worker behavior, blocked resources, DNS, and application readiness rather than covered with an arbitrarily large number.
Rank #4
- Brand: Wiley
- Set of 2 Volumes
- A handy two-book set that uniquely combines related technologies Highly visual format and accessible language makes these books highly effective learning tools Perfect for beginning web designers and front-end developers
Whole-run limit
globalTimeout limits the entire suite, not an individual setup callback or test. It is disabled by default. A command-line --global-timeout or config value can terminate a busy suite, but it will not change a 30-second test timeout or a five-second assertion timeout. See the TestConfig timeout reference.
A repeatable diagnosis procedure
- Capture the exact error. Record whether it names a test, hook, fixture, assertion, navigation, action, or whole run.
- Confirm the mechanism. Locate
globalSetupin the config or identify a setup project and its dependent projects. - Run one target in debug mode. Use Inspector to see the last action and its actionability log, but remember that timeout zero changes the experiment.
- Run with normal settings. Reproduce under the original command so you know which configured budget is exceeded.
- Instrument opaque code. Add before/after logs around each await in config setup, fixtures, hooks, API calls, and browser operations.
- Inspect setup visibility. For dependencies, open the report and trace. For config-level setup, rely on your explicit logs and external service logs.
- Change one scope only. Give a slow fixture, assertion, navigation, or test the narrowest appropriate timeout; do not raise
globalTimeoutas a universal fix. - Re-run without debug. Verify the fix under normal workers, retries, headed/headless mode, and the CI environment.
Common symptoms and fixes
- “Timeout 30000ms exceeded” before the first assertion: a test, hook, or fixture consumed the test budget. Inspect the last log and fixture setup.
- “expect … timed out after 5000ms”: only the assertion budget expired. Check the locator, application state, and assertion-specific timeout.
- It passes only with
--debug: timeout zero masked a slow or blocked step. Reproduce normally and instrument the await. - Setup never appears in the report: you are likely using config
globalSetup, not a dependency project. Move runner-visible work into a setup project if traces and fixtures matter. - Dependent tests run without authentication:
--no-deps, a project filter, or an incorrect dependency name skipped setup. - A run stops after a suite-wide limit: inspect
globalTimeoutand--global-timeout; this is distinct from per-test limits. - CI times out but a laptop does not: compare environment variables, network access, browser binaries, CPU contention, worker count, and service readiness. Add timestamps rather than guessing.
When a setup project is the better long-term design
Choose a dependency project when setup should be a first-class, reportable piece of the run, needs Playwright fixtures or browser management, or benefits from traces. Keep config-level globalSetup for genuinely one-time callback logic that does not need those runner features. Neither design guarantees completion: the awaited operation still needs a reachable service, valid credentials, and correct code.
Or skip the browser setup
If your goal is simply to capture a page rather than run an end-to-end test, ScreenshotNeo provides a website screenshot API and MCP server. One GET request returns PNG, JPEG, WebP, or PDF, with options for full-page lazy-image loading, CSS-selector element capture, device and retina settings, custom CSS or JavaScript, waits, cookies, headers, blocking, geolocation, PDF ranges, caching, signed links, async webhooks, and bulk capture.
Recommended Free Tools
Example using the documented API; see the ScreenshotNeo documentation for parameters:
Best Value
curl -G "https://api.screenshotneo.com/v1/shot" -d access_key=YOUR_API_KEY --data-urlencode url=https://stripe.com -o shot.webp
import requests
r = requests.get("https://api.screenshotneo.com/v1/shot", params={"access_key": "YOUR_API_KEY", "url": "https://stripe.com"}, timeout=90)
open("shot.webp", "wb").write(r.content)
const q = new URLSearchParams({ access_key: 'YOUR_API_KEY', url: 'https://stripe.com' });
const res = await fetch(`https://api.screenshotneo.com/v1/shot?${q}`);
ScreenshotNeo accepts cookie and consent banners before capture and removes more than 60 known consent platforms, newsletter popups, and chat widgets; each step can be disabled. Bot checks or CAPTCHAs, blank pages, timeouts, failed loads, and cache hits are not billed, and response headers report the page verdict and billing result. Its MCP server exposes take_screenshot, get_page_info, and capture_pdf to Claude, Cursor, and other MCP clients. The Free plan includes 1,000 shots a month with no card; paid plans start at $5 for 3,000 shots. Create a free ScreenshotNeo account.
FAQ
Does globalSetup have its own documented default timeout?
The important documented defaults are the test, assertion, action/navigation, fixture, and whole-run scopes. Determine the effective limit from the callback’s awaited operations and your repository configuration rather than treating “global setup” as one timeout category.
Can I get a trace for config-level global setup?
Use a setup project with dependencies when setup tracing and report entries are required. Config-level setup is not represented as an ordinary setup test.
Should I leave debug mode enabled in CI?
No. Use it to inspect progress, then validate the correction with the normal command and configured limits.
Quick Recap
Product prices and availability are accurate as of the date/time indicated and are subject to change. Any price and availability information displayed on Amazon at the time of purchase will apply.

