Files
ArtPlayer/test/helpers/danmuku-combination-load.js

62 lines
3.2 KiB
JavaScript

import { expect } from '@playwright/test'
// Observe real media/RAF delivery after a companion plugin has become operational.
export async function observeDanmukuLoad(page, { label, requireComplete, rate = 20, seconds = 6 }) {
let result
try {
await page.evaluate(async ({ label, rate, seconds }) => {
const art = window.art
const plugin = art.plugins.artplayerPluginDanmuku
const owner = plugin.config({ speed: 1, antiOverlap: false })
const host = art.template.$player.ownerDocument.defaultView
const base = art.currentTime
const rows = Array.from({ length: rate * seconds }, (_, index) => ({
id: `${label}-${index}`,
text: `${label} ${index}`,
time: base + 0.5 + index / rate,
mode: index % 3,
}))
const ids = new Set(rows.map(row => row.id))
const state = window.danmukuCombinationLoad = { base, end: base + seconds + 2, rows, visible: [], frames: [], errors: [], startWall: host.performance.now() }
const visible = (row) => {
if (ids.has(row.id))
state.visible.push({ id: row.id, time: art.currentTime, wall: host.performance.now() })
}
const error = error => state.errors.push(String(error))
let frame
const sample = () => {
state.frames.push({ time: art.currentTime, wall: host.performance.now() })
frame = host.requestAnimationFrame(sample)
}
frame = host.requestAnimationFrame(sample)
art.on('artplayerPluginDanmuku:visible', visible)
art.on('artplayerPluginDanmuku:error', error)
window.finishDanmukuCombinationLoad = () => {
host.cancelAnimationFrame(frame)
art.off('artplayerPluginDanmuku:visible', visible)
art.off('artplayerPluginDanmuku:error', error)
const loaded = owner.queue.filter(row => ids.has(row.id))
const buffered = { pending: [...owner.scheduler?.buffer.pending || []].filter(row => ids.has(row.id)).map(row => row.id), reserved: [...owner.scheduler?.buffer.reserved || []].filter(row => ids.has(row.id)).map(row => row.id) }
const result = { ...state, endWall: host.performance.now(), time: art.currentTime, loaded: loaded.length, waiting: loaded.filter(row => row.$state === 'wait').length, referenced: loaded.filter(row => row.$ref).length, nodes: art.template.$danmuku.children.length, pooled: owner.$refs.length, uniquePool: new Set(owner.$refs).size, decodedWidth: art.video.videoWidth, buffered }
window.danmukuCombinationLoadResult = result
return result
}
await plugin.load(rows)
}, { label, rate, seconds })
await expect.poll(() => page.evaluate(() => window.art.currentTime >= window.danmukuCombinationLoad.end), { timeout: 16000 }).toBe(true)
}
finally {
result = await page.evaluate(() => window.finishDanmukuCombinationLoad?.())
}
expect(result.decodedWidth).toBeGreaterThan(0)
expect(result.loaded).toBe(rate * seconds)
expect(result.errors).toEqual([])
if (requireComplete) {
expect(result.visible.map(row => row.id).sort()).toEqual(result.rows.map(row => row.id).sort())
expect(result.waiting).toBe(rate * seconds)
expect(result.referenced).toBe(0)
expect(result.uniquePool).toBe(result.pooled)
}
return { ...result, requireComplete, rate, seconds }
}