From f8f4083f227bf72d5c4f3c7fcf7d6ec7fcfa5464 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Wed, 23 Sep 2026 14:31:16 +0700 Subject: [PATCH 1/2] test(desktop): isolate expected certificate error navigations --- apps/desktop/test/windows-pit-browser.mjs | 22 +++++++++++++++------- 1 file changed, 15 insertions(+), 7 deletions(-) diff --git a/apps/desktop/test/windows-pit-browser.mjs b/apps/desktop/test/windows-pit-browser.mjs index 701ddb3..f0356df 100644 --- a/apps/desktop/test/windows-pit-browser.mjs +++ b/apps/desktop/test/windows-pit-browser.mjs @@ -21,6 +21,19 @@ try { await controls.goto(`chrome-extension://${id}/options.html`); const message = (type, on) => controls.evaluate( ({ type, on }) => chrome.runtime.sendMessage({ type, on }), { type, on }); + // Certificate rejection can commit chrome-error:// after goto rejects. Keep + // that late navigation out of the tab used for subsequent routing checks. + const rejectUntrusted = async (url, screenshotPath) => { + const invalid = await context.newPage(); + try { + await assert.rejects(invalid.goto(url, { + waitUntil: 'domcontentloaded', timeout: 45000, + }), /ERR_CERT_AUTHORITY_INVALID/); + if (screenshotPath) await invalid.screenshot({ path: screenshotPath }); + } finally { + await invalid.close(); + } + }; const deadline = Date.now() + 5000; let initial, initialProxy; @@ -51,10 +64,7 @@ try { check('HTTP Moshpit name resolves through the browser'); if (phase === 'before-trust' || phase === 'after-removal') { - await assert.rejects(page.goto('https://profullstack.agent/', { - waitUntil: 'domcontentloaded', timeout: 45000, - }), /ERR_CERT_AUTHORITY_INVALID/); - await page.screenshot({ path: path.join(evidence, `${phase}.png`) }); + await rejectUntrusted('https://profullstack.agent/', path.join(evidence, `${phase}.png`)); check('registry HTTPS is rejected without root trust'); } else { const response = await page.goto('https://profullstack.agent/', { @@ -70,9 +80,7 @@ try { check('registry HTTPS succeeds with normal browser certificate verification'); } - await assert.rejects(page.goto(invalidTlsUrl, { - waitUntil: 'domcontentloaded', timeout: 15000, - }), /ERR_CERT_AUTHORITY_INVALID/); + await rejectUntrusted(invalidTlsUrl); check('unrelated self-signed HTTPS remains rejected'); assert.equal((await message('pit-set', false)).enabled, false); From ecceeffe2b29986dd3789fa6d2a24ed76815f829 Mon Sep 17 00:00:00 2001 From: Phuc Nguyen Date: Wed, 23 Sep 2026 14:33:31 +0700 Subject: [PATCH 2/2] test(desktop): retain certificate rejection diagnostics --- apps/desktop/test/windows-pit-browser.mjs | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) diff --git a/apps/desktop/test/windows-pit-browser.mjs b/apps/desktop/test/windows-pit-browser.mjs index f0356df..b0b8c5e 100644 --- a/apps/desktop/test/windows-pit-browser.mjs +++ b/apps/desktop/test/windows-pit-browser.mjs @@ -23,15 +23,21 @@ try { ({ type, on }) => chrome.runtime.sendMessage({ type, on }), { type, on }); // Certificate rejection can commit chrome-error:// after goto rejects. Keep // that late navigation out of the tab used for subsequent routing checks. - const rejectUntrusted = async (url, screenshotPath) => { + const rejectUntrusted = async (url, { screenshotPath, timeout = 45000 } = {}) => { const invalid = await context.newPage(); try { await assert.rejects(invalid.goto(url, { - waitUntil: 'domcontentloaded', timeout: 45000, + waitUntil: 'domcontentloaded', timeout, }), /ERR_CERT_AUTHORITY_INVALID/); - if (screenshotPath) await invalid.screenshot({ path: screenshotPath }); + if (screenshotPath) { + await invalid.waitForFunction(() => Boolean(document.body?.innerText.trim()), null, { timeout: 5000 }); + await invalid.screenshot({ path: screenshotPath }); + } + } catch (error) { + await invalid.screenshot({ path: path.join(evidence, `${phase}-invalid-tls-failure.png`) }).catch(() => {}); + throw error; } finally { - await invalid.close(); + await invalid.close().catch(() => {}); } }; @@ -64,7 +70,7 @@ try { check('HTTP Moshpit name resolves through the browser'); if (phase === 'before-trust' || phase === 'after-removal') { - await rejectUntrusted('https://profullstack.agent/', path.join(evidence, `${phase}.png`)); + await rejectUntrusted('https://profullstack.agent/', { screenshotPath: path.join(evidence, `${phase}.png`) }); check('registry HTTPS is rejected without root trust'); } else { const response = await page.goto('https://profullstack.agent/', { @@ -80,7 +86,7 @@ try { check('registry HTTPS succeeds with normal browser certificate verification'); } - await rejectUntrusted(invalidTlsUrl); + await rejectUntrusted(invalidTlsUrl, { timeout: 15000 }); check('unrelated self-signed HTTPS remains rejected'); assert.equal((await message('pit-set', false)).enabled, false);