const automator = require('miniprogram-automator'); const path = require('path'); const PROJECT_PATH = path.resolve(__dirname, '../../unpackage/dist/dev/mp-weixin'); const CLI_PATH = 'D:\\wechat-dev-tools\\cli.bat'; const DEVTOOL_PORT = 45869; /** * 启动微信小程序 * @returns {Promise} */ async function launchMiniProgram() { console.log('[automator] 启动小程序...'); const miniProgram = await automator.launch({ projectPath: PROJECT_PATH, cliPath: CLI_PATH, port: DEVTOOL_PORT }); console.log('[automator] 小程序已启动'); return miniProgram; } /** * 连接已在运行的小程序 */ async function connectMiniProgram() { return automator.connect({ port: DEVTOOL_PORT }); } /** * 模拟微信登录流程 * 通过调用 wx.login 获取 code,触发后端登录 * @param {MiniProgram} miniProgram * @returns {Promise} */ async function loginAsMember(miniProgram) { console.log('[automator] 执行会员登录流程...'); try { // 调用微信登录接口 await miniProgram.callWxMethod('login', {}); } catch (err) { console.warn('[automator] wx.login 调用异常(可能已在模拟器中自动完成):', err.message); } // 等待登录完成并跳转到首页 await miniProgram.waitFor(1000); } /** * 等待当前页面 URL 匹配指定模式 * @param {MiniProgram} miniProgram * @param {string} urlPattern - 页面路径模式 * @param {number} timeout - 超时时间(ms) * @returns {Promise} */ async function waitForPage(miniProgram, urlPattern, timeout = 30000) { const startTime = Date.now(); while (Date.now() - startTime < timeout) { try { const page = await miniProgram.currentPage(); if (page && page.path && page.path.includes(urlPattern)) { console.log(`[automator] 页面已加载: ${page.path}`); return page; } } catch (e) { // 页面尚未准备好,继续等待 } await miniProgram.waitFor(500); } throw new Error(`等待页面 "${urlPattern}" 超时 (${timeout}ms)`); } /** * 截图保存 * @param {MiniProgram} miniProgram * @param {string} name - 截图名称 * @returns {Promise} 截图文件路径 */ async function screenshot(miniProgram, name) { const screenshotsDir = path.resolve(__dirname, '../screenshots'); const fs = require('fs'); if (!fs.existsSync(screenshotsDir)) { fs.mkdirSync(screenshotsDir, { recursive: true }); } const timestamp = Date.now(); const safeName = name.replace(/[^a-zA-Z0-9_-]/g, '_'); const filePath = path.join(screenshotsDir, `${timestamp}_${safeName}.png`); await miniProgram.screenshot({ path: filePath }); console.log(`[automator] 截图已保存: ${filePath}`); return filePath; } /** * 通过 TabBar 切换页面 * @param {MiniProgram} miniProgram * @param {number} index - TabBar 索引 (0:首页, 1:课程, 2:我的课程, 3:我的) * @returns {Promise} */ async function switchTab(miniProgram, index) { console.log(`[automator] 切换到 TabBar 索引: ${index}`); await miniProgram.callWxMethod('switchTab', { url: getTabBarUrl(index) }); await miniProgram.waitFor(1000); } /** * 获取 TabBar 页面 URL */ function getTabBarUrl(index) { const tabs = [ '/pages/index/index', '/pages/search/search', '/pages/my-courses/my-courses', '/pages/profile/profile' ]; return tabs[index] || tabs[0]; } /** * 生成唯一测试数据标识 */ function generateTestId() { return `e2e_${Date.now()}_${Math.random().toString(36).substring(2, 8)}`; } module.exports = { launchMiniProgram, connectMiniProgram, loginAsMember, waitForPage, screenshot, switchTab, getTabBarUrl, generateTestId, PROJECT_PATH, CLI_PATH, DEVTOOL_PORT };