test(游戏共创): 截图工具断言跟进终稿语义(封面主视觉/选中路径/面包屑)
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 1/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust lane 2/2 (pull_request) Has been cancelled
Project CI / AI game creator shell Rust crates (pull_request) Has been cancelled
Project CI / Backend tests (pull_request) Has been cancelled
Project CI / Native shell tests (pull_request) Has been cancelled
Project CI / Frontend tests (pull_request) Has been cancelled
Project CI / Repository checks (pull_request) Has been cancelled
Project CI / AI game creator shell web tests (pull_request) Has been cancelled
This commit is contained in:
@@ -727,14 +727,19 @@ async function main() {
|
||||
.then((text) => text.includes('当前作品'))),
|
||||
`anchorCount=${await anchor.count()}`,
|
||||
);
|
||||
const focusable = await nodeCards.evaluateAll((nodes) =>
|
||||
nodes.every(
|
||||
(node) =>
|
||||
node.getAttribute('tabindex') === '0' &&
|
||||
(node.getAttribute('aria-label') ?? '').length > 0,
|
||||
),
|
||||
const accessibleNames = await nodeCards.evaluateAll((nodes) =>
|
||||
nodes.every((node) => (node.getAttribute('aria-label') ?? '').length > 0),
|
||||
);
|
||||
check(
|
||||
'DOM 断言:每个节点卡片都有可访问名称(aria-label)',
|
||||
accessibleNames,
|
||||
);
|
||||
const openButtons = await page.locator('.game-lineage-node__open').count();
|
||||
check(
|
||||
'DOM 断言:每个可交互节点都有可聚焦的「打开《…》详情」主行动作(占位节点除外)',
|
||||
openButtons >= 6,
|
||||
`openButtons=${openButtons}`,
|
||||
);
|
||||
check('DOM 断言:每个节点都可聚焦且有可访问名称', focusable);
|
||||
|
||||
const b1Node = nodeCards.filter({ hasText: b1.title }).first();
|
||||
const c1Node = nodeCards.filter({ hasText: c1.title }).first();
|
||||
@@ -758,7 +763,7 @@ async function main() {
|
||||
`cardText=${cardText.replace(/\n/gu, ' / ').slice(0, 70)}`,
|
||||
);
|
||||
const coverImages = await page
|
||||
.locator('.game-lineage-node__main img')
|
||||
.locator('.game-lineage-node__cover img')
|
||||
.count();
|
||||
check(
|
||||
'DOM 断言:节点卡片渲染真实封面缩略图(coverObjectKey 有值才渲染)',
|
||||
@@ -929,15 +934,73 @@ async function main() {
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
await page.waitForTimeout(800);
|
||||
await nodeCards.filter({ hasText: e.title }).first().focus();
|
||||
// 关键字可达:主行动作(打开《…》详情)聚焦后按 Enter 应跳转(卡片主体现在=选中,不再跳详情)。
|
||||
const openE = page.locator(
|
||||
`.game-lineage-node__open[aria-label="打开《${e.title}》详情"]`,
|
||||
);
|
||||
await openE.first().focus();
|
||||
await page.keyboard.press('Enter');
|
||||
await page.waitForTimeout(800);
|
||||
check(
|
||||
'DOM 断言:键盘 Enter 也能跳转(可聚焦 + 键盘可达)',
|
||||
'DOM 断言:键盘 Enter(在「打开详情」主行动作上)能跳转',
|
||||
page.url().includes(nodeIds.E),
|
||||
`url=${page.url()}`,
|
||||
);
|
||||
|
||||
// 本轮终稿的核心:卡片主体点击 = 选中并保持路径高亮 + 面包屑(不跳详情)
|
||||
await page.goto(richUrl, { waitUntil: 'commit', timeout: 120_000 });
|
||||
await page.waitForFunction(
|
||||
() => document.querySelectorAll('.game-lineage-node').length >= 6,
|
||||
undefined,
|
||||
{ timeout: 120_000 },
|
||||
);
|
||||
await page.waitForTimeout(900);
|
||||
const b1CardForSelect = page
|
||||
.locator('.game-lineage-node')
|
||||
.filter({ hasText: b1.title })
|
||||
.first();
|
||||
await b1CardForSelect.click({ position: { x: 6, y: 6 } });
|
||||
await page.waitForTimeout(700);
|
||||
const breadcrumb = page.locator('.game-lineage-breadcrumb');
|
||||
const crumbText = await breadcrumb
|
||||
.first()
|
||||
.innerText()
|
||||
.catch(() => '');
|
||||
const selectedDimmed = await page
|
||||
.locator('.game-lineage-node--dimmed')
|
||||
.count();
|
||||
const selectedActiveEdges = await page
|
||||
.locator('.game-lineage-edge--active')
|
||||
.count();
|
||||
check(
|
||||
'DOM 断言(新):点击卡片主体 → 出现面包屑「已选中的路径」且包含根与当前节点',
|
||||
(await breadcrumb.count()) >= 1 &&
|
||||
crumbText.includes(root.title) &&
|
||||
crumbText.includes(b1.title),
|
||||
`crumb=${crumbText.replace(/\n+/gu, ' › ').slice(0, 70)}`,
|
||||
);
|
||||
check(
|
||||
'DOM 断言(新):点击后路径持续高亮(--active 边 ≥1 且其余节点降透明度)',
|
||||
selectedActiveEdges >= 1 && selectedDimmed >= 1,
|
||||
`activeEdges=${selectedActiveEdges} dimmed=${selectedDimmed}`,
|
||||
);
|
||||
await page.mouse.move(5, 5);
|
||||
await page.waitForTimeout(500);
|
||||
const dimmedAfterHoverOut = await page
|
||||
.locator('.game-lineage-node--dimmed')
|
||||
.count();
|
||||
check(
|
||||
'DOM 断言(新):鼠标移开后选中路径仍保持(不是 hover 一次性效果)',
|
||||
dimmedAfterHoverOut >= 1,
|
||||
`dimmed=${dimmedAfterHoverOut}`,
|
||||
);
|
||||
check(
|
||||
'DOM 断言(新):卡片主体点击不会跳走详情页',
|
||||
page.url().includes('/games/lineage'),
|
||||
`url=${page.url()}`,
|
||||
);
|
||||
await takeShot(page, 'lineage-08-selected-path.png');
|
||||
|
||||
// ---------- 移动端窄屏 ----------
|
||||
// 只给窄视口宽度(不模拟触摸设备):验证窄屏布局不溢出 + 画布内部可横向平移。
|
||||
const mobile = await browser.newContext({
|
||||
@@ -1136,6 +1199,7 @@ async function main() {
|
||||
'⑦ lineage-07-hover-edge-path.png(新增,核心)—— 在放大状态下 hover 1 代 B1:B1→根的**祖先路径连线被强化**(--active),其余连线变淡(--dimmed),同时节点侧兄弟卡降透明度。这是「可视化路径」需求的直接证据。',
|
||||
'⑥ lineage-06-fit-window.png(新增)—— 点「适应窗口」后:全树真正完整落在画布框内(6 个节点都在框内)、右侧大片空白消失(内容水平居中)、第 3 代不再贴底被裁。',
|
||||
'③ lineage-03-hover-ancestor.png:默认视野 hover B1 —— 自身与祖先不降透明度,同代兄弟 C1/F1(及 D/E)降透明度。',
|
||||
'⑧ lineage-08-selected-path.png(新增)—— 点击 1 代卡片主体(非标题/按钮)后:路径被「选中」并**保持**高亮(祖先连线加粗、其余节点降透明度),鼠标移开也不消失,顶部出现面包屑「已选中的路径」(含根 → 当前节点);页面不跳转。',
|
||||
'④ lineage-04-mobile-narrow.png:390×844 窄屏 —— 控件折行、**页面本身不横向溢出**、底部 tab 正常;初访不再是 35%(按可读下限 + 提示),画布内可拖拽横向平移(这张是平移后的画面)。',
|
||||
'⑤ lineage-05-parent-unavailable.png:父作品下架后 —— 缺失父作品处是占位卡「原作品已不可用/标题与作者名不对外展示」,顶部有「母版已不可用…」notice,标题回退为「创作族谱」,全文不出现被下架父作品的标题与作者名。',
|
||||
];
|
||||
|
||||
Reference in New Issue
Block a user