mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:46:16 -08:00
83 lines
4.4 KiB
JavaScript
83 lines
4.4 KiB
JavaScript
import { expect, test } from './fixtures.js'
|
|
|
|
for (const core of ['published', 'candidate']) {
|
|
test(`${core}: real media preserves timeline, volume, rate and property descriptors`, async ({ page }) => {
|
|
await page.goto(`/test/player.html?core=${core}&chapter=published`)
|
|
await page.evaluate(() => window.createPlayer('/test/pattern.mp4?properties=media'))
|
|
await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true)
|
|
const result = await page.evaluate(() => {
|
|
const { art } = window
|
|
const seeks = []
|
|
const muted = []
|
|
art.on('seek', (...args) => seeks.push(args))
|
|
art.on('muted', value => muted.push(value))
|
|
art.seek = '2.5 seconds'
|
|
const seekNotice = art.template.$noticeInner.textContent
|
|
art.forward = 1
|
|
art.backward = 0.5
|
|
art.volume = 0.42
|
|
const volumeNotice = art.template.$noticeInner.textContent
|
|
art.muted = 'truthy'
|
|
art.playbackRate = 1.5
|
|
const rateNotice = art.template.$noticeInner.textContent
|
|
art.playbackRate = 0
|
|
const resetNotice = art.template.$noticeInner.textContent
|
|
const descriptors = Object.fromEntries(['currentTime', 'seek', 'forward', 'backward', 'volume', 'muted', 'playbackRate', 'loaded', 'loadedTime', 'played', 'state'].map((name) => {
|
|
const descriptor = Object.getOwnPropertyDescriptor(art, name)
|
|
return [name, { getter: typeof descriptor.get === 'function', setter: typeof descriptor.set === 'function', enumerable: descriptor.enumerable, configurable: descriptor.configurable }]
|
|
}))
|
|
const unreadable = Object.fromEntries(['seek', 'forward', 'backward', 'switch', 'quality'].map(name => [name, art[name] === undefined]))
|
|
const buffered = Array.from({ length: art.video.buffered.length }, (_, index) => art.video.buffered.end(index))
|
|
const result = { seeks, muted, time: art.currentTime, volume: art.volume, mediaMuted: art.video.muted, rate: art.playbackRate, seekNotice, volumeNotice, rateNotice, resetNotice, descriptors, unreadable, played: art.played, duration: art.duration, buffered, loadedTime: art.loadedTime, loaded: art.loaded, error: art.video.error?.code || 0 }
|
|
art.destroy()
|
|
return result
|
|
})
|
|
expect(result.seeks).toEqual([[2.5, '2.5 seconds'], [3.5, 3.5], [3, 3]])
|
|
expect(result.muted).toEqual(['truthy'])
|
|
expect(result.time).toBeCloseTo(3, 2)
|
|
expect(result.volume).toBeCloseTo(0.42, 6)
|
|
expect(result.mediaMuted).toBe(true)
|
|
expect(result.rate).toBe(1)
|
|
expect(result.seekNotice).toBe('00:02 / 00:08')
|
|
expect(result.volumeNotice).toBe('Volume: 42')
|
|
expect(result.rateNotice).toBe('Rate: 1.5x')
|
|
expect(result.resetNotice).toBe('Rate: Normal')
|
|
expect(result.played).toBeCloseTo(3 / result.duration, 6)
|
|
// WebKit may empty its buffered ranges during seek; compare the actual media surface.
|
|
expect(result.loadedTime).toBe(result.buffered.at(-1) || 0)
|
|
expect(result.loaded).toBeCloseTo(result.loadedTime / result.duration, 6)
|
|
expect(result.error).toBe(0)
|
|
expect(Object.values(result.unreadable)).toEqual([true, true, true, true, true])
|
|
for (const [name, descriptor] of Object.entries(result.descriptors)) {
|
|
expect(descriptor).toEqual({
|
|
getter: !['seek', 'forward', 'backward'].includes(name),
|
|
setter: !['loaded', 'loadedTime', 'played'].includes(name),
|
|
enumerable: false,
|
|
configurable: false,
|
|
})
|
|
}
|
|
})
|
|
|
|
test(`${core}: invalid time inputs and rate no-op retain native behavior`, async ({ page }) => {
|
|
await page.goto(`/test/player.html?core=${core}&chapter=published`)
|
|
await page.evaluate(() => window.createPlayer('/test/pattern.mp4?properties=invalid'))
|
|
await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true)
|
|
const result = await page.evaluate(() => {
|
|
const { art } = window
|
|
art.currentTime = 2
|
|
const times = []
|
|
for (const input of [Number.NaN, undefined, null, '', 'invalid']) {
|
|
art.currentTime = input
|
|
times.push(art.currentTime)
|
|
}
|
|
art.notice.show = 'keep'
|
|
art.playbackRate = 1
|
|
art.playbackRate = Number.NaN
|
|
const result = { times, rate: art.playbackRate, notice: art.template.$noticeInner.textContent, noRuntimeType: window.Artplayer.PlaybackControls === undefined }
|
|
art.destroy()
|
|
return result
|
|
})
|
|
expect(result).toEqual({ times: [2, 2, 2, 2, 2], rate: 1, notice: 'keep', noRuntimeType: true })
|
|
})
|
|
}
|