const BaseAction = require('../core/base-action'); const SmartSelector = require('../core/smart-selector'); /** * 点击动作 */ class ClickAction extends BaseAction { async execute() { const selector = this.config.selector || this.config.find; if (!selector) { throw new Error('缺少选择器配置'); } this.log('info', '执行点击'); // 查找元素 const smartSelector = SmartSelector.fromConfig(selector, this.page); const element = await smartSelector.find(this.config.timeout || 10000); if (!element) { throw new Error(`无法找到元素: ${JSON.stringify(selector)}`); } // 滚动到可视区域 await element.evaluate((el) => { el.scrollIntoView({ behavior: 'smooth', block: 'center' }); }); await new Promise(resolve => setTimeout(resolve, 300)); // 点击 await element.click(); this.log('debug', '✓ 点击完成'); // 验证点击后的变化(新元素出现 / 旧元素消失) if (this.config.verifyAfter) { await this.verifyAfterClick(this.config.verifyAfter); } // 等待页面变化(如果配置了) if (this.config.waitForPageChange) { await this.waitForPageChange(this.config.checkSelector); } // 可选的等待时间 if (this.config.waitAfter) { await new Promise(resolve => setTimeout(resolve, this.config.waitAfter)); } return { success: true }; } /** * 验证点击后的变化 */ async verifyAfterClick(config) { const { appears, disappears, timeout = 10000 } = config; // 验证新元素出现 if (appears) { this.log('debug', '验证新元素出现...'); for (const selector of (Array.isArray(appears) ? appears : [appears])) { try { await this.page.waitForSelector(selector, { timeout, visible: true }); this.log('debug', `✓ 新元素已出现: ${selector}`); } catch (error) { throw new Error(`点击后验证失败: 元素 "${selector}" 未出现`); } } } // 验证旧元素消失 if (disappears) { this.log('debug', '验证旧元素消失...'); for (const selector of (Array.isArray(disappears) ? disappears : [disappears])) { try { await this.page.waitForSelector(selector, { timeout, hidden: true }); this.log('debug', `✓ 旧元素已消失: ${selector}`); } catch (error) { throw new Error(`点击后验证失败: 元素 "${selector}" 未消失`); } } } } /** * 等待页面内容变化 */ async waitForPageChange(checkSelector, timeout = 15000) { this.log('debug', '等待页面变化...'); const startTime = Date.now(); const initialUrl = this.page.url(); while (Date.now() - startTime < timeout) { // 检查 URL 是否变化 if (this.page.url() !== initialUrl) { this.log('debug', '✓ URL 已变化'); return true; } // 检查特定元素是否出现 if (checkSelector) { const smartSelector = SmartSelector.fromConfig(checkSelector, this.page); const newElement = await smartSelector.find(1000); if (newElement) { this.log('debug', '✓ 页面内容已变化'); return true; } } await new Promise(resolve => setTimeout(resolve, 500)); } this.log('warn', '等待页面变化超时'); return false; } } module.exports = ClickAction;