mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:46:16 -08:00
169 lines
6.2 KiB
JavaScript
169 lines
6.2 KiB
JavaScript
import { expect, test } from './fixtures.js'
|
|
|
|
async function setup(page, core) {
|
|
await page.goto(`/test/player.html?core=${core}&chapter=published`)
|
|
await page.evaluate(() => window.createPlayer('/test/pattern.mp4'))
|
|
await expect.poll(() => page.evaluate(() => window.art.isReady)).toBe(true)
|
|
await page.evaluate(() => {
|
|
window.Artplayer.NOTICE_TIME = 24733
|
|
window.art.notice.destroy()
|
|
})
|
|
}
|
|
|
|
for (const core of ['published', 'candidate']) {
|
|
test(`${core}: notice updates do not call a consumer override of destroy`, async ({ page }) => {
|
|
await setup(page, core)
|
|
expect(await page.evaluate(() => {
|
|
const notice = window.art.notice
|
|
const original = notice.destroy
|
|
let calls = 0
|
|
notice.destroy = function () {
|
|
calls++
|
|
return original.call(this)
|
|
}
|
|
notice.show = 'first'
|
|
notice.show = 'second'
|
|
const implicit = calls
|
|
notice.destroy()
|
|
const explicit = calls
|
|
window.art.destroy()
|
|
return { implicit, explicit }
|
|
})).toEqual({ implicit: 0, explicit: 1 })
|
|
})
|
|
|
|
test(`${core}: notice preserves public shape, Error text and false hide semantics`, async ({ page }) => {
|
|
await setup(page, core)
|
|
expect(await page.evaluate(() => {
|
|
const art = window.art
|
|
const notice = art.notice
|
|
notice.show = new Error(' trimmed ')
|
|
const visible = notice.show
|
|
const text = art.template.$noticeInner.textContent
|
|
const timer = notice.timer
|
|
notice.show = false
|
|
const result = {
|
|
fields: Object.keys(notice),
|
|
prototype: Object.getOwnPropertyNames(Object.getPrototypeOf(notice)),
|
|
visible,
|
|
text,
|
|
hidden: !notice.show,
|
|
retained: art.template.$noticeInner.textContent,
|
|
sameTimer: timer === notice.timer,
|
|
}
|
|
notice.destroy()
|
|
art.destroy()
|
|
return result
|
|
})).toEqual({ fields: ['art', 'timer'], prototype: ['constructor', 'destroy', 'show'], visible: true, text: 'trimmed', hidden: true, retained: 'trimmed', sameTimer: true })
|
|
})
|
|
|
|
test(`${core}: notice expires naturally during real playback`, async ({ page }) => {
|
|
await setup(page, core)
|
|
await page.evaluate(() => window.art.play())
|
|
await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.1)
|
|
await page.evaluate(() => {
|
|
window.Artplayer.NOTICE_TIME = 20
|
|
window.art.notice.show = 'transient'
|
|
})
|
|
await expect.poll(() => page.evaluate(() => ({ visible: window.art.notice.show, text: window.art.template.$noticeInner.textContent }))).toEqual({ visible: false, text: '' })
|
|
expect(await page.evaluate(() => window.art.playing)).toBe(true)
|
|
await page.evaluate(() => window.art.destroy())
|
|
})
|
|
|
|
test(`${core}: manual notice destroy permits reuse and does not hide its DOM`, async ({ page }) => {
|
|
await setup(page, core)
|
|
expect(await page.evaluate(() => {
|
|
const notice = window.art.notice
|
|
notice.show = 'visible'
|
|
notice.destroy()
|
|
const visible = notice.show
|
|
const timer = notice.timer
|
|
notice.show = 'reused'
|
|
const reused = window.art.template.$noticeInner.textContent
|
|
notice.destroy()
|
|
window.art.destroy()
|
|
return { visible, timer, reused }
|
|
})).toEqual({ visible: true, timer: null, reused: 'reused' })
|
|
})
|
|
|
|
test(`${core}: destruction during notice text assignment cannot schedule a late timer`, async ({ page }) => {
|
|
await setup(page, core)
|
|
expect(await page.evaluate(() => {
|
|
const art = window.art
|
|
const notice = art.notice
|
|
const inner = art.template.$noticeInner
|
|
const descriptor = Object.getOwnPropertyDescriptor(Node.prototype, 'textContent')
|
|
Object.defineProperty(inner, 'textContent', {
|
|
configurable: true,
|
|
get() {
|
|
return descriptor.get.call(this)
|
|
},
|
|
set(value) {
|
|
descriptor.set.call(this, value)
|
|
art.destroy(false)
|
|
},
|
|
})
|
|
notice.show = 'destroy during write'
|
|
const result = { destroyed: art.isDestroy, timer: notice.timer !== null, visible: notice.show }
|
|
notice.destroy()
|
|
return result
|
|
})).toEqual({ destroyed: true, timer: core === 'published', visible: core === 'published' })
|
|
})
|
|
|
|
test(`${core}: expiry does not hide a notice installed during the clearing write`, async ({ page }) => {
|
|
await setup(page, core)
|
|
expect(await page.evaluate(() => {
|
|
const art = window.art
|
|
const inner = art.template.$noticeInner
|
|
const descriptor = Object.getOwnPropertyDescriptor(Node.prototype, 'textContent')
|
|
const original = window.setTimeout
|
|
let expire
|
|
window.setTimeout = function (callback, delay, ...args) {
|
|
if (delay === 24733)
|
|
expire = callback
|
|
return original.call(this, callback, delay, ...args)
|
|
}
|
|
art.notice.show = 'old'
|
|
Object.defineProperty(inner, 'textContent', {
|
|
configurable: true,
|
|
get() {
|
|
return descriptor.get.call(this)
|
|
},
|
|
set(value) {
|
|
descriptor.set.call(this, value)
|
|
if (value === '')
|
|
art.notice.show = 'nested'
|
|
},
|
|
})
|
|
expire()
|
|
const result = { text: inner.textContent, visible: art.notice.show }
|
|
window.setTimeout = original
|
|
art.notice.destroy()
|
|
art.destroy()
|
|
return result
|
|
})).toEqual({ text: 'nested', visible: core === 'candidate' })
|
|
})
|
|
}
|
|
|
|
test('candidate: retained callbacks and assignments cannot revive destroyed notice resources', async ({ page }) => {
|
|
await setup(page, 'candidate')
|
|
expect(await page.evaluate(() => {
|
|
const art = window.art
|
|
const original = window.setTimeout
|
|
const callbacks = []
|
|
window.setTimeout = function (callback, delay, ...args) {
|
|
if (delay === 24733)
|
|
callbacks.push(callback)
|
|
return original.call(this, callback, delay, ...args)
|
|
}
|
|
art.notice.show = 'old'
|
|
art.notice.show = 'new'
|
|
callbacks[0]()
|
|
const before = art.template.$noticeInner.textContent
|
|
art.destroy(false)
|
|
callbacks[1]()
|
|
art.notice.show = 'ignored'
|
|
window.setTimeout = original
|
|
return { before, after: art.template.$noticeInner.textContent, timer: art.notice.timer, calls: callbacks.length }
|
|
})).toEqual({ before: 'new', after: 'new', timer: null, calls: 2 })
|
|
})
|