docs/helpers/Detox.md
Extends Helper
This is a wrapper on top of Detox library, aimied to unify testing experience for CodeceptJS framework. Detox provides a grey box testing for mobile applications, playing especially good for React Native apps.
Detox plays quite differently from Appium. To establish detox testing you need to build a mobile application in a special way to inject Detox code. This why Detox is grey box testing solution, so you need access to application source code, and a way to build and execute it on emulator.
Comparing to Appium, Detox runs faster and more stable but requires an additional setup for build.
detox build command.npm i @codeceptjs/detox-helper --save
Detox configuration is required in package.json under detox section.
If you completed step 1 and step 2 you should have a configuration similar this:
"detox": {
"configurations": {
"ios.sim.debug": {
"device": "simulator",
"app": "ios.debug"
}
},
"apps": {
"ios.debug": {
"type": "ios.app",
"binaryPath": "../test/ios/build/Build/Products/Debug-iphonesimulator/MyTestApp.app",
"build": "xcodebuild -workspace ../test/ios/MyTestApp.xcworkspace -scheme MyTestApp -configuration Debug -sdk iphonesimulator -derivedDataPath ../test/ios/build"
}
},
"devices": {
"simulator": {
"type": "ios.simulator",
"device": {
"type": "iPhone 15"
}
}
}
}
Besides Detox configuration, CodeceptJS should also be configured to use Detox.
In codecept.conf.js enable Detox helper:
helpers: {
Detox: {
require: '@codeceptjs/detox-helper',
configuration: '<detox-configuration-name>',
}
}
It's important to specify a package name under require section and current detox configuration taken from package.json.
Options:
configuration - a detox configuration name. Required.reloadReactNative - should be enabled for React Native applications.reuse - reuse application for tests. By default, Detox reinstalls and relaunches app.registerGlobals - (default: true) Register Detox helper functions by, element, expect, waitFor globally.url - URL to open via deep-link each time the app is launched (android) or immediately afterwards (iOS). Useful for opening a bundle URL at the beginning of tests when working with Expo.config Appends text into the field. A field can be located by text, accessibility id, id.
I.appendField('name', 'davert');
Checks if an element exists.
I.checkIfElementExists('~edit'); // located by accessibility id
I.checkIfElementExists('~edit', '#menu'); // element inside #menu
locator (string | object) element to locatecontext (string | object | null) context element (optional, default null)Clears a text field. A field can be located by text, accessibility id, id.
I.clearField('~name');
Clicks on an element. Element can be located by its text or id or accessibility id
The second parameter is a context (id | type | accessibility id) to narrow the search.
Same as tap
I.click('Login'); // locate by text
I.click('~nav-1'); // locate by accessibility label
I.click('#user'); // locate by id
I.click('Login', '#nav'); // locate by text inside #nav
I.click({ ios: 'Save', android: 'SAVE' }, '#main'); // different texts on iOS and Android
Performs click on element with horizontal and vertical offset. An element is located by text, id, accessibility id.
I.clickAtPoint('Save', 10, 10);
I.clickAtPoint('~save', 10, 10); // locate by accessibility id
locator (string | object) x number horizontal offset (optional, default 0)y number vertical offset (optional, default 0)Checks text not to be visible. Use second parameter to narrow down the search.
I.dontSee('Record created');
I.dontSee('Record updated', '#message');
I.dontSee('Record deleted', '~message');
text string to check invisibilitycontext (string | object | null) element in which to search for text (optional, default null)Checks that element is not visible. Use second parameter to narrow down the search.
I.dontSeeElement('~edit'); // located by accessibility id
I.dontSeeElement('~edit', '#menu'); // element inside #menu
locator (string | object) element to locatecontext (string | object | null) context element (optional, default null)Checks that element not exists. Use second parameter to narrow down the search.
I.dontSeeElementExist('~edit'); // located by accessibility id
I.dontSeeElementExist('~edit', '#menu'); // element inside #menu
locator (string | object) element to locatecontext (string | object) context element (optional, default null)Fills in text field in an app. A field can be located by text, accessibility id, id.
I.fillField('Username', 'davert');
I.fillField('~name', 'davert');
I.fillField({ android: 'NAME', ios: 'name' }, 'davert');
Goes back on Android
I.goBack(); // on Android only
Grab the device platform
const platform = await I.grabPlatform();
Installs a configured application. Application is installed by default.
I.installApp();
Launches an application. If application instance already exists, use relaunchApp.
I.launchApp();
Taps an element and holds for a requested time.
I.longPress('Login', 2); // locate by text, hold for 2 seconds
I.longPress('~nav', 1); // locate by accessibility label, hold for second
I.longPress('Update', 2, '#menu'); // locate by text inside #menu, hold for 2 seconds
locator (string | object) element to locatesec number number of seconds to hold tapcontext (string | object | null) context element (optional, default null)Multi taps on an element. Element can be located by its text or id or accessibility id.
Set the number of taps in second argument. Optionally define the context element by third argument.
I.multiTap('Login', 2); // locate by text
I.multiTap('~nav', 2); // locate by accessibility label
I.multiTap('#user', 2); // locate by id
I.multiTap('Update', 2, '#menu'); // locate by id
locator (string | object) element to locatenum number number of tapscontext (string | object | null) context element (optional, default null)Relaunches an application.
I.relaunchApp();
Execute code only on Android
I.runOnAndroid(() => {
I.click('Button');
I.see('Hi, Android');
});
fn Function a function which will be executed on androidExecute code only on iOS
I.runOnIOS(() => {
I.click('Button');
I.see('Hi, IOS');
});
fn Function a function which will be executed on iOSSaves a screenshot to the output dir
I.saveScreenshot('main-window.png');
name string Scrolls to the bottom of an element.
I.scrollDown('#container');
Scrolls to the left of an element.
I.scrollLeft('#container');
Scrolls to the right of an element.
I.scrollRight('#container');
Scrolls within a scrollable container to an element.
targetLocator (string | object) Locator of the element to scroll tocontainerLocator (string | object) Locator of the scrollable containerdirection string 'up' or 'down' (optional, default 'down')offset number Offset for scroll, can be adjusted based on need (optional, default 100)Scrolls to the top of an element.
I.scrollUp('#container');
Checks text to be visible. Use second parameter to narrow down the search.
I.see('Record created');
I.see('Record updated', '#message');
I.see('Record deleted', '~message');
text string to check visibilitycontext (string | object | null) element inside which to search for text (optional, default null)Checks for visibility of an element. Use second parameter to narrow down the search.
I.seeElement('~edit'); // located by accessibility id
I.seeElement('~edit', '#menu'); // element inside #menu
locator (string | object) element to locatecontext (string | object | null) context element (optional, default null)Checks for existence of an element. An element can be visible or not. Use second parameter to narrow down the search.
I.seeElementExists('~edit'); // located by accessibility id
I.seeElementExists('~edit', '#menu'); // element inside #menu
locator (string | object) element to locatecontext (string | object) context element (optional, default null)Switches device to landscape orientation
I.setLandscapeOrientation();
Switches device to portrait orientation
I.setPortraitOrientation();
Shakes the device.
I.shakeDevice();
Performs a swipe up inside an element.
Can be slow or fast swipe.
I.swipeUp('#container');
locator (string | object) an element on which to perform swipespeed string a speed to perform: slow or fast. (optional, default 'slow')Performs a swipe up inside an element.
Can be slow or fast swipe.
I.swipeUp('#container');
locator (string | object) an element on which to perform swipespeed string a speed to perform: slow or fast. (optional, default 'slow')Performs a swipe up inside an element.
Can be slow or fast swipe.
I.swipeUp('#container');
locator (string | object) an element on which to perform swipespeed string a speed to perform: slow or fast. (optional, default 'slow')Performs a swipe up inside an element.
Can be slow or fast swipe.
I.swipeUp('#container');
locator (string | object) an element on which to perform swipespeed string a speed to perform: slow or fast. (optional, default 'slow')Taps on an element. Element can be located by its text or id or accessibility id.
The second parameter is a context element to narrow the search.
Same as click
I.tap('Login'); // locate by text
I.tap('~nav-1'); // locate by accessibility label
I.tap('#user'); // locate by id
I.tap('Login', '#nav'); // locate by text inside #nav
I.tap({ ios: 'Save', android: 'SAVE' }, '#main'); // different texts on iOS and Android
Clicks on an element. Element can be located by its label
The second parameter is a context (id | type | accessibility id) to narrow the search.
I.tapByLabel('Login'); // locate by text
I.tapByLabel('Login', '#nav'); // locate by text inside #nav
Taps return key. A field can be located by text, accessibility id, id.
I.tapReturnKey('Username');
I.tapReturnKey('~name');
I.tapReturnKey({ android: 'NAME', ios: 'name' });
Waits for number of seconds
I.wait(2); // waits for 2 seconds
sec number number of seconds to waitWaits for an element to exist on page.
I.waitForElement('#message', 1); // wait for 1 second
locator (string | object) an element to wait forsec number number of seconds to wait, 5 by default (optional, default 5)Waits for an element to be visible on page.
I.waitForElementVisible('#message', 1); // wait for 1 second
locator (string | object) an element to wait forsec number number of seconds to wait (optional, default 5)Waits an elmenet to become not visible.
I.waitToHide('#message', 2); // wait for 2 seconds