/* * 冒烟测试:真实浏览器加载演示页,验证核心功能 * 覆盖:播放器初始化、播放/暂停、seek 跳转、点击进度条、皮肤文件加载 * 用法:npm test(需要先 npm run build) */ const { chromium } = require('playwright'); const { spawn } = require('child_process'); const path = require('path'); const PORT = 8931; let failed = 0; function check(name, cond, detail) { if (cond) { console.log(' ✓ ' + name); } else { failed++; console.error(' ✗ ' + name + (detail ? ' —— ' + detail : '')); } } (async () => { const server = spawn('node', [path.join(__dirname, 'serve.js'), String(PORT)], { stdio: 'ignore' }); await new Promise(r => setTimeout(r, 800)); const browser = await chromium.launch(); const page = await browser.newPage(); const errors = []; page.on('pageerror', e => errors.push(e.message)); await page.goto(`http://localhost:${PORT}/index.html`); await page.waitForTimeout(2500); const video = () => page.evaluate(() => { const v = document.querySelector('video'); return v ? { duration: v.duration, currentTime: v.currentTime, paused: v.paused } : null; }); console.log('初始化'); check('全局 MoePlayer 存在', await page.evaluate(() => typeof window.MoePlayer === 'function')); const v0 = await video(); check('video 元素已创建', !!v0); check('元数据已加载(duration>0)', v0 && v0.duration > 0, JSON.stringify(v0)); console.log('播放控制'); await page.evaluate(() => player.play()); await page.waitForTimeout(1500); const v1 = await video(); check('播放中', v1 && !v1.paused && v1.currentTime > 0.5, JSON.stringify(v1)); await page.evaluate(() => player.pause()); await page.waitForTimeout(300); check('暂停', (await video()).paused); console.log('seek'); await page.evaluate(() => player.seek(20)); await page.waitForTimeout(800); const v2 = await video(); check('seek(20) 生效', v2.currentTime >= 19 && v2.currentTime <= 22, 'currentTime=' + v2.currentTime); console.log('进度条点击'); const rect = await page.evaluate(() => { const r = document.querySelector('.moe-bar-progress-bg').getBoundingClientRect(); return { x: r.x, y: r.y, w: r.width, h: r.height }; }); await page.mouse.click(rect.x + rect.w * 0.7, rect.y + rect.h / 2); await page.waitForTimeout(800); const v3 = await video(); const expect3 = v0.duration * 0.7; check('点击 70% 位置跳转', Math.abs(v3.currentTime - expect3) < 2.5, `currentTime=${v3.currentTime},期望≈${expect3}`); console.log('皮肤'); for (const css of ['moeplayer.css', 'moeplayer.red.css', 'moeplayer.ixigua.css']) { const resp = await page.request.get(`http://localhost:${PORT}/moeplayer/css/${css}`); check(css + ' 可加载', resp.status() === 200); } check('无页面 JS 错误', errors.length === 0, errors.join(' | ')); await browser.close(); server.kill(); console.log(failed === 0 ? '\n全部通过' : `\n${failed} 项失败`); process.exit(failed === 0 ? 0 : 1); })().catch(e => { console.error(e); process.exit(1); });