import fs from "node:fs"; import path from "node:path"; import { expect, test, type Page } from "@playwright/test"; import { CHANNEL_SLUG, VIDEO_TRANSCRIPT_ONLY } from "../e2e/fixtures/data"; import { expectModalOpen, installRoutes } from "../e2e/helpers"; // The hub has no site.json: its switch is homepage.json `transcriptDownloads` // (SITES_DIR/_homepage/homepage.json), read by hubSite() into currentSite(), so // HubHome's transcript modal follows it. The fixture tree has no homepage.json // at all (every field its default); the off case writes one for one test and // removes it. playwright.hub.config.ts removes a leftover from a killed run. const HOMEPAGE_FILE = path.resolve( process.cwd(), "e2e", "fixtures", "sites", "_homepage", "homepage.json", ); test.describe.configure({ mode: "serial" }); test.afterEach(() => { fs.rmSync(path.dirname(HOMEPAGE_FILE), { recursive: true, force: true }); }); function exportControls(page: Page) { return [ page.getByRole("button", { name: "Download this transcript as a file" }), page.getByRole("button", { name: "Copy this transcript as Markdown (for AI)", }), ]; } // The yt-dlp clip command copies a line and serves no file, so it is not a // download: it shows whatever the switch says (unmarked state). function ytDlpButton(page: Page) { return page.getByRole("button", { name: "Mark both clip start and end first" }); } // A bare channel/video id is same-origin content, which the hub reads from its // own origin — installRoutes serves it. async function openModal(page: Page) { await installRoutes(page); await page.route("**/hub-sites.json", (r) => r.fulfill({ status: 200, contentType: "application/json", body: "[]" }), ); await page.goto(`/?v=${CHANNEL_SLUG}/${VIDEO_TRANSCRIPT_ONLY}`); await expectModalOpen(page); await expect(page.locator("li", { hasText: "beta line" })).toBeVisible(); } test("hub, no homepage.json key: the export controls and yt-dlp are present", async ({ page, }) => { await openModal(page); for (const control of exportControls(page)) { await expect(control).toBeVisible(); } await expect(ytDlpButton(page)).toBeVisible(); }); test("hub, homepage.json transcriptDownloads: false hides both; yt-dlp and Share stay", async ({ page, }) => { fs.mkdirSync(path.dirname(HOMEPAGE_FILE), { recursive: true }); fs.writeFileSync(HOMEPAGE_FILE, JSON.stringify({ transcriptDownloads: false })); await openModal(page); for (const control of exportControls(page)) { await expect(control).toHaveCount(0); } await expect(ytDlpButton(page)).toBeVisible(); await expect( page.getByRole("button", { name: "Copy share link at current time" }), ).toBeVisible(); });