Detox
End-to-end tests driving the real app on a simulator or device.
The rule
What belongs here
Only flows where a regression would be unacceptable — sign-in, purchase, the core task the app exists for. Everything a component test can catch belongs in a component test: each E2E test costs minutes of CI on every push.
Selectors
- Use
by.id()with accessibility ids. Unlike component tests, this is the right default — text changes with locale and copy edits. - Add the id to the component deliberately, as part of the change.
Waiting
await waitFor(element(by.id('pro-badge'))).toBeVisible().withTimeout(10000);Never sleep(). A fixed delay is slow when the app is fast and flaky when it is not, and it hides the real timing bug.
Isolation
device.launchApp({ newInstance: true })inbeforeEach. State leaking between tests produces failures that depend on execution order.- Stub the network and third-party SDKs in the E2E build. A test that charges a real card, sends a real email, or pollutes analytics is not a test.
Do not
- Do not add an E2E test for something a unit test proves.
- Do not assert on exact copy that product will change next week.
- Do not delete a flaky test — quarantine it and fix the non-determinism.
As each tool receives it
The same guidance, in the shape each editor reads. Cursor and Claude Code are written separately by hand; the rest are derived from the Cursor rule.
---
description: Detox end-to-end testing conventions
globs: ["e2e/**", ".detoxrc.js"]
alwaysApply: false
---
# Detox
## What belongs here
Only flows where a regression would be unacceptable — sign-in, purchase, the
core task the app exists for. Everything a component test can catch belongs in
a component test: each E2E test costs minutes of CI on every push.
## Selectors
- Use `by.id()` with accessibility ids. Unlike component tests, this is the
right default — text changes with locale and copy edits.
- Add the id to the component deliberately, as part of the change.
## Waiting
```js
await waitFor(element(by.id('pro-badge'))).toBeVisible().withTimeout(10000);
```
Never `sleep()`. A fixed delay is slow when the app is fast and flaky when it
is not, and it hides the real timing bug.
## Isolation
- `device.launchApp({ newInstance: true })` in `beforeEach`. State leaking
between tests produces failures that depend on execution order.
- Stub the network and third-party SDKs in the E2E build. A test that charges a
real card, sends a real email, or pollutes analytics is not a test.
## Do not
- Do not add an E2E test for something a unit test proves.
- Do not assert on exact copy that product will change next week.
- Do not delete a flaky test — quarantine it and fix the non-determinism.
What else this module writes
Selecting Detox contributes more than a rule file — all of it merged with every other module you pick, with conflicts resolved rather than duplicated.
Related
Adds Detox to a project this tool generated, without starting over. Files you have hand-edited are left alone.