import { test, expect } from "@playwright/test"; import { buildIndex, resetData } from "./helpers"; test("empty state when no jobs have run", async ({ page }) => { await resetData("empty"); // Clear any stray .jobs/*.log from other tests in this lifetime. await page.goto("/jobs"); await page.getByRole("button", { name: "Clear logs" }).click(); await page.getByRole("menuitem", { name: "All finished logs" }).click(); // The menu clears via a transition + router.refresh(); wait for it to land, // then confirm it persists on a fresh load. await expect(page.getByText("No jobs have run yet.")).toBeVisible(); await page.goto("/jobs"); await expect(page.getByText("No jobs have run yet.")).toBeVisible(); }); // Build index is the update-index publish stage (release 18): /jobs labels it // "Update the index" and reads it as one run, `run ยท _index`. test("kicks off the index update, lists it, and tails its log", async ({ page, }) => { await resetData("one-youtube-channel-with-data"); await buildIndex(page); await page.goto("/jobs"); const buildRow = page .getByRole("row") .filter({ hasText: "Update the index" }) .first(); await expect(buildRow).toBeVisible(); // Click into the most recent job. The job-id link is the first link in the row. await buildRow.getByRole("link").first().click(); // 30 s: under next dev the job page compiles on its first visit, and in a // long run the index stage's child is still winding down beside it. await expect(page.getByLabel("Job log")).toContainText("Done", { timeout: 30_000, }); const status = await page.getByLabel("Job status").textContent(); expect(["done", "running"]).toContain((status ?? "").trim()); });