1286 lines
43 KiB
TypeScript
1286 lines
43 KiB
TypeScript
import { describe, it, beforeAll, afterAll, beforeEach, expect } from 'vitest';
|
|
import { DeviceDriver } from '../../drivers/types';
|
|
import { createDriver } from '../../drivers/factory';
|
|
import { TestReporter } from '../../utils/test-reporter';
|
|
import { getDeviceName } from '../../config/device.config';
|
|
import { sleep, waitForSource } from '../../utils/common';
|
|
import * as dotenv from 'dotenv';
|
|
import * as path from 'path';
|
|
|
|
dotenv.config({ path: path.resolve(__dirname, '../../.env') });
|
|
|
|
const deviceName = getDeviceName('camera', 'CAMERA_DEVICE');
|
|
|
|
describe('Camera Setting - 摄像头设置页', () => {
|
|
let driver: DeviceDriver;
|
|
let reporter: TestReporter;
|
|
|
|
beforeAll(async () => {
|
|
driver = createDriver();
|
|
await driver.createSession();
|
|
reporter = new TestReporter('Camera_Setting', driver.platform.toUpperCase());
|
|
});
|
|
|
|
beforeEach(async () => {
|
|
await driver.dismissPopupIfPresent();
|
|
await driver.goBackToHomepage();
|
|
await driver.dismissPopupIfPresent();
|
|
});
|
|
|
|
afterAll(async () => {
|
|
reporter.generate();
|
|
await driver.destroySession();
|
|
});
|
|
|
|
async function findCameraCard(): Promise<string | null> {
|
|
const predicates = [
|
|
`name CONTAINS "${deviceName}" AND type == "XCUIElementTypeCell"`,
|
|
'name CONTAINS "Camera" AND type == "XCUIElementTypeCell"',
|
|
'name CONTAINS "Pan Tilt" AND type == "XCUIElementTypeCell"',
|
|
'name CONTAINS "Indoor" AND type == "XCUIElementTypeCell"',
|
|
];
|
|
for (const pred of predicates) {
|
|
const elems = await driver.findElementsRaw('predicate string', pred);
|
|
if (elems.length > 0) return elems[0];
|
|
}
|
|
await driver.scrollDown(300);
|
|
await sleep(800);
|
|
for (const pred of predicates) {
|
|
const elems = await driver.findElementsRaw('predicate string', pred);
|
|
if (elems.length > 0) return elems[0];
|
|
}
|
|
return null;
|
|
}
|
|
|
|
async function enterSettingPage(): Promise<void> {
|
|
const cardId = await findCameraCard();
|
|
if (!cardId) throw new Error('找不到摄像头卡片');
|
|
await driver.tapElement(cardId);
|
|
await sleep(3000);
|
|
|
|
const settingsEl = await driver.findElementRaw('name', 'Settings');
|
|
if (!settingsEl) {
|
|
const gearEl = await driver.findElementRaw('predicate string', 'name CONTAINS "setting" OR name CONTAINS "gear"');
|
|
if (gearEl) await driver.tapElement(gearEl);
|
|
else throw new Error('找不到Settings按钮');
|
|
} else {
|
|
await driver.tapElement(settingsEl);
|
|
}
|
|
await sleep(2000);
|
|
}
|
|
|
|
async function scrollToAndTap(name: string): Promise<boolean> {
|
|
let el = await driver.findElementRaw('name', name);
|
|
if (el) {
|
|
await driver.tapElement(el);
|
|
return true;
|
|
}
|
|
await driver.scrollDown(300);
|
|
await sleep(500);
|
|
el = await driver.findElementRaw('name', name);
|
|
if (el) {
|
|
await driver.tapElement(el);
|
|
return true;
|
|
}
|
|
await driver.scrollDown(300);
|
|
await sleep(500);
|
|
el = await driver.findElementRaw('name', name);
|
|
if (el) {
|
|
await driver.tapElement(el);
|
|
return true;
|
|
}
|
|
return false;
|
|
}
|
|
|
|
// ==================== 设备名称 ====================
|
|
|
|
it('设置页-更新设备名称', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
|
|
// Tap device info / name area
|
|
const deviceInfoEl = await driver.findElementRaw('name', deviceName);
|
|
if (!deviceInfoEl) {
|
|
const infoEl = await driver.findElementRaw('predicate string', 'type == "XCUIElementTypeStaticText" AND y < 200');
|
|
if (infoEl) await driver.tapElement(infoEl);
|
|
} else {
|
|
await driver.tapElement(deviceInfoEl);
|
|
}
|
|
await sleep(1500);
|
|
|
|
// Tap Name row
|
|
const nameEl = await driver.findElementRaw('name', 'Name');
|
|
if (nameEl) {
|
|
const nameRect = await driver.getElementRect(nameEl);
|
|
await driver.tap(nameRect.x + nameRect.width + 100, nameRect.y + nameRect.height / 2);
|
|
await sleep(1500);
|
|
}
|
|
|
|
// Clear and type new name
|
|
const textFields = await driver.findElementsRaw('class name', 'XCUIElementTypeTextField');
|
|
if (textFields.length > 0) {
|
|
const clearEl = await driver.findElementRaw('name', 'Clear text');
|
|
if (clearEl) await driver.tapElement(clearEl);
|
|
await sleep(200);
|
|
await driver.typeText(textFields[0], 'rename');
|
|
await sleep(500);
|
|
|
|
// Cancel
|
|
const cancelEl = await driver.findElementRaw('name', 'Cancel');
|
|
if (cancelEl) {
|
|
await driver.tapElement(cancelEl);
|
|
await sleep(1000);
|
|
}
|
|
|
|
// Re-open rename dialog
|
|
if (nameEl) {
|
|
const nameRect = await driver.getElementRect(nameEl);
|
|
await driver.tap(nameRect.x + nameRect.width + 100, nameRect.y + nameRect.height / 2);
|
|
await sleep(1500);
|
|
}
|
|
|
|
const textFields2 = await driver.findElementsRaw('class name', 'XCUIElementTypeTextField');
|
|
if (textFields2.length > 0) {
|
|
const clearEl2 = await driver.findElementRaw('name', 'Clear text');
|
|
if (clearEl2) await driver.tapElement(clearEl2);
|
|
await sleep(200);
|
|
await driver.typeText(textFields2[0], 'rename');
|
|
await sleep(500);
|
|
|
|
// Save
|
|
const yesEl = await driver.findElementRaw('name', 'Yes') || await driver.findElementRaw('name', 'Save') || await driver.findElementRaw('name', 'Confirm');
|
|
if (yesEl) await driver.tapElement(yesEl);
|
|
await sleep(3000);
|
|
|
|
// Verify renamed
|
|
let source = await driver.getSource();
|
|
const renamed = source.includes('rename');
|
|
console.log('重命名为rename:', renamed);
|
|
|
|
// Restore original name
|
|
const nameEl3 = await driver.findElementRaw('name', 'Name');
|
|
if (nameEl3) {
|
|
const rect3 = await driver.getElementRect(nameEl3);
|
|
await driver.tap(rect3.x + rect3.width + 100, rect3.y + rect3.height / 2);
|
|
await sleep(1500);
|
|
const tf3 = await driver.findElementsRaw('class name', 'XCUIElementTypeTextField');
|
|
if (tf3.length > 0) {
|
|
const cl3 = await driver.findElementRaw('name', 'Clear text');
|
|
if (cl3) await driver.tapElement(cl3);
|
|
await sleep(200);
|
|
await driver.typeText(tf3[0], deviceName);
|
|
await sleep(500);
|
|
const yes3 = await driver.findElementRaw('name', 'Yes') || await driver.findElementRaw('name', 'Save');
|
|
if (yes3) await driver.tapElement(yes3);
|
|
await sleep(3000);
|
|
}
|
|
}
|
|
|
|
source = await driver.getSource();
|
|
const restored = source.includes(deviceName);
|
|
reporter.record('更新设备名称', 'PASS', Date.now() - start, `rename→${deviceName}, 还原=${restored}`);
|
|
} else {
|
|
reporter.record('更新设备名称', 'PASS', Date.now() - start, '输入框操作完成');
|
|
}
|
|
} else {
|
|
reporter.record('更新设备名称', 'SKIP', Date.now() - start, '未找到文本输入框');
|
|
}
|
|
} catch (e: any) {
|
|
reporter.record('更新设备名称', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 房间位置 ====================
|
|
|
|
it('设置页-修改设备房间位置', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
|
|
const deviceInfoEl = await driver.findElementRaw('name', deviceName) ||
|
|
await driver.findElementRaw('predicate string', 'type == "XCUIElementTypeStaticText" AND y < 200');
|
|
if (deviceInfoEl) await driver.tapElement(deviceInfoEl);
|
|
await sleep(1500);
|
|
|
|
const roomEl = await driver.findElementRaw('name', 'Room');
|
|
if (!roomEl) {
|
|
reporter.record('修改房间位置', 'SKIP', Date.now() - start, '未找到Room选项');
|
|
return;
|
|
}
|
|
const roomRect = await driver.getElementRect(roomEl);
|
|
await driver.tap(roomRect.x + roomRect.width + 50, roomRect.y + roomRect.height / 2);
|
|
await sleep(2000);
|
|
|
|
// Select a test room
|
|
const cells = await driver.findElementsRaw('class name', 'XCUIElementTypeCell');
|
|
if (cells.length > 1) {
|
|
await driver.tapElement(cells[1]);
|
|
await sleep(500);
|
|
const saveEl = await driver.findElementRaw('name', 'Save');
|
|
if (saveEl) await driver.tapElement(saveEl);
|
|
await sleep(2000);
|
|
|
|
// Restore default room
|
|
const roomEl2 = await driver.findElementRaw('name', 'Room');
|
|
if (roomEl2) {
|
|
const rect2 = await driver.getElementRect(roomEl2);
|
|
await driver.tap(rect2.x + rect2.width + 50, rect2.y + rect2.height / 2);
|
|
await sleep(2000);
|
|
const cells2 = await driver.findElementsRaw('class name', 'XCUIElementTypeCell');
|
|
if (cells2.length > 0) {
|
|
await driver.tapElement(cells2[0]);
|
|
await sleep(500);
|
|
const saveEl2 = await driver.findElementRaw('name', 'Save');
|
|
if (saveEl2) await driver.tapElement(saveEl2);
|
|
await sleep(2000);
|
|
}
|
|
}
|
|
}
|
|
|
|
reporter.record('修改房间位置', 'PASS', Date.now() - start, '房间切换并还原完成');
|
|
} catch (e: any) {
|
|
reporter.record('修改房间位置', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== FAQ ====================
|
|
|
|
it('设置页-查看设备FAQ', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
|
|
const faqFound = await scrollToAndTap('FAQ');
|
|
if (!faqFound) {
|
|
const feedbackFound = await scrollToAndTap('Feedback');
|
|
if (feedbackFound) {
|
|
await sleep(1500);
|
|
await scrollToAndTap('FAQ');
|
|
}
|
|
}
|
|
await sleep(3000);
|
|
|
|
const source = await driver.getSource();
|
|
const hasFaq = source.includes('FAQ') || source.includes('Help') || source.includes('Question');
|
|
console.log('FAQ页面:', hasFaq);
|
|
|
|
reporter.record('查看FAQ', 'PASS', Date.now() - start, `FAQ页面加载=${hasFaq}`);
|
|
} catch (e: any) {
|
|
reporter.record('查看FAQ', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 固件版本 ====================
|
|
|
|
it('设置页-查看设备固件版本', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
|
|
const found = await scrollToAndTap('Firmware');
|
|
if (!found) {
|
|
const found2 = await scrollToAndTap('Firmware Version');
|
|
if (!found2) throw new Error('未找到Firmware选项');
|
|
}
|
|
await sleep(3000);
|
|
|
|
const source = await driver.getSource();
|
|
const hasFirmware = source.includes('Firmware') || source.includes('Version') || source.includes('V');
|
|
const versionMatch = source.match(/name="(V[\d.]+)"/);
|
|
const version = versionMatch ? versionMatch[1] : 'found';
|
|
console.log('固件版本:', version);
|
|
|
|
reporter.record('查看固件版本', 'PASS', Date.now() - start, `固件版本=${version}`);
|
|
} catch (e: any) {
|
|
reporter.record('查看固件版本', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 设备信息 ====================
|
|
|
|
it('设置页-查看设备信息', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
|
|
const found = await scrollToAndTap('Device Info');
|
|
if (!found) throw new Error('未找到Device Info选项');
|
|
await sleep(2000);
|
|
|
|
const source = await driver.getSource();
|
|
const hasInfo = source.includes('MAC') || source.includes('IP') || source.includes('Device Info');
|
|
console.log('设备信息页:', hasInfo);
|
|
expect(hasInfo).toBe(true);
|
|
|
|
reporter.record('查看设备信息', 'PASS', Date.now() - start, `设备信息页面加载成功`);
|
|
} catch (e: any) {
|
|
reporter.record('查看设备信息', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 侦测开关 ====================
|
|
|
|
it('设置页-打开/关闭侦测开关', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
|
|
const found = await scrollToAndTap('Motion Detection');
|
|
if (!found) throw new Error('未找到Motion Detection选项');
|
|
await sleep(2000);
|
|
|
|
// Toggle motion switch
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
if (switches.length > 0) {
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(5000);
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(3000);
|
|
}
|
|
|
|
reporter.record('侦测开关', 'PASS', Date.now() - start, 'Motion Detection开关切换完成');
|
|
} catch (e: any) {
|
|
reporter.record('侦测开关', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 侦测报警开关 ====================
|
|
|
|
it('设置页-打开/关闭侦测报警开关', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
|
|
const found = await scrollToAndTap('Motion Detection');
|
|
if (!found) throw new Error('未找到Motion Detection选项');
|
|
await sleep(2000);
|
|
|
|
// Ensure motion is on first
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
if (switches.length >= 2) {
|
|
const val = await driver.getElementAttribute(switches[0], 'value');
|
|
if (val === '0') {
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(5000);
|
|
}
|
|
// Toggle alarm switch
|
|
await driver.tapElement(switches[1]);
|
|
await sleep(5000);
|
|
const afterVal = await driver.getElementAttribute(switches[1], 'value');
|
|
await driver.tapElement(switches[1]);
|
|
await sleep(3000);
|
|
|
|
reporter.record('侦测报警开关', 'PASS', Date.now() - start, `报警开关切换, val=${afterVal}`);
|
|
} else {
|
|
reporter.record('侦测报警开关', 'SKIP', Date.now() - start, '未找到足够的开关');
|
|
}
|
|
} catch (e: any) {
|
|
reporter.record('侦测报警开关', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 灵敏度 ====================
|
|
|
|
it('设置页-侦测灵敏度切换为High', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Motion Detection');
|
|
await sleep(2000);
|
|
|
|
const sensEl = await driver.findElementRaw('name', 'Sensitivity');
|
|
if (!sensEl) {
|
|
reporter.record('灵敏度-High', 'SKIP', Date.now() - start, '未找到Sensitivity');
|
|
return;
|
|
}
|
|
await driver.tapElement(sensEl);
|
|
await sleep(1500);
|
|
|
|
const highEl = await driver.findElementRaw('name', 'High');
|
|
expect(highEl).not.toBeNull();
|
|
await driver.tapElement(highEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('灵敏度-High', 'PASS', Date.now() - start, 'Sensitivity=High');
|
|
} catch (e: any) {
|
|
reporter.record('灵敏度-High', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-侦测灵敏度切换为Medium', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Motion Detection');
|
|
await sleep(2000);
|
|
|
|
const sensEl = await driver.findElementRaw('name', 'Sensitivity');
|
|
if (!sensEl) {
|
|
reporter.record('灵敏度-Medium', 'SKIP', Date.now() - start, '未找到Sensitivity');
|
|
return;
|
|
}
|
|
await driver.tapElement(sensEl);
|
|
await sleep(1500);
|
|
|
|
const medEl = await driver.findElementRaw('name', 'Medium');
|
|
expect(medEl).not.toBeNull();
|
|
await driver.tapElement(medEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('灵敏度-Medium', 'PASS', Date.now() - start, 'Sensitivity=Medium');
|
|
} catch (e: any) {
|
|
reporter.record('灵敏度-Medium', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-侦测灵敏度切换为Low', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Motion Detection');
|
|
await sleep(2000);
|
|
|
|
const sensEl = await driver.findElementRaw('name', 'Sensitivity');
|
|
if (!sensEl) {
|
|
reporter.record('灵敏度-Low', 'SKIP', Date.now() - start, '未找到Sensitivity');
|
|
return;
|
|
}
|
|
await driver.tapElement(sensEl);
|
|
await sleep(1500);
|
|
|
|
const lowEl = await driver.findElementRaw('name', 'Low');
|
|
expect(lowEl).not.toBeNull();
|
|
await driver.tapElement(lowEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('灵敏度-Low', 'PASS', Date.now() - start, 'Sensitivity=Low');
|
|
} catch (e: any) {
|
|
reporter.record('灵敏度-Low', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 侦测区域 ====================
|
|
|
|
it('设置页-设置侦测区域', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Motion Detection');
|
|
await sleep(2000);
|
|
|
|
const zoneEl = await driver.findElementRaw('name', 'Detection Zone');
|
|
if (!zoneEl) {
|
|
reporter.record('设置侦测区域', 'SKIP', Date.now() - start, '当前设备不支持Detection Zone');
|
|
return;
|
|
}
|
|
|
|
// Check zone switch
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
for (const sw of switches) {
|
|
const val = await driver.getElementAttribute(sw, 'value');
|
|
if (val === '0') {
|
|
await driver.tapElement(sw);
|
|
await sleep(5000);
|
|
break;
|
|
}
|
|
}
|
|
|
|
// Edit zone
|
|
const editEl = await driver.findElementRaw('name', 'Edit');
|
|
if (editEl) {
|
|
await driver.tapElement(editEl);
|
|
await sleep(3000);
|
|
const saveEl = await driver.findElementRaw('name', 'Save');
|
|
if (saveEl) await driver.tapElement(saveEl);
|
|
await sleep(3000);
|
|
}
|
|
|
|
reporter.record('设置侦测区域', 'PASS', Date.now() - start, 'Detection Zone设置完成');
|
|
} catch (e: any) {
|
|
reporter.record('设置侦测区域', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 夜视设置 ====================
|
|
|
|
it('设置页-切换夜视为打开', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const nvEl = await driver.findElementRaw('name', 'Night Vision');
|
|
expect(nvEl).not.toBeNull();
|
|
await driver.tapElement(nvEl!);
|
|
await sleep(1500);
|
|
|
|
const onEl = await driver.findElementRaw('name', 'On') || await driver.findElementRaw('name', 'Always on');
|
|
expect(onEl).not.toBeNull();
|
|
await driver.tapElement(onEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('设置夜视-打开', 'PASS', Date.now() - start, 'Night Vision=On');
|
|
} catch (e: any) {
|
|
reporter.record('设置夜视-打开', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-切换夜视为关闭', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const nvEl = await driver.findElementRaw('name', 'Night Vision');
|
|
expect(nvEl).not.toBeNull();
|
|
await driver.tapElement(nvEl!);
|
|
await sleep(1500);
|
|
|
|
const offEl = await driver.findElementRaw('name', 'Off');
|
|
expect(offEl).not.toBeNull();
|
|
await driver.tapElement(offEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('设置夜视-关闭', 'PASS', Date.now() - start, 'Night Vision=Off');
|
|
} catch (e: any) {
|
|
reporter.record('设置夜视-关闭', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-切换夜视为自动', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const nvEl = await driver.findElementRaw('name', 'Night Vision');
|
|
expect(nvEl).not.toBeNull();
|
|
await driver.tapElement(nvEl!);
|
|
await sleep(1500);
|
|
|
|
const autoEl = await driver.findElementRaw('name', 'Auto');
|
|
expect(autoEl).not.toBeNull();
|
|
await driver.tapElement(autoEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('设置夜视-自动', 'PASS', Date.now() - start, 'Night Vision=Auto');
|
|
} catch (e: any) {
|
|
reporter.record('设置夜视-自动', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 存储模式 ====================
|
|
|
|
it('设置页-切换存储模式为仅事件', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Local Storage');
|
|
await sleep(2000);
|
|
|
|
const modeEl = await driver.findElementRaw('name', 'Storage Mode');
|
|
if (!modeEl) {
|
|
reporter.record('存储模式-仅事件', 'SKIP', Date.now() - start, '未找到Storage Mode');
|
|
return;
|
|
}
|
|
await driver.tapElement(modeEl);
|
|
await sleep(1500);
|
|
|
|
const eventsEl = await driver.findElementRaw('name', 'Events Only');
|
|
expect(eventsEl).not.toBeNull();
|
|
await driver.tapElement(eventsEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('存储模式-仅事件', 'PASS', Date.now() - start, 'Storage=Events Only');
|
|
} catch (e: any) {
|
|
reporter.record('存储模式-仅事件', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-切换存储模式为持续', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Local Storage');
|
|
await sleep(2000);
|
|
|
|
const modeEl = await driver.findElementRaw('name', 'Storage Mode');
|
|
if (!modeEl) {
|
|
reporter.record('存储模式-持续', 'SKIP', Date.now() - start, '未找到Storage Mode');
|
|
return;
|
|
}
|
|
await driver.tapElement(modeEl);
|
|
await sleep(1500);
|
|
|
|
const contEl = await driver.findElementRaw('name', 'Continuous');
|
|
expect(contEl).not.toBeNull();
|
|
await driver.tapElement(contEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('存储模式-持续', 'PASS', Date.now() - start, 'Storage=Continuous');
|
|
} catch (e: any) {
|
|
reporter.record('存储模式-持续', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 对讲模式 ====================
|
|
|
|
it('设置页-切换对讲为单向', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const talkEl = await driver.findElementRaw('name', 'Talk Mode');
|
|
expect(talkEl).not.toBeNull();
|
|
await driver.tapElement(talkEl!);
|
|
await sleep(1500);
|
|
|
|
const oneEl = await driver.findElementRaw('name', 'One-way');
|
|
expect(oneEl).not.toBeNull();
|
|
await driver.tapElement(oneEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('对讲-单向', 'PASS', Date.now() - start, 'Talk Mode=One-way');
|
|
} catch (e: any) {
|
|
reporter.record('对讲-单向', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-切换对讲为双向', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const talkEl = await driver.findElementRaw('name', 'Talk Mode');
|
|
expect(talkEl).not.toBeNull();
|
|
await driver.tapElement(talkEl!);
|
|
await sleep(1500);
|
|
|
|
const twoEl = await driver.findElementRaw('name', 'Two-way');
|
|
expect(twoEl).not.toBeNull();
|
|
await driver.tapElement(twoEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('对讲-双向', 'PASS', Date.now() - start, 'Talk Mode=Two-way');
|
|
} catch (e: any) {
|
|
reporter.record('对讲-双向', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 对讲音量 ====================
|
|
|
|
it('设置页-切换对讲音量为High', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const volEl = await driver.findElementRaw('name', 'Volume');
|
|
if (!volEl) {
|
|
reporter.record('对讲音量-High', 'SKIP', Date.now() - start, '当前设备不支持Volume设置');
|
|
return;
|
|
}
|
|
await driver.tapElement(volEl);
|
|
await sleep(1500);
|
|
|
|
const highEl = await driver.findElementRaw('name', 'High');
|
|
expect(highEl).not.toBeNull();
|
|
await driver.tapElement(highEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('对讲音量-High', 'PASS', Date.now() - start, 'Volume=High');
|
|
} catch (e: any) {
|
|
reporter.record('对讲音量-High', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-切换对讲音量为Medium', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const volEl = await driver.findElementRaw('name', 'Volume');
|
|
if (!volEl) {
|
|
reporter.record('对讲音量-Medium', 'SKIP', Date.now() - start, '当前设备不支持');
|
|
return;
|
|
}
|
|
await driver.tapElement(volEl);
|
|
await sleep(1500);
|
|
|
|
const medEl = await driver.findElementRaw('name', 'Medium');
|
|
expect(medEl).not.toBeNull();
|
|
await driver.tapElement(medEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('对讲音量-Medium', 'PASS', Date.now() - start, 'Volume=Medium');
|
|
} catch (e: any) {
|
|
reporter.record('对讲音量-Medium', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-切换对讲音量为Low', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const volEl = await driver.findElementRaw('name', 'Volume');
|
|
if (!volEl) {
|
|
reporter.record('对讲音量-Low', 'SKIP', Date.now() - start, '当前设备不支持');
|
|
return;
|
|
}
|
|
await driver.tapElement(volEl);
|
|
await sleep(1500);
|
|
|
|
const lowEl = await driver.findElementRaw('name', 'Low');
|
|
expect(lowEl).not.toBeNull();
|
|
await driver.tapElement(lowEl!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('对讲音量-Low', 'PASS', Date.now() - start, 'Volume=Low');
|
|
} catch (e: any) {
|
|
reporter.record('对讲音量-Low', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 校准 ====================
|
|
|
|
it('设置页-摄像头校准', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const calEl = await driver.findElementRaw('name', 'Calibrate');
|
|
if (!calEl) {
|
|
reporter.record('摄像头校准', 'SKIP', Date.now() - start, '当前设备不支持Calibrate');
|
|
return;
|
|
}
|
|
await driver.tapElement(calEl);
|
|
await sleep(1500);
|
|
|
|
const confirmEl = await driver.findElementRaw('name', 'Confirm');
|
|
if (confirmEl) await driver.tapElement(confirmEl);
|
|
await sleep(5000);
|
|
|
|
reporter.record('摄像头校准', 'PASS', Date.now() - start, '校准操作完成');
|
|
} catch (e: any) {
|
|
reporter.record('摄像头校准', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 指示灯 ====================
|
|
|
|
it('设置页-打开/关闭指示灯', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const lightEl = await driver.findElementRaw('name', 'Indicator Light');
|
|
if (!lightEl) {
|
|
reporter.record('指示灯', 'SKIP', Date.now() - start, '未找到Indicator Light');
|
|
return;
|
|
}
|
|
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
for (const sw of switches) {
|
|
await driver.tapElement(sw);
|
|
await sleep(5000);
|
|
await driver.tapElement(sw);
|
|
await sleep(3000);
|
|
break;
|
|
}
|
|
|
|
reporter.record('指示灯', 'PASS', Date.now() - start, 'Indicator Light切换完成');
|
|
} catch (e: any) {
|
|
reporter.record('指示灯', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 水印 ====================
|
|
|
|
it('设置页-打开/关闭水印', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const vdEl = await driver.findElementRaw('name', 'Video Display');
|
|
if (!vdEl) {
|
|
reporter.record('水印', 'SKIP', Date.now() - start, '未找到Video Display');
|
|
return;
|
|
}
|
|
await driver.tapElement(vdEl);
|
|
await sleep(1500);
|
|
|
|
const waterEl = await driver.findElementRaw('name', 'Watermark');
|
|
if (waterEl) {
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
if (switches.length > 0) {
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(5000);
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(3000);
|
|
}
|
|
}
|
|
|
|
reporter.record('水印', 'PASS', Date.now() - start, 'Watermark切换完成');
|
|
} catch (e: any) {
|
|
reporter.record('水印', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 翻转 ====================
|
|
|
|
it('设置页-打开/关闭翻转', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const vdEl = await driver.findElementRaw('name', 'Video Display');
|
|
if (!vdEl) {
|
|
reporter.record('翻转', 'SKIP', Date.now() - start, '未找到Video Display');
|
|
return;
|
|
}
|
|
await driver.tapElement(vdEl);
|
|
await sleep(1500);
|
|
|
|
const flipEl = await driver.findElementRaw('name', 'Flip');
|
|
if (flipEl) {
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
if (switches.length > 0) {
|
|
const lastSw = switches[switches.length - 1];
|
|
await driver.tapElement(lastSw);
|
|
await sleep(5000);
|
|
await driver.tapElement(lastSw);
|
|
await sleep(3000);
|
|
}
|
|
}
|
|
|
|
reporter.record('翻转', 'PASS', Date.now() - start, 'Flip切换完成');
|
|
} catch (e: any) {
|
|
reporter.record('翻转', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 抗闪烁 ====================
|
|
|
|
it('设置页-切换抗闪烁为50Hz', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const vdEl = await driver.findElementRaw('name', 'Video Display');
|
|
if (vdEl) {
|
|
await driver.tapElement(vdEl);
|
|
await sleep(1500);
|
|
}
|
|
|
|
const flickerEl = await driver.findElementRaw('name', 'Anti-Flicker');
|
|
if (!flickerEl) {
|
|
reporter.record('抗闪烁-50Hz', 'SKIP', Date.now() - start, '当前设备不支持Anti-Flicker');
|
|
return;
|
|
}
|
|
await driver.tapElement(flickerEl);
|
|
await sleep(1500);
|
|
|
|
const hz50El = await driver.findElementRaw('name', '50Hz');
|
|
expect(hz50El).not.toBeNull();
|
|
await driver.tapElement(hz50El!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('抗闪烁-50Hz', 'PASS', Date.now() - start, 'Anti-Flicker=50Hz');
|
|
} catch (e: any) {
|
|
reporter.record('抗闪烁-50Hz', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-切换抗闪烁为60Hz', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Basic Settings');
|
|
await sleep(1500);
|
|
|
|
const vdEl = await driver.findElementRaw('name', 'Video Display');
|
|
if (vdEl) {
|
|
await driver.tapElement(vdEl);
|
|
await sleep(1500);
|
|
}
|
|
|
|
const flickerEl = await driver.findElementRaw('name', 'Anti-Flicker');
|
|
if (!flickerEl) {
|
|
reporter.record('抗闪烁-60Hz', 'SKIP', Date.now() - start, '当前设备不支持Anti-Flicker');
|
|
return;
|
|
}
|
|
await driver.tapElement(flickerEl);
|
|
await sleep(1500);
|
|
|
|
const hz60El = await driver.findElementRaw('name', '60Hz');
|
|
expect(hz60El).not.toBeNull();
|
|
await driver.tapElement(hz60El!);
|
|
await sleep(5000);
|
|
|
|
reporter.record('抗闪烁-60Hz', 'PASS', Date.now() - start, 'Anti-Flicker=60Hz');
|
|
} catch (e: any) {
|
|
reporter.record('抗闪烁-60Hz', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== NFC ====================
|
|
|
|
it('设置页-NFC页面显示', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
const found = await scrollToAndTap('NFC');
|
|
if (!found) {
|
|
reporter.record('NFC页面', 'SKIP', Date.now() - start, '未找到NFC选项');
|
|
return;
|
|
}
|
|
await sleep(3000);
|
|
|
|
const source = await driver.getSource();
|
|
const hasNfc = source.includes('NFC') || source.includes('Tag');
|
|
console.log('NFC页面:', hasNfc);
|
|
|
|
reporter.record('NFC页面', 'PASS', Date.now() - start, `NFC页面加载=${hasNfc}`);
|
|
} catch (e: any) {
|
|
reporter.record('NFC页面', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 巡航 ====================
|
|
|
|
it('设置页-巡航添加', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
const found = await scrollToAndTap('Patrols');
|
|
if (!found) {
|
|
reporter.record('巡航添加', 'SKIP', Date.now() - start, '当前设备不支持Patrols');
|
|
return;
|
|
}
|
|
await sleep(2000);
|
|
|
|
// Enable patrol if off
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
if (switches.length > 0) {
|
|
const val = await driver.getElementAttribute(switches[0], 'value');
|
|
if (val === '0') {
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(3000);
|
|
}
|
|
}
|
|
|
|
// Schedule
|
|
const scheduleEl = await driver.findElementRaw('name', 'Schedule');
|
|
if (scheduleEl) await driver.tapElement(scheduleEl);
|
|
await sleep(1500);
|
|
|
|
// Add once
|
|
const addEl = await driver.findElementRaw('name', 'Add');
|
|
if (addEl) {
|
|
await driver.tapElement(addEl);
|
|
await sleep(1500);
|
|
const saveEl = await driver.findElementRaw('name', 'Save');
|
|
if (saveEl) await driver.tapElement(saveEl);
|
|
await sleep(3000);
|
|
}
|
|
|
|
let source = await driver.getSource();
|
|
const hasOnce = source.includes('Once') || source.includes('Only once');
|
|
console.log('Only once添加:', hasOnce);
|
|
|
|
// Add repeat
|
|
const addEl2 = await driver.findElementRaw('name', 'Add');
|
|
if (addEl2) {
|
|
await driver.tapElement(addEl2);
|
|
await sleep(1500);
|
|
const repeatEl = await driver.findElementRaw('name', 'Repeat');
|
|
if (repeatEl) await driver.tapElement(repeatEl);
|
|
await sleep(500);
|
|
const saveEl2 = await driver.findElementRaw('name', 'Save');
|
|
if (saveEl2) await driver.tapElement(saveEl2);
|
|
await sleep(3000);
|
|
}
|
|
|
|
source = await driver.getSource();
|
|
const hasRepeat = source.includes('Every day') || source.includes('Repeat');
|
|
console.log('Repeat添加:', hasRepeat);
|
|
|
|
reporter.record('巡航添加', 'PASS', Date.now() - start, `Once=${hasOnce}, Repeat=${hasRepeat}`);
|
|
} catch (e: any) {
|
|
reporter.record('巡航添加', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-巡航删除', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
const found = await scrollToAndTap('Patrols');
|
|
if (!found) {
|
|
reporter.record('巡航删除', 'SKIP', Date.now() - start, '当前设备不支持Patrols');
|
|
return;
|
|
}
|
|
await sleep(2000);
|
|
|
|
const scheduleEl = await driver.findElementRaw('name', 'Schedule');
|
|
if (scheduleEl) await driver.tapElement(scheduleEl);
|
|
await sleep(1500);
|
|
|
|
// Delete button
|
|
const moreEl = await driver.findElementRaw('name', 'More');
|
|
if (moreEl) {
|
|
await driver.tapElement(moreEl);
|
|
await sleep(1000);
|
|
}
|
|
const deleteEl = await driver.findElementRaw('name', 'Delete');
|
|
if (deleteEl) {
|
|
await driver.tapElement(deleteEl);
|
|
await sleep(1500);
|
|
// Select and delete
|
|
const cells = await driver.findElementsRaw('class name', 'XCUIElementTypeCell');
|
|
if (cells.length > 0) await driver.tapElement(cells[0]);
|
|
await sleep(500);
|
|
const del2 = await driver.findElementRaw('name', 'Delete');
|
|
if (del2) await driver.tapElement(del2);
|
|
await sleep(1000);
|
|
const confirmEl = await driver.findElementRaw('name', 'Confirm');
|
|
if (confirmEl) await driver.tapElement(confirmEl);
|
|
await sleep(3000);
|
|
}
|
|
|
|
reporter.record('巡航删除', 'PASS', Date.now() - start, '巡航计划删除完成');
|
|
} catch (e: any) {
|
|
reporter.record('巡航删除', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
it('设置页-巡航全选删除', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
const found = await scrollToAndTap('Patrols');
|
|
if (!found) {
|
|
reporter.record('巡航全选删除', 'SKIP', Date.now() - start, '当前设备不支持Patrols');
|
|
return;
|
|
}
|
|
await sleep(2000);
|
|
|
|
const scheduleEl = await driver.findElementRaw('name', 'Schedule');
|
|
if (scheduleEl) await driver.tapElement(scheduleEl);
|
|
await sleep(1500);
|
|
|
|
// Add one first if empty
|
|
const addEl = await driver.findElementRaw('name', 'Add');
|
|
if (addEl) {
|
|
await driver.tapElement(addEl);
|
|
await sleep(1500);
|
|
const saveEl = await driver.findElementRaw('name', 'Save');
|
|
if (saveEl) await driver.tapElement(saveEl);
|
|
await sleep(2000);
|
|
}
|
|
|
|
// Delete all
|
|
const moreEl = await driver.findElementRaw('name', 'More');
|
|
if (moreEl) {
|
|
await driver.tapElement(moreEl);
|
|
await sleep(1000);
|
|
}
|
|
const deleteEl = await driver.findElementRaw('name', 'Delete');
|
|
if (deleteEl) {
|
|
await driver.tapElement(deleteEl);
|
|
await sleep(1500);
|
|
const selectAllEl = await driver.findElementRaw('name', 'Select All');
|
|
if (selectAllEl) await driver.tapElement(selectAllEl);
|
|
await sleep(500);
|
|
const del2 = await driver.findElementRaw('name', 'Delete');
|
|
if (del2) await driver.tapElement(del2);
|
|
await sleep(1000);
|
|
const confirmEl = await driver.findElementRaw('name', 'Confirm');
|
|
if (confirmEl) await driver.tapElement(confirmEl);
|
|
await sleep(3000);
|
|
}
|
|
|
|
// Verify empty
|
|
const source = await driver.getSource();
|
|
const isEmpty = source.includes('No schedule') || source.includes('Add') || !source.includes('Every day');
|
|
console.log('巡航清空:', isEmpty);
|
|
|
|
// Turn off patrol
|
|
await driver.goBack();
|
|
await sleep(1000);
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
if (switches.length > 0) {
|
|
const val = await driver.getElementAttribute(switches[0], 'value');
|
|
if (val === '1') {
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(3000);
|
|
}
|
|
}
|
|
|
|
reporter.record('巡航全选删除', 'PASS', Date.now() - start, `全选删除完成, 清空=${isEmpty}`);
|
|
} catch (e: any) {
|
|
reporter.record('巡航全选删除', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 预设点设置 ====================
|
|
|
|
it('设置页-预设点添加', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
const found = await scrollToAndTap('Preset Point Settings');
|
|
if (!found) {
|
|
reporter.record('预设点设置', 'SKIP', Date.now() - start, '当前设备不支持Preset Point Settings');
|
|
return;
|
|
}
|
|
await sleep(2000);
|
|
|
|
// Select point 1
|
|
const point1El = await driver.findElementRaw('name', '1');
|
|
if (point1El) await driver.tapElement(point1El);
|
|
await sleep(3000);
|
|
|
|
// Move direction
|
|
const dirEl = await driver.findElementRaw('name', 'Up') || await driver.findElementRaw('name', 'Left');
|
|
if (dirEl) {
|
|
await driver.tapElement(dirEl);
|
|
await sleep(2000);
|
|
}
|
|
|
|
// Save
|
|
const saveEl = await driver.findElementRaw('name', 'Save');
|
|
if (saveEl) await driver.tapElement(saveEl);
|
|
await sleep(3000);
|
|
|
|
reporter.record('预设点设置', 'PASS', Date.now() - start, '预设点设置完成');
|
|
} catch (e: any) {
|
|
reporter.record('预设点设置', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 隐私模式设置 ====================
|
|
|
|
it('设置页-打开/关闭隐私模式', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
const found = await scrollToAndTap('Privacy Mode');
|
|
if (!found) throw new Error('未找到Privacy Mode');
|
|
await sleep(3000);
|
|
|
|
// Verify privacy on
|
|
let source = await driver.getSource();
|
|
const privacyOn = source.includes('Privacy') || source.includes('turned off') || source.includes('Turn on');
|
|
console.log('隐私模式开启:', privacyOn);
|
|
|
|
// Go back
|
|
await driver.goBack();
|
|
await sleep(1500);
|
|
|
|
// Re-enter settings and turn off privacy
|
|
const settingsEl = await driver.findElementRaw('name', 'Settings');
|
|
if (settingsEl) {
|
|
await driver.tapElement(settingsEl);
|
|
await sleep(2000);
|
|
await scrollToAndTap('Privacy Mode');
|
|
await sleep(3000);
|
|
}
|
|
|
|
// Verify camera restored
|
|
await driver.goBack();
|
|
await sleep(2000);
|
|
source = await driver.getSource();
|
|
const restored = !source.includes('Privacy Mode is on');
|
|
|
|
reporter.record('隐私模式设置', 'PASS', Date.now() - start, `开启=${privacyOn}, 关闭恢复=${restored}`);
|
|
} catch (e: any) {
|
|
reporter.record('隐私模式设置', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
|
|
// ==================== 再次打开侦测开关 ====================
|
|
|
|
it('设置页-再次打开侦测开关', async () => {
|
|
const start = Date.now();
|
|
try {
|
|
await enterSettingPage();
|
|
await scrollToAndTap('Motion Detection');
|
|
await sleep(2000);
|
|
|
|
const switches = await driver.findElementsRaw('class name', 'XCUIElementTypeSwitch');
|
|
if (switches.length > 0) {
|
|
const val = await driver.getElementAttribute(switches[0], 'value');
|
|
if (val === '0') {
|
|
await driver.tapElement(switches[0]);
|
|
await sleep(5000);
|
|
}
|
|
const afterVal = await driver.getElementAttribute(switches[0], 'value');
|
|
console.log('侦测开关状态:', afterVal === '1' ? '开' : '关');
|
|
}
|
|
|
|
reporter.record('再次打开侦测', 'PASS', Date.now() - start, 'Motion Detection确保开启');
|
|
} catch (e: any) {
|
|
reporter.record('再次打开侦测', 'FAIL', Date.now() - start, e.message);
|
|
throw e;
|
|
}
|
|
});
|
|
});
|