diff --git a/src/tests/tools/session/session.test.ts b/src/tests/tools/session/session.test.ts index 3466fc60..df5631f1 100644 --- a/src/tests/tools/session/session.test.ts +++ b/src/tests/tools/session/session.test.ts @@ -10,22 +10,26 @@ const mockAttachToSession = jest.fn< })); let mockSelectedDevicePlatform: 'android' | 'ios' | null = 'ios'; +let mockSelectedDevice: string | null = 'device-udid'; jest.unstable_mockModule('../../../tools/session/select-device', () => ({ - getSelectedLocalDevice: () => ({ - get udid() { - return 'device-udid'; - }, - get platform() { - return mockSelectedDevicePlatform; - }, - get type() { - return mockSelectedDevicePlatform === 'ios' ? 'simulator' : null; - }, - get info() { - return { name: 'iPhone 12', platform: '16.0' }; - }, - }), + getSelectedLocalDevice: () => + mockSelectedDevice + ? { + get udid() { + return mockSelectedDevice; + }, + get platform() { + return mockSelectedDevicePlatform; + }, + get type() { + return mockSelectedDevicePlatform === 'ios' ? 'simulator' : null; + }, + get info() { + return { name: 'iPhone 12', platform: '16.0' }; + }, + } + : null, clearSelectedDevice: () => {}, })); @@ -134,6 +138,7 @@ let mockFetch: jest.MockedFunction; beforeEach(() => { jest.clearAllMocks(); mockSelectedDevicePlatform = 'ios'; + mockSelectedDevice = 'device-udid'; mockGetSessionOwnership.mockReturnValue(null); mockAttachToSession.mockResolvedValue({ sessionId: 'attached-session-id', @@ -589,6 +594,30 @@ describe('buildAndroidCapabilities', () => { expect(caps['appium:settings[waitForSelectorTimeout]']).toBe(0); }); + test('does not override explicit appium:udid from capabilities', () => { + mockSelectedDevicePlatform = 'android'; + + const caps = buildAndroidCapabilities( + {}, + { 'appium:udid': 'explicit-udid' }, + false + ); + + expect(caps['appium:udid']).toBe('explicit-udid'); + }); + + test('does not override appium:udid from config capabilities', () => { + mockSelectedDevicePlatform = 'android'; + + const caps = buildAndroidCapabilities( + { 'appium:udid': 'config-udid' }, + undefined, + false + ); + + expect(caps['appium:udid']).toBe('config-udid'); + }); + test('ignores selected iOS device for local server', () => { mockSelectedDevicePlatform = 'ios'; @@ -623,6 +652,18 @@ describe('buildIOSCapabilities', () => { expect(caps['appium:bundleId']).toBe('com.example.app'); }); + test('does not override explicit appium:udid from capabilities', async () => { + mockSelectedDevicePlatform = 'ios'; + + const caps = await buildIOSCapabilities( + {}, + { 'appium:udid': 'explicit-udid' }, + false + ); + + expect(caps['appium:udid']).toBe('explicit-udid'); + }); + test('ignores selected Android device for local server', async () => { mockSelectedDevicePlatform = 'android'; diff --git a/src/tools/session/create-session.ts b/src/tools/session/create-session.ts index 2e2c057c..eb0ad88c 100644 --- a/src/tools/session/create-session.ts +++ b/src/tools/session/create-session.ts @@ -67,18 +67,21 @@ export function buildAndroidCapabilities( customCaps: Record | undefined, isRemoteServer: boolean ): Capabilities { + const givenCaps = { ...configCaps, ...customCaps }; + const selectedLocalDevice = getSelectedLocalDevice(); + const selectedDeviceUdid = + !isRemoteServer && + !givenCaps['appium:udid'] && + selectedLocalDevice?.platform === 'android' + ? selectedLocalDevice.udid + : undefined; + const defaultCaps: Capabilities = { platformName: 'Android', 'appium:automationName': 'UiAutomator2', 'appium:deviceName': 'Android Device', }; - const selectedLocalDevice = getSelectedLocalDevice(); - const selectedDeviceUdid = - !isRemoteServer && selectedLocalDevice?.platform === 'android' - ? selectedLocalDevice?.udid - : undefined; - const additionalCaps = { 'appium:settings[actionAcknowledgmentTimeout]': 0, 'appium:settings[waitForIdleTimeout]': 0, @@ -146,8 +149,13 @@ export async function buildIOSCapabilities( const deviceType = selectedIOSDevice?.type || null; await validateIOSDeviceSelection(deviceType); - // Get selected device info BEFORE constructing defaultCaps so we can use the actual device name - const selectedDeviceUdid = selectedIOSDevice?.udid; + const givenCaps = { ...configCaps, ...customCaps }; + const selectedDeviceUdid = + !isRemoteServer && + !givenCaps['appium:udid'] && + selectedIOSDevice?.platform === 'ios' + ? selectedIOSDevice.udid + : undefined; const selectedDeviceInfo = selectedIOSDevice?.info; log.debug('Selected device info:', selectedDeviceInfo);