|
|
import { chromium } from 'playwright'; |
|
|
import config from '../config.js'; |
|
|
import { loadCookies, saveScreenshot, getHumanReadableTimestamp } from './common-utils.js'; |
|
|
import { info, error } from './logger.js'; |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function createBrowserSession(cookieFile, cookiesFromEnv) { |
|
|
info('启动浏览器...'); |
|
|
const browser = await chromium.launch(config.browserOptions); |
|
|
const context = await browser.newContext(); |
|
|
|
|
|
|
|
|
const cookies = loadCookies(cookieFile, cookiesFromEnv); |
|
|
await context.addCookies(cookies); |
|
|
|
|
|
const page = await context.newPage(); |
|
|
|
|
|
return { browser, context, page }; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function navigateToWebIDE(page) { |
|
|
info('导航到WebIDE页面...'); |
|
|
await page.goto(config.webideUrl); |
|
|
|
|
|
|
|
|
await page.waitForTimeout(config.waitTimes.pageLoad); |
|
|
|
|
|
info('当前页面URL:', page.url()); |
|
|
info('页面标题:', await page.title()); |
|
|
|
|
|
|
|
|
await handleRetryButton(page); |
|
|
|
|
|
|
|
|
|
|
|
try { |
|
|
await page.waitForSelector(config.selectors.editor, { |
|
|
timeout: 60000 |
|
|
}); |
|
|
info('成功进入WebIDE界面'); |
|
|
return true; |
|
|
} catch (err) { |
|
|
info('警告: 未检测到编辑器界面,可能需要重新登录'); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function handleRetryButton(page) { |
|
|
try { |
|
|
const retryButton = await page.waitForSelector('button.btn__21_ID', { timeout: 5000 }); |
|
|
if (retryButton && await retryButton.isVisible()) { |
|
|
info('发现"立即重试"按钮,点击处理...'); |
|
|
await retryButton.click(); |
|
|
return true; |
|
|
} |
|
|
} catch (err) { |
|
|
|
|
|
info('未发现"立即重试"按钮,继续执行...'); |
|
|
} |
|
|
return false; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function handleModalDialog(page) { |
|
|
try { |
|
|
const dialogButton = await page.waitForSelector(config.selectors.dialogButton, { timeout: 30000 }); |
|
|
if (dialogButton && await dialogButton.isVisible()) { |
|
|
info('发现模态对话框按钮,点击处理...'); |
|
|
await dialogButton.click(); |
|
|
await page.waitForTimeout(500); |
|
|
return true; |
|
|
} |
|
|
} catch (err) { |
|
|
|
|
|
info('未发现模态对话框,继续执行...'); |
|
|
} |
|
|
return false; |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function openTerminal(page) { |
|
|
info('尝试打开终端 (Ctrl+~)...'); |
|
|
|
|
|
|
|
|
await page.click('body'); |
|
|
await page.waitForTimeout(500); |
|
|
|
|
|
|
|
|
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) { |
|
|
info(`找到终端元素: ${selector}`); |
|
|
terminalFound = true; |
|
|
break; |
|
|
} |
|
|
} catch (err) { |
|
|
|
|
|
} |
|
|
} |
|
|
|
|
|
if (!terminalFound) { |
|
|
info('未找到终端元素,尝试直接输入命令...'); |
|
|
return null; |
|
|
} else { |
|
|
|
|
|
await terminalElement.click(); |
|
|
await page.waitForTimeout(500); |
|
|
return terminalElement; |
|
|
} |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
export async function executeTerminalCommand(page, command) { |
|
|
info(`执行命令: ${command}`); |
|
|
|
|
|
|
|
|
await page.keyboard.type(command); |
|
|
await page.waitForTimeout(500); |
|
|
|
|
|
|
|
|
await page.keyboard.press('Enter'); |
|
|
|
|
|
|
|
|
await page.waitForTimeout(config.waitTimes.commandExecution); |
|
|
|
|
|
info('命令已执行'); |
|
|
} |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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 (err) { |
|
|
error(`[${getHumanReadableTimestamp()}] 执行命令时发生错误:`, err); |
|
|
return false; |
|
|
} |
|
|
} |
|
|
|