Files
ArtPlayer/test/browser/plugins.spec.js
T

95 lines
4.3 KiB
JavaScript

import { expect, test } from './fixtures.js'
for (const core of ['published', 'candidate']) {
test(`${core}: late plugin registration preserves fulfillment without reviving a closed candidate`, async ({ page }) => {
await page.goto(`/test/player.html?core=${core}&chapter=published`)
const result = await page.evaluate(async () => {
const container = document.createElement('div')
document.body.append(container)
const art = new window.Artplayer({ container, url: '' })
const registry = art.plugins
let resolve
let disposed = 0
const pending = registry.add(() => new Promise(done => resolve = done))
art.destroy()
resolve({ name: 'late', destroy() {
disposed++
} })
const fulfilled = await pending
const before = registry.id
let calls = 0
let error = ''
try {
registry.add(() => {
calls++
return { name: 'afterClose' }
})
}
catch (caught) {
error = caught.message
}
return { same: fulfilled === registry, late: Object.hasOwn(registry, 'late'), disposed, calls, error, idDelta: registry.id - before }
})
expect(result).toEqual(core === 'published'
? { same: true, late: true, disposed: 0, calls: 1, error: '', idDelta: 1 }
: { same: true, late: false, disposed: 0, calls: 0, error: 'Cannot add a plugin after ArtPlayer is destroyed', idDelta: 0 })
})
}
test('candidate: a plugin that closes construction prevents subsequent factories', async ({ page }) => {
await page.goto('/test/player.html?core=candidate&chapter=published')
const result = await page.evaluate(() => {
const container = document.createElement('div')
document.body.append(container)
let calls = 0
const art = new window.Artplayer({ container, url: '', plugins: [(art) => {
art.destroy()
return { name: 'closing' }
}, () => {
calls++
return { name: 'never' }
}] })
return { calls, id: art.plugins.id, closing: Object.hasOwn(art.plugins, 'closing'), destroyed: art.isDestroy, instances: window.Artplayer.instances.length }
})
expect(result).toEqual({ calls: 0, id: 1, closing: false, destroyed: true, instances: 0 })
})
test('candidate: constructor-owned rejection is reported once without an unhandled rejection', async ({ page }) => {
const warnings = []
page.on('console', (message) => {
if (message.type() === 'warning' && message.text().startsWith('Failed to initialize ArtPlayer plugin:'))
warnings.push(message.args()[1].evaluate(error => ({ message: error.message, same: error === window.pluginFailure })))
})
await page.goto('/test/player.html?core=candidate&chapter=published')
await page.evaluate(() => {
const container = document.createElement('div')
document.body.append(container)
window.pluginFailure = new Error('owned-plugin-rejection')
window.art = new window.Artplayer({ container, url: '', plugins: [() => Promise.reject(window.pluginFailure)] })
})
await expect.poll(() => warnings.length).toBe(1)
expect(await warnings[0]).toEqual({ message: 'owned-plugin-rejection', same: true })
await page.evaluate(() => window.art.destroy())
})
test.describe('mobile user-agent builtin selection (not physical-device evidence)', () => {
test.use({ userAgent: 'Mozilla/5.0 (Linux; Android 13) AppleWebKit/537.36 Chrome/120.0.0.0 Mobile Safari/537.36' })
for (const core of ['published', 'candidate']) {
test(`${core}: builtin order and live exclusions precede user plugins`, async ({ page }) => {
await page.goto(`/test/player.html?core=${core}&chapter=published`)
const results = await page.evaluate(() => [false, true].map((isLive) => {
const container = document.createElement('div')
document.body.append(container)
const art = new window.Artplayer({ container, url: '', isLive, miniProgressBar: true, lock: true, autoPlayback: true, autoOrientation: true, fastForward: true, plugins: [() => ({ name: 'user' })] })
const names = Object.getOwnPropertyNames(art.plugins).filter(name => !['art', 'id'].includes(name))
art.destroy()
return names
}))
expect(results).toEqual([
['mini-progress-bar', 'lock', 'auto-playback', 'autoOrientation', 'fastForward', 'user'],
['lock', 'autoOrientation', 'user'],
])
})
}
})