cloudstudio-runner / utils /webide-utils.js
github-actions[bot]
Update from GitHub Actions
844fe52
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;
}
}