@@ -12,26 +12,48 @@ const fs = require('fs');
1212
1313const usage = `
1414=== Usage ===
15- node maestro-android .js <path to app> <app_id> <maestro_flow> <flavor> <working_directory>
15+ node maestro-ios .js <path to app> <app_id> <maestro_flow> <jsengine> < flavor> <working_directory> [device_model] [device_os]
1616
1717@param {string} appPath - Path to the app APK
1818@param {string} appId - App ID that needs to be launched
1919@param {string} maestroFlow - Path to the maestro flow to be executed
2020@param {string} jsengine - The JSEngine to use for the test
2121@param {string} flavor - Flavor of the app to be launched. Can be 'Release' or 'Debug'
2222@param {string} workingDirectory - Working directory from where to run Metro
23+ @param {string} deviceModel - Optional Maestro device model, such as iPhone-17-Pro
24+ @param {string} deviceOS - Optional Maestro device OS, such as iOS-26-2
2325==============
2426` ;
2527
2628const MAX_ATTEMPTS = 5 ;
2729
28- function findAvailableSimulator ( ) {
30+ function findAvailableSimulator ( deviceModel , deviceOS ) {
2931 const output = childProcess . execSync (
3032 'xcrun simctl list devices available -j' ,
3133 ) ;
32- const devices = Object . values ( JSON . parse ( String ( output ) ) . devices )
33- . flat ( )
34- . reverse ( ) ;
34+ const devicesByRuntime = JSON . parse ( String ( output ) ) . devices ;
35+
36+ if ( ( deviceModel == null ) !== ( deviceOS == null ) ) {
37+ throw new Error ( 'Device model and OS must be configured together' ) ;
38+ }
39+
40+ if ( deviceModel != null && deviceOS != null ) {
41+ const runtime = `com.apple.CoreSimulator.SimRuntime.${ deviceOS } ` ;
42+ const simulatorName = deviceModel . replaceAll ( '-' , ' ' ) ;
43+ const simulator = devicesByRuntime [ runtime ] ?. find (
44+ device => device . name === simulatorName ,
45+ ) ;
46+
47+ if ( simulator == null ) {
48+ throw new Error (
49+ `Unable to find ${ simulatorName } simulator on ${ deviceOS } ` ,
50+ ) ;
51+ }
52+
53+ return simulator ;
54+ }
55+
56+ const devices = Object . values ( devicesByRuntime ) . flat ( ) . reverse ( ) ;
3557 const simulator = devices . find ( device => / ^ i P h o n e .* P r o $ / . test ( device . name ) ) ;
3658
3759 if ( simulator == null ) {
@@ -153,7 +175,7 @@ function executeFlows(appId, udid, maestroFlow, jsengine) {
153175}
154176
155177async function main ( args = process . argv . slice ( 2 ) ) {
156- if ( args . length !== 6 ) {
178+ if ( args . length < 6 || args . length > 8 ) {
157179 throw new Error ( `Invalid number of arguments.\n${ usage } ` ) ;
158180 }
159181
@@ -163,6 +185,8 @@ async function main(args = process.argv.slice(2)) {
163185 const jsengine = args [ 3 ] ;
164186 const isDebug = args [ 4 ] === 'Debug' ;
165187 const workingDirectory = args [ 5 ] ;
188+ const deviceModel = args [ 6 ] || null ;
189+ const deviceOS = args [ 7 ] || null ;
166190
167191 console . info ( '\n==============================' ) ;
168192 console . info ( 'Running tests for iOS with the following parameters:' ) ;
@@ -172,9 +196,11 @@ async function main(args = process.argv.slice(2)) {
172196 console . info ( `JS_ENGINE: ${ jsengine } ` ) ;
173197 console . info ( `IS_DEBUG: ${ isDebug } ` ) ;
174198 console . info ( `WORKING_DIRECTORY: ${ workingDirectory } ` ) ;
199+ console . info ( `DEVICE_MODEL: ${ deviceModel ?? '<automatic>' } ` ) ;
200+ console . info ( `DEVICE_OS: ${ deviceOS ?? '<automatic>' } ` ) ;
175201 console . info ( '==============================\n' ) ;
176202
177- const simulator = findAvailableSimulator ( ) ;
203+ const simulator = findAvailableSimulator ( deviceModel , deviceOS ) ;
178204 launchSimulator ( simulator ) ;
179205 installAppOnSimulator ( appPath ) ;
180206 bringSimulatorInForeground ( ) ;
0 commit comments