[ Documentation ]
Simulating the device

Simulating the device

Your app reads a lot from the device it runs on: whether the user granted the camera, where they are, what phone they hold, whether it is dark mode. Peach lets you set each of these from the terminal, so a test or an agent can put the device in a known state before it runs.

Every command on this page targets the current sim. Add --sim <id> to target another one (peach list shows them).

At a glance

you want torun
grant or deny a permissionpeach permissions set <app-id> <kind> <status>
set the device’s locationpeach location set <lat>,<lon>
feed the camera a video, or scan a barcodepeach camera play <file>, peach do scan <text>
change the phone modelpeach device set <model>
boot in landscapepeach open <port> --orientation landscape
switch light or dark modepeach shell appearance dark
change accessibility settingsthe built-in Settings app
clear app datapeach storage clear, peach reset
keep separate logins side by sidepeach open <port> --profile <id>
watch network requestspeach network

Permissions

Peach keeps a permission registry for each installed app. Your app’s permission APIs read it, and the built-in Settings app shows it.

terminal
peach permissions list # installed apps and their ids
peach permissions get dock-8081 # one app's current permissions
peach permissions set dock-8081 camera denied
peach permissions set dock-8081 photo-library limited
peach permissions reset dock-8081 camera # back to not determined
peach permissions reset dock-8081 # every permission for the app

Use peach permissions list to find your app’s id. A change applies immediately: the next time your app checks a permission, it sees the new status.

Kinds: app-tracking-transparency, bluetooth, calendars, camera, contacts, face-id, local-network, location-always, location-when-in-use, media-library, microphone, motion, notifications, photo-library, photo-library-add-only, reminders, siri, speech-recognition.

Statuses: not-determined, restricted, denied, authorized, limited, provisional, ephemeral, unavailable.

Two options refine an authorized grant:

terminal
peach permissions set dock-8081 camera authorized --once # expires when the app closes
peach permissions set dock-8081 location-when-in-use authorized --accuracy reduced

In a Maestro flow, launchApp sets permissions before it launches the app, as Maestro does on iOS: everything is allowed unless the step names its own.

- launchApp:
permissions:
camera: deny
location: inuse

allow, deny and unset work for every Maestro permission name. Location also takes always, inuse and never.

Face ID and notifications

Face ID and notifications are permissions in this registry, so you can test how your app behaves when each is granted, denied or not yet asked. Peach has no command yet to simulate a matching or failed face, or to deliver a push notification.

Location

The device has one simulated location, like simctl location on the iOS Simulator. It never reads your computer’s real position.

terminal
peach location set 37.785834,-122.406417
peach location set 40.748817,-73.985428 --accuracy 10
peach location get
peach location clear # back to iOS's own default location

set also takes --altitude <m>, --heading <deg> and --speed <m/s>. Your app sees the new position at once, both from a one-time position request and from every active position watch.

Location access is a separate permission: grant location-when-in-use or location-always with peach permissions when your app asks for it. In a Detox suite, device.setLocation(latitude, longitude) sets the same location. Maestro’s setLocation and travel steps are not supported yet.

Camera

Replace the camera feed with a local video so a capture or scanning screen sees the same input every run:

terminal
peach camera play ./fixtures/qr.mp4 --loop
peach camera play ./fixtures/document.webm --rate 2
peach camera status
peach camera stop # back to the live camera

For barcode scanning, inject a result straight into the active scan session:

terminal
peach do scan "https://example.com"

The format defaults to qr_code; pass another web barcode format name with --format.

Device model

terminal
peach device # the current model
peach device list # every model id
peach device set pixel-8 # switch the running sim
peach open 8081 --device iphone-16

Switching reshapes the running sim, its screen size, density and hardware frame, without restarting your app’s bundle. peach ios and peach android start a sim on that platform’s current or default device. The full list of models, with their screen sizes, is on Devices and settings.

Orientation

Boot the sim in landscape:

terminal
peach open 8081 --orientation landscape

Without the flag, a sim boots in its device’s default orientation, which is portrait. The flag goes on the sim’s own address, so it survives reloads.

Appearance and accessibility

terminal
peach shell appearance dark # light, dark, auto, or toggle
peach open 8081 --theme light # boot in a scheme (-t for short)

auto follows your computer’s light or dark setting.

Accessibility settings live in the built-in Settings app, under Accessibility, as on iOS: text size, bold text, reduce motion, reduce transparency, increase contrast, show borders, on and off labels, differentiate without color, smart invert, and prefer cross-fade transitions. Open it with peach shell launch settings. Your app reads the values through the normal React Native accessibility APIs.

Other hardware

terminal
peach shell home # go to the home screen
peach shell lock # lock the device
peach shell shake # shake it

Storage and app data

Clear the current app’s local storage:

terminal
peach storage clear

Clear the app’s data and relaunch it:

terminal
peach reset # app data
peach reset --full # also the keychain, user defaults and permissions

In a Maestro flow, clearState and clearKeychain do the same.

Storage profiles

A storage profile is a separate, persistent set of cookies, local storage, IndexedDB, caches, permissions and service workers. Use one to keep a logged-in account, a QA account and a fresh install side by side:

terminal
peach storage profile create qa
peach open 8081 --profile qa --driver playwright
peach storage profile list
peach storage profile clear qa
peach storage profile delete qa

Opening a profile always starts a new sim, because a sim’s storage is fixed when it launches. For a throwaway clean start, use peach open 8081 --new --ephemeral --driver playwright: a temporary profile with nothing carried over from earlier runs.

Network

Your app sees your browser’s real connection: when the browser goes offline, your app’s network state reports it, and the connection type comes from the browser too. Peach has no command yet to throttle the network or switch the device offline on its own, and Maestro’s setAirplaneMode is not supported.

To see what your app sends, read its traffic from the terminal:

terminal
peach network # the last 20 requests
peach network --failed # errors and non-2xx responses
peach network --slow # slower than 1000ms
peach network --tail # follow live
peach network get <id> # one request in detail

See peach network.