Add triage tests, prepare-export, and UI fixes for Levkin migration.
Cherry-pick heuristics, manifest merge, global file search, scrollbar styling, and pytest/Playwright coverage unblock review and filtered export for mmetl.
This commit is contained in:
@@ -0,0 +1,139 @@
|
||||
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 });
|
||||
});
|
||||
});
|
||||
Reference in New Issue
Block a user