mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-11 13:56:15 -08:00
test(chapter): [PKG-CHAPTER-HOVER-01] wait for stable fullscreen geometry
This commit is contained in:
1 parent
492e58a345
commit
d89728c0a6
14 files changed
+1797
-14
No files matched your search
@@ -103,3 +103,12 @@ bridges; typesVersions provides the legacy subpath to old resolvers. All bridges
|
||||
refer to one contract and runtime import paths stay unchanged. The frozen
|
||||
published baseline is under refactor/baselines; never overwrite it with candidate
|
||||
behavior. Physical device, full editor and final release checks remain separate tasks.
|
||||
|
||||
The combination suite uses `test/browser/chapter-hover.ts` to wait for Playwright
|
||||
actionability/stable geometry before reading progress coordinates. Fullscreen state
|
||||
alone does not mean the bottom controls have finished their CSS transition.
|
||||
`chapter-hover.spec.js` exercises this boundary with an intentional native Web
|
||||
Animation after entering real fullscreen. It preserves title/opacity/hit-test
|
||||
assertions and uses actual installed artifacts in the installed browser scope.
|
||||
`ARTPLAYER_CHAPTER_HOVER_BASELINE=1` restores the old immediate coordinate read for
|
||||
diagnosis only. This helper corrects test synchronization, not player behavior.
|
||||
File diff suppressed because it is too large.
Load diff
@@ -0,0 +1,57 @@
|
||||
# PKG-CHAPTER-HOVER-01 全屏悬停测试同步
|
||||
|
||||
## 问题与边界
|
||||
|
||||
CI-BROWSER-01 的已安装四包检查曾实际出现 224 通过、1 失败:Chromium 中
|
||||
5.4.0 核心搭配候选 Chapter,原生全屏后的章节标题先通过文本断言,再隐藏,
|
||||
opacity 从 0.279 降到 0。原始报告、trace 和截图保留在
|
||||
`refactor/.cache/ci-browser-installed-full-report`,不改写为通过。
|
||||
|
||||
旧测试在 `art.fullscreen === true` 后立即读取进度条 boundingBox 并移动鼠标。
|
||||
核心 bottom.less 的进度条/控件有 transform transition;全屏布尔状态不代表
|
||||
几何已稳定。原 trace 的鼠标位置为 (640, 665.9921875),终态截图的进度条已
|
||||
移动。仅靠后来通过不能证明原因,因此另建受控移动实验。
|
||||
|
||||
## 实现与责任
|
||||
|
||||
- `test/browser/chapter-hover.ts` 统一几何读取:先通过 Playwright locator 的
|
||||
`hover({ trial: true })` actionability/stability 检查,再读取 box 并实际移动鼠标。
|
||||
trial 不发送实际 hover;没有增加固定 sleep、断言超时或 test retries。
|
||||
- `chapter-combinations.spec.js` 复用该函数;标题、透明度、缩略图、边界及全屏
|
||||
退出断言保持原样。
|
||||
- `chapter-hover.spec.js` 在真实原生全屏中用原生 Web Animation 让进度条移动
|
||||
600ms,结束后通过真实 hit-test 验证指针仍在进度条内,再验证 Middle/opacity。
|
||||
这是故意注入的几何移动,不是宣称产品 transition 实际持续 600ms。
|
||||
- `ARTPLAYER_CHAPTER_HOVER_BASELINE=1` 可恢复旧的立即读取路径,保留可重跑的
|
||||
反例。默认必须使用稳定路径;诊断模式的失败不能豁免正式验收。
|
||||
- 新 TS helper 纳入严格工具类型检查;安装浏览器范围显式加入该回归文件。
|
||||
|
||||
API-08 仅涉及测试如何操作 DOM;生产源码、公开接口/事件/声明/CSS 和安装包
|
||||
字节都未修改。包架构文档记录入口和边界。本任务不需要重建生产运行时或引入依赖。
|
||||
|
||||
## 证据与限制
|
||||
|
||||
完整结果、报告摘要、浏览器版本、实际安装入口及 SHA 见
|
||||
[chapter-hover-validation.json](../baselines/chapter-hover-validation.json)。
|
||||
先前立即读取路径在受控移动中 4 失败、2 通过;等待稳定后同样 6 项全部通过。
|
||||
Chromium/Firefox 的失败是最终指针已离开移动后的进度条。首版 WebKit 旧路径
|
||||
通过,但审查附件发现其 hit-test 与最终矩形不一致。因此补上最终 x/y 矩形范围
|
||||
断言:最终 baseline 三引擎 6 项全部失败;默认稳定路径在 main/legacy 各 6 项
|
||||
通过。首版的 2 项通过仍留档,不能把只依赖 hit-test 的结果当作几何正确。
|
||||
原有组合与首版新增移动回归在 main/legacy 各 66 项
|
||||
通过,均无重试、跳过或失败。严格 TS、专项 ESLint、根 lint(0 错误/1 个既有
|
||||
warning)、4 项 browser runner 测试和固定工具链检查通过。
|
||||
|
||||
实验确认旧测试的几何竞态及针对该机制的修正,原失败符合相同症状;不能重新播放
|
||||
原 run 的精确调度,也不能据此声称所有全屏生产缺陷已排除。新旧包字节保持一致,
|
||||
本次修复归类为测试同步问题。CHAPTER-TIMING-01 的 WebKit restart 观察耗时、
|
||||
真机、完整发布/分发验收仍由 Chapter-05/06 负责。
|
||||
|
||||
验证使用 Node 24.21.0、Yarn 1.22.22、实际安装产物及桌面三引擎。没有远端 CI、
|
||||
真机、全量 source suite 或 npm 发布;不把模拟触摸称为手机证据。
|
||||
|
||||
## 回退与接续
|
||||
|
||||
诊断时设置 baseline 环境变量并运行 README 所列命令,可比较真实指针与终态
|
||||
矩形。交付回退可还原本任务的 helper、回归测试、scope 和文档/状态;不要删除
|
||||
历史失败报告或把 opacity 断言放宽。后续 UI/CSS 改动须继续运行这两个浏览器文件。
|
||||
+3
-3
@@ -4,7 +4,7 @@
|
||||
|
||||
基线:`40fcda6a37d0049d42e49c1e64e70d4fd9ba5f7f`。总任务 258 项,范围 22 个包及工作区/示例。
|
||||
|
||||
状态:todo 51 / doing 19 / blocked 0 / done 188 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
状态:todo 50 / doing 19 / blocked 0 / done 189 / deferred 0。风险 L/M/H 表示兼容风险,不表示工期。
|
||||
|
||||
前置依赖是启动条件;验收是完成条件。任务可以继续拆分,但不能复用或悄悄删除旧 ID。
|
||||
|
||||
@@ -146,7 +146,7 @@
|
||||
| PKG-CHAPTER-04 | artplayer-plugin-chapter<br>迁移自有源码和公开类型 | PKG-CHAPTER-03, ENG-04, ENG-06 | 承接 03 的自有源码 TS 化,完善公开 Chapters/Option/Result 与 update 推导,关闭声明模块解析和旧消费差异 | 严格类型检查、旧消费样例通过;声明路径/导出和同步异步兼容;处理 BASE-TYPE-01/03,保持运行时和新旧 TS 模块解析消费 | M | done |
|
||||
| PKG-CHAPTER-05 | artplayer-plugin-chapter<br>验证新旧核心和组合 | PKG-CHAPTER-04, CORE-22 | chapter + quality/thumbnail、移动和全屏进度场景 | 最终核心与原支持范围核心分别通过;设备/SDK 缺证据不能标完成 | M | doing |
|
||||
| PKG-CHAPTER-06 | artplayer-plugin-chapter<br>验证分发并同步文档 | PKG-CHAPTER-05, ENG-07, PKG-CHAPTER-HOVER-01 | chapter.js 示例、产物和变更记录 | tarball 入口/资源、类型、8082 demo 和 README 一致,有回退记录 | M | todo |
|
||||
| PKG-CHAPTER-HOVER-01 | artplayer-plugin-chapter<br>定位并修复原生全屏章节悬停时序 | PKG-CHAPTER-04, CI-BROWSER-01 | 原生全屏动态几何与指针时序复现、针对根因的修复和真实浏览器回归 | 解释 Chromium 旧核心+新章节的 opacity 失败;保留标题、缩略图和全屏退出断言,不以重试或扩大等待掩盖;区分测试同步与生产缺陷 | M | todo |
|
||||
| PKG-CHAPTER-HOVER-01 | artplayer-plugin-chapter<br>定位并修复原生全屏章节悬停时序 | PKG-CHAPTER-04, CI-BROWSER-01 | 原生全屏动态几何与指针时序复现、针对根因的修复和真实浏览器回归 | 解释 Chromium 旧核心+新章节的 opacity 失败;保留标题、缩略图和全屏退出断言,不以重试或扩大等待掩盖;区分测试同步与生产缺陷 | M | done |
|
||||
|
||||
## 5 包迁移:artplayer-plugin-ambilight
|
||||
|
||||
@@ -669,4 +669,4 @@
|
||||
- ENG-13: [记录](changes/2026-09-14-ENG-13-observation-window.md) [记录](baselines/observation-window-validation.json)
|
||||
- SITE-VCONSOLE-01: [记录](changes/2026-09-14-SITE-VCONSOLE-01-lifecycle.md) [记录](baselines/vconsole-lifecycle-validation.json)
|
||||
- CI-BROWSER-01: [记录](changes/2026-09-14-CI-BROWSER-01-scopes.md) [记录](baselines/browser-scope-validation.json)
|
||||
- PKG-CHAPTER-HOVER-01: [记录](changes/2026-09-14-CI-BROWSER-01-scopes.md) [记录](baselines/browser-scope-validation.json)
|
||||
- PKG-CHAPTER-HOVER-01: [记录](changes/2026-09-14-PKG-CHAPTER-HOVER-01-geometry.md) [记录](baselines/chapter-hover-validation.json)
|
||||
@@ -1,5 +1,20 @@
|
||||
# 进度与证据
|
||||
|
||||
## PKG-CHAPTER-HOVER-01 全屏悬停测试同步完成
|
||||
|
||||
原始 installed 224/1 失败保持归档。受控原生进度条移动实验确认立即读取坐标
|
||||
可让指针落在终态进度条外:首版旧步骤4失败/2通过,等待actionability后6通过。
|
||||
审查发现WebKit hit-test与最终矩形不一致,补强数值边界后baseline六项全部失败,
|
||||
默认路径main/legacy各六项通过;保留首版报告,不把hit-test等同于几何正确。
|
||||
共享TS helper先等待几何稳定再读取box;保留文字、opacity、缩略图、边界和
|
||||
全屏退出断言,不更改生产代码或超时。完整main/legacy各66通过,实际安装
|
||||
字节、新旧核心/插件组合及三桌面引擎均有报告;原run精确调度不能重放。
|
||||
严格TS、专项lint、根lint(0错误/1既有warning)、4项runner测试、工具链通过。
|
||||
见[变更](changes/2026-09-14-PKG-CHAPTER-HOVER-01-geometry.md)和
|
||||
[证据](baselines/chapter-hover-validation.json)。258项:189 done、19 doing、50 todo。
|
||||
CHAPTER-FULLSCREEN-GEOMETRY-01按测试同步关闭;CHAPTER-TIMING-01、真机及
|
||||
Chapter-05/06仍未完成。没有远端CI、push或发布;本任务独立本地提交后审计。
|
||||
|
||||
## CI-BROWSER-01 源码/安装浏览器范围隔离完成
|
||||
|
||||
复现全局安装map使HLS源码用例beforeAll直接失败;新source入口清除继承map后实际
|
||||
|
||||
@@ -271,4 +271,4 @@
|
||||
| JASSUB-RENDER-RESOURCES-01 | resolved / 已复现 | Main-thread async rendering leaves received ImageBitmaps open when native canvas operations throw | PKG-JASSUB-10 |
|
||||
| ENG-PERF-OBS-01 | resolved / 已复现 | A nominal 350 ms resource observation can record only 349 ms and fail the required minimum | ENG-13 |
|
||||
| VCONSOLE-LIFECYCLE-01 | resolved / 已复现 | vConsole delayed log, panel and scroller work outlives its owner | SITE-07, SITE-05, SITE-VCONSOLE-01 |
|
||||
| CHAPTER-FULLSCREEN-GEOMETRY-01 | open / 已复现 | Chromium 原生全屏后章节 hover 标题曾出现后又隐藏 | PKG-CHAPTER-05, PKG-CHAPTER-HOVER-01 |
|
||||
| CHAPTER-FULLSCREEN-GEOMETRY-01 | resolved / 已复现 | Chromium 原生全屏后章节 hover 标题曾出现后又隐藏 | PKG-CHAPTER-05, PKG-CHAPTER-HOVER-01 |
|
||||
+9
-2
@@ -6198,7 +6198,7 @@
|
||||
"id": "CHAPTER-FULLSCREEN-GEOMETRY-01",
|
||||
"title": "Chromium 原生全屏后章节 hover 标题曾出现后又隐藏",
|
||||
"confirmation": "reproduced",
|
||||
"status": "open",
|
||||
"status": "resolved",
|
||||
"owners": [
|
||||
"PKG-CHAPTER-05",
|
||||
"PKG-CHAPTER-HOVER-01"
|
||||
@@ -6210,7 +6210,14 @@
|
||||
],
|
||||
"compatibleResolution": "核对原生全屏布局/controls transition 与鼠标坐标的时序;根据实际根因修复测试同步或生产实现,保持旧接口。",
|
||||
"closureCriteria": "保留原失败并取得可解释的旧红新绿/稳定真实浏览器证据,不用重试、延时扩大或移除 opacity 断言关闭。",
|
||||
"workspaceState": "Installed 225-case run with two workers: 224 pass, published 5.4.0 core + candidate Chapter Chromium fullscreen case fails at hoverChapter opacity. Text assertion initially passes, opacity falls from 0.279 to 0 and title clears. Trace mouse=(640,665.9921875); screenshot is fullscreen1280x720. Geometry transition is a hypothesis; production defect versus test synchronization remains unverified."
|
||||
"workspaceState": "Shared typed hover helper waits for actionability before coordinate sampling. Production package bytes are unchanged; report-bound old/new core/plugin combinations cover main and legacy on three desktop engines. Physical devices and Chapter-05/06 acceptance remain open.",
|
||||
"resolutionEvidence": [
|
||||
"refactor/changes/2026-09-14-PKG-CHAPTER-HOVER-01-geometry.md",
|
||||
"refactor/baselines/chapter-hover-validation.json",
|
||||
"test/browser/chapter-hover.ts",
|
||||
"test/browser/chapter-hover.spec.js"
|
||||
],
|
||||
"resolutionRationale": "The immediate bounding-box read permits stale pointer coordinates while progress transforms move. Initial hit-test control gives 4 failures/2 passes before and 6 passes after waiting for locator stability. WebKit hit tests disagree with the final rectangle, so additional explicit bounds assertions were added: baseline 6 failures, stable main/legacy 6 passes each. Complete main/legacy chapter combination suites retain title, opacity, thumbnails and fullscreen assertions (66 passes each). This closes the identified test synchronization race, not all possible production fullscreen defects or CHAPTER-TIMING-01. Original 224/1 failure remains archived; its exact scheduler cannot be replayed."
|
||||
}
|
||||
]
|
||||
}
|
||||
+3
-3
@@ -5381,13 +5381,13 @@
|
||||
"PKG-CHAPTER-04",
|
||||
"CI-BROWSER-01"
|
||||
],
|
||||
"status": "todo",
|
||||
"status": "done",
|
||||
"risk": "M",
|
||||
"deliverable": "原生全屏动态几何与指针时序复现、针对根因的修复和真实浏览器回归",
|
||||
"acceptance": "解释 Chromium 旧核心+新章节的 opacity 失败;保留标题、缩略图和全屏退出断言,不以重试或扩大等待掩盖;区分测试同步与生产缺陷",
|
||||
"evidence": [
|
||||
"changes/2026-09-14-CI-BROWSER-01-scopes.md",
|
||||
"baselines/browser-scope-validation.json"
|
||||
"changes/2026-09-14-PKG-CHAPTER-HOVER-01-geometry.md",
|
||||
"baselines/chapter-hover-validation.json"
|
||||
]
|
||||
}
|
||||
]
|
||||
|
||||
@@ -9,6 +9,7 @@ export const installedTests = [
|
||||
'initialization.spec.js',
|
||||
'chapter.spec.js',
|
||||
'chapter-combinations.spec.js',
|
||||
'chapter-hover.spec.js',
|
||||
'ambilight-lifecycle.spec.js',
|
||||
'ambilight-proxy.spec.js',
|
||||
'canvas-lifecycle.spec.js',
|
||||
|
||||
@@ -30,6 +30,7 @@
|
||||
"build-docs.js",
|
||||
"../packages/artplayer-vitepress/build/**/*.ts",
|
||||
"build-vconsole.mjs",
|
||||
"browser-validation/**/*.ts"
|
||||
"browser-validation/**/*.ts",
|
||||
"../test/browser/chapter-hover.ts"
|
||||
]
|
||||
}
|
||||
@@ -1,5 +1,25 @@
|
||||
# Browser regression entry
|
||||
|
||||
Chapter pointer geometry is shared by `chapter-hover.ts` and the combination
|
||||
suite. It awaits locator actionability with `hover({ trial: true })` before
|
||||
reading coordinates; `art.fullscreen` can become true while controls still move.
|
||||
The motion regression enters native fullscreen and adds a controlled 600ms Web
|
||||
Animation to reproduce stale coordinates. It checks the final hit target, chapter
|
||||
text and opacity without changing production CSS or increasing assertion timeouts.
|
||||
It also requires pointer x/y to lie within the final inner rectangle; WebKit's
|
||||
initial hit-test alone reported a hit outside that recorded rectangle.
|
||||
Use `ARTPLAYER_CHAPTER_HOVER_BASELINE=1` to rerun the old immediate-read path;
|
||||
this diagnostic intentionally fails on affected engines and is not an acceptance
|
||||
mode. Both files belong to source and installed scopes. For installed runs:
|
||||
|
||||
```sh
|
||||
# Set ARTPLAYER_BROWSER_ARTIFACTS to a verified installation map first.
|
||||
yarn test:browser:installed test/browser/chapter-combinations.spec.js test/browser/chapter-hover.spec.js --workers=2
|
||||
```
|
||||
|
||||
See `refactor/baselines/chapter-hover-validation.json` for the original failure,
|
||||
controlled red/green observations and actual execution limits.
|
||||
|
||||
CI uses `yarn test:browser:source` for the complete source suite and
|
||||
`yarn test:browser:installed` for the reviewed installed-package subset. The source
|
||||
launcher clears inherited ARTPLAYER_BROWSER_ARTIFACTS; the installed launcher and
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { devices } from '@playwright/test'
|
||||
import { hoverProgress } from './chapter-hover.ts'
|
||||
import { expect, test } from './fixtures.js'
|
||||
|
||||
async function openChapter(page, core, chapter) {
|
||||
@@ -37,10 +38,7 @@ async function openChapter(page, core, chapter) {
|
||||
}
|
||||
|
||||
async function hoverChapter(page, percentage, text) {
|
||||
const inner = page.locator('.art-control-progress-inner')
|
||||
const box = await inner.boundingBox()
|
||||
const x = Math.round(box.x + box.width * percentage)
|
||||
await page.mouse.move(x, box.y + box.height / 2)
|
||||
const { box, x } = await hoverProgress(page, percentage)
|
||||
await expect(page.locator('.art-chapter-title')).toHaveText(text)
|
||||
await expect(page.locator('.art-chapter-title')).toHaveCSS('opacity', '1')
|
||||
await expect(page.locator('.art-control-thumbnails')).toBeVisible()
|
||||
|
||||
@@ -0,0 +1,52 @@
|
||||
import { hoverProgress } from './chapter-hover.ts'
|
||||
import { expect, test } from './fixtures.js'
|
||||
|
||||
for (const core of ['published', 'candidate']) {
|
||||
test(`${core}: chapter hover waits for a moving fullscreen progress bar`, async ({ page }, testInfo) => {
|
||||
await page.goto(`/test/player.html?core=${core}&chapter=candidate`)
|
||||
await page.evaluate(() => {
|
||||
window.art = new window.Artplayer({
|
||||
container: '.player',
|
||||
url: '/test/pattern.mp4',
|
||||
muted: true,
|
||||
fullscreen: true,
|
||||
plugins: [window.artplayerPluginChapter({ chapters: [{ start: 0, end: 2, title: 'Opening' }, { start: 2, end: 6, title: 'Middle' }, { start: 6, end: Infinity, title: 'Ending' }] })],
|
||||
})
|
||||
})
|
||||
await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true)
|
||||
await page.locator('.art-control-fullscreen').click()
|
||||
await expect.poll(() => page.evaluate(() => window.art.fullscreen)).toBe(true)
|
||||
await page.evaluate(async () => {
|
||||
window.progressAnimation = document.querySelector('.art-progress').animate([
|
||||
{ transform: 'translateY(-60px)' },
|
||||
{ transform: 'translateY(0)' },
|
||||
], { duration: 600, easing: 'linear' })
|
||||
await window.progressAnimation.ready
|
||||
})
|
||||
const pointer = await hoverProgress(page, 0.5)
|
||||
await page.evaluate(() => window.progressAnimation.finished)
|
||||
const layout = await page.evaluate(({ x, y }) => {
|
||||
const element = document.querySelector('.art-control-progress-inner')
|
||||
const rect = element.getBoundingClientRect()
|
||||
return { x: rect.x, y: rect.y, width: rect.width, height: rect.height, pointerInside: !!document.elementFromPoint(x, y)?.closest('.art-progress'), title: document.querySelector('.art-chapter-title').textContent }
|
||||
}, pointer)
|
||||
await testInfo.attach('chapter-hover-motion', { contentType: 'application/json', body: JSON.stringify({ core, baseline: process.env.ARTPLAYER_CHAPTER_HOVER_BASELINE === '1', pointer, layout, motion: 'controlled native Web Animation after actual fullscreen; no media or hit-test mocks' }) })
|
||||
expect(layout.pointerInside).toBe(true)
|
||||
expect(pointer.x).toBeGreaterThanOrEqual(layout.x)
|
||||
expect(pointer.x).toBeLessThanOrEqual(layout.x + layout.width)
|
||||
expect(pointer.y).toBeGreaterThanOrEqual(layout.y)
|
||||
expect(pointer.y).toBeLessThanOrEqual(layout.y + layout.height)
|
||||
await expect(page.locator('.art-chapter-title')).toHaveText('Middle')
|
||||
await expect(page.locator('.art-chapter-title')).toHaveCSS('opacity', '1')
|
||||
await page.locator('.art-control-fullscreen').click()
|
||||
await expect.poll(() => page.evaluate(() => window.art.fullscreen)).toBe(false)
|
||||
await page.evaluate(() => window.art.destroy())
|
||||
})
|
||||
}
|
||||
|
||||
test.afterEach(async ({ page }) => {
|
||||
await page.evaluate(() => {
|
||||
if (window.art && !window.art.isDestroy)
|
||||
window.art.destroy()
|
||||
})
|
||||
})
|
||||
@@ -0,0 +1,15 @@
|
||||
import type { Page } from '@playwright/test'
|
||||
import assert from 'node:assert/strict'
|
||||
import process from 'node:process'
|
||||
|
||||
export async function hoverProgress(page: Page, percentage: number) {
|
||||
const inner = page.locator('.art-control-progress-inner')
|
||||
if (process.env.ARTPLAYER_CHAPTER_HOVER_BASELINE !== '1')
|
||||
await inner.hover({ trial: true })
|
||||
const box = await inner.boundingBox()
|
||||
assert(box, 'Chapter progress must have a visible box')
|
||||
const x = Math.round(box.x + box.width * percentage)
|
||||
const y = box.y + box.height / 2
|
||||
await page.mouse.move(x, y)
|
||||
return { box, x, y }
|
||||
}
|
||||
Reference in new issue
Block a user