通过表格原生渲染统一生成手机布局标签,删除全页监听与后补扫描。动态等级列使用单一标题并保留颜色。 补齐首次插入、深链刷新、动态表头与首页延迟响应几何回归。全量214项通过,最终专项16项通过;不声明全站所有场景零位移。
This commit is contained in:
1 parent
30cbfd3a9c
commit
1c0c0f16bc
6 files changed
+241
-58
No files matched your search
@@ -0,0 +1,86 @@
|
||||
/** 回归缺口:异步列表替换骨架时,已显示的相邻卡片不应因同样五行内容而上下跳动。 */
|
||||
import assert from "node:assert/strict";
|
||||
import { test } from "node:test";
|
||||
import { backendOrigin, login, scenario } from "./helpers/console-browser.mjs";
|
||||
|
||||
for (const width of [1440, 390]) {
|
||||
test(
|
||||
`home list reserves its rendered row geometry at ${width}px`,
|
||||
{ timeout: 30000 },
|
||||
(t) =>
|
||||
scenario(t, {}, async (page) => {
|
||||
await page.setViewportSize({ width, height: 900 });
|
||||
await page.emulateMedia({ reducedMotion: "reduce" });
|
||||
let release;
|
||||
const held = new Promise((resolve) => {
|
||||
release = resolve;
|
||||
});
|
||||
await page.route(`${backendOrigin}/console/v1/**`, async (route) => {
|
||||
const path = new URL(route.request().url()).pathname;
|
||||
if (![/\/ticket$/, /\/announcement$/].some((end) => end.test(path)))
|
||||
return route.fallback();
|
||||
await held;
|
||||
return route.fulfill({
|
||||
json: {
|
||||
status: 200,
|
||||
msg: "",
|
||||
data: {
|
||||
count: 5,
|
||||
list: Array.from({ length: 5 }, (_, index) => ({
|
||||
id: index + 1,
|
||||
title: `本地布局验收 ${index + 1}`,
|
||||
create_time: 1730000000,
|
||||
post_time: 1730000000,
|
||||
status: "待回复",
|
||||
color: "#0284c7",
|
||||
})),
|
||||
},
|
||||
},
|
||||
});
|
||||
});
|
||||
const geometry = () =>
|
||||
page.locator(".home-tickets, .home-notices").evaluateAll((cards) =>
|
||||
cards.map((card) => {
|
||||
const box = card.getBoundingClientRect();
|
||||
return {
|
||||
card: card.classList.contains("home-tickets")
|
||||
? "tickets"
|
||||
: "notices",
|
||||
top: box.top + scrollY,
|
||||
height: box.height,
|
||||
};
|
||||
}),
|
||||
);
|
||||
let before;
|
||||
try {
|
||||
await login(page, "/");
|
||||
await page
|
||||
.locator(".home-tickets .home-row-skeleton")
|
||||
.first()
|
||||
.waitFor();
|
||||
await page.evaluate(() => document.fonts.ready);
|
||||
// 只比较本次控制的两个响应,避免混入其他独立面板的正常数据替换。
|
||||
await page.waitForFunction(
|
||||
() =>
|
||||
!document.querySelector(
|
||||
".home-servers .home-row-skeleton, .home-expiring .home-row-skeleton, .home-referral .p-skeleton",
|
||||
),
|
||||
);
|
||||
before = await geometry();
|
||||
} finally {
|
||||
release();
|
||||
}
|
||||
await page.locator(".home-notices .notice-row").last().waitFor();
|
||||
await page.locator(".home-tickets .home-row").last().waitFor();
|
||||
const after = await geometry();
|
||||
for (let index = 0; index < before.length; index++) {
|
||||
for (const dimension of ["height", "top"])
|
||||
assert.ok(
|
||||
Math.abs(before[index][dimension] - after[index][dimension]) <= 1,
|
||||
`${before[index].card} ${dimension} changed: ${before[index][dimension]} -> ${after[index][dimension]}`,
|
||||
);
|
||||
}
|
||||
return { width, sameRowGeometryAfterData: true };
|
||||
}),
|
||||
);
|
||||
}
|
||||
Reference in new issue
Block a user