import { describe, it, beforeAll, afterAll, beforeEach, expect } from 'vitest'; import { DeviceDriver } from '../../drivers/types'; import { createDriver } from '../../drivers/factory'; import { TestReporter } from '../../utils/test-reporter'; import { sleep, navigateToTimerPage, addTimer, deleteAllTimers, scrollToAndTap, } from '../../utils/common'; import { getDeviceName } from '../../config/device.config'; import * as dotenv from 'dotenv'; import * as path from 'path'; dotenv.config({ path: path.resolve(__dirname, '../../.env') }); const deviceName = getDeviceName('humidifier', 'HUMIDIFIER_DEVICE'); // 必测项控制锚点: Humidifier 快捷弹窗开启加湿器(自动/低/中/高/关) BLE 15975#GkkrZpaC / WiFi 15974#8tx3Rg76 import { onesCtrl } from "../../utils/common"; const CTRL_HUMID = onesCtrl("humidifier", deviceName); describe('Humidifier Control - 功能页操作', () => { let driver: DeviceDriver; let reporter: TestReporter; beforeAll(async () => { driver = createDriver(); await driver.createSession(); reporter = new TestReporter('Humidifier_Control', driver.platform.toUpperCase()); }); beforeEach(async () => { await driver.dismissPopupIfPresent(); await driver.goBackToHomepage(); await driver.dismissPopupIfPresent(); }); afterAll(async () => { reporter.generate(); await driver.destroySession(); }); async function enterHumidifierControl(): Promise { const el = await driver.findElementRaw('name', deviceName); if (!el) throw new Error(`找不到${deviceName}卡片`); await driver.tapElement(el); await sleep(3000); } it('功能页打开开关', async () => { const start = Date.now(); try { await enterHumidifierControl(); const powerEl = await driver.findElementRaw('name', 'Power') || await driver.findElementRaw('name', 'power') || await driver.findElementRaw('name', 'ON/OFF'); expect(powerEl).not.toBeNull(); await driver.tapElement(powerEl!); await sleep(3000); const source = await driver.getSource(); const isOn = source.includes('ON') || source.includes('Auto') || source.includes('Manual'); expect(isOn).toBe(true); reporter.record(`${CTRL_HUMID} 功能页打开开关`, 'PASS', Date.now() - start, `加湿器已开启, ON=${isOn}`); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record(`${CTRL_HUMID} 功能页打开开关`, 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it('切换模式为Auto', async () => { const start = Date.now(); try { await enterHumidifierControl(); const autoEl = await driver.findElementRaw('name', 'Auto') || await driver.findElementRaw('name', 'AUTO'); expect(autoEl).not.toBeNull(); await driver.tapElement(autoEl!); await sleep(2000); const source = await driver.getSource(); const isAuto = source.includes('Auto') || source.includes('AUTO'); expect(isAuto).toBe(true); reporter.record('切换模式为Auto', 'PASS', Date.now() - start, `模式已切换为Auto`); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('切换模式为Auto', 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it('切换模式为Manual', async () => { const start = Date.now(); try { await enterHumidifierControl(); const manualEl = await driver.findElementRaw('name', 'Manual') || await driver.findElementRaw('name', 'MANUAL'); expect(manualEl).not.toBeNull(); await driver.tapElement(manualEl!); await sleep(2000); const source = await driver.getSource(); const isManual = source.includes('Manual') || source.includes('MANUAL'); expect(isManual).toBe(true); reporter.record('切换模式为Manual', 'PASS', Date.now() - start, `模式已切换为Manual`); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('切换模式为Manual', 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it('定时器添加', async () => { const start = Date.now(); try { await enterHumidifierControl(); const navOk = await navigateToTimerPage(driver); expect(navOk).toBe(true); await sleep(2000); const added = await addTimer(driver); expect(added).toBe(true); const source = await driver.getSource(); const hasTimer = source.includes('Only once') || source.includes('Timer'); console.log('定时器添加成功:', hasTimer); 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('定时器删除', async () => { const start = Date.now(); try { await enterHumidifierControl(); const navOk = await navigateToTimerPage(driver); expect(navOk).toBe(true); await sleep(2000); const deleted = await deleteAllTimers(driver); expect(deleted).toBe(true); console.log('定时器已清空: true'); 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('延迟开关', async () => { const start = Date.now(); try { await enterHumidifierControl(); const delayEl = await driver.findElementRaw('name', 'Delay') || await driver.findElementRaw('name', 'delay'); if (!delayEl) { await scrollToAndTap(driver, 'Delay'); } else { await driver.tapElement(delayEl); } await sleep(2000); const source = await driver.getSource(); const hasDelay = source.includes('Delay') || source.includes('Timer') || source.includes('Hour') || source.includes('Min'); expect(hasDelay).toBe(true); // Confirm the delay setting const confirmEl = await driver.findElementRaw('name', 'Confirm') || await driver.findElementRaw('name', 'OK') || await driver.findElementRaw('name', 'Save'); if (confirmEl) { await driver.tapElement(confirmEl); await sleep(2000); } 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('打开/关闭指示灯', async () => { const start = Date.now(); try { await enterHumidifierControl(); const indicatorEl = await driver.findElementRaw('name', 'Indicator Light') || await driver.findElementRaw('name', 'indicator light') || await driver.findElementRaw('name', 'LED'); if (!indicatorEl) { await scrollToAndTap(driver, 'Indicator Light'); await sleep(2000); } else { await driver.tapElement(indicatorEl); await sleep(2000); } // Toggle back const indicatorEl2 = await driver.findElementRaw('name', 'Indicator Light') || await driver.findElementRaw('name', 'indicator light') || await driver.findElementRaw('name', 'LED'); if (indicatorEl2) { await driver.tapElement(indicatorEl2); await sleep(2000); } 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('打开/关闭声音', async () => { const start = Date.now(); try { await enterHumidifierControl(); const soundEl = await driver.findElementRaw('name', 'Sound') || await driver.findElementRaw('name', 'sound') || await driver.findElementRaw('name', 'Beep'); if (!soundEl) { await scrollToAndTap(driver, 'Sound'); await sleep(2000); } else { await driver.tapElement(soundEl); await sleep(2000); } // Toggle back const soundEl2 = await driver.findElementRaw('name', 'Sound') || await driver.findElementRaw('name', 'sound') || await driver.findElementRaw('name', 'Beep'); if (soundEl2) { await driver.tapElement(soundEl2); await sleep(2000); } 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('功能页关闭开关', async () => { const start = Date.now(); try { await enterHumidifierControl(); const powerEl = await driver.findElementRaw('name', 'Power') || await driver.findElementRaw('name', 'power') || await driver.findElementRaw('name', 'ON/OFF'); expect(powerEl).not.toBeNull(); await driver.tapElement(powerEl!); await sleep(3000); const source = await driver.getSource(); const isOff = source.includes('OFF') || source.includes('off') || !source.includes('Auto'); console.log('加湿器已关闭:', isOff); reporter.record(`${CTRL_HUMID} 功能页关闭开关`, 'PASS', Date.now() - start, `加湿器已关闭`); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record(`${CTRL_HUMID} 功能页关闭开关`, 'FAIL', Date.now() - start, e.message, ss); throw e; } }); });