import { chromium } from 'playwright'; import config from '../config.js'; import { loadCookies, saveScreenshot, getHumanReadableTimestamp } from './common-utils.js'; /** * 创建浏览器实例和上下文 * @param {string} cookieFile - Cookie 文件路径 * @returns {Object} { browser, context, page } */ export async function createBrowserSession(cookieFile) { console.log('启动浏览器...'); const browser = await chromium.launch(config.browserOptions); const context = await browser.newContext(); // 读取并设置cookies const cookies = loadCookies(cookieFile); await context.addCookies(cookies); const page = await context.newPage(); return { browser, context, page }; } /** * 导航到 WebIDE 页面并验证登录状态 * @param {Object} page - Playwright 页面对象 */ export async function navigateToWebIDE(page) { console.log('导航到WebIDE页面...'); await page.goto(config.webideUrl); // 等待页面加载 await page.waitForTimeout(config.waitTimes.pageLoad); console.log('当前页面URL:', page.url()); console.log('页面标题:', await page.title()); // 检查是否成功登录 try { await page.waitForSelector(config.selectors.editor, { timeout: 60000 }); console.log('成功进入WebIDE界面'); return true; } catch (error) { console.log('警告: 未检测到编辑器界面,可能需要重新登录'); return false; } } /** * 处理模态对话框 * @param {Object} page - Playwright 页面对象 */ export async function handleModalDialog(page) { try { const dialogButton = await page.waitForSelector(config.selectors.dialogButton, { timeout: 30000 }); if (dialogButton && await dialogButton.isVisible()) { console.log('发现模态对话框按钮,点击处理...'); await dialogButton.click(); await page.waitForTimeout(500); return true; } } catch (error) { // 没有找到对话框按钮,继续执行 console.log('未发现模态对话框,继续执行...'); } return false; } /** * 打开终端 * @param {Object} page - Playwright 页面对象 * @returns {Object|null} 终端元素或 null */ export async function openTerminal(page) { console.log('尝试打开终端 (Ctrl+~)...'); // 确保页面获得焦点 await page.click('body'); await page.waitForTimeout(500); // 按下 Ctrl+~ 打开终端 await page.keyboard.press('Control+`'); // 等待终端打开 await page.waitForTimeout(config.waitTimes.terminalOpen); // 尝试多种方式查找终端 const terminalSelectors = config.selectors.terminals; let terminalFound = false; let terminalElement = null; for (const selector of terminalSelectors) { try { terminalElement = await page.waitForSelector(selector, { timeout: 2000 }); if (terminalElement) { console.log(`找到终端元素: ${selector}`); terminalFound = true; break; } } catch (error) { // 继续尝试下一个选择器 } } if (!terminalFound) { console.log('未找到终端元素,尝试直接输入命令...'); return null; } else { // 点击终端区域确保焦点 await terminalElement.click(); await page.waitForTimeout(500); return terminalElement; } } /** * 在终端中执行命令 * @param {Object} page - Playwright 页面对象 * @param {string} command - 要执行的命令 */ export async function executeTerminalCommand(page, command) { console.log(`执行命令: ${command}`); // 输入命令 await page.keyboard.type(command); await page.waitForTimeout(500); // 按回车执行命令 await page.keyboard.press('Enter'); // 等待命令执行 await page.waitForTimeout(config.waitTimes.commandExecution); console.log('命令已执行'); } /** * 完整的命令执行流程 * @param {Object} page - Playwright 页面对象 * @param {string} screenshotPrefix - 截图文件名前缀 * @returns {boolean} 执行是否成功 */ export async function executeCommandFlow(page, screenshotPrefix = 'screenshot') { try { // 处理模态对话框 await handleModalDialog(page); // 打开终端 await openTerminal(page); // 执行命令 await executeTerminalCommand(page, config.command); // 截图保存执行结果 // const screenshotDir = config.screenshotDir || './screenshots'; // const screenshotPath = await saveScreenshot(page, screenshotDir, screenshotPrefix); return true; } catch (error) { console.error(`[${getHumanReadableTimestamp()}] 执行命令时发生错误:`, error); return false; } }