|
|
@@ -49,6 +49,35 @@ class BaseTestCase {
|
|
|
this.status = 'running';
|
|
|
}
|
|
|
|
|
|
+ normalizeSnapshot(snapshot) {
|
|
|
+ if (!snapshot) {
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(snapshot)) {
|
|
|
+ return snapshot;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(snapshot.elements)) {
|
|
|
+ return snapshot.elements;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(snapshot.nodes)) {
|
|
|
+ return snapshot.nodes;
|
|
|
+ }
|
|
|
+
|
|
|
+ if (Array.isArray(snapshot.items)) {
|
|
|
+ return snapshot.items;
|
|
|
+ }
|
|
|
+
|
|
|
+ return [];
|
|
|
+ }
|
|
|
+
|
|
|
+ findByText(snapshot, text) {
|
|
|
+ const items = this.normalizeSnapshot(snapshot);
|
|
|
+ return items.find(item => typeof item.text === 'string' && item.text.includes(text));
|
|
|
+ }
|
|
|
+
|
|
|
/**
|
|
|
* 截图
|
|
|
*/
|
|
|
@@ -67,12 +96,22 @@ class BaseTestCase {
|
|
|
text: [selector],
|
|
|
timeout: timeout
|
|
|
});
|
|
|
+
|
|
|
+ const snapshot = await this.getSnapshot();
|
|
|
+ const match = this.findByText(snapshot, selector);
|
|
|
+ if (!match || !match.uid) {
|
|
|
+ throw new Error(`未找到可交互元素: ${selector}`);
|
|
|
+ }
|
|
|
+ return match;
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
* 点击元素
|
|
|
*/
|
|
|
async click(uid) {
|
|
|
+ if (!uid) {
|
|
|
+ throw new Error('点击失败:缺少元素 uid');
|
|
|
+ }
|
|
|
await chrome_devtools_click({ uid: uid });
|
|
|
}
|
|
|
|
|
|
@@ -80,6 +119,9 @@ class BaseTestCase {
|
|
|
* 填充输入框
|
|
|
*/
|
|
|
async fill(uid, value) {
|
|
|
+ if (!uid) {
|
|
|
+ throw new Error('填充失败:缺少元素 uid');
|
|
|
+ }
|
|
|
await chrome_devtools_fill({ uid: uid, value: value });
|
|
|
}
|
|
|
|
|
|
@@ -87,7 +129,8 @@ class BaseTestCase {
|
|
|
* 获取页面快照
|
|
|
*/
|
|
|
async getSnapshot() {
|
|
|
- return await chrome_devtools_take_snapshot({});
|
|
|
+ const snapshot = await chrome_devtools_take_snapshot({});
|
|
|
+ return this.normalizeSnapshot(snapshot);
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
@@ -184,8 +227,7 @@ class TASK_002_TestCase extends BaseTestCase {
|
|
|
await this.setup();
|
|
|
|
|
|
// 1. 创建任务页面
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const createTaskBtn = snapshot.find(item => item.text.includes('创建任务'));
|
|
|
+ const createTaskBtn = await this.waitForElement('创建任务');
|
|
|
await this.click(createTaskBtn.uid);
|
|
|
|
|
|
// 2. 输入任务名称
|
|
|
@@ -234,8 +276,7 @@ class TASK_003_TestCase extends BaseTestCase {
|
|
|
await this.setup();
|
|
|
|
|
|
// 1. 创建任务
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const createTaskBtn = snapshot.find(item => item.text.includes('创建任务'));
|
|
|
+ const createTaskBtn = await this.waitForElement('创建任务');
|
|
|
await this.click(createTaskBtn.uid);
|
|
|
|
|
|
// 2. 设置截止时间
|
|
|
@@ -273,32 +314,31 @@ class TASK_003_TestCase extends BaseTestCase {
|
|
|
}
|
|
|
|
|
|
/**
|
|
|
- * TASK-005: 设置任务分类(学习类/生活类/运动类/其他)
|
|
|
+ * TASK-005: 设置任务分类(学习类/生活类/运动类/游戏类/其他)
|
|
|
*/
|
|
|
class TASK_005_TestCase extends BaseTestCase {
|
|
|
constructor() {
|
|
|
- super('TASK-005', '设置任务分类(学习类/生活类/运动类/其他)', 'P0');
|
|
|
+ super('TASK-005', '设置任务分类(学习类/生活类/运动类/游戏类/其他)', 'P0');
|
|
|
}
|
|
|
|
|
|
async run() {
|
|
|
try {
|
|
|
await this.setup();
|
|
|
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const createTaskBtn = snapshot.find(item => item.text.includes('创建任务'));
|
|
|
+ const createTaskBtn = await this.waitForElement('创建任务');
|
|
|
await this.click(createTaskBtn.uid);
|
|
|
|
|
|
const categoryField = await this.waitForElement('任务分类');
|
|
|
await this.click(categoryField.uid);
|
|
|
await this.screenshot('01_open_category');
|
|
|
|
|
|
- const studyOption = await this.waitForElement('学习类');
|
|
|
- await this.click(studyOption.uid);
|
|
|
+ const gameOption = await this.waitForElement('游戏类');
|
|
|
+ await this.click(gameOption.uid);
|
|
|
await this.screenshot('02_select_category');
|
|
|
|
|
|
const result = await this.getSnapshot();
|
|
|
const hasCategory = result.some(item =>
|
|
|
- item.text.includes('学习类') ||
|
|
|
+ item.text.includes('游戏类') ||
|
|
|
item.text.includes('任务分类')
|
|
|
);
|
|
|
|
|
|
@@ -322,8 +362,7 @@ class TASK_008_TestCase extends BaseTestCase {
|
|
|
await this.setup();
|
|
|
|
|
|
// 1. 切换到孩子模式
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const switchBtn = snapshot.find(item => item.text.includes('切换模式'));
|
|
|
+ const switchBtn = await this.waitForElement('切换模式');
|
|
|
await this.click(switchBtn.uid);
|
|
|
|
|
|
// 2. 输入孩子密码
|
|
|
@@ -366,8 +405,7 @@ class TASK_009_TestCase extends BaseTestCase {
|
|
|
await this.setup();
|
|
|
|
|
|
// 1. 进入孩子模式
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const childModeBtn = snapshot.find(item => item.role === 'child');
|
|
|
+ const childModeBtn = await this.waitForElement('孩子模式');
|
|
|
await this.click(childModeBtn.uid);
|
|
|
|
|
|
// 2. 选择一个待完成的任务
|
|
|
@@ -693,7 +731,7 @@ class POINT_001_TestCase extends BaseTestCase {
|
|
|
const beforeValue = parseInt(pointsBefore?.text.match(/\d+/)?.[0] || '0');
|
|
|
|
|
|
// 2. 完成一个任务
|
|
|
- const task = snapshotBefore.find(item => item.text.includes('任务'));
|
|
|
+ const task = this.findByText(snapshotBefore, '任务');
|
|
|
await this.click(task.uid);
|
|
|
|
|
|
const completeBtn = await this.waitForElement('完成');
|
|
|
@@ -851,25 +889,24 @@ class POINT_007_TestCase extends BaseTestCase {
|
|
|
*/
|
|
|
class POINT_008_TestCase extends BaseTestCase {
|
|
|
constructor() {
|
|
|
- super('POINT-008', '扣分功能按年龄配置:6岁以下默认关闭,6岁及以上默认开启', 'P0');
|
|
|
+ super('POINT-008', '扣分功能按年龄配置:9岁以下默认关闭,9岁及以上默认开启', 'P0');
|
|
|
}
|
|
|
|
|
|
async run() {
|
|
|
try {
|
|
|
await this.setup();
|
|
|
|
|
|
- // 测试6岁以下孩子
|
|
|
- // 1. 设置孩子年龄为5岁
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const settingsBtn = snapshot.find(item => item.text.includes('设置'));
|
|
|
+ // 测试9岁以下孩子
|
|
|
+ // 1. 设置孩子年龄为8岁
|
|
|
+ const settingsBtn = await this.waitForElement('设置');
|
|
|
await this.click(settingsBtn.uid);
|
|
|
|
|
|
const childInfoBtn = await this.waitForElement('孩子信息');
|
|
|
await this.click(childInfoBtn.uid);
|
|
|
|
|
|
const ageInput = await this.waitForElement('年龄');
|
|
|
- await this.fill(ageInput.uid, '5');
|
|
|
- await this.screenshot('01_child_age_5');
|
|
|
+ await this.fill(ageInput.uid, '8');
|
|
|
+ await this.screenshot('01_child_age_8');
|
|
|
|
|
|
// 2. 验证扣分开关默认关闭
|
|
|
const penaltySwitch = await this.getSnapshot();
|
|
|
@@ -878,10 +915,10 @@ class POINT_008_TestCase extends BaseTestCase {
|
|
|
item.status === 'disabled'
|
|
|
);
|
|
|
|
|
|
- // 测试6岁及以上
|
|
|
- // 3. 设置孩子年龄为7岁
|
|
|
- await this.fill(ageInput.uid, '7');
|
|
|
- await this.screenshot('02_child_age_7');
|
|
|
+ // 测试9岁及以上
|
|
|
+ // 3. 设置孩子年龄为9岁
|
|
|
+ await this.fill(ageInput.uid, '9');
|
|
|
+ await this.screenshot('02_child_age_9');
|
|
|
|
|
|
// 4. 验证扣分开关默认开启
|
|
|
const penaltyEnabled = await this.getSnapshot();
|
|
|
@@ -950,8 +987,7 @@ class REWARD_001_TestCase extends BaseTestCase {
|
|
|
await this.setup();
|
|
|
|
|
|
// 1. 进入孩子模式
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const childModeBtn = snapshot.find(item => item.text.includes('孩子'));
|
|
|
+ const childModeBtn = await this.waitForElement('孩子');
|
|
|
await this.click(childModeBtn.uid);
|
|
|
|
|
|
// 2. 进入心愿单
|
|
|
@@ -1002,8 +1038,7 @@ class REWARD_001A_TestCase extends BaseTestCase {
|
|
|
try {
|
|
|
await this.setup();
|
|
|
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const wishlistBtn = snapshot.find(item => item.text.includes('心愿单'));
|
|
|
+ const wishlistBtn = await this.waitForElement('心愿单');
|
|
|
await this.click(wishlistBtn.uid);
|
|
|
|
|
|
const wishItem = await this.waitForElement('去游乐园玩');
|
|
|
@@ -1044,8 +1079,7 @@ class REWARD_002A_TestCase extends BaseTestCase {
|
|
|
try {
|
|
|
await this.setup();
|
|
|
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const rewardPoolBtn = snapshot.find(item => item.text.includes('奖励库'));
|
|
|
+ const rewardPoolBtn = await this.waitForElement('奖励库');
|
|
|
await this.click(rewardPoolBtn.uid);
|
|
|
|
|
|
const rewardItem = await this.waitForElement('去游乐园玩');
|
|
|
@@ -1086,8 +1120,7 @@ class REWARD_002B_TestCase extends BaseTestCase {
|
|
|
try {
|
|
|
await this.setup();
|
|
|
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const switchChildBtn = snapshot.find(item => item.text.includes('切换孩子'));
|
|
|
+ const switchChildBtn = await this.waitForElement('切换孩子');
|
|
|
await this.click(switchChildBtn.uid);
|
|
|
|
|
|
const childA = await this.waitForElement('测试孩子1');
|
|
|
@@ -1127,8 +1160,7 @@ class DAN_001_TestCase extends BaseTestCase {
|
|
|
try {
|
|
|
await this.setup();
|
|
|
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const danBtn = snapshot.find(item => item.text.includes('DAN测评'));
|
|
|
+ const danBtn = await this.waitForElement('DAN测评');
|
|
|
await this.click(danBtn.uid);
|
|
|
|
|
|
const syncBtn = await this.waitForElement('同步测评数据');
|
|
|
@@ -1267,8 +1299,7 @@ class MODE_002_TestCase extends BaseTestCase {
|
|
|
await this.setup();
|
|
|
|
|
|
// 1. 切换到孩子模式
|
|
|
- const snapshot = await this.getSnapshot();
|
|
|
- const switchBtn = snapshot.find(item => item.text.includes('切换'));
|
|
|
+ const switchBtn = await this.waitForElement('切换');
|
|
|
await this.click(switchBtn.uid);
|
|
|
|
|
|
const passwordInput = await this.waitForElement('密码');
|
|
|
@@ -1348,7 +1379,7 @@ class MODE_003_TestCase extends BaseTestCase {
|
|
|
const result = await this.getSnapshot();
|
|
|
const switched = result.some(item =>
|
|
|
item.text.includes('孩子') ||
|
|
|
- item.role === 'child'
|
|
|
+ item.text.includes('任务')
|
|
|
);
|
|
|
|
|
|
this.logResult(hasPasswordInput && switched);
|