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 to | run |
|---|---|
| grant or deny a permission | peach permissions set <app-id> <kind> <status> |
| set the device’s location | peach location set <lat>,<lon> |
| feed the camera a video, or scan a barcode | peach camera play <file>, peach do scan <text> |
| change the phone model | peach device set <model> |
| boot in landscape | peach open <port> --orientation landscape |
| switch light or dark mode | peach shell appearance dark |
| change accessibility settings | the built-in Settings app |
| clear app data | peach storage clear, peach reset |
| keep separate logins side by side | peach open <port> --profile <id> |
| watch network requests | peach 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.
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:
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.
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.
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:
For barcode scanning, inject a result straight into the active scan session:
The format defaults to qr_code; pass another web barcode format name with
--format.
Device model
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:
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
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
Storage and app data
Clear the current app’s local storage:
Clear the app’s data and relaunch it:
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:
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:
See peach network.