[ Documentation ]
Detox suites

Detox suites

peach detox runs Detox-style suites against Peach. It shells out to your own Jest, so your Jest version, transforms, and setupFiles keep working; the one thing it forces is that import ... from 'detox' resolves to the Peach driver.

Run an existing suite

Jest runs from your project, so add its dev dependencies once:

terminal
npm i -D peachsim jest
peach detox --app 8081

--app names the app each device.launchApp() opens: your dev server’s port or a bundle URL.

Test discovery checks e2e/, test/e2e/, and detox/ (or set PEACH_TEST_DIR). If a peach-detox.config.cjs, jest.config.cjs, or jest.config.js exists it is used; otherwise the Peach preset is applied directly. Useful flags:

terminal
peach detox --config e2e/jest.config.js
peach detox --port 5173 # shell port (also -p)
peach detox -t "login" # jest --testNamePattern
peach detox --watch
peach detox --headed # keep the peach window visible

If no Peach shell is reachable, the runner warns and tells you how to start one; pass --no-launch when you manage the shell yourself.

Start from scratch

terminal
peach detox init

scaffolds peach-detox.config.cjs plus a runnable e2e/example.test.ts using by, device, element, expect, and waitFor from detox.

What the driver supports

Matchers (by.id, by.text, by.label, by.role, by.type), actions (tap, longPress, typeText, replaceText, clearText, scroll, swipe, takeScreenshot), and the assertion set (toBeVisible, toExist, toHaveText, toHaveLabel, toHaveValue, toBeEnabled, and their negations). The full API lives in Detox Driver.

Migrating from native Detox

device.launchApp() and device.reloadReactNative() work as expected. Some device methods depend on native capabilities Peach intentionally handles differently:

Detox featurePeach behavior
device.takeScreenshot()captures a canvas screenshot
device.shake()no-op
device.sendToHome()no-op
device.installApp() / uninstallApp()no-op (runs in the browser)
device.setLocation()updates simulator location
device.setURLBlacklist()no-op

Many teams keep both: Peach in CI for fast feedback on every PR, native Detox for a final device pass.

{
"scripts": {
"test:native": "detox test",
"test:peach": "peach detox"
}
}

Results in CI and the dashboard

The exit code is Jest’s exit code, so any CI can gate on it with no account. When the suite runs in CI through the Peach GitHub App (or with an API key), the run also registers in your dashboard with the test counts and the first failure, so a red suite is visible in the dashboard without opening CI logs.

When a spec fails

The exit code is Jest’s, so a red run reads like any Jest failure: the spec name, the failed assertion, and the stack. The common failures and their fastest fixes:

symptomfix
no tests foundspecs live in e2e/, test/e2e/, or detox/, or set PEACH_TEST_DIR
runner warns no shell is reachablestart the dev server, then peach open <port>; peach list should show a connected sim. drop --no-launch unless you manage the shell yourself
a device.* call silently does nothingshake, sendToHome, install, uninstall, and setURLBlacklist are no-ops; see the migration table above
an assertion fails on a live simpeach describe shows what is actually on screen, peach get errors 5 shows recent console errors, and peach what-happened shows what just happened (toasts, navigation, fetches)

Next