From 0cd0cd5e81f02ec4996fce3226ddb972064b2b25 Mon Sep 17 00:00:00 2001 From: Navin Chandra Date: Thu, 5 Feb 2026 11:10:56 +0530 Subject: [PATCH 1/4] support retrieving specific attributes in `listApps` --- lib/commands/app-management.ts | 7 +++++-- lib/execute-method-map.ts | 2 +- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lib/commands/app-management.ts b/lib/commands/app-management.ts index 745b113e0e..b53692851f 100644 --- a/lib/commands/app-management.ts +++ b/lib/commands/app-management.ts @@ -298,7 +298,9 @@ export async function queryAppState( * List applications installed on the real device under test * * Read [Pushing/Pulling files](https://appium.io/docs/en/writing-running-appium/ios/ios-xctest-file-movement/) for more details. - * @param applicationType - The type of applications to list. + * @param applicationType - The type of applications to list (default: 'User'). + * @param returnAttributes - Array of attribute names to return for each app (e.g., ["CFBundleIdentifier", "CFBundleName"]). + * If not provided, all available attributes are returned. * @returns An object mapping bundle identifiers to app properties (e.g., CFBundleName, CFBundleVersion, etc.). * @remarks Having `UIFileSharingEnabled` set to `true` in the app properties means the app supports file upload/download in its `documents` container. * @group Real Device Only @@ -306,12 +308,13 @@ export async function queryAppState( export async function mobileListApps( this: XCUITestDriver, applicationType: 'User' | 'System' = 'User', + returnAttributes?: string[], ): Promise { const device = requireRealDevice(this, 'Listing apps'); const useRemoteXPC = isIos18OrNewer(this.opts); const client = await InstallationProxyClient.create(device.udid, useRemoteXPC); try { - return await client.listApplications({applicationType}); + return await client.listApplications({applicationType, returnAttributes}); } finally { await client.close(); } diff --git a/lib/execute-method-map.ts b/lib/execute-method-map.ts index c960d790d1..4c606562e9 100644 --- a/lib/execute-method-map.ts +++ b/lib/execute-method-map.ts @@ -199,7 +199,7 @@ export const executeMethodMap = { 'mobile: listApps': { command: 'mobileListApps', params: { - optional: ['applicationType'], + optional: ['applicationType', 'returnAttributes'], }, }, 'mobile: clearApp': { From 33dbd6bda6f1860b8f7e85b0b1efd0a4d347e95c Mon Sep 17 00:00:00 2001 From: Navin Chandra Date: Thu, 5 Feb 2026 11:11:25 +0530 Subject: [PATCH 2/4] update docs --- docs/reference/execute-methods.md | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/docs/reference/execute-methods.md b/docs/reference/execute-methods.md index dc049e7bb9..a2749f268b 100644 --- a/docs/reference/execute-methods.md +++ b/docs/reference/execute-methods.md @@ -333,10 +333,11 @@ Offload applications will not be in the result. Name | Type | Required | Description | Example --- | --- | --- | --- | --- applicationType | string | no | The type of applications to list. Either `System` or `User` (the default one) | System +returnAttributes | array<string> | no | Array of attribute names to return for each app. If not provided, all available attributes are returned. Common attributes include: `CFBundleIdentifier`, `CFBundleName`, `CFBundleDisplayName`, `CFBundleVersion`, `CFBundleShortVersionString`, `UIFileSharingEnabled` | `['CFBundleIdentifier', 'CFBundleName', 'CFBundleVersion']` #### Returned Result -A map where keys are bundle identifiers and values are maps of platform-specific app properties. Having `UIFileSharingEnabled` set to `true` in the app properties map means this app supports file upload and download into its `documents` container. Read the [File Transfer](../guides/file-transfer.md) guide for more details. +A map where keys are bundle identifiers and values are maps of platform-specific app properties. The properties included depend on the `returnAttributes` parameter. Having `UIFileSharingEnabled` set to `true` in the app properties map means this app supports file upload and download into its `documents` container. Read the [File Transfer](../guides/file-transfer.md) guide for more details. ### mobile: clearApp From 6b8de34763660010cefcc7f6b1f8e493524fea63 Mon Sep 17 00:00:00 2001 From: Navin Chandra Date: Thu, 5 Feb 2026 11:32:08 +0530 Subject: [PATCH 3/4] always include `CFBundleIdentifier` --- lib/device/installation-proxy-client.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/device/installation-proxy-client.ts b/lib/device/installation-proxy-client.ts index 883dd7d5b5..c94a81330b 100644 --- a/lib/device/installation-proxy-client.ts +++ b/lib/device/installation-proxy-client.ts @@ -81,15 +81,20 @@ export class InstallationProxyClient { * @returns Object keyed by bundle ID */ async listApplications(opts?: ListApplicationOptions): Promise { + // Ensure CFBundleIdentifier is always included + const normalizedOpts = opts?.returnAttributes && !opts.returnAttributes.includes('CFBundleIdentifier') + ? { ...opts, returnAttributes: ['CFBundleIdentifier', ...opts.returnAttributes] } + : opts; + if (!this.isRemoteXPC) { - return await this.iosDeviceService.listApplications(opts); + return await this.iosDeviceService.listApplications(normalizedOpts); } // RemoteXPC returns array, need to convert to object const apps = await this.remoteXPCService.browse({ - applicationType: opts?.applicationType || 'Any', + applicationType: normalizedOpts?.applicationType || 'Any', // Use '*' to request all attributes when returnAttributes is not explicitly specified - returnAttributes: opts?.returnAttributes || '*', + returnAttributes: normalizedOpts?.returnAttributes || '*', }); // Convert array to object keyed by CFBundleIdentifier From 096b7538a76b10dff195f1f531d2406fdc1db7e8 Mon Sep 17 00:00:00 2001 From: Navin Chandra Date: Thu, 5 Feb 2026 14:09:42 +0530 Subject: [PATCH 4/4] refactor for readability --- lib/device/installation-proxy-client.ts | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/device/installation-proxy-client.ts b/lib/device/installation-proxy-client.ts index c94a81330b..66714405f9 100644 --- a/lib/device/installation-proxy-client.ts +++ b/lib/device/installation-proxy-client.ts @@ -81,10 +81,15 @@ export class InstallationProxyClient { * @returns Object keyed by bundle ID */ async listApplications(opts?: ListApplicationOptions): Promise { + let normalizedOpts = opts; + // Ensure CFBundleIdentifier is always included - const normalizedOpts = opts?.returnAttributes && !opts.returnAttributes.includes('CFBundleIdentifier') - ? { ...opts, returnAttributes: ['CFBundleIdentifier', ...opts.returnAttributes] } - : opts; + if (opts?.returnAttributes && !opts.returnAttributes.includes('CFBundleIdentifier')) { + normalizedOpts = { + ...opts, + returnAttributes: ['CFBundleIdentifier', ...opts.returnAttributes], + }; + } if (!this.isRemoteXPC) { return await this.iosDeviceService.listApplications(normalizedOpts);