(step, payload)
| 1277 | } |
| 1278 | |
| 1279 | async function fillVerificationCode(step, payload) { |
| 1280 | const { code } = payload; |
| 1281 | if (!code) throw new Error('未提供验证码。'); |
| 1282 | |
| 1283 | log(`步骤 ${step}:正在填写验证码:${code}`); |
| 1284 | |
| 1285 | if (step === 7) { |
| 1286 | await waitForLoginVerificationPageReady(); |
| 1287 | } |
| 1288 | |
| 1289 | // Find code input — could be a single input or multiple separate inputs |
| 1290 | // Retry with 405 error recovery if needed |
| 1291 | const maxRetries = 3; |
| 1292 | let codeInput = null; |
| 1293 | |
| 1294 | for (let retry = 0; retry <= maxRetries; retry++) { |
| 1295 | throwIfStopped(); |
| 1296 | |
| 1297 | // Before looking for input, check if page is in 405 error state |
| 1298 | if (is405MethodNotAllowedPage()) { |
| 1299 | log(`步骤 ${step}:检测到 405 错误页面,正在恢复...`, 'warn'); |
| 1300 | await handle405ResendError(step, 30000); |
| 1301 | continue; |
| 1302 | } |
| 1303 | |
| 1304 | try { |
| 1305 | codeInput = await waitForElement(VERIFICATION_CODE_INPUT_SELECTOR, 10000); |
| 1306 | break; // Found it |
| 1307 | } catch { |
| 1308 | // Check for multiple single-digit inputs (common pattern) |
| 1309 | const singleInputs = document.querySelectorAll('input[maxlength="1"]'); |
| 1310 | if (singleInputs.length >= 6) { |
| 1311 | log(`步骤 ${step}:发现分开的单字符验证码输入框,正在逐个填写...`); |
| 1312 | for (let i = 0; i < 6 && i < singleInputs.length; i++) { |
| 1313 | fillInput(singleInputs[i], code[i]); |
| 1314 | await sleep(100); |
| 1315 | } |
| 1316 | const outcome = await waitForVerificationSubmitOutcome(step); |
| 1317 | if (outcome.invalidCode) { |
| 1318 | log(`步骤 ${step}:验证码被拒绝:${outcome.errorText}`, 'warn'); |
| 1319 | } else if (outcome.addPhonePage) { |
| 1320 | log(`步骤 ${step}:验证码已通过,并已跳转到手机号页面。`, 'ok'); |
| 1321 | } else { |
| 1322 | log(`步骤 ${step}:验证码已通过${outcome.assumed ? '(按成功推定)' : ''}。`, 'ok'); |
| 1323 | } |
| 1324 | return outcome; |
| 1325 | } |
| 1326 | |
| 1327 | // No input found — check if it's a 405 error and can be recovered |
| 1328 | if (is405MethodNotAllowedPage() && retry < maxRetries) { |
| 1329 | log(`步骤 ${step}:未找到验证码输入框且页面出现 405 错误,正在恢复...`, 'warn'); |
| 1330 | await handle405ResendError(step, 30000); |
| 1331 | continue; |
| 1332 | } |
| 1333 | |
| 1334 | throw new Error('未找到验证码输入框。URL: ' + location.href); |
| 1335 | } |
| 1336 | } |
no test coverage detected