Detox is a framework for gray-box E2E testing of mobile applications, created by the Wix team specifically for React Native projects. Unlike black-box approaches, Detox has access to the internal state of the application, allowing it to automatically synchronize without manual timeouts. According to Wix Engineering, 2026, automatic synchronization reduces test run time by 40% compared to traditional pauses.
Key Takeaways
Detox is a framework for end-to-end (E2E) testing of mobile applications, developed by Wix in 2017. It is designed for React Native projects but also supports purely native applications on iOS and Android. Detox works on a gray-box model, meaning it has access to the internal mechanisms of the application.
The main difference between Detox and Appium or Calabash is automatic synchronization with the application. The framework waits for animations, network requests and event processing to complete before executing the next action. This completely eliminates the need for Thread.sleep() or waitForElement, which slow down tests.
Detox supports iOS (via XCTest and Xcode) and Android (via Espresso and UI Automator). For React Native applications, full support is provided for Fabric and the old architecture. On iOS, tests run on the simulator; on Android, on the emulator or a real device.
The Detox architecture consists of three key components: Detox CLI, Detox test runner and Detox Native Driver. Detox CLI manages the application build, installation and test execution. The test runner (Jest or Mocha) executes test scenarios and communicates with the application via WebSocket.
Gray-box testing means that Detox has access to the internal state of the application through a native bridge. The framework monitors network requests, animations, timers and the operation queue. When all queues are empty, Detox considers the application ready for the next step.
Synchronization is based on monitoring the main thread of the application. Detox waits until all animations complete, HTTP requests return responses and event handlers finish executing. If a test hangs due to infinite animation, you can manually disable synchronization for a specific code block.
// Disabling synchronization for a problematic section
await device.disableSynchronization();
// Action with long animation
await element(by.id('loader')).swipe('down');
await device.enableSynchronization();
Installing Detox starts by adding the package via npm or yarn. After installation, you need to create a configuration file .detoxrc.js, which describes the build and run settings for each platform. Detox uses its own build type for iOS, based on Xcode configuration.
The configuration includes the path to the application (app), builder type (build), build arguments and device settings (device). For iOS, appleSimulator is used; for Android, androidEmulator. You can also specify launch arguments such as the simulator language or region.
// .detoxrc.js — configuration example
module.exports = {
testRunner: { args: { '$0': 'jest', config: 'e2e/config.json' } },
apps: {
'ios.debug': { type: 'ios.app', build: 'xcodebuild ...' },
'android.debug': { type: 'android.apk', build: 'cd android && ./gradlew ...' }
},
devices: {
simulator: { type: 'ios.simulator', device: { type: 'iPhone 15' } },
emulator: { type: 'android.emulator', device: { avdName: 'Pixel_4_API_34' } }
}
};
After configuration, the following commands are available: detox build — builds the application with testing flags, and detox test — runs the tests. Detox supports parallel execution on multiple devices using the --workers flag.
Detox tests are written in JavaScript or TypeScript using an API based on element search (matchers) and actions. Matchers allow you to find an element by identifier, text, type or position on the screen. Actions perform taps, text input, swipes and scrolling.
A typical test follows this sequence: find an element → perform an action → verify the result. For assertions, the expect API is used with matchers for presence, visibility or element text. Detox supports describe/it syntax through integration with Jest.
describe('Login flow', () => {
beforeEach(async () => {
await device.reloadReactNative();
});
it('should log in with valid credentials', async () => {
await element(by.id('emailInput')).typeText('user@test.com');
await element(by.id('passwordInput')).typeText('password123');
await element(by.id('loginButton')).tap();
await expect(element(by.id('homeScreen'))).toBeVisible();
});
});
Detox supports all popular gestures: tap, longPress, swipe, scroll, pinch, multiTap. For scroll, you can specify the direction, speed and stop position. This allows testing complex scenarios such as pull-to-refresh or carousels.
Detox integrates well with popular CI systems: GitHub Actions, CircleCI, Bitrise and Jenkins. For running in CI, you need to set up a virtual iOS simulator (without GUI) and an Android emulator with hardware acceleration. Detox provides artifacts — screenshots and logs — for analyzing failed tests.
To speed up test runs in CI, it is recommended to use sharding (parallelization) with the --workers flag. Detox automatically distributes test files across multiple simulators. It is also useful to cache application builds between runs to reduce build time.
# GitHub Actions — running Detox on iOS
- name: Install Dependencies
run: npm ci
- name: Build Detox App
run: npx detox build --configuration ios.sim
- name: Run Detox Tests
run: npx detox test --configuration ios.sim --workers 2
timeout-minutes: 30
For stable and fast E2E tests, it is recommended to follow several rules. Avoid sleep() — Detox provides automatic synchronization, and explicit delays only slow down tests and make them unstable. If a test fails due to timing issues, first check whether synchronization is disabled. It is also useful to group tests by feature and run them independently — this simplifies finding the cause of failure.
Detox provides several device methods for state management: device.reloadReactNative() reloads the bundle, device.launchNewApp() launches the application with new parameters, device.sendToHome() minimizes the application. device.setURLBlacklist() allows you to exclude certain URLs from synchronization, which is useful for analytics and long-polling connections.
For each test, it is recommended to create an isolated state. Use beforeEach to reload the application via device.reloadReactNative(). For tests requiring specific data, create factories or API clients to prepare data on the server. Avoid dependencies between tests — each test should be independent.
Detox supports testing WebView via web.element() and web.invoke() methods. To interact with web elements, by.web](:id, css or className is used. It is important to remember that WebView requires additional loading time — if synchronization does not work, add a loading wait using waitFor.
// Testing WebView in Detox
const webView = web(by.id('webview'));
await webView.element(by.web.cssSelector('#submit-btn')).tap();
const result = await webView.element(
by.web.cssSelector('.result-text')
).getText();
await expect(result).toEqual('Success');
Detox supports screenshot comparison via the detox-image-matching plugin. Screenshots allow you to detect visual regressions: shifted elements, incorrect colors, missing icons. For stable screenshots, disable animations and use a fixed simulator size.
The most common Detox issues are related to synchronization: infinite animations, long network requests or stuck timers. Logging with the --loglevel trace flag shows which resources Detox is waiting for. If Detox hangs, use device.disableSynchronization() for the problematic code block.
On the iOS simulator, Detox requires the application to be built first via xcodebuild with the iphonesimulator configuration. A common mistake is using a Release scheme instead of Debug, which disables testing flags. For Android, make sure the AVD is created with an API compatible with your application and Intel HAXM acceleration is enabled. For CI environments on macOS, it is convenient to use GitHub Actions with a macOS runner, where Xcode and simulators are already pre-installed.
If tests regularly fail due to timeout, check: whether synchronization is disabled globally, whether setTimeout or setInterval are used in the application code without cleanup, and whether the main thread is blocked by a long operation. Sometimes increasing the timeout in detoxrc.js via testRunner.args.jest.$.testTimeout helps. To find problematic areas, enable Detox trace logging — it shows which resources and timers the framework is currently waiting for.
After running tests, Detox creates artifacts: screenshots of failed tests, application logs and JUnit XML reports. Screenshots are taken automatically when a test fails and help visually identify the problem. For CI, artifacts are uploaded to cloud storage and available via a web interface for analyzing the causes of failure.
Frequently Asked Questions
Detox uses a gray-box approach with access to the application’s internal state and automatic synchronization. Appium works on a black-box model via WebDriver and requires manual waits. Detox is faster and more stable for React Native projects.
Detox tests are written in JavaScript or TypeScript. The framework integrates with Jest and Mocha as test runners. The native engine for iOS is written in Swift, for Android in Kotlin and Java.
Yes, Detox supports native applications on iOS (via XCTest) and Android (via Espresso). However, the main audience for Detox is React Native developers, since more mature solutions exist for native projects.
Detox provides artifacts: screenshots, application logs and HTML reports. For local debugging, use the --loglevel trace flag, and for CI, an automatic artifact collector with cloud upload.
This is a Detox API method that reloads the React Native JavaScript bundle without reinstalling the application. It is used in beforeEach to reset the application state to the initial screen before each test.
Summary
We will develop a mobile application turnkey
IT Sectr creates iOS and Android applications for startups and businesses since 2017. We will advise you and propose the best solution.
Read also