iOS simulator apps
Configure an iOS simulator app, enter text, tap controls and check the result.
Use an iOS simulator target when a flow needs your native app. This page shows how to prepare the simulator, launch the app and check its accessibility elements through XCTest and WebDriverAgent.
Requirements
You need Node.js 24.12 or later on an Apple silicon Mac, Xcode 26.5 build 17F42, iOS simulator runtime 26.5 build 23F77 and a simulator .app build of your app. Retest refuses a toolchain outside this pinned set.
Prepare the executor Link to Prepare the executor
Build the pinned WebDriverAgent executor before running the suite. You need clean source checkouts of both WebDriverAgent and appium-mac2-driver because Retest checks licence files from both repositories.
npx retest install webdriveragentThis command builds from existing checkouts; it does not clone them. If they are missing, it prints the required paths, pinned commits and commands to prepare them. Follow those instructions, then run the install command again.
Configure the app Link to Configure the app
Set the app bundle, simulator device type and runtime in retest.config.ts. This example uses TaskPhone from Retest's cross-platform fixture, which accepts arguments to reset its local state and choose its task service.
import { defineConfig, env } from '@rehearsal-labs/retest'const config = defineConfig({ apps: { phone: { platform: 'ios-simulator', appPath: './TaskPhone.app', device: 'iPhone 17', runtime: '26.5', arguments: ['-reset', '-serviceURL', 'http://127.0.0.1:4310'], }, }, secrets: { password: env('TASK_APP_PASSWORD') }, secretOrigins: { password: ['dev.retest.fixtures.taskphone'] },})export default configdeclare module '@rehearsal-labs/retest' { interface Register { config: typeof config }}appPath is relative to the config file. Replace the fixture's arguments with settings your app understands, and use its own bundle identifier in secretOrigins. Native secrets are allowed by bundle identifier, rather than by web origin.
npx retest doctorFor a native target, doctor checks the cached executor and the app bundle's presence without starting them. A run checks Xcode, the runtime and the app itself, so a successful doctor check does not prove the simulator will launch.
Write a native test Link to Write a native test
getByTestId finds a native element by its accessibility identifier. The following test signs in to TaskPhone, creates a task and checks the title the app shows after saving it.
import { expect, secret, test } from '@rehearsal-labs/retest'test('creates a task on the phone', { apps: ['phone'] }, async ({ phone }) => { await phone.getByTestId('account-field').fill('ada') await phone.getByTestId('password-field').fill(secret('password')) await phone.getByTestId('sign-in-button').tap() await expect(phone.getByTestId('signed-in-account')).toHaveText('ada') await phone.getByTestId('new-task-title-field').fill('Release checklist') await phone.getByTestId('create-task-button').tap() await expect(phone.getByTestId('created-task-title')).toHaveText('Release checklist') await expect(phone.getByTestId('created-task-state')).toHaveText('Open')})Registering the config gives the test a typed phone handle. Use tap() for controls and fill() for text fields. Checks read the native accessibility tree again until they pass or reach their deadline. Use toHaveValue when checking an editable field.
npx retest run tests/phone.retest.tsState and supported operations Link to State and supported operations
Retest creates a fresh simulator for each test and deletes it during shutdown. Your backend data remains external, so prepare the account and task service separately. The fixture's -reset argument asks the app to reset; it does not reset the server.
You can also find elements by supported roles, labels and text, then scope a finder inside another element. CSS, placeholder lookup, web navigation and saved browser state are unavailable. A test may use one app per simulator device type and runtime.
Gesture coverage
The API includes swipe, software keyboard helpers and labelled alert buttons. These helpers have been checked with a stand-in executor, but have not been exercised on a real simulator. Android and real iOS devices are not supported.
When an action has an unknown outcome, Retest records that result and does not resend the input. The run folder keeps native session details and available evidence, so you can investigate with Debugging a failure.