106 lines
3.8 KiB
TypeScript
106 lines
3.8 KiB
TypeScript
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();
|
|
});
|
|
});
|