diff --git a/docs/reference/execute-methods.md b/docs/reference/execute-methods.md index dc049e7bb..a2749f268 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 diff --git a/lib/commands/app-management.ts b/lib/commands/app-management.ts index 745b113e0..b53692851 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/device/installation-proxy-client.ts b/lib/device/installation-proxy-client.ts index 883dd7d5b..66714405f 100644 --- a/lib/device/installation-proxy-client.ts +++ b/lib/device/installation-proxy-client.ts @@ -81,15 +81,25 @@ export class InstallationProxyClient { * @returns Object keyed by bundle ID */ async listApplications(opts?: ListApplicationOptions): Promise { + let normalizedOpts = opts; + + // Ensure CFBundleIdentifier is always included + if (opts?.returnAttributes && !opts.returnAttributes.includes('CFBundleIdentifier')) { + normalizedOpts = { + ...opts, + returnAttributes: ['CFBundleIdentifier', ...opts.returnAttributes], + }; + } + 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 diff --git a/lib/execute-method-map.ts b/lib/execute-method-map.ts index c960d790d..4c606562e 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': {