Why a browser test can pass locally and fail in CI

Arni Mittal··2 min read

A test passing on a laptop and failing in CI has at least two environments to explain. Start there, and save the original failure's screenshots and output before you rerun anything.

Compare the environments

Go through these in order, since the first few account for a lot:

  1. The app. Does CI reach the deployment you think it does? A shared staging URL may not be serving this commit.
  2. The data. Is the account or fixture in the same state? Local databases often have data CI doesn't, and shared records can be changed by another run.
  3. Credentials. Are the CI secrets the ones the test expects?
  4. The browser. Viewport, locale and time zone often differ. A date assertion written in one time zone can fail in another.
  5. Speed. CI runners are often slower than a laptop, so background work may finish later than the test assumes.

Then inspect the assertion

Is the test waiting for a meaningful application state, or merely assuming an operation has finished after a fixed delay? A wait for "Saved" to appear holds up on a slower machine. A two-second sleep might not.

If the failure comes and goes

Run the same test repeatedly in CI before you change anything. If it fails sometimes, you're probably looking at timing or shared data. If it always fails in CI and never locally, look for a configuration difference.

With Zerocheck

Zerocheck records the environment, the browser location and the YAML with each result, so you can open a local run and a CI run and compare them. The CLI can run on a development machine or a CI runner, while the hosted browser needs a URL it can reach. In all three, your instance makes the decisions and keeps the results, so a local browser changes where the browser runs and not the connection it needs.

For the setup itself, see how to run browser tests in GitHub Actions.

Try it on your own app

US$500 in credits at sign up, with a dedicated instance and hands-on onboarding.

Book a setup call