import { describe, it, beforeAll, afterAll, beforeEach, expect } from 'vitest'; import { DeviceDriver } from '../../drivers/types'; import { createDriver } from '../../drivers/factory'; import { CAMERA_LOCATORS } from '../../locators/camera-locators'; 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 Card - 摄像头拉流', () => { let driver: DeviceDriver; let reporter: TestReporter; beforeAll(async () => { driver = createDriver(); await driver.createSession(); reporter = new TestReporter('Camera_Card', 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 { 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; } it('摄像头拉流 - 点击卡片进入实时画面', async () => { const start = Date.now(); try { await sleep(3000); const cardId = await findCameraCard(); expect(cardId).not.toBeNull(); await driver.tapElement(cardId!); await sleep(3000); // Verify camera is connected and streaming const source = await driver.getSource(); const isConnected = source.includes('Connected') || source.includes('Live') || source.includes('XCUIElementTypeOther') || !source.includes('Disconnected'); expect(isConnected).toBe(true); // Verify camera status page loaded (check for control elements) const hasControls = source.includes('Photo') || source.includes('Video') || source.includes('Audio') || source.includes('Features') || source.includes('Events') || source.includes('Playback'); console.log('摄像头页面加载:', hasControls ? '成功' : '部分加载'); // Wait and verify stream stays stable (5 checks, 10s intervals) for (let i = 0; i < 5; i++) { await sleep(10000); const src = await driver.getSource(); const stillLive = !src.includes('Disconnected') && !src.includes('Connection failed'); console.log(`拉流检查 ${i + 1}/5: ${stillLive ? '正常' : '异常'}`); expect(stillLive).toBe(true); } const detail = `摄像头拉流验证通过, 持续稳定50s`; reporter.record('摄像头拉流', 'PASS', Date.now() - start, detail); } catch (e: any) { reporter.record('摄像头拉流', 'FAIL', Date.now() - start, e.message); throw e; } }); });