|
| 1 | +import test from 'node:test'; |
| 2 | +import assert from 'node:assert/strict'; |
| 3 | +import { promises as fs } from 'node:fs'; |
| 4 | +import os from 'node:os'; |
| 5 | +import path from 'node:path'; |
| 6 | +import { dispatchCommand } from '../dispatch.ts'; |
| 7 | +import type { DeviceInfo } from '../../utils/device.ts'; |
| 8 | + |
| 9 | +const ANDROID_DEVICE: DeviceInfo = { |
| 10 | + platform: 'android', |
| 11 | + id: 'emulator-5554', |
| 12 | + name: 'Pixel', |
| 13 | + kind: 'emulator', |
| 14 | + booted: true, |
| 15 | +}; |
| 16 | + |
| 17 | +async function withMockedAdb( |
| 18 | + tempPrefix: string, |
| 19 | + run: (argsLogPath: string) => Promise<void>, |
| 20 | +): Promise<void> { |
| 21 | + const tmpDir = await fs.mkdtemp(path.join(os.tmpdir(), tempPrefix)); |
| 22 | + const adbPath = path.join(tmpDir, 'adb'); |
| 23 | + const argsLogPath = path.join(tmpDir, 'args.log'); |
| 24 | + await fs.writeFile( |
| 25 | + adbPath, |
| 26 | + '#!/bin/sh\nprintf "%s\\n" "$@" >> "$AGENT_DEVICE_TEST_ARGS_FILE"\nexit 0\n', |
| 27 | + 'utf8', |
| 28 | + ); |
| 29 | + await fs.chmod(adbPath, 0o755); |
| 30 | + |
| 31 | + const previousPath = process.env.PATH; |
| 32 | + const previousArgsFile = process.env.AGENT_DEVICE_TEST_ARGS_FILE; |
| 33 | + process.env.PATH = `${tmpDir}${path.delimiter}${previousPath ?? ''}`; |
| 34 | + process.env.AGENT_DEVICE_TEST_ARGS_FILE = argsLogPath; |
| 35 | + |
| 36 | + try { |
| 37 | + await run(argsLogPath); |
| 38 | + } finally { |
| 39 | + process.env.PATH = previousPath; |
| 40 | + if (previousArgsFile === undefined) delete process.env.AGENT_DEVICE_TEST_ARGS_FILE; |
| 41 | + else process.env.AGENT_DEVICE_TEST_ARGS_FILE = previousArgsFile; |
| 42 | + await fs.rm(tmpDir, { recursive: true, force: true }); |
| 43 | + } |
| 44 | +} |
| 45 | + |
| 46 | +test('dispatch back --in-app falls back to Android system back keyevent', async () => { |
| 47 | + await withMockedAdb('agent-device-dispatch-back-in-app-', async (argsLogPath) => { |
| 48 | + const result = await dispatchCommand(ANDROID_DEVICE, 'back', [], undefined, { |
| 49 | + backMode: 'in-app', |
| 50 | + }); |
| 51 | + |
| 52 | + assert.equal(result?.action, 'back'); |
| 53 | + assert.equal(result?.mode, 'in-app'); |
| 54 | + const args = (await fs.readFile(argsLogPath, 'utf8')).trim().split('\n').filter(Boolean); |
| 55 | + assert.deepEqual(args, ['-s', 'emulator-5554', 'shell', 'input', 'keyevent', '4']); |
| 56 | + }); |
| 57 | +}); |
| 58 | + |
| 59 | +test('dispatch back --system uses Android system back keyevent', async () => { |
| 60 | + await withMockedAdb('agent-device-dispatch-back-system-', async (argsLogPath) => { |
| 61 | + const result = await dispatchCommand(ANDROID_DEVICE, 'back', [], undefined, { |
| 62 | + backMode: 'system', |
| 63 | + }); |
| 64 | + |
| 65 | + assert.equal(result?.action, 'back'); |
| 66 | + assert.equal(result?.mode, 'system'); |
| 67 | + const args = (await fs.readFile(argsLogPath, 'utf8')).trim().split('\n').filter(Boolean); |
| 68 | + assert.deepEqual(args, ['-s', 'emulator-5554', 'shell', 'input', 'keyevent', '4']); |
| 69 | + }); |
| 70 | +}); |
0 commit comments