diff --git a/README.md b/README.md index 3589b79..ffef8ff 100644 --- a/README.md +++ b/README.md @@ -623,7 +623,7 @@ Step 8 默认要求当前认证页已经处于登录验证码页。 - 等待按钮可点击 - 获取按钮坐标 - 通过 Chrome `debugger` 的输入事件点击该按钮 -- 点击后会持续检查页面是否真正离开当前状态;如果出现认证页 `重试` 页面,会先通过共享恢复逻辑最多自动点击 5 次 `重试` 尝试恢复,再重新执行当前轮的“继续”点击 +- 点击后会持续检查页面是否真正离开当前状态;如果点击后出现认证页 `重试` 页面,则直接报错,不会在 Step 9 内部点击 `重试` - 同时监听 `chrome.webNavigation.onBeforeNavigate` - 一旦捕获本地回调地址,就把结果保存到 `Callback` diff --git a/background.js b/background.js index 93511a7..0f5aea1 100644 --- a/background.js +++ b/background.js @@ -7194,7 +7194,6 @@ async function getStep8PageState(tabId, responseTimeoutMs = 1500) { async function waitForStep8Ready(tabId, timeoutMs = STEP8_READY_WAIT_TIMEOUT_MS) { const start = Date.now(); let recovered = false; - let retryRecovered = false; while (Date.now() - start < timeoutMs) { throwIfStopped(); @@ -7206,20 +7205,9 @@ async function waitForStep8Ready(tabId, timeoutMs = STEP8_READY_WAIT_TIMEOUT_MS) throw new Error('步骤 9:认证页进入了手机号页面,当前不是 OAuth 同意页,无法继续自动授权。'); } if (pageState?.retryPage) { - await recoverAuthRetryPageOnTab(tabId, { - flow: 'auth', - logLabel: '步骤 9:检测到认证页重试页,正在点击“重试”恢复', - step: 8, - timeoutMs: Math.max(1000, Math.min(12000, timeoutMs)), - }); - retryRecovered = true; - await sleepWithStop(250); - continue; + throw new Error(`步骤 9:当前认证页已进入重试页,当前流程将直接报错。URL: ${pageState.url || 'unknown'}`); } if (pageState?.consentReady) { - if (retryRecovered) { - await addLog('步骤 9:认证页重试页已恢复,准备重新定位“继续”按钮...', 'info'); - } return pageState; } if (pageState === null && !recovered) { @@ -7384,18 +7372,7 @@ async function waitForStep8ClickEffect(tabId, baselineUrl, timeoutMs = STEP8_CLI throw new Error('步骤 9:点击“继续”后页面跳到了手机号页面,当前流程无法继续自动授权。'); } if (pageState?.retryPage) { - await recoverAuthRetryPageOnTab(tabId, { - flow: 'auth', - logLabel: '步骤 9:点击“继续”后进入重试页,正在点击“重试”恢复', - step: 8, - timeoutMs: Math.max(1000, Math.min(12000, timeoutMs)), - }); - return { - progressed: false, - reason: 'retry_page_recovered', - restartCurrentStep: true, - url: pageState.url || baselineUrl || '', - }; + throw new Error(`步骤 9:点击“继续”后页面进入认证页重试页,当前流程将直接报错。URL: ${pageState.url || baselineUrl || 'unknown'}`); } if (pageState === null) { if (!recovered) { @@ -7429,8 +7406,6 @@ function getStep8EffectLabel(effect) { switch (effect?.reason) { case 'url_changed': return `URL 已变化:${effect.url}`; - case 'retry_page_recovered': - return '页面进入重试页并已恢复,需要重新执行当前步骤'; case 'page_reloading': return '页面正在跳转或重载'; case 'left_consent_page': diff --git a/background/steps/confirm-oauth.js b/background/steps/confirm-oauth.js index 1c9076c..d61f8b2 100644 --- a/background/steps/confirm-oauth.js +++ b/background/steps/confirm-oauth.js @@ -200,12 +200,6 @@ break; } - if (effect.restartCurrentStep) { - await addLog(`步骤 9:${getStep8EffectLabel(effect)},准备重新定位“继续”按钮并重试...`, 'warn'); - await sleepWithStop(STEP8_CLICK_RETRY_DELAY_MS); - continue; - } - if (round >= STEP8_MAX_ROUNDS) { throw new Error(`步骤 9:连续 ${STEP8_MAX_ROUNDS} 轮点击“继续”后页面仍无反应。`); } diff --git a/tests/step8-retry-page-recovery.test.js b/tests/step8-retry-page-recovery.test.js index 34d76aa..bdc8ac5 100644 --- a/tests/step8-retry-page-recovery.test.js +++ b/tests/step8-retry-page-recovery.test.js @@ -51,10 +51,8 @@ function extractFunction(name) { return source.slice(start, end); } -test('step 8 click effect returns restart_current_step when retry page is recovered', async () => { +test('step 8 click effect throws when retry page appears after clicking continue', async () => { const api = new Function(` -let recoverCalls = 0; - const chrome = { tabs: { async get() { @@ -69,10 +67,6 @@ const chrome = { function throwIfStopped() {} async function sleepWithStop() {} async function ensureStep8SignupPageReady() {} -async function recoverAuthRetryPageOnTab() { - recoverCalls += 1; - return { recovered: true }; -} async function getStep8PageState() { return { url: 'https://auth.openai.com/authorize', @@ -89,20 +83,51 @@ return { async run() { return waitForStep8ClickEffect(88, 'https://auth.openai.com/authorize', 1000); }, - snapshot() { - return { recoverCalls }; +}; +`)(); + + await assert.rejects( + () => api.run(), + /点击“继续”后页面进入认证页重试页/ + ); +}); + +test('step 8 ready check throws when consent page is already a retry page before clicking', async () => { + const api = new Function(` +const chrome = { + tabs: { + async get() { + return { + id: 88, + url: 'https://auth.openai.com/authorize', + }; + }, + }, +}; + +function throwIfStopped() {} +async function sleepWithStop() {} +async function ensureStep8SignupPageReady() {} +async function getStep8PageState() { + return { + url: 'https://auth.openai.com/authorize', + retryPage: true, + addPhonePage: false, + consentReady: false, + }; +} + +${extractFunction('waitForStep8Ready')} + +return { + async run() { + return waitForStep8Ready(88, 1000); }, }; `)(); - const result = await api.run(); - const snapshot = api.snapshot(); - - assert.deepStrictEqual(result, { - progressed: false, - reason: 'retry_page_recovered', - restartCurrentStep: true, - url: 'https://auth.openai.com/authorize', - }); - assert.equal(snapshot.recoverCalls, 1); + await assert.rejects( + () => api.run(), + /当前认证页已进入重试页/ + ); }); diff --git a/项目完整链路说明.md b/项目完整链路说明.md index 7f4f5c6..3fa355c 100644 --- a/项目完整链路说明.md +++ b/项目完整链路说明.md @@ -709,7 +709,7 @@ - Step 8 如果发现认证页已经进入登录超时报错/重试页,会直接报错并回到 Step 7 重新开始,而不是在 Step 8 内部点击 `重试`。 - Step 8 的登录重试页判定也覆盖 `/email-verification` 上的 `405 / Route Error`,避免这类页面被误当成普通未知页。 - 任意认证页重试页如果正文中出现 `max_check_attempts`,会被视为 Cloudflare 风控触发:后台立刻完全停止流程,侧边栏会复用现有确认弹窗提示等待 15~30 分钟后再试,避免继续刷新或反复重试加重风控,确认按钮显示为“我知道了”。 -- Step 9 在点击 OAuth 同意页 `继续` 后,会额外检查是否进入认证页重试页;若命中则先通过共享恢复逻辑最多自动点击 5 次 `重试` 尝试恢复,再重新执行当前轮的 `继续` 点击。 +- Step 9 在点击 OAuth 同意页 `继续` 后,会持续等待页面跳转;若点击后命中认证页重试页,则直接报错,不会在 Step 9 内部点击 `重试`。 ## 2026-04-21 2925 邮件时间窗补充 - `2925` 在 Step 4 / Step 8 现在会携带固定的步骤开始时间窗口,实际筛选下限为“步骤开始时间向前回看 10 分钟”。