AI_UIAutomation/utils/common/room.helper.ts

108 lines
4.5 KiB
TypeScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

import { DeviceDriver } from '../../drivers/types';
import { sleep, waitForSource } from './element.helper';
import { goToProfile } from './auth.helper';
async function tapText(driver: DeviceDriver, t: string): Promise<boolean> {
const el = driver.platform === 'android'
? await driver.findElementRaw('-android uiautomator', `new UiSelector().text("${t}")`)
: await driver.findElementRaw('name', t);
if (el) { await driver.tapElement(el); return true; }
return false;
}
/**
* 进入 Manage Rooms(房间管理)列表页:Profile → Manage Homes → 第一个 home → Rooms。
* 坐标按 1080×2280(进第一个 home 行);换机型需调。
*/
export async function goToManageRooms(driver: DeviceDriver): Promise<boolean> {
await goToProfile(driver);
if (!(await tapText(driver, 'Manage Homes'))) return false;
await sleep(2500);
await tapText(driver, 'Got it'); // 可能的"邀请加入"提示弹框
await sleep(500);
await driver.tap(540, 486); // 进第一个 home(行中心)
await sleep(2500);
if (!(await tapText(driver, 'Rooms'))) return false;
await sleep(2500);
return waitForSource(driver, 'Manage Rooms', 6000).catch(() => false) as Promise<boolean>;
}
/** 在 Manage Rooms 页创建房间:Create Room → 输入名 → OK。返回房间是否出现在列表。 */
export async function createRoom(driver: DeviceDriver, roomName: string): Promise<boolean> {
// 进 Manage Rooms 首次会弹「新手引导文档」,会遮挡 Create Room → 先点 Got it 关掉(无则 tapText 返回 false,无副作用)。
await tapText(driver, 'Got it');
await sleep(800);
if (!(await tapText(driver, 'Create Room'))) return false;
await sleep(1500);
const ed = await driver.findElementRaw('-android uiautomator', 'new UiSelector().className("android.widget.EditText")');
if (!ed) return false;
await driver.typeText(ed, roomName);
await sleep(500);
await tapText(driver, 'OK');
await sleep(2500);
await tapText(driver, 'Got it'); // 创建后可能再弹引导,兜底关掉
await sleep(1000);
const ok = (await driver.getSource()).includes(roomName);
console.log(`创建房间 ${roomName}: ${ok}`);
return ok;
}
/** 删除房间(清理/恢复数据):点房间 → 详情页右上角删除图标(top_bar_right_icon)→ Attention 弹框 Confirm。返回房间是否已消失。 */
export async function deleteRoom(driver: DeviceDriver, roomName: string): Promise<boolean> {
if (!(await tapText(driver, roomName))) return false; // 进房间详情
await sleep(2000);
const icon = await driver.findElementRaw('id', 'com.theswitchbot.switchbot:id/top_bar_right_icon');
if (icon) await driver.tapElement(icon); else await driver.tap(1018, 185); // 右上角删除
await sleep(1500);
await tapText(driver, 'Confirm'); // Attention 确认框
await sleep(2500);
const gone = !(await driver.getSource()).includes(roomName);
console.log(`删除房间 ${roomName}: ${gone ? '已删除' : '仍存在'}`);
return gone;
}
export async function selectRoom(driver: DeviceDriver, roomName: string): Promise<boolean> {
if (driver.platform === 'android') {
const rooms = await driver.findElementsRaw('id', 'com.theswitchbot.switchbot:id/clSelectRoom');
for (const room of rooms) {
const text = await driver.getElementAttribute(room, 'text');
if (text.includes(roomName)) {
await driver.tapElement(room);
await sleep(500);
const saveEl = await driver.findElementRaw('-android uiautomator', 'new UiSelector().text("Save")');
if (saveEl) await driver.tapElement(saveEl);
await sleep(2000);
return true;
}
}
return false;
}
// iOS
const cells = await driver.findElementsRaw('class name', 'XCUIElementTypeCell');
for (const cell of cells) {
const name = await driver.getElementAttribute(cell, 'name');
if (name.includes(roomName)) {
await driver.tapElement(cell);
await sleep(500);
const saveEl = await driver.findElementRaw('name', 'Save');
if (saveEl) await driver.tapElement(saveEl);
await sleep(2000);
return true;
}
}
return false;
}
export async function getCurrentRoom(driver: DeviceDriver): Promise<string> {
const source = await driver.getSource();
if (source.includes('Not in any room')) return '';
if (driver.platform === 'android') {
const match = source.match(/sivDeviceRoom[\s\S]*?text="([^"]+)"/);
return match ? match[1] : '';
}
const roomLabel = await driver.findElementRaw('name', 'Room');
if (!roomLabel) return '';
return '';
}