Files
evening_detective_screen/scripts/smoke.cjs
T
2026-10-17 18:25:04 +07:00

154 lines
5.6 KiB
JavaScript
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
const assert = require('node:assert/strict')
const { app, BrowserWindow, screen } = require('electron')
const root = require('node:path').resolve(__dirname, '..')
app.setAppPath(root)
app.setPath(
'userData',
require('node:fs').mkdtempSync(
require('node:path').join(require('node:os').tmpdir(), 'screen-smoke-'),
),
)
const delay = (ms) => new Promise((r) => setTimeout(r, ms))
app.whenReady().then(() => {
const original = screen.getAllDisplays.bind(screen)
screen.getAllDisplays = () => [
...original(),
{
...original()[0],
id: 424242,
label: 'Synthetic test display',
bounds: { x: 1280, y: 0, width: 1280, height: 720 },
size: { width: 1280, height: 720 },
},
]
})
require(root + '/dist-electron/electron/main.js')
async function poll(check, label) {
for (let i = 0; i < 150; i++) {
const result = await check()
if (result) return result
await delay(100)
}
throw new Error('Timeout: ' + label)
}
app.whenReady().then(async () => {
try {
const control = await poll(() => BrowserWindow.getAllWindows()[0], 'control')
control.webContents.on('console-message', (_event, details) =>
console.log('renderer:', details.message),
)
await poll(
async () =>
!control.webContents.isLoading() &&
(await control.webContents.executeJavaScript(
'!!window.screenBridge && !!document.querySelector("h1")',
)),
'control UI',
)
const evaluate = (s) => control.webContents.executeJavaScript(s)
assert.equal(await evaluate('typeof window.require'), 'undefined')
await evaluate('window.screenBridge.show(424242)')
const output = await poll(
() => BrowserWindow.getAllWindows().find((w) => w !== control),
'output',
)
output.webContents.on('console-message', (_event, details) =>
console.log('output:', details.message),
)
await poll(
async () =>
!output.webContents.isLoading() &&
(await output.webContents.executeJavaScript(
'document.querySelector("video")?.readyState >= 1',
)),
'metadata',
)
const range = await output.webContents.executeJavaScript(
`fetch('screen-app://app/media/video', {headers: {Range: 'bytes=100-199'}}).then(async r => ({status:r.status, size:(await r.arrayBuffer()).byteLength, range:r.headers.get('content-range')}))`,
)
assert.equal(range.status, 206)
assert.equal(range.size, 100)
const command = async (id, action, media = 'audio', position = 0) => {
await evaluate(
`window.screenBridge.command(${JSON.stringify({ id, action, media, position })})`,
)
return poll(async () => {
const s = await evaluate('window.screenBridge.state()')
if (s.status === 'error') throw new Error(s.error)
return s.status !== 'pending' && s.command.id === id && s
}, id)
}
await evaluate(
`Array.from(document.querySelectorAll('button')).find(b => b.textContent.includes('Пуск с начала')).click()`,
)
await poll(async () => {
const state = await evaluate('window.screenBridge.state()')
if (state.status === 'error') throw new Error(state.error)
return state.status === 'playing'
}, 'computer UI play')
assert.equal((await command('audio-play', 'play')).status, 'playing')
assert.equal((await command('audio-pause', 'pause')).status, 'paused')
assert.equal((await command('audio-stop', 'stop')).status, 'stopped')
assert.equal((await command('video-play', 'play', 'video')).status, 'playing')
await command('video-seek', 'seek', 'video', 30)
const position = await output.webContents.executeJavaScript(
'document.querySelector("video").currentTime',
)
assert.ok(position >= 29.9 && position < 35, 'video seek actual position')
await command('video-pause', 'pause', 'video')
assert.equal(
await output.webContents.executeJavaScript('document.querySelector("audio").paused'),
true,
)
assert.equal(
await output.webContents.executeJavaScript('document.querySelector("video").paused'),
true,
)
await assert.rejects(
output.webContents.executeJavaScript(
`window.screenBridge.command({id:'forbidden', action:'play', media:'audio', position:0})`,
),
)
assert.equal(
await evaluate("document.body.textContent.includes('Телефон по локальной сети')"),
false,
)
assert.deepEqual(Object.keys(await evaluate('window.screenBridge.host()')), ['displays'])
assert.equal(await evaluate('typeof window.screenBridge.lan'), 'undefined')
assert.equal(await evaluate('typeof window.screenBridge.approve'), 'undefined')
output.close()
await evaluate('window.screenBridge.show(424242)')
const reopened = await poll(
() => BrowserWindow.getAllWindows().find((w) => w !== control),
'reopened output',
)
await poll(
async () =>
!reopened.webContents.isLoading() &&
(await reopened.webContents.executeJavaScript('!!document.querySelector("video")')),
'reopened ready',
)
assert.equal(
await reopened.webContents.executeJavaScript('document.querySelector("video").paused'),
true,
)
console.log(
'SCREEN_SMOKE_PASS',
JSON.stringify({
range,
seek: position,
samples: (await evaluate('window.screenBridge.state()')).samples,
electron: process.versions.electron,
}),
)
app.exit(0)
} catch (error) {
console.error('SCREEN_SMOKE_FAIL', error)
app.exit(1)
}
})
setTimeout(() => {
console.error('Global timeout')
app.exit(1)
}, 45000)