mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:46:16 -08:00
133 lines
5.7 KiB
JavaScript
133 lines
5.7 KiB
JavaScript
import { expect, test } from './fixtures.js'
|
|
|
|
async function setup(page, core) {
|
|
await page.addInitScript(() => Object.defineProperty(navigator, 'userAgent', { configurable: true, value: 'ArtPlayer Android long-press fixture' }))
|
|
await page.goto(`/test/player.html?core=${core}&chapter=published`)
|
|
await page.evaluate(() => {
|
|
window.Artplayer.FAST_FORWARD_TIME = 20
|
|
window.art = new window.Artplayer({ container: '.player', url: '/test/pattern.mp4', muted: true, fastForward: true })
|
|
window.touch = (type, count = 1) => {
|
|
const event = new Event(type, { bubbles: true, cancelable: true })
|
|
Object.defineProperty(event, 'touches', { value: Array.from({ length: count }, (_, identifier) => ({ identifier, pageX: 50, pageY: 50, clientX: 50, clientY: 50 })) })
|
|
window.art.template.$video.dispatchEvent(event)
|
|
}
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true)
|
|
await page.evaluate(() => window.art.play())
|
|
await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.1)
|
|
await page.evaluate(() => {
|
|
window.art.playbackRate = 1.5
|
|
})
|
|
}
|
|
|
|
for (const core of ['published', 'candidate']) {
|
|
test(`${core}: native source reset retains its default playback rate behavior`, async ({ page }) => {
|
|
await setup(page, core)
|
|
await page.evaluate(() => {
|
|
window.art.url = '/test/pattern.mp4?reset=1'
|
|
})
|
|
await expect.poll(() => page.evaluate(() => window.art.playbackRate)).toBe(1)
|
|
expect(await page.evaluate(() => window.art.template.$video.defaultPlaybackRate)).toBe(1)
|
|
await page.evaluate(() => window.art.destroy())
|
|
})
|
|
|
|
test(`${core}: long press accelerates real playback and restores its prior rate`, async ({ page }) => {
|
|
await setup(page, core)
|
|
expect(await page.evaluate(() => Object.keys(window.art.plugins.fastForward))).toEqual(['name', 'state'])
|
|
await page.evaluate(() => window.touch('touchstart'))
|
|
await expect.poll(() => page.evaluate(() => window.art.plugins.fastForward.state)).toBe(true)
|
|
expect(await page.evaluate(() => window.art.playbackRate)).toBe(3)
|
|
await page.evaluate(() => window.touch('touchend', 0))
|
|
expect(await page.evaluate(() => ({ state: window.art.plugins.fastForward.state, rate: window.art.playbackRate }))).toEqual({ state: false, rate: 1.5 })
|
|
await page.evaluate(() => window.art.destroy())
|
|
})
|
|
|
|
test(`${core}: touchcancel releases an active long press`, async ({ page }) => {
|
|
await setup(page, core)
|
|
await page.evaluate(() => window.touch('touchstart'))
|
|
await expect.poll(() => page.evaluate(() => window.art.plugins.fastForward.state)).toBe(true)
|
|
await page.evaluate(() => window.touch('touchcancel', 0))
|
|
expect(await page.evaluate(() => ({ state: window.art.plugins.fastForward.state, rate: window.art.playbackRate }))).toEqual({ state: core === 'published', rate: core === 'published' ? 3 : 1.5 })
|
|
await page.evaluate(() => {
|
|
window.touch('touchend', 0)
|
|
window.art.destroy()
|
|
})
|
|
})
|
|
}
|
|
|
|
for (const action of ['lock', 'pause', 'source', 'destroy']) {
|
|
test(`candidate: ${action} restores the active long-press rate`, async ({ page }) => {
|
|
await setup(page, 'candidate')
|
|
await page.evaluate(() => window.touch('touchstart'))
|
|
await expect.poll(() => page.evaluate(() => window.art.plugins.fastForward.state)).toBe(true)
|
|
await page.evaluate((action) => {
|
|
const art = window.art
|
|
if (action === 'lock') {
|
|
art.isLock = true
|
|
art.emit('lock', true)
|
|
}
|
|
else if (action === 'pause') {
|
|
art.pause()
|
|
}
|
|
else if (action === 'source') {
|
|
const video = art.template.$video
|
|
const rate = Object.getOwnPropertyDescriptor(HTMLMediaElement.prototype, 'playbackRate')
|
|
window.restoredRates = []
|
|
Object.defineProperty(video, 'playbackRate', {
|
|
configurable: true,
|
|
get() {
|
|
return rate.get.call(this)
|
|
},
|
|
set(value) {
|
|
window.restoredRates.push(value)
|
|
rate.set.call(this, value)
|
|
},
|
|
})
|
|
art.url = '/test/pattern.mp4?replacement=1'
|
|
}
|
|
else {
|
|
art.destroy(false)
|
|
}
|
|
}, action)
|
|
await expect.poll(() => page.evaluate(() => ({ state: window.art.plugins.fastForward.state, rate: window.art.playbackRate }))).toEqual({ state: false, rate: action === 'source' ? 1 : 1.5 })
|
|
if (action === 'source')
|
|
expect(await page.evaluate(() => window.restoredRates)).toEqual([1.5])
|
|
await page.evaluate(() => window.art.destroy())
|
|
})
|
|
}
|
|
|
|
test('candidate: repeated pending touches own a single timer which destruction cancels', async ({ page }) => {
|
|
await setup(page, 'candidate')
|
|
expect(await page.evaluate(() => {
|
|
const art = window.art
|
|
art.constructor.FAST_FORWARD_TIME = 24734
|
|
const set = window.setTimeout
|
|
const clear = window.clearTimeout
|
|
const pending = new Set()
|
|
const callbacks = []
|
|
window.setTimeout = function (callback, delay, ...args) {
|
|
const timer = set.call(this, callback, delay, ...args)
|
|
if (delay === 24734) {
|
|
pending.add(timer)
|
|
callbacks.push(callback)
|
|
}
|
|
return timer
|
|
}
|
|
window.clearTimeout = function (timer) {
|
|
pending.delete(timer)
|
|
return clear.call(this, timer)
|
|
}
|
|
window.touch('touchstart')
|
|
window.touch('touchstart')
|
|
const scheduled = pending.size
|
|
art.destroy(false)
|
|
const resetRate = art.playbackRate
|
|
for (const callback of callbacks)
|
|
callback()
|
|
const result = { scheduled, remaining: pending.size, state: art.plugins.fastForward.state, resetRate, rate: art.playbackRate }
|
|
window.setTimeout = set
|
|
window.clearTimeout = clear
|
|
return result
|
|
})).toEqual({ scheduled: 1, remaining: 0, state: false, resetRate: 1, rate: 1 })
|
|
})
|