|
| 1 | +import { beforeEach, test, vi } from 'vitest'; |
| 2 | +import assert from 'node:assert/strict'; |
| 3 | +import { promises as fs } from 'node:fs'; |
| 4 | +import path from 'node:path'; |
| 5 | + |
| 6 | +vi.mock('@agent-device/host-kit/command', async (importOriginal) => { |
| 7 | + const actual = await importOriginal<typeof import('@agent-device/host-kit/command')>(); |
| 8 | + return { ...actual, runCmd: vi.fn(actual.runCmd) }; |
| 9 | +}); |
| 10 | +vi.mock('../simulator.ts', async (importOriginal) => { |
| 11 | + const actual = await importOriginal<typeof import('../simulator.ts')>(); |
| 12 | + return { ...actual, ensureBootedSimulator: vi.fn(actual.ensureBootedSimulator) }; |
| 13 | +}); |
| 14 | + |
| 15 | +const execActual = await vi.importActual<typeof import('@agent-device/host-kit/command')>( |
| 16 | + '@agent-device/host-kit/command', |
| 17 | +); |
| 18 | +const simulatorActual = await vi.importActual<typeof import('../simulator.ts')>('../simulator.ts'); |
| 19 | + |
| 20 | +import { closeIosApp } from '../app-launch.ts'; |
| 21 | +import { ensureBootedSimulator } from '../simulator.ts'; |
| 22 | +import { IOS_SIMULATOR_TERMINATE_TIMEOUT_MS } from '../config.ts'; |
| 23 | +import { runCmd } from '@agent-device/host-kit/command'; |
| 24 | +import { withMockedMacOsHelper } from './macos-helper-test-utils.ts'; |
| 25 | +import { IOS_TEST_SIMULATOR, MACOS_TEST_DEVICE } from './apple-core-stub-helpers.ts'; |
| 26 | + |
| 27 | +const mockRunCmd = vi.mocked(runCmd); |
| 28 | +const mockEnsureBootedSimulator = vi.mocked(ensureBootedSimulator); |
| 29 | + |
| 30 | +beforeEach(() => { |
| 31 | + vi.resetAllMocks(); |
| 32 | + mockRunCmd.mockImplementation(execActual.runCmd); |
| 33 | + mockEnsureBootedSimulator.mockImplementation(simulatorActual.ensureBootedSimulator); |
| 34 | +}); |
| 35 | + |
| 36 | +test('closeIosApp on macOS uses helper quit for bundle identifiers', async () => { |
| 37 | + await withMockedMacOsHelper( |
| 38 | + [ |
| 39 | + '#!/bin/sh', |
| 40 | + String.raw`printf "%s\n" "$@" > "$AGENT_DEVICE_TEST_ARGS_FILE"`, |
| 41 | + "cat <<'JSON'", |
| 42 | + '{"ok":true,"data":{"bundleId":"com.example.foobar","running":false,"terminated":false,"forceTerminated":false}}', |
| 43 | + 'JSON', |
| 44 | + '', |
| 45 | + ].join('\n'), |
| 46 | + async ({ tmpDir }) => { |
| 47 | + const argsLogPath = path.join(tmpDir, 'args.log'); |
| 48 | + const previousArgsFile = process.env.AGENT_DEVICE_TEST_ARGS_FILE; |
| 49 | + process.env.AGENT_DEVICE_TEST_ARGS_FILE = argsLogPath; |
| 50 | + |
| 51 | + try { |
| 52 | + await closeIosApp(MACOS_TEST_DEVICE, 'com.example.foobar'); |
| 53 | + const logged = await fs.readFile(argsLogPath, 'utf8'); |
| 54 | + assert.equal(logged, 'app\nquit\n--bundle-id\ncom.example.foobar\n'); |
| 55 | + } finally { |
| 56 | + if (previousArgsFile === undefined) delete process.env.AGENT_DEVICE_TEST_ARGS_FILE; |
| 57 | + else process.env.AGENT_DEVICE_TEST_ARGS_FILE = previousArgsFile; |
| 58 | + } |
| 59 | + }, |
| 60 | + { tempPrefix: 'agent-device-macos-close-helper-test-' }, |
| 61 | + ); |
| 62 | +}); |
| 63 | + |
| 64 | +test('closeIosApp on iOS simulator bounds simctl terminate', async () => { |
| 65 | + mockEnsureBootedSimulator.mockResolvedValue(undefined); |
| 66 | + mockRunCmd.mockResolvedValue({ stdout: '', stderr: '', exitCode: 0 }); |
| 67 | + |
| 68 | + await closeIosApp(IOS_TEST_SIMULATOR, 'com.example.foobar'); |
| 69 | + |
| 70 | + assert.equal(mockRunCmd.mock.calls.length, 1); |
| 71 | + assert.equal(mockRunCmd.mock.calls[0]?.[0], 'xcrun'); |
| 72 | + assert.deepEqual(mockRunCmd.mock.calls[0]?.[1], [ |
| 73 | + 'simctl', |
| 74 | + 'terminate', |
| 75 | + 'sim-1', |
| 76 | + 'com.example.foobar', |
| 77 | + ]); |
| 78 | + assert.equal(mockRunCmd.mock.calls[0]?.[2]?.allowFailure, true); |
| 79 | + assert.equal(mockRunCmd.mock.calls[0]?.[2]?.timeoutMs, IOS_SIMULATOR_TERMINATE_TIMEOUT_MS); |
| 80 | +}); |
0 commit comments