Playwright Tests Timing Out on CI Pipeline
Your Playwright end-to-end tests pass consistently in local development but timeout or fail intermittently on CI platforms like GitHub Actions, Vercel, or GitLab CI. Tests that complete in seconds locally take minutes on CI before being killed by the timeout, and the same test suite may pass on one run and fail on the next.
CI environments have significantly fewer resources than developer machines. Shared runners have limited CPU, memory, and no GPU acceleration for browser rendering. Combined with the overhead of starting a Next.js development server and launching browser instances, tests that are fast locally can exceed CI timeouts by a large margin.
V0-generated Playwright configurations often use default settings optimized for local development, not for resource-constrained CI environments where tests run headless on shared infrastructure.
Error Messages You Might See
Common Causes
- Dev server slow to start on CI — next dev takes 30+ seconds on CI runners, causing tests to start before the server is ready
- Default timeouts too short — Playwright's 30-second default timeout insufficient for CI rendering speeds
- Too many parallel workers — default worker count matches CPU cores, which overwhelms CI runners with limited resources
- Browser installation missing — Playwright browsers not cached between CI runs, adding minutes to each pipeline
- Animations and transitions — CSS animations that complete instantly locally take full duration on underpowered CI
- Network requests to external services — tests hitting real APIs that are slow or rate-limited from CI IP addresses
How to Fix It
- Use production build — run
next buildthennext startinstead of next dev for faster, more consistent performance on CI - Increase timeouts — set
timeout: 60000in playwright.config.ts and per-test timeouts for slow operations - Limit workers — set
workers: 1orworkers: process.env.CI ? 1 : undefinedto prevent resource contention on CI - Cache Playwright browsers — add browser cache to your CI configuration to avoid downloading browsers on every run
- Wait for server properly — use
webServer: { command: 'next start', url: 'http://localhost:3000', reuseExistingServer: !process.env.CI } - Mock external APIs — use Playwright's route.fulfill() to mock external API responses and eliminate network dependencies
Real developers can help you.
You don't need to be technical. Just describe what's wrong and a verified developer will handle the rest.
Get HelpFrequently Asked Questions
Why do tests pass locally but fail on CI?
CI runners have less CPU, memory, and no GPU. Tests that complete in milliseconds locally can take seconds on CI. Increase timeouts and reduce parallelism.
How do I cache Playwright browsers on GitHub Actions?
Use actions/cache with key based on playwright version: path: ~/.cache/ms-playwright, key: playwright-${{ hashFiles('package-lock.json') }}.
Should I use next dev or next start for CI tests?
Always use next build && next start for CI. The production build is faster, more consistent, and closer to what users actually experience.