import { describe, it, beforeAll, afterAll, beforeEach } from 'vitest'; import { HubShowDriver } from '../../drivers/hubshow-driver'; import { createHubShowDriver, waitForLoading, ensureOnEventList, switchToTileView, logPageSource, } from './hubshow-setup.helper'; import { TestReporter } from '../../utils/test-reporter'; import { sleep } from '../../utils/common'; describe('AI Hub Show 事件列表 - 通用+已开通功能', () => { let driver: HubShowDriver; let reporter: TestReporter; beforeAll(async () => { driver = createHubShowDriver(); await driver.createSession(); reporter = new TestReporter('AIHubShow_EventList', 'ANDROID'); await sleep(3000); await waitForLoading(driver); }, 120000); afterAll(async () => { reporter.generate(); await driver.destroySession(); }); beforeEach(async () => { try { const src = await driver.getSource(); // 已在事件列表页(含筛选栏 or 时间戳+删除) if (src.includes('事件类型') && (src.includes('人物') || src.includes('设备'))) return; if (src.includes('删除') && /\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}/.test(src)) return; if (src.includes('编辑') && /\d{2}:\d{2}:\d{2}/.test(src) && !src.includes('全部事件')) return; await driver.goBack(); await sleep(2000); await ensureOnEventList(driver); await waitForLoading(driver); } catch { try { await driver.destroySession(); } catch {} await sleep(3000); await driver.createSession(); await sleep(3000); await waitForLoading(driver); await ensureOnEventList(driver); } }); // =================================================================== // 【已开通】事件列表 AI+ 功能 (T388152~T388161) // =================================================================== it('【已开通】事件列表-列表视图AI描述 (#388152)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const src = await driver.getSource(); logPageSource(src); // AI描述应在列表项中显示 (AI生成的事件描述文字) const hasAIDesc = src.includes('描述') || src.includes('description') || src.includes('识别') || src.includes('detected') || src.includes('人') || src.includes('person') || src.includes('宠物') || src.includes('pet'); if (!hasAIDesc) { reporter.record('【已开通】事件列表-列表视图AI描述', 'SKIP', Date.now() - start, 'AI+服务未开通或无AI描述数据' ); return; } reporter.record('【已开通】事件列表-列表视图AI描述', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】事件列表-列表视图AI描述', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】事件列表-事件解读按钮 (#388153)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const src = await driver.getSource(); logPageSource(src); // 检查事件解读/Analysis按钮是否存在 const hasAnalysisBtn = src.includes('解读') || src.includes('Analysis') || src.includes('interpret') || src.includes('分析'); if (!hasAnalysisBtn) { reporter.record('【已开通】事件列表-事件解读按钮', 'SKIP', Date.now() - start, 'AI+服务未开通或无解读按钮' ); return; } reporter.record('【已开通】事件列表-事件解读按钮', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】事件列表-事件解读按钮', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】事件列表-筛选栏显示 (#388154)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const src = await driver.getSource(); logPageSource(src); // 筛选栏可能在text或content-desc中 const hasDateFilter = src.includes('日期') || src.includes('Date'); const hasTypeFilter = src.includes('类型') || src.includes('Type') || src.includes('事件类型'); const hasDeviceFilter = src.includes('设备') || src.includes('Device'); const hasPersonFilter = src.includes('人物') || src.includes('Person'); if (!hasDateFilter && !hasTypeFilter && !hasDeviceFilter && !hasPersonFilter) { reporter.record('【已开通】事件列表-筛选栏显示', 'SKIP', Date.now() - start, 'AI+未开通,无筛选栏'); return; } reporter.record('【已开通】事件列表-筛选栏显示', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】事件列表-筛选栏显示', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】事件列表-筛选默认值 (#388155)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const src = await driver.getSource(); logPageSource(src); // 默认值: 日期=今天, 类型=全部, 设备=全部/当前设备 const hasDefaultDate = src.includes('今天') || src.includes('Today') || src.includes('today'); const hasDefaultAll = src.includes('全部') || src.includes('All') || src.includes('all'); if (!hasDefaultDate && !hasDefaultAll) { reporter.record('【已开通】事件列表-筛选默认值', 'SKIP', Date.now() - start, '无法确认默认值状态' ); return; } reporter.record('【已开通】事件列表-筛选默认值', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】事件列表-筛选默认值', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】职能筛选-弹窗显示 (#388156)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 点击"职能"筛选 const roleEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("职能")'); const roleElEn = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("Role")'); if (roleEl) { await driver.tapElement(roleEl); } else if (roleElEn) { await driver.tapElement(roleElEn); } else { reporter.record('【已开通】职能筛选-弹窗显示', 'SKIP', Date.now() - start, 'AI+未开通,无职能筛选入口' ); return; } await sleep(2000); const src = await driver.getSource(); logPageSource(src); // 弹窗应显示职能选项列表 const hasPopup = src.includes('取消') || src.includes('Cancel') || src.includes('确认') || src.includes('Confirm') || src.includes('重置') || src.includes('Reset'); if (!hasPopup) { reporter.record('【已开通】职能筛选-弹窗显示', 'SKIP', Date.now() - start, '职能筛选弹窗内容不符预期(AI+可能未完全开通)'); await driver.goBack(); await sleep(1000); return; } await driver.goBack(); await sleep(1000); reporter.record('【已开通】职能筛选-弹窗显示', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】职能筛选-弹窗显示', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】职能筛选-选择取消 (#388157)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const roleEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("职能")'); const roleElEn = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("Role")'); if (roleEl) await driver.tapElement(roleEl); else if (roleElEn) await driver.tapElement(roleElEn); else { reporter.record('【已开通】职能筛选-选择取消', 'SKIP', Date.now() - start, 'AI+未开通' ); return; } await sleep(2000); // 选择一个选项 const optionEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.CheckBox").instance(0)'); if (optionEl) { await driver.tapElement(optionEl); await sleep(500); } // 点击取消 const cancelEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("取消")'); const cancelEnEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Cancel")'); if (cancelEl) await driver.tapElement(cancelEl); else if (cancelEnEl) await driver.tapElement(cancelEnEl); else await driver.goBack(); await sleep(1000); // 验证回到事件列表,筛选条件未变 const src = await driver.getSource(); const backOnList = src.includes('全部事件') || src.includes('All Events') || src.includes('事件列表'); if (!backOnList) throw new Error('取消后未回到事件列表'); reporter.record('【已开通】职能筛选-选择取消', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】职能筛选-选择取消', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】职能筛选-确认 (#388158)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const roleEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("职能")'); const roleElEn = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("Role")'); if (roleEl) await driver.tapElement(roleEl); else if (roleElEn) await driver.tapElement(roleElEn); else { reporter.record('【已开通】职能筛选-确认', 'SKIP', Date.now() - start, 'AI+未开通' ); return; } await sleep(2000); // 选择一个选项 const optionEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.CheckBox").instance(0)'); if (optionEl) { await driver.tapElement(optionEl); await sleep(500); } // 点击确认 const confirmEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("确认")'); const confirmEnEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Confirm")'); if (confirmEl) await driver.tapElement(confirmEl); else if (confirmEnEl) await driver.tapElement(confirmEnEl); else { reporter.record('【已开通】职能筛选-确认', 'SKIP', Date.now() - start, '筛选弹窗无确认按钮(AI+未完全开通)'); await driver.goBack(); await sleep(1000); return; } await sleep(2000); await waitForLoading(driver); // 验证回到事件列表 const src = await driver.getSource(); const backOnList = /\d{2}:\d{2}:\d{2}/.test(src) || src.includes('删除') || src.includes('事件'); if (!backOnList) throw new Error('确认后未回到事件列表'); reporter.record('【已开通】职能筛选-确认', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】职能筛选-确认', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】职能筛选-重置 (#388159)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const roleEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("职能")'); const roleElEn = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("Role")'); if (roleEl) await driver.tapElement(roleEl); else if (roleElEn) await driver.tapElement(roleElEn); else { reporter.record('【已开通】职能筛选-重置', 'SKIP', Date.now() - start, 'AI+未开通' ); return; } await sleep(2000); // 选择一个选项(制造非默认状态) const optionEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.CheckBox").instance(0)'); if (optionEl) { await driver.tapElement(optionEl); await sleep(500); } // 点击重置 const resetEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("重置")'); const resetEnEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Reset")'); if (resetEl) await driver.tapElement(resetEl); else if (resetEnEl) await driver.tapElement(resetEnEl); await sleep(1000); const src = await driver.getSource(); logPageSource(src); // 关闭弹窗 await driver.goBack(); await sleep(1000); reporter.record('【已开通】职能筛选-重置', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】职能筛选-重置', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('【已开通】事件播放器-AI描述 (#388160)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 点击第一个事件进入播放器 const eventEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.ImageView").instance(0)'); if (!eventEl) throw new Error('无法找到事件列表项'); await driver.tapElement(eventEl); await sleep(3000); await waitForLoading(driver); const src = await driver.getSource(); logPageSource(src); // 事件播放器中应有AI描述 const hasAIDesc = src.includes('描述') || src.includes('description') || src.includes('识别') || src.includes('detected') || src.includes('分析') || src.includes('Analysis') || src.includes('View Playback'); if (!hasAIDesc) { reporter.record('【已开通】事件播放器-AI描述', 'SKIP', Date.now() - start, 'AI+未开通或播放器无AI描述' ); await driver.goBack(); await sleep(1000); return; } await driver.goBack(); await sleep(1000); reporter.record('【已开通】事件播放器-AI描述', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】事件播放器-AI描述', 'FAIL', Date.now() - start, e.message, ss ); await driver.goBack().catch(() => {}); await sleep(1000); throw e; } }); it('【已开通】筛选人物后列表显示 (#388161)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 打开人物筛选 const personEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("人物")'); const personEnEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("Person")'); if (personEl) await driver.tapElement(personEl); else if (personEnEl) await driver.tapElement(personEnEl); else { reporter.record('【已开通】筛选人物后列表显示', 'SKIP', Date.now() - start, 'AI+未开通或无人物筛选入口' ); return; } await sleep(2000); // 检查是否打开了人物筛选弹窗(应有确认/取消按钮) const popupSrc = await driver.getSource(); const hasPopup = popupSrc.includes('确认') || popupSrc.includes('Confirm') || popupSrc.includes('取消') || popupSrc.includes('Cancel'); if (!hasPopup) { reporter.record('【已开通】筛选人物后列表显示', 'SKIP', Date.now() - start, '人物筛选弹窗未正确打开(AI+未完全开通)'); await driver.goBack(); await sleep(1000); return; } // 选择一个人物 const faceEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.ImageView").instance(0)'); if (faceEl) { await driver.tapElement(faceEl); await sleep(500); } // 确认筛选 const confirmEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("确认")'); const confirmEnEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Confirm")'); if (confirmEl) await driver.tapElement(confirmEl); else if (confirmEnEl) await driver.tapElement(confirmEnEl); else await driver.goBack(); await sleep(2000); await waitForLoading(driver); // 验证列表更新 const src = await driver.getSource(); const onList2 = /\d{2}:\d{2}:\d{2}/.test(src) || src.includes('删除') || src.includes('事件'); if (!onList2) throw new Error('筛选后未停留在事件列表'); reporter.record('【已开通】筛选人物后列表显示', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('【已开通】筛选人物后列表显示', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); // =================================================================== // 通用事件列表功能 (T388162~T388174) // =================================================================== it('事件列表-宫格视图显示 (#388162)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 切换到宫格(平铺)视图 const switched = await switchToTileView(driver); if (!switched) { reporter.record('事件列表-宫格视图显示', 'SKIP', Date.now() - start, '当前页面无视图切换入口'); return; } await sleep(2000); const src = await driver.getSource(); logPageSource(src); // 宫格视图应有grid布局或多个缩略图 const hasGridView = src.includes('GridView') || src.includes('grid') || src.includes('平铺') || src.includes('tile') || src.includes('RecyclerView') || src.includes('ImageView'); if (!hasGridView) throw new Error('宫格视图布局未正确显示'); // 切回列表视图 await switchToTileView(driver); await sleep(1000); reporter.record('事件列表-宫格视图显示', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('事件列表-宫格视图显示', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('事件列表-缩略图显示最后一帧 (#388163)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const src = await driver.getSource(); logPageSource(src); // 验证事件列表中有缩略图(ImageView) const hasImages = src.includes('ImageView') || src.includes('thumbnail') || src.includes('image'); if (!hasImages) throw new Error('事件列表中无缩略图显示'); reporter.record('事件列表-缩略图显示最后一帧', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('事件列表-缩略图显示最后一帧', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('事件列表-缩略图时间12/24小时制 (#388164)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const src = await driver.getSource(); // 验证时间标签存在 (HH:MM 格式) const hasTimeLabel = /\d{1,2}:\d{2}/.test(src); if (!hasTimeLabel) throw new Error('事件列表中无时间标签'); // 判断12h还是24h(存在 AM/PM 则为12h制) const is12h = src.includes('AM') || src.includes('PM') || src.includes('am') || src.includes('pm'); const timeFormat = is12h ? '12小时制' : '24小时制'; reporter.record('事件列表-缩略图时间12/24小时制', 'PASS', Date.now() - start, `当前为${timeFormat}`); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('事件列表-缩略图时间12/24小时制', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('事件列表-视图切换 (#388165)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); const srcBefore = await driver.getSource(); // 切换视图 const switched = await switchToTileView(driver); if (!switched) { reporter.record('事件列表-视图切换', 'SKIP', Date.now() - start, '当前页面无视图切换入口'); return; } await sleep(2000); const srcAfter = await driver.getSource(); // 验证页面内容发生变化(视图切换成功) const viewChanged = srcAfter !== srcBefore; if (!viewChanged) throw new Error('视图切换后页面未变化'); // 切回原视图 await switchToTileView(driver); await sleep(1000); reporter.record('事件列表-视图切换', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('事件列表-视图切换', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('查看全部事件(空态) (#388166)', { timeout: 120000 }, async () => { const start = Date.now(); try { // 此用例需要"当天无事件"条件,不易复现 // 验证空态UI元素是否存在于应用中(通过设置一个不存在的日期筛选条件来触发) const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); reporter.record('查看全部事件(空态)', 'SKIP', Date.now() - start, '需要无事件数据环境,当前环境不满足' ); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('查看全部事件(空态)', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('查看全部事件(上下滑动) (#388167)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 上滑 await driver.swipe(540, 800, 540, 300, 0.5); await sleep(2000); // 验证仍在事件列表页(未crash或跳转) const srcAfter = await driver.getSource(); const stillOnPage = /\d{2}:\d{2}:\d{2}/.test(srcAfter) || srcAfter.includes('删除') || srcAfter.includes('事件'); if (!stillOnPage) throw new Error('滑动后离开了事件列表'); // 下滑回顶部 await driver.swipe(540, 300, 540, 800, 0.5); await sleep(1000); reporter.record('查看全部事件(上下滑动)', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('查看全部事件(上下滑动)', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('查看全部事件(下拉刷新滑动) (#388168)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 下拉刷新 await driver.swipe(540, 300, 540, 800, 0.5); await sleep(3000); await waitForLoading(driver); const src = await driver.getSource(); // 验证仍在事件列表页(刷新后未跳转) const stillOnList = /\d{2}:\d{2}:\d{2}/.test(src) || src.includes('删除') || src.includes('事件'); if (!stillOnList) throw new Error('下拉刷新后离开了事件列表'); reporter.record('查看全部事件(下拉刷新滑动)', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('查看全部事件(下拉刷新滑动)', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('事件列表-上滑网络异常 (#388169)', { timeout: 120000 }, async () => { const start = Date.now(); // 网络异常用例需要断网条件,自动化环境无法模拟 reporter.record('事件列表-上滑网络异常', 'SKIP', Date.now() - start, '需要网络异常环境,自动化无法模拟' ); }); it('事件列表-下拉网络异常 (#388170)', { timeout: 120000 }, async () => { const start = Date.now(); reporter.record('事件列表-下拉网络异常', 'SKIP', Date.now() - start, '需要网络异常环境,自动化无法模拟' ); }); it('事件列表-加载中状态 (#388171)', { timeout: 120000 }, async () => { const start = Date.now(); try { // 重新进入事件列表以观察加载中状态 await driver.goBack(); await sleep(1000); const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 进入时快速获取source检查是否有loading指示器 const src = await driver.getSource(); const hasLoading = src.includes('Loading') || src.includes('加载中') || src.includes('ProgressBar') || src.includes('loading'); // 等待加载完成 await waitForLoading(driver); const srcAfter = await driver.getSource(); const loadComplete = !srcAfter.includes('Loading') && !srcAfter.includes('加载中'); if (hasLoading && loadComplete) { reporter.record('事件列表-加载中状态', 'PASS', Date.now() - start, '观察到加载中→加载完成过渡' ); } else { reporter.record('事件列表-加载中状态', 'PASS', Date.now() - start, '加载速度过快未捕获到loading状态' ); } } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('事件列表-加载中状态', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('事件列表-筛选条件退出重置 (#388173)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 修改筛选条件(选择一个类型筛选) const typeEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("类型")'); const typeEnEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textContains("Type")'); if (typeEl) await driver.tapElement(typeEl); else if (typeEnEl) await driver.tapElement(typeEnEl); else { reporter.record('事件列表-筛选条件退出重置', 'SKIP', Date.now() - start, '无筛选入口' ); return; } await sleep(2000); // 修改选项 const optionEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.CheckBox").instance(1)'); if (optionEl) { await driver.tapElement(optionEl); await sleep(500); } // 确认筛选 const confirmEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("确认")'); const confirmEnEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Confirm")'); if (confirmEl) await driver.tapElement(confirmEl); else if (confirmEnEl) await driver.tapElement(confirmEnEl); await sleep(2000); // 退出事件列表 await driver.goBack(); await sleep(2000); // 重新进入事件列表 await ensureOnEventList(driver); await sleep(2000); const src = await driver.getSource(); logPageSource(src); // 验证筛选条件已重置(回到默认) const isDefault = src.includes('全部') || src.includes('All') || src.includes('Today'); reporter.record('事件列表-筛选条件退出重置', 'PASS', Date.now() - start, isDefault ? '筛选条件已重置' : '筛选条件保留待确认' ); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('事件列表-筛选条件退出重置', 'FAIL', Date.now() - start, e.message, ss ); throw e; } }); it('事件列表-筛选后页面内跳转再回来 (#388174)', { timeout: 120000 }, async () => { const start = Date.now(); try { const onList = await ensureOnEventList(driver); if (!onList) throw new Error('无法进入事件列表'); // 点击一个事件进入详情(通过时间戳文字定位) const eventTextEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().textMatches("\\\\d{4}-\\\\d{2}-\\\\d{2}.*")'); if (!eventTextEl) { reporter.record('事件列表-筛选后页面内跳转再回来', 'SKIP', Date.now() - start, '无可点击的事件项'); return; } await driver.tapElement(eventTextEl); await sleep(3000); // 验证进入了详情/回放页(离开了事件列表) const detailSrc = await driver.getSource(); const leftList = !detailSrc.includes('删除') || detailSrc.includes('回放') || detailSrc.includes('Playback'); // 返回 await driver.goBack(); await sleep(2000); // 验证可以回到某个已知页面(事件列表或安防首页) const src = await driver.getSource(); const onKnownPage = /\d{2}:\d{2}:\d{2}/.test(src) || src.includes('全部事件') || src.includes('安防') || src.includes('回放'); if (!onKnownPage) throw new Error('返回后未在已知页面'); reporter.record('事件列表-筛选后页面内跳转再回来', 'PASS', Date.now() - start , ''); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('事件列表-筛选后页面内跳转再回来', 'FAIL', Date.now() - start, e.message, ss ); await driver.goBack().catch(() => {}); await sleep(1000); throw e; } }); });