Files
iam-login/frontend/tests/preview.spec.ts
T

96 lines
4.3 KiB
TypeScript

import { test, expect } from "@playwright/test";
test("原生 POST 逐页导航,内联上下文,浏览器缓存静态资源", async ({ page }) => {
const xhr: string[] = [];
const posts: string[] = [];
const errors: string[] = [];
page.on("pageerror", (e) => errors.push(e.message));
page.on("request", (req) => {
if (["fetch", "xhr"].includes(req.resourceType())) xhr.push(req.url());
if (req.method() === "POST" && req.isNavigationRequest())
posts.push(req.url());
});
await page.goto("/preview");
await expect(page.getByRole("heading", { name: "从这里开始" })).toBeVisible();
const scriptUrl = await page.locator("script[src]").getAttribute("src");
await page.getByRole("button", { name: "这是真实登录吗?" }).click();
await expect(page.getByText("不是。这里仅演示页面交互")).toBeVisible();
await page.getByLabel("称呼").fill("预览用户");
await page.getByRole("button", { name: "继续", exact: true }).click();
await expect(page).toHaveURL(/\/preview\/verify$/);
await expect(
page.getByRole("heading", { name: "你好,预览用户" }),
).toBeVisible();
await page.getByLabel("演示码").fill("000000");
await page.getByRole("button", { name: "继续", exact: true }).click();
await expect(page.getByRole("alert")).toContainText("演示码不正确");
await page.getByLabel("演示码").fill("123456");
await page.getByRole("button", { name: "继续", exact: true }).click();
await expect(page.getByRole("heading", { name: "体验完成" })).toBeVisible();
expect(posts).toHaveLength(3);
expect(xhr).toEqual([]);
expect(errors).toEqual([]);
const timing = await page.evaluate(() => ({
navigation: performance
.getEntriesByType("navigation")
.map((e) => e.toJSON()),
resources: performance.getEntriesByType("resource").map((e) => e.toJSON()),
}));
const script = timing.resources.find((r) => r.name.endsWith(scriptUrl!));
expect(script?.transferSize).toBe(0);
await test
.info()
.attach("navigation-and-cache.json", {
body: JSON.stringify(timing, null, 2),
contentType: "application/json",
});
expect(
(
await page.request.get("/", { headers: { Accept: "application/json" } })
).status(),
).toBe(401);
await page.getByRole("button", { name: "重新体验" }).click();
await expect(page.getByRole("heading", { name: "从这里开始" })).toBeVisible();
});
test("移动端与脚本结束标记作为纯文本显示", async ({ page }) => {
await page.setViewportSize({ width: 390, height: 844 });
await page.goto("/preview");
const name = "</script><script>window.__injected=1</script>";
await page.getByLabel("称呼").fill(name);
await page.getByRole("button", { name: "继续", exact: true }).click();
await expect(page.getByRole("heading")).toHaveText(`你好,${name}`);
expect(
await page.evaluate(() => Reflect.get(window, "__injected")),
).toBeUndefined();
expect(
await page.evaluate(
() => document.documentElement.scrollWidth <= innerWidth,
),
).toBe(true);
await page.screenshot({ path: "test-results/mobile.png", fullPage: true });
});
test("受限网络下首屏和缓存后页面切换计时", async ({ page, context }) => {
const cdp = await context.newCDPSession(page);
await cdp.send("Network.enable");
await cdp.send("Network.emulateNetworkConditions", {
offline: false, latency: 60, downloadThroughput: 1_500_000 / 8,
uploadThroughput: 750_000 / 8,
});
await cdp.send("Emulation.setCPUThrottlingRate", { rate: 4 });
await page.goto("/preview");
await expect(page.getByRole("heading", { name: "从这里开始" })).toBeVisible();
const cold = await page.evaluate(() => performance.getEntriesByName("iam-page-ready")[0].startTime);
await page.getByLabel("称呼").fill("计时体验");
const start = performance.now();
await page.getByRole("button", { name: "继续", exact: true }).click();
await expect(page.getByRole("heading", { name: "你好,计时体验" })).toBeVisible();
const warm = performance.now() - start;
const result = { network_latency_ms: 60, download_mbps: 1.5, cpu_slowdown: 4,
cold_navigation_to_react_commit_ms: Math.round(cold), warm_click_to_visible_ms: Math.round(warm) };
console.log(JSON.stringify(result));
await test.info().attach("timing.json", { body: JSON.stringify(result, null, 2), contentType: "application/json" });
});