@percy/detox
v1.0.0
Published
Percy visual testing SDK for Detox (React Native E2E)
Maintainers
Readme
@percy/detox
Percy visual testing SDK for Detox — the gray-box E2E framework for React Native apps.
Quick start
npm install --save-dev @percy/cli @percy/detoxAdd a screenshot call to any Detox test:
const { device, element, by } = require('detox');
const percyScreenshot = require('@percy/detox');
describe('Login flow', () => {
it('renders the welcome screen', async () => {
await expect(element(by.id('welcome'))).toBeVisible();
await percyScreenshot(device, 'Welcome screen');
});
});Run under Percy CLI's app:exec with an App-type project token (app_...):
export PERCY_TOKEN=<app_...>
npx percy app:exec -- npx detox test -c android.emu.debugA working example app is available at percy/example-percy-detox.
Requirements
- Node ≥ 18
- Detox ≥ 20.32.0
- An App-type Percy project (token starts with
app_)
Supported execution targets
| Target | Status | |---|---| | Android — local emulator | ✅ Fully supported | | Android — local USB-attached real device | ✅ Same local driver as emulator | | iOS — local simulator | ✅ Supported | | iOS — local real device | ⚠️ Works in principle; uncommon |
API
await percyScreenshot(deviceOrElement, name, options?)deviceOrElement— the Detoxdeviceobject, or an element handle fromelement(by.id(...)).name— unique snapshot name within the build.options(all optional):
| Option | Type | Description |
|---|---|---|
| fullscreen | boolean | Treat the screenshot as full-screen (no chrome cropping). |
| fullPage | boolean | Accepted for API parity; produces a single-tile capture (warns once per process). |
| deviceName | string | Override auto-detected device name. |
| osVersion | string | Override auto-detected OS version. |
| orientation | 'portrait' \| 'landscape' | Override; defaults to 'portrait'. |
| statusBarHeight | number | Pixel override; default 0. |
| navigationBarHeight | number | Pixel override; default 0. |
| ignoreRegionIds | string[] | Mask elements located via by.id(testID). |
| ignoreRegionElements | DetoxElement[] | Mask pre-matched Detox element handles. |
| customIgnoreRegions | {top,bottom,left,right}[] | Mask rectangles in point coordinates. |
| considerRegionIds | string[] | Restrict diff to these elements. |
| considerRegionElements | DetoxElement[] | Restrict diff to these handles. |
| customConsiderRegions | {top,bottom,left,right}[] | Restrict diff to these rects (points). |
| testCase | string | Group snapshot in the Percy review UI. |
| labels | string | Comma-separated label chips for the snapshot. |
| sync | boolean | Block until the Percy build finalizes. |
Coordinate space: all region options accept point coordinates. The SDK multiplies by the device scale factor automatically. Do not pre-multiply.
Examples
Element-level capture
const hero = element(by.id('hero'));
await expect(hero).toBeVisible();
await percyScreenshot(hero, 'Hero element');Ignore dynamic regions
await percyScreenshot(device, 'Dashboard', {
ignoreRegionIds: ['live-clock', 'unread-count'],
customIgnoreRegions: [{ top: 0, bottom: 100, left: 0, right: 414 }]
});Group snapshots by test case
await percyScreenshot(device, 'Login screen', { testCase: 'auth-suite' });Configuration
| Environment variable | Effect |
|---|---|
| PERCY_TOKEN | Required. App-type Percy project token (starts with app_). |
| PERCY_IGNORE_ERRORS | If 'true', screenshot failures are logged and swallowed instead of failing the test. |
| PERCY_LOGLEVEL | silent, info, debug. Defaults to info. |
| PERCY_METRICS | If 'true', collect per-screenshot timing telemetry. |
Debugging
If you run into issues, the first place to look is the Debugging SDKs guide — it covers log levels, common setup gotchas, and how to gather logs for a bug report.
To enable verbose output:
PERCY_LOGLEVEL=debug npx percy app:exec -- npx detox test -c android.emu.debugMigration from @percy/appium-app
| @percy/appium-app option | @percy/detox equivalent |
|---|---|
| ignoreRegionXpaths | Rejected — Detox has no XPath. Use ignoreRegionIds. |
| ignoreRegionAccessibilityIds | ignoreRegionIds. |
| ignoreRegionAppiumElements | ignoreRegionElements. |
| considerRegionXpaths | Rejected — use considerRegionIds. |
| considerRegionAccessibilityIds | considerRegionIds. |
| considerRegionAppiumElements | considerRegionElements. |
| scrollableXpath, scrollableId, screenLengths, topScrollviewOffset, bottomScrollviewOffset, androidScrollAreaPercentage, scrollSpeed, iosOptimizedFullpage | Rejected — fullPage scroll-and-stitch is not supported on Detox. |
| thTestCaseExecutionId | Rejected — TestHub is not supported. |
Passing a rejected key throws TypeError with a migration hint — nothing is silently ignored.
Known limitations
element.takeScreenshotmisses TextureView, GLSurfaceView, Skia canvases, and other hardware-accelerated content on Android (wix/Detox#4489). Usedevice.takeScreenshotfor views backed by these surfaces.- iOS:
atIndex(n).getAttributes()is silently ignored (wix/Detox#4633). When multi-match occurs,@percy/detoxuses the first result and logs a warning. fullPageis accepted but produces a single-tile capture — Detox has no server-side stitching channel (unlike BrowserStack's Appium executor).- iOS scale factor is inferred from PNG width:
>=1080 → 3x, otherwise2x. iPad retina at 2x with width 1536+ may be misclassified; override with explicit options or open an issue.
Resources
License
MIT
