mirror of
https://github.com/hanzoai/Detox.git
synced 2026-09-24 16:55:12 +00:00
docs: fix lint issues
This commit is contained in:
+1
-1
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"first-line-heading": { "level": 2 },
|
"first-line-heading": { "level": 1 },
|
||||||
"heading-style": { "style": "atx" },
|
"heading-style": { "style": "atx" },
|
||||||
"hr-style": { "style": "---" },
|
"hr-style": { "style": "---" },
|
||||||
"ol-prefix": { "style": "one_or_ordered" },
|
"ol-prefix": { "style": "one_or_ordered" },
|
||||||
|
|||||||
+6
-1
@@ -15,6 +15,7 @@ CLI
|
|||||||
CMD
|
CMD
|
||||||
CocoaPods
|
CocoaPods
|
||||||
Detox
|
Detox
|
||||||
|
Docusaurus
|
||||||
E2E/M
|
E2E/M
|
||||||
ES5
|
ES5
|
||||||
Genymotion
|
Genymotion
|
||||||
@@ -48,6 +49,7 @@ TeamCity
|
|||||||
TypeScript
|
TypeScript
|
||||||
UDID/M
|
UDID/M
|
||||||
UI/M
|
UI/M
|
||||||
|
Vitest
|
||||||
WebDriver
|
WebDriver
|
||||||
Wix
|
Wix
|
||||||
XCTest
|
XCTest
|
||||||
@@ -68,13 +70,14 @@ blob/M
|
|||||||
blogpost/M
|
blogpost/M
|
||||||
breakpoint/M
|
breakpoint/M
|
||||||
bundler
|
bundler
|
||||||
|
bunyan
|
||||||
cancelled
|
cancelled
|
||||||
cheatsheet/M
|
cheatsheet/M
|
||||||
codebase/M
|
codebase/M
|
||||||
config/M
|
config/M
|
||||||
config/M
|
|
||||||
customization/M
|
customization/M
|
||||||
de
|
de
|
||||||
|
deallocate/M
|
||||||
debuggable
|
debuggable
|
||||||
dedupe
|
dedupe
|
||||||
destructure/M
|
destructure/M
|
||||||
@@ -99,6 +102,7 @@ lockfile/M
|
|||||||
macOS
|
macOS
|
||||||
matcher/M
|
matcher/M
|
||||||
minification/M
|
minification/M
|
||||||
|
minified
|
||||||
minSdkVersion
|
minSdkVersion
|
||||||
monorepo
|
monorepo
|
||||||
multistep
|
multistep
|
||||||
@@ -153,4 +157,5 @@ v20
|
|||||||
webhook/M
|
webhook/M
|
||||||
websocket/M
|
websocket/M
|
||||||
xcodebuild
|
xcodebuild
|
||||||
|
xcpretty
|
||||||
ᵃ
|
ᵃ
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
## Contributing to Detox
|
# Contributing to Detox
|
||||||
|
|
||||||
'So thrilled to know you want to contribute to Detox! 💙
|
'So thrilled to know you want to contribute to Detox! 💙
|
||||||
|
|
||||||
|
|||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
## Detox
|
# Detox
|
||||||
|
|
||||||
Graybox End-to-End Tests and Automation Library for Mobile
|
Graybox End-to-End Tests and Automation Library for Mobile
|
||||||
|
|
||||||
|
|||||||
@@ -58,7 +58,7 @@ we recommend adding `--reuse` flag to save your time when running the tests.
|
|||||||
detox test -c ios.sim.debug --reuse # or android.emu.debug
|
detox test -c ios.sim.debug --reuse # or android.emu.debug
|
||||||
```
|
```
|
||||||
|
|
||||||
By default, Detox reinstalls the app before picking every next test suite which is redundant in this situation
|
By default, Detox re-installs the app before picking every next test suite which is redundant in this situation
|
||||||
since your app code changes are delivered via network with React Native packager, and the app binary itself does
|
since your app code changes are delivered via network with React Native packager, and the app binary itself does
|
||||||
not change.
|
not change.
|
||||||
|
|
||||||
|
|||||||
@@ -29,7 +29,7 @@ In this context, launch argument are useful for implementing step [#3](https://g
|
|||||||
User-defined launch arguments specification is very flexible, and can be defined on 4 levels:
|
User-defined launch arguments specification is very flexible, and can be defined on 4 levels:
|
||||||
|
|
||||||
| Level | Description |
|
| Level | Description |
|
||||||
| ----------------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
| ----------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| 1. Static Configuration | As a part of a static [Detox configuration](config/overview.md), using the `launchArgs` property.<br />This is can sufficient, for example, if you only require one mock server instance, and can use the same static port throughout the entire testing execution session. |
|
| 1. Static Configuration | As a part of a static [Detox configuration](config/overview.md), using the `launchArgs` property.<br />This is can sufficient, for example, if you only require one mock server instance, and can use the same static port throughout the entire testing execution session. |
|
||||||
| 2. Static via CLI | As arguments specified explicitly in the [command-line](api/detox-cli.md) execution of `detox test`, using `--app-launch-args`. |
|
| 2. Static via CLI | As arguments specified explicitly in the [command-line](api/detox-cli.md) execution of `detox test`, using `--app-launch-args`. |
|
||||||
| 3.`device.appLaunchArgs` | Dynamically, using the [`device.appLaunchArgs`](api/device.md#deviceapplaunchargs) API, which initially holds the static configuration, and then allows for the modification of it before applied through `device.launchApp()`.<br/>Mostly required in complex test environments, where the servers and ports are dynamic, and are determined via distinct software components (e.g. separate test kits). |
|
| 3.`device.appLaunchArgs` | Dynamically, using the [`device.appLaunchArgs`](api/device.md#deviceapplaunchargs) API, which initially holds the static configuration, and then allows for the modification of it before applied through `device.launchApp()`.<br/>Mostly required in complex test environments, where the servers and ports are dynamic, and are determined via distinct software components (e.g. separate test kits). |
|
||||||
|
|||||||
@@ -1,8 +1,6 @@
|
|||||||
---
|
---
|
||||||
id: mocking
|
id: mocking
|
||||||
slug: guide/mocking
|
slug: guide/mocking
|
||||||
title: Mocking
|
|
||||||
sidebar_label: Mocking
|
|
||||||
---
|
---
|
||||||
|
|
||||||
# Mocking
|
# Mocking
|
||||||
|
|||||||
@@ -9,17 +9,17 @@ slug: guide/proguard-configuration
|
|||||||
|
|
||||||
You can skip this guide if you are working solely with debug builds (`android.emu.debug`, etc.),
|
You can skip this guide if you are working solely with debug builds (`android.emu.debug`, etc.),
|
||||||
but as soon as you move to the **release builds**, where the native code gets minified and obfuscated,
|
but as soon as you move to the **release builds**, where the native code gets minified and obfuscated,
|
||||||
you are going to have problems with Detox if you leave your ProGuard rules unconfigured.
|
you are going to have problems with Detox if you leave your ProGuard rules not configured.
|
||||||
|
|
||||||
:::
|
:::
|
||||||
|
|
||||||
Since Detox relies on
|
Since Detox relies on
|
||||||
[Android Reflection API](https://developer.android.com/reference/java/lang/reflect/package-summary)
|
[Android Reflection API](https://developer.android.com/reference/java/lang/reflect/package-summary)
|
||||||
to integrate with React Native on Android, you should keep [ProGuard minification](https://developer.android.com/studio/build/shrink-code)
|
to integrate with React Native on Android, you should keep [ProGuard minification](https://developer.android.com/studio/build/shrink-code)
|
||||||
under tight control. Otherwise, you'll be seeing Detox crashing or hanging up infinitely upon an attempt to
|
under tight control. Otherwise, you’ll be seeing Detox crashing or hanging up infinitely upon an attempt to
|
||||||
run tests with your app built in **release mode**.
|
run tests with your app built in **release mode**.
|
||||||
|
|
||||||
To fix that, you'd need to return to your app build script:
|
To fix that, you’d need to return to your app build script:
|
||||||
|
|
||||||
```diff title="app/build.gradle"
|
```diff title="app/build.gradle"
|
||||||
buildTypes {
|
buildTypes {
|
||||||
@@ -36,7 +36,7 @@ To fix that, you'd need to return to your app build script:
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
1. `release` is typically the default proguard-enabled build-type
|
1. `release` build type is usually expected to have ProGuard enabled
|
||||||
1. Typical pro-guard definitions. Check out Android docs to get to know more.
|
1. Typical pro-guard definitions. Check out Android docs to get to know more.
|
||||||
1. Detox-specific additions to pro-guard
|
1. Detox-specific additions to pro-guard
|
||||||
|
|
||||||
|
|||||||
@@ -60,17 +60,15 @@ This can be a result of various reasons. It is generally up to you to debug and
|
|||||||
|
|
||||||
- You might have forgotten to run `device.launchApp()` in the beginning of your test.
|
- You might have forgotten to run `device.launchApp()` in the beginning of your test.
|
||||||
- The app might have crashed before Detox has had a chance to connect to it. To get the crash details, you can run Detox tests with `--record-logs all` CLI option and then inspect the device logs in the artifacts' folder.
|
- The app might have crashed before Detox has had a chance to connect to it. To get the crash details, you can run Detox tests with `--record-logs all` CLI option and then inspect the device logs in the artifacts' folder.
|
||||||
- **On Android**, there might be a problem with the native test code in the `DetoxTest.java` file. Revisit the [associated section](introduction/building-with-detox.mdx#5-create-a-detox-test-class) in the setup guide.
|
- **On Android**, there might be a problem with the native test code in the `DetoxTest.java` file. Revisit the [associated section](introduction/building-with-detox.mdx#step-3-android-configuration) in the setup guide.
|
||||||
|
|
||||||
##### If you _do_ see your app running on the device
|
##### If you _do_ see your app running on the device
|
||||||
|
|
||||||
- **On Android with SDK≥28**, the app’s connection to the Detox test server is blocked due to clear-traffic blockage (as reported in issue [#1450](https://github.com/wix/Detox/issues/1450)).
|
- **On Android with SDK≥28**, the app’s connection to the Detox test server is blocked due to clear-traffic blockage (as reported in issue [#1450](https://github.com/wix/Detox/issues/1450)).
|
||||||
The main step for getting this fixed is to revisit the [associated section](introduction/building-with-detox.mdx#6-enable-clear-text-unencrypted-traffic-for-detox) in the setup guide, which discusses network-security. Alternatively, the `android:usesCleartextTraffic="true"` attribute can be configured in the `<application>` tag of the app’s `AndroidManifest.xml`, but **that is highly discouraged**.
|
The main step for getting this fixed is to revisit the [associated section](introduction/building-with-detox.mdx#step-3-android-configuration) in the setup guide, which discusses network-security. Alternatively, the `android:usesCleartextTraffic="true"` attribute can be configured in the `<application>` tag of the app’s `AndroidManifest.xml`, but **that is highly discouraged**.
|
||||||
- If you’ve applied the above suggestion but the app fails to connect to the Detox test server, nonetheless: Refer to the device’s logs, which should contain messages about failed connection attempts (get them using the `--record-logs all` argument)
|
- If you’ve applied the above suggestion but the app fails to connect to the Detox test server, nonetheless: Refer to the device’s logs, which should contain messages about failed connection attempts (get them using the `--record-logs all` argument)
|
||||||
- The app could be running without Detox native code injected. In this case, first, make sure you’re not trying to run in manual launch mode (where this behavior is valid). If so, examine the logs from the device (get them using the `--record-logs all` argument). If you see a crash related to Detox’s native code, you are welcome to report it on our GitHub tracker.
|
- The app could be running without Detox native code injected. In this case, first, make sure you’re not trying to run in manual launch mode (where this behavior is valid). If so, examine the logs from the device (get them using the `--record-logs all` argument). If you see a crash related to Detox’s native code, you are welcome to report it on our GitHub tracker.
|
||||||
- If you are in fact debugging your native code integration with Detox, these guides may prove helpful:
|
- If you are in fact debugging your native code integration with Detox, our [Debugging tutorial](introduction/debugging.mdx) may prove helpful.
|
||||||
- <https://github.com/wix/Detox/blob/master/docs/Guide.DebuggingInAndroidStudio.md>
|
|
||||||
- <https://github.com/wix/Detox/blob/master/docs/Guide.DebuggingInXcode.md>
|
|
||||||
|
|
||||||
#### Syntax Error: Unexpected Token
|
#### Syntax Error: Unexpected Token
|
||||||
|
|
||||||
|
|||||||
+29
-29
@@ -1,10 +1,10 @@
|
|||||||
# Actions
|
# Actions
|
||||||
|
|
||||||
Detox uses [matchers](api/matchers.md) to find UI elements in your app and actions to simulate user interaction with those elements.
|
Detox uses [matchers](matchers.md) to find UI elements in your app and actions to simulate user interaction with those elements.
|
||||||
|
|
||||||
Use [expectations](api/expect.md) to verify element states.
|
Use [expectations](expect.md) to verify element states.
|
||||||
|
|
||||||
### Methods
|
## Methods
|
||||||
|
|
||||||
- [`.tap()`](#tappoint)
|
- [`.tap()`](#tappoint)
|
||||||
- [`.multiTap()`](#multitaptimes)
|
- [`.multiTap()`](#multitaptimes)
|
||||||
@@ -27,7 +27,7 @@ Use [expectations](api/expect.md) to verify element states.
|
|||||||
- [`.getAttributes()`](#getattributes)
|
- [`.getAttributes()`](#getattributes)
|
||||||
- [`.takeScreenshot(name)`](#takescreenshotname)
|
- [`.takeScreenshot(name)`](#takescreenshotname)
|
||||||
|
|
||||||
#### `tap(point)`
|
### `tap(point)`
|
||||||
|
|
||||||
Simulates a tap on the element at the specified point, or at element’s activation point if no point is specified.
|
Simulates a tap on the element at the specified point, or at element’s activation point if no point is specified.
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ await element(by.id('tappable')).tap();
|
|||||||
await element(by.id('tappable')).tap({x:5, y:10});
|
await element(by.id('tappable')).tap({x:5, y:10});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `multiTap(times)`
|
### `multiTap(times)`
|
||||||
|
|
||||||
Simulates multiple taps on the element at its activation point. All taps are applied as a part of the same gesture and there is no synchronization attempt between taps.
|
Simulates multiple taps on the element at its activation point. All taps are applied as a part of the same gesture and there is no synchronization attempt between taps.
|
||||||
|
|
||||||
@@ -50,7 +50,7 @@ Simulates multiple taps on the element at its activation point. All taps are app
|
|||||||
await element(by.id('tappable')).multiTap(3);
|
await element(by.id('tappable')).multiTap(3);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `longPress(duration)`
|
### `longPress(duration)`
|
||||||
|
|
||||||
Simulates a long press on the element at its activation point.
|
Simulates a long press on the element at its activation point.
|
||||||
|
|
||||||
@@ -61,7 +61,7 @@ await element(by.id('tappable')).longPress();
|
|||||||
await element(by.id('tappable')).longPress(1500);
|
await element(by.id('tappable')).longPress(1500);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `longPressAndDrag(duration, normalizedPositionX, normalizedPositionY, targetElement, normalizedTargetPositionX, normalizedTargetPositionY, speed, holdDuration)` iOS only
|
### `longPressAndDrag(duration, normalizedPositionX, normalizedPositionY, targetElement, normalizedTargetPositionX, normalizedTargetPositionY, speed, holdDuration)` iOS only
|
||||||
|
|
||||||
Simulates a long press on the element and then drag it to a position of another element.
|
Simulates a long press on the element and then drag it to a position of another element.
|
||||||
|
|
||||||
@@ -79,7 +79,7 @@ await element(by.id('elementToDrag')).longPressAndDrag(2000, NaN, NaN, element(b
|
|||||||
await element(by.id('cellId_1')).longPressAndDrag(2000, 0.9, NaN, element(by.id('cellId_6')), 0.9, NaN, 'slow', 0);
|
await element(by.id('cellId_1')).longPressAndDrag(2000, 0.9, NaN, element(by.id('cellId_6')), 0.9, NaN, 'slow', 0);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `swipe(direction, speed, normalizedOffset, normalizedStartingPointX, normalizedStartingPointY)`
|
### `swipe(direction, speed, normalizedOffset, normalizedStartingPointX, normalizedStartingPointY)`
|
||||||
|
|
||||||
Simulates a swipe on the element with the provided options.
|
Simulates a swipe on the element with the provided options.
|
||||||
|
|
||||||
@@ -97,7 +97,7 @@ await element(by.id('scrollView')).swipe('down', 'fast', NaN, 0.8); // set start
|
|||||||
await element(by.id('scrollView')).swipe('down', 'fast', NaN, NaN, 0.25); // set starting point Y
|
await element(by.id('scrollView')).swipe('down', 'fast', NaN, NaN, 0.25); // set starting point Y
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `pinch(scale, speed, angle)` iOS only
|
### `pinch(scale, speed, angle)` iOS only
|
||||||
|
|
||||||
Simulates a pinch on the element with the provided options.
|
Simulates a pinch on the element with the provided options.
|
||||||
|
|
||||||
@@ -111,7 +111,7 @@ await element(by.id('PinchableScrollView')).pinch(2.0); //Zooms in a lot
|
|||||||
await element(by.id('PinchableScrollView')).pinch(0.001); //Zooms out a lot
|
await element(by.id('PinchableScrollView')).pinch(0.001); //Zooms out a lot
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `scrollToIndex(index)` Android only
|
### `scrollToIndex(index)` Android only
|
||||||
|
|
||||||
Scrolls until it reaches the element with the provided index. This works for `ReactScrollView` and `ReactHorizontalScrollView`.
|
Scrolls until it reaches the element with the provided index. This works for `ReactScrollView` and `ReactHorizontalScrollView`.
|
||||||
|
|
||||||
@@ -121,7 +121,7 @@ Scrolls until it reaches the element with the provided index. This works for `Re
|
|||||||
await element(by.id('scrollView')).scrollToIndex(0);
|
await element(by.id('scrollView')).scrollToIndex(0);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `scroll(offset, direction, startPositionX, startPositionY)`
|
### `scroll(offset, direction, startPositionX, startPositionY)`
|
||||||
|
|
||||||
Simulates a scroll on the element with the provided options.
|
Simulates a scroll on the element with the provided options.
|
||||||
|
|
||||||
@@ -135,7 +135,7 @@ await element(by.id('scrollView')).scroll(100, 'up');
|
|||||||
await element(by.id('scrollView')).scroll(100, 'down', NaN, 0.85);
|
await element(by.id('scrollView')).scroll(100, 'down', NaN, 0.85);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `whileElement(element)`
|
### `whileElement(element)`
|
||||||
|
|
||||||
Continuously scrolls the scroll element until the specified expectation is resolved. If the edge of the scroll element is reached while the expectation is not resolved, the operation is failed.
|
Continuously scrolls the scroll element until the specified expectation is resolved. If the edge of the scroll element is reached while the expectation is not resolved, the operation is failed.
|
||||||
|
|
||||||
@@ -143,7 +143,7 @@ Continuously scrolls the scroll element until the specified expectation is resol
|
|||||||
await waitFor(element(by.text('Text5'))).toBeVisible().whileElement(by.id('ScrollView630')).scroll(50, 'down');
|
await waitFor(element(by.text('Text5'))).toBeVisible().whileElement(by.id('ScrollView630')).scroll(50, 'down');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `scrollTo(edge)`
|
### `scrollTo(edge)`
|
||||||
|
|
||||||
Simulates a scroll to the specified edge.
|
Simulates a scroll to the specified edge.
|
||||||
|
|
||||||
@@ -154,7 +154,7 @@ await element(by.id('scrollView')).scrollTo('bottom');
|
|||||||
await element(by.id('scrollView')).scrollTo('top');
|
await element(by.id('scrollView')).scrollTo('top');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `typeText(text)`
|
### `typeText(text)`
|
||||||
|
|
||||||
Simulates typing of the specified text into the element, using the system’s builtin keyboard and typing behavior.
|
Simulates typing of the specified text into the element, using the system’s builtin keyboard and typing behavior.
|
||||||
|
|
||||||
@@ -166,7 +166,7 @@ On iOS, any element can be typed into, as long as it can become first responder
|
|||||||
await element(by.id('textField')).typeText('passcode');
|
await element(by.id('textField')).typeText('passcode');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `replaceText(text)`
|
### `replaceText(text)`
|
||||||
|
|
||||||
Replaces the element’s text with the specified text, without using the system’s builtin keyboard or typing behavior. **Note**, that using this method is faster than using [`.typeText()`](#typetexttext), but may not trigger all text input callbacks, causing an undefined state in your app.
|
Replaces the element’s text with the specified text, without using the system’s builtin keyboard or typing behavior. **Note**, that using this method is faster than using [`.typeText()`](#typetexttext), but may not trigger all text input callbacks, causing an undefined state in your app.
|
||||||
|
|
||||||
@@ -178,7 +178,7 @@ On iOS, any element’s text can be replaced, as long as it can become first res
|
|||||||
await element(by.id('textField')).replaceText('passcode again');
|
await element(by.id('textField')).replaceText('passcode again');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `clearText()`
|
### `clearText()`
|
||||||
|
|
||||||
Simulates clearing the text of the element, using the system’s builtin keyboard and typing behavior.
|
Simulates clearing the text of the element, using the system’s builtin keyboard and typing behavior.
|
||||||
|
|
||||||
@@ -188,7 +188,7 @@ On iOS, any element’s text can be cleared, as long as it can become first resp
|
|||||||
await element(by.id('textField')).clearText();
|
await element(by.id('textField')).clearText();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `tapReturnKey()`
|
### `tapReturnKey()`
|
||||||
|
|
||||||
Simulates tapping on the return key into the element, using the system’s builtin keyboard and typing behavior.
|
Simulates tapping on the return key into the element, using the system’s builtin keyboard and typing behavior.
|
||||||
|
|
||||||
@@ -198,7 +198,7 @@ On iOS, any element can be sent return key input, as long as it can become first
|
|||||||
await element(by.id('textField')).tapReturnKey();
|
await element(by.id('textField')).tapReturnKey();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `tapBackspaceKey()`
|
### `tapBackspaceKey()`
|
||||||
|
|
||||||
Simulates tapping of the backspace key into the element, using the system’s builtin keyboard and typing behavior.
|
Simulates tapping of the backspace key into the element, using the system’s builtin keyboard and typing behavior.
|
||||||
|
|
||||||
@@ -208,7 +208,7 @@ On iOS, any element can be sent backspace key input, as long as it can become fi
|
|||||||
await element(by.id('textField')).tapBackspaceKey();
|
await element(by.id('textField')).tapBackspaceKey();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `setColumnToValue(column, value)` iOS only
|
### `setColumnToValue(column, value)` iOS only
|
||||||
|
|
||||||
Sets the element’s specified column to the specified value, using the system’s picker view APIs.
|
Sets the element’s specified column to the specified value, using the system’s picker view APIs.
|
||||||
|
|
||||||
@@ -224,9 +224,9 @@ await element(by.id('pickerView')).setColumnToValue(1, "6");
|
|||||||
await element(by.id('pickerView')).setColumnToValue(2, "Hello World");
|
await element(by.id('pickerView')).setColumnToValue(2, "Hello World");
|
||||||
```
|
```
|
||||||
|
|
||||||
> **Note:** When working with date pickers, you should always set an explicit locale when launching your app in order to prevent flakiness from different date and time styles. See [here](api/device.md#9-languageandlocalelaunch-with-a-specific-language-andor-local-ios-only) for more information.
|
> **Note:** When working with date pickers, you should always set an explicit locale when launching your app in order to prevent flakiness from different date and time styles. See [here](device.md#9-languageandlocalelaunch-with-a-specific-language-andor-local-ios-only) for more information.
|
||||||
|
|
||||||
#### `setDatePickerDate(dateString, dateFormat)` iOS only
|
### `setDatePickerDate(dateString, dateFormat)` iOS only
|
||||||
|
|
||||||
Sets the element’s date to the specified date string, parsed using the specified date format.
|
Sets the element’s date to the specified date string, parsed using the specified date format.
|
||||||
|
|
||||||
@@ -240,7 +240,7 @@ await element(by.id('datePicker')).setDatePickerDate('2019-02-06T05:10:00-08:00'
|
|||||||
await element(by.id('datePicker')).setDatePickerDate('2019/02/06', "yyyy/MM/dd");
|
await element(by.id('datePicker')).setDatePickerDate('2019/02/06', "yyyy/MM/dd");
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `adjustSliderToPosition(normalizedPosition)`
|
### `adjustSliderToPosition(normalizedPosition)`
|
||||||
|
|
||||||
Manipulates the UI to change the displayed value of the slider element to a new value, based on a normalized position.
|
Manipulates the UI to change the displayed value of the slider element to a new value, based on a normalized position.
|
||||||
|
|
||||||
@@ -250,7 +250,7 @@ Manipulates the UI to change the displayed value of the slider element to a new
|
|||||||
await element(by.id('slider')).adjustSliderToPosition(0.75);
|
await element(by.id('slider')).adjustSliderToPosition(0.75);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `getAttributes()`
|
### `getAttributes()`
|
||||||
|
|
||||||
Returns an object, representing various attributes of the element.
|
Returns an object, representing various attributes of the element.
|
||||||
|
|
||||||
@@ -264,7 +264,7 @@ Retrieved attributes are:
|
|||||||
- `visible`: Whether the element is visible. On iOS, visibility is calculated for the [activation point](https://developer.apple.com/documentation/objectivec/nsobject/1615179-accessibilityactivationpoint). On Android, the attribute directly holds the value returned by [View.getLocalVisibleRect()](https://developer.android.com/reference/kotlin/android/view/View#getglobalvisiblerect)).
|
- `visible`: Whether the element is visible. On iOS, visibility is calculated for the [activation point](https://developer.apple.com/documentation/objectivec/nsobject/1615179-accessibilityactivationpoint). On Android, the attribute directly holds the value returned by [View.getLocalVisibleRect()](https://developer.android.com/reference/kotlin/android/view/View#getglobalvisiblerect)).
|
||||||
- `value`: The value of the element, where applicable. For example: the position of a slider, or whether a checkbox has been marked. Matches `accessibilityValue`, on iOS.
|
- `value`: The value of the element, where applicable. For example: the position of a slider, or whether a checkbox has been marked. Matches `accessibilityValue`, on iOS.
|
||||||
|
|
||||||
##### iOS-Only
|
#### iOS-Only
|
||||||
|
|
||||||
- `activationPoint`: The [activation point](https://developer.apple.com/documentation/objectivec/nsobject/1615179-accessibilityactivationpoint) of the element, in element coordinate space.
|
- `activationPoint`: The [activation point](https://developer.apple.com/documentation/objectivec/nsobject/1615179-accessibilityactivationpoint) of the element, in element coordinate space.
|
||||||
- `normalizedActivationPoint`: The activation point of the element, in normalized percentage (\[0.0, 1.0]).
|
- `normalizedActivationPoint`: The activation point of the element, in normalized percentage (\[0.0, 1.0]).
|
||||||
@@ -280,7 +280,7 @@ Retrieved attributes are:
|
|||||||
- `contentInset`: The content inset (in case the element is a scroll view).
|
- `contentInset`: The content inset (in case the element is a scroll view).
|
||||||
- `adjustedContentInset`: The adjusted content inset (in case the element is a scroll view).
|
- `adjustedContentInset`: The adjusted content inset (in case the element is a scroll view).
|
||||||
|
|
||||||
##### Android-Only
|
#### Android-Only
|
||||||
|
|
||||||
- `visibility`: The OS visibility type associated with the element: `visible`, `invisible` or `gone`.
|
- `visibility`: The OS visibility type associated with the element: `visible`, `invisible` or `gone`.
|
||||||
- `width`: Width of the element, in pixels.
|
- `width`: Width of the element, in pixels.
|
||||||
@@ -304,18 +304,18 @@ jestExpect(multipleMatchedElements.elements.length).toBe(5);
|
|||||||
jestExpect(multipleMatchedElements.elements[0].identifier).toBe('FirstElement');
|
jestExpect(multipleMatchedElements.elements[0].identifier).toBe('FirstElement');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `takeScreenshot(name)`
|
### `takeScreenshot(name)`
|
||||||
|
|
||||||
Takes a screenshot of the matched element. For full details on taking screenshots with Detox, refer to the [screenshots guide](../guide/taking-screenshots.md).
|
Takes a screenshot of the matched element. For full details on taking screenshots with Detox, refer to the [screenshots guide](../guide/taking-screenshots.md).
|
||||||
|
|
||||||
`name`—the name of the screenshot
|
`name`—the name of the screenshot
|
||||||
|
|
||||||
### Deprecated Methods
|
## Deprecated Methods
|
||||||
|
|
||||||
- [`.tapAtPoint()`](#tapatpointpoint)
|
- [`.tapAtPoint()`](#tapatpointpoint)
|
||||||
- [`.pinchWithAngle()`](#pinchwithangledirection-speed-angle--ios-only) **iOS only**
|
- [`.pinchWithAngle()`](#pinchwithangledirection-speed-angle--ios-only) **iOS only**
|
||||||
|
|
||||||
#### `tapAtPoint(point)`
|
### `tapAtPoint(point)`
|
||||||
|
|
||||||
**Deprecated:** Use [`.tap()`](#tappoint) instead.
|
**Deprecated:** Use [`.tap()`](#tappoint) instead.
|
||||||
|
|
||||||
@@ -327,7 +327,7 @@ Simulates a tap at on the element at the specified point.
|
|||||||
await element(by.id('tappable')).tapAtPoint({x:5, y:10});
|
await element(by.id('tappable')).tapAtPoint({x:5, y:10});
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `pinchWithAngle(direction, speed, angle)` iOS only
|
### `pinchWithAngle(direction, speed, angle)` iOS only
|
||||||
|
|
||||||
**Deprecated:** Use [`.pinch()`](#pinchscale-speed-angle--ios-only) instead.
|
**Deprecated:** Use [`.pinch()`](#pinchscale-speed-angle--ios-only) instead.
|
||||||
|
|
||||||
|
|||||||
+13
-13
@@ -2,7 +2,7 @@
|
|||||||
|
|
||||||
`detox-cli` lets you operate Detox from command line.
|
`detox-cli` lets you operate Detox from command line.
|
||||||
|
|
||||||
### Installation
|
## Installation
|
||||||
|
|
||||||
Install `detox-cli` globally via [npm](http://npmjs.org/detox-cli):
|
Install `detox-cli` globally via [npm](http://npmjs.org/detox-cli):
|
||||||
|
|
||||||
@@ -10,13 +10,13 @@ Install `detox-cli` globally via [npm](http://npmjs.org/detox-cli):
|
|||||||
npm install detox-cli --global
|
npm install detox-cli --global
|
||||||
```
|
```
|
||||||
|
|
||||||
### Usage
|
## Usage
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
detox <command> [options]
|
detox <command> [options]
|
||||||
```
|
```
|
||||||
|
|
||||||
### Commands
|
## Commands
|
||||||
|
|
||||||
| Command | Description |
|
| Command | Description |
|
||||||
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------ |
|
||||||
@@ -29,14 +29,14 @@ detox <command> [options]
|
|||||||
| [rebuild-framework-cache](#cache) | **MacOS only.** Rebuilds the Detox cache |
|
| [rebuild-framework-cache](#cache) | **MacOS only.** Rebuilds the Detox cache |
|
||||||
| [recorder](#recorder) | Starts a [Detox Recorder](https://github.com/wix/DetoxRecorder) recording |
|
| [recorder](#recorder) | Starts a [Detox Recorder](https://github.com/wix/DetoxRecorder) recording |
|
||||||
|
|
||||||
#### Options
|
## Options
|
||||||
|
|
||||||
| Options | Description |
|
| Options | Description |
|
||||||
| --------- | ------------------- |
|
| --------- | ------------------- |
|
||||||
| --version | Show version number |
|
| --version | Show version number |
|
||||||
| --help | Show help |
|
| --help | Show help |
|
||||||
|
|
||||||
#### init
|
## init
|
||||||
|
|
||||||
Scaffolds initial E2E test folder structure for a specific test runner
|
Scaffolds initial E2E test folder structure for a specific test runner
|
||||||
|
|
||||||
@@ -46,7 +46,7 @@ Scaffolds initial E2E test folder structure for a specific test runner
|
|||||||
| ------ | ----------- |
|
| ------ | ----------- |
|
||||||
| --help | Show help |
|
| --help | Show help |
|
||||||
|
|
||||||
#### build
|
## build
|
||||||
|
|
||||||
Run the command defined in `build` property of the specified **configuration**.
|
Run the command defined in `build` property of the specified **configuration**.
|
||||||
|
|
||||||
@@ -60,7 +60,7 @@ Run the command defined in `build` property of the specified **configuration**.
|
|||||||
| -s, --silent | Do not fail with error if an app config has no build command. |
|
| -s, --silent | Do not fail with error if an app config has no build command. |
|
||||||
| --help | Show help |
|
| --help | Show help |
|
||||||
|
|
||||||
##### Examples
|
### Examples
|
||||||
|
|
||||||
If you have only one configuration, you can simply use:
|
If you have only one configuration, you can simply use:
|
||||||
|
|
||||||
@@ -80,7 +80,7 @@ To skip building an app if it already is built:
|
|||||||
detox build --configuration yourConfiguration --if-missing
|
detox build --configuration yourConfiguration --if-missing
|
||||||
```
|
```
|
||||||
|
|
||||||
#### test
|
## test
|
||||||
|
|
||||||
`detox test [options] <...testFilePaths>`
|
`detox test [options] <...testFilePaths>`
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ DETOX_CONFIGURATION=ios.debug jest --help
|
|||||||
```
|
```
|
||||||
|
|
||||||
| Option | Description |
|
| Option | Description |
|
||||||
| --------------------------------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
| --------------------------------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| -C, --config-path `<configPath>` | Specify Detox config file path. If not supplied, detox searches for .detoxrc\[.js] or "detox" section in package.json |
|
| -C, --config-path `<configPath>` | Specify Detox config file path. If not supplied, detox searches for .detoxrc\[.js] or "detox" section in package.json |
|
||||||
| -c, --configuration `<device config>` | Select a device configuration from your defined configurations, if not supplied, and there’s only one configuration, detox will default to it |
|
| -c, --configuration `<device config>` | Select a device configuration from your defined configurations, if not supplied, and there’s only one configuration, detox will default to it |
|
||||||
| -n, --device-name \[name] | Override the device name specified in a configuration. Useful for running a single build configuration on multiple devices. |
|
| -n, --device-name \[name] | Override the device name specified in a configuration. Useful for running a single build configuration on multiple devices. |
|
||||||
@@ -132,7 +132,7 @@ DETOX_CONFIGURATION=ios.debug jest --help
|
|||||||
| --inspect-brk | Uses [node’s --inspect-brk](https://nodejs.org/en/docs/guides/debugging-getting-started/#enable-inspector) flag to let users debug the test runner <br />_Default: false_ |
|
| --inspect-brk | Uses [node’s --inspect-brk](https://nodejs.org/en/docs/guides/debugging-getting-started/#enable-inspector) flag to let users debug the test runner <br />_Default: false_ |
|
||||||
| --help | Show help |
|
| --help | Show help |
|
||||||
|
|
||||||
##### `DETOX_ARGV_OVERRIDE`
|
### `DETOX_ARGV_OVERRIDE`
|
||||||
|
|
||||||
If you happen to be troubleshooting Detox tests inside a complex script, or a failing CI build
|
If you happen to be troubleshooting Detox tests inside a complex script, or a failing CI build
|
||||||
(e.g., on TeamCity or Jenkins), there is an escape-hatch feature for running Detox with
|
(e.g., on TeamCity or Jenkins), there is an escape-hatch feature for running Detox with
|
||||||
@@ -158,7 +158,7 @@ save your time.
|
|||||||
Please avoid using it in your regular flows – instead, use Detox configuration files (`.detoxrc.js`)
|
Please avoid using it in your regular flows – instead, use Detox configuration files (`.detoxrc.js`)
|
||||||
as your primary choice.
|
as your primary choice.
|
||||||
|
|
||||||
#### run-server
|
## run-server
|
||||||
|
|
||||||
Start a standalone Detox server
|
Start a standalone Detox server
|
||||||
|
|
||||||
@@ -171,11 +171,11 @@ Start a standalone Detox server
|
|||||||
| --no-color | Disable colorful logs |
|
| --no-color | Disable colorful logs |
|
||||||
| --help | Show help |
|
| --help | Show help |
|
||||||
|
|
||||||
#### recorder
|
## recorder
|
||||||
|
|
||||||
If you have installed [Detox Recorder](https://github.com/wix/DetoxRecorder) in your project, you can use this command to start a new recording.
|
If you have installed [Detox Recorder](https://github.com/wix/DetoxRecorder) in your project, you can use this command to start a new recording.
|
||||||
|
|
||||||
#### Cache
|
## Cache
|
||||||
|
|
||||||
Detox stores a cached version of its framework in `~/Library/Detox`. A different cache folder is used for different Xcode and Detox versions. Use the various cache commands to clean or build this cache.
|
Detox stores a cached version of its framework in `~/Library/Detox`. A different cache folder is used for different Xcode and Detox versions. Use the various cache commands to clean or build this cache.
|
||||||
|
|
||||||
|
|||||||
+3
-3
@@ -279,7 +279,7 @@ The method calls `launchApp({newInstance: true})` as a convenience method.
|
|||||||
|
|
||||||
### `device.terminateApp()`
|
### `device.terminateApp()`
|
||||||
|
|
||||||
By default, `terminateApp()` with no params will terminate the app file defined in the current [`configuration`](config/overview.md).
|
By default, `terminateApp()` with no params will terminate the app file defined in the current [`configuration`](../config/overview.md).
|
||||||
|
|
||||||
To terminate another app, specify its bundle id
|
To terminate another app, specify its bundle id
|
||||||
|
|
||||||
@@ -309,7 +309,7 @@ If this is a React Native app, reload the React Native JS bundle. This action is
|
|||||||
|
|
||||||
### `device.installApp()`
|
### `device.installApp()`
|
||||||
|
|
||||||
By default, `installApp()` with no params will install the app file defined in the current [`configuration`](config/overview.md).
|
By default, `installApp()` with no params will install the app file defined in the current [`configuration`](../config/overview.md).
|
||||||
|
|
||||||
To install another app, specify its path
|
To install another app, specify its path
|
||||||
|
|
||||||
@@ -319,7 +319,7 @@ await device.installApp('path/to/other/app');
|
|||||||
|
|
||||||
### `device.uninstallApp()`
|
### `device.uninstallApp()`
|
||||||
|
|
||||||
By default, `uninstallApp()` with no params will uninstall the app defined in the current [`configuration`](config/overview.md).
|
By default, `uninstallApp()` with no params will uninstall the app defined in the current [`configuration`](../config/overview.md).
|
||||||
|
|
||||||
To uninstall another app, specify its bundle id
|
To uninstall another app, specify its bundle id
|
||||||
|
|
||||||
|
|||||||
+18
-18
@@ -1,10 +1,10 @@
|
|||||||
# Expect
|
# Expect
|
||||||
|
|
||||||
Detox uses [matchers](api/matchers.md) to match UI elements in your app and expectations to verify those elements are in the expected state.
|
Detox uses [matchers](matchers.md) to match UI elements in your app and expectations to verify those elements are in the expected state.
|
||||||
|
|
||||||
Use [actions](api/actions.md) to simulate use interaction with elements.
|
Use [actions](actions.md) to simulate use interaction with elements.
|
||||||
|
|
||||||
### Methods
|
## Methods
|
||||||
|
|
||||||
- [`.toBeVisible()`](#tobevisible)
|
- [`.toBeVisible()`](#tobevisible)
|
||||||
- [`.toExist()`](#toexist)
|
- [`.toExist()`](#toexist)
|
||||||
@@ -18,7 +18,7 @@ Use [actions](api/actions.md) to simulate use interaction with elements.
|
|||||||
- [`.not`](#not)
|
- [`.not`](#not)
|
||||||
- [`.withTimeout()`](#withtimeouttimeout)
|
- [`.withTimeout()`](#withtimeouttimeout)
|
||||||
|
|
||||||
#### `toBeVisible()`
|
### `toBeVisible()`
|
||||||
|
|
||||||
Expects the view to be at least N% visible on the screen.
|
Expects the view to be at least N% visible on the screen.
|
||||||
Accepts an optional parameter of percent threshold of element visibility, integer ranging from 1 to 100, that determines whether the element is visible or not. If no number is provided then defaults to 75%.
|
Accepts an optional parameter of percent threshold of element visibility, integer ranging from 1 to 100, that determines whether the element is visible or not. If no number is provided then defaults to 75%.
|
||||||
@@ -32,7 +32,7 @@ await expect(element(by.id('UniqueId203'))).toBeVisible();
|
|||||||
await expect(element(by.id('UniqueId204'))).toBeVisible(35);
|
await expect(element(by.id('UniqueId204'))).toBeVisible(35);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toExist()`
|
### `toExist()`
|
||||||
|
|
||||||
Expects the element to exist within the app’s current UI hierarchy.
|
Expects the element to exist within the app’s current UI hierarchy.
|
||||||
|
|
||||||
@@ -40,7 +40,7 @@ Expects the element to exist within the app’s current UI hierarchy.
|
|||||||
await expect(element(by.id('UniqueId205'))).toExist();
|
await expect(element(by.id('UniqueId205'))).toExist();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toBeFocused()`
|
### `toBeFocused()`
|
||||||
|
|
||||||
Expects the element to be the focused element.
|
Expects the element to be the focused element.
|
||||||
|
|
||||||
@@ -48,7 +48,7 @@ Expects the element to be the focused element.
|
|||||||
await expect(element(by.id('textFieldId'))).toBeFocused();
|
await expect(element(by.id('textFieldId'))).toBeFocused();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toHaveText(text)`
|
### `toHaveText(text)`
|
||||||
|
|
||||||
Expects the element to have the specified text.
|
Expects the element to have the specified text.
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ Expects the element to have the specified text.
|
|||||||
await expect(element(by.id('UniqueId204'))).toHaveText('I contain some text');
|
await expect(element(by.id('UniqueId204'))).toHaveText('I contain some text');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toHaveLabel(label)`
|
### `toHaveLabel(label)`
|
||||||
|
|
||||||
Expects the element to have the specified label as its accessibility label (iOS) or content description (Android). In React Native, this corresponds to the value in the [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) prop.
|
Expects the element to have the specified label as its accessibility label (iOS) or content description (Android). In React Native, this corresponds to the value in the [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) prop.
|
||||||
|
|
||||||
@@ -68,7 +68,7 @@ Note that there is an inconsistency between the implementation for accessibility
|
|||||||
await expect(element(by.id('UniqueId204'))).toHaveLabel('Done');
|
await expect(element(by.id('UniqueId204'))).toHaveLabel('Done');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toHaveId(id)`
|
### `toHaveId(id)`
|
||||||
|
|
||||||
Expects the element to have the specified accessibility identifier. In React Native, this corresponds to the value in the [`testID`](https://reactnative.dev/docs/view.html#testid) prop.
|
Expects the element to have the specified accessibility identifier. In React Native, this corresponds to the value in the [`testID`](https://reactnative.dev/docs/view.html#testid) prop.
|
||||||
|
|
||||||
@@ -76,7 +76,7 @@ Expects the element to have the specified accessibility identifier. In React Nat
|
|||||||
await expect(element(by.text('I contain some text'))).toHaveId('UniqueId204');
|
await expect(element(by.text('I contain some text'))).toHaveId('UniqueId204');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toHaveValue(value)`
|
### `toHaveValue(value)`
|
||||||
|
|
||||||
Expects the element to have the specified accessibility value. In React Native, this corresponds to the value in the [`accessibilityValue`](https://reactnative.dev/docs/view.html#accessibilityvalue) prop.
|
Expects the element to have the specified accessibility value. In React Native, this corresponds to the value in the [`accessibilityValue`](https://reactnative.dev/docs/view.html#accessibilityvalue) prop.
|
||||||
|
|
||||||
@@ -84,7 +84,7 @@ Expects the element to have the specified accessibility value. In React Native,
|
|||||||
await expect(element(by.id('UniqueId533'))).toHaveValue('0');
|
await expect(element(by.id('UniqueId533'))).toHaveValue('0');
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toHaveSliderPosition(normalizedPosition, tolerance)`
|
### `toHaveSliderPosition(normalizedPosition, tolerance)`
|
||||||
|
|
||||||
Expects the slider element to have the specified normalized position (\[0, 1]), within the provided tolerance (optional).
|
Expects the slider element to have the specified normalized position (\[0, 1]), within the provided tolerance (optional).
|
||||||
|
|
||||||
@@ -93,7 +93,7 @@ await expect(element(by.id('slider'))).toHaveSliderPosition(0.75);
|
|||||||
await expect(element(by.id('slider'))).toHaveSliderPosition(0.3113, 0.00001);
|
await expect(element(by.id('slider'))).toHaveSliderPosition(0.3113, 0.00001);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toHaveToggleValue(value)`
|
### `toHaveToggleValue(value)`
|
||||||
|
|
||||||
Expects a toggle-able element (e.g. a Switch or a Check-Box) to be on/checked or off/unchecked. As a reference, in react-native, this is the [equivalent switch component](https://reactnative.dev/docs/switch).
|
Expects a toggle-able element (e.g. a Switch or a Check-Box) to be on/checked or off/unchecked. As a reference, in react-native, this is the [equivalent switch component](https://reactnative.dev/docs/switch).
|
||||||
|
|
||||||
@@ -102,7 +102,7 @@ await expect(element(by.id('switch'))).toHaveToggleValue(true);
|
|||||||
await expect(element(by.id('checkbox'))).toHaveToggleValue(false);
|
await expect(element(by.id('checkbox'))).toHaveToggleValue(false);
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `not`
|
### `not`
|
||||||
|
|
||||||
Negates the expectation.
|
Negates the expectation.
|
||||||
|
|
||||||
@@ -110,7 +110,7 @@ Negates the expectation.
|
|||||||
await expect(element(by.id('UniqueId533'))).not.toBeVisible();
|
await expect(element(by.id('UniqueId533'))).not.toBeVisible();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `withTimeout(timeout)`
|
### `withTimeout(timeout)`
|
||||||
|
|
||||||
Waits until the expectation is resolved for the specified amount of time. If timeout is reached before resolution, the expectation is failed.
|
Waits until the expectation is resolved for the specified amount of time. If timeout is reached before resolution, the expectation is failed.
|
||||||
|
|
||||||
@@ -120,13 +120,13 @@ Waits until the expectation is resolved for the specified amount of time. If tim
|
|||||||
await waitFor(element(by.id('UniqueId204'))).toBeVisible().withTimeout(2000);
|
await waitFor(element(by.id('UniqueId204'))).toBeVisible().withTimeout(2000);
|
||||||
```
|
```
|
||||||
|
|
||||||
### Deprecated Methods
|
## Deprecated Methods
|
||||||
|
|
||||||
- [`.toBeNotVisible()`](#tobenotvisible)
|
- [`.toBeNotVisible()`](#tobenotvisible)
|
||||||
- [`.toNotExist()`](#tonotexist)
|
- [`.toNotExist()`](#tonotexist)
|
||||||
- [`.toBeNotFocused()`](#tobenotfocused)
|
- [`.toBeNotFocused()`](#tobenotfocused)
|
||||||
|
|
||||||
#### `toBeNotVisible()`
|
### `toBeNotVisible()`
|
||||||
|
|
||||||
**Deprecated:** Use `.not.toBeVisible()` instead.
|
**Deprecated:** Use `.not.toBeVisible()` instead.
|
||||||
|
|
||||||
@@ -136,7 +136,7 @@ Expects the element to not be visible on screen.
|
|||||||
await expect(element(by.id('UniqueId205'))).toBeNotVisible();
|
await expect(element(by.id('UniqueId205'))).toBeNotVisible();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toNotExist()`
|
### `toNotExist()`
|
||||||
|
|
||||||
**Deprecated:** Use `.not.toExist()` instead.
|
**Deprecated:** Use `.not.toExist()` instead.
|
||||||
|
|
||||||
@@ -146,7 +146,7 @@ Expects the element to not exist within the app’s current UI hierarchy.
|
|||||||
await expect(element(by.id('RandomJunk959'))).toNotExist();
|
await expect(element(by.id('RandomJunk959'))).toNotExist();
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `toBeNotFocused()`
|
### `toBeNotFocused()`
|
||||||
|
|
||||||
**Deprecated:** Use `.not.toBeFocused()` instead.
|
**Deprecated:** Use `.not.toBeFocused()` instead.
|
||||||
|
|
||||||
|
|||||||
+26
-26
@@ -13,32 +13,32 @@ or if you are planning to integrate with a third-party test runner like
|
|||||||
|
|
||||||
## Main lifecycle
|
## Main lifecycle
|
||||||
|
|
||||||
### resolveConfig
|
### `resolveConfig`
|
||||||
|
|
||||||
Use with a caution, when you still have no config, yet need to avoid \[internals.init()]\[#init] call.
|
Use with a caution, when you still have no config, yet need to avoid \[internals.init()]\[#init] call.
|
||||||
|
|
||||||
You normally don't need it if you use Detox CLI (`detox test …`), but if you want to start tests
|
You normally don’t need it if you use Detox CLI (`detox test …`), but if you want to start tests
|
||||||
directly and you need to have the config resolved before \[internals.init()]\[#init] is called, this
|
directly and you need to have the config resolved before \[internals.init()]\[#init] is called, this
|
||||||
is the way to go.
|
is the way to go.
|
||||||
|
|
||||||
### getStatus
|
### `getStatus`
|
||||||
|
|
||||||
Returns a string (`inactive`, `init`, `active` or `cleanup`) depending on what's going on.
|
Returns a string (`inactive`, `init`, `active` or `cleanup`) depending on what’s going on.
|
||||||
|
|
||||||
### init
|
### `init`
|
||||||
|
|
||||||
This is the phase where Detox reads its configuration, starts a server.
|
This is the phase where Detox reads its configuration, starts a server.
|
||||||
|
|
||||||
### cleanup
|
### `cleanup`
|
||||||
|
|
||||||
The global cleanup phase should happen after all the tests have finished.
|
The global cleanup phase should happen after all the tests have finished.
|
||||||
This is the phase where the Detox server shuts down.
|
This is the phase where the Detox server shuts down.
|
||||||
|
|
||||||
### installWorker
|
### `installWorker`
|
||||||
|
|
||||||
This is the phase where Detox loads its expectation library and starts a device.
|
This is the phase where Detox loads its expectation library and starts a device.
|
||||||
|
|
||||||
### uninstallWorker
|
### `uninstallWorker`
|
||||||
|
|
||||||
Deallocates the device.
|
Deallocates the device.
|
||||||
|
|
||||||
@@ -48,18 +48,18 @@ Deallocates the device.
|
|||||||
|
|
||||||
The naming you can see adheres much to Jest Circus workflow:
|
The naming you can see adheres much to Jest Circus workflow:
|
||||||
|
|
||||||
- onRunStart
|
- `onRunStart`
|
||||||
- onRunDescribeStart
|
- `onRunDescribeStart`
|
||||||
- onTestStart
|
- `onTestStart`
|
||||||
- onHookStart
|
- `onHookStart`
|
||||||
- onHookFailure
|
- `onHookFailure`
|
||||||
- onHookSuccess
|
- `onHookSuccess`
|
||||||
- onTestFnStart
|
- `onTestFnStart`
|
||||||
- onTestFnFailure
|
- `onTestFnFailure`
|
||||||
- onTestFnSuccess
|
- `onTestFnSuccess`
|
||||||
- onTestDone
|
- `onTestDone`
|
||||||
- onRunDescribeFinish
|
- `onRunDescribeFinish`
|
||||||
- onRunFinish
|
- `onRunFinish`
|
||||||
|
|
||||||
### Reporting failed tests
|
### Reporting failed tests
|
||||||
|
|
||||||
@@ -80,12 +80,12 @@ It takes two arguments:
|
|||||||
|
|
||||||
### log
|
### log
|
||||||
|
|
||||||
### tracing.createEventStream()
|
### `tracing`
|
||||||
|
|
||||||
Creates a readable stream of the currently recorded events in
|
`tracing.createEventStream()` – creates a readable stream of the currently recorded events in
|
||||||
[Chrome Trace Event format](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU).
|
[Chrome Trace Event format](https://docs.google.com/document/d/1CvAClvFfyA5R-PhYUmn5OOQtYMH4h6I0nSsKchNAySU).
|
||||||
|
|
||||||
See also: [DurationBeginEvent], [DurationEndEvent], [InstantEvent].
|
See also: [`DurationBeginEvent`], [`DurationEndEvent`], [`InstantEvent`].
|
||||||
|
|
||||||
### worker
|
### worker
|
||||||
|
|
||||||
@@ -98,8 +98,8 @@ holds the device driver, websocket client, matchers, expectations, etc.
|
|||||||
|
|
||||||
[Vitest]: https://vitest.dev
|
[Vitest]: https://vitest.dev
|
||||||
|
|
||||||
[DurationBeginEvent]: https://wix-incubator.github.io/trace-event-lib/interfaces/DurationBeginEvent.html
|
[`DurationBeginEvent`]: https://wix-incubator.github.io/trace-event-lib/interfaces/DurationBeginEvent.html
|
||||||
|
|
||||||
[DurationEndEvent]: https://wix-incubator.github.io/trace-event-lib/interfaces/DurationEndEvent.html
|
[`DurationEndEvent`]: https://wix-incubator.github.io/trace-event-lib/interfaces/DurationEndEvent.html
|
||||||
|
|
||||||
[InstantEvent]: https://wix-incubator.github.io/trace-event-lib/interfaces/InstantEvent.html
|
[`InstantEvent`]: https://wix-incubator.github.io/trace-event-lib/interfaces/InstantEvent.html
|
||||||
|
|||||||
+12
-12
@@ -1,12 +1,12 @@
|
|||||||
# Matchers
|
# Matchers
|
||||||
|
|
||||||
Detox uses [matchers](api/matchers.md) to match UI elements in your app.
|
Detox uses [matchers](matchers.md) to match UI elements in your app.
|
||||||
|
|
||||||
Use [actions](api/actions.md) to simulate use interaction with elements and [expectations](api/expect.md) to verify element states.
|
Use [actions](actions.md) to simulate use interaction with elements and [expectations](expect.md) to verify element states.
|
||||||
|
|
||||||
**Note:** For best results, it is recommended to match elements by unique identifiers. Matching by text or labels can introduce test flakiness when your app’s text change or when changing your app’s localization.
|
**Note:** For best results, it is recommended to match elements by unique identifiers. Matching by text or labels can introduce test flakiness when your app’s text change or when changing your app’s localization.
|
||||||
|
|
||||||
### Methods
|
## Methods
|
||||||
|
|
||||||
- [`by.id()`](#byidid)
|
- [`by.id()`](#byidid)
|
||||||
- [`by.label()`](#bylabellabel)
|
- [`by.label()`](#bylabellabel)
|
||||||
@@ -18,7 +18,7 @@ Use [actions](api/actions.md) to simulate use interaction with elements and [exp
|
|||||||
- [`and()`](#andmatcher)
|
- [`and()`](#andmatcher)
|
||||||
- [`atIndex()`](#atindexindex)
|
- [`atIndex()`](#atindexindex)
|
||||||
|
|
||||||
#### `by.id(id)`
|
### `by.id(id)`
|
||||||
|
|
||||||
Match elements with the specified accessibility identifier. In React Native, this corresponds to the value in the [`testID`](https://reactnative.dev/docs/view.html#testid) prop.
|
Match elements with the specified accessibility identifier. In React Native, this corresponds to the value in the [`testID`](https://reactnative.dev/docs/view.html#testid) prop.
|
||||||
|
|
||||||
@@ -26,7 +26,7 @@ Match elements with the specified accessibility identifier. In React Native, thi
|
|||||||
element(by.id('tap_me'));
|
element(by.id('tap_me'));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `by.label(label)`
|
### `by.label(label)`
|
||||||
|
|
||||||
Match elements with the specified accessibility label (iOS) or content description (Android). In React Native, this corresponds to the value in the [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) prop.
|
Match elements with the specified accessibility label (iOS) or content description (Android). In React Native, this corresponds to the value in the [`accessibilityLabel`](https://reactnative.dev/docs/accessibility#accessibilitylabel) prop.
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ Match elements with the specified accessibility label (iOS) or content descripti
|
|||||||
element(by.label('Welcome'));
|
element(by.label('Welcome'));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `by.text(text)`
|
### `by.text(text)`
|
||||||
|
|
||||||
Match elements with the specified text.
|
Match elements with the specified text.
|
||||||
|
|
||||||
@@ -42,7 +42,7 @@ Match elements with the specified text.
|
|||||||
element(by.text('Tap Me'));
|
element(by.text('Tap Me'));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `by.type(className)`
|
### `by.type(className)`
|
||||||
|
|
||||||
Matches elements whose class is, or inherits from, the specified class name. On Android, provide the class canonical name.
|
Matches elements whose class is, or inherits from, the specified class name. On Android, provide the class canonical name.
|
||||||
|
|
||||||
@@ -53,7 +53,7 @@ element(by.type('RCTImageView')); //iOS class name
|
|||||||
element(by.type('android.widget.ImageView')); //Android class canonical name
|
element(by.type('android.widget.ImageView')); //Android class canonical name
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `by.traits([traits])` **iOS Only**
|
### `by.traits([traits])` **iOS Only**
|
||||||
|
|
||||||
Matches elements by their [accessibility traits](https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619584-accessibilitytraits).
|
Matches elements by their [accessibility traits](https://developer.apple.com/documentation/uikit/uiaccessibilityelement/1619584-accessibilitytraits).
|
||||||
|
|
||||||
@@ -82,7 +82,7 @@ Currently supported values:
|
|||||||
element(by.traits(['button']));
|
element(by.traits(['button']));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `withAncestor(matcher)`
|
### `withAncestor(matcher)`
|
||||||
|
|
||||||
Matches elements with an ancestor that matches the specified matcher.
|
Matches elements with an ancestor that matches the specified matcher.
|
||||||
|
|
||||||
@@ -90,7 +90,7 @@ Matches elements with an ancestor that matches the specified matcher.
|
|||||||
element(by.id('child').withAncestor(by.id('parent')));
|
element(by.id('child').withAncestor(by.id('parent')));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `withDescendant(matcher)`
|
### `withDescendant(matcher)`
|
||||||
|
|
||||||
Matches elements with at least one descendant that matches the specified matcher.
|
Matches elements with at least one descendant that matches the specified matcher.
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ Matches elements with at least one descendant that matches the specified matcher
|
|||||||
element(by.id('parent').withDescendant(by.id('child')));
|
element(by.id('parent').withDescendant(by.id('child')));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `and(matcher)`
|
### `and(matcher)`
|
||||||
|
|
||||||
Matches elements by combining several matchers together.
|
Matches elements by combining several matchers together.
|
||||||
|
|
||||||
@@ -106,7 +106,7 @@ Matches elements by combining several matchers together.
|
|||||||
element(by.id('uniqueId').and(by.text('some text')));
|
element(by.id('uniqueId').and(by.text('some text')));
|
||||||
```
|
```
|
||||||
|
|
||||||
#### `atIndex(index)`
|
### `atIndex(index)`
|
||||||
|
|
||||||
If a matcher resolves into multiple matched UI elements, you may specify which element to use by its index.
|
If a matcher resolves into multiple matched UI elements, you may specify which element to use by its index.
|
||||||
|
|
||||||
|
|||||||
@@ -20,7 +20,7 @@ While Detox technically supports Android devices and iOS simulators out of the b
|
|||||||
|
|
||||||
If your app targets a third-party platform, you may switch to use a [third-party driver](#how-to-use-a-third-party-driver) to run your tests on said platform. If one doesn’t already exist, you can [write your own](#Writing-a-new-third-party-driver).
|
If your app targets a third-party platform, you may switch to use a [third-party driver](#how-to-use-a-third-party-driver) to run your tests on said platform. If one doesn’t already exist, you can [write your own](#Writing-a-new-third-party-driver).
|
||||||
|
|
||||||
### How to Use a Third-party Driver
|
## How to Use a Third-party Driver
|
||||||
|
|
||||||
Check to see if a [third-party driver](#existing-third-party-drivers) already exists for the platform you wish to target. Mostly likely, the driver will have setup instructions.
|
Check to see if a [third-party driver](#existing-third-party-drivers) already exists for the platform you wish to target. Mostly likely, the driver will have setup instructions.
|
||||||
|
|
||||||
@@ -49,9 +49,9 @@ Overall the setup for any third party driver is fairly simple.
|
|||||||
detox test --configuration thirdparty.driver.config
|
detox test --configuration thirdparty.driver.config
|
||||||
```
|
```
|
||||||
|
|
||||||
### Writing a New Third-party Driver
|
## Writing a New Third-party Driver
|
||||||
|
|
||||||
#### Anatomy of the Drivers
|
### Anatomy of the Drivers
|
||||||
|
|
||||||
The architecture of a driver is split into a few different pieces; Understanding the [overall architecture of Detox](how-detox-works.md#Architecture) will help with this section.
|
The architecture of a driver is split into a few different pieces; Understanding the [overall architecture of Detox](how-detox-works.md#Architecture) will help with this section.
|
||||||
|
|
||||||
@@ -69,7 +69,7 @@ _The component running on the device being tested, injected into the test app:_
|
|||||||
back of whether each step of your test succeeds or fails. Typically, a device client will use an underlying library specific
|
back of whether each step of your test succeeds or fails. Typically, a device client will use an underlying library specific
|
||||||
to the platform at hand to implement the expectations.
|
to the platform at hand to implement the expectations.
|
||||||
|
|
||||||
#### Implementation Details
|
### Implementation Details
|
||||||
|
|
||||||
In order to introduce a third-party Driver, there is a set of core classes you must implement - each responsible for a different Detox concern:
|
In order to introduce a third-party Driver, there is a set of core classes you must implement - each responsible for a different Detox concern:
|
||||||
|
|
||||||
@@ -135,6 +135,6 @@ class MyExpect {
|
|||||||
module.exports = MyNewDriver;
|
module.exports = MyNewDriver;
|
||||||
```
|
```
|
||||||
|
|
||||||
### Existing Third-party Drivers
|
## Existing Third-party Drivers
|
||||||
|
|
||||||
- [detox-puppeteer](https://github.com/ouihealth/detox-puppeteer)
|
- [detox-puppeteer](https://github.com/ouihealth/detox-puppeteer)
|
||||||
|
|||||||
+2
-2
@@ -28,7 +28,7 @@ The format of Detox config allows you to define inside it multiple app configs i
|
|||||||
An app config can have the following params:
|
An app config can have the following params:
|
||||||
|
|
||||||
| Configuration Params | Details |
|
| Configuration Params | Details |
|
||||||
| -------------------- |-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------|
|
| -------------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||||
| `type` | Mandatory property to discern app types: `ios.app`, `android.apk`. |
|
| `type` | Mandatory property to discern app types: `ios.app`, `android.apk`. |
|
||||||
| `name` | Use only when working with multiple apps within the same configuration. See an example below. |
|
| `name` | Use only when working with multiple apps within the same configuration. See an example below. |
|
||||||
| `binaryPath` | Relative path to the ipa/app/apk due to be tested (make sure you build the app in a project relative path) |
|
| `binaryPath` | Relative path to the ipa/app/apk due to be tested (make sure you build the app in a project relative path) |
|
||||||
@@ -61,7 +61,7 @@ To work with multiple apps within the same configuration you should be giving ea
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
After that, you can change the current app in your tests via [device API](api/device.md):
|
After that, you can change the current app in your tests via [device API](../api/device.md):
|
||||||
|
|
||||||
```js
|
```js
|
||||||
await device.selectApp('driver');
|
await device.selectApp('driver');
|
||||||
|
|||||||
+17
-17
@@ -74,20 +74,20 @@ There is also a shortcut to disable artifacts for a specific configuration:
|
|||||||
|
|
||||||
Artifacts are various recordings during tests including, but not limited to, device logs, device screenshots and screen recordings (videos).
|
Artifacts are various recordings during tests including, but not limited to, device logs, device screenshots and screen recordings (videos).
|
||||||
|
|
||||||
### Enabling Artifacts
|
## Enabling Artifacts
|
||||||
|
|
||||||
Artifacts are disabled by default. To enable them, specify via **launch arguments** or a **configuration** object what artifacts you want to record.
|
Artifacts are disabled by default. To enable them, specify via **launch arguments** or a **configuration** object what artifacts you want to record.
|
||||||
|
|
||||||
#### Launch Arguments
|
### Launch Arguments
|
||||||
|
|
||||||
- To record `.log` files, add `--record-logs all` (or `--record-logs failing`, if you want to keep logs only for failing tests).
|
- To record `.log` files, add `--record-logs all` (or `--record-logs failing`, if you want to keep logs only for failing tests).
|
||||||
- To record `.mp4` test run videos, add `--record-videos all` (or `--record-videos failing`, if you want to keep video recordings only for failing tests).
|
- To record `.mp4` test run videos, add `--record-videos all` (or `--record-videos failing`, if you want to keep video recordings only for failing tests).
|
||||||
- To record `.dtxrec` (Detox Instruments recordings) for each test, add `--record-performance all`. To open those recordings, you’ll need [Detox Instruments](https://github.com/wix/DetoxInstruments). **NOTE:** only iOS is supported.
|
- To record `.dtxrec` (Detox Instruments recordings) for each test, add `--record-performance all`. To open those recordings, you’ll need [Detox Instruments](https://github.com/wix/DetoxInstruments). **NOTE:** only iOS is supported.
|
||||||
- To capture `.uihierarchy` snapshots (**iOS only, Xcode 12.0+**) on view action failures, add `--capture-view-hierarchy enabled`.
|
- To capture `.uihierarchy` snapshots (**iOS only, Xcode 12.0+**) on view action failures, add `--capture-view-hierarchy enabled`.
|
||||||
- To take `.png` screenshots before and after each test, add `--take-screenshots all` (or `--take-screenshots failing`, if you want to keep only screenshots of failing tests).\
|
- To take `.png` screenshots before and after each test, add `--take-screenshots all` (or `--take-screenshots failing`, if you want to keep only screenshots of failing tests).\
|
||||||
Alternatively, you might leverage the [device.takeScreenshot()](api/device.md#devicetakescreenshotname) API for manual control.
|
Alternatively, you might leverage the [device.takeScreenshot()](../api/device.md#devicetakescreenshotname) API for manual control.
|
||||||
|
|
||||||
##### Artifacts root directory
|
#### Artifacts root directory
|
||||||
|
|
||||||
- To change artifacts root directory location (by default it is `./artifacts`), add `--artifacts-location <path>`.\
|
- To change artifacts root directory location (by default it is `./artifacts`), add `--artifacts-location <path>`.\
|
||||||
**NOTE:** There is a slightly obscure convention. If you want to create automatically a subdirectory with timestamp and configuration name (to avoid file overwrites upon consequent reruns), specify a path to directory that does not end with a slash. Otherwise, if you want to put artifacts straight to the specified directory (in a case where you make a single run only, e.g. on CI), add a slash (or a backslash) to the end.
|
**NOTE:** There is a slightly obscure convention. If you want to create automatically a subdirectory with timestamp and configuration name (to avoid file overwrites upon consequent reruns), specify a path to directory that does not end with a slash. Otherwise, if you want to put artifacts straight to the specified directory (in a case where you make a single run only, e.g. on CI), add a slash (or a backslash) to the end.
|
||||||
@@ -97,7 +97,7 @@ detox test --artifacts-location /tmp/detox_artifacts # will also append /androi
|
|||||||
detox test --artifacts-location /tmp/detox_artifacts/ # won’t append anything, hereby treating it as a root
|
detox test --artifacts-location /tmp/detox_artifacts/ # won’t append anything, hereby treating it as a root
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Configuration Object
|
### Configuration Object
|
||||||
|
|
||||||
Detox artifacts can be configured in a more advanced way with the `artifacts` configuration in `package.json` (or `.detoxrc`):
|
Detox artifacts can be configured in a more advanced way with the `artifacts` configuration in `package.json` (or `.detoxrc`):
|
||||||
|
|
||||||
@@ -123,7 +123,7 @@ The `artifacts` object has the following properties:
|
|||||||
| pathBuilder | `"./e2e/config/pathbuilder.js"` | `undefined` | Path to a module that exports a custom `PathBuilder` [ᵃ](#path-builder) |
|
| pathBuilder | `"./e2e/config/pathbuilder.js"` | `undefined` | Path to a module that exports a custom `PathBuilder` [ᵃ](#path-builder) |
|
||||||
| plugins | `{ ... }` | ... see below | ... see below |
|
| plugins | `{ ... }` | ... see below | ... see below |
|
||||||
|
|
||||||
##### Path builder
|
#### Path builder
|
||||||
|
|
||||||
**ᵃ** `PathBuilder` should be either an _object_ with a method `buildPathForTestArtifact` or a _class_ — see the corresponding interfaces below:
|
**ᵃ** `PathBuilder` should be either an _object_ with a method `buildPathForTestArtifact` or a _class_ — see the corresponding interfaces below:
|
||||||
|
|
||||||
@@ -193,7 +193,7 @@ For more technical details, search for `ArtifactPathBuilder.js` in Detox source
|
|||||||
|
|
||||||
The further subsections describe the `plugins` object structure.
|
The further subsections describe the `plugins` object structure.
|
||||||
|
|
||||||
##### Screenshot Plugin
|
#### Screenshot Plugin
|
||||||
|
|
||||||
Below is a default screenshot plugin object configuration, which is loaded implicitly and corresponds to the `manual` preset:
|
Below is a default screenshot plugin object configuration, which is loaded implicitly and corresponds to the `manual` preset:
|
||||||
|
|
||||||
@@ -250,23 +250,23 @@ Hence, for example, if you wish to enable only `testDone` screenshots and leave
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
##### Video Plugin
|
#### Video Plugin
|
||||||
|
|
||||||
To be done. See meanwhile the example in [artifacts configuration section](#artifacts-configuration).
|
To be done. See meanwhile the example [above](#artifacts).
|
||||||
|
|
||||||
##### Log Plugin
|
#### Log Plugin
|
||||||
|
|
||||||
To be done. See meanwhile the example in [artifacts configuration section](#artifacts-configuration).
|
To be done. See meanwhile the example [above](#artifacts).
|
||||||
|
|
||||||
##### Instruments Plugin
|
#### Instruments Plugin
|
||||||
|
|
||||||
To be done. See meanwhile the example in [artifacts configuration section](#artifacts-configuration).
|
To be done. See meanwhile the example [above](#artifacts).
|
||||||
|
|
||||||
##### UI hierarchy Plugin
|
#### UI hierarchy Plugin
|
||||||
|
|
||||||
To be done. See meanwhile the example in [artifacts configuration section](#artifacts-configuration).
|
To be done. See meanwhile the example [above](#artifacts).
|
||||||
|
|
||||||
### Artifacts Structure
|
## Artifacts Structure
|
||||||
|
|
||||||
1. **Artifacts root folder** is created per detox test run. If, for instance,`--artifacts-location /tmp` is used with `--configuration ios.sim.release` configuration on 14th June 2018 at 11:02:11 GMT+02, then the folder `/tmp/ios.sim.release.2018-06-14 09:02:11Z` is created.
|
1. **Artifacts root folder** is created per detox test run. If, for instance,`--artifacts-location /tmp` is used with `--configuration ios.sim.release` configuration on 14th June 2018 at 11:02:11 GMT+02, then the folder `/tmp/ios.sim.release.2018-06-14 09:02:11Z` is created.
|
||||||
|
|
||||||
@@ -287,7 +287,7 @@ To be done. See meanwhile the example in [artifacts configuration section](#arti
|
|||||||
afterEach.png
|
afterEach.png
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Example of the structure
|
### Example of the structure
|
||||||
|
|
||||||
```plain text
|
```plain text
|
||||||
artifacts/android.emu.release.2018-06-12 06:36:18Z/startup.log
|
artifacts/android.emu.release.2018-06-12 06:36:18Z/startup.log
|
||||||
|
|||||||
@@ -1,11 +1,11 @@
|
|||||||
# Logger
|
# Logger
|
||||||
|
|
||||||
## level
|
## `level`
|
||||||
|
|
||||||
default level
|
default level
|
||||||
|
|
||||||
## overrideConsole
|
## `overrideConsole`
|
||||||
|
|
||||||
## options
|
## `options`
|
||||||
|
|
||||||
TODO: bunyan options
|
TODO: bunyan options
|
||||||
|
|||||||
@@ -127,7 +127,7 @@ Note: If there is only one configuration in `configurations`, Detox will default
|
|||||||
}
|
}
|
||||||
```
|
```
|
||||||
|
|
||||||
If you have multiple configurations, you'll have to append `-c <configurationName>` to every invocation of
|
If you have multiple configurations, you’ll have to append `-c <configurationName>` to every invocation of
|
||||||
`detox build` and `detox test` CLI, e.g.:
|
`detox build` and `detox test` CLI, e.g.:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -135,7 +135,7 @@ detox build -c ios.sim.debug
|
|||||||
detox test -c ios.sim.debug
|
detox test -c ios.sim.debug
|
||||||
```
|
```
|
||||||
|
|
||||||
If this is inconvenient, and you can have some configuration as a default choice, there's a property for that:
|
If this is inconvenient, and you can have some configuration as a default choice, there’s a property for that:
|
||||||
|
|
||||||
```diff
|
```diff
|
||||||
+"selectedConfiguration": "ios.sim.debug",
|
+"selectedConfiguration": "ios.sim.debug",
|
||||||
@@ -146,5 +146,5 @@ If this is inconvenient, and you can have some configuration as a default choice
|
|||||||
},
|
},
|
||||||
```
|
```
|
||||||
|
|
||||||
Obviously, if you have only one configuration, there's no need to specify its name, just use `detox build` and
|
Obviously, if you have only one configuration, there’s no need to specify its name, just use `detox build` and
|
||||||
`detox test` as-is.
|
`detox test` as-is.
|
||||||
|
|||||||
@@ -36,7 +36,7 @@ function expectBitmapsToBeEqual(imagePath, expectedImagePath) {
|
|||||||
|
|
||||||
**Important:** The recommended, more practical way of doing this, is by utilizing more advanced 3rd-party image snapshotting & comparison tools such as [Applitools](https://applitools.com).
|
**Important:** The recommended, more practical way of doing this, is by utilizing more advanced 3rd-party image snapshotting & comparison tools such as [Applitools](https://applitools.com).
|
||||||
|
|
||||||
### Device-level Screenshots
|
## Device-level Screenshots
|
||||||
|
|
||||||
Taking a screenshot of the entire screen can be done using a device-level API:
|
Taking a screenshot of the entire screen can be done using a device-level API:
|
||||||
|
|
||||||
@@ -56,7 +56,7 @@ Important: The returned path is guaranteed to be valid only during the test exec
|
|||||||
|
|
||||||
`name (optional)` - Name of the final image-file to store as the artifact. For example, setting `name` to `opened general section` would result in an artifact file named `opened general section.png`. In case the name isn’t provided, Detox would self-generate a random, distinct name, instead (though not a very descriptive one).
|
`name (optional)` - Name of the final image-file to store as the artifact. For example, setting `name` to `opened general section` would result in an artifact file named `opened general section.png`. In case the name isn’t provided, Detox would self-generate a random, distinct name, instead (though not a very descriptive one).
|
||||||
|
|
||||||
#### Artifacts Management
|
### Artifacts Management
|
||||||
|
|
||||||
Means of creation of the final image as an artifact is tightly connected to the `--take-screenshots` argument to Detox CLI:
|
Means of creation of the final image as an artifact is tightly connected to the `--take-screenshots` argument to Detox CLI:
|
||||||
|
|
||||||
@@ -65,7 +65,7 @@ Means of creation of the final image as an artifact is tightly connected to the
|
|||||||
- In the other modes (`manual` and `all`), if the test passes, the screenshot will be put to `<artifacts-location>/✓ Members area should greet the member with an announcement/opened general section.png`.
|
- In the other modes (`manual` and `all`), if the test passes, the screenshot will be put to `<artifacts-location>/✓ Members area should greet the member with an announcement/opened general section.png`.
|
||||||
- In the other modes (`manual` and `all`), if the test fails, the screenshot will be put to `<artifacts-location>/✗ Members area should greet the member with an announcement/opened general section.png`.
|
- In the other modes (`manual` and `all`), if the test fails, the screenshot will be put to `<artifacts-location>/✗ Members area should greet the member with an announcement/opened general section.png`.
|
||||||
|
|
||||||
#### Caveats
|
### Caveats
|
||||||
|
|
||||||
This API well-captures all elements, although alongside surrounding "visual noise" such as the navigation bar, as can be seen in the image below:
|
This API well-captures all elements, although alongside surrounding "visual noise" such as the navigation bar, as can be seen in the image below:
|
||||||
|
|
||||||
@@ -98,7 +98,7 @@ async function setDemoMode() {
|
|||||||
|
|
||||||
> Note: This script implicitly assumes only one device is used, as device ID isn’t specified anywhere (e.g. with `adb -s <id>`).
|
> Note: This script implicitly assumes only one device is used, as device ID isn’t specified anywhere (e.g. with `adb -s <id>`).
|
||||||
|
|
||||||
### Element-level Screenshots
|
## Element-level Screenshots
|
||||||
|
|
||||||
Taking a screenshot of a specific element can be simply done using an API similar to other element-interaction Detox APIs:
|
Taking a screenshot of a specific element can be simply done using an API similar to other element-interaction Detox APIs:
|
||||||
|
|
||||||
@@ -114,7 +114,7 @@ In this example, the image-file specified by `imagePath` will hold the visual co
|
|||||||
|
|
||||||
Meaning, assuming `announcementsRoot` has been specified over some ancestor view which has both the `Announcement` title _and_ the card as its direct or indirect children, the result would include both. That, in turns, also includes the card’s children, such as the avatar, welcome text, etc.
|
Meaning, assuming `announcementsRoot` has been specified over some ancestor view which has both the `Announcement` title _and_ the card as its direct or indirect children, the result would include both. That, in turns, also includes the card’s children, such as the avatar, welcome text, etc.
|
||||||
|
|
||||||
#### Caveats of this approach
|
### Caveats of this approach
|
||||||
|
|
||||||
Focusing on specific elements, this approach is key to more stable comparisons, and hence more stable tests, over time. However, inspecting less content evidently means protecting against less bugs. For example, In a screen where the element in question is partly obstructed by other elements drawn on the screen, the image created by `takeScreenshot()` will successfully hold all of it’s content, nonetheless.
|
Focusing on specific elements, this approach is key to more stable comparisons, and hence more stable tests, over time. However, inspecting less content evidently means protecting against less bugs. For example, In a screen where the element in question is partly obstructed by other elements drawn on the screen, the image created by `takeScreenshot()` will successfully hold all of it’s content, nonetheless.
|
||||||
|
|
||||||
|
|||||||
@@ -7,6 +7,7 @@ import ConfigIOS from './partials/_debugging-native-code-config-ios.mdx';
|
|||||||
import ConfigAndroid from './partials/_debugging-native-code-config-android.mdx';
|
import ConfigAndroid from './partials/_debugging-native-code-config-android.mdx';
|
||||||
import RunIos from './partials/_debugging-native-code-run-ios.mdx';
|
import RunIos from './partials/_debugging-native-code-run-ios.mdx';
|
||||||
import RunAndroid from './partials/_debugging-native-code-run-android.mdx';
|
import RunAndroid from './partials/_debugging-native-code-run-android.mdx';
|
||||||
|
import TroubleshootingAndroid from './partials/_debugging-native-code-troubleshooting-android.mdx';
|
||||||
|
|
||||||
# Debugging
|
# Debugging
|
||||||
|
|
||||||
@@ -166,3 +167,13 @@ Detox stops instead and prompts you to launch the app from the IDE:
|
|||||||
</TabItem>
|
</TabItem>
|
||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
|
### Troubleshooting
|
||||||
|
|
||||||
|
<Tabs groupId="mobileOs">
|
||||||
|
<TabItem value="iOS" label="iOS">
|
||||||
|
<>There are no known issues at the moment. Check out <b>Android</b> tab if you need some.</>
|
||||||
|
</TabItem>
|
||||||
|
<TabItem value="Android" label="Android">
|
||||||
|
<TroubleshootingAndroid />
|
||||||
|
</TabItem>
|
||||||
|
</Tabs>
|
||||||
|
|||||||
@@ -95,7 +95,7 @@ Make sure to periodically update your version of `applesimutils` to the latest v
|
|||||||
</Tabs>
|
</Tabs>
|
||||||
|
|
||||||
```bash npm2yarn
|
```bash npm2yarn
|
||||||
npm install detox --save-dev
|
npm install detox@20.0.10-prerelease.0 --save-dev
|
||||||
```
|
```
|
||||||
|
|
||||||
The next step would be to **install a test runner**. Out of the box, Detox offers you first-class integration
|
The next step would be to **install a test runner**. Out of the box, Detox offers you first-class integration
|
||||||
|
|||||||
@@ -33,24 +33,3 @@ in your breakpoint.
|
|||||||

|

|
||||||
|
|
||||||
Happy debugging!
|
Happy debugging!
|
||||||
|
|
||||||
P.S. If you see this timeout error too often while debugging:
|
|
||||||
|
|
||||||
```plain text
|
|
||||||
Waited for the new RN-context for too long! (60 seconds)
|
|
||||||
If you think that’s not long enough, consider applying a custom Detox runtime-config in DetoxTest.runTests().
|
|
||||||
```
|
|
||||||
|
|
||||||
you can temporarily hack the timeout here:
|
|
||||||
|
|
||||||
```diff title="detox/android/detox/src/main/java/com/wix/detox/config/DetoxConfig.kt"
|
|
||||||
package com.wix.detox.config
|
|
||||||
|
|
||||||
class DetoxConfig {
|
|
||||||
@JvmField var idlePolicyConfig: DetoxIdlePolicyConfig = DetoxIdlePolicyConfig()
|
|
||||||
- @JvmField var rnContextLoadTimeoutSec = 60
|
|
||||||
+ @JvmField var rnContextLoadTimeoutSec = Int.MAX_VALUE
|
|
||||||
|
|
||||||
fun apply() {
|
|
||||||
idlePolicyConfig.apply()
|
|
||||||
```
|
|
||||||
|
|||||||
@@ -0,0 +1,38 @@
|
|||||||
|
Here are some known issues you can solve on your own:
|
||||||
|
|
||||||
|
1. **DetoxWSClient: Retrying... At connectToServer**
|
||||||
|
|
||||||
|
```plain text
|
||||||
|
I/DetoxWSClient: At connectToServer
|
||||||
|
D/DetoxWSClient: Retrying...
|
||||||
|
```
|
||||||
|
|
||||||
|
If you see the repeatedly printed messages like above in Android application logs, it's likely
|
||||||
|
that your port is not reversed. Assuming you're following the tutorial and `detoxServer` address
|
||||||
|
is `ws://localhost:8099` (if not – check what Detox prints you), reverse the port on your device
|
||||||
|
using ADB:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
adb reverse tcp:8099 tcp:8099
|
||||||
|
```
|
||||||
|
|
||||||
|
1. **Waited for the new RN-context for too long!**
|
||||||
|
|
||||||
|
```plain text
|
||||||
|
Waited for the new RN-context for too long! (60 seconds)
|
||||||
|
If you think that’s not long enough, consider applying a custom Detox runtime-config in DetoxTest.runTests().
|
||||||
|
```
|
||||||
|
|
||||||
|
If you see an error like above, you can patch Detox code to disable the timeout here:
|
||||||
|
|
||||||
|
```diff title="detox/android/detox/src/main/java/com/wix/detox/config/DetoxConfig.kt"
|
||||||
|
package com.wix.detox.config
|
||||||
|
|
||||||
|
class DetoxConfig {
|
||||||
|
@JvmField var idlePolicyConfig: DetoxIdlePolicyConfig = DetoxIdlePolicyConfig()
|
||||||
|
- @JvmField var rnContextLoadTimeoutSec = 60
|
||||||
|
+ @JvmField var rnContextLoadTimeoutSec = Int.MAX_VALUE
|
||||||
|
|
||||||
|
fun apply() {
|
||||||
|
idlePolicyConfig.apply()
|
||||||
|
```
|
||||||
@@ -1,3 +1,5 @@
|
|||||||
|
<!-- markdownlint-configure-file { "first-line-h1": 0 } -->
|
||||||
|
|
||||||
:::caution Note
|
:::caution Note
|
||||||
|
|
||||||
Expo support with Detox is entirely a community driven effort. We have no specific support in Detox for Expo applications (ejected or otherwise).
|
Expo support with Detox is entirely a community driven effort. We have no specific support in Detox for Expo applications (ejected or otherwise).
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ Running Detox on CI is not that different from running it locally. There are two
|
|||||||
## Step 1: Prepare a Release Configuration for Your App
|
## Step 1: Prepare a Release Configuration for Your App
|
||||||
|
|
||||||
We will need to create a release app configuration for Detox – follow [the previous tutorial](building-with-detox.mdx)
|
We will need to create a release app configuration for Detox – follow [the previous tutorial](building-with-detox.mdx)
|
||||||
if you haven't completed it already.
|
if you haven’t completed it already.
|
||||||
|
|
||||||
## Step 2: Add `build` and `test` Commands to Your CI Script
|
## Step 2: Add `build` and `test` Commands to Your CI Script
|
||||||
|
|
||||||
|
|||||||
@@ -1,3 +1,3 @@
|
|||||||
## Native Android Demo Project
|
# Native Android Demo Project
|
||||||
|
|
||||||
This example project is broken and unmaintained indefinitely.
|
This example project is broken and unmaintained indefinitely.
|
||||||
|
|||||||
@@ -1,12 +1,10 @@
|
|||||||
## Pure Native iOS Demo Project
|
# Pure Native iOS Demo Project
|
||||||
|
|
||||||
### Environment
|
## Environment
|
||||||
|
|
||||||
#### Fundamentals
|
|
||||||
|
|
||||||
**IMPORTANT:** Get your environment properly set up, as explained in our [contribution guide](https://wix.github.io/docs/contributing).
|
**IMPORTANT:** Get your environment properly set up, as explained in our [contribution guide](https://wix.github.io/docs/contributing).
|
||||||
|
|
||||||
#### Step 1: Build the Demo Project
|
## Step 1: Build the Demo Project
|
||||||
|
|
||||||
- Build the demo project
|
- Build the demo project
|
||||||
|
|
||||||
@@ -14,7 +12,7 @@
|
|||||||
detox build --configuration ios.sim.release
|
detox build --configuration ios.sim.release
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Step 2: Run the E2E Tests
|
## Step 2: Run the E2E Tests
|
||||||
|
|
||||||
- Run tests on the demo project
|
- Run tests on the demo project
|
||||||
|
|
||||||
|
|||||||
@@ -1,10 +1,10 @@
|
|||||||
## React Native Demo Project
|
# React Native Demo Project
|
||||||
|
|
||||||
**IMPORTANT:** Get your environment properly set up, as explained in our [contribution guide](../../docs/Guide.Contributing.md).
|
**IMPORTANT:** Get your environment properly set up, as explained in our [contribution guide](../../docs/Guide.Contributing.md).
|
||||||
|
|
||||||
### To test Release build of your app
|
## To test Release build of your app
|
||||||
|
|
||||||
#### \[Release] Step 1: Build
|
### \[Release] Step 1: Build
|
||||||
|
|
||||||
Build the demo project:
|
Build the demo project:
|
||||||
|
|
||||||
@@ -12,7 +12,7 @@ Build the demo project:
|
|||||||
detox build --configuration ios.sim.release
|
detox build --configuration ios.sim.release
|
||||||
```
|
```
|
||||||
|
|
||||||
#### \[Release] Step 2: Test
|
### \[Release] Step 2: Test
|
||||||
|
|
||||||
Run tests on the demo project:
|
Run tests on the demo project:
|
||||||
|
|
||||||
@@ -22,9 +22,9 @@ detox test --configuration ios.sim.release
|
|||||||
|
|
||||||
This action will open a new simulator and run the tests on it.
|
This action will open a new simulator and run the tests on it.
|
||||||
|
|
||||||
### To test Debug build of your app
|
## To test Debug build of your app
|
||||||
|
|
||||||
#### \[Debug] Step 1: Build
|
### \[Debug] Step 1: Build
|
||||||
|
|
||||||
Build the demo project:
|
Build the demo project:
|
||||||
|
|
||||||
@@ -32,7 +32,7 @@ Build the demo project:
|
|||||||
detox build --configuration ios.sim.debug
|
detox build --configuration ios.sim.debug
|
||||||
```
|
```
|
||||||
|
|
||||||
#### \[Debug] Step 2: Test
|
### \[Debug] Step 2: Test
|
||||||
|
|
||||||
1. Start react-native packager:
|
1. Start react-native packager:
|
||||||
|
|
||||||
|
|||||||
@@ -1,20 +1,20 @@
|
|||||||
## React Native Demo Project
|
# React Native Demo Project
|
||||||
|
|
||||||
### Environment
|
## Environment
|
||||||
|
|
||||||
#### Fundamentals
|
### Fundamentals
|
||||||
|
|
||||||
**IMPORTANT:** Get your environment properly set up, as explained in our [contribution guide](../../docs/Guide.Contributing.md).
|
**IMPORTANT:** Get your environment properly set up, as explained in our [contribution guide](../../docs/Guide.Contributing.md).
|
||||||
|
|
||||||
#### Execution Target
|
### Execution Target
|
||||||
|
|
||||||
Be sure to set up either an iOS simulator or a proper Android AVD emulator matching the Detox configurations of the project (`devices` section of the `detox.config.js` file).
|
Be sure to set up either an iOS simulator or a proper Android AVD emulator matching the Detox configurations of the project (`devices` section of the `detox.config.js` file).
|
||||||
|
|
||||||
### Running this project in Release mode
|
## Running this project in Release mode
|
||||||
|
|
||||||
#### Step 0: Prebuild
|
### Step 0: Prebuild
|
||||||
|
|
||||||
##### Android
|
#### Android
|
||||||
|
|
||||||
Prebuild Detox as an Android archive (a `.aar` file), locally:
|
Prebuild Detox as an Android archive (a `.aar` file), locally:
|
||||||
|
|
||||||
@@ -25,7 +25,7 @@ npm run build:android
|
|||||||
|
|
||||||
> On success, the result is a set of maven artifacts published in subdirectories under `detox/Detox-android/`. That includes `detox-999.999.999.aar` (i.e. Detox' native code packaged with the fake version `999.999.999`).
|
> On success, the result is a set of maven artifacts published in subdirectories under `detox/Detox-android/`. That includes `detox-999.999.999.aar` (i.e. Detox' native code packaged with the fake version `999.999.999`).
|
||||||
|
|
||||||
##### iOS
|
#### iOS
|
||||||
|
|
||||||
Install the necessary pods:
|
Install the necessary pods:
|
||||||
|
|
||||||
@@ -34,7 +34,7 @@ cd detox
|
|||||||
npm run podInstall:ios
|
npm run podInstall:ios
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Step 1: Build
|
### Step 1: Build
|
||||||
|
|
||||||
Build the demo project using one of the `npm` scripts.
|
Build the demo project using one of the `npm` scripts.
|
||||||
|
|
||||||
@@ -44,7 +44,7 @@ npm run build:ios-release
|
|||||||
npm run build:android-release
|
npm run build:android-release
|
||||||
```
|
```
|
||||||
|
|
||||||
#### Step 2: Execute Tests
|
### Step 2: Execute Tests
|
||||||
|
|
||||||
```sh
|
```sh
|
||||||
npm run test:ios-release
|
npm run test:ios-release
|
||||||
@@ -52,7 +52,7 @@ npm run test:ios-release
|
|||||||
npm run test:android-release
|
npm run test:android-release
|
||||||
```
|
```
|
||||||
|
|
||||||
### Running this project in Debug mode
|
## Running this project in Debug mode
|
||||||
|
|
||||||
The project’s tests can also be executed with the app running in debug mode (mainly, with JavaScript code getting bundled on-the-fly using the `metro` server).
|
The project’s tests can also be executed with the app running in debug mode (mainly, with JavaScript code getting bundled on-the-fly using the `metro` server).
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,4 @@
|
|||||||
## Generation
|
# Generation
|
||||||
|
|
||||||
This part of the repository aims to automate the adaption of the underlying testing frameworks.
|
This part of the repository aims to automate the adaption of the underlying testing frameworks.
|
||||||
For now, it only covers `EarlGrey`’s `GREYActions`.
|
For now, it only covers `EarlGrey`’s `GREYActions`.
|
||||||
@@ -7,13 +7,13 @@ We chose to check the generated files into version control to have them availabl
|
|||||||
|
|
||||||
To correlate changes to the generation with changes in the generated code, please make sure to run the build before every commit.
|
To correlate changes to the generation with changes in the generated code, please make sure to run the build before every commit.
|
||||||
|
|
||||||
### Development
|
## Development
|
||||||
|
|
||||||
- `npm install`
|
- `npm install`
|
||||||
- `npm run build` builds every file specified in the `index.js`
|
- `npm run build` builds every file specified in the `index.js`
|
||||||
- `npm test`
|
- `npm test`
|
||||||
|
|
||||||
### Testing
|
## Testing
|
||||||
|
|
||||||
- We test with integration level tests by having a fixture Objective-C file which we generate and import before the tests.
|
- We test with integration level tests by having a fixture Objective-C file which we generate and import before the tests.
|
||||||
- We only add unit tests for code that is used in production, e.g. helper functions.
|
- We only add unit tests for code that is used in production, e.g. helper functions.
|
||||||
@@ -21,7 +21,7 @@ To correlate changes to the generation with changes in the generated code, pleas
|
|||||||
- We decided to base our tests around snapshot tests with the goal to spot mistakes in the return values of the functions without over-specification.
|
- We decided to base our tests around snapshot tests with the goal to spot mistakes in the return values of the functions without over-specification.
|
||||||
- If you add functionality that affects the API surface of detox, please also make sure to include [End to End tests for it](../detox/test/e2e).
|
- If you add functionality that affects the API surface of detox, please also make sure to include [End to End tests for it](../detox/test/e2e).
|
||||||
|
|
||||||
### Resources
|
## Resources
|
||||||
|
|
||||||
Parsing, ASTs, and code generation are hard topics but don’t worry; we got your back.
|
Parsing, ASTs, and code generation are hard topics but don’t worry; we got your back.
|
||||||
Here are some resources that might come in handy:
|
Here are some resources that might come in handy:
|
||||||
|
|||||||
Reference in New Issue
Block a user