mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-17 10:01:20 -08:00
refactor(core): CORE-08 type plugin registration and guard closed instances
This commit is contained in:
1 parent
f9707bad71
commit
874dac9f22
36 files changed
+2865
-142
No files matched your search
@@ -0,0 +1,94 @@
|
||||
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'],
|
||||
])
|
||||
})
|
||||
}
|
||||
})
|
||||
Reference in new issue
Block a user