mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-09 03:46:16 -08:00
80 lines
5.9 KiB
JavaScript
80 lines
5.9 KiB
JavaScript
import fs from 'node:fs'
|
|
import { hash } from '../../refactor/scripts/releases.mjs'
|
|
import { browserCandidate } from '../helpers/browser-candidate.js'
|
|
import { expect, test } from './fixtures.js'
|
|
import { skippableVast } from './vast-fixture.mjs'
|
|
|
|
// eslint-disable-next-line antfu/no-top-level-await -- Select the complete source or installed SDK bundle before discovery.
|
|
const { code, provenance } = await browserCandidate('artplayer-plugin-vast')
|
|
|
|
for (const compatibility of [undefined, 'workspace-1.2']) {
|
|
test(`real IMA ${compatibility || 'npm-default'} requests playUrl and skips through the SDK button`, async ({ page }, testInfo) => {
|
|
await page.goto('/test/player.html?core=candidate')
|
|
await page.addScriptTag({ content: code })
|
|
await testInfo.attach('native-vast-inputs', { contentType: 'application/json', body: JSON.stringify({ provenance, sourceSha256: hash(code), compatibility: compatibility || 'npm-default', scope: 'Complete glomex bundle with real remote Google IMA; no SDK substitution.' }) })
|
|
await page.evaluate(async (compatibility) => {
|
|
window.createPlayer('/assets/sample/video.mp4')
|
|
window.skipEvents = []
|
|
await window.art.plugins.add(window.artplayerPluginVast((context) => {
|
|
window.skipContext = context
|
|
const player = context.init()
|
|
for (const type of ['AdStarted', 'AdComplete', 'AdSkipped', 'AdSkippableStateChanged', 'AdContentPauseRequested', 'AdContentResumeRequested', 'AdError']) {
|
|
player.addEventListener(type, event => window.skipEvents.push({ type, at: performance.now(), time: window.art.currentTime, paused: window.art.template.$video.paused, skipOffset: event.detail?.ad?.getSkipTimeOffset(), error: event.detail?.error?.message }))
|
|
}
|
|
}, compatibility ? { compatibility } : undefined))
|
|
}, compatibility)
|
|
await page.locator('#play').click()
|
|
await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(0.5)
|
|
await page.evaluate(() => {
|
|
document.querySelector('#play').onclick = () => window.skipContext.playUrl(`${location.origin}/test/vast-skippable.xml`)
|
|
})
|
|
const beforeAd = await page.evaluate(() => window.art.currentTime)
|
|
const responsePromise = page.waitForResponse(response => response.url().endsWith('/test/vast-skippable.xml'), { timeout: 7000 })
|
|
await page.locator('#play').click()
|
|
const response = await responsePromise
|
|
expect(response.status()).toBe(200)
|
|
expect(response.headers()['content-type']).toBe('application/xml')
|
|
expect(['http://imasdk.googleapis.com', 'https://imasdk.googleapis.com']).toContain(response.headers()['access-control-allow-origin'])
|
|
const xml = await response.text()
|
|
expect(xml).toBe(skippableVast(new URL(page.url()).origin))
|
|
await testInfo.attach('native-vast-skip.xml', { contentType: 'application/xml', body: xml })
|
|
await expect.poll(() => page.evaluate(() => window.skipEvents.some(event => event.type === 'AdStarted'))).toBe(true)
|
|
await expect.poll(() => page.evaluate(() => [...document.querySelectorAll('video')].some(video => video.currentSrc.includes('/test/pattern.mp4?skippable=1') && video.videoWidth > 0 && video.currentTime > 0))).toBe(true)
|
|
expect(await page.evaluate(() => window.art.template.$video.paused)).toBe(true)
|
|
await testInfo.attach('native-vast-before-skip.png', { contentType: 'image/png', body: await page.screenshot() })
|
|
await expect.poll(() => page.evaluate(() => window.skipEvents.some(event => event.type === 'AdSkippableStateChanged'))).toBe(true)
|
|
let skipButton
|
|
await expect.poll(async () => {
|
|
for (const frame of page.frames()) {
|
|
const button = frame.getByRole('button', { name: /skip ad/i })
|
|
if (await button.count() === 1 && await button.isVisible() && await button.isEnabled()) {
|
|
skipButton = button
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}).toBe(true)
|
|
await testInfo.attach('native-vast-skip-button.png', { contentType: 'image/png', body: await page.screenshot() })
|
|
await skipButton.click()
|
|
await expect.poll(() => page.evaluate(() => window.skipEvents.filter(event => event.type === 'AdSkipped').length)).toBe(1)
|
|
await expect.poll(() => page.evaluate(() => window.skipEvents.some(event => event.type === 'AdContentResumeRequested'))).toBe(true)
|
|
await expect(page.locator('[id^="art-"]')).toBeHidden()
|
|
await expect.poll(() => page.evaluate(() => window.art.currentTime)).toBeGreaterThan(beforeAd + 0.2)
|
|
const state = await page.evaluate(() => ({ events: window.skipEvents, time: window.art.currentTime, paused: window.art.template.$video.paused, imaVersion: window.google.ima.VERSION }))
|
|
expect(state.paused).toBe(false)
|
|
expect(state.events.filter(event => event.type === 'AdError' || event.type === 'AdComplete')).toEqual([])
|
|
await testInfo.attach('native-vast-skip', { contentType: 'application/json', body: JSON.stringify({ sourceSha256: hash(code), provenance, xmlSha256: hash(xml), mediaSha256: hash(fs.readFileSync('test/browser/media/pattern.mp4')), compatibility: compatibility || 'npm-default', beforeAd, ...state }) })
|
|
await page.evaluate(() => window.art.destroy())
|
|
await expect(page.locator('[id^="art-"]')).toHaveCount(0)
|
|
})
|
|
}
|
|
|
|
test.afterEach(async ({ page }, testInfo) => {
|
|
await testInfo.attach('native-vast-skip-final', { contentType: 'application/json', body: JSON.stringify(await page.evaluate(() => ({ events: window.skipEvents, imaVersion: window.google?.ima?.VERSION, videos: [...document.querySelectorAll('video')].map(video => ({ src: video.currentSrc, time: video.currentTime, width: video.videoWidth, paused: video.paused })) }))) })
|
|
for (const [index, frame] of page.frames().entries()) {
|
|
if (frame !== page.mainFrame())
|
|
await testInfo.attach(`native-vast-frame-${index}`, { contentType: 'text/plain', body: await frame.locator('body').ariaSnapshot().catch(error => String(error)) })
|
|
}
|
|
await page.evaluate(() => window.art?.destroy())
|
|
})
|