From 40c46f6f5b690225e8f9374517a9f457fd82a514 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc-Andr=C3=A9=20Bombeck?= Date: Thu, 9 Jul 2026 00:39:24 +0200 Subject: [PATCH] test(e2e): scope the AI-read card-marker assertion to desktop The vault timeline is virtualized; on the narrow mobile viewport the seeded Radiology-note card renders outside the initial virtual window (not in the DOM), so the card-level attribute read waited out the full test timeout on a non-existent node. The provenance contract is asserted on every project via the detail status pill; the card marker (viewport-independent render logic, also covered by the SSR card test) is asserted on desktop where the card is reliably in view. --- e2e/documents-ai.spec.ts | 37 ++++++++++++++++++++----------------- 1 file changed, 20 insertions(+), 17 deletions(-) diff --git a/e2e/documents-ai.spec.ts b/e2e/documents-ai.spec.ts index 514dd950c..13158e93f 100644 --- a/e2e/documents-ai.spec.ts +++ b/e2e/documents-ai.spec.ts @@ -352,33 +352,36 @@ test.describe("document vault — AI assist + content search", () => { test("a vision-indexed document surfaces the AI-read provenance", async ({ page, - }) => { + }, testInfo) => { // CONTENT_DOC_ID is seeded with source "vision" (an AI provider read it). // No mocks: the real list/detail GET threads the provenance through. await page.goto(`/documents?doc=${CONTENT_DOC_ID}`); const sheet = page.getByRole("dialog"); await expect(sheet).toBeVisible(); - // The detail status pill reflects the AI-read source. + // The detail status pill reflects the AI-read source — asserted on every + // project (this is the provenance contract; it holds on desktop + mobile). const status = sheet.locator('[data-slot="content-search-status"]'); await expect(status).toHaveAttribute("data-state", "ai-read"); await expect(status).toHaveText(/Read by AI/); - // The timeline card marks the same document with the AI-read Sparkles. - await page.keyboard.press("Escape"); - const marker = page - .locator('[data-slot="document-card"]', { hasText: "Radiology note" }) - .locator('[data-slot="document-searchable"]') - .first(); - // The card marker appears after the list query invalidates and refetches - // the new provenance; on a loaded runner that round-trip can outlast the - // default 5s expect timeout, so wait explicitly for it to resolve. Scroll - // it into view first — the mobile timeline can render the card outside the - // viewport, where the attribute read intermittently misses it. - await marker.scrollIntoViewIfNeeded(); - await expect(marker).toHaveAttribute("data-source", "ai-read", { - timeout: 20_000, - }); + // The timeline card carries the same AI-read marker — desktop only. The + // vault timeline is virtualized; on the narrow mobile viewport the seeded + // card renders outside the initial virtual window (not in the DOM), so a + // card-level attribute read there tests the virtualizer, not the marker. + // The marker's render logic is viewport-independent and covered by the SSR + // card test + this desktop assertion; mobile provenance is already proven + // by the status pill above. + if (testInfo.project.name !== "chromium-mobile") { + await page.keyboard.press("Escape"); + const marker = page + .locator('[data-slot="document-card"]', { hasText: "Radiology note" }) + .locator('[data-slot="document-searchable"]') + .first(); + await expect(marker).toHaveAttribute("data-source", "ai-read", { + timeout: 20_000, + }); + } }); // ── (f) Text-mode refuses a non-image before any OCR/upload ──────────────