// The scraping method is an operational choice, not a create-time one: the X // paths reach very different amounts of history, so it must be switchable from // the channel page. import { test, expect } from "@playwright/test"; import { mkdir, writeFile } from "node:fs/promises"; import { resetData, readJson, resolvePath } from "./helpers"; type Cfg = { postFetcher?: string; platform?: string }; async function makeSocialChannel(slug: string, platform: string, fetcher: string) { const dir = resolvePath(`test-transcripts/channels/${slug}`); await mkdir(dir, { recursive: true }); await writeFile( `${dir}/config.json`, JSON.stringify({ handling: "transcribe", sourceKind: "social", platform, postFetcher: fetcher, socialHandle: "someone", name: `@someone on ${platform}`, url: platform === "twitter" ? "https://x.com/someone" : "https://bsky.app/profile/someone", }, null, 2), ); } test("an X channel offers every X scraping method and switching persists", async ({ page }) => { await resetData("empty"); await makeSocialChannel("x-chan", "twitter", "x-gallery-dl"); await page.goto("/channels/x-chan"); const picker = page.getByLabel("post fetcher"); await expect(picker).toBeVisible(); await expect(picker).toHaveValue("x-gallery-dl"); // All three X paths are offered — and no Bluesky one. const ids = await picker.locator("option").evaluateAll((os) => os.map((o) => (o as HTMLOptionElement).value), ); expect(ids.sort()).toEqual(["x-gallery-dl", "x-nitter", "x-playwright"]); await picker.selectOption("x-nitter"); await expect(page.getByText("Fetcher updated")).toBeVisible(); // The choice is persisted to the channel config, not just local state. await expect .poll(async () => (await readJson("test-transcripts/channels/x-chan/config.json")).postFetcher, { timeout: 10_000 }) .toBe("x-nitter"); await page.reload(); await expect(page.getByLabel("post fetcher")).toHaveValue("x-nitter"); }); test("a Bluesky channel shows no picker — it has only one method", async ({ page }) => { await resetData("empty"); await makeSocialChannel("bsky-chan", "bluesky", "bluesky-atproto"); await page.goto("/channels/bsky-chan"); await expect(page.locator("[data-social-panel]")).toBeVisible(); await expect(page.getByLabel("post fetcher")).toHaveCount(0); });