105 lines
4.3 KiB
TypeScript
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;
|
|
}
|
|
});
|
|
});
|