mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-20 20:21:20 -08:00
test(audio): [PKG-AUDIO-05] distinguish prefix startup from native starvation
This commit is contained in:
1 parent
bf56d09178
commit
3eb5500525
9 files changed
+4151
-11
No files matched your search
@@ -230,6 +230,17 @@ playback after release; inspect its progressed/waiting flags before claiming buf
|
||||
These capability observation timeouts do not relax the integration assertions.
|
||||
Archive the report and results (including traces) before starting another browser suite.
|
||||
|
||||
For byte-prefix diagnostics, set `ARTPLAYER_MEDIA_GATE_VIDEO_LIMIT` and/or
|
||||
`ARTPLAYER_MEDIA_GATE_AUDIO_LIMIT` to an integer byte count strictly between zero
|
||||
and the corresponding file size. Unset them for the unchanged 96 KiB video / 32 KiB
|
||||
audio defaults. These variables only affect the native diagnostic, never the audio
|
||||
plugin integration test. `native-gate-before-release` retains the media state and
|
||||
an immutable request snapshot before releasing the tail; `native-gate-capability`
|
||||
also survives failures after that observation and records any successful recovery.
|
||||
Check `progressed` and `waiting` independently. Larger prefixes can start Windows
|
||||
WebKit playback without yielding a trusted waiting event; this does not prove the
|
||||
integration buffering contract. See the audio prefix checkpoint in refactor.
|
||||
|
||||
Danmuku input, scheduler, resources and heatmap-density specs accept
|
||||
`ARTPLAYER_DANMUKU_ARTIFACT` for a built main/legacy file; unset it to compile the
|
||||
current JS/TS entry. Run each format sequentially and wait for the command's final
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import fs from 'node:fs'
|
||||
import process from 'node:process'
|
||||
import { hash } from '../../refactor/scripts/releases.mjs'
|
||||
import { createMediaGate } from '../helpers/media-gate.js'
|
||||
import { expect, test } from './fixtures.js'
|
||||
@@ -8,8 +9,10 @@ for (const owner of ['video', 'audio']) {
|
||||
test(`native ${owner} ${completeRanges ? 'complete ranges' : 'streamed response'} capability without ArtPlayer instances`, async ({ page }, testInfo) => {
|
||||
const file = owner === 'video' ? 'pattern.mp4' : 'audio-tone.m4a'
|
||||
const bytes = fs.readFileSync(new URL(`./media/${file}`, import.meta.url))
|
||||
const limit = owner === 'video' ? 96 * 1024 : 32 * 1024
|
||||
const configuredLimit = process.env[`ARTPLAYER_MEDIA_GATE_${owner.toUpperCase()}_LIMIT`]
|
||||
const limit = configuredLimit === undefined ? (owner === 'video' ? 96 * 1024 : 32 * 1024) : Number(configuredLimit)
|
||||
const gate = await createMediaGate(bytes, owner === 'video' ? 'video/mp4' : 'audio/mp4', limit, completeRanges)
|
||||
const observation = { file, sha256: hash(bytes), bytes: bytes.length, limit, completeRanges, configuredLimit: configuredLimit ?? null, progressed: false, waiting: false }
|
||||
try {
|
||||
await page.goto('/test/player.html')
|
||||
await page.evaluate(({ owner, url }) => {
|
||||
@@ -25,29 +28,31 @@ for (const owner of ['video', 'audio']) {
|
||||
}, { owner, url: gate.url })
|
||||
await expect.poll(() => page.evaluate(() => window.nativeMedia.readyState >= 2 || Boolean(window.nativeMedia.error))).toBe(true)
|
||||
await page.locator('#play').click()
|
||||
let progressed = false
|
||||
let waiting = false
|
||||
try {
|
||||
await page.waitForFunction(() => window.nativeMedia.currentTime > 0.3, null, { timeout: 3000 })
|
||||
progressed = true
|
||||
observation.progressed = true
|
||||
await page.waitForFunction(() => window.nativeEvents.some(event => event.event === 'waiting' && event.trusted && event.time > 0.3 && event.readyState < 3), null, { timeout: 7000 })
|
||||
waiting = true
|
||||
observation.waiting = true
|
||||
}
|
||||
catch (error) {
|
||||
if (error.name !== 'TimeoutError')
|
||||
throw error
|
||||
}
|
||||
const before = await page.evaluate(() => ({ time: window.nativeMedia.currentTime, readyState: window.nativeMedia.readyState, paused: window.nativeMedia.paused, error: window.nativeMedia.error?.code || null, instances: window.Artplayer.instances.length, events: window.nativeEvents }))
|
||||
const before = await page.evaluate(() => ({ time: window.nativeMedia.currentTime, duration: window.nativeMedia.duration, ended: window.nativeMedia.ended, readyState: window.nativeMedia.readyState, paused: window.nativeMedia.paused, error: window.nativeMedia.error?.code || null, instances: window.Artplayer.instances.length, events: window.nativeEvents, buffered: Array.from({ length: window.nativeMedia.buffered.length }, (_, index) => [window.nativeMedia.buffered.start(index), window.nativeMedia.buffered.end(index)]) }))
|
||||
observation.before = before
|
||||
observation.requestsBeforeRelease = structuredClone(gate.requests)
|
||||
await testInfo.attach('native-gate-before-release', { contentType: 'application/json', body: JSON.stringify(observation) })
|
||||
expect(before.instances).toBe(0)
|
||||
expect(gate.blocked).toBeGreaterThan(0)
|
||||
gate.release()
|
||||
await page.locator('#play').click()
|
||||
await expect.poll(() => page.evaluate(() => window.nativeMedia.currentTime)).toBeGreaterThan(before.time + 0.3)
|
||||
expect(await page.evaluate(() => window.nativeMedia.error)).toBeNull()
|
||||
await testInfo.attach('native-gate-capability', { contentType: 'application/json', body: JSON.stringify({ file, sha256: hash(bytes), limit, completeRanges, progressed, waiting, before, requests: gate.requests, after: await page.evaluate(() => ({ time: window.nativeMedia.currentTime, readyState: window.nativeMedia.readyState, paused: window.nativeMedia.paused })) }) })
|
||||
observation.after = await page.evaluate(() => ({ time: window.nativeMedia.currentTime, readyState: window.nativeMedia.readyState, paused: window.nativeMedia.paused }))
|
||||
}
|
||||
finally {
|
||||
try {
|
||||
await testInfo.attach('native-gate-capability', { contentType: 'application/json', body: JSON.stringify({ ...observation, requests: gate.requests }) })
|
||||
await page.evaluate(() => {
|
||||
window.nativeMedia?.pause()
|
||||
window.nativeMedia?.removeAttribute('src')
|
||||
|
||||
Reference in new issue
Block a user