import path from "node:path"; import { expect, test } from "@playwright/test"; import { encode } from "next-auth/jwt"; const SESSION_COOKIE_NAME = "authjs.session-token"; async function createSessionCookie() { const secret = process.env.AUTH_SECRET; if (!secret) { throw new Error("AUTH_SECRET 未配置,无法生成测试会话"); } return encode({ secret, salt: SESSION_COOKIE_NAME, token: { sub: "product-planning-page-user", id: "product-planning-page-user", email: "product-planning-page@example.com", name: "Product Planning Page User", type: "regular", }, }); } test.describe.serial("Product planning page", () => { const keywordFixture = path.join(process.cwd(), "tests/data/product-planning-keywords.txt"); const manualFixture = path.join(process.cwd(), "tests/data/product-planning-manual.csv"); test("anonymous user is redirected to login", async ({ page }) => { await page.goto("/product-planning", { waitUntil: "commit" }).catch((error) => { const message = error instanceof Error ? error.message : String(error); if (!/ERR_ABORTED|frame was detached/i.test(message)) { throw error; } }); await page.waitForURL(/\/login/); await expect(page).toHaveURL(/\/login/); }); test("authenticated user can open product planning page", async ({ page }) => { const token = await createSessionCookie(); await page.context().addCookies([ { name: SESSION_COOKIE_NAME, value: token, url: "http://localhost:3000", httpOnly: true, sameSite: "Lax", }, ]); await page.goto("/product-planning"); await expect(page).toHaveURL(/\/product-planning/); await expect(page.getByRole("heading", { name: "商品策划工具" })).toBeVisible(); await expect(page.getByRole("tab", { name: "关键词拆词" })).toBeVisible(); await expect(page.getByRole("tab", { name: "评价 / 问大家分析" })).toBeVisible(); await expect(page.getByRole("tab", { name: "拓展分析" })).toBeVisible(); await expect(page.getByText("云端模板库")).toBeVisible(); }); test("authenticated user can upload keyword file and get results", async ({ page }) => { const token = await createSessionCookie(); await page.context().addCookies([ { name: SESSION_COOKIE_NAME, value: token, url: "http://localhost:3000", httpOnly: true, sameSite: "Lax", }, ]); await page.goto("/product-planning"); await page.locator("input[type='file']").first().setInputFiles(keywordFixture); await page.getByRole("button", { name: "开始拆词" }).click(); await expect(page.getByText("已生成")).toBeVisible(); await expect(page.getByRole("cell", { name: "换鞋凳" }).first()).toBeVisible(); await expect(page.getByRole("cell", { name: "场景词" }).first()).toBeVisible(); await expect(page.getByRole("button", { name: "导出 xlsx" })).toBeEnabled(); }); test("authenticated user can import manual segmentation file", async ({ page }) => { const token = await createSessionCookie(); await page.context().addCookies([ { name: SESSION_COOKIE_NAME, value: token, url: "http://localhost:3000", httpOnly: true, sameSite: "Lax", }, ]); await page.goto("/product-planning"); await page.getByRole("switch").click(); await page.locator("input[type='file']").first().setInputFiles(manualFixture); await page.getByRole("button", { name: "开始拆词" }).click(); await expect(page.getByRole("cell", { name: "换鞋凳" }).first()).toBeVisible(); await expect(page.getByRole("cell", { name: "品类大词" })).toBeVisible(); await expect(page.getByRole("cell", { name: "实木" }).first()).toBeVisible(); }); });