import { test, expect } from "@playwright/test"; const BASE = process.env.SLACK_REVIEW_URL || "http://127.0.0.1:18765"; async function waitForAppReady(page: import("@playwright/test").Page) { await page.goto(BASE); await expect(page.locator("#channel-title")).not.toHaveText("Select a channel", { timeout: 15_000, }); } async function showAllChannels(page: import("@playwright/test").Page) { await page.locator("#filter-status").selectOption("all"); await expect(page.locator("#sidebar-list .list-item").first()).toBeVisible(); } async function openChannel(page: import("@playwright/test").Page, name: string) { await showAllChannels(page); const btn = page.locator("#sidebar-list button").filter({ hasText: name }); await btn.first().click(); } test.describe("Review UI", () => { test.beforeAll(async ({ request }) => { const res = await request.get(`${BASE}/api/health`); expect(res.ok()).toBeTruthy(); }); test("loads channel list and stats", async ({ page }) => { await waitForAppReady(page); await expect(page.locator("h1")).toHaveText("Slack import review"); await expect(page.locator("#stats")).not.toBeEmpty(); await expect(page.locator("#sidebar-list .list-item").first()).toBeVisible({ timeout: 10_000, }); }); test("opens medical channel and shows messages", async ({ page }) => { await waitForAppReady(page); await openChannel(page, "medical"); await expect(page.locator("#channel-title")).toHaveText("#medical"); await expect(page.locator(".message").first()).toBeVisible({ timeout: 10_000 }); }); test("cherry-pick checkbox toggles on and off", async ({ page }) => { await waitForAppReady(page); await openChannel(page, "medical"); await page.waitForSelector(".message", { timeout: 10_000 }); const row = page.locator(".message").first(); const checkbox = row.locator("input[data-msg-check]"); await checkbox.check(); await expect(row).toHaveClass(/sel-import/); await checkbox.uncheck(); await expect(row).not.toHaveClass(/sel-import/); }); test("detail panel skip clears selection", async ({ page }) => { await waitForAppReady(page); await openChannel(page, "medical"); await page.waitForSelector(".message", { timeout: 10_000 }); const row = page.locator(".message").first(); await row.click(); await expect(page.locator("#message-detail")).toBeVisible(); await page.locator("#msg-action").selectOption("import"); await expect(row).toHaveClass(/sel-import/); await page.locator("#msg-action").selectOption("skip"); await expect(row).not.toHaveClass(/sel-import/); }); test("filter only selected hides unchecked", async ({ page }) => { await waitForAppReady(page); await openChannel(page, "zoey"); await page.waitForSelector(".message", { timeout: 10_000 }); const before = await page.locator(".message").count(); const checkbox = page.locator(".message").first().locator("input[data-msg-check]"); await checkbox.check(); await page.locator("#filter-only-selected").check(); const after = await page.locator(".message").count(); expect(after).toBeLessThanOrEqual(before); expect(after).toBeGreaterThanOrEqual(1); }); test("global file search mode returns hits", async ({ page }) => { await waitForAppReady(page); await page.locator("#global-search-mode").selectOption("files"); await page.locator("#global-file-type").selectOption("image"); await page.waitForTimeout(400); const results = page.locator("#global-search-results .search-hit"); const count = await results.count(); expect(count).toBeGreaterThanOrEqual(0); }); test("sidebar Has picks filter", async ({ page }) => { await waitForAppReady(page); await page.locator("#filter-status").selectOption("partial"); const items = page.locator("#sidebar-list .list-item"); await expect(items.first()).toBeVisible(); const count = await items.count(); expect(count).toBeGreaterThanOrEqual(1); }); test("import mode pick checkbox enables cherry-pick", async ({ page }) => { await waitForAppReady(page); await openChannel(page, "medical"); await page.locator("#import-mode-pick").check(); await expect(page.locator("#import-mode-pick")).toBeChecked(); }); test("save button shows confirmation", async ({ page }) => { await waitForAppReady(page); await page.locator("#btn-save").click(); await expect(page.locator("#save-status")).toContainText("Saved", { timeout: 3000 }); }); test("global text search finds channel", async ({ page }) => { await waitForAppReady(page); await page.locator("#global-search-mode").selectOption("text"); await page.locator("#global-search").fill("niagara"); await page.waitForTimeout(400); await expect(page.locator("#global-search-results .search-hit").first()).toBeVisible(); }); test("select files in view toggles", async ({ page }) => { await waitForAppReady(page); await openChannel(page, "153niagara"); await page.waitForSelector(".message", { timeout: 10_000 }); await page.locator("#filter-attachment-type").selectOption("any"); const btn = page.locator("#btn-select-files"); await btn.click(); await expect(btn).toContainText("Clear", { timeout: 3000 }); await btn.click(); await expect(btn).toContainText("Select", { timeout: 3000 }); }); });