fix(install-e2e): force 100% zoom before driving the app

The app ships a 90% UI-zoom default, so a fresh install renders at devicePixelRatio 0.9 and Playwright's input coordinates land ~10% off target on the CI runners: clicks aimed at the titlebar settings gear hit the bar beside it, which read as a phantom overlay interception and failed every app-update leg. Set zoom to 100% through webContents after boot, retrying until dpr reads 1 because the boot path re-applies the default asynchronously.
This commit is contained in:
yoniebans
2026-08-25 09:47:23 +03:00
parent f0e3bcdac9
commit c26bbe5d06
2 changed files with 48 additions and 0 deletions
+24
View File
@@ -117,6 +117,30 @@ async function main() {
log(`window picked (${app.windows().length} windows, url=${page.url()})`)
log('first window acquired')
// The app ships a 90% UI-zoom default, so a fresh install renders at
// devicePixelRatio 0.9 and Playwright's input coordinates land ~10% off
// target on the CI runners. Force 100% through the same webContents API
// the app's zoom control uses. A single set gets reverted (the boot path
// re-applies the default asynchronously), so set-verify-retry until dpr
// reads 1.
try {
const before = await page.evaluate(() => window.devicePixelRatio)
let after = before
for (let i = 0; i < 20; i++) {
await app.evaluate(({ BrowserWindow }) => {
for (const w of BrowserWindow.getAllWindows()) {
w.webContents.setZoomLevel(0)
}
})
await page.waitForTimeout(1000)
after = await page.evaluate(() => window.devicePixelRatio)
if (Math.abs(after - 1) < 0.001) break
}
log(`[zoom] forced 100% via webContents.setZoomLevel(0): dpr ${before} -> ${after}`)
} catch (e) {
log(`[zoom] direct zoom set failed (continuing): ${e.message}`)
}
// Boot: wait for the composer to exist — the shell is mounted by then.
// The real backend (`hermes serve`) is booting underneath; give it time.
await page.waitForSelector('textarea, [contenteditable="true"]', {
@@ -131,6 +131,30 @@ async function main() {
log(`window up: ${await window.title()} (${app.windows().length} windows, picked url=${window.url()})`);
await window.screenshot({ path: `${values.spec}.window.png` }).catch(() => {});
// The app ships a 90% UI-zoom default, so a fresh install renders at
// devicePixelRatio 0.9 and Playwright's input coordinates land ~10% off
// target on the CI runners. Force 100% through the same webContents API
// the app's zoom control uses. A single set gets reverted (the boot path
// re-applies the default asynchronously), so set-verify-retry until dpr
// reads 1.
try {
const before = await window.evaluate(() => window.devicePixelRatio);
let after = before;
for (let i = 0; i < 20; i++) {
await app.evaluate(({ BrowserWindow }) => {
for (const w of BrowserWindow.getAllWindows()) {
w.webContents.setZoomLevel(0);
}
});
await window.waitForTimeout(1000);
after = await window.evaluate(() => window.devicePixelRatio);
if (Math.abs(after - 1) < 0.001) break;
}
log(`[zoom] forced 100% via webContents.setZoomLevel(0): dpr ${before} -> ${after}`);
} catch (e) {
log(`[zoom] direct zoom set failed (continuing): ${e.message}`);
}
if (values['no-update']) {
log('smoke mode: window proven, closing');
await app.close().catch(() => {});