lecture 10 of 180 completed

Content that appears, changes and disappears

Lists that load late, rows that update in place, and messages that vanish. Where auto-waiting saves you and where it does not.

The contacts page shows a spinner, then the table appears. Your test opens the page and counts the rows immediately. It finds zero.

Playwright handles most of this for you, which is exactly why the cases where it cannot are worth knowing.

Content that arrives late.

This works, and it is worth understanding why:

await page.goto('/contacts');
await expect(page.getByTestId('contact-row')).toHaveCount(5);

expect with a locator is a web-first assertion. It retries until the condition is true or the timeout runs out. If the rows arrive after 800ms, the assertion passes at 800ms.

Here is the version that does not work:

const count = await page.getByTestId('contact-row').count();
expect(count).toBe(5);          // checked once, no retry

.count() reads the number right now and hands you a plain value. expect(5) on a plain number cannot retry, because there is nothing to re-check. If the rows had not arrived, this fails permanently.

The rule that follows is worth memorising: keep the locator inside expect. The moment you await a value out of the locator, you lose retrying.

Content that changes in place.

You click "mark as won" and a status cell changes from Open to Won. Nothing appears or disappears, so assert the new value:

await expect(page.getByTestId('status-dana-fox')).toHaveText('Won');

This retries until the text matches, then fails with a clear diff if it never does.

Content that disappears.

Toasts are the usual case. Checking one is gone has its own assertion:

await expect(page.getByTestId('toast')).toBeHidden();

More important than the syntax: do not build the rest of your test on a message designed to vanish. Check it once, straight away, then move on to something permanent.

That last point has a bigger version. A toast tells you the app claims it saved. The row still present after a reload tells you it did. When a test can check either, check the durable one. That is exactly what the problem below asks for.

Remember this: keep locators inside expect so assertions retry, and prefer the permanent result over the temporary message.

Reference: Auto-waiting.

now prove it

Reading is the setup. Solve this problem in the editor. We break the app on purpose to check your test would catch it.