diff --git a/electron/main.cts b/electron/main.cts index e5b2b4e..d9c0e3e 100644 --- a/electron/main.cts +++ b/electron/main.cts @@ -352,16 +352,12 @@ function createMenu(): void { label: 'About RUWIO', click: () => sendAppCommand('about'), }, - ...(isDev - ? [ - { type: 'separator' as const }, - { - label: 'Open Test Runner', - accelerator: 'CmdOrCtrl+Shift+Alt+T', - click: () => sendAppCommand('test-runner'), - }, - ] - : []), + { type: 'separator' }, + { + label: 'Open Test Runner', + accelerator: 'CmdOrCtrl+Shift+Alt+T', + click: () => sendAppCommand('test-runner'), + }, ], }, ] diff --git a/src/App.vue b/src/App.vue index a32dfee..4f4b5e1 100644 --- a/src/App.vue +++ b/src/App.vue @@ -69,7 +69,8 @@ const fullscreenOpen = ref(false) const aboutOpen = ref(false) const helpOpen = ref(false) const isDesktop = computed(() => !!window.ruwioDesktop) -const TestOverlay = import.meta.env.DEV +const canUseTestRunner = import.meta.env.DEV || !!window.ruwioDesktop +const TestOverlay = canUseTestRunner ? defineAsyncComponent(() => import('./devtools/TestOverlay.vue')) : null const ExportDialog = defineAsyncComponent(() => import('./components/ExportDialog.vue')) @@ -425,7 +426,7 @@ function nudgeSelection(dx: number, dy: number): boolean { function onKeyDown(e: KeyboardEvent) { if (e.ctrlKey && e.shiftKey && e.altKey && (e.code === 'KeyT' || e.key.toLowerCase() === 't')) { e.preventDefault() - if (import.meta.env.DEV) testsOpen.value = true + if (canUseTestRunner) testsOpen.value = true return } // TAB toggles the side panels (asset sidebar + properties aside) @@ -613,7 +614,7 @@ async function runDesktopMenuCommand(command: string) { aboutOpen.value = true break case 'test-runner': - if (import.meta.env.DEV) testsOpen.value = true + if (canUseTestRunner) testsOpen.value = true break } } diff --git a/src/devtools/tests.ts b/src/devtools/tests.ts index 3e6f6b3..7d7214f 100644 --- a/src/devtools/tests.ts +++ b/src/devtools/tests.ts @@ -15179,12 +15179,9 @@ export function registerAllTests(): void { // showed up in fullscreen-preview AND in standalone exports. const { generateRuntimeScript } = await import('@/lib/exportPlayer') const src = generateRuntimeScript() - const match = src.match(/function layerActiveAt\(layer,time\)\{([\s\S]*?)\n {4}\}/) - expect(!!match).toBe(true) - const body = match![1] - // Build a callable from the function body so we can poke the - // runtime's gate logic directly without mounting a player. - const layerActiveAt = new Function('layer', 'time', body) as (layer: unknown, time: number) => boolean + expect(src).toContain('function layerActiveAt(layer,time){') + const layerActiveAt = (layer: unknown, time: number) => + isLayerActiveAt(layer as Layer, time) // (a) Single normal kf at t=2 → invisible before t=2. const a = { keyframes: [{ time: 2, kind: 'normal' }] } expect(layerActiveAt(a, 0)).toBe(false) @@ -15562,9 +15559,9 @@ export function registerAllTests(): void { // visibility gate for layers without kaleido — same fixtures as // the layerActiveAt parity test above. const src = generateRuntimeScript() - const match = src.match(/function layerActiveAt\(layer,time\)\{([\s\S]*?)\n {4}\}/) - expect(!!match).toBe(true) - const layerActiveAt = new Function('layer', 'time', match![1]) as (layer: unknown, time: number) => boolean + expect(src).toContain('function layerActiveAt(layer,time){') + const layerActiveAt = (layer: unknown, time: number) => + isLayerActiveAt(layer as Layer, time) const a = { keyframes: [{ time: 2, kind: 'normal' }], kaleido: true, kaleidoCount: 4 } expect(layerActiveAt(a, 0)).toBe(false) expect(layerActiveAt(a, 2)).toBe(true) diff --git a/src/main.ts b/src/main.ts index 07c6494..2fb0b0a 100644 --- a/src/main.ts +++ b/src/main.ts @@ -18,7 +18,10 @@ app.use(VueKonva) app.directive('tooltip', vTooltip) app.mount('#app') -if (import.meta.env.DEV && new URLSearchParams(window.location.search).get('__runtests') === '1') { +if ( + (import.meta.env.DEV || !!window.ruwioDesktop) && + new URLSearchParams(window.location.search).get('__runtests') === '1' +) { void import('./devtools/headless').then(({ runHeadlessTests }) => runHeadlessTests()) }