Wait for text to appear
Let a label, message, or heading settle before you assert on it, without guessing a delay.
A button triggers an update and some text lands a moment later. Wait for the text, not for the clock. A web-first assertion polls the page until the string is there, then returns.
Assert the text with auto-retry
toHaveText() and toContainText() re-check the element until it matches or the timeout runs out. In the Playwright\Testing\expect() helper, both match a substring for compatibility. Use toHaveExactText() when the complete text matters.
use function Playwright\Testing\expect;
$page->getByRole('button', ['name' => 'Save'])->click();
expect($page->getByRole('status'))->toHaveText('Changes saved');
The click returns before the server responds. The assertion covers that gap on its own, so there is nothing to time by hand.
Make substring intent explicit
When the node holds more than the part you care about, assert the substring:
use function Playwright\Testing\expect;
expect($page->getByRole('alert'))->toContainText('3 items updated');
toContainText() makes the substring intent clear. The testing helper also treats toHaveText() as a substring match, while toHaveExactText() compares the complete text content.
Give a slow update more room
The default timeout covers most cases. Raise it on the one slow step rather than for the whole run:
use function Playwright\Testing\expect;
expect($page->getByText('Report ready'))->withTimeout(15000)->toHaveText('Report ready');
withTimeout() takes milliseconds.
The sleep trap
sleep(2); // waits for the clock, not the text
sleep(2) is wrong twice over: too short when the server lags, wasted time when it is quick. toHaveText() returns the instant the text matches and fails with a clear message when it never does.
Expected result
The assertion returns only after the expected text is present, or fails with a clear timeout message. No fixed delay is needed.
Go next
- Assert a list count: the same retry model for counts
- Choosing assertions: pick the assertion that matches the product signal
- Timeouts and retries: where waiting budgets come from