Assert a list count

Check how many elements a locator matches, and wait for the right number instead of counting too early.

A list should hold a known number of rows after an action. Assert the count with retry so a slow render does not fail the check, and reach for the raw number only when you need it as data.

Assert the count with retry

toHaveCount() polls until the locator matches exactly that many elements or the timeout runs out. It waits for the list to settle, so you do not have to.

php
use function Playwright\Testing\expect;

$page->getByRole('button', ['name' => 'Load users'])->click();

expect($page->getByRole('row'))->toHaveCount(5);

The click returns before the rows render. The assertion covers that gap and fails with a clear message if the count never reaches five.

Read the raw number when you need it

count() returns the current number of matches as an integer. It reads once and does not retry, so use it for a value to compute with, not to wait on.

php
$open = $page->getByRole('listitem')->count();

echo "Open items: {$open}".PHP_EOL;

The counting-too-early trap

php
// wrong: reads before the list has rendered
self::assertSame(5, $page->getByRole('row')->count());

count() samples the page the instant you call it. Right after a click, the rows may not be there yet, so the number is too low. toHaveCount(5) waits for the fifth row instead of guessing that it has arrived.

When you do need the raw number, assert the count first, then read:

php
use function Playwright\Testing\expect;

expect($page->getByRole('row'))->toHaveCount(5);

$rows = $page->getByRole('row')->count();

Expected result

The assertion retries until exactly five rows exist. If the page renders four, six, or never finishes loading, the failure points to the list count instead of a stale sampled integer.

Go next

← All recipes