import { DeviceDriver } from '../../drivers/types'; import { sleep } from '../../utils/common'; import { getDeviceName } from '../../config/device.config'; import { execSync } from 'child_process'; const AIHUB_NAME = getDeviceName('aihub', 'AIHUB_NAME'); const PKG = 'com.theswitchbot.switchbot'; const ACTIVITY = `${PKG}/.index.ui.SplashActivity`; export function isAndroid(driver: DeviceDriver): boolean { return driver.platform === 'android'; } export async function forceRestartApp(driver: DeviceDriver): Promise { if (!isAndroid(driver)) return; try { execSync(`adb shell am force-stop ${PKG}`); await sleep(2000); execSync(`adb shell am start -n ${ACTIVITY}`); await sleep(10000); await driver.dismissPopupIfPresent(); await sleep(2000); await driver.dismissPopupIfPresent(); } catch (e) { console.error('[forceRestartApp] error:', e); } } export async function ensureAppOnHomepage(driver: DeviceDriver): Promise { try { const src = await driver.getSource(); if (src.includes('All Devices') || src.includes('content-desc="Home"') || (src.includes('Home') && !src.includes('Motion Detection') && !src.includes('Extended Display'))) { return true; } } catch { /* session may be dead */ } // Try goBackToHomepage first try { await driver.goBackToHomepage(); await sleep(3000); await driver.dismissPopupIfPresent(); const src = await driver.getSource(); if (src.includes('All Devices') || src.includes('content-desc="Home"')) return true; } catch { /* ignore */ } // Force restart as last resort await forceRestartApp(driver); try { const src = await driver.getSource(); return src.includes('All Devices') || src.includes('content-desc="Home"') || src.includes('Home'); } catch { return false; } } export async function enterHubFunctionPage(driver: DeviceDriver): Promise { const src = await driver.getSource(); if (src.includes('Cameras') && src.includes('AI Events')) return true; const onHome = await ensureAppOnHomepage(driver); if (!onHome) return false; if (isAndroid(driver)) { const card = await (driver as any).findDeviceCard(AIHUB_NAME); if (!card) { console.log('[enterHubFunctionPage] Hub card not found, trying scroll'); for (let i = 0; i < 3; i++) { await driver.scrollDown(400); await sleep(2000); const retryCard = await (driver as any).findDeviceCard(AIHUB_NAME); if (retryCard) { await driver.tapElement(retryCard); await sleep(6000); await driver.dismissPopupIfPresent(); const s = await driver.getSource(); if (s.includes('Cameras') || s.includes('AI Events')) return true; } } return false; } await driver.tapElement(card); await sleep(6000); await driver.dismissPopupIfPresent(); const s = await driver.getSource(); return s.includes('Cameras') || s.includes('AI Events'); } // iOS for (let scroll = 0; scroll <= 5; scroll++) { let hubEl = await driver.findElementRaw('predicate string', `name CONTAINS "${AIHUB_NAME}" AND type == "XCUIElementTypeCell"`); if (!hubEl) { hubEl = await driver.findElementRaw('predicate string', `label CONTAINS "${AIHUB_NAME}"`); } if (hubEl) { await driver.tapElement(hubEl); await sleep(5000); await driver.dismissPopupIfPresent(); const s = await driver.getSource(); if (s.includes('Cameras') || s.includes('AI Events')) return true; } if (scroll < 5) { await driver.swipe(195, 650, 195, 300, 0.5); await sleep(1500); } } return false; } export async function enterHubSettings(driver: DeviceDriver): Promise { const src = await driver.getSource(); if (src.includes('Motion Detection') || src.includes('Firmware') || src.includes('Do Not Disturb') || src.includes('Extended Display') || src.includes('Local Storage')) { return true; } const inHub = await enterHubFunctionPage(driver); if (!inHub) return false; const gearX = isAndroid(driver) ? 999 : 361; const gearY = isAndroid(driver) ? 175 : 70; await driver.tap(gearX, gearY); await sleep(5000); const settingSrc = await driver.getSource(); return settingSrc.includes('Motion Detection') || settingSrc.includes('Firmware') || settingSrc.includes('Do Not Disturb') || settingSrc.includes('Wi-Fi'); } export async function waitForLoading(driver: DeviceDriver, maxWait = 30000): Promise { const start = Date.now(); while (Date.now() - start < maxWait) { const s = await driver.getSource(); if (!s.includes('Loading') && !s.includes('In progress')) return; await sleep(3000); } } export async function robustBeforeEach(driver: DeviceDriver): Promise { try { await driver.dismissPopupIfPresent(); } catch { // Session might be dead - recreate try { await driver.destroySession(); } catch { /* ignore */ } await driver.createSession(); await sleep(5000); await forceRestartApp(driver); } } export async function robustBeforeAll(driver: DeviceDriver): Promise { await forceRestartApp(driver); }