import { expect, type Locator } from '@playwright/test'; /** * N-27 整改新增的共享断言辅助(2026-09-23)。 * * 背景:多个 spec 曾以 `const box = await locator.boundingBox(); if (box) {...}` * 守卫几何断言——高负载下 boundingBox 偶发返回 null(chain3 实测,见 * p3-compatibility「移动端导航可用」原注释),守卫会把「元素消失」这种真实回归 * 静默吞成绿色。此类站点统一改用 pollBoundingBox: * - 轮询直到 boundingBox 非 null(超时 ⇒ 红色失败); * - 轮询通过后若仍为 null(元素在断言瞬间被移除)⇒ 显式 throw,绝不静默跳过。 * * 规则:本文件只做「等待」,不做「放宽」——不提供任何跳过断言的开关。 */ export interface BoxLike { x: number; y: number; width: number; height: number; } /** * 轮询 target 的 boundingBox 直到非 null,返回稳定后的盒模型。 * 超时未就绪时由 expect.poll 直接失败(测试变红),不会静默通过。 */ export async function pollBoundingBox( target: Locator, timeout = 10000, message = '等待 boundingBox 就绪', ): Promise { await expect .poll(() => target.boundingBox(), { timeout, message }) .not.toBeNull(); const box = await target.boundingBox(); if (!box) { throw new Error('boundingBox 在轮询通过后仍为 null(元素在断言瞬间消失)'); } return box; }