mirror of
https://github.com/zhw2590582/ArtPlayer.git
synced 2026-10-08 19:06:15 -08:00
102 lines
4.3 KiB
JavaScript
102 lines
4.3 KiB
JavaScript
import { spawn } from 'node:child_process'
|
|
import fs from 'node:fs'
|
|
import net from 'node:net'
|
|
import path from 'node:path'
|
|
import process from 'node:process'
|
|
import { fileURLToPath, pathToFileURL } from 'node:url'
|
|
import { expect, test } from '@playwright/test'
|
|
|
|
const root = fileURLToPath(new URL('../../', import.meta.url))
|
|
const cache = path.join(root, 'refactor/.cache')
|
|
|
|
function removeFixture(directory) {
|
|
if (fs.realpathSync(directory) !== directory || path.dirname(directory) !== fs.realpathSync(cache))
|
|
throw new Error(`Refusing redirected fixture cleanup: ${directory}`)
|
|
fs.rmSync(directory, { recursive: true, force: true })
|
|
}
|
|
|
|
async function freePort() {
|
|
const server = net.createServer()
|
|
await new Promise((resolve, reject) => {
|
|
server.once('error', reject)
|
|
server.listen(0, resolve)
|
|
})
|
|
const port = server.address().port
|
|
await new Promise(resolve => server.close(resolve))
|
|
return port
|
|
}
|
|
|
|
test('typed development builds real assets and workers, watches edits and recovers from compilation errors', async ({ page }, testInfo) => {
|
|
test.setTimeout(60000)
|
|
const directory = fs.mkdtempSync(path.join(cache, 'library-development-'))
|
|
const name = 'artplayer-plugin-build-probe'
|
|
const source = path.join(directory, 'packages', name, 'src')
|
|
fs.mkdirSync(source, { recursive: true })
|
|
fs.cpSync(path.join(root, 'refactor/fixtures/build'), source, { recursive: true })
|
|
fs.writeFileSync(path.join(source, '../package.json'), JSON.stringify({ name, version: '1.0.0' }))
|
|
fs.mkdirSync(path.join(directory, 'docs'))
|
|
fs.writeFileSync(path.join(directory, 'docs/index.html'), `<!doctype html><html><body><main></main>
|
|
<script src="/uncompiled/${name}/index.js"></script><script>
|
|
window.probe = artplayerPluginBuildProbe();
|
|
document.querySelector('main').textContent = String(probe.value);
|
|
</script></body></html>`)
|
|
const port = await freePort()
|
|
const url = `http://localhost:${port}`
|
|
const module = pathToFileURL(path.join(root, 'scripts/library/development.ts')).href
|
|
const code = `import { runDevelop } from ${JSON.stringify(module)};
|
|
process.argv = [process.execPath, 'fixture.js', '${name}', '--no-open'];
|
|
await runDevelop({port:${port}});`
|
|
const launcher = path.join(directory, 'launch.mjs')
|
|
fs.writeFileSync(launcher, code)
|
|
const child = spawn(process.execPath, [launcher], { cwd: directory, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe'] })
|
|
let output = ''
|
|
child.stdout.on('data', (data) => {
|
|
output += data
|
|
})
|
|
child.stderr.on('data', (data) => {
|
|
output += data
|
|
})
|
|
const exited = new Promise(resolve => child.once('exit', resolve))
|
|
try {
|
|
await expect.poll(() => output, { timeout: 20000 }).toContain('Watching')
|
|
expect(child.exitCode).toBeNull()
|
|
await page.goto(url)
|
|
await expect(page.locator('main')).toHaveText('42')
|
|
expect(await page.evaluate(() => window.probe.css)).toContain('#123abc')
|
|
expect(await page.evaluate(() => window.probe.svg)).toContain('<svg')
|
|
const workerResult = await page.evaluate(() => new Promise((resolve, reject) => {
|
|
const worker = window.probe.createWorker()
|
|
worker.onmessage = ({ data }) => {
|
|
worker.terminate()
|
|
resolve(data)
|
|
}
|
|
worker.onerror = (error) => {
|
|
worker.terminate()
|
|
reject(new Error(error.message))
|
|
}
|
|
worker.postMessage(21)
|
|
}))
|
|
expect(workerResult).toBe(22)
|
|
const entry = path.join(source, 'index.ts')
|
|
const original = fs.readFileSync(entry, 'utf8')
|
|
const before = output.length
|
|
fs.writeFileSync(entry, original.replace('add(20, 22)', 'add(20, 23)'))
|
|
await expect.poll(() => output.slice(before), { timeout: 15000 }).toContain('Built in')
|
|
await expect(page.locator('main')).toHaveText('43')
|
|
const valid = output.length
|
|
fs.writeFileSync(entry, 'export default function broken( {')
|
|
await expect.poll(() => output.slice(valid), { timeout: 15000 }).toContain('Build error')
|
|
expect(child.exitCode).toBeNull()
|
|
const failed = output.length
|
|
fs.writeFileSync(entry, original.replace('add(20, 22)', 'add(20, 24)'))
|
|
await expect.poll(() => output.slice(failed), { timeout: 15000 }).toContain('Built in')
|
|
await expect(page.locator('main')).toHaveText('44')
|
|
}
|
|
finally {
|
|
await testInfo.attach('development-server.log', { body: output, contentType: 'text/plain' })
|
|
child.kill()
|
|
await exited
|
|
removeFixture(directory)
|
|
}
|
|
})
|