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, scrollToAndTap, waitForSource, } 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('lock', 'LOCK_DEVICE'); // 必测项控制锚点(协议相关): 点击控制Lock 开锁/解锁 BLE 15975#5YEfmpJz / WiFi 15974#7cEkbh4Y // 上锁+解锁两个用例同覆盖此 step,回写按 step 聚合 import { onesCtrl } from "../../utils/common"; const CTRL_LOCK = onesCtrl("lock", deviceName); describe('Lock Control - 功能页操作', () => { let driver: DeviceDriver; let reporter: TestReporter; beforeAll(async () => { driver = createDriver(); await driver.createSession(); reporter = new TestReporter('Lock_Control', driver.platform.toUpperCase()); }); beforeEach(async () => { await driver.dismissPopupIfPresent(); await driver.goBackToHomepage(); await driver.dismissPopupIfPresent(); }); afterAll(async () => { reporter.generate(); await driver.destroySession(); }); async function enterControlPage(): Promise { let el = await driver.findElementRaw('name', deviceName); if (!el) { await driver.scrollDown(250); await sleep(1000); 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 enterControlPage(); // Find and tap lock button const lockBtn = await driver.findElementRaw('name', 'Lock') || await driver.findElementRaw('name', 'lock') || await driver.findElementRaw('name', 'LOCK'); expect(lockBtn).not.toBeNull(); await driver.tapElement(lockBtn!); await sleep(8000); // Verify locked state const source = await driver.getSource(); const isLocked = source.includes('Locked') || source.includes('locked') || source.includes('LOCKED') || source.includes('Lock'); console.log('上锁状态:', isLocked); expect(isLocked).toBe(true); reporter.record(`${CTRL_LOCK} 上锁`, 'PASS', Date.now() - start, '门锁已上锁'); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record(`${CTRL_LOCK} 上锁`, 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it('功能页-解锁', async () => { const start = Date.now(); try { await enterControlPage(); // Find and tap unlock button const unlockBtn = await driver.findElementRaw('name', 'Unlock') || await driver.findElementRaw('name', 'unlock') || await driver.findElementRaw('name', 'UNLOCK') || await driver.findElementRaw('name', 'Open'); expect(unlockBtn).not.toBeNull(); await driver.tapElement(unlockBtn!); await sleep(8000); // Verify unlocked state const source = await driver.getSource(); const isUnlocked = source.includes('Unlocked') || source.includes('unlocked') || source.includes('UNLOCKED') || source.includes('Open'); console.log('解锁状态:', isUnlocked); expect(isUnlocked).toBe(true); // Re-lock for safety const relockBtn = await driver.findElementRaw('name', 'Lock') || await driver.findElementRaw('name', 'lock'); if (relockBtn) { await driver.tapElement(relockBtn); await sleep(5000); } reporter.record(`${CTRL_LOCK} 解锁`, 'PASS', Date.now() - start, '门锁已解锁'); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record(`${CTRL_LOCK} 解锁`, 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it('绑定Keypad', async () => { const start = Date.now(); try { await enterControlPage(); const tapped = await scrollToAndTap(driver, 'Pair Keypad') || await scrollToAndTap(driver, 'Keypad'); expect(tapped).toBe(true); await sleep(3000); const source = await driver.getSource(); const hasBindingPage = source.includes('Keypad') || source.includes('Pair') || source.includes('Scan') || source.includes('Add'); expect(hasBindingPage).toBe(true); console.log('Keypad绑定页面验证成功'); reporter.record('绑定Keypad', 'PASS', Date.now() - start, 'Pair Keypad页面打开成功'); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('绑定Keypad', 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it('绑定Remote', async () => { const start = Date.now(); try { await enterControlPage(); const tapped = await scrollToAndTap(driver, 'Pair Remote') || await scrollToAndTap(driver, 'Remote'); expect(tapped).toBe(true); await sleep(3000); const source = await driver.getSource(); const hasBindingPage = source.includes('Remote') || source.includes('Pair') || source.includes('Scan') || source.includes('Add'); expect(hasBindingPage).toBe(true); console.log('Remote绑定页面验证成功'); reporter.record('绑定Remote', 'PASS', Date.now() - start, 'Pair Remote页面打开成功'); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('绑定Remote', 'FAIL', Date.now() - start, e.message, ss); throw e; } }); it('查看日志', async () => { const start = Date.now(); try { await enterControlPage(); const tapped = await scrollToAndTap(driver, 'Logs'); expect(tapped).toBe(true); await waitForSource(driver, 'Logs', 5000); const source = await driver.getSource(); expect(source).toContain('Logs'); const hasEntries = source.includes('Locked') || source.includes('Unlocked') || source.includes('Lock') || source.includes('Unlock') || source.includes('App Control') || source.includes('Manual') || source.includes('No more data') || source.includes('No logs'); const detail = `Logs页面加载成功, 有操作记录=${hasEntries}`; console.log(detail); reporter.record('查看日志', 'PASS', Date.now() - start, detail); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record('查看日志', 'FAIL', Date.now() - start, e.message, ss); throw e; } }); });