From 1804dad0ce7df4df98efca1075fa11bf3454705f Mon Sep 17 00:00:00 2001 From: Peter Abbondanzo Date: Thu, 10 Sep 2026 12:48:45 -0700 Subject: [PATCH] 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 --- .github/actions/maestro-ios/action.yml | 12 +++++- .../__tests__/maestro-ios-test.js | 29 ++++++++++++++ .github/workflow-scripts/maestro-ios.js | 40 +++++++++++++++---- .github/workflows/e2e-ios-rntester.yml | 2 + .github/workflows/maestro-cloud-rntester.yml | 10 +++++ .github/workflows/test-all.yml | 2 + 6 files changed, 87 insertions(+), 8 deletions(-) diff --git a/.github/actions/maestro-ios/action.yml b/.github/actions/maestro-ios/action.yml index 6ebc7327fb0b..def69fd78092 100644 --- a/.github/actions/maestro-ios/action.yml +++ b/.github/actions/maestro-ios/action.yml @@ -18,6 +18,14 @@ inputs: required: false default: '.' description: The directory from which metro should be started + device-model: + required: false + default: '' + description: Maestro device model name, such as iPhone-17-Pro + device-os: + required: false + default: '' + description: Maestro device OS name, such as iOS-26-2 runs: using: composite @@ -63,7 +71,9 @@ runs: "${{ inputs.maestro-flow }}" \ "Hermes" \ "${{ inputs.flavor }}" \ - "${{ inputs.working-directory }}" + "${{ inputs.working-directory }}" \ + "${{ inputs.device-model }}" \ + "${{ inputs.device-os }}" - name: Store video record if: always() uses: actions/upload-artifact@v6 diff --git a/.github/workflow-scripts/__tests__/maestro-ios-test.js b/.github/workflow-scripts/__tests__/maestro-ios-test.js index 8b604ae1da66..8b23a47a3418 100644 --- a/.github/workflow-scripts/__tests__/maestro-ios-test.js +++ b/.github/workflow-scripts/__tests__/maestro-ios-test.js @@ -78,4 +78,33 @@ describe('Maestro iOS runner', () => { udid: 'new-pro', }); }); + + it('selects the configured device model and OS', () => { + childProcess.execSync.mockReturnValue( + JSON.stringify({ + devices: { + 'com.apple.CoreSimulator.SimRuntime.iOS-26-0': [ + {name: 'iPhone 17 Pro', udid: 'wrong-runtime'}, + ], + 'com.apple.CoreSimulator.SimRuntime.iOS-26-2': [ + {name: 'iPhone 17 Pro Max', udid: 'wrong-model'}, + {name: 'iPhone 17 Pro', udid: 'expected'}, + ], + }, + }), + ); + + expect(findAvailableSimulator('iPhone-17-Pro', 'iOS-26-2')).toEqual({ + name: 'iPhone 17 Pro', + udid: 'expected', + }); + }); + + it('fails when the configured simulator is unavailable', () => { + childProcess.execSync.mockReturnValue(JSON.stringify({devices: {}})); + + expect(() => findAvailableSimulator('iPhone-17-Pro', 'iOS-26-2')).toThrow( + 'Unable to find iPhone 17 Pro simulator on iOS-26-2', + ); + }); }); diff --git a/.github/workflow-scripts/maestro-ios.js b/.github/workflow-scripts/maestro-ios.js index 6b7a536f72d2..02ed4a08d5d0 100644 --- a/.github/workflow-scripts/maestro-ios.js +++ b/.github/workflow-scripts/maestro-ios.js @@ -12,7 +12,7 @@ const fs = require('fs'); const usage = ` === Usage === -node maestro-android.js +node maestro-ios.js [device_model] [device_os] @param {string} appPath - Path to the app APK @param {string} appId - App ID that needs to be launched @@ -20,18 +20,40 @@ node maestro-android.js device.name === simulatorName, + ); + + if (simulator == null) { + throw new Error( + `Unable to find ${simulatorName} simulator on ${deviceOS}`, + ); + } + + return simulator; + } + + const devices = Object.values(devicesByRuntime).flat().reverse(); const simulator = devices.find(device => /^iPhone .* Pro$/.test(device.name)); if (simulator == null) { @@ -153,7 +175,7 @@ function executeFlows(appId, udid, maestroFlow, jsengine) { } async function main(args = process.argv.slice(2)) { - if (args.length !== 6) { + if (args.length < 6 || args.length > 8) { throw new Error(`Invalid number of arguments.\n${usage}`); } @@ -163,6 +185,8 @@ async function main(args = process.argv.slice(2)) { const jsengine = args[3]; const isDebug = args[4] === 'Debug'; const workingDirectory = args[5]; + const deviceModel = args[6] || null; + const deviceOS = args[7] || null; console.info('\n=============================='); console.info('Running tests for iOS with the following parameters:'); @@ -172,9 +196,11 @@ async function main(args = process.argv.slice(2)) { console.info(`JS_ENGINE: ${jsengine}`); console.info(`IS_DEBUG: ${isDebug}`); console.info(`WORKING_DIRECTORY: ${workingDirectory}`); + console.info(`DEVICE_MODEL: ${deviceModel ?? ''}`); + console.info(`DEVICE_OS: ${deviceOS ?? ''}`); console.info('==============================\n'); - const simulator = findAvailableSimulator(); + const simulator = findAvailableSimulator(deviceModel, deviceOS); launchSimulator(simulator); installAppOnSimulator(appPath); bringSimulatorInForeground(); diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index f7ec8894d3d9..e0f69be743ae 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -44,6 +44,8 @@ jobs: app-id: com.meta.RNTester.localDevelopment maestro-flow: ./packages/rn-tester/.maestro/ flavor: ${{ matrix.flavor }} + device-model: iPhone-17-Pro + device-os: iOS-26-2 - name: Report status id: report-status if: ${{ always() && steps.run-tests.outcome == 'failure' }} diff --git a/.github/workflows/maestro-cloud-rntester.yml b/.github/workflows/maestro-cloud-rntester.yml index a620ca368810..7f245bbcbebf 100644 --- a/.github/workflows/maestro-cloud-rntester.yml +++ b/.github/workflows/maestro-cloud-rntester.yml @@ -26,6 +26,14 @@ on: description: 'RNTester application identifier' required: true type: string + device-model: + description: 'Device model passed to Maestro Cloud' + required: false + type: string + device-os: + description: 'Device OS passed to Maestro Cloud' + required: false + type: string exclude-tags: description: 'Maestro flow tags to exclude' required: true @@ -70,6 +78,8 @@ jobs: workspace: packages/rn-tester/.maestro branch: ${{ github.head_ref || github.ref_name }} name: RNTester ${{ inputs.platform }} - ${{ github.event.pull_request.title || github.sha }} + device-model: ${{ inputs.device-model }} + device-os: ${{ inputs.device-os }} exclude-tags: ${{ inputs.exclude-tags }} env: | APP_ID=${{ inputs.app-id }} diff --git a/.github/workflows/test-all.yml b/.github/workflows/test-all.yml index f1ee1caab331..237f4ad66f70 100644 --- a/.github/workflows/test-all.yml +++ b/.github/workflows/test-all.yml @@ -184,6 +184,8 @@ jobs: download-path: /tmp/RNTesterBuild/RNTester.app app-file: /tmp/RNTesterBuild/RNTester.app app-id: com.meta.RNTester.localDevelopment + device-model: iPhone-17-Pro + device-os: iOS-26-2 exclude-tags: android-only secrets: inherit