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 CLI_PORT = 45869; const BASE_URL = 'http://192.168.110.64:8084/api'; let miniProgram = null; /** * 启动微信小程序 */ async function launchMiniProgram() { miniProgram = await automator.launch({ projectPath: PROJECT_PATH, cliPath: CLI_PATH, port: CLI_PORT }); return miniProgram; } /** * 关闭小程序连接 */ async function closeMiniProgram() { if (miniProgram) { try { await miniProgram.close(); } catch (e) { console.warn('[automator] 关闭小程序失败:', e.message); } miniProgram = null; } } /** * 获取当前 miniProgram 实例 */ function getMiniProgram() { return miniProgram; } /** * 等待指定毫秒 */ function sleep(ms) { return new Promise(resolve => setTimeout(resolve, ms)); } /** * 教练端通过 username/password 登录 * @param {object} mp - miniProgram 实例 * @param {string} username * @param {string} password */ async function loginAsCoach(mp, username = 'coach_test1', password = 'Test@123') { await sleep(1500); const page = await mp.currentPage(); // 等待登录表单渲染 await page.waitFor('input', { timeout: 10000 }); // 填写用户名 const inputs = await page.$$('input'); if (inputs.length >= 2) { await inputs[0].input(username); await sleep(300); await inputs[1].input(password); await sleep(300); // 点击登录按钮 const loginBtn = await page.$('.login-btn'); if (loginBtn) { await loginBtn.tap(); } } } /** * 等待页面跳转(用于登录成功后等待首页加载) * @param {object} mp - miniProgram 实例 * @param {string} targetPath - 目标页面路径,如 'pages/index/index' * @param {number} timeoutMs */ async function waitForPage(mp, targetPath, timeoutMs = 15000) { const startTime = Date.now(); while (Date.now() - startTime < timeoutMs) { try { const page = await mp.currentPage(); if (page.path.includes(targetPath)) { return page; } } catch (e) { // 页面切换中,忽略错误 } await sleep(500); } throw new Error(`等待页面 "${targetPath}" 超时 (${timeoutMs}ms)`); } /** * 导航到指定页面 * @param {object} mp - miniProgram 实例 * @param {string} url - 小程序页面路径,如 '/pages/course-list/course-list' */ async function navigateTo(mp, url) { await mp.navigateTo(url); await sleep(1500); return mp.currentPage(); } /** * 检查后端服务可用性 */ async function checkBackendHealth() { const http = require('http'); return new Promise((resolve) => { const req = http.get(BASE_URL + '/auth/login', { timeout: 10000 }, (res) => { resolve(true); }); req.on('error', () => { console.warn('[automator] 后端服务不可达:', BASE_URL); resolve(false); }); req.on('timeout', () => { req.destroy(); console.warn('[automator] 后端服务连接超时:', BASE_URL); resolve(false); }); }); } module.exports = { launchMiniProgram, closeMiniProgram, getMiniProgram, loginAsCoach, waitForPage, navigateTo, sleep, checkBackendHealth, BASE_URL, CLI_PORT };