Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
5 changes: 4 additions & 1 deletion packages/platform-android/src/inventory-parsers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand Down
31 changes: 31 additions & 0 deletions packages/platform-android/src/inventory.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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)],
[
Expand Down
Loading