fix(install-e2e): verify input readiness and tolerate transient windows
This commit is contained in:
@@ -6,6 +6,28 @@ const { prepareWindowForInput } = createRequire(import.meta.url)(
|
||||
'../../../tests/install/e2e-assets/window-input.cjs',
|
||||
)
|
||||
|
||||
test('does not finish when IPC reports 100% before the window factor settles', async () => {
|
||||
let observations = 0
|
||||
const previous = (globalThis as any).hermesDesktop
|
||||
;(globalThis as any).hermesDesktop = { zoom: {
|
||||
setPercent: () => undefined,
|
||||
get: async () => ({ percent: 100 }),
|
||||
} }
|
||||
const appWindow = { evaluate: async (fn: any) => fn({ webContents: {
|
||||
getZoomFactor: () => ++observations === 1 ? 0.9 : 1,
|
||||
} }) }
|
||||
const page = {
|
||||
evaluate: async (fn: any) => fn(),
|
||||
waitForTimeout: async () => undefined,
|
||||
}
|
||||
try {
|
||||
await prepareWindowForInput({ browserWindow: async () => appWindow }, page)
|
||||
expect(observations).toBeGreaterThan(1)
|
||||
} finally {
|
||||
;(globalThis as any).hermesDesktop = previous
|
||||
}
|
||||
})
|
||||
|
||||
test('reapplies zoom when startup overwrites the first request', async () => {
|
||||
let requests = 0
|
||||
let factor = 0.9
|
||||
|
||||
@@ -161,6 +161,8 @@ async function main() {
|
||||
let iter = 0
|
||||
|
||||
while (!openedSettings) {
|
||||
// A boot-time restore or focus event can move the scale after preparation.
|
||||
await prepareWindowForInput(app, page)
|
||||
iter++
|
||||
for (const make of laterLocators) {
|
||||
try {
|
||||
|
||||
@@ -199,14 +199,16 @@ if launchFound {
|
||||
}
|
||||
Log("Launch clicked; waiting for the Hermes desktop app window")
|
||||
|
||||
; The installer spawns Hermes.exe detached and exits itself.
|
||||
; WinWait returns 0 on timeout; it does not throw. The old unchecked return
|
||||
; led to WinGetPos throwing "Target window not found." Reuse the bounded
|
||||
; real-window poll so transient handles are ignored and failures name the wait.
|
||||
; CI's installer remained on LAUNCHING past 120s after a successful bootstrap.
|
||||
try {
|
||||
WinWait(appWin, , 120)
|
||||
appRect := WaitForRealWindow(appWin, 300000)
|
||||
} catch {
|
||||
throw Error("Hermes.exe window did not appear within 120s of clicking Launch")
|
||||
throw Error("Hermes.exe real-sized window did not appear within 300s of clicking Launch")
|
||||
}
|
||||
WinGetPos(&ax, &ay, &aw, &ah, appWin)
|
||||
Log(Format("App window appeared at x={1} y={2} w={3} h={4}", ax, ay, aw, ah))
|
||||
Log(Format("App window appeared at x={1} y={2} w={3} h={4}", appRect.x, appRect.y, appRect.w, appRect.h))
|
||||
|
||||
Sleep(8000) ; let the renderer paint (recorded as proof)
|
||||
Log("done")
|
||||
|
||||
@@ -216,6 +216,7 @@ async function main() {
|
||||
}
|
||||
}).then((d) => JSON.stringify(d)).catch((e) => `hit-dump failed: ${e.message}`)
|
||||
for (let iter = 1; ; iter++) {
|
||||
await prepareWindowForInput(app, window);
|
||||
await later
|
||||
.click({ timeout: 2_000 })
|
||||
.then(async () => {
|
||||
@@ -225,6 +226,9 @@ async function main() {
|
||||
.catch((e) => log(`[overlay] iter ${iter} chooseLater click failed: ${brief(e)}`))
|
||||
try {
|
||||
await settingsButton.click({ timeout: 4_000 })
|
||||
// A landed click during shell hydration can be lost on a remount.
|
||||
// Confirm the destination before looking for its About control.
|
||||
await window.waitForURL(/[#/]settings(?:[/?]|$)/, { timeout: 4_000 })
|
||||
settingsOpened = true
|
||||
break
|
||||
} catch (e) {
|
||||
|
||||
@@ -21,8 +21,13 @@ async function prepareWindowForInput(app, page) {
|
||||
globalThis.hermesDesktop.zoom.setPercent(100)
|
||||
return globalThis.hermesDesktop.zoom.get()
|
||||
})
|
||||
if (state.percent === 100) break
|
||||
if (Date.now() >= deadline) throw new Error('timed out waiting for 100% app window zoom')
|
||||
// The renderer IPC and BrowserWindow can observe different moments of
|
||||
// startup restoration. Both must agree before the driver sends input.
|
||||
const factor = await window.evaluate(win => win.webContents.getZoomFactor())
|
||||
if (state.percent === 100 && Math.abs(factor - 1) < 0.001) return
|
||||
if (Date.now() >= deadline) {
|
||||
throw new Error(`timed out waiting for 100% app window zoom (IPC ${state.percent}%, factor ${factor})`)
|
||||
}
|
||||
await page.waitForTimeout(100)
|
||||
}
|
||||
} else {
|
||||
|
||||
Reference in New Issue
Block a user