120 lines
5.4 KiB
TypeScript
120 lines
5.4 KiB
TypeScript
import { mkdirSync } from "node:fs";
|
|
import { resolve } from "node:path";
|
|
|
|
import { expect, test } from "@playwright/test";
|
|
import { createServer, type ViteDevServer } from "vite";
|
|
|
|
let vite: ViteDevServer;
|
|
let webUrl: string;
|
|
|
|
test.use({ trace: "off" });
|
|
|
|
test.beforeAll(async () => {
|
|
vite = await createServer({
|
|
configFile: resolve("apps/web/vite.config.ts"),
|
|
root: resolve("apps/web"),
|
|
server: { host: "127.0.0.1", port: 0 },
|
|
});
|
|
await vite.listen();
|
|
const address = vite.httpServer?.address();
|
|
if (!address || typeof address === "string") throw new Error("Vite did not expose a test port.");
|
|
webUrl = `http://127.0.0.1:${address.port}`;
|
|
});
|
|
|
|
test.afterAll(async () => vite.close());
|
|
|
|
test("TDD-WP1-NOTICE-001 expands DVPM8 only after successful code delivery", async ({ page }) => {
|
|
await page.route("**/api/v1/auth/register/send", (route) => route.fulfill({
|
|
contentType: "application/json",
|
|
status: 200,
|
|
body: JSON.stringify({
|
|
challenge_expires_at: "2026-07-28T09:10:00.000Z",
|
|
registration_id: "00000000-0000-4000-8000-000000000003",
|
|
resend_available_at: "2026-07-28T09:01:00.000Z",
|
|
status: "verification_sent",
|
|
}),
|
|
}));
|
|
await page.goto(webUrl);
|
|
await page.getByRole("tab", { name: "注册" }).click();
|
|
await page.getByRole("textbox", { name: "邀请码" }).fill("DADA-P0A-TEST-7K2");
|
|
await page.getByRole("textbox", { name: "邮箱" }).fill("registration@example.invalid");
|
|
await page.getByRole("button", { name: "获取验证码" }).click();
|
|
|
|
await expect(page.getByRole("heading", { name: "完善注册资料" })).toBeVisible();
|
|
await expect(page.getByText("邀请码 · 已验证")).toBeVisible();
|
|
await expect(page.getByText("邮箱 · 已验证")).toBeVisible();
|
|
await expect(page.getByRole("button", { name: "修改邀请码和邮箱" })).toBeVisible();
|
|
await expect(page.getByLabel("验证码")).toBeVisible();
|
|
await expect(page.getByLabel("创作署名")).toBeVisible();
|
|
await expect(page.getByLabel("社交 ID")).toBeVisible();
|
|
await expect(page.getByRole("checkbox", { name: /同意/ })).not.toBeChecked();
|
|
await expect(page.getByRole("button", { name: "注册并进入 Dada" })).toBeDisabled();
|
|
|
|
await page.getByRole("button", { name: "查看全文" }).click();
|
|
const dialog = page.getByRole("dialog", { name: "内测使用与隐私告知" });
|
|
const noticeClose = page.getByRole("button", { name: "我已阅读" });
|
|
await expect(noticeClose).toBeFocused();
|
|
await expect(dialog).toContainText("AI 网关");
|
|
await expect(dialog).toContainText("Resend");
|
|
await expect(dialog).toContainText("高德");
|
|
await expect(dialog).toContainText("DYN004");
|
|
await expect(dialog).toContainText("180 天");
|
|
await expect(dialog).toContainText("不会迁移到正式系统");
|
|
|
|
const evidenceDirectory = process.env.DADA_EVIDENCE_DIR_NOTICE;
|
|
if (evidenceDirectory) {
|
|
mkdirSync(resolve(evidenceDirectory, "screenshots"), { recursive: true });
|
|
await page.screenshot({ path: resolve(evidenceDirectory, "screenshots", "notice-expanded.png") });
|
|
}
|
|
await page.keyboard.press("Tab");
|
|
await expect(noticeClose).toBeFocused();
|
|
await page.keyboard.press("Escape");
|
|
await expect(dialog).toHaveCount(0);
|
|
await expect(page.getByRole("button", { name: "查看全文" })).toBeFocused();
|
|
await expect(page.getByRole("checkbox", { name: /同意/ })).not.toBeChecked();
|
|
});
|
|
|
|
test("TDD-WP1-SLOT-001 preserves profile fields when final capacity recheck fails", async ({ page }) => {
|
|
await page.route("**/api/v1/auth/register/send", (route) => route.fulfill({
|
|
contentType: "application/json",
|
|
status: 200,
|
|
body: JSON.stringify({
|
|
challenge_expires_at: "2026-07-28T09:10:00.000Z",
|
|
registration_id: "00000000-0000-4000-8000-000000000004",
|
|
resend_available_at: "2026-07-28T09:01:00.000Z",
|
|
status: "verification_sent",
|
|
}),
|
|
}));
|
|
await page.route("**/api/v1/auth/register/complete", async (route) => {
|
|
await new Promise((resolveDelay) => setTimeout(resolveDelay, 150));
|
|
await route.fulfill({
|
|
contentType: "application/json",
|
|
status: 409,
|
|
body: JSON.stringify({
|
|
error: {
|
|
code: "REGISTRATION_REJECTED",
|
|
correlation_id: "00000000-0000-4000-8000-000000000005",
|
|
details: { field_errors: [{ field: "invite_code", message_key: "auth.registration.stage_limit_reached" }] },
|
|
message_key: "registration.rejected",
|
|
},
|
|
}),
|
|
});
|
|
});
|
|
|
|
await page.goto(webUrl);
|
|
await page.getByRole("tab", { name: "注册" }).click();
|
|
await page.getByRole("textbox", { name: "邀请码" }).fill("DADA-P0A-TEST-9M4");
|
|
await page.getByRole("textbox", { name: "邮箱" }).fill("capacity@example.invalid");
|
|
await page.getByRole("button", { name: "获取验证码" }).click();
|
|
await page.getByLabel("验证码").fill("418205");
|
|
await page.getByLabel("创作署名").fill("Capacity User");
|
|
await page.getByLabel("社交 ID").fill("@capacity_user");
|
|
await page.getByRole("checkbox", { name: /同意/ }).check();
|
|
await page.getByRole("button", { name: "注册并进入 Dada" }).click();
|
|
await expect(page.getByRole("button", { name: "注册中" })).toBeDisabled();
|
|
await expect(page.getByRole("alert")).toContainText("本轮内测名额已满");
|
|
await expect(page.getByLabel("创作署名")).toHaveValue("Capacity User");
|
|
await expect(page.getByLabel("社交 ID")).toHaveValue("@capacity_user");
|
|
await expect(page.getByRole("checkbox", { name: /同意/ })).toBeChecked();
|
|
});
|