From e5edc7ee10f9d7089e5e6f2ede04e4b6494d0fb5 Mon Sep 17 00:00:00 2001 From: Francesco Bonacci Date: Sun, 12 Jul 2026 15:19:24 -0500 Subject: [PATCH] test(cua-driver): restore shared fixture journals --- .../apps/cross-platform/electron/build.sh | 7 +- .../apps/cross-platform/electron/main.js | 76 +++++++++++++++++-- .../apps/cross-platform/electron/preload.js | 48 ++++++++++++ .../tauri/src-tauri/src/main.rs | 7 ++ 4 files changed, 130 insertions(+), 8 deletions(-) create mode 100644 libs/cua-driver/tests/fixtures/apps/cross-platform/electron/preload.js diff --git a/libs/cua-driver/tests/fixtures/apps/cross-platform/electron/build.sh b/libs/cua-driver/tests/fixtures/apps/cross-platform/electron/build.sh index bf03e88064..b196919d5e 100755 --- a/libs/cua-driver/tests/fixtures/apps/cross-platform/electron/build.sh +++ b/libs/cua-driver/tests/fixtures/apps/cross-platform/electron/build.sh @@ -119,6 +119,7 @@ if [ "$platform" = "Darwin" ]; then rm -rf "$appDir" mkdir -p "$appDir" cp "$elecDir/main.js" "$appDir/" + cp "$elecDir/preload.js" "$appDir/" cp "$elecDir/package.json" "$appDir/" cp -R "$elecDir/web" "$appDir/web" @@ -157,10 +158,12 @@ else appDir="$outDir/resources/app" mkdir -p "$appDir" cp "$elecDir/main.js" "$appDir/" + cp "$elecDir/preload.js" "$appDir/" cp "$elecDir/package.json" "$appDir/" cp -r "$elecDir/web" "$appDir/web" - mv "$outDir/electron" "$outDir/CuaTestHarness.Electron" - chmod +x "$outDir/CuaTestHarness.Electron" + mv "$outDir/electron" "$outDir/CuaTestHarness.Electron.bin" + cp "$elecDir/launcher-linux.sh" "$outDir/CuaTestHarness.Electron" + chmod +x "$outDir/CuaTestHarness.Electron" "$outDir/CuaTestHarness.Electron.bin" cat < 65535) { const CDP_PORT = String(cdpPortNum); app.commandLine.appendSwitch('remote-debugging-port', CDP_PORT); +ipcMain.on('cua-e2e-config', event => { + event.returnValue = { journalUrl: fixtureJournalUrl, sentinelMode }; +}); + +ipcMain.on('cua-e2e-fixture-state', (_event, state) => { + if (!fixtureJournalUrl) return; + const body = JSON.stringify(state); + const request = http.request(fixtureJournalUrl, { + method: 'POST', + headers: { + 'Content-Type': 'text/plain', + 'Content-Length': Buffer.byteLength(body), + }, + }); + request.on('error', () => {}); + request.end(body); +}); + +ipcMain.on('cua-e2e-sentinel-event', (_event, entry) => { + if (!sentinelMode || !sentinelJournalPath) return; + fs.appendFileSync(sentinelJournalPath, `${JSON.stringify(entry)}\n`, 'utf8'); +}); + let mainWindow; function createWindow() { - const fixedTitle = `CuaTestHarness Electron [cdp=${CDP_PORT}]`; + const fixedTitle = sentinelMode + ? `CuaTestHarness Sentinel [cdp=${CDP_PORT}]` + : `CuaTestHarness Electron [cdp=${CDP_PORT}]`; mainWindow = new BrowserWindow({ - width: 940, - height: 780, + width: sentinelMode ? 1280 : 940, + height: sentinelMode ? 900 : 780, + // Keep the normal fixture inside virtual desktops whose window manager + // has no persisted placement policy (notably Openbox under Xvfb). + x: sentinelMode ? 0 : 120, + y: sentinelMode ? 0 : 120, title: fixedTitle, - show: false, + // Map the normal harness immediately. Xvfb/Openbox can enumerate a + // deferred BrowserWindow while never painting it into the root desktop. + // The sentinel stays hidden until it has maximized and claimed focus. + show: !sentinelMode, + // A floating-level macOS window is omitted by cua-driver's deliberate + // layer-0 top-level window contract. Foreground + maximized is sufficient + // for occlusion there and lets an unexpected target raise remain visible. + alwaysOnTop: sentinelMode && process.platform !== 'darwin', autoHideMenuBar: true, webPreferences: { nodeIntegration: false, contextIsolation: true, + sandbox: !sentinelMode, + preload: path.join(__dirname, 'preload.js'), }, }); @@ -66,7 +116,21 @@ function createWindow() { // our fixedTitle and break the harness-window-discovery test. if (mainWindow && !mainWindow.isDestroyed()) { mainWindow.setTitle(fixedTitle); - mainWindow.showInactive(); + if (sentinelMode) { + if (process.platform !== 'darwin') { + mainWindow.setAlwaysOnTop(true); + } + mainWindow.maximize(); + mainWindow.show(); + mainWindow.focus(); + } else { + // Xvfb/Openbox can keep a showInactive window inspectable through + // AT-SPI while never mapping it onto the captured root desktop. + // Show it normally; background cells subsequently foreground the + // occlusion sentinel before taking their desktop snapshot. + mainWindow.show(); + mainWindow.focus(); + } } }) .catch(err => { diff --git a/libs/cua-driver/tests/fixtures/apps/cross-platform/electron/preload.js b/libs/cua-driver/tests/fixtures/apps/cross-platform/electron/preload.js new file mode 100644 index 0000000000..c111490cdd --- /dev/null +++ b/libs/cua-driver/tests/fixtures/apps/cross-platform/electron/preload.js @@ -0,0 +1,48 @@ +const { contextBridge, ipcRenderer } = require('electron'); + +const fixtureConfig = ipcRenderer.sendSync('cua-e2e-config'); +const fixtureJournalUrl = fixtureConfig.journalUrl || ''; + +contextBridge.exposeInMainWorld('cuaE2E', { + journalUrl: fixtureJournalUrl, + publishFixtureState(state) { + if (fixtureJournalUrl) ipcRenderer.send('cua-e2e-fixture-state', state); + }, +}); + +const sentinelMode = fixtureConfig.sentinelMode; + +function record(kind, details = {}) { + if (!sentinelMode) return; + ipcRenderer.send('cua-e2e-sentinel-event', { + kind, + at_ms: Date.now(), + ...details, + }); +} + +if (sentinelMode) { + window.addEventListener('DOMContentLoaded', () => { + document.body.innerHTML = ` +
+

CUA OCCLUSION SENTINEL

+

CUA_OCCLUSION_SENTINEL_v1

+
+ `; + record('ready'); + }); + window.addEventListener('focus', () => record('focus')); + window.addEventListener('blur', () => record('blur')); + window.addEventListener('keydown', event => + record('keydown', { key: event.key, code: event.code }) + ); + window.addEventListener('pointerdown', event => + record('pointerdown', { button: event.button, x: event.clientX, y: event.clientY }) + ); + window.addEventListener('wheel', event => + record('wheel', { delta_x: event.deltaX, delta_y: event.deltaY }) + ); + window.addEventListener('contextmenu', event => + record('contextmenu', { x: event.clientX, y: event.clientY }) + ); +} diff --git a/libs/cua-driver/tests/fixtures/apps/cross-platform/tauri/src-tauri/src/main.rs b/libs/cua-driver/tests/fixtures/apps/cross-platform/tauri/src-tauri/src/main.rs index 2331526d10..f689a4d095 100644 --- a/libs/cua-driver/tests/fixtures/apps/cross-platform/tauri/src-tauri/src/main.rs +++ b/libs/cua-driver/tests/fixtures/apps/cross-platform/tauri/src-tauri/src/main.rs @@ -1,7 +1,14 @@ #![cfg_attr(not(debug_assertions), windows_subsystem = "windows")] fn main() { + let journal_url = std::env::var("CUA_E2E_FIXTURE_JOURNAL_URL").unwrap_or_default(); + let journal_plugin = tauri::plugin::Builder::::new("e2e-journal") + .js_init_script(format!( + "window.__CUA_E2E_FIXTURE_JOURNAL_URL = {journal_url:?};" + )) + .build(); tauri::Builder::default() + .plugin(journal_plugin) .run(tauri::generate_context!()) .expect("error while running CuaTestHarness.Tauri"); }