Skip to content

Commit 547301e

Browse files
committed
Select an available simulator for iOS E2E tests
1 parent 296e145 commit 547301e

2 files changed

Lines changed: 44 additions & 17 deletions

File tree

.github/workflow-scripts/__tests__/maestro-ios-test.js

Lines changed: 20 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ jest.mock('fs', () => ({
2020
const childProcess = require('child_process');
2121
const fs = require('fs');
2222

23-
const {executeFlows} = require('../maestro-ios');
23+
const {executeFlows, findAvailableSimulator} = require('../maestro-ios');
2424

2525
describe('Maestro iOS runner', () => {
2626
beforeEach(() => {
@@ -59,4 +59,23 @@ describe('Maestro iOS runner', () => {
5959
expect(call[0]).toContain('test "flow.yml"');
6060
}
6161
});
62+
63+
it('selects an iPhone Pro simulator from the latest runtime', () => {
64+
childProcess.execSync.mockReturnValue(
65+
JSON.stringify({
66+
devices: {
67+
'iOS 18.5': [{name: 'iPhone 16 Pro', udid: 'old-pro'}],
68+
'iOS 26.5': [
69+
{name: 'iPhone 17 Pro Max', udid: 'new-pro-max'},
70+
{name: 'iPhone 17 Pro', udid: 'new-pro'},
71+
],
72+
},
73+
}),
74+
);
75+
76+
expect(findAvailableSimulator()).toEqual({
77+
name: 'iPhone 17 Pro',
78+
udid: 'new-pro',
79+
});
80+
});
6281
});

.github/workflow-scripts/maestro-ios.js

Lines changed: 24 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,26 @@ node maestro-android.js <path to app> <app_id> <maestro_flow> <flavor> <working_
2525

2626
const MAX_ATTEMPTS = 5;
2727

28-
function launchSimulator(simulatorName) {
29-
console.log(`Launching simulator ${simulatorName}`);
28+
function findAvailableSimulator() {
29+
const output = childProcess.execSync(
30+
'xcrun simctl list devices available -j',
31+
);
32+
const devices = Object.values(JSON.parse(String(output)).devices)
33+
.flat()
34+
.reverse();
35+
const simulator = devices.find(device => /^iPhone .* Pro$/.test(device.name));
36+
37+
if (simulator == null) {
38+
throw new Error('Unable to find an available iPhone Pro simulator');
39+
}
40+
41+
return simulator;
42+
}
43+
44+
function launchSimulator(simulator) {
45+
console.log(`Launching simulator ${simulator.name} (${simulator.udid})`);
3046
try {
31-
childProcess.execSync(`xcrun simctl boot "${simulatorName}"`);
47+
childProcess.execSync(`xcrun simctl boot "${simulator.udid}"`);
3248
} catch (error) {
3349
if (
3450
!error.message.includes('Unable to boot device in current state: Booted')
@@ -43,14 +59,6 @@ function installAppOnSimulator(appPath) {
4359
childProcess.execSync(`xcrun simctl install booted "${appPath}"`);
4460
}
4561

46-
function extractSimulatorUDID() {
47-
console.log('Retrieving device UDID');
48-
const command = `xcrun simctl list devices booted -j | jq -r '[.devices[]] | add | first | .udid'`;
49-
const udid = String(childProcess.execSync(command)).trim();
50-
console.log(`UDID is ${udid}`);
51-
return udid;
52-
}
53-
5462
function bringSimulatorInForeground() {
5563
console.log('Bringing simulator in foreground');
5664
childProcess.execSync('open -a simulator');
@@ -166,13 +174,12 @@ async function main(args = process.argv.slice(2)) {
166174
console.info(`WORKING_DIRECTORY: ${workingDirectory}`);
167175
console.info('==============================\n');
168176

169-
const simulatorName = 'iPhone 16 Pro';
170-
launchSimulator(simulatorName);
177+
const simulator = findAvailableSimulator();
178+
launchSimulator(simulator);
171179
installAppOnSimulator(appPath);
172-
const udid = extractSimulatorUDID();
173180
bringSimulatorInForeground();
174-
await launchAppOnSimulator(appId, udid, isDebug);
175-
executeFlows(appId, udid, maestroFlow, jsengine);
181+
await launchAppOnSimulator(appId, simulator.udid, isDebug);
182+
executeFlows(appId, simulator.udid, maestroFlow, jsengine);
176183
console.log('Test finished');
177184
}
178185

@@ -182,4 +189,5 @@ if (require.main === module) {
182189

183190
module.exports = {
184191
executeFlows,
192+
findAvailableSimulator,
185193
};

0 commit comments

Comments
 (0)