Skip to content

Commit 1804dad

Browse files
Abbondanzofacebook-github-bot
authored andcommitted
Fix failing iOS text width mode Maestro test (#58457)
Summary: Pin the RNTester iOS Debug, Release, and Maestro Cloud lanes to the same iPhone 17 Pro / iOS 26.2 profile. This keeps the existing 960x489 screenshot baseline valid across all three lanes while preserving automatic simulator selection for other action callers. Document that shared screenshot baselines require an explicit matching device profile. Changelog: [Internal] Reviewed By: christophpurrer Differential Revision: D119440006
1 parent 5ef4087 commit 1804dad

6 files changed

Lines changed: 87 additions & 8 deletions

File tree

.github/actions/maestro-ios/action.yml

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,14 @@ inputs:
1818
required: false
1919
default: '.'
2020
description: The directory from which metro should be started
21+
device-model:
22+
required: false
23+
default: ''
24+
description: Maestro device model name, such as iPhone-17-Pro
25+
device-os:
26+
required: false
27+
default: ''
28+
description: Maestro device OS name, such as iOS-26-2
2129

2230
runs:
2331
using: composite
@@ -63,7 +71,9 @@ runs:
6371
"${{ inputs.maestro-flow }}" \
6472
"Hermes" \
6573
"${{ inputs.flavor }}" \
66-
"${{ inputs.working-directory }}"
74+
"${{ inputs.working-directory }}" \
75+
"${{ inputs.device-model }}" \
76+
"${{ inputs.device-os }}"
6777
- name: Store video record
6878
if: always()
6979
uses: actions/upload-artifact@v6

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

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -78,4 +78,33 @@ describe('Maestro iOS runner', () => {
7878
udid: 'new-pro',
7979
});
8080
});
81+
82+
it('selects the configured device model and OS', () => {
83+
childProcess.execSync.mockReturnValue(
84+
JSON.stringify({
85+
devices: {
86+
'com.apple.CoreSimulator.SimRuntime.iOS-26-0': [
87+
{name: 'iPhone 17 Pro', udid: 'wrong-runtime'},
88+
],
89+
'com.apple.CoreSimulator.SimRuntime.iOS-26-2': [
90+
{name: 'iPhone 17 Pro Max', udid: 'wrong-model'},
91+
{name: 'iPhone 17 Pro', udid: 'expected'},
92+
],
93+
},
94+
}),
95+
);
96+
97+
expect(findAvailableSimulator('iPhone-17-Pro', 'iOS-26-2')).toEqual({
98+
name: 'iPhone 17 Pro',
99+
udid: 'expected',
100+
});
101+
});
102+
103+
it('fails when the configured simulator is unavailable', () => {
104+
childProcess.execSync.mockReturnValue(JSON.stringify({devices: {}}));
105+
106+
expect(() => findAvailableSimulator('iPhone-17-Pro', 'iOS-26-2')).toThrow(
107+
'Unable to find iPhone 17 Pro simulator on iOS-26-2',
108+
);
109+
});
81110
});

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

Lines changed: 33 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -12,26 +12,48 @@ const fs = require('fs');
1212

1313
const 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

2628
const 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 => /^iPhone .* Pro$/.test(device.name));
3658

3759
if (simulator == null) {
@@ -153,7 +175,7 @@ function executeFlows(appId, udid, maestroFlow, jsengine) {
153175
}
154176

155177
async 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();

.github/workflows/e2e-ios-rntester.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,8 @@ jobs:
4444
app-id: com.meta.RNTester.localDevelopment
4545
maestro-flow: ./packages/rn-tester/.maestro/
4646
flavor: ${{ matrix.flavor }}
47+
device-model: iPhone-17-Pro
48+
device-os: iOS-26-2
4749
- name: Report status
4850
id: report-status
4951
if: ${{ always() && steps.run-tests.outcome == 'failure' }}

.github/workflows/maestro-cloud-rntester.yml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,14 @@ on:
2626
description: 'RNTester application identifier'
2727
required: true
2828
type: string
29+
device-model:
30+
description: 'Device model passed to Maestro Cloud'
31+
required: false
32+
type: string
33+
device-os:
34+
description: 'Device OS passed to Maestro Cloud'
35+
required: false
36+
type: string
2937
exclude-tags:
3038
description: 'Maestro flow tags to exclude'
3139
required: true
@@ -70,6 +78,8 @@ jobs:
7078
workspace: packages/rn-tester/.maestro
7179
branch: ${{ github.head_ref || github.ref_name }}
7280
name: RNTester ${{ inputs.platform }} - ${{ github.event.pull_request.title || github.sha }}
81+
device-model: ${{ inputs.device-model }}
82+
device-os: ${{ inputs.device-os }}
7383
exclude-tags: ${{ inputs.exclude-tags }}
7484
env: |
7585
APP_ID=${{ inputs.app-id }}

.github/workflows/test-all.yml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -184,6 +184,8 @@ jobs:
184184
download-path: /tmp/RNTesterBuild/RNTester.app
185185
app-file: /tmp/RNTesterBuild/RNTester.app
186186
app-id: com.meta.RNTester.localDevelopment
187+
device-model: iPhone-17-Pro
188+
device-os: iOS-26-2
187189
exclude-tags: android-only
188190
secrets: inherit
189191

0 commit comments

Comments
 (0)