新增e2e测试脚本,修复部分问题
This commit was merged in pull request #51.
This commit is contained in:
@@ -0,0 +1,199 @@
|
||||
const { sleep } = require('../helpers/automator');
|
||||
|
||||
class CourseDetailPage {
|
||||
/**
|
||||
* @param {object} miniProgram - miniprogram-automator 实例
|
||||
*/
|
||||
constructor(miniProgram) {
|
||||
this.mp = miniProgram;
|
||||
}
|
||||
|
||||
/**
|
||||
* 等待课程详情页加载完成
|
||||
*/
|
||||
async waitForLoad() {
|
||||
const page = await this.mp.currentPage();
|
||||
await page.waitFor('.detail-page', { timeout: 10000 });
|
||||
await sleep(1500); // 等待异步数据加载
|
||||
return page;
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取课程基本信息
|
||||
* @returns {Promise<{courseName: string, status: string, time: string, location: string, memberCount: string}>}
|
||||
*/
|
||||
async getCourseInfo() {
|
||||
const page = await this.mp.currentPage();
|
||||
const info = {};
|
||||
|
||||
try {
|
||||
// 课程名
|
||||
const titleEl = await page.$('.detail-title');
|
||||
info.courseName = titleEl ? (await titleEl.text()).trim() : '';
|
||||
|
||||
// 状态标签
|
||||
const statusEl = await page.$('.cover-status text');
|
||||
info.status = statusEl ? (await statusEl.text()).trim() : '';
|
||||
|
||||
// 信息项
|
||||
const infoItems = await page.$$('.info-item');
|
||||
for (const item of infoItems) {
|
||||
try {
|
||||
const labelEl = await item.$('.info-label');
|
||||
const valueEl = await item.$('.info-value');
|
||||
if (labelEl && valueEl) {
|
||||
const label = (await labelEl.text()).trim();
|
||||
const value = (await valueEl.text()).trim();
|
||||
if (label === '时间') info.time = value;
|
||||
if (label === '地点') info.location = value;
|
||||
if (label === '人数') info.memberCount = value;
|
||||
}
|
||||
} catch (e) {
|
||||
// 跳过
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
// 忽略
|
||||
}
|
||||
|
||||
return info;
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击开课按钮
|
||||
* 仅当 course.status == 0 (待开课) 时可用
|
||||
*/
|
||||
async startCourse() {
|
||||
const page = await this.mp.currentPage();
|
||||
const startBtn = await page.$('.start-btn');
|
||||
if (!startBtn) {
|
||||
throw new Error('未找到开课按钮(课程可能不是"待开课"状态)');
|
||||
}
|
||||
|
||||
// 检查按钮是否被禁用
|
||||
const isDisabled = await this._isButtonDisabled(startBtn);
|
||||
if (isDisabled) {
|
||||
throw new Error('开课按钮被禁用(尚未到开课时间)');
|
||||
}
|
||||
|
||||
await startBtn.tap();
|
||||
await sleep(3000); // 等待开课请求完成
|
||||
}
|
||||
|
||||
/**
|
||||
* 点击结课按钮
|
||||
* 仅当 course.status == 3 || 7 (进行中) 时可用
|
||||
*/
|
||||
async endCourse() {
|
||||
const page = await this.mp.currentPage();
|
||||
const endBtn = await page.$('.end-btn');
|
||||
if (!endBtn) {
|
||||
throw new Error('未找到结课按钮(课程可能不是"进行中"状态)');
|
||||
}
|
||||
|
||||
const isDisabled = await this._isButtonDisabled(endBtn);
|
||||
if (isDisabled) {
|
||||
throw new Error('结课按钮被禁用(尚未到结课时间)');
|
||||
}
|
||||
|
||||
await endBtn.tap();
|
||||
await sleep(3000); // 等待结课请求完成
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取学员列表
|
||||
* 注意:当前课程详情页设计中没有独立的学员列表区域,
|
||||
* 学员人数信息在 info-card 中展示。
|
||||
* @returns {Promise<{count: number, max: number}>}
|
||||
*/
|
||||
async getStudentList() {
|
||||
const info = await this.getCourseInfo();
|
||||
if (info.memberCount) {
|
||||
const match = info.memberCount.match(/(\d+)\s*\/\s*(\d+)/);
|
||||
if (match) {
|
||||
return {
|
||||
count: parseInt(match[1], 10),
|
||||
max: parseInt(match[2], 10)
|
||||
};
|
||||
}
|
||||
}
|
||||
return { count: 0, max: 0 };
|
||||
}
|
||||
|
||||
/**
|
||||
* 生成签到二维码
|
||||
* 注意:当前课程详情页没有直接的生成二维码按钮。
|
||||
* 二维码通常通过后端 API 生成,MiniTest 中可通过 evaluate 调用 API。
|
||||
*/
|
||||
async generateQRCode() {
|
||||
const page = await this.mp.currentPage();
|
||||
// 通过 evaluate 在小程序环境中生成二维码
|
||||
// 实际二维码生成逻辑取决于后端 API
|
||||
try {
|
||||
const qrData = await this.mp.evaluate(() => {
|
||||
// 尝试获取当前课程的签到信息
|
||||
const pages = getCurrentPages();
|
||||
const currentPage = pages[pages.length - 1];
|
||||
return {
|
||||
courseId: currentPage.courseId || '',
|
||||
timestamp: Date.now()
|
||||
};
|
||||
});
|
||||
return qrData;
|
||||
} catch (e) {
|
||||
console.warn('[CourseDetailPage] 生成二维码失败:', e.message);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* 获取操作按钮状态
|
||||
*/
|
||||
async getActionButtonStatus() {
|
||||
const page = await this.mp.currentPage();
|
||||
try {
|
||||
const startBtn = await page.$('.start-btn');
|
||||
if (startBtn) {
|
||||
const text = (await startBtn.text()).trim();
|
||||
const isDisabled = await this._isButtonDisabled(startBtn);
|
||||
return { type: 'start', text, disabled: isDisabled };
|
||||
}
|
||||
|
||||
const endBtn = await page.$('.end-btn');
|
||||
if (endBtn) {
|
||||
const text = (await endBtn.text()).trim();
|
||||
const isDisabled = await this._isButtonDisabled(endBtn);
|
||||
return { type: 'end', text, disabled: isDisabled };
|
||||
}
|
||||
|
||||
const disabledBtn = await page.$('.disabled-btn');
|
||||
if (disabledBtn) {
|
||||
const text = (await disabledBtn.text()).trim();
|
||||
return { type: 'disabled', text, disabled: true };
|
||||
}
|
||||
} catch (e) {
|
||||
// 忽略
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* 内部方法:检查按钮是否被禁用
|
||||
*/
|
||||
async _isButtonDisabled(btnElement) {
|
||||
try {
|
||||
const disabled = await btnElement.attribute('disabled');
|
||||
if (disabled === 'true' || disabled === true || disabled === '') {
|
||||
return true;
|
||||
}
|
||||
// 也检查 CSS class
|
||||
const className = await btnElement.attribute('class');
|
||||
return (className || '').includes('disabled');
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
module.exports = CourseDetailPage;
|
||||
Reference in New Issue
Block a user