import { spawn } from 'node:child_process'
import { createHash } from 'node:crypto'
import fs from 'node:fs'
import path from 'node:path'
import process from 'node:process'
import { fileURLToPath, pathToFileURL } from 'node:url'
import { expect, test } from '@playwright/test'
import { startDevServer } from '../../scripts/library/server.ts'
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 })
}
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'), `
`)
const module = pathToFileURL(path.join(root, 'scripts/dev.js')).href
const code = `process.on('message', () => process.emit('SIGTERM'));
process.argv = [process.execPath, 'fixture.js', '${name}', '--no-open'];
await import(${JSON.stringify(module)});
process.disconnect();`
const launcher = path.join(directory, 'launch.mjs')
fs.writeFileSync(launcher, code)
const child = spawn(process.execPath, [launcher], { cwd: directory, env: { ...process.env, ARTPLAYER_DEV_PORT: '0' }, windowsHide: true, stdio: ['ignore', 'pipe', 'pipe', 'ipc'] })
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()
const url = /Demo: (http:\/\/localhost:\d+)/.exec(output)[1]
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('