Build advertiser console with scoped page URLs and runner-based deployment tests
Advertiser console CI and test deployment / build-deploy (push) Has been cancelled
Advertiser console CI and test deployment / build-deploy (push) Has been cancelled
This commit is contained in:
@@ -0,0 +1,154 @@
|
||||
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();
|
||||
});
|
||||
Reference in New Issue
Block a user