diff --git a/packages/platform-android/src/inventory-parsers.ts b/packages/platform-android/src/inventory-parsers.ts index cf65fae510..5ee5f9b874 100644 --- a/packages/platform-android/src/inventory-parsers.ts +++ b/packages/platform-android/src/inventory-parsers.ts @@ -39,11 +39,14 @@ export function parseAndroidDeviceDescription(rawOutput: string): { }; } +/** avdmanager restricts AVD names to these characters; other stdout lines are emulator logging. */ +const ANDROID_AVD_NAME = /^[A-Za-z0-9._-]+$/; + export function parseAndroidAvdList(rawOutput: string): string[] { return rawOutput .split('\n') .map((line) => line.trim()) - .filter((line) => line.length > 0); + .filter((line) => ANDROID_AVD_NAME.test(line)); } export function parseAndroidEmulatorAvdNameOutput(rawOutput: string): string | undefined { diff --git a/packages/platform-android/src/inventory.test.ts b/packages/platform-android/src/inventory.test.ts index 2c3f4f50f6..6d48b980f9 100644 --- a/packages/platform-android/src/inventory.test.ts +++ b/packages/platform-android/src/inventory.test.ts @@ -77,6 +77,37 @@ test.each([ }, ); +const EMULATOR_CRASHDATA_BANNER = + 'INFO | Storing crashdata in: /tmp/user/emu-crash-34.2.16.db, detection is enabled for process: 98765'; + +test.each([ + ['only the crashdata banner', `${EMULATOR_CRASHDATA_BANNER}\n`, []], + [ + 'the crashdata banner beside AVD names', + `${EMULATOR_CRASHDATA_BANNER}\r\nPixel_9_Pro_XL\r\nwear-os.36\r\n`, + ['Pixel_9_Pro_XL', 'wear-os.36'], + ], +] as const)( + 'Android inventory lists only AVD names when emulator -list-avds prints %s', + async (_case, listAvdsStdout, expectedAvds) => { + const host = createHost(async (request) => { + if (request.executable === 'emulator') return result(listAvdsStdout); + if (request.args.join('\0') === 'devices\0-l') return result('List of devices attached\n'); + throw new Error(`Unexpected command: ${request.executable} ${request.args.join(' ')}`); + }); + + const devices = await createAndroidInventory(host).discover( + { androidAvdSelection: 'include-stopped' }, + scope, + ); + + assert.deepEqual( + devices.map((device) => device.id), + expectedAvds, + ); + }, +); + test.each([ ['exits non-zero', async () => result('', 'error: closed', 1)], [