import { expect, test, type Page } from "@playwright/test"; import { CHANNEL_SLUG, VIDEO_CHAT_LARGE, VIDEO_CHAT_SMALL, VIDEO_TRANSCRIPT_ONLY, } from "./fixtures/data"; import { installRoutes, showAll } from "./helpers"; // Browse-all e2e: with no search query active the results section lists every // video passing the committed filters (no hits) — once the visitor has pressed // Search; until then the page shows no results area at all (first-search.spec). // Typing a query narrows it; clearing it returns to the full browse list. const TRANSCRIPT_ONLY_SLUG = `${CHANNEL_SLUG}/${VIDEO_TRANSCRIPT_ONLY}`; const CHAT_SMALL_SLUG = `${CHANNEL_SLUG}/${VIDEO_CHAT_SMALL}`; const CHAT_LARGE_SLUG = `${CHANNEL_SLUG}/${VIDEO_CHAT_LARGE}`; const ALL_SLUGS = [TRANSCRIPT_ONLY_SLUG, CHAT_SMALL_SLUG, CHAT_LARGE_SLUG]; async function expectResultSlugs(page: Page, slugs: string[]) { const cards = page.locator("[data-card-header]"); await expect(async () => { const got = await cards.evaluateAll((els) => els.map((e) => e.getAttribute("data-result-slug") ?? ""), ); expect(got.slice().sort()).toEqual(slugs.slice().sort()); }).toPass({ timeout: 15_000 }); } test.describe("browse all (no query)", () => { test.beforeEach(async ({ page }) => { await installRoutes(page); }); test("a clear screen on load, then every video on an empty Search", async ({ page, }) => { await page.goto("/"); await page.getByTestId("query-builder").waitFor(); // Give the session time to hydrate (it waits for the manifest) and to // show a listing if it were going to. await page.waitForTimeout(1_000); await expect(page.getByTestId("results-section")).toHaveCount(0); await expect(page.getByTestId("results-summary")).toHaveCount(0); await expect(page.getByTestId("browse-hint")).toHaveCount(0); await expect(page.locator("[data-card-header]")).toHaveCount(0); await page.getByTestId("search-submit").click(); await expect(page.getByTestId("results-section")).toBeVisible(); await expect(page.getByTestId("results-summary")).toHaveText( "All videos (3)", ); await expect(page.getByTestId("browse-hint")).toBeVisible(); await expectResultSlugs(page, ALL_SLUGS); }); test("filters apply to the browse list on Search", async ({ page }) => { await page.goto("/"); await showAll(page); await expectResultSlugs(page, ALL_SLUGS); // All fixture videos are non-livestream, so unchecking "Videos" excludes // every one of them. await page.getByRole("checkbox", { name: "Videos" }).uncheck(); await page.getByTestId("search-submit").click(); await expect(page.getByTestId("results-summary")).toHaveText( "All videos (0)", ); await expect( page.getByText("No videos match the current filters."), ).toBeVisible(); }); test("typing a query narrows, clearing it returns to browse", async ({ page, }) => { await page.goto("/"); await showAll(page); await expectResultSlugs(page, ALL_SLUGS); const leafInput = page.locator('input[data-testid^="leaf-query-"]').first(); await leafInput.fill("alpha"); await page.getByTestId("search-submit").click(); await expect(page.getByTestId("results-summary")).toContainText( "Matching videos", ); await expectResultSlugs(page, ALL_SLUGS); await expect(page.getByTestId("browse-hint")).toHaveCount(0); // Clearing the query drops back to the full browse list. await leafInput.fill(""); await page.getByTestId("search-submit").click(); await expect(page.getByTestId("results-summary")).toHaveText( "All videos (3)", ); await expect(page.getByTestId("browse-hint")).toBeVisible(); await expectResultSlugs(page, ALL_SLUGS); }); });