From bfd6c9ef3d5125d2cd585c318d257be1627a4c3b Mon Sep 17 00:00:00 2001 From: dengqichen Date: Mon, 17 Nov 2025 12:37:56 +0800 Subject: [PATCH] dasdasd --- src/tools/account-register/sites/windsurf.js | 242 ++++++++++++------- 1 file changed, 154 insertions(+), 88 deletions(-) diff --git a/src/tools/account-register/sites/windsurf.js b/src/tools/account-register/sites/windsurf.js index 7e360de..5eb2cf2 100644 --- a/src/tools/account-register/sites/windsurf.js +++ b/src/tools/account-register/sites/windsurf.js @@ -74,49 +74,94 @@ class WindsurfRegister { } /** - * 通用方法:点击按钮并等待页面跳转 - * @param {Function} checkPageChanged - 检查页面是否已跳转的函数,返回Promise - * @param {number} maxAttempts - 最多尝试次数 - * @param {string} actionName - 操作名称(用于日志) - * @returns {Promise} - 是否成功跳转 + * 通用方法:等待按钮激活并点击,然后等待页面内容变化 + * @param {Object} options - 配置选项 + * @param {string} options.buttonText - 按钮文本(用于识别,如'Continue') + * @param {Function} options.checkContentChanged - 检查页面内容是否已变化的函数,返回Promise + * @param {number} options.waitButtonTimeout - 等待按钮激活的超时时间(毫秒),默认30000 + * @param {number} options.waitContentTimeout - 等待内容变化的超时时间(毫秒),默认15000 + * @param {string} options.actionName - 操作名称(用于日志) + * @returns {Promise} - 是否成功完成 */ - async clickButtonAndWaitForPageChange(checkPageChanged, maxAttempts = 5, actionName = '点击按钮') { - let pageChanged = false; - let attempts = 0; + async clickButtonAndWaitForPageChange(options) { + const { + buttonText = 'Continue', + checkContentChanged, + waitButtonTimeout = 30000, + waitContentTimeout = 15000, + actionName = '点击按钮' + } = options; - while (!pageChanged && attempts < maxAttempts) { - attempts++; + try { + // 阶段1: 等待按钮变为可点击状态(enabled) + logger.info(this.siteName, ` → 等待"${buttonText}"按钮激活...`); - // 查找未禁用的按钮 - const button = await this.page.$('button:not([disabled])'); - if (button) { - const text = await this.page.evaluate(el => el.textContent.trim(), button); - logger.info(this.siteName, ` → 第${attempts}次${actionName}"${text}"...`); - await button.click(); - await this.human.randomDelay(2000, 3000); + const buttonStartTime = Date.now(); + let buttonEnabled = false; + + while (Date.now() - buttonStartTime < waitButtonTimeout) { + buttonEnabled = await this.page.evaluate((btnText) => { + const buttons = Array.from(document.querySelectorAll('button')); + const targetButton = buttons.find(btn => + btn.textContent.trim() === btnText && !btn.disabled + ); + return !!targetButton; + }, buttonText); - // 使用自定义检查函数判断页面是否跳转 - const changed = await checkPageChanged(); - - if (changed) { - pageChanged = true; - logger.success(this.siteName, ` → ✓ 页面已跳转`); + if (buttonEnabled) { + const elapsed = ((Date.now() - buttonStartTime) / 1000).toFixed(1); + logger.success(this.siteName, ` → ✓ 按钮已激活 (耗时: ${elapsed}秒)`); break; } - logger.warn(this.siteName, ` → 页面未跳转,${attempts}/${maxAttempts}`); - await this.human.randomDelay(2000, 3000); - } else { - logger.warn(this.siteName, ` → 未找到可点击的按钮`); - break; + // 每5秒输出一次进度 + const elapsed = Date.now() - buttonStartTime; + if (elapsed > 0 && elapsed % 5000 === 0) { + logger.info(this.siteName, ` → 等待按钮激活中... 已用时 ${(elapsed/1000).toFixed(0)}秒`); + } + + await new Promise(resolve => setTimeout(resolve, 1000)); } + + if (!buttonEnabled) { + logger.error(this.siteName, ` → ⚠️ 等待${waitButtonTimeout/1000}秒后按钮仍未激活`); + return false; + } + + // 阶段2: 点击按钮 + logger.info(this.siteName, ` → ${actionName}...`); + await this.human.humanClick(this.page, `button:not([disabled])`); + await this.human.randomDelay(1000, 2000); + + // 阶段3: 等待页面内容变化 + logger.info(this.siteName, ` → 等待页面内容变化...`); + + const contentStartTime = Date.now(); + let contentChanged = false; + + while (Date.now() - contentStartTime < waitContentTimeout) { + contentChanged = await checkContentChanged(); + + if (contentChanged) { + const elapsed = ((Date.now() - contentStartTime) / 1000).toFixed(1); + logger.success(this.siteName, ` → ✓ 页面内容已变化 (耗时: ${elapsed}秒)`); + break; + } + + await new Promise(resolve => setTimeout(resolve, 500)); + } + + if (!contentChanged) { + logger.warn(this.siteName, ` → ⚠️ 等待${waitContentTimeout/1000}秒后页面内容未变化`); + return false; + } + + return true; + + } catch (error) { + logger.error(this.siteName, ` → ${actionName}失败: ${error.message}`); + return false; } - - if (!pageChanged) { - logger.error(this.siteName, ` → ${maxAttempts}次尝试后页面仍未跳转`); - } - - return pageChanged; } /** @@ -260,30 +305,25 @@ class WindsurfRegister { } // 点击Continue按钮并等待跳转到密码页面 - logger.info(this.siteName, ' → 点击Continue按钮...'); + const success = await this.clickButtonAndWaitForPageChange({ + buttonText: 'Continue', + checkContentChanged: async () => { + // 检查是否有密码输入框(表示已进入下一步) + return await this.page.evaluate(() => { + return !!document.querySelector('#password'); + }); + }, + waitButtonTimeout: 30000, + waitContentTimeout: 15000, + actionName: '点击Continue进入密码设置页面' + }); - // 等待按钮激活 - await this.page.waitForSelector('button:not([disabled])', { timeout: 10000 }); - logger.info(this.siteName, ' → 按钮已激活'); - - // 使用通用方法处理页面跳转 - const checkPageChanged = async () => { - // 检查是否有密码输入框 - const hasPasswordField = await this.page.evaluate(() => { - return !!document.querySelector('#password'); - }); - - // 检查URL是否改变 - const currentUrl = this.page.url(); - const urlChanged = currentUrl !== this.siteUrl; - - return hasPasswordField || urlChanged; - }; - - await this.clickButtonAndWaitForPageChange(checkPageChanged, 5, '点击Continue'); + if (!success) { + throw new Error('步骤1:未能成功进入密码设置页面'); + } // 额外等待确保页面稳定 - await this.human.randomDelay(2000, 3000); + await this.human.randomDelay(1000, 2000); this.currentStep = 1; logger.success(this.siteName, `步骤 1 完成`); @@ -909,28 +949,24 @@ class WindsurfRegister { } logger.success(this.siteName, ' → 验证码已填写完成'); - // 等待按钮激活(填完验证码后按钮会自动启用) - logger.info(this.siteName, ' → 等待按钮激活...'); - await this.human.randomDelay(2000, 3000); + // 点击"Create account"按钮并等待页面内容变化 + const success = await this.clickButtonAndWaitForPageChange({ + buttonText: 'Create account', + checkContentChanged: async () => { + // 检查验证码输入框是否已消失(表示已进入下一步) + return await this.page.evaluate(() => { + return !document.querySelector('input[type="text"]'); + }); + }, + waitButtonTimeout: 30000, + waitContentTimeout: 15000, + actionName: '点击Create account进入下一步' + }); - // 等待按钮激活 - try { - await this.page.waitForSelector('button:not([disabled])', { timeout: 10000 }); - logger.success(this.siteName, ' → 按钮已激活'); - } catch (e) { - logger.warn(this.siteName, ` → 按钮等待超时: ${e.message}`); + if (!success) { + throw new Error('步骤3:未能成功创建账号'); } - // 点击按钮并等待页面跳转 - const checkPageChanged = async () => { - // 检查是否离开了验证码页面(URL改变或页面元素改变) - const currentUrl = this.page.url(); - return !currentUrl.includes('/register') || - await this.page.$('input[type="text"]').then(el => !el).catch(() => true); - }; - - await this.clickButtonAndWaitForPageChange(checkPageChanged, 3, '点击Create account'); - this.currentStep = 3; logger.success(this.siteName, `步骤 3 完成`); @@ -957,26 +993,54 @@ class WindsurfRegister { logger.info(this.siteName, `[步骤 4/${this.getTotalSteps()}] 跳过问卷`); try { - // 等待页面加载 + // 初始等待页面加载 await this.human.readPage(2, 3); - // 查找并点击"Skip this step"按钮 - logger.info(this.siteName, ' → 查找"Skip this step"按钮...'); + logger.info(this.siteName, ' → 持续查找"Skip this step"按钮...'); - // 方式1: 通过button文本查找 - const buttons = await this.page.$$('button'); + const startTime = Date.now(); + const maxWait = 60000; // 最多等待60秒 + let elapsed = 0; let skipButton = null; + let buttonFound = false; - for (const button of buttons) { - const text = await this.page.evaluate(el => el.textContent?.trim(), button); - if (text && text.toLowerCase().includes('skip')) { - skipButton = button; - logger.info(this.siteName, ` → 找到按钮: "${text}"`); - break; + // 轮询查找按钮 + while (elapsed < maxWait && !buttonFound) { + try { + // 查找所有按钮 + const buttons = await this.page.$$('button'); + + for (const button of buttons) { + const text = await this.page.evaluate(el => el.textContent?.trim(), button); + if (text && text.toLowerCase().includes('skip')) { + skipButton = button; + buttonFound = true; + logger.success(this.siteName, ` → ✓ 找到按钮: "${text}" (耗时: ${((Date.now() - startTime) / 1000).toFixed(1)}秒)`); + break; + } + } + + if (buttonFound) { + break; + } + + // 每5秒输出一次进度 + if (elapsed > 0 && elapsed % 5000 === 0) { + logger.info(this.siteName, ` → 等待按钮出现... 已用时 ${elapsed/1000}秒`); + } + + // 等待2秒后继续查找 + await new Promise(resolve => setTimeout(resolve, 2000)); + elapsed = Date.now() - startTime; + + } catch (error) { + logger.warn(this.siteName, ` → 查找按钮时出错: ${error.message},继续尝试...`); + await new Promise(resolve => setTimeout(resolve, 2000)); + elapsed = Date.now() - startTime; } } - if (skipButton) { + if (skipButton && buttonFound) { logger.info(this.siteName, ' → 点击"Skip this step"按钮...'); await skipButton.click(); @@ -985,8 +1049,10 @@ class WindsurfRegister { this.currentStep = 4; logger.success(this.siteName, `步骤 4 完成`); - } else { - logger.warn(this.siteName, ' → 未找到Skip按钮,可能已跳过此页面'); + } else if (elapsed >= maxWait) { + logger.warn(this.siteName, ` → ⚠️ 等待${maxWait/1000}秒后仍未找到Skip按钮`); + logger.warn(this.siteName, ' → 可能原因:页面已自动跳过或页面结构已变化'); + logger.info(this.siteName, ' → 尝试继续执行下一步...'); this.currentStep = 4; }