AI_UIAutomation/tests/platform/scene_operation.test.ts

105 lines
4.3 KiB
TypeScript

import { describe, it, beforeAll, afterAll, expect } from 'vitest';
import { execSync } from 'child_process';
import { DeviceDriver } from '../../drivers/types';
import { createDriver } from '../../drivers/factory';
import { TestReporter } from '../../utils/test-reporter';
import { setupResilientHooks } from "../../utils/common";
import {
sleep, ensureHomeTab, onesPlatform,
createAutomation, verifyAutomationExecuted, deleteAutomation,
createScene, executeSceneFromHomepage, verifySceneInLogs, deleteScene,
signInWithEmail, isLoggedIn,
} from '../../utils/common';
import * as dotenv from 'dotenv';
import * as path from 'path';
dotenv.config({ path: path.resolve(__dirname, '../../.env') });
const ANCHOR = `${onesPlatform(15976)} 场景操作`; // P0:场景操作验证(① 自动化 ② 场景)
/** 读安卓设备当前时间 [h, m]。 */
function deviceNow(): [number, number] {
const out = execSync('adb shell date +%H:%M').toString().trim().split(':');
return [parseInt(out[0], 10), parseInt(out[1], 10)];
}
/** 在 [h,m] 上加 addMin 分钟,返回 [h,m](跨小时进位)。 */
function plusMin(h: number, m: number, addMin: number): [number, number] {
const t = (h * 60 + m + addMin) % (24 * 60);
return [Math.floor(t / 60), t % 60];
}
describe('Platform - 场景操作(自动化 + 场景)', () => {
let driver: DeviceDriver;
let reporter: TestReporter;
setupResilientHooks(() => driver);
const autoName = `AutoOp${Date.now() % 100000}`;
const sceneName = `SceneOp${Date.now() % 100000}`;
beforeAll(async () => {
driver = createDriver();
await driver.createSession();
reporter = new TestReporter('Platform_SceneOp', driver.platform.toUpperCase());
if (!(await isLoggedIn(driver))) await signInWithEmail(driver);
});
afterAll(async () => {
// 兜底清理
try { await deleteAutomation(driver, autoName); } catch { /**/ }
try { await ensureHomeTab(driver); await deleteScene(driver, sceneName); } catch { /**/ }
reporter.generate();
await driver.destroySession();
});
it(`${ANCHOR} ① 自动化创建与执行`, { timeout: 360000 }, async () => {
const start = Date.now();
try {
// 定时设为设备时间 + 2 分钟(创建较快,留出创建耗时后约 1 分钟内触发)
const [nh, nm] = deviceNow();
const [th, tm] = plusMin(nh, nm, 2);
console.log(`设备时间 ${nh}:${nm} → 定时 ${th}:${tm}`);
const created = await createAutomation(driver, { name: autoName, deviceKeyword: 'Bot 14', targetHour: th, targetMinute: tm, action: 'Turns off' });
expect(created).toBe(true);
// 等到点(目标时间 + 40s 让引擎触发+落日志)
const deadlineMin = th * 60 + tm;
for (let i = 0; i < 60; i++) {
const [ch, cm] = deviceNow();
if (ch * 60 + cm > deadlineMin) break;
await sleep(10000);
}
await sleep(40000);
const executed = await verifyAutomationExecuted(driver, autoName);
expect(executed).toBe(true);
await deleteAutomation(driver, autoName);
reporter.record(`${ANCHOR} ①自动化`, 'PASS', Date.now() - start, `自动化 ${autoName} 定时${th}:${tm} 触发并有日志,已删除`);
} catch (e: any) {
const ss = await driver.screenshot().catch(() => '');
reporter.record(`${ANCHOR} ①自动化`, 'FAIL', Date.now() - start, e.message, ss);
throw e;
}
});
it(`${ANCHOR} ② 场景创建与执行`, { timeout: 180000 }, async () => {
const start = Date.now();
try {
// 场景动作与自动化(Bot Turns off)区分:Bot Turns on(同设备不同动作)
const created = await createScene(driver, { name: sceneName, deviceKeyword: 'Bot 14', action: 'Turns on' });
expect(created).toBe(true);
await ensureHomeTab(driver);
const executed = await executeSceneFromHomepage(driver, sceneName);
expect(executed).toBe(true);
await sleep(6000);
await driver.goBackToHomepage();
const hasLog = await verifySceneInLogs(driver, sceneName);
expect(hasLog).toBe(true);
await deleteScene(driver, sceneName);
reporter.record(`${ANCHOR} ②场景`, 'PASS', Date.now() - start, `场景 ${sceneName} 执行并有日志,已删除`);
} catch (e: any) {
const ss = await driver.screenshot().catch(() => '');
reporter.record(`${ANCHOR} ②场景`, 'FAIL', Date.now() - start, e.message, ss);
throw e;
}
});
});