Wait for content the page owns before scanning it

Several accessibility scans ran against a page that had not finished
arriving, so axe reported violations the app does not have. The worst of
them was the medications case, which waited for a level-one heading and
then checked that a level-one heading exists. A page that really lost its
heading would have waited out the timeout under a misleading name instead
of failing the rule, which makes it a check that cannot fail rather than a
flaky one.

The filter rail was the other bad sentinel. It renders beside the loading
silhouettes rather than after them, so it was on screen while the rows were
still grey rectangles. Under an 8x CPU throttle the rail and the loading
marker resolved in the same 40ms poll and the rows a poll later.

Every case now gates on a marker the real component carries in its
resolved, non-empty branch, and on a component other than the one the scan
asserts. Both the desktop table and the mobile card list carry the same
marker so the wait holds at any viewport. No sentinel names a heading, the
app frame, a busy marker or the filter rail any more.
This commit is contained in:
Marc-André Bombeck committed 2026-08-02 18:50:31 +02:00
1 parent 210380f46d
commit 47e50ece39
10 files changed
+153 -31

No files matched your search

+11 -2
View File
@@ -629,7 +629,16 @@ export function MoodList({ onAddFirst }: MoodListProps = {}) {
) : (
<>
{/* Desktop table */}
<div className="bg-card border-border hidden overflow-hidden rounded-lg border md:block">
<div
// `mood-rows` marks the READ entries, not the list frame: the
// filter rail above renders next to the loading silhouettes
// too, so it proves nothing about the data having arrived.
// This wrapper exists only in the resolved, non-empty branch,
// and the mobile list below carries the same marker so a wait
// on it holds at any viewport.
data-slot="mood-rows"
className="bg-card border-border hidden overflow-hidden rounded-lg border md:block"
>
<Table>
<TableHeader>
<TableRow>
@@ -760,7 +769,7 @@ export function MoodList({ onAddFirst }: MoodListProps = {}) {
`data-testid="mood-row"` hook is what the Playwright Pixel-5
guard at `e2e/mood-card-mobile.spec.ts` queries to assert
"exactly one occurrence of the score per row". */}
<div className="space-y-2 md:hidden">
<div data-slot="mood-rows" className="space-y-2 md:hidden">
{data.entries.map((entry) => {
const isSelected = selectedIds.has(entry.id);
return (