|
| 1 | +diff --git a/README.md b/README.md |
| 2 | +index 4046b69619f5770d26353894eeb02b15bd8baedc..497e8d97982c3b4391e4d8ecfa6b4bb382ba371c 100644 |
| 3 | +--- a/README.md |
| 4 | ++++ b/README.md |
| 5 | +@@ -68,13 +68,15 @@ Creates an iOS simulator device configuration. |
| 6 | + - `deviceName` - Name of the iOS simulator (e.g., 'iPhone 16 Pro Max') |
| 7 | + - `osVersion` - iOS version (e.g., '18.0') |
| 8 | + |
| 9 | +-### `applePhysicalDevice(deviceName)` |
| 10 | ++### `applePhysicalDevice(deviceNameOrId)` |
| 11 | + |
| 12 | + Creates a physical Apple device configuration. |
| 13 | + |
| 14 | + **Parameters:** |
| 15 | + |
| 16 | +-- `deviceName` - Name of the physical device (e.g., 'iPhone (Your Name)') |
| 17 | ++- `deviceNameOrId` - Name, CoreDevice identifier, or hardware UDID of the |
| 18 | ++ physical device (e.g., 'iPhone (Your Name)' or |
| 19 | ++ '6954F636-D116-52FA-9D00-8298BBB63705') |
| 20 | + |
| 21 | + ## Requirements |
| 22 | + |
| 23 | +diff --git a/dist/xcrun/devicectl.d.ts b/dist/xcrun/devicectl.d.ts |
| 24 | +index 14a80c74f1dc73972db8a75325bb3883760f667e..140217054d1744ce725da5a3986752ad2e7824bf 100644 |
| 25 | +--- a/dist/xcrun/devicectl.d.ts |
| 26 | ++++ b/dist/xcrun/devicectl.d.ts |
| 27 | +@@ -62,8 +62,9 @@ export declare const copyFileFrom: (identifier: string, options: { |
| 28 | + domainType: "systemCrashLogs"; |
| 29 | + }) => Promise<void>; |
| 30 | + export declare const stopApp: (identifier: string, bundleId: string) => Promise<void>; |
| 31 | +-export declare const getDevice: (name: string) => Promise<AppleDeviceInfo | null>; |
| 32 | +-export declare const getDeviceId: (name: string) => Promise<string | null>; |
| 33 | ++export declare const isMatchingDevice: (device: AppleDeviceInfo, identifier: string) => boolean; |
| 34 | ++export declare const getDevice: (identifier: string) => Promise<AppleDeviceInfo | null>; |
| 35 | ++export declare const getDeviceId: (identifier: string) => Promise<string | null>; |
| 36 | + export declare const isAppRunning: (identifier: string, bundleId: string) => Promise<boolean>; |
| 37 | + export {}; |
| 38 | + //# sourceMappingURL=devicectl.d.ts.map |
| 39 | +\ No newline at end of file |
| 40 | +diff --git a/dist/xcrun/devicectl.js b/dist/xcrun/devicectl.js |
| 41 | +index afe05044f103f10ecdb057ee0ec58f9425f96981..34d4cefc4d43a8433a235a3bee7eabfac70a3738 100644 |
| 42 | +--- a/dist/xcrun/devicectl.js |
| 43 | ++++ b/dist/xcrun/devicectl.js |
| 44 | +@@ -172,12 +172,20 @@ export const stopApp = async (identifier, bundleId) => { |
| 45 | + process.processIdentifier.toString(), |
| 46 | + ]); |
| 47 | + }; |
| 48 | +-export const getDevice = async (name) => { |
| 49 | ++export const isMatchingDevice = (device, identifier) => { |
| 50 | ++ return (device.deviceProperties.name === identifier || |
| 51 | ++ device.identifier === identifier || |
| 52 | ++ device.hardwareProperties.udid === identifier); |
| 53 | ++}; |
| 54 | ++export const getDevice = async (identifier) => { |
| 55 | + const devices = await listDevices(); |
| 56 | +- return (devices.find((device) => device.deviceProperties.name === name) ?? null); |
| 57 | ++ const matchingDevice = devices.find((device) => { |
| 58 | ++ return isMatchingDevice(device, identifier); |
| 59 | ++ }); |
| 60 | ++ return matchingDevice ?? null; |
| 61 | + }; |
| 62 | +-export const getDeviceId = async (name) => { |
| 63 | +- const device = await getDevice(name); |
| 64 | ++export const getDeviceId = async (identifier) => { |
| 65 | ++ const device = await getDevice(identifier); |
| 66 | + return device?.identifier ?? null; |
| 67 | + }; |
| 68 | + export const isAppRunning = async (identifier, bundleId) => { |
1 | 69 | diff --git a/dist/xctest-agent.js b/dist/xctest-agent.js |
2 | 70 | index 837e6a141ddedeadff87b2c5b7e891d248323019..e28ac2bb10281b560a846d588a98525a93e31d8f 100644 |
3 | 71 | --- a/dist/xctest-agent.js |
@@ -82,6 +150,93 @@ index 837e6a141ddedeadff87b2c5b7e891d248323019..e28ac2bb10281b560a846d588a98525a |
82 | 150 | '-destination', |
83 | 151 | getXCTestAgentRunDestination(target), |
84 | 152 | '-parallel-testing-enabled', |
| 153 | +diff --git a/src/__tests__/launch-options.test.ts b/src/__tests__/launch-options.test.ts |
| 154 | +index 1e4e058385e227ea9c7ef9f19de7d0e737e2c4bc..b5bc63c862fe360f4599485df4b4dcf5b1611564 100644 |
| 155 | +--- a/src/__tests__/launch-options.test.ts |
| 156 | ++++ b/src/__tests__/launch-options.test.ts |
| 157 | +@@ -2,6 +2,7 @@ import { describe, expect, it } from 'vitest'; |
| 158 | + import { |
| 159 | + getDeviceConnectionHost, |
| 160 | + getDeviceCtlLaunchArgs, |
| 161 | ++ isMatchingDevice, |
| 162 | + } from '../xcrun/devicectl.js'; |
| 163 | + import { getSimctlChildEnvironment } from '../xcrun/simctl.js'; |
| 164 | + |
| 165 | +@@ -62,4 +63,31 @@ describe('Apple app launch options', () => { |
| 166 | + }) |
| 167 | + ).toBe('fd12:3456:789a::1'); |
| 168 | + }); |
| 169 | ++ |
| 170 | ++ it('matches physical devices by name, CoreDevice identifier, or hardware UDID', () => { |
| 171 | ++ const device = { |
| 172 | ++ identifier: '6954F636-D116-52FA-9D00-8298BBB63705', |
| 173 | ++ deviceProperties: { |
| 174 | ++ name: 'G22RJQXC3V', |
| 175 | ++ osVersionNumber: '26.0', |
| 176 | ++ }, |
| 177 | ++ hardwareProperties: { |
| 178 | ++ marketingName: 'iPhone', |
| 179 | ++ productType: 'iPhone17,1', |
| 180 | ++ udid: '00008140-001600222422201C', |
| 181 | ++ }, |
| 182 | ++ }; |
| 183 | ++ const matchesName = isMatchingDevice(device, 'G22RJQXC3V'); |
| 184 | ++ const matchesIdentifier = isMatchingDevice( |
| 185 | ++ device, |
| 186 | ++ '6954F636-D116-52FA-9D00-8298BBB63705' |
| 187 | ++ ); |
| 188 | ++ const matchesUdid = isMatchingDevice(device, '00008140-001600222422201C'); |
| 189 | ++ const matchesUnknownName = isMatchingDevice(device, 'Unknown iPhone'); |
| 190 | ++ |
| 191 | ++ expect(matchesName).toBe(true); |
| 192 | ++ expect(matchesIdentifier).toBe(true); |
| 193 | ++ expect(matchesUdid).toBe(true); |
| 194 | ++ expect(matchesUnknownName).toBe(false); |
| 195 | ++ }); |
| 196 | + }); |
| 197 | +diff --git a/src/xcrun/devicectl.ts b/src/xcrun/devicectl.ts |
| 198 | +index 6269a237e15f83ea9bb574255cec99fd6ce09d0c..521951e5aa376f5ffeb6ae7f992f0e76df540313 100644 |
| 199 | +--- a/src/xcrun/devicectl.ts |
| 200 | ++++ b/src/xcrun/devicectl.ts |
| 201 | +@@ -331,17 +331,32 @@ export const stopApp = async ( |
| 202 | + ]); |
| 203 | + }; |
| 204 | + |
| 205 | ++export const isMatchingDevice = ( |
| 206 | ++ device: AppleDeviceInfo, |
| 207 | ++ identifier: string |
| 208 | ++): boolean => { |
| 209 | ++ return ( |
| 210 | ++ device.deviceProperties.name === identifier || |
| 211 | ++ device.identifier === identifier || |
| 212 | ++ device.hardwareProperties.udid === identifier |
| 213 | ++ ); |
| 214 | ++}; |
| 215 | ++ |
| 216 | + export const getDevice = async ( |
| 217 | +- name: string |
| 218 | ++ identifier: string |
| 219 | + ): Promise<AppleDeviceInfo | null> => { |
| 220 | + const devices = await listDevices(); |
| 221 | +- return ( |
| 222 | +- devices.find((device) => device.deviceProperties.name === name) ?? null |
| 223 | +- ); |
| 224 | ++ const matchingDevice = devices.find((device) => { |
| 225 | ++ return isMatchingDevice(device, identifier); |
| 226 | ++ }); |
| 227 | ++ |
| 228 | ++ return matchingDevice ?? null; |
| 229 | + }; |
| 230 | + |
| 231 | +-export const getDeviceId = async (name: string): Promise<string | null> => { |
| 232 | +- const device = await getDevice(name); |
| 233 | ++export const getDeviceId = async ( |
| 234 | ++ identifier: string |
| 235 | ++): Promise<string | null> => { |
| 236 | ++ const device = await getDevice(identifier); |
| 237 | + return device?.identifier ?? null; |
| 238 | + }; |
| 239 | + |
85 | 240 | diff --git a/src/xctest-agent.ts b/src/xctest-agent.ts |
86 | 241 | index cdbb3187bcfc07ac812dd7d5990e9d23220dfdf6..9716c1beb6d210b9ca39b2139ce5b1d53e0f6f3a 100644 |
87 | 242 | --- a/src/xctest-agent.ts |
|
0 commit comments