Skip to content
Latchkey

Playwright "expect(received).toHaveText(expected)" race in CI

A toHaveText assertion saw the wrong (often empty or placeholder) text because the content had not finished rendering when it was read. Web-first assertions auto-retry up to the expect timeout, so when this fails it usually means the timeout was too short for the slower CI machine or the text never becomes what you assert.

What this error means

The diff shows the expected string against an empty or stale "Received string", and the test is flaky: green locally, red in CI, green on retry.

playwright
Error: expect(received).toHaveText(expected)
Expected string: "Welcome, Ada"
Received string: ""
Call log:
  - expect.toHaveText with timeout 5000ms
  - waiting for getByTestId('greeting')

Common causes

The text had not rendered when asserted

Async data populates the element after first paint; on a slower CI runner the 5s expect timeout can elapse before the text appears.

A non-retrying assertion on a snapshot value

Reading textContent() into a variable and asserting that with expect(value) does not auto-retry, so it captures the pre-render state.

How to fix it

Use the auto-retrying web-first assertion

Assert on the locator directly so Playwright polls until the text matches or the timeout elapses.

tests/home.spec.ts
await expect(page.getByTestId('greeting'))
  .toHaveText('Welcome, Ada');

Raise the expect timeout for CI

Give web-first assertions more time so genuinely slow renders are not misreported as failures.

playwright.config.ts
expect: { timeout: 10_000 },

How to prevent it

  • Assert on locators, never on captured textContent() snapshots.
  • Size the expect timeout for the slowest CI runner.
  • Wait for the network/data state the text depends on before asserting.

Frequently asked questions

What causes ""expect(locator).toHaveText" failed"?
Async data populates the element after first paint; on a slower CI runner the 5s expect timeout can elapse before the text appears.
How do I fix "expect(locator).toHaveText" failed?
Assert on the locator directly so Playwright polls until the text matches or the timeout elapses.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card