diff --git a/scripts/smoke.cjs b/scripts/smoke.cjs index fbfc453..6e984e8 100644 --- a/scripts/smoke.cjs +++ b/scripts/smoke.cjs @@ -260,6 +260,8 @@ app.whenReady().then(async () => { } assert.equal(await evaluate('typeof window.require'), 'undefined') assert.equal((await evaluate('window.screenBridge.packages()')).length, 1) + if (process.argv.includes('--intro-waveform')) + await evaluate(`window.screenBridge.selectPackage(${JSON.stringify(offlinePackage.key)})`) await evaluate(`window.screenBridge.show(${targetDisplay.id})`) let output = await poll( () => BrowserWindow.getAllWindows().find((w) => w.webContents.getURL() === 'screen-app://app/index.html?output=1'), @@ -269,6 +271,48 @@ app.whenReady().then(async () => { BrowserWindow.getAllWindows() .find((w) => w.webContents.getURL() === 'screen-app://app/index.html?output=1') .webContents.executeJavaScript(source) + if (process.argv.includes('--intro-waveform')) { + await command({ action: 'step', index: 1 }) + await poll(() => inspect('document.querySelector(".intro-waveform")?.getAttribute("aria-valuenow") === "0"'), 'intro waveform starts empty') + assert.equal(await inspect('document.querySelectorAll(".intro-recording button,.intro-recording input").length'), 0) + await command({ action: 'play', channel: 'main' }) + await command({ action: 'seek', channel: 'main', position: 15 }) + await command({ action: 'pause', channel: 'main' }) + await poll(() => inspect('Number(document.querySelector(".intro-waveform").getAttribute("aria-valuenow")) >= 24'), 'intro progress follows seek') + const pausedTime = await inspect('document.querySelector(".intro-time").textContent') + await delay(400) + assert.equal(await inspect('document.querySelector(".intro-time").textContent'), pausedTime) + writeFileSync('/tmp/screen-intro-waveform.png', (await output.webContents.capturePage()).toPNG()) + const pausedPosition = await inspect('document.querySelector("audio[data-channel=main-audio]").currentTime') + await command({ action: 'resume', channel: 'main' }) + await poll(() => inspect(`document.querySelector('audio[data-channel=main-audio]').currentTime > ${pausedPosition + 0.3}`), 'intro resumes') + await command({ action: 'pause', channel: 'main' }) + output.webContents.enableDeviceEmulation({ screenPosition: 'desktop', screenSize: { width: 320, height: 240 }, viewSize: { width: 320, height: 240 }, deviceScaleFactor: 1, scale: 1 }) + await poll(() => inspect('window.innerWidth === 320 && window.innerHeight === 240'), 'small output viewport') + assert.ok(await inspect('(() => { const r = document.querySelector(".intro-recording").getBoundingClientRect(); return r.width <= 320 && r.height <= 240 })()')) + output.webContents.disableDeviceEmulation() + await command({ action: 'replay', channel: 'main' }) + await poll(() => inspect('Number(document.querySelector(".intro-waveform").getAttribute("aria-valuenow")) < 5'), 'intro replay resets progress') + await command({ action: 'seek', channel: 'main', position: 59.7 }) + await poll(async () => (await state()).channels.main.status === 'ended', 'intro audio ends') + await poll(() => inspect('document.querySelector(".intro-waveform").getAttribute("aria-valuenow") === "100"'), 'intro finishes filled') + await command({ action: 'step', index: 2 }) + await poll(() => inspect('!document.querySelector(".intro-recording")'), 'waveform hidden in other modes') + await command({ action: 'step', index: 1 }) + await poll(() => inspect('document.querySelector(".intro-waveform")?.getAttribute("aria-valuenow") === "0"'), 'return to intro resets progress') + await inspect('const a = document.querySelector("audio[data-channel=main-audio]"); Object.defineProperty(a, "duration", { value: NaN, configurable: true }); a.dispatchEvent(new Event("durationchange"))') + await poll(() => inspect('document.querySelector(".intro-time").textContent === "00:00 / —"'), 'unknown duration') + await inspect('delete document.querySelector("audio[data-channel=main-audio]").duration') + await evaluate('window.screenBridge.closeOutput()') + await evaluate('window.screenBridge.selectPackage(null)') + await evaluate(`window.screenBridge.show(${targetDisplay.id})`) + await poll(() => BrowserWindow.getAllWindows().some((w) => w.webContents.getURL() === 'screen-app://app/index.html?output=1' && !w.webContents.isLoading()), 'new output ready') + await command({ action: 'mode', mode: 2 }) + await poll(() => inspect('document.querySelector(".intro-waveform")?.getAttribute("aria-valuenow") === "0"'), 'new game starts empty') + console.log('SCREEN_INTRO_WAVEFORM_PASS') + app.exit(0) + return + } await poll(async () => (await state()).channels.main.status === 'stopped', 'fixture prepared') if (process.platform === 'linux') assert.equal(app.commandLine.getSwitchValue('ozone-platform'), 'x11') diff --git a/src/components/OutputPage.vue b/src/components/OutputPage.vue index 2f73d41..9649869 100644 --- a/src/components/OutputPage.vue +++ b/src/components/OutputPage.vue @@ -1,9 +1,10 @@