import { describe, it, beforeAll, afterAll, expect } from 'vitest'; import { DeviceDriver } from '../../drivers/types'; import { createDriver } from '../../drivers/factory'; import { TestReporter } from '../../utils/test-reporter'; import { sleep, scrollToAndTap, onesCtrl } from '../../utils/common'; import { setupResilientHooks } from "../../utils/common"; import * as dotenv from 'dotenv'; import * as path from 'path'; dotenv.config({ path: path.resolve(__dirname, '../../.env') }); // 百叶帘:首页快捷弹窗控制(Fully open / Close Down)。锚点 BlindTilt 3C → 15975#3frMRDZj (step18) const deviceName = process.env.BT_DEVICE || 'Blind Tilt 42'; const BT_MODEL = process.env.BT_MODEL || 'BlindTilt 3C'; const CTRL_BT = onesCtrl('curtain', BT_MODEL); describe('Blind Tilt Control - 百叶帘控制(首页快捷弹窗)', () => { let driver: DeviceDriver; let reporter: TestReporter; setupResilientHooks(() => driver); beforeAll(async () => { driver = createDriver(); await driver.createSession(); reporter = new TestReporter('BlindTilt_Control', driver.platform.toUpperCase()); }); beforeEach(async () => { await driver.dismissPopupIfPresent(); await driver.goBackToHomepage(); await sleep(500); await driver.dismissPopupIfPresent(); }); afterAll(async () => { reporter.generate(); await driver.destroySession(); }); async function openBtPopup(): Promise { const ok = await scrollToAndTap(driver, deviceName); if (!ok) throw new Error(`找不到${deviceName}卡片`); await sleep(2500); } // 读弹窗里百叶帘倾斜状态:Fully open / Fully closed / "X% Opened up|down" function readBtState(src: string): string { const m = src.match(/text="(Fully open|Fully closed[^"]*|[0-9]{1,3}% (?:Opened|Closed)[^"]*)"/); return m ? m[1] : 'unknown'; } async function tapBtnAndWait(btn: string, pred: (s: string) => boolean): Promise { const el = await driver.findElementRaw('-android uiautomator', `new UiSelector().text("${btn}")`); expect(el).not.toBeNull(); await driver.tapElement(el!); await sleep(8000); // 等百叶帘转动 // 弹窗状态不实时刷新 → 回首页重开弹窗读新鲜状态,轮询到目标 let st = 'unknown'; for (let i = 0; i < 6; i++) { await driver.goBackToHomepage(); await sleep(1500); await openBtPopup(); st = readBtState(await driver.getSource()); if (pred(st)) break; await sleep(2000); } return st; } it(`${CTRL_BT} 向下关闭(Close Down)`, { timeout: 90000 }, async () => { const start = Date.now(); try { await openBtPopup(); expect(readBtState(await driver.getSource())).not.toBe('unknown'); // 弹窗能读到倾斜状态 const after = await tapBtnAndWait('Close Down', s => /closed/i.test(s)); // 等到 "Fully closed" console.log('Close Down →', after); expect(/closed/i.test(after)).toBe(true); // 硬断言:已关闭(Fully closed) reporter.record(`${CTRL_BT} 向下关闭`, 'PASS', Date.now() - start, `状态=${after}`); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record(`${CTRL_BT} 向下关闭`, 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it(`${CTRL_BT} 完全打开(Fully open)`, { timeout: 90000 }, async () => { const start = Date.now(); try { await openBtPopup(); expect(readBtState(await driver.getSource())).not.toBe('unknown'); const after = await tapBtnAndWait('Fully open', s => s === 'Fully open'); // 等到完全打开(水平) console.log('Fully open →', after); expect(after).toBe('Fully open'); // 硬断言:已完全打开 reporter.record(`${CTRL_BT} 完全打开`, 'PASS', Date.now() - start, `状态=${after}`); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record(`${CTRL_BT} 完全打开`, 'FAIL', Date.now() - start, e.message, ss); throw e; } }); });