import { test, expect } from "@playwright/test"; import { channelStage, generateReport, pathExists, readJson, resetData, } from "./helpers"; test("shows empty state with no channels", async ({ page }) => { await resetData("empty"); await page.goto("/channels"); await expect(page.getByText("No channels yet.")).toBeVisible(); }); test("creates a youtube channel", async ({ page }) => { await resetData("empty"); await generateReport(page, "new"); await page.goto("/channels/new"); await page.getByLabel(/^name/i).fill("New Test Channel"); await page.getByLabel(/^slug/i).fill("new-test"); await page .getByLabel(/^url/i) .fill("https://www.youtube.com/@newtest/videos"); await page.getByRole("button", { name: /create channel/i }).click(); await page.waitForURL("**/channels/new-test", { timeout: 10_000 }); expect( await readJson("test-transcripts/channels/new-test/config.json"), ).toEqual({ handling: "youtube", name: "New Test Channel", url: "https://www.youtube.com/@newtest/videos", platform: "youtube", }); }); test("auto-detects twitch platform from URL", async ({ page }) => { await resetData("empty"); await generateReport(page, "new"); await page.goto("/channels/new"); await page.getByLabel(/^name/i).fill("Twitch Test Channel"); await page.getByLabel(/^slug/i).fill("twitch-test"); await page.getByLabel(/^url/i).fill("https://www.twitch.tv/sometwitchuser"); await page.getByRole("button", { name: /create channel/i }).click(); await page.waitForURL("**/channels/twitch-test", { timeout: 10_000 }); const config = await readJson<{ platform?: string; url?: string }>( "test-transcripts/channels/twitch-test/config.json", ); expect(config.platform).toBe("twitch"); }); test("auto-derives slug from name when blank", async ({ page }) => { await resetData("empty"); await generateReport(page, "new"); await page.goto("/channels/new"); await page.getByLabel(/^name/i).fill("Auto Slug Channel"); await page.getByRole("button", { name: /create channel/i }).click(); await page.waitForURL("**/channels/auto-slug-channel", { timeout: 10_000 }); }); test("rejects duplicate slug", async ({ page }) => { await resetData("one-youtube-channel"); await generateReport(page, "new"); await page.goto("/channels/new"); await page.getByLabel(/^name/i).fill("Test YouTube Channel"); await page.getByLabel(/^slug/i).fill("test-youtube"); await page.getByRole("button", { name: /create channel/i }).click(); await expect(page.getByText(/already exists/i)).toBeVisible(); }); test("edits an existing channel", async ({ page }) => { await resetData("one-youtube-channel"); await generateReport(page, "test-youtube"); await page.goto(channelStage("test-youtube", "configure")); await page.getByLabel(/^name/i).fill("Renamed Channel"); await page.getByRole("button", { name: /save changes/i }).click(); await expect(page.getByText("Renamed Channel").first()).toBeVisible(); const config = await readJson<{ name?: string }>( "test-transcripts/channels/test-youtube/config.json", ); expect(config.name).toBe("Renamed Channel"); }); test("requires typed-confirmation to delete", async ({ page }) => { await resetData("one-youtube-channel"); await generateReport(page, "test-youtube"); await page.goto(channelStage("test-youtube", "danger")); // getByPlaceholder would be ambiguous: the rename form's confirm input // shares the slug placeholder. await page.getByLabel("confirm slug to delete").fill("wrong-slug"); await page.getByRole("button", { name: /delete channel/i }).click(); await expect(page.getByText(/type the channel slug/i)).toBeVisible(); expect(await pathExists("test-transcripts/channels/test-youtube")).toBe(true); await page.getByLabel("confirm slug to delete").fill("test-youtube"); await page.getByRole("button", { name: /delete channel/i }).click(); await page.waitForURL("**/channels", { timeout: 10_000 }); expect(await pathExists("test-transcripts/channels/test-youtube")).toBe(false); }); test("hides transcribe form fields for youtube channels (cosmetic)", async ({ page, }) => { await resetData("one-transcribe-channel"); await generateReport(page, "test-transcribe"); await page.goto(channelStage("test-transcribe", "configure")); await expect( page.getByLabel(/audio format \(transcribe only\)/i), ).toHaveValue("m4a"); });