import { test, expect } from "@playwright/test"; const USERNAME = process.env.LOCAL_USERNAME ?? "admin"; const PASSWORD = process.env.LOCAL_PASSWORD ?? ""; test("deep check button runs a check and shows results for an unknown device", 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 }); const unknownRow = page.locator(".device-table tbody tr").filter({ hasText: "unknown" }).first(); await expect(unknownRow).toBeVisible(); const button = unknownRow.getByRole("button", { name: /deep check|checking/i }); await expect(button).toBeVisible(); await button.click(); await expect(button).toHaveText("Checking…"); // Bounded by the script's own timeouts (well under 15s) plus SSH round trip. await expect(page.locator(".deep-check-row").first()).toBeVisible({ timeout: 20_000 }); await expect(button).toHaveText("Deep check"); // Either real findings (SSDP/mDNS/ports) or the explicit "nothing found" // message -- either way, a result panel with actual content, not empty. const resultRow = page.locator(".deep-check-row").first(); await expect(resultRow).not.toBeEmpty(); }); test("deep check surfaces a Fingerbank identification with a confidence label", 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(); // Wait for the table to actually render before checking whether the // target device is in it -- checking row.count() too early always finds // zero rows and skips the test regardless of whether the device is really // on the network. Bit me on the first run of this test. await expect(page.locator(".device-table tbody tr").first()).toBeVisible({ timeout: 15_000 }); // The Nintendo device (192.168.1.106) reliably gets a Fingerbank match, if // it's still on the network -- skip rather than fail if it's gone, since // this specific IP isn't something the test suite controls. const row = page.locator('tr[data-ip="192.168.1.106"]'); test.skip((await row.count()) === 0, "192.168.1.106 not currently on the network"); await row.getByRole("button", { name: /deep check/i }).click(); await expect(page.locator(".deep-check-row").first()).toBeVisible({ timeout: 20_000 }); const resultText = await page.locator(".deep-check-row").first().textContent(); expect(resultText).toContain("Fingerbank ID"); // Confidence label should always accompany a score -- never a bare // number, which could be mistaken for a confirmed identification. expect(resultText).toMatch(/low confidence|moderate confidence|high confidence|very high confidence/); }); test("known devices have no deep check button", 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 }); // .device-badge.known specifically -- "known" is a substring of "unknown", // so a text-based filter would match both (bit me on the labeling test too). const knownRow = page.locator(".device-table tbody tr").filter({ has: page.locator(".device-badge.known") }).first(); await expect(knownRow).toBeVisible(); await expect(knownRow.getByRole("button", { name: /deep check/i })).toHaveCount(0); });