From f83a672a5d5418effc26193ed843a827aa8ee9d4 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Tue, 18 Aug 2026 12:08:44 +0100 Subject: [PATCH 1/3] Fix iOS E2E runners for idb-companion --- .github/workflows/e2e-ios-rntester.yml | 4 +++- .github/workflows/e2e-ios-templateapp.yml | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index cd53e954788c..1881beeca058 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -16,7 +16,7 @@ on: jobs: test: - runs-on: macos-15-large + runs-on: macos-26-large outputs: status: ${{ steps.report-status.outputs.status }} strategy: @@ -37,6 +37,8 @@ jobs: run: ls -lR /tmp/RNTesterBuild - name: Setup xcode uses: ./.github/actions/setup-xcode + with: + xcode-version: '26.0.1' - name: Run E2E Tests id: run-tests continue-on-error: true diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index 44b64858bb48..6f5d62036ad1 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -16,7 +16,7 @@ on: jobs: test: - runs-on: macos-15-large + runs-on: macos-26-large outputs: status: ${{ steps.report-status.outputs.status }} strategy: @@ -28,6 +28,8 @@ jobs: uses: actions/checkout@v6 - name: Setup xcode uses: ./.github/actions/setup-xcode + with: + xcode-version: '26.0.1' - name: Setup node.js uses: ./.github/actions/setup-node - name: Run yarn From 296e145d188804ae079814f2e9b530ff14ee07b4 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Tue, 18 Aug 2026 12:50:09 +0100 Subject: [PATCH 2/3] Use default Xcode on macOS 26 E2E runners --- .github/workflows/e2e-ios-rntester.yml | 4 ---- .github/workflows/e2e-ios-templateapp.yml | 4 ---- 2 files changed, 8 deletions(-) diff --git a/.github/workflows/e2e-ios-rntester.yml b/.github/workflows/e2e-ios-rntester.yml index 1881beeca058..f7ec8894d3d9 100644 --- a/.github/workflows/e2e-ios-rntester.yml +++ b/.github/workflows/e2e-ios-rntester.yml @@ -35,10 +35,6 @@ jobs: path: /tmp/RNTesterBuild/RNTester.app - name: Check downloaded folder content run: ls -lR /tmp/RNTesterBuild - - name: Setup xcode - uses: ./.github/actions/setup-xcode - with: - xcode-version: '26.0.1' - name: Run E2E Tests id: run-tests continue-on-error: true diff --git a/.github/workflows/e2e-ios-templateapp.yml b/.github/workflows/e2e-ios-templateapp.yml index 6f5d62036ad1..20e5a9c5dff3 100644 --- a/.github/workflows/e2e-ios-templateapp.yml +++ b/.github/workflows/e2e-ios-templateapp.yml @@ -26,10 +26,6 @@ jobs: steps: - name: Checkout uses: actions/checkout@v6 - - name: Setup xcode - uses: ./.github/actions/setup-xcode - with: - xcode-version: '26.0.1' - name: Setup node.js uses: ./.github/actions/setup-node - name: Run yarn From 547301e75dd6ee74e40e2989056749dc9d996443 Mon Sep 17 00:00:00 2001 From: Riccardo Cipolleschi Date: Tue, 18 Aug 2026 13:38:39 +0100 Subject: [PATCH 3/3] Select an available simulator for iOS E2E tests --- .../__tests__/maestro-ios-test.js | 21 +++++++++- .github/workflow-scripts/maestro-ios.js | 40 +++++++++++-------- 2 files changed, 44 insertions(+), 17 deletions(-) diff --git a/.github/workflow-scripts/__tests__/maestro-ios-test.js b/.github/workflow-scripts/__tests__/maestro-ios-test.js index 07e3c547c2c2..8b604ae1da66 100644 --- a/.github/workflow-scripts/__tests__/maestro-ios-test.js +++ b/.github/workflow-scripts/__tests__/maestro-ios-test.js @@ -20,7 +20,7 @@ jest.mock('fs', () => ({ const childProcess = require('child_process'); const fs = require('fs'); -const {executeFlows} = require('../maestro-ios'); +const {executeFlows, findAvailableSimulator} = require('../maestro-ios'); describe('Maestro iOS runner', () => { beforeEach(() => { @@ -59,4 +59,23 @@ describe('Maestro iOS runner', () => { expect(call[0]).toContain('test "flow.yml"'); } }); + + it('selects an iPhone Pro simulator from the latest runtime', () => { + childProcess.execSync.mockReturnValue( + JSON.stringify({ + devices: { + 'iOS 18.5': [{name: 'iPhone 16 Pro', udid: 'old-pro'}], + 'iOS 26.5': [ + {name: 'iPhone 17 Pro Max', udid: 'new-pro-max'}, + {name: 'iPhone 17 Pro', udid: 'new-pro'}, + ], + }, + }), + ); + + expect(findAvailableSimulator()).toEqual({ + name: 'iPhone 17 Pro', + udid: 'new-pro', + }); + }); }); diff --git a/.github/workflow-scripts/maestro-ios.js b/.github/workflow-scripts/maestro-ios.js index fa0153ad1e61..6b7a536f72d2 100644 --- a/.github/workflow-scripts/maestro-ios.js +++ b/.github/workflow-scripts/maestro-ios.js @@ -25,10 +25,26 @@ node maestro-android.js /^iPhone .* Pro$/.test(device.name)); + + if (simulator == null) { + throw new Error('Unable to find an available iPhone Pro simulator'); + } + + return simulator; +} + +function launchSimulator(simulator) { + console.log(`Launching simulator ${simulator.name} (${simulator.udid})`); try { - childProcess.execSync(`xcrun simctl boot "${simulatorName}"`); + childProcess.execSync(`xcrun simctl boot "${simulator.udid}"`); } catch (error) { if ( !error.message.includes('Unable to boot device in current state: Booted') @@ -43,14 +59,6 @@ function installAppOnSimulator(appPath) { childProcess.execSync(`xcrun simctl install booted "${appPath}"`); } -function extractSimulatorUDID() { - console.log('Retrieving device UDID'); - const command = `xcrun simctl list devices booted -j | jq -r '[.devices[]] | add | first | .udid'`; - const udid = String(childProcess.execSync(command)).trim(); - console.log(`UDID is ${udid}`); - return udid; -} - function bringSimulatorInForeground() { console.log('Bringing simulator in foreground'); childProcess.execSync('open -a simulator'); @@ -166,13 +174,12 @@ async function main(args = process.argv.slice(2)) { console.info(`WORKING_DIRECTORY: ${workingDirectory}`); console.info('==============================\n'); - const simulatorName = 'iPhone 16 Pro'; - launchSimulator(simulatorName); + const simulator = findAvailableSimulator(); + launchSimulator(simulator); installAppOnSimulator(appPath); - const udid = extractSimulatorUDID(); bringSimulatorInForeground(); - await launchAppOnSimulator(appId, udid, isDebug); - executeFlows(appId, udid, maestroFlow, jsengine); + await launchAppOnSimulator(appId, simulator.udid, isDebug); + executeFlows(appId, simulator.udid, maestroFlow, jsengine); console.log('Test finished'); } @@ -182,4 +189,5 @@ if (require.main === module) { module.exports = { executeFlows, + findAvailableSimulator, };