AI_UIAutomation/tests/curtain/curtain_connect.test.ts

86 lines
4.3 KiB
TypeScript

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,
addDeviceWithSerialPairing,
findDeviceNameOnHomepage,
saveAddedDevice,
onesAdd,
curtain3PostConnect,
curtainPostConnect,
} from '../../utils/common';
import { getDeviceName, getModelName } from '../../config/device.config';
import * as dotenv from 'dotenv';
import * as path from 'path';
dotenv.config({ path: path.resolve(__dirname, '../../.env') });
const deviceName = getDeviceName('curtain', 'CURTAIN_DEVICE');
const model = getModelName('curtain', 'CURTAIN_DEVICE'); // 型号名(锚点用)
// curtain 与 curtain3 校准流程不同:按型号区分 relay 设备 + 连接后流程
const isCurtain3 = /curtain\s*3|curtain3/i.test(model);
const RELAY_DEVICE = isCurtain3 ? 'curtain3' : 'curtain';
const ADD_ANCHOR = onesAdd('curtain', model);
// 首页实际设备名:curtain/curtain3/2025 首页**都叫 "Curtain XX"**(名字不带型号)→ 型号区分靠**添加向导内联改名**(RENAME_TO);
// skip / home 校验统一按重命名名,curtain 与 curtain3 互不串台。可用 env 覆盖。
// 是否做行程校验(需设备装在真实导轨上);默认跳过(Install and calibrate later),CURTAIN_CALIBRATE=1 开启
const CALIBRATE = process.env.CURTAIN_CALIBRATE === '1';
// 添加完成后按**类型重命名**(便于区分 Curtain/Curtain3,后续 skip/校验按稳定名精确识别,互不串台)。
// "Curtain Auto" 与 "Curtain3 Auto" 互不匹配(Curtain+空格 vs Curtain3)。
const RENAME_TO = process.env.CURTAIN_RENAME || (isCurtain3 ? 'Curtain3 Auto' : 'Curtain Auto');
describe('Curtain Connect - 添加窗帘设备(串口配对 + 行程校验)', () => {
let driver: DeviceDriver;
let reporter: TestReporter;
beforeAll(async () => {
driver = createDriver();
await driver.createSession();
reporter = new TestReporter(`Curtain_Connect_${deviceName}`, driver.platform.toUpperCase());
});
afterAll(async () => {
reporter.generate();
await driver.destroySession();
});
it(`${ADD_ANCHOR} 通过BLE添加窗帘设备`, { timeout: 360000 }, async () => {
const start = Date.now();
try {
// 已按类型重命名过(如 "Curtain3 Auto")→ 跳过。按稳定重命名名识别,Curtain/Curtain3 互不串台。
const renamed = await findDeviceNameOnHomepage(driver, RENAME_TO);
if (renamed) {
console.log(`${renamed}已在首页(已重命名),跳过重新添加`);
saveAddedDevice('curtain', renamed);
reporter.record(`${ADD_ANCHOR} 添加窗帘设备`, 'SKIP', Date.now() - start, `${renamed}已存在, 无需重新添加`);
return;
}
const result = await addDeviceWithSerialPairing(driver, {
categoryName: 'Curtain', // curtain / curtain3 同一添加入口
deviceKeyword: deviceName,
relayDevice: RELAY_DEVICE, // 按开关键 2s(curtain ch39 / curtain3 ch37)
registryCategory: 'curtain',
// curtain/curtain3 均在**添加向导内联改名**为 RENAME_TO(curtain=命名页 / curtain3=Install 页)→ 落首页即该名,故 home 校验统一用 RENAME_TO
namePattern: RENAME_TO,
preferNamePattern: true, // 改名后名("Curtain3 Auto")含默认名子串("Curtain")→ 必须优先按 namePattern 回写真实名,否则注册表塌成通用 "Curtain"
// 连接后专属流程:选模式 + 内联改名 +(curtain3:Install→行程校验 / curtain:命名页→稍后校准)
postConnectSteps: (d) =>
isCurtain3
? curtain3PostConnect(d, { calibrate: CALIBRATE, renameTo: RENAME_TO })
: curtainPostConnect(d, { calibrate: CALIBRATE, renameTo: RENAME_TO }),
});
expect(result).toBe(true);
const elapsed = ((Date.now() - start) / 1000).toFixed(1);
reporter.record(`${ADD_ANCHOR} 添加窗帘设备`, 'PASS', Date.now() - start, `${model}添加成功并重命名为"${RENAME_TO}"${CALIBRATE ? '(含行程校验)' : ''}, 耗时${elapsed}s`);
} catch (e: any) {
const ss = await driver.screenshot().catch(() => '');
reporter.record(`${ADD_ANCHOR} 添加窗帘设备`, 'FAIL', Date.now() - start, e.message, ss);
throw e;
}
});
});