import { test, expect } from "@playwright/test"; const USERNAME = process.env.LOCAL_USERNAME ?? "admin"; const PASSWORD = process.env.LOCAL_PASSWORD ?? ""; test("known/unknown ratio matches the actual badge counts", async ({ page }) => { test.skip(!PASSWORD, "LOCAL_PASSWORD not set"); await page.goto("/"); await page.getByPlaceholder("Username").fill(USERNAME); await page.getByPlaceholder("Password").fill(PASSWORD); await page.getByRole("button", { name: "Sign in" }).click(); await expect(page.locator(".device-table tbody tr").first()).toBeVisible({ timeout: 15_000 }); // Re-reads badge counts and the displayed text together, retrying the // whole comparison if they're ever caught mid-render (e.g. a background // poll landing between the two reads) instead of a one-shot comparison — // .count() and .textContent() don't auto-wait/retry the way expect() // matchers do, so a bare single read raced a poll and failed once already. await expect(async () => { const knownCount = await page.locator(".device-badge.known").count(); const unknownCount = await page.locator(".device-badge.unknown").count(); const ratioText = await page.locator(".device-ratio").textContent(); const countText = await page.locator(".device-count").textContent(); expect(ratioText).toBe(`${knownCount} known / ${unknownCount} unknown`); expect(countText).toBe(`(${knownCount + unknownCount})`); }).toPass({ timeout: 10_000 }); });