155 lines
6.6 KiB
TypeScript
155 lines
6.6 KiB
TypeScript
import { test, expect } from "@playwright/test";
|
||
import {
|
||
parseRoute,
|
||
projectPath,
|
||
promotionPath,
|
||
safeReturnTo,
|
||
stepSlugs,
|
||
} from "../src/navigation";
|
||
|
||
test("URL hierarchy and wizard steps resolve independently", () => {
|
||
for (const [step] of stepSlugs.entries()) {
|
||
expect(
|
||
parseRoute(projectPath("main-id", "child-id", "project-id", step)),
|
||
).toEqual({
|
||
kind: "project",
|
||
accountId: "main-id",
|
||
promotionId: "child-id",
|
||
projectId: "project-id",
|
||
step,
|
||
});
|
||
expect(
|
||
parseRoute(projectPath("main-id", "child-id", undefined, step)),
|
||
).toEqual({
|
||
kind: "project",
|
||
accountId: "main-id",
|
||
promotionId: "child-id",
|
||
step,
|
||
});
|
||
}
|
||
expect(parseRoute(promotionPath("main-id", "child-id"))).toEqual({
|
||
kind: "promotion",
|
||
accountId: "main-id",
|
||
promotionId: "child-id",
|
||
});
|
||
expect(
|
||
parseRoute(
|
||
"/account-manage/main-id/promotion-manage/child-id/create-project/unknown",
|
||
).kind,
|
||
).toBe("not-found");
|
||
expect(safeReturnTo("?returnTo=https://external.example")).toBe("/workbench");
|
||
expect(safeReturnTo("?returnTo=//external.example")).toBe("/workbench");
|
||
});
|
||
|
||
test("deployed console supports registration, scoped URLs, editing, refresh and login return", async ({
|
||
page,
|
||
context,
|
||
}) => {
|
||
const email = `ci-${Date.now()}-${Math.random().toString(16).slice(2)}@example.com`;
|
||
const password = `CI-${crypto.randomUUID()}`;
|
||
await page.goto("/register");
|
||
await page.getByLabel("联系人姓名", { exact: true }).fill("CI 自动验证");
|
||
await page
|
||
.getByLabel("企业 / 主账户名称", { exact: true })
|
||
.fill("CI 广告主验收");
|
||
await page.getByLabel("邮箱", { exact: true }).fill(email);
|
||
await page.getByLabel("密码", { exact: true }).fill(password);
|
||
await page
|
||
.getByRole("button", { name: "注册并进入工作台", exact: true })
|
||
.click();
|
||
await expect(page).toHaveURL(/\/workbench$/);
|
||
await page.getByRole("button", { name: "账户管理", exact: true }).click();
|
||
await expect(page).toHaveURL(/\/account-manage$/);
|
||
await page.getByRole("link", { name: "CI 广告主验收", exact: true }).click();
|
||
await expect(page).toHaveURL(/\/account-manage\/[^/]+$/);
|
||
const parentUrl = new URL(page.url()).pathname;
|
||
await page
|
||
.getByRole("button", { name: "+ 新建子账户", exact: true })
|
||
.click();
|
||
await expect(page).toHaveURL(/\/promotion-manage\/new$/);
|
||
await page.getByLabel("账户名称", { exact: true }).fill("CI 第二投放账户");
|
||
await page.getByRole("button", { name: "保存账户", exact: true }).click();
|
||
await expect(page).toHaveURL(new RegExp(`${parentUrl}$`));
|
||
await page
|
||
.getByRole("link", { name: "CI 第二投放账户", exact: true })
|
||
.click();
|
||
await expect(page).toHaveURL(/\/promotion-manage\/[^/]+$/);
|
||
const promotionUrl = new URL(page.url()).pathname;
|
||
await page.getByRole("button", { name: "+ 新建项目", exact: true }).click();
|
||
await expect(page).toHaveURL(/\/create-project\/goal$/);
|
||
await page.getByRole("button", { name: "下一步 →", exact: true }).click();
|
||
await expect(page).toHaveURL(/\/create-project\/product$/);
|
||
await page.getByLabel("推广产品或服务", { exact: true }).fill("秋季新品");
|
||
await page.getByRole("button", { name: "下一步 →", exact: true }).click();
|
||
await page.getByLabel("投放地域", { exact: true }).fill("上海");
|
||
await page.getByRole("button", { name: "下一步 →", exact: true }).click();
|
||
await page.getByLabel("日预算(元,最低 100)", { exact: true }).fill("500");
|
||
await page.getByRole("button", { name: "下一步 →", exact: true }).click();
|
||
await page
|
||
.getByLabel("落地页地址(可选)", { exact: true })
|
||
.fill("https://example.com/product");
|
||
await page.getByRole("button", { name: "下一步 →", exact: true }).click();
|
||
await page.getByLabel("项目名称", { exact: true }).fill("CI 六步创建项目");
|
||
await page.getByRole("button", { name: "保存项目", exact: true }).click();
|
||
await expect(page).toHaveURL(new RegExp(`${promotionUrl}$`));
|
||
await page
|
||
.getByRole("link", { name: "CI 六步创建项目", exact: true })
|
||
.click();
|
||
await expect(page).toHaveURL(/\/projects\/[^/]+\/edit\/goal$/);
|
||
const editRoot = new URL(page.url()).pathname.replace(/goal$/, "");
|
||
await page.goto(editRoot + "name");
|
||
await expect(page.getByLabel("项目名称", { exact: true })).toHaveValue(
|
||
"CI 六步创建项目",
|
||
);
|
||
await page.getByLabel("项目名称", { exact: true }).fill("CI 已修改项目");
|
||
await page.getByRole("button", { name: "保存项目", exact: true }).click();
|
||
await expect(
|
||
page.getByRole("link", { name: "CI 已修改项目", exact: true }),
|
||
).toBeVisible();
|
||
await page.goto(editRoot + "budget");
|
||
await page.reload();
|
||
await expect(
|
||
page.getByLabel("日预算(元,最低 100)", { exact: true }),
|
||
).toHaveValue("500");
|
||
await page.getByRole("button", { name: "下一步 →", exact: true }).click();
|
||
await expect(page).toHaveURL(/\/edit\/tracking$/);
|
||
await page.goBack();
|
||
await expect(page).toHaveURL(/\/edit\/budget$/);
|
||
await page.goForward();
|
||
await expect(page).toHaveURL(/\/edit\/tracking$/);
|
||
await page.getByRole("button", { name: "退出", exact: true }).click();
|
||
await page.goto(editRoot + "name");
|
||
await expect(page).toHaveURL(/\/login\?returnTo=/);
|
||
await page.getByLabel("邮箱", { exact: true }).fill(email);
|
||
await page.getByLabel("密码", { exact: true }).fill(password);
|
||
await page.getByRole("button", { name: "登录", exact: true }).click();
|
||
await expect(page).toHaveURL(new RegExp(`${editRoot}name$`));
|
||
await expect(page.getByLabel("项目名称", { exact: true })).toHaveValue(
|
||
"CI 已修改项目",
|
||
);
|
||
await page.goto(promotionUrl.replace(/[^/]+$/, "invalid-id"));
|
||
await expect(
|
||
page.getByRole("heading", { name: "页面或账户不存在" }),
|
||
).toBeVisible();
|
||
await page.goto(promotionUrl);
|
||
await page
|
||
.getByRole("combobox", { name: "当前投放子账户" })
|
||
.selectOption({ label: "CI 广告主验收 · 默认投放账户" });
|
||
await expect(page).not.toHaveURL(new RegExp(`${promotionUrl}$`));
|
||
await expect(
|
||
page.getByRole("heading", { name: "还没有推广项目" }),
|
||
).toBeVisible();
|
||
// A second tab can open the exact project and restore its account context.
|
||
const other = await context.newPage();
|
||
await other.goto(editRoot + "name");
|
||
await expect(other.getByLabel("项目名称", { exact: true })).toHaveValue(
|
||
"CI 已修改项目",
|
||
);
|
||
await other.close();
|
||
await page.setViewportSize({ width: 390, height: 844 });
|
||
await page.goto("/workbench");
|
||
await expect(
|
||
page.getByRole("heading", { name: "你好,CI 自动验证" }),
|
||
).toBeVisible();
|
||
});
|