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 { sleep } from '../../utils/common'; import * as dotenv from 'dotenv'; import * as path from 'path'; dotenv.config({ path: path.resolve(__dirname, '../../.env') }); // 摄像头全屏(普通功能用例,非 P0)。manifest 摄像头控制 P0 只有 15974「出流」,无单列全屏 step → 不挂 P0/ONES。 // 流程:进功能页 → 唤出 overlay → 点控制栏「全屏 ⛶」(右端,自绘,相对坐标 W*0.926,H*0.358) → 转横屏(W>H)校验 → BACK 回竖屏。 // 与已保留的 iOS 骨架 camera_control_fullscreen.test.ts 并存(那份后续单独调 iOS/细分动作)。 interface CamCfg { name: string; } const CAMERAS: CamCfg[] = [ { name: 'Pan/Tilt Cam 2K oy' }, // 需要覆盖更多型号时按 camera_stream 的列表加(Indoor / Pan/Tilt / PTC Plus 2K·3K / OSC) ]; const ONLY = process.env.CAMERA_NAME || ''; const TARGETS = ONLY ? CAMERAS.filter((c) => c.name.includes(ONLY)) : CAMERAS; const FULL_X = parseFloat(process.env.CAM_FULL_X || '0.926'); const FULL_Y = parseFloat(process.env.CAM_FULL_Y || '0.358'); describe('Camera FullScreen - 摄像头全屏(横屏切换)', () => { let driver: DeviceDriver; let reporter: TestReporter; let W = 1080, H = 2400; beforeAll(async () => { driver = createDriver(); await driver.createSession(); reporter = new TestReporter('Camera_FullScreen', driver.platform.toUpperCase()); const s = await driver.getWindowSize(); W = s.width; H = s.height; }); afterAll(async () => { reporter.generate(); await driver.destroySession(); }); beforeEach(async () => { await driver.dismissPopupIfPresent(); await driver.goBackToHomepage(); await driver.dismissPopupIfPresent(); }); async function enterCamera(name: string): Promise { for (let i = 0; i < 8; i++) { const el = await driver.findElementRaw('-android uiautomator', `new UiSelector().textContains("${name}")`).catch(() => null); if (el) { const r = await driver.getElementRect(el); await driver.tap(r.x + Math.min(r.width / 2, 120), Math.max(r.y - 40, r.y + 20)); await sleep(7000); return true; } await driver.scrollDown(500); await sleep(800); } return false; } for (const cam of TARGETS) { it(`[Camera] ${cam.name} 全屏切换`, { timeout: 120000 }, async () => { const start = Date.now(); const label = `全屏${cam.name}`; try { if (!(await enterCamera(cam.name))) throw new Error(`首页找不到摄像头卡片 "${cam.name}"`); await driver.tap(Math.round(W / 2), Math.round(H * 0.25)); await sleep(1200); // 唤出 overlay await driver.tap(Math.round(W * FULL_X), Math.round(H * FULL_Y)); await sleep(2500); let sz = await driver.getWindowSize(); const landscape = sz.width > sz.height; if (!landscape) { const ss = await driver.screenshot().catch(() => ''); reporter.record(label, 'FAIL', Date.now() - start, `点全屏未转横屏(size=${sz.width}x${sz.height})`, ss); throw new Error('全屏未转横屏'); } console.log(`${cam.name} 已转横屏 ${sz.width}x${sz.height}`); await driver.goBack(); await sleep(2500); sz = await driver.getWindowSize(); const backPortrait = sz.height > sz.width; const elapsed = ((Date.now() - start) / 1000).toFixed(1); reporter.record(label, 'PASS', Date.now() - start, `全屏成功(横屏${landscape}→退出回竖屏${backPortrait}), 耗时${elapsed}s`); expect(landscape).toBe(true); } catch (e: any) { const ss = await driver.screenshot().catch(() => ''); reporter.record(label, 'FAIL', Date.now() - start, e.message, ss); throw e; } }); } });