Skip to content
Latchkey

Backstage e2e Playwright test fails to reach the app in CI

Backstage e2e tests drive the running app with Playwright. In CI they often fail not from a real bug but because the test navigates before the backend has finished starting, so the first page load is refused.

What this error means

Playwright fails with "net::ERR_CONNECTION_REFUSED at http://localhost:3000" or a navigation timeout, while the app starts fine when run by hand.

playwright
Error: page.goto: net::ERR_CONNECTION_REFUSED at http://localhost:3000/
    at CatalogPage ...
1 failed
  [chromium] catalog loads

Common causes

The app is not serving yet when the test starts

The backend build and startup take time; the test navigates before the port is listening, so the connection is refused.

Missing config makes the backend exit early

An unset app-config value or a database that is not ready stops the backend, so the app never comes up.

How to fix it

Wait for the app to serve before testing

  1. Use the Playwright webServer config to start the app and wait for its URL.
  2. Set a generous timeout for the first build and start.
  3. Only then run the e2e specs.
playwright.config.ts
webServer: {
  command: 'yarn start',
  url: 'http://localhost:3000',
  timeout: 180000,
  reuseExistingServer: false,
}

Provide the config the backend needs to start

Ensure required env and a ready database exist so the backend actually serves before the test runs.

.github/workflows/ci.yml
env:
  BACKEND_SECRET: ${{ secrets.BACKEND_SECRET }}
  POSTGRES_PASSWORD: postgres

How to prevent it

  • Gate e2e on the app URL being reachable, not a fixed sleep.
  • Provide all config and services the backend needs to start.
  • Give the first build and start a generous timeout in CI.

Related guides

Tired of flaky CI? Latchkey auto-heals failed jobs and retries them for you. Start free →