diff --git a/scripts/check-deps-helpers.mjs b/scripts/check-deps-helpers.mjs new file mode 100644 index 0000000..42fe943 --- /dev/null +++ b/scripts/check-deps-helpers.mjs @@ -0,0 +1,18 @@ +export async function waitForProxyConnection({ + healthUrl, + attempts = 15, + timeoutMs = 8000, + httpGetJson, + sleep = (ms) => new Promise((resolve) => setTimeout(resolve, ms)), +}) { + for (let i = 1; i <= attempts; i++) { + const health = await httpGetJson(healthUrl, timeoutMs); + if (health?.status === 'ok' && health.connected) { + return true; + } + if (i < attempts) { + await sleep(1000); + } + } + return false; +} diff --git a/scripts/check-deps.mjs b/scripts/check-deps.mjs index 87c49ba..5672fed 100644 --- a/scripts/check-deps.mjs +++ b/scripts/check-deps.mjs @@ -14,6 +14,7 @@ import os from 'node:os'; import path from 'node:path'; import { fileURLToPath } from 'node:url'; import { selectBrowser, knownBrowsers, findFallbackPort } from './browser-discovery.mjs'; +import { waitForProxyConnection } from './check-deps-helpers.mjs'; const ROOT = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..'); const PROXY_SCRIPT = path.join(ROOT, 'scripts', 'cdp-proxy.mjs'); @@ -77,7 +78,6 @@ function startProxyDetached(browserOverride) { async function ensureProxy(expectedBrowserId, browserOverride) { const healthUrl = `http://127.0.0.1:${PROXY_PORT}/health`; - const targetsUrl = `http://127.0.0.1:${PROXY_PORT}/targets`; // 复用:proxy 已运行 + 已连接浏览器 → 校验 expected vs actual const health = await httpGetJson(healthUrl); @@ -98,18 +98,16 @@ async function ensureProxy(expectedBrowserId, browserOverride) { await new Promise((r) => setTimeout(r, 2000)); - for (let i = 1; i <= 15; i++) { - const result = await httpGetJson(targetsUrl, 8000); - if (Array.isArray(result)) { - const newHealth = await httpGetJson(healthUrl); - const label = newHealth?.browser?.label || 'unknown'; - console.log(`proxy: ready (${label})`); - return true; - } - if (i === 1) { - console.log('⚠️ 浏览器可能有授权弹窗,请点击「允许」后等待连接...'); - } - await new Promise((r) => setTimeout(r, 1000)); + console.log('⚠️ 浏览器可能有授权弹窗,请点击「允许」后等待连接...'); + const ready = await waitForProxyConnection({ + healthUrl, + httpGetJson, + }); + if (ready) { + const newHealth = await httpGetJson(healthUrl); + const label = newHealth?.browser?.label || 'unknown'; + console.log(`proxy: ready (${label})`); + return true; } console.log('❌ 连接超时,请检查浏览器调试设置'); diff --git a/tests/check-deps-wait.test.mjs b/tests/check-deps-wait.test.mjs new file mode 100644 index 0000000..9cc0030 --- /dev/null +++ b/tests/check-deps-wait.test.mjs @@ -0,0 +1,40 @@ +import test from 'node:test'; +import assert from 'node:assert/strict'; + +import { waitForProxyConnection } from '../scripts/check-deps-helpers.mjs'; + +test('waitForProxyConnection polls health until proxy reports connected', async () => { + const calls = []; + const healthUrl = 'http://127.0.0.1:3456/health'; + const responses = [ + { status: 'ok', connected: false }, + { status: 'ok', connected: false }, + { status: 'ok', connected: true, browser: { label: 'Chrome' } }, + ]; + + const ready = await waitForProxyConnection({ + healthUrl, + attempts: responses.length, + httpGetJson: async (url) => { + calls.push(url); + return responses.shift() ?? null; + }, + sleep: async () => {}, + }); + + assert.equal(ready, true); + assert.deepEqual(calls, [healthUrl, healthUrl, healthUrl]); +}); + +test('waitForProxyConnection returns false after exhausting health polls', async () => { + const healthUrl = 'http://127.0.0.1:3456/health'; + + const ready = await waitForProxyConnection({ + healthUrl, + attempts: 2, + httpGetJson: async () => ({ status: 'ok', connected: false }), + sleep: async () => {}, + }); + + assert.equal(ready, false); +});