test(qa): e2e 装配修正 + 集成/门禁测试与工具链重构

- e2e:修死选择器与蜜罐误命中、补断言、GA4/security-headers 用例诚实标注
  skip 边界;新增 assert-helpers/fixtures/hydrated/primary-nav/touch-targets
  等复用桩。
- 集成层:config/test/jest.integration.config.js + tests-integration/ 真库
  一次性 SQLite 用例,teardown 守卫开发库指纹。
- 门禁工具链:jest.setup 归位到根、scripts/accessibility 全站 axe 节点计数、
  check-brand-text-token/check-motion-constraints 机械守卫、stryker/lighthouse
  配置收敛。
This commit is contained in:
2026-09-28 10:48:08 +08:00
parent a366bd1400
commit 6bb7c557ee
142 changed files with 6597 additions and 2653 deletions
+26
View File
@@ -0,0 +1,26 @@
import { expect, type Locator } from '@playwright/test';
/**
* 等到 React 把 props/事件监听挂到目标元素上,再对它发起交互。
*
* 为什么需要:SSR HTML 一进入 DOM,元素就已经「可见」,但客户端组件的 onClick/onMouseEnter
* 要等 hydration 完成才存在。这段窗口内派发的指针事件被浏览器当作普通事件丢弃,hydration 后
* 也不会重放 —— 表现为 hover/click 调用成功、状态却永远不变,然后 expect 轮询到 15s timeout。
*
* 实测依据(next dev,本机 :3000):/contact 的 [data-testid="submit-button"] 在 first visible
* 之后 1735ms 才挂上 handler;早点击得到 0 条 [data-testid="error-message"],
* hydration 后同一动作得到 5 条。主导航「产品」按钮 first visible 时同样尚未 hydration。
*
* 探针取 React DOM 写在宿主元素上的 __reactProps$ 内部键:`toBeVisible()` 只能证明
* 「渲染出来了」,证明不了「能交互」,而这个键是唯一能把两者分开的信号。项目锁定 React 18.3
* (package.json),该前缀自 React 16 起稳定。
*/
export async function expectHydrated(target: Locator, timeout = 20000): Promise<void> {
await expect
.poll(
async () =>
target.evaluate((el) => Object.keys(el).some((key) => key.startsWith('__reactProps$'))),
{ timeout, message: '目标元素尚未完成 hydration' },
)
.toBe(true);
}