From 56682698a32199354ab057346f57d41639276093 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Fri, 23 Feb 2018 08:54:44 +0100 Subject: [PATCH 01/10] show version overview --- website/i18n/en.json | 2 +- website/pages/en/versions.js | 90 ++++++++++++++++++++++++++++++++++++ 2 files changed, 91 insertions(+), 1 deletion(-) create mode 100644 website/pages/en/versions.js diff --git a/website/i18n/en.json b/website/i18n/en.json index 9ce8b3e727..62db24c3bb 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -17,7 +17,7 @@ "APIRef.TestLifecycle": "Test Lifecycle", "APIRef.waitFor": "Manual Synchronization Using `waitFor`", "Guide.Contributing": "Contributing", - "Guide.DebuggingInXcode": "Debugging Apps in Xcode During a Test", + "Guide.DebuggingInXcode": "Guide.DebuggingInXcode", "Guide.DevelopingWhileWritingTests": "Developing Your App While Writing Tests", "Guide.Jest": "Jest", "Guide.Migration": "Migration Guide", diff --git a/website/pages/en/versions.js b/website/pages/en/versions.js new file mode 100644 index 0000000000..ddd6e53463 --- /dev/null +++ b/website/pages/en/versions.js @@ -0,0 +1,90 @@ +/** + * Copyright (c) 2017-present, Facebook, Inc. + * + * This source code is licensed under the MIT license found in the + * LICENSE file in the root directory of this source tree. + */ + +const React = require('react'); + +const CompLibrary = require('../../core/CompLibrary'); +const Container = CompLibrary.Container; +const GridBlock = CompLibrary.GridBlock; + +const CWD = process.cwd(); + +const siteConfig = require(CWD + '/siteConfig.js'); +const versions = require(CWD + '/versions.json'); +const githubReleaseUrl = version => `https://github.com/wix/detox/releases/tag/${version}`; +const documentationTarget = "Introduction.GettingStarted.html" + +function VersionLinks({version, isLatest = false}) { + const expandedVersion = version.replace('.X', '.0.0') + const isMaster = version === "master"; + + const docIdentifier = isMaster ? "next/" : (isLatest ? "" : version + "/"); + + return ( + + {version} + + Documentation + + + Release Notes + + + ) +} + +class Versions extends React.Component { + render() { + const latestVersion = versions[0]; + return ( +
+ +
+
+

{siteConfig.title + ' Versions'}

+
+ +

Current version (Stable)

+ + + + +
+

+ This is the version that is configured automatically when you + first install this project. +

+
+

Pre-release versions

+ + + + +
+

Other text describing this section.

+
+

Past Versions

+ + + {versions + .filter(version => version !== latestVersion) + .map(version => ) + } + +
+

+ You can find past versions of this project{' '} + on GitHub . +

+
+
+
+ ); + } +} + +module.exports = Versions; From b06bc48c2f3503b39212d9fe6f2f3bcad434b4b4 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Fri, 23 Feb 2018 08:55:11 +0100 Subject: [PATCH 02/10] add documentation for release 7.X --- .../version-7.X/APIRef.DetoxCLI.md | 98 ++++++++ .../version-7.X/APIRef.DetoxObjectAPI.md | 76 ++++++ .../version-7.X/APIRef.DeviceObjectAPI.md | 220 ++++++++++++++++++ .../version-7.X/APIRef.waitFor.md | 100 ++++++++ .../version-7.X/Guide.Contributing.md | 135 +++++++++++ .../versioned_docs/version-7.X/Guide.Jest.md | 76 ++++++ .../version-7.X/Introduction.Android.md | 137 +++++++++++ .../Introduction.GettingStarted.md | 154 ++++++++++++ website/versioned_docs/version-7.X/README.md | 57 +++++ website/versions.json | 1 + 10 files changed, 1054 insertions(+) create mode 100644 website/versioned_docs/version-7.X/APIRef.DetoxCLI.md create mode 100644 website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md create mode 100644 website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md create mode 100644 website/versioned_docs/version-7.X/APIRef.waitFor.md create mode 100644 website/versioned_docs/version-7.X/Guide.Contributing.md create mode 100644 website/versioned_docs/version-7.X/Guide.Jest.md create mode 100644 website/versioned_docs/version-7.X/Introduction.Android.md create mode 100644 website/versioned_docs/version-7.X/Introduction.GettingStarted.md create mode 100644 website/versioned_docs/version-7.X/README.md diff --git a/website/versioned_docs/version-7.X/APIRef.DetoxCLI.md b/website/versioned_docs/version-7.X/APIRef.DetoxCLI.md new file mode 100644 index 0000000000..158192493c --- /dev/null +++ b/website/versioned_docs/version-7.X/APIRef.DetoxCLI.md @@ -0,0 +1,98 @@ +--- +id: version-7.X-APIRef.DetoxCLI +title: Detox Command Line Tools (detox-cli) +original_id: APIRef.DetoxCLI +--- + +`detox-cli` lets you operate Detox from command line. + +## Installation +Install `detox-cli` globally via npm: + +```sh +npm install -g detox-cli +``` + +## Usage +```sh +detox [options] [command] +``` + +## Commands: +| Command | Description | +| --- | --- | +| [test](#test) | Initiating your test suite | +| [build](#build) | Run the command defined in `configuration.build` | +| [run-server](#run-server) | Starts a standalone detox server | +| [init](#init) | Create initial e2e tests folder | +| clean-framework-cache | Delete all compiled framework binaries from ~/Library/Detox, they will be rebuilt on 'npm install' or when running 'build-framework-cache' +| build-framework-cache | Build Detox.framework to ~/Library/Detox. The framework cache is specific for each combination of Xcode and Detox versions +| [help](#help) | Display help for specific command | + +## Options: + +| Options | Description | +| --- | --- | +| -h
--help | Output usage information | + +## Commands + +### test +Initiating your test suite + +`detox test [options]` + + + +| Option| Description | +| --- | --- | +| -h, --help | output usage information | +| -o, --runner-config \ | Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest | +| -l, --loglevel [value] | info, debug, verbose, silly, wss | +| -c, -configuration \ | Select a device configuration from your defined configurations,if not supplied, and there's only one configuration, detox will default to it | +| -r, --reuse | Reuse existing installed app (do not delete and re-tall) for a faster run. | +| -u, --cleanup | Shutdown simulator when test is over, useful for CI ipts, to make sure detox exists cleanly with no residue | +| -d, --debug-synchronization \ | When an action/expectation takes a significant amount time use this option to print device synchronization status. The status will be printed if the ion takes more than [value]ms to complete | +| -a, --artifacts-location \ | Artifacts destination path (currently contains only logs). For more details, please check the [Artifacts doc](APIRef.Artifacts.md#artifacts) | +|-p, --platform [ios/android] | Run platform specific tests. Runs tests with invert grep on `:platform:`, e.g test with substring `:ios:` in its name will not run when passing `--platform android` +|                  || + + + +### build +Run a command defined in 'configuration.build' + +`detox build [options]` + +| Option | Description | +| --- | --- | +| -h, --help | output usage information | +| -c, --configuration \ | Select a device configuration from your defined configurations,if not supplied, and there's only one configuration, detox will default to it | +|                  || + + +### run-server +Start a standalone detox server + +`detox run-server [options]` + +| Option | Description | +| --- | --- | +| -h, --help | output usage information | + + +### init +Create initial e2e tests folder + +`detox init [options` + +| Option | Description | +| --- | --- | +| -h, --help | output usage information | +| -r, --runner | Test runner (currently supports only `mocha`) | + +### help +Display help for a command + +`detox help [command]` + diff --git a/website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md b/website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md new file mode 100644 index 0000000000..5fdfae074a --- /dev/null +++ b/website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md @@ -0,0 +1,76 @@ +--- +id: version-7.X-APIRef.DetoxObjectAPI +title: The `detox` Object +original_id: APIRef.DetoxObjectAPI +--- + +`detox` is globally available in every test file, though currently it is only used in the setup/init file. + +>NOTE: detox is test runner independent, and we encourge you to choose your own test runner, but for the sake of demonstration we will use `mocha`'s syntax. + +### Methods + +- [`detox.init()`](#detox.init) +- [`detox.cleanup()`](#detox.cleanup) + +### `detox.init()` +The setup phase happens inside `detox.init()`. This is the phase where detox reads its configuration, starts a server, loads its expection library and starts a simulator. + +##### (if you're using mocha) In your `init.js` add: + +```js +const config = require('../package.json').detox; + +before(async () => { + await detox.init(config); +}); +``` + +##### Explicit imports during initialization +Detox exports `device `, `expect`, `element`, `by` and `waitFor` as globals by default, if you want to control their initialization manually, set init detox with `initGlobals` set to `false`. This is useful when during E2E tests you also need to run regular expectations in node. jest `Expect` for instance, will not be overriden by Detox when this option is used. + +```js +before(async () => { + await detox.init(config, {initGlobals: false}); +}); +``` + +Then import them manually: + +```js +const {device, expect, element, by, waitFor} = require('detox'); +``` + +Use [this example](../examples/demo-react-native/e2eExplicitRequire) for initial setup + + + +#### Controlling first app intialization +By default `await detox.init(config);` will launch the installed app. If you wish to control when your app is launched, add `{launchApp: false}` param to your init. + +```js +const config = require('../package.json').detox; + +before(async () => { + await detox.init(config, {launchApp: false}); +}); +``` + +>NOTE: Detox 6.X.X introduced a **breaking change** , setting `launchApp` to `false` by default. In order to prevent any breaking changes to your tests when you upgrade (and if you still would like `init` to launch the app for you) do the following: + +```js +before(async () => { + await detox.init(config, {launchApp: true}); +}); +``` + +### `detox.cleanup()` +The cleanup phase should happen after all the tests have finished. This is the phase where detox-server shuts down. The simulator will also shut itself down if `--cleanup` flag is added to `detox test` + +##### (if you're using mocha) In your `init.js` add: + +```js +after(async () => { + await detox.cleanup(); +}); +``` diff --git a/website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md b/website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md new file mode 100644 index 0000000000..2e7d9e9754 --- /dev/null +++ b/website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md @@ -0,0 +1,220 @@ +--- +id: version-7.X-APIRef.DeviceObjectAPI +title: The `device` Object +original_id: APIRef.DeviceObjectAPI +--- + +`device` is globally available in every test file, it enables control over the current attached device (currently only simulators are supported). + +### Methods + +- [`device.launchApp()`](#devicelaunchappparams) +- [`device.relaunchApp()` **Deprecated**](#devicerelaunchappparams) +- [`device.terminateApp()`](#deviceterminateapp) +- [`device.reloadReactNative()`](#devicereloadreactnative) +- [`device.sendToHome()`](#devicesendtohome) +- [`device.installApp()`](#deviceinstallapp) +- [`device.uninstallApp()`](#deviceuninstallapp) +- [`device.openURL(url)`](#deviceopenurlurl-sourceappoptional) +- [`device.sendUserNotification(params)`](#devicesendusernotificationparams) +- [`device.setOrientation(orientation)`](#devicesetorientationorientation) +- [`device.setLocation(lat, lon)`](#devicesetlocationlat-lon) +- [`device.setURLBlacklist([urls])`](#deviceseturlblacklisturls) +- [`device.enableSynchronization()`](#deviceenablesynchronization) +- [`device.disableSynchronization()`](#devicedisablesynchronization) +- [`device.resetContentAndSettings()`](#deviceresetcontentandsettings) +- [`device.getPlatform()`](#devicegetplatform) + +### `device.launchApp(params)` +Launch the app defined in the current [`configuration`](APIRef.Configuration.md). + +**Options:** + +##### 1. Restart the app +Terminate the app and launch it again. +If set to `false`, the simulator will try to bring app from background, if the app isn't running, it will launch a new instance. default is `false` + +```js +await device.launchApp({newInstance: true}); +``` + +##### 2. Set runtime permissions +Grant or deny runtime permissions for your application. + +```js +await device.launchApp({permissions: {calendar: 'YES'}}); +``` +Detox uses [AppleSimUtils](https://github.com/wix/AppleSimulatorUtils) on iOS to support this functionality. Read about the different types of permissions and how to set them in AppleSimUtils' Readme. +Check out Detox's [own test suite](../detox/test/e2e/l-permissions.js) + +##### 3. Launch from URL +Mock opening the app from URL to test your app's deep link handling mechanism. + +```js +await device.launchApp({url: url}); +``` +###### Mock opening from a URL when app is not running +```js +await device.launchApp({url: url, newInstance: true}); +``` +This will launch a new instance of the app and handle the deep link. + +###### Mock opening from a URL when app is in background + +```js +await device.launchApp({url: url, newInstance: false}); +``` +This will launch the app from background and handle the deep link. + +Read more in [Mocking Open From URL](APIRef.MockingOpenFromURL.md) section. + +##### 4. Launch from user notifications + +```js +await device.launchApp({userNotification: notification}); +``` + +###### Mock receiving a notifications when app is not running +```js +await device.launchApp({userNotification: notification, newInstance: true}); +``` +This will launch a new instance of the app and handle the notification. + +###### Mock receiving a notifications when app is in background + +```js +await device.launchApp({userNotification: notification, newInstance: false}); +``` +This will launch the app from background and handle the notification. + +Read more in [Mocking User Notifications](APIRef.MockingUserNotifications.md) section. + +##### 5. Launch into a fresh installation +A flag that enables relaunching into a fresh installation of the app (it will uninstall and install the binary again), default is `false`. + +```js +await device.launchApp({delete: true}); +``` + +##### 6. Additional launch arguments +Detox can start the app with additional launch arguments + +```js +await device.launchApp({launchArgs: {arg1: 1, arg2: "2"}}); +``` + +The added `launchArgs` will be passed through the launch command to the device and be accessible via `[[NSProcessInfo processInfo] arguments]` + +### `device.relaunchApp(params)` +**Deprecated** Use `device.launchApp(params)` instead. This method is now calling `launchApp({newInstance: true})` for backwards compatibility, it will be removed in Detox 6.X.X.
+Kill and relaunch the app defined in the current [`configuration`](APIRef.Configuration.md). + +### `device.terminateApp()` +By default, `terminateApp()` with no params will terminate the app file defined in the current [`configuration`](APIRef.Configuration.md). + +To terminate another app, specify its bundle id + +```js +await device.terminateApp('other.bundle.id'); +``` + +### `device.sendToHome()` +Send application to background by bringing `com.apple.springboard` to the foreground.
+Combining `sendToHome()` with `launchApp({newInstance: false})` will simulate app coming back from background.
+Check out Detox's [own test suite](../detox/test/e2e/f-simulator.js) + +```js +await device.sendToHome(); +await device.launchApp({newInstance: false}); +// app returned from background, do stuff +``` +Check out Detox's [own test suite](../detox/test/e2e/f-device.js) + +### `device.reloadReactNative()` +If this is a react native app, reload react native JS bundle. This action is much faster than `device.relaunchApp()`, and is recommended if you just need to reset your react native logic. + +### `device.installApp()` +By default, `installApp()` with no params will install the app file defined in the current [`configuration`](APIRef.Configuration.md). + +To install another app, specify its path + +```js +await device.installApp('path/to/other/app'); +``` + +### `device.uninstallApp()` +By default, `uninstallApp()` with no params will uninstall the app defined in the current [`configuration`](APIRef.Configuration.md). + +To uninstall another app, specify its bundle id + +```js +await device.installApp('other.bundle.id'); +``` + +### `device.openURL({url, sourceApp[optional]})` +Mock opening the app from URL. `sourceApp` is an optional parameter to specify source application bundle id.
+Read more in [Mocking Open From URL](APIRef.MockingOpenFromURL.md) section.
+Check out Detox's [own test suite](../detox/test/e2e/n-deep-links.js) + +### `device.sendUserNotification(params)` +Mock handling of received user notification when app is in foreground.
+Read more in [Mocking User Notifications](APIRef.MockingUserNotifications.md) section.
+Check out Detox's [own test suite](../detox/test/e2e/k-user-notifications.js) + +### `device.setOrientation(orientation)` +Takes `"portrait"` or `"landscape"` and rotates the device to the given orientation. +Currently only available in the iOS Simulator.
+Check out Detox's [own test suite](../detox/test/e2e/f-device.js) + +### `device.setLocation(lat, lon)` +>Note: `setLocation` is dependent on `fbsimctl`. if `fbsimctl` is not installed, the command will fail, asking for it to be installed. +Sets the simulator location to the given latitude and longitude. +```js +await device.setLocation(32.0853, 34.7818); +``` + +### `device.setURLBlacklist([urls])` + +Disable [EarlGrey's network synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#network) on preffered endpoints. Usful if you want to on skip over synchronizing on certain URLs. + +```js +await device.setURLBlacklist(['.*127.0.0.1.*']); +``` + +```js +await device.setURLBlacklist(['.*my.ignored.endpoint.*']); +``` + +### `device.enableSynchronization()` +Enable [EarlGrey's synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#synchronization +) (enabled by default). **This is being reset on every new instance of the app.** +```js +await device.enableSynchronization(); +``` + + +### `device.disableSynchronization()` +Disable [EarlGrey's synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#synchronization +) (enabled by default) **This is being reset on every new instance of the app.** + +```js +await device.disableSynchronization(); +``` + + +### `device.resetContentAndSettings()` +Resets the Simulator to clean state (like the Simulator > Reset Content and Settings... menu item), especially removing +previously set permissions. + +```js +await device.resetContentAndSettings(); +``` + +### `device.getPlatform()` +Returns the current device, `ios` or `android`. + +```js +if (device.getPlatform() === 'ios') { + await expect(loopSwitch).toHaveValue('1'); +} +``` diff --git a/website/versioned_docs/version-7.X/APIRef.waitFor.md b/website/versioned_docs/version-7.X/APIRef.waitFor.md new file mode 100644 index 0000000000..92213b1184 --- /dev/null +++ b/website/versioned_docs/version-7.X/APIRef.waitFor.md @@ -0,0 +1,100 @@ +--- +id: version-7.X-APIRef.waitFor +title: Manual Synchronization Using `waitFor` +original_id: APIRef.waitFor +--- + +In most cases, tests should be automatically synchronized with the app. When synchronization doesn't work, you have a fail-safe by using `waitFor`. This API polls using the given expectation continuously until the expectation is met. Use manual synchronization with `waitFor` only as a **last resort**. Polling for expectations isn't exactly a best practice. + +Test async code with waitFor.
+**Hang the test until an expectation is met.** + +### Methods + +- [`.toBeVisible()`](#tobevisible) +- [`.toBeNotVisible()`](#tobenotvisible) +- [`.toExist()`](#toexist) +- [`.toNotExist()`](#tonotexist) +- [`.toHaveText()`](#tohavetexttext) +- [`.toHaveValue()`](#tohavevaluevalue) +- [`.withTimeout()`](#withtimeoutmillis) +- [`.whileElement()`](#whileelementelement) + +>NOTE: Every `waitFor` call must set a timeout using `withTimeout()`. Calling `waitFor` without setting a timeout **will do nothing**. + +>NOTE: `waitFor` will not throw when reaching timeout, instead it will just continue to the next line. To make sure your tests work as you expect them to add `expect()` at the following line. + +### `toBeVisible()` +Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toBeVisible()`](APIRef.Expect.md#tobevisible)
+Wait for the view to be at least 75% visible. + +```js +await waitFor(element(by.id('UniqueId204'))).toBeVisible().withTimeout(2000); +await expect(element(by.id('UniqueId204'))).toBeVisible(); +``` + +### `toBeNotVisible()` +Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toBeNotVisible()`](APIRef.Expect.md#tobenotvisible)
+Wait for the view to not be visible. + +```js +await waitFor(element(by.id('UniqueId205'))).toBeNotVisible().withTimeout(2000); +await expect(element(by.id('UniqueId205'))).toBeNotVisible(); +``` + +### `toExist()` +Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toExist()`](APIRef.Expect.md#toexist)
+Wait for the view to exist in the UI hierarchy. + +```js +await waitFor(element(by.id('UniqueId205'))).toExist().withTimeout(2000); +await expect(element(by.id('UniqueId205'))).toExist(); +``` + +### `toNotExist()` +Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toNotExist()`](APIRef.Expect.md#tonotexist)
+Wait for the view to not exist in the UI hierarchy. + +```js +await waitFor(element(by.id('RandomJunk959'))).toNotExist().withTimeout(2000); +await expect(element(by.id('RandomJunk959'))).toNotExist(); +``` + +### `toHaveText(text)` +Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toHaveText(text)`](APIRef.Expect.md#tohavetexttext)
+- In React Native apps, expect UI component of type `` to have text. +- In native iOS apps, expect UI elements of type UIButton, UILabel, UITextField or UITextViewIn to have inputText with text. + +```js +await waitFor(element(by.id('UniqueId204'))).toHaveText('I contain some text').withTimeout(2000); +await expect(element(by.id('UniqueId204'))).toHaveText('I contain some text'); +``` + +### `toHaveValue(value)` +Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toHaveValue(value)`](APIRef.Expect.md#tohavevaluevalue)
+ +- In React Native apps, expect UI component to have [`testID`](https://facebook.github.io/react-native/docs/view.html#testid) with that id. +- In native iOS apps, expect UI element to have accesibilityIdentifier with that id. + +```js +await waitFor(element(by.id('uniqueId'))).toHaveValue('Some value').withTimeout(2000); +await expect(element(by.id('uniqueId'))).toHaveValue('Some value'); +``` + + +### `withTimeout(millis)` +Waits for the condition to be met until the specified time (millis) have elapsed. + +```js +await waitFor(element(by.id('UniqueId336'))).toExist().withTimeout(2000); +await expect(element(by.id('UniqueId336'))).toExist(); +``` + + +### `whileElement(element)` +Performs the action repeatedly on the element until an expectation is met. + +```js +await waitFor(element(by.text('Text5'))).toBeVisible().whileElement(by.id('ScrollView630')).scroll(50, 'down'); +await expect(element(by.text('Text5'))).toBeVisible(); +``` diff --git a/website/versioned_docs/version-7.X/Guide.Contributing.md b/website/versioned_docs/version-7.X/Guide.Contributing.md new file mode 100644 index 0000000000..fc8860ce16 --- /dev/null +++ b/website/versioned_docs/version-7.X/Guide.Contributing.md @@ -0,0 +1,135 @@ +--- +id: version-7.X-Guide.Contributing +title: Contributing +original_id: Guide.Contributing +--- + +## Prerequisites + +### Install `node` v7.6 or higher (to support async-await natively) + +``` +brew install node +``` + +### Install global node libraries `lerna` and `react-native-cli` + +```sh +npm install -g lerna +npm install -g react-native-cli +``` + +For all the internal projects (detox, detox-server, detox-cli, demos, test) `lerna` will create symbolic links in `node_modules` instead of `npm` copying the content of the projects. This way, any change you do on any code is there immediately. There is no need to update node modules or copy files between projects. + +### Install `xcpretty` + +```sh +gem install xcpretty +``` + +Alternatively, run `scripts/install.ios.sh` / `scripts/install.android.sh` to install all prerequisites. + +## Detox + +### Clone Detox and submodules + +```sh +git clone git@github.com:wix/detox.git +cd detox +git submodule update --init --recursive +``` +(this makes sure all git submodule dependencies are properly checked out) + +### Installing and linking internal projects + +```sh +scripts/bootstrap.sh +``` + +### Building + +```sh +lerna run build +``` + +### Testing + +### 1. Unit tests + +```sh +lerna run test +``` + +Detox JS code is 100% test covered and is set to break the build if coverage gets below, so make sure you run unit tests (`lerna run test`) locally before pushing. + +Alternatively, to run only the JS tests, run the following from the `detox/detox` directory: + +```sh +npm run unit +-or- +npm run unit:watch +``` + +#### How to read the coverage report +After running the tests, jest will create a coverage report. + +```sh +cd detox +open coverage/lcov-report/index.html +``` + +### 2. Running Detox e2e coverage tests +Detox has a suite of e2e tests to test its own API while developing (and for regression). The way we do is is by maintaining a special application that is "tested" against Detox's API, but essentially, it's the API that is tested, not the app. +To run the e2e tests, go to `detox/detox/test` + +```sh +cd detox/test +``` + + +```sh +npm run build +``` + +To run the e2e tests, after the application was built. + +#### iOS +```sh +npm run build:ios +npm run e2e:ios +``` + +#### Android +```sh +npm run build:android +npm run e2e:android +``` + +### 3. Android Native tests + +0. Install Java and Android SDK 25 +1. In `detox/android` run `./gradlew install` run + + ```sh + ./gradlew test + ``` + +### 4. Code Generation + +We are using a code generator based on `babel` and `objective-c-parser` to generate a Javascript Interface for `EarlGrey` (the testing library we use on iOS). +This interface allows us to call Objective-C methods through the WebSocket connection directly on the testing device. + +This approach is currently limited to `GREYActions`, but we plan on extending it to cover more functionality of `EarlGrey`. +You may see the generated files under [`detox/src/ios/earlgreyapi/`](../detox/src/ios/earlgreyapi). + +What happens under the hood can be seen in [`generation/`](../generation); it boils down to these steps for each input file: + +1. Convert Objective-C header file in a JSON Representation +2. Build an Abstract Syntax Tree: Create Class & for each method + 1. Check if the type can be expressed simpler (`NSString *` => `NSString`) + 2. Get the type checks for the arguments + 2. Get the return value + 4. Assemble type checks and return value to complete function +3. Generate the code for the syntax tree & add helpers + +If you would like to extend the code generation, please make sure to read the [`generation/README.md`](../generation#generation) diff --git a/website/versioned_docs/version-7.X/Guide.Jest.md b/website/versioned_docs/version-7.X/Guide.Jest.md new file mode 100644 index 0000000000..4cd9a5605d --- /dev/null +++ b/website/versioned_docs/version-7.X/Guide.Jest.md @@ -0,0 +1,76 @@ +--- +id: version-7.X-Guide.Jest +title: Jest +original_id: Guide.Jest +--- + +## Usage + +### 0. Use the [Getting Started](Introduction.GettingStarted.md) Guide to set up detox + +Except that you need to skip the install mocha step. + +### 1. Install Jest + +```sh +npm install --save-dev jest +``` + +### 2. Remove mocha specific files + +You should remove `e2e/mocha.opts`, you no longer need it. + +### 3. Replace generated detox setup file (e2e/init.js) + +```js +const detox = require('detox'); +const config = require('../package.json').detox; + +// Set the default test timeout of 120s +jest.setTimeout(120000); + +beforeAll(async () => { + await detox.init(config); +}); + +afterAll(async () => { + await detox.cleanup(); +}); +``` + +### 4. Configure Detox to run with Jest + +Add a Jest config file `e2e/config.json`: + +```json +{ + "setupTestFrameworkScriptFile" : "./init.js" +} +``` + + +In `package.json`: + +```json +"scripts": { + "test:e2e": "detox test -c ios.sim.debug", + "test:e2e:build": "detox build" +}, +"detox": { + "test-runner": "jest", + "runner-config": "e2e/config.json" + ... +} +``` + +### Writing Tests + +There are some things you should notice: + +- Don't worry about mocks being used, detox works on the compiled version of your app. +- Detox exposes it's primitives (`expect`, `device`, ...) globally, it will override Jest's global `expect` object. + +## How to run unit test and E2E tests in the same project + +- If you have a setup file for the unit tests pass `./jest/setup` implementation into your unit setup. +- Call your E2E tests using `detox-cli`: `detox test` diff --git a/website/versioned_docs/version-7.X/Introduction.Android.md b/website/versioned_docs/version-7.X/Introduction.Android.md new file mode 100644 index 0000000000..e063c9d8c9 --- /dev/null +++ b/website/versioned_docs/version-7.X/Introduction.Android.md @@ -0,0 +1,137 @@ +--- +id: version-7.X-Introduction.Android +title: Detox for Android +original_id: Introduction.Android +--- + +## Setup +Detox 7 was updated to support Android gradle plugin 3.0.0. This is a breaking change that makes it impossible to support previous Android gradle plugin versions. + +https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html + +For older Android gradle plugin support use `detox@6.x.x` instead ([previous setup guide here](https://github.com/wix/detox/blob/97654071573053def90e8207be8eba011408f977/docs/Introduction.Android.md)).
+**Detox 6 will not continue to be updated, to continue getting updates and features, update your Android gradle config and migrate to Detox 7.** + +### 1. Do the initial setup described in the Getting Started Guide + +- [Getting Started](Introduction.GettingStarted.md) + +### 2. Add Detox dependency to an Android project + +In `android/settings.gradle` add: + +```gradle +include ':detox' +project(':detox').projectDir = new File(rootProject.projectDir, '../node_modules/detox/android/detox') +``` + +In `android/app/build.gradle` add this to `defaultConfig` section: + +```gradle + defaultConfig { + ... + testBuildType System.getProperty('testBuildType', 'debug') //this will later be used to control the test apk build type + missingDimensionStrategy "minReactNative", "minReactNative46" //read note + testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" + ... + } +``` +Please be aware that the `minSdkVersion` needs to be at least 18. + +> ###### Choosing the right build type (in missingDimensionStrategy) +>Detox runs on multiple React Native versions, choose the correct build type to support the version you use.
+>**Available versions:** +> +>* `minReactNative44`: Support for React Native 0.44-0.45 +>* `minReactNative46`: Support for React Native 0.46+ + + +In `android/app/build.gradle` add this in `dependencies` section: + +```gradle +dependencies { + ... + androidTestImplementation(project(path: ":detox")) + androidTestImplementation 'junit:junit:4.12' + androidTestImplementation 'com.android.support.test:runner:1.0.1' + androidTestImplementation 'com.android.support.test:rules:1.0.1' + ... +} +``` + +And in the same file you need to add this under `allprojects > repositories`: + +```gradle +buildscript { + repositories { + ... + google() + ... + } +} +``` + +### 3. Create Android Test class + +You need to add the file `android/app/src/androidTest/java/com/[your.package]/DetoxTest.java` and fill it like [this](../detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java), expect that you need to change the package to your projects name. + +### 4. Add Android configuration + +Add this part to your `package.json`: + +```json +"detox" : { + "configurations": { + "android.emu.debug": { + "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", + "build": + "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", + "type": "android.emulator", + "name": "Nexus_5X_API_24" + }, + "android.emu.release": { + "binaryPath": "android/app/build/outputs/apk/release/app-release.apk", + "build": + "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..", + "type": "android.emulator", + "name": "Nexus_5X_API_26" + } + } +} +``` +Pay attention to `-DtestBuildType`, set either to `debug` or `release` according to the main apk type. + + +Following device types could be used to control Android devices: + +`android.emulator`. Boot stock SDK emulator with provided `name`, for example `Nexus_5X_API_25`. After booting connect to it. + +`android.attached`. Connect to already-attached android device. The device should be listed in the output of `adb devices` command under provided `name`. +Use this type to connect to Genymotion emulator. + +### 5. Run the tests + +Using the `android.emu.debug` configuration from above, you can invoke it in the standard way. + +```sh +detox test -c android.emu.debug +``` + +## Troubleshooting + +### Problem: `Duplicate files copied in ...` + +If you get an error like this: + +```sh +Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'. +> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/LICENSE +``` + +You need to add this to the `android` section of your `android/app/build.gradle`: + +```gradle +packagingOptions { + exclude 'META-INF/LICENSE' +} +``` diff --git a/website/versioned_docs/version-7.X/Introduction.GettingStarted.md b/website/versioned_docs/version-7.X/Introduction.GettingStarted.md new file mode 100644 index 0000000000..3172b998d3 --- /dev/null +++ b/website/versioned_docs/version-7.X/Introduction.GettingStarted.md @@ -0,0 +1,154 @@ +--- +id: version-7.X-Introduction.GettingStarted +title: Getting Started +original_id: Introduction.GettingStarted +--- + +This is a step-by-step guide for adding Detox to your React Native project. + +> TIP: You can also check out this [awesome tutorial](https://medium.com/@bogomolnyelad/how-to-test-your-react-native-app-like-a-real-user-ecfc72e9b6bc) on Medium with video by [@bogomolnyelad](https://medium.com/@bogomolnyelad) + +
+ +## Prerequisites + +Running Detox (on iOS) requires the following: + +* Mac with macOS (at least macOS El Capitan 10.11) + +* Xcode 8.3+ with Xcode command line tools +> TIP: Verify Xcode command line tools is installed by typing `gcc -v` in terminal (shows a popup if not installed) + +* A working [React Native](https://facebook.github.io/react-native/docs/getting-started.html) app you want to test + +
+ +## Step 1: Install dependencies + +#### 1. Install the latest version of [Homebrew](http://brew.sh) + +Homebrew is a package manager for macOS, we'll need it to install other command line tools. + +> TIP: Verify it works by typing in terminal `brew -h` to output list of available commands + +#### 2. Install [Node.js](https://nodejs.org/en/) + +Node is the JavaScript runtime Detox will run on. **Install Node 7.6.0 or above for native async-await support** + + ```sh + brew update && brew install node + ``` + +> TIP: Verify it works by typing in terminal `node -v` to output current node version, should be higher than 7.6.0 + +#### 3. Install [appleSimUtils](https://github.com/wix/AppleSimulatorUtils) + +A collection of utils for Apple simulators, Detox uses it communicate with the simulator. + +```sh +brew tap wix/brew +brew install --HEAD applesimutils +``` + +> TIP: Verify it works by typing in terminal `applesimutils` to output the tool help screen + +#### 4. Install Detox command line tools (detox-cli) + +This package makes it easier to operate Detox from the command line. `detox-cli` should be installed globally, enabling usage of the command line tools outside of your npm scripts. + + ```sh + npm install -g detox-cli + ``` +> TIP: Verify it works by typing in terminal `detox -h` to output the list of available commands + +
+ +## Step 2: Add Detox to your project + +#### 1. Install detox + +Go to the root folder of your React Native app (where `package.json` is found): + +```sh +npm install detox --save-dev +``` + +#### 2. Install mocha + +You can use any JavaScript test runner +- [Jest](Guide.Jest.md) +- [Mocha](https://mochajs.org/) is a good one we recommend: + +```sh +npm install mocha --save-dev +``` + +#### 3. Add Detox config to package.json + +The basic configuration for Detox should be in your `package.json` file under the `detox` property: + +```json +"detox": { + "configurations": { + "ios.sim.debug": { + "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app", + "build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", + "type": "ios.simulator", + "name": "iPhone 7" + } + } +} +``` + +In the above configuration example, change `example` to your actual project name. Under the key `"binaryPath"`, `example.app` should be `.app`. Under the key `"build"`, `example.xcodeproj` should be `.xcodeproj` and `-scheme example` should be `-scheme `. + +For iOS apps in a workspace (eg: CocoaPods) use `-workspace ios/example.xcworkspace` instead of `-project`. + +Also make sure the simulator model specified under the key `"name"` (`iPhone 7` above) is actually available on your machine (it was installed by Xcode). Check this by typing `xcrun simctl list` in terminal to display all available simulators. + +> TIP: To test a release version, replace 'Debug' with 'Release' in the binaryPath and build properties. For full configuration options see Configuration under the API Reference. + +
+ +## Step 3: Create your first test (using mocha test runner) + +You can do this automatically by running: + +```sh +detox init +``` + +Or you can do this manually instead by following these steps: + +* Create an `e2e` folder in your project root +* Create `mocha.opts` file inside with this [content](/examples/demo-react-native/e2e/mocha.opts) +* Create `init.js` file inside with this [content](/examples/demo-react-native/e2e/init.js) +* Create your first test `firstTest.spec.js` inside with content similar to [this](/examples/demo-react-native/e2e/example.spec.js) + +> TIP: Detox is not tightly coupled to Mocha or this directory structure, both are just a recommendation and are easy to replace without touching the internal implementation of Detox itself. + +
+ +## Step 4: Build your app and run Detox tests + +#### 1. Build your app + +Use the Detox command line tools to build your project easily: + +```sh +detox build +``` + +> TIP: Notice that the actual build command was specified in the Detox configuration above + +#### 2. Run the tests (finally) + +Use the Detox command line tools to test your project easily: + +```sh +detox test +``` + +That's it. Your first failing Detox test is running! + +Next, we'll go over usage and how to make this test [actually pass](Introduction.WritingFirstTest.md). diff --git a/website/versioned_docs/version-7.X/README.md b/website/versioned_docs/version-7.X/README.md new file mode 100644 index 0000000000..e2121c829a --- /dev/null +++ b/website/versioned_docs/version-7.X/README.md @@ -0,0 +1,57 @@ +--- +id: version-7.X-README +title: detox +sidebar_label: Overview +original_id: README +--- + +# Detox Documentation + +## Introduction + +- [Getting Started](Introduction.GettingStarted.md) +- [Writing Your First Passing Test](Introduction.WritingFirstTest.md) +- [Adding Android](Introduction.Android.md) +- [How Detox Works](Introduction.HowDetoxWorks.md) +- [Recommended Workflows With Detox](Introduction.Workflows.md) + +## API Reference + +- [Detox Configuration](APIRef.Configuration.md) +- [The `detox` Object](APIRef.DetoxObjectAPI.md) +- [The `device` Object](APIRef.DeviceObjectAPI.md) +- [Test Lifecycle](APIRef.TestLifecycle.md) +- [Matchers](APIRef.Matchers.md) +- [Actions](APIRef.ActionsOnElement.md) +- [Expectations](APIRef.Expect.md) +- [Manual Synchronization](APIRef.waitFor.md) +- [Mocking Deep Links (App Launch From URL)](APIRef.MockingOpenFromURL.md) +- [Mocking User Notifications](APIRef.MockingUserNotifications.md) +- [Detox Command Line Tools (detox-cli)](APIRef.DetoxCLI.md) + +## Troubleshooting + +- [Troubleshooting Detox Installation](Troubleshooting.Installation.md) +- [Troubleshooting a Test That Keeps Failing](Troubleshooting.RunningTests.md) +- [Dealing With Synchronization Issues in Tests](Troubleshooting.Synchronization.md) +- [Dealing With Flakiness in Tests](Troubleshooting.Flakiness.md) + +## Guides + +- [Running Tests Locally on Your Machine](Guide.RunningLocally.md) +- [Developing Your App While Writing Tests](Guide.DevelopingWhileWritingTests.md) +- [Running Tests on CI (like Travis)](Guide.RunningOnCI.md) +- [Debugging Apps in Xcode During a Test](Guide.DebuggingInXcode.md) +- [Advanced Mocking With Detox](Guide.Mocking.md) +- [Migration Between Detox Versions](Guide.Migration.md) +- [Use Jest as Test Runner](Guide.Jest.md) + +## Under The Hood + +- [Detox Design Principles](More.DesignPrinciples.md) + +## Contributing to Detox + +- [Detox Contribution Guide](Guide.Contributing.md) +- [Detox Development Roadmap](More.Roadmap.md) +- [Android Support - Current Status](More.AndroidSupportStatus.md) diff --git a/website/versions.json b/website/versions.json index d8f9140e5d..1cf1cd1125 100644 --- a/website/versions.json +++ b/website/versions.json @@ -1,3 +1,4 @@ [ + "7.X", "6.X" ] From bf25220ba38c1f8631961e019e12656e696b61ac Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Mon, 5 Mar 2018 09:22:16 +0100 Subject: [PATCH 03/10] Gather doc versions from git tags --- .travis.yml | 6 + website/.gitignore | 7 + website/gatherDocs.js | 73 ++++++ website/i18n/en.json | 2 +- website/package.json | 8 +- .../version-6.X/APIRef.ActionsOnElement.md | 110 -------- .../version-6.X/APIRef.Artifacts.md | 84 ------- .../version-6.X/APIRef.Configuration.md | 147 ----------- .../version-6.X/APIRef.DetoxCLI.md | 98 -------- .../version-6.X/APIRef.DetoxObjectAPI.md | 57 ----- .../version-6.X/APIRef.DeviceObjectAPI.md | 220 ---------------- .../version-6.X/APIRef.Expect.md | 82 ------ .../version-6.X/APIRef.Matchers.md | 124 --------- .../version-6.X/APIRef.MockingOpenFromURL.md | 36 --- .../APIRef.MockingUserNotifications.md | 129 ---------- .../version-6.X/APIRef.TestLifecycle.md | 50 ---- .../version-6.X/APIRef.waitFor.md | 100 -------- .../version-6.X/Guide.Contributing.md | 135 ---------- .../version-6.X/Guide.DebuggingInXcode.md | 85 ------- .../Guide.DevelopingWhileWritingTests.md | 75 ------ .../versioned_docs/version-6.X/Guide.Jest.md | 76 ------ .../version-6.X/Guide.Migration.md | 156 ------------ .../version-6.X/Guide.Mocking.md | 21 -- .../version-6.X/Guide.RunningLocally.md | 36 --- .../version-6.X/Guide.RunningOnCI.md | 159 ------------ .../version-6.X/Introduction.Android.md | 143 ----------- .../Introduction.GettingStarted.md | 154 ------------ .../version-6.X/Introduction.HowDetoxWorks.md | 53 ---- .../version-6.X/Introduction.Workflows.md | 15 -- .../Introduction.WritingFirstTest.md | 89 ------- .../version-6.X/More.AndroidSupportStatus.md | 106 -------- .../version-6.X/More.DesignPrinciples.md | 27 -- .../version-6.X/More.Roadmap.md | 38 --- website/versioned_docs/version-6.X/README.md | 57 ----- .../version-6.X/Troubleshooting.Flakiness.md | 37 --- .../Troubleshooting.Installation.md | 17 -- .../Troubleshooting.RunningTests.md | 236 ------------------ .../Troubleshooting.Synchronization.md | 124 --------- .../version-7.X/APIRef.DetoxCLI.md | 98 -------- .../version-7.X/APIRef.DetoxObjectAPI.md | 76 ------ .../version-7.X/APIRef.DeviceObjectAPI.md | 220 ---------------- .../version-7.X/APIRef.waitFor.md | 100 -------- .../version-7.X/Guide.Contributing.md | 135 ---------- .../versioned_docs/version-7.X/Guide.Jest.md | 76 ------ .../version-7.X/Introduction.Android.md | 137 ---------- .../Introduction.GettingStarted.md | 154 ------------ website/versioned_docs/version-7.X/README.md | 57 ----- .../version-6.X-sidebars.json | 47 ---- website/versions.json | 4 - 49 files changed, 94 insertions(+), 4182 deletions(-) create mode 100644 website/gatherDocs.js delete mode 100644 website/versioned_docs/version-6.X/APIRef.ActionsOnElement.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.Artifacts.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.Configuration.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.DetoxCLI.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.DetoxObjectAPI.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.DeviceObjectAPI.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.Expect.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.Matchers.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.MockingOpenFromURL.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.MockingUserNotifications.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.TestLifecycle.md delete mode 100644 website/versioned_docs/version-6.X/APIRef.waitFor.md delete mode 100644 website/versioned_docs/version-6.X/Guide.Contributing.md delete mode 100644 website/versioned_docs/version-6.X/Guide.DebuggingInXcode.md delete mode 100644 website/versioned_docs/version-6.X/Guide.DevelopingWhileWritingTests.md delete mode 100644 website/versioned_docs/version-6.X/Guide.Jest.md delete mode 100644 website/versioned_docs/version-6.X/Guide.Migration.md delete mode 100644 website/versioned_docs/version-6.X/Guide.Mocking.md delete mode 100644 website/versioned_docs/version-6.X/Guide.RunningLocally.md delete mode 100644 website/versioned_docs/version-6.X/Guide.RunningOnCI.md delete mode 100644 website/versioned_docs/version-6.X/Introduction.Android.md delete mode 100644 website/versioned_docs/version-6.X/Introduction.GettingStarted.md delete mode 100644 website/versioned_docs/version-6.X/Introduction.HowDetoxWorks.md delete mode 100644 website/versioned_docs/version-6.X/Introduction.Workflows.md delete mode 100644 website/versioned_docs/version-6.X/Introduction.WritingFirstTest.md delete mode 100644 website/versioned_docs/version-6.X/More.AndroidSupportStatus.md delete mode 100644 website/versioned_docs/version-6.X/More.DesignPrinciples.md delete mode 100644 website/versioned_docs/version-6.X/More.Roadmap.md delete mode 100644 website/versioned_docs/version-6.X/README.md delete mode 100644 website/versioned_docs/version-6.X/Troubleshooting.Flakiness.md delete mode 100644 website/versioned_docs/version-6.X/Troubleshooting.Installation.md delete mode 100644 website/versioned_docs/version-6.X/Troubleshooting.RunningTests.md delete mode 100644 website/versioned_docs/version-6.X/Troubleshooting.Synchronization.md delete mode 100644 website/versioned_docs/version-7.X/APIRef.DetoxCLI.md delete mode 100644 website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md delete mode 100644 website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md delete mode 100644 website/versioned_docs/version-7.X/APIRef.waitFor.md delete mode 100644 website/versioned_docs/version-7.X/Guide.Contributing.md delete mode 100644 website/versioned_docs/version-7.X/Guide.Jest.md delete mode 100644 website/versioned_docs/version-7.X/Introduction.Android.md delete mode 100644 website/versioned_docs/version-7.X/Introduction.GettingStarted.md delete mode 100644 website/versioned_docs/version-7.X/README.md delete mode 100644 website/versioned_sidebars/version-6.X-sidebars.json delete mode 100644 website/versions.json diff --git a/.travis.yml b/.travis.yml index 3544c67c5a..d48a844909 100644 --- a/.travis.yml +++ b/.travis.yml @@ -52,6 +52,12 @@ matrix: # Website - language: node_js + addons: + apt: + sources: + - ubuntu-toolchain-r-test + packages: + - libstdc++-4.9-dev env: - NAME='Website - master' node_js: 8 diff --git a/website/.gitignore b/website/.gitignore index aeedda9bfc..f80a7be301 100644 --- a/website/.gitignore +++ b/website/.gitignore @@ -9,3 +9,10 @@ website/node_modules website/i18n/* !website/i18n/en.json + +versioned_docs/* +!versioned_docs/.gitkeep + +versioned_sidebars/* +!versioned_sidebars/.gitkeep +versions.json \ No newline at end of file diff --git a/website/gatherDocs.js b/website/gatherDocs.js new file mode 100644 index 0000000000..126ec8d1f1 --- /dev/null +++ b/website/gatherDocs.js @@ -0,0 +1,73 @@ +#!/usr/bin/env node +const fs = require("fs-extra"); +const git = require("nodegit"); +const execSync = require('child_process').execSync; +const REPO_URL = "https://github.com/wix/detox.git" + +// From https://gist.github.com/joerx/3296d972735adc5b4ec1 +function clearRequireCache() { + Object.keys(require.cache).forEach(function (key) { + delete require.cache[key]; + }); +} + +function getMajorVersion(tag) { + return parseInt(tag.split('.')[0], 10) +} + +async function getVersions() { + const tmp = fs.mkdtempSync('detox-versions'); + const repo = await git.Clone(REPO_URL, tmp); + const tags = await git.Tag.list(repo); + + const semverTags = tags + .filter(tag => tag.split('.').length === 3 && getMajorVersion(tag) >= 6) + .sort() + .reverse(); + await fs.remove(tmp); + return semverTags; +} + +const sidebars = []; + +(async function () { + const versions = await getVersions(); + console.log("Cleanup versioned docs"); + await fs.remove("./versions.json") + await fs.emptyDir("./versioned_docs"); + await fs.emptyDir("./versioned_sidebars"); + + fs.writeFileSync("./versions.json", JSON.stringify(versions), "utf8"); + for (let version of versions) { + const tempDir = fs.mkdtempSync(`detox-${version}`); + console.log("Clone repository into tmp directory"); + const repo = await git.Clone(REPO_URL, tempDir); + + console.log("Checking out version", version); + await repo.checkoutBranch(version); + + // We need to do this as we forgot the header in this one file, but added git tags with it included + console.log("Temporary fix for Guide.DebuggingInXcode") + const header = '---\nid: Guide.DebuggingInXcode\ntitle: Debugging in Xcode During Detox Tests\n---'; + execSync( + `echo "${header}" | cat - Guide.DebuggingInXcode.md > /tmp/out && mv /tmp/out Guide.DebuggingInXcode.md`, + { + cwd: tempDir + "/docs" + } + ); + + console.log("Generating versioned doc for", version) + execSync(`npm install && rm versions.json && rm -rf {versioned_docs,versioned_sidebars} && npm run version ${version}`, { cwd: tempDir + '/website' }) + + console.log("Copy versioned doc"); + fs.copySync(`${tempDir}/website/versioned_docs/version-${version}`, `./versioned_docs/version-${version}`); + + console.log("Copy sidebar into versioned_sidebars"); + fs.copyFileSync(`${tempDir}/website/versioned_sidebars/version-${version}-sidebars.json`, `./versioned_sidebars/version-${version}-sidebars.json`) + + console.log("Cleanup temporary clone"); + await fs.remove(tempDir); + console.log(`Done with ${version}\n\n`); + } +})(); + diff --git a/website/i18n/en.json b/website/i18n/en.json index 62db24c3bb..9129c1994b 100644 --- a/website/i18n/en.json +++ b/website/i18n/en.json @@ -17,7 +17,7 @@ "APIRef.TestLifecycle": "Test Lifecycle", "APIRef.waitFor": "Manual Synchronization Using `waitFor`", "Guide.Contributing": "Contributing", - "Guide.DebuggingInXcode": "Guide.DebuggingInXcode", + "Guide.DebuggingInXcode": "Debugging in Xcode During Detox Tests", "Guide.DevelopingWhileWritingTests": "Developing Your App While Writing Tests", "Guide.Jest": "Jest", "Guide.Migration": "Migration Guide", diff --git a/website/package.json b/website/package.json index ae58a7fd94..d45abbc1cb 100644 --- a/website/package.json +++ b/website/package.json @@ -3,12 +3,18 @@ "examples": "docusaurus-examples", "start": "docusaurus-start", "build": "docusaurus-build", + "prepublish-gh-pages": "npm run gatherDocs", "publish-gh-pages": "docusaurus-publish", "write-translations": "docusaurus-write-translations", "version": "docusaurus-version", - "rename-version": "docusaurus-rename-version" + "rename-version": "docusaurus-rename-version", + "gatherDocs": "node ./gatherDocs" }, "devDependencies": { "docusaurus": "^1.0.4" + }, + "dependencies": { + "fs-extra": "^5.0.0", + "nodegit": "^0.21.0" } } diff --git a/website/versioned_docs/version-6.X/APIRef.ActionsOnElement.md b/website/versioned_docs/version-6.X/APIRef.ActionsOnElement.md deleted file mode 100644 index 4a39c383bc..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.ActionsOnElement.md +++ /dev/null @@ -1,110 +0,0 @@ ---- -id: version-6.X-APIRef.ActionsOnElement -title: Actions on Element -original_id: APIRef.ActionsOnElement ---- - -Detox uses **Matchers** to find UI `elements` in your app, **Actions** to emulate user interaction with those `elements` and **Expectations** to verify values on those `elements`. - - -## Actions -Actions are functions that emulate user behavior. They are being performed on matched elements. - -### Methods - -- [`.tap()`](#tap) -- [`.longPress()`](#longpress) -- [`.multiTap()`](#multitaptimes) -- [`.tapAtPoint()`](#tapatpoint) -- [`.typeText()`](#typetexttext) -- [`.replaceText()`](#replacetexttext) -- [`.clearText()`](#cleartext) -- [`.scroll()`](#scrollpixels-direction) -- [`.scrollTo()`](#scrolltoedge) -- [`.swipe()`](#swipedirection-speed-percentage) - - -### `tap()` -Simulate tap on an element. - -```js -await element(by.id('tappable')).tap(); -``` - -### `longPress()` -Simulate long press on an element. - -```js -await element(by.id('tappable')).longPress(); -``` - -### `multiTap(times)` -Simulate multiple taps on an element. - -```js -await element(by.id('tappable')).multiTap(3); -``` -### `tapAtPoint()` -Simulate tap at a specific point on an element.

-Note: The point coordinates are relative to the matched element and the element size could changes on different devices or even when changing the device font size. - -```js -await element(by.id('tappable')).tapAtPoint({x:5, y:10}); -``` - -### `typeText(text)` -Use the builtin keyboard to type text into a text field. - -```js -await element(by.id('textField')).typeText('passcode'); -``` - -> **Note:** Make sure hardware keyboard is disconnected. Otherwise, Detox may fail when attempting to type text. -> -> To make sure hardware keybaord is disconnected, open the simulator from Xcode and make sure **Hardware** -> **Keyboard** -> **Connect Hardware Keyboard** is deselected (or press ⇧⌘K). - -### `replaceText(text)` -Paste text into a text field. - -```js -await element(by.id('textField')).replaceText('passcode again'); -``` - -### `clearText()` -Clear text from a text field. - -```js -await element(by.id('textField')).clearText(); -``` - -### `scroll(pixels, direction)` -Scroll amount of pixels.
-pixels - independent device pixels.
-direction - left/right/top/bottom - -```js -await element(by.id('scrollView')).scroll(100, 'down'); -await element(by.id('scrollView')).scroll(100, 'up'); -``` - -### `scrollTo(edge)` -Scroll to edge. - -edge - left/right/top/bottom - -```js -await element(by.id('scrollView')).scrollTo('bottom'); -await element(by.id('scrollView')).scrollTo('top'); -``` - -### `swipe(direction, speed, percentage)` - -direction - left/right/up/down
-speed - fast/slow - default is fast
-percentage - (optional) screen percentage to swipe as float - -```js -await element(by.id('scrollView')).swipe('down'); -await element(by.id('scrollView')).swipe('down', 'fast'); -await element(by.id('scrollView')).swipe('down', 'fast', 0.5); -``` diff --git a/website/versioned_docs/version-6.X/APIRef.Artifacts.md b/website/versioned_docs/version-6.X/APIRef.Artifacts.md deleted file mode 100644 index 36ddd93975..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.Artifacts.md +++ /dev/null @@ -1,84 +0,0 @@ ---- -id: version-6.X-APIRef.Artifacts -title: Artifacts -original_id: APIRef.Artifacts ---- - -Artifacts currently include only logs from the app process. - -## Enabling artifacts - -Artifacts are disabled by default. Two things are required to enable them: - -1. **Call `detox.beforeEach()` and `detox.afterEach()` before/after each test**: - In order for artifacts to work, you have to call `detox.beforeEach()` / `detox.afterEach()` before / after each test. The easiest way to do it is to add beforeEach / afterEach functions to init.js . The following example works with mocha:

- - ```js - beforeEach(async function() { - await detox.beforeEach(this.currentTest.parent.title, this.currentTest.title); - }); - - afterEach(async function() { - await detox.afterEach(); - }); - ``` - - The arguments provided to beforeEach are optional name components. It's convenient to provide suite name and test name as the components in order to have them in the artifacts per-test folders. If not specified, the test folders will be named by the test numbers. - - **Note**: other test runners may have other ways to add the beforeEach/afterEach calls and to fetch test and suite titles. - -2. Provide artifacts location via launch arguments: -`--artifacts-location ` specifies artifacts location and enables artifacts creation. If you use Detox CLI tools, then the following command will create the artifacts under `/tmp`: - - ```sh - detox test --artifacts-location /tmp - ``` - - The provided path should be an existing directory with write permission. Detox will create a new folder `detox_artifacts.` under the provided location. In such way, every additional execution of detox with the same artifacts location will be saved separately. - -## Artifacts structure - -1. **Artifacts root folder** is created per detox run. If, for instance,`--artifacts-location tmp` is used, then the folder `/tmp/detox_artifacts.2017-07-18T09:02:11.094Z` is created. - -2. **Test folder** is created per test inside the root folder. The folder name consists of the test number, and the name components provided to `detox.beforeEach()` as explained above - separated by dots. For instance, for the above example, the following folders will be created inside `/tmp/detox_artifacts.2017-07-18T09:02:11.094Z`: - - ``` - 1.Sanity.should have welcome - 2.Sanity.should show hello - 3.Sanity.should show world - 4.Matchers.should match - 5.Matchers.should match - 6.Matchers.should match - 7.Matchers.should match - 8.Matchers.should match - ``` - -3. **Artifacts files** are created inside the test folders. The files suffixes stand for the files types (currently there are .err.log and .out.log), and the files prefixes are the launch numbers of the application per test (if the app was executed more than once per test, you will have several artifacts of each type - one per launch). For instance, a test folder may contain the following artifacts files: - - ``` - 1.err.log - 1.out.log - 2.err.log - 2.out.log - ``` - -### Example of the structure: - -``` -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/1.Sanity.should have welcome screen/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/1.Sanity.should have welcome screen/1.out.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/2.Sanity.should show hello screen after tap/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/2.Sanity.should show hello screen after tap/1.out.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/3.Sanity.should show world screen after tap/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/3.Sanity.should show world screen after tap/1.out.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/4.Matchers.should match elements by (accesibility) label/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/4.Matchers.should match elements by (accesibility) label/1.out.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/5.Matchers.should match elements by (accesibility) id/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/5.Matchers.should match elements by (accesibility) id/1.out.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/6.Matchers.should match elements by type (native class)/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/6.Matchers.should match elements by type (native class)/1.out.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/7.Matchers.should match elements by accesibility trait/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/7.Matchers.should match elements by accesibility trait/1.out.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/8.Matchers.should match elements with ancenstor (parent)/1.err.log -/tmp/detox_artifacts.2017-07-18T09:02:11.094Z/8.Matchers.should match elements with ancenstor (parent)/1.out.log -``` \ No newline at end of file diff --git a/website/versioned_docs/version-6.X/APIRef.Configuration.md b/website/versioned_docs/version-6.X/APIRef.Configuration.md deleted file mode 100644 index 6a02b1f709..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.Configuration.md +++ /dev/null @@ -1,147 +0,0 @@ ---- -id: version-6.X-APIRef.Configuration -title: Configuration Options -original_id: APIRef.Configuration ---- - -## Configuring package.json -### Device Configuration -`configurations` holds all the device configurations, if there is only one configuration in `configurations` `detox build` and `detox test` will default to it, to choose a specific configuration use `--configuration` param
- - -|Configuration Params|Details| -|---|---| -|`binaryPath`|relative path to the ipa/app due to be tested (make sure you build the app in a project relative path)| -|`type`|device type, currently only `ios.simulator` is supported| -|`name`|device name, aligns to the device list avaliable through `xcrun simctl list` for example, this is one line of the output of `xcrun simctl list`: `A3C93900-6D17-4830-8FBE-E102E4BBCBB9 iPhone 7 Shutdown iPhone 7 iOS 10.2`, ir order to choose the first `iPhone 7` regardless of OS version, use `iPhone 7`.
To be OS specific use `iPhone 7, iOS 10.2`| -|`build`| **[optional]** build command (either `xcodebuild`, `react-native run-ios`, etc...), will be later available through detox CLI tool.| - -**Example:** - -```json - "detox": { - ... - "configurations": { - "ios.sim.debug": { - "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app", - "build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.simulator", - "name": "iPhone 7 Plus" - } - } - } -``` - - -### Server Configuration -Detox can either initialize a server using a generated configuration, or can be overriden with a manual configuration: - -```json - "detox": { - ... - "session": { - "server": "ws://localhost:8099", - "sessionId": "YourProjectSessionId" - } - } -``` - -Session can also be set per configuration: - -```json - "detox": { - ... - "configurations": { - "ios.sim.debug": { - ... - "session": { - "server": "ws://localhost:8099", - "sessionId": "YourProjectSessionId" - } - } - } - } -``` - -### Test Runner Configuration - -##### Optional: setting a test runner (Mocha as default, Jest is supported) -##### Mocha -```json - "detox": { - ... - "test-runner": "mocha" - "runner-config": "path/to/mocha.opts" - "specs": "path/to/tests/root" - } -``` -`mocha.opts` refers to `--opts` in https://mochajs.org/#mochaopts - -##### Jest -```json - "detox": { - ... - "test-runner": "jest" - "runner-config": "path/to/config.json" - } -``` -`config.json` refers to `--config` in https://facebook.github.io/jest/docs/en/configuration.html ->NOTE: jest tests will run in band, as Detox does not currently supports parallelization. - -## detox-cli -### Build Configuration - -In your detox config (in `package.json`) paste your build command into the configuration's `build` field. -The build command will be triggered when running `detox build`.
-**This is only a convience method, to help you manage building multiple configurations of your app and couple them to your tests. You can also choose not to use it and provide a compiled `app` by yourself.** - -You can choose to build your project in any of these ways... - -* If there's only one configuration, you can simply use: - - ```sh - detox build - ``` - -* To choose a specific configuration: - - ```sh - detox build --configuration yourConfiguration - ``` -* Building with xcodebuild: - - ```sh - xcodebuild -project ios/YourProject.xcodeproj -scheme YourProject -sdk iphonesimulator -derivedDataPath ios/build - ``` - -* Building using React Native, this is the least suggested way of running your build, since it also starts a random simulator and installs the app on it. - - ```sh - react-native run-ios - ``` - -> Note: remember to update the `app` path in your `package.json`. - - -### Test Configuration -* If there's only one configuration, you can simply use: - - ```sh - detox test - ``` -* For multiple configurations, choose your configuration by passing `--configuration` param: - - ```sh - detox test --configuration yourConfiguration - ``` - -### Faster test runs with app reuse -By default the app is removed, reinstalled and launched before each run. -Starting fresh is critical in CI but in dev you might be able to save time between test runs and reuse the app that was previously installed in the simulator. To do so use the `reuse` flag and run your tests like this: - -```sh -detox test --reuse -``` - -This is especially useful with React Native DEV mode when making Javascript code changes that are getting picked up by the packager (and thus no reinstall is needed). This can save up to 7 seconds per run! -You should not use this option if you made native code changes or if your app relies on local ("disk") storage. diff --git a/website/versioned_docs/version-6.X/APIRef.DetoxCLI.md b/website/versioned_docs/version-6.X/APIRef.DetoxCLI.md deleted file mode 100644 index 774b995fb4..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.DetoxCLI.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: version-6.X-APIRef.DetoxCLI -title: Detox Command Line Tools (detox-cli) -original_id: APIRef.DetoxCLI ---- - -`detox-cli` lets you operate Detox from command line. - -## Installation -Install `detox-cli` globally via npm: - -```sh -npm install -g detox-cli -``` - -## Usage -```sh -detox [options] [command] -``` - -## Commands: -| Command | Description | -| --- | --- | -| [test](#test) | Initiating your test suite | -| [build](#build) | Run the command defined in `configuration.build` | -| [run-server](#run-server) | Starts a standalone detox server | -| [init](#init) | Create initial e2e tests folder | -| clean-framework-cache | Delete all compiled framework binaries from ~/Library/Detox, they will be rebuilt on 'npm install' or when running 'build-framework-cache' -| build-framework-cache | Build Detox.framework to ~/Library/Detox. The framework cache is specific for each combination of Xcode and Detox versions -| [help](#help) | Display help for specific command | - -## Options: - -| Options | Description | -| --- | --- | -| -h
--help | Output usage information | - -## Commands - -### test -Initiating your test suite - -`detox test [options]` - - - -| Option| Description | -| --- | --- | -| -h, --help | output usage information | -| -o, --runner-config \ | Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest | -| -l, --loglevel [value] | info, debug, verbose, silly, wss | -| -c, -configuration \ | Select a device configuration from your defined figurations,if not supplied, and there's only one configuration, detox will default to it | -| -r, --reuse | Reuse existing installed app (do not delete and re-tall) for a faster run. | -| -u, --cleanup | Shutdown simulator when test is over, useful for CI ipts, to make sure detox exists cleanly with no residue | -| -d, --debug-synchronization \ | When an action/expectation takes a significant amount time use this option to print device synchronization status. The status will be printed if the ion takes more than [value]ms to complete | -| -a, --artifacts-location \ | Artifacts destination path (currently contains only logs). For more details, please check the [Artifacts doc](APIRef.Artifacts.md#artifacts) | -|-p, --platform [ios/android] | Run platform specific tests. Runs tests with invert grep on `:platform:`, e.g test with substring `:ios:` in its name will not run when passing `--platform android` -|                  || - - - -### build -Run a command defined in 'configuration.build' - -`detox build [options]` - -| Option | Description | -| --- | --- | -| -h, --help | output usage information | -| -c, --configuration \ | Select a device configuration from your defined configurations,if not supplied, and there's only one configuration, detox will default to it | -|                  || - - -### run-server -Start a standalone detox server - -`detox run-server [options]` - -| Option | Description | -| --- | --- | -| -h, --help | output usage information | - - -### init -Create initial e2e tests folder - -`detox init [options` - -| Option | Description | -| --- | --- | -| -h, --help | output usage information | -| -r, --runner | Test runner (currently supports only `mocha`) | - -### help -Display help for a command - -`detox help [command]` - diff --git a/website/versioned_docs/version-6.X/APIRef.DetoxObjectAPI.md b/website/versioned_docs/version-6.X/APIRef.DetoxObjectAPI.md deleted file mode 100644 index cc5598964d..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.DetoxObjectAPI.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: version-6.X-APIRef.DetoxObjectAPI -title: The `detox` Object -original_id: APIRef.DetoxObjectAPI ---- - -`detox` is globally available in every test file, though currently it is only used in the setup/init file. - ->NOTE: detox is test runner independent, and we encourge you to choose your own test runner, but for the sake of demonstration we will use `mocha`'s syntax. - -### Methods - -- [`detox.init()`](#detox.init) -- [`detox.cleanup()`](#detox.cleanup) - -### `detox.init()` -The setup phase happens inside `detox.init()`. This is the phase where detox reads its configuration, starts a server, loads its expection library and starts a simulator. - -##### (if you're using mocha) In your `init.js` add: - -```js -const config = require('../package.json').detox; - -before(async () => { - await detox.init(config); -}); -``` - -#### controlling first app intialization -By default `await detox.init(config);` will launch the installed app. If you wish to control when your app is launched, add `{launchApp: false}` param to your init. - -```js -const config = require('../package.json').detox; - -before(async () => { - await detox.init(config, {launchApp: false}); -}); -``` - ->NOTE: Detox 6.X.X will introduce a **breaking change** , setting `launchApp` to `false` by default. In order to prevent any breaking changes to your tests when you upgrade (and if you still would like `init` to launch the app for you) do the following: - -```js -before(async () => { - await detox.init(config, {launchApp: true}); -}); -``` - -### `detox.cleanup()` -The cleanup phase should happen after all the tests have finished. This is the phase where detox-server shuts down. The simulator will also shut itself down if `--cleanup` flag is added to `detox test` - -##### (if you're using mocha) In your `init.js` add: - -```js -after(async () => { - await detox.cleanup(); -}); -``` \ No newline at end of file diff --git a/website/versioned_docs/version-6.X/APIRef.DeviceObjectAPI.md b/website/versioned_docs/version-6.X/APIRef.DeviceObjectAPI.md deleted file mode 100644 index c557f46f05..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.DeviceObjectAPI.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -id: version-6.X-APIRef.DeviceObjectAPI -title: The `device` Object -original_id: APIRef.DeviceObjectAPI ---- - -`device` is globally available in every test file, it enables control over the current attached device (currently only simulators are supported). - -### Methods - -- [`device.launchApp()`](#devicelaunchappparams) -- [`device.relaunchApp()` **Deprecated**](#devicerelaunchappparams) -- [`device.terminateApp()`](#deviceterminateapp) -- [`device.reloadReactNative()`](#devicereloadreactnative) -- [`device.sendToHome()`](#devicesendtohome) -- [`device.installApp()`](#deviceinstallapp) -- [`device.uninstallApp()`](#deviceuninstallapp) -- [`device.openURL(url)`](#deviceopenurlurl-sourceappoptional) -- [`device.sendUserNotification(params)`](#devicesendusernotificationparams) -- [`device.setOrientation(orientation)`](#devicesetorientationorientation) -- [`device.setLocation(lat, lon)`](#devicesetlocationlat-lon) -- [`device.setURLBlacklist([urls])`](#deviceseturlblacklisturls) -- [`device.enableSynchronization()`](#deviceenablesynchronization) -- [`device.disableSynchronization()`](#devicedisablesynchronization) -- [`device.resetContentAndSettings()`](#resetcontentandsettings) -- [`device.getPlatform()`](#devicegetplatform) - -### `device.launchApp(params)` -Launch the app defined in the current [`configuration`](APIRef.Configuration.md). - -**Options:** - -##### 1. Restart the app -Terminate the app and launch it again. -If set to `false`, the simulator will try to bring app from background, if the app isn't running, it will launch a new instance. default is `false` - -```js -await device.launchApp({newInstance: true}); -``` - -##### 2. Set runtime permissions -Grant or deny runtime permissions for your application. - -```js -await device.launchApp({permissions: {calendar: 'YES'}}); -``` -Detox uses [AppleSimUtils](https://github.com/wix/AppleSimulatorUtils) on iOS to support this functionality. Read about the different types of permissions and how to set them in AppleSimUtils' Readme. -Check out Detox's [own test suite](../detox/test/e2e/l-permissions.js) - -##### 3. Launch from URL -Mock opening the app from URL to test your app's deep link handling mechanism. - -```js -await device.launchApp({url: url}); -``` -###### Mock opening from a URL when app is not running -```js -await device.launchApp({url: url, newInstance: true}); -``` -This will launch a new instance of the app and handle the deep link. - -###### Mock opening from a URL when app is in background - -```js -await device.launchApp({url: url, newInstance: false}); -``` -This will launch the app from background and handle the deep link. - -Read more in [Mocking Open From URL](APIRef.MockingOpenFromURL.md) section. - -##### 4. Launch from user notifications - -```js -await device.launchApp({userNotification: notification}); -``` - -###### Mock receiving a notifications when app is not running -```js -await device.launchApp({userNotification: notification, newInstance: true}); -``` -This will launch a new instance of the app and handle the notification. - -###### Mock receiving a notifications when app is in background - -```js -await device.launchApp({userNotification: notification, newInstance: false}); -``` -This will launch the app from background and handle the notification. - -Read more in [Mocking User Notifications](APIRef.MockingUserNotifications.md) section. - -##### 5. Launch into a fresh installation -A flag that enables relaunching into a fresh installation of the app (it will uninstall and install the binary again), default is `false`. - -```js -await device.launchApp({delete: true}); -``` - -##### 6. Additional launch arguments -Detox can start the app with additional launch arguments - -```js -await device.launchApp({launchArgs: {arg1: 1, arg2: "2"}}); -``` - -The added `launchArgs` will be passed through the launch command to the device and be accessible via `[[NSProcessInfo processInfo] arguments]` - -### `device.relaunchApp(params)` -**Deprecated** Use `device.launchApp(params)` instead. This method is now calling `launchApp({newInstance: true})` for backwards compatibility, it will be removed in Detox 6.X.X.
-Kill and relaunch the app defined in the current [`configuration`](APIRef.Configuration.md). - -### `device.terminateApp()` -By default, `terminateApp()` with no params will terminate the app file defined in the current [`configuration`](APIRef.Configuration.md). - -To terminate another app, specify its bundle id - -```js -await device.terminateApp('other.bundle.id'); -``` - -### `device.sendToHome()` -Send application to background by bringing `com.apple.springboard` to the foreground.
-Combining `sendToHome()` with `launchApp({newInstance: false})` will simulate app coming back from background.
-Check out Detox's [own test suite](../detox/test/e2e/f-simulator.js) - -```js -await device.sendToHome(); -await device.launchApp({newInstance: false}); -// app returned from background, do stuff -``` -Check out Detox's [own test suite](../detox/test/e2e/f-device.js) - -### `device.reloadReactNative()` -If this is a react native app, reload react native JS bundle. This action is much faster than `device.relaunchApp()`, and is recommended if you just need to reset your react native logic. - -### `device.installApp()` -By default, `installApp()` with no params will install the app file defined in the current [`configuration`](APIRef.Configuration.md). - -To install another app, specify its path - -```js -await device.installApp('path/to/other/app'); -``` - -### `device.uninstallApp()` -By default, `uninstallApp()` with no params will uninstall the app defined in the current [`configuration`](APIRef.Configuration.md). - -To uninstall another app, specify its bundle id - -```js -await device.installApp('other.bundle.id'); -``` - -### `device.openURL({url, sourceApp[optional]})` -Mock opening the app from URL. `sourceApp` is an optional parameter to specify source application bundle id.
-Read more in [Mocking Open From URL](APIRef.MockingOpenFromURL.md) section.
-Check out Detox's [own test suite](../detox/test/e2e/n-deep-links.js) - -### `device.sendUserNotification(params)` -Mock handling of received user notification when app is in foreground.
-Read more in [Mocking User Notifications](APIRef.MockingUserNotifications.md) section.
-Check out Detox's [own test suite](../detox/test/e2e/k-user-notifications.js) - -### `device.setOrientation(orientation)` -Takes `"portrait"` or `"landscape"` and rotates the device to the given orientation. -Currently only available in the iOS Simulator.
-Check out Detox's [own test suite](../detox/test/e2e/f-device.js) - -### `device.setLocation(lat, lon)` ->Note: `setLocation` is dependent on `fbsimctl`. if `fbsimctl` is not installed, the command will fail, asking for it to be installed. -Sets the simulator location to the given latitude and longitude. -```js -await device.setLocation(32.0853, 34.7818); -``` - -### `device.setURLBlacklist([urls])` - -Disable [EarlGrey's network synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#network) on preffered endpoints. Usful if you want to on skip over synchronizing on certain URLs. - -```js -await device.setURLBlacklist(['.*127.0.0.1.*']); -``` - -```js -await device.setURLBlacklist(['.*my.ignored.endpoint.*']); -``` - -### `device.enableSynchronization()` -Enable [EarlGrey's synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#synchronization -) (enabled by default). **This is being reset on every new instance of the app.** -```js -await device.enableSynchronization(); -``` - - -### `device.disableSynchronization()` -Disable [EarlGrey's synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#synchronization -) (enabled by default) **This is being reset on every new instance of the app.** - -```js -await device.disableSynchronization(); -``` - - -### `device.resetContentAndSettings()` -Resets the Simulator to clean state (like the Simulator > Reset Content and Settings... menu item), especially removing -previously set permissions. - -```js -await device.resetContentAndSettings(); -``` - -### `device.getPlatform()` -Returns the current device, `ios` or `android`. - -```js -if (device.getPlatform() === 'ios') { - await expect(loopSwitch).toHaveValue('1'); -} -``` diff --git a/website/versioned_docs/version-6.X/APIRef.Expect.md b/website/versioned_docs/version-6.X/APIRef.Expect.md deleted file mode 100644 index 087c162db0..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.Expect.md +++ /dev/null @@ -1,82 +0,0 @@ ---- -id: version-6.X-APIRef.Expect -title: Expect -original_id: APIRef.Expect ---- - -Detox uses **Matchers** to find UI `elements` in your app, **Actions** to emulate user interaction with those `elements` and **Expectations** to verify values on those `elements`. - -Expect verifies if a certain value is as expected to be. - -### Methods - -- [`.toBeVisible()`](#tobevisible) -- [`.toBeNotVisible()`](#tobenotvisible) -- [`.toExist()`](#toexist) -- [`.toNotExist()`](#tonotexist) -- [`.toHaveText()`](#tohavetexttext) -- [`.toHaveLabel()`](#tohavelabellabel) -- [`.toHaveId()`](#tohaveidid) -- [`.toHaveValue()`](#tohavevaluevalue) - - -### `toBeVisible()` -Expect the view to be at least 75% visible. - -```js -await expect(element(by.id('UniqueId204'))).toBeVisible(); -``` - -### `toBeNotVisible()` -Expect the view to not be visible. - -```js -await expect(element(by.id('UniqueId205'))).toBeNotVisible(); -``` - -### `toExist()` -Expect the view to exist in the UI hierarchy. - -```js -await expect(element(by.id('UniqueId205'))).toExist(); -``` - -### `toNotExist()` -Expect the view to not exist in the UI hierarchy. - -```js -await expect(element(by.id('RandomJunk959'))).toNotExist(); -``` - -### `toHaveText(text)` -- In React Native apps, expect UI component of type `` to have text. - -- In native iOS apps, expect UI elements of type UIButton, UILabel, UITextField or UITextViewIn to have inputText with text. - -```js -await expect(element(by.id('UniqueId204'))).toHaveText('I contain some text'); -``` - -### `toHaveLabel(label)` -- It searches by accessibilityLabel on iOS, or by contentDescription on Android. - -- In React Native it can be set for both platforms by defining an [`accessibilityLabel`](https://facebook.github.io/react-native/docs/view.html#accessibilitylabel) on the view. - -```js -await expect(element(by.id('UniqueId204'))).toHaveLabel('Done'); -``` - -### `toHaveId(id)` -- In React Native apps, expect UI component to have [`testID`](https://facebook.github.io/react-native/docs/view.html#testid) with that id. -- In native iOS apps, expect UI element to have accesibilityIdentifier with that id. - -```js -await expect(element(by.text('I contain some text'))).toHaveId('UniqueId204'); -``` - -### `toHaveValue(value)` -Expect components like a Switch to have a value ('0' for off, '1' for on). - -```js -await expect(element(by.id('UniqueId533'))).toHaveValue('0'); -``` diff --git a/website/versioned_docs/version-6.X/APIRef.Matchers.md b/website/versioned_docs/version-6.X/APIRef.Matchers.md deleted file mode 100644 index 05078768b8..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.Matchers.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -id: version-6.X-APIRef.Matchers -title: Matchers -original_id: APIRef.Matchers ---- - -Detox uses **Matchers** to find UI `elements` in your app, **Actions** to emulate user interaction with those `elements` and **Expectations** to verify values on those `elements`. - - -Matchers find elements in your app that match one or more properties. - -**NOTE: Whenever possible we recommend to match elements `by.id`, these are more resilient to layout restructuring and text/language changes** - -### Methods - -- [`by.id()`](#byidid) -- [`by.text()`](#bytexttext) -- [`by.label()`](#bylabellabel) -- [`by.type()`](#bytypenativeviewtype) -- [`by.traits()`](#bytraitstraits) - -- [Advanced](#advanced) - - -#### `by.id(id)` -`by.id` will match an id that is given to the view via [`testID`](https://facebook.github.io/react-native/docs/view.html#testid) prop. - -In a React Native component add testID like so: - -```js - -... -``` - -Then match with `by.id`: - -```js -await element(by.id('tap_me')); -``` - - -For other cases, and only if you can't use `by.id` there is a variety of options: - -#### `by.text(text)` -Find an element by text, useful for text fields, buttons. - -```js -await element(by.text('Tap Me')); -``` - -#### `by.label(label)` -Find an element by `accessibilityLabel` on iOS, or by `contentDescription` on Android. - -```js -await element(by.label('Welcome')); -``` - -#### `by.type(nativeViewType)` -Find an element by native view type. - -```js -await element(by.type('RCTImageView')); -``` -#### `by.traits([traits])` -Find an element with an accessibility trait. (iOS only) - -```js -await element(by.traits(['button'])); -``` - -#### Advanced -##### By id and by parent id - -```js -await element(by.id('Grandson883').withAncestor(by.id('Son883'))); - -``` -##### By id and by child id - -```js -await element(by.id('Son883').withDescendant(by.id('Grandson883'))); -``` - -###### Example -- To find the view with the id `Son883` - - ```jsx - - - - - - - - ``` - - Use: - - ```js - // any of the following will work - await element(by.id('Son883')) - await element(by.id('Son883').withAncestor(by.id('Father883'))) - await element(by.id('Son883').withDescendant(by.id('Grandson883'))) - ``` - - -##### Multiple matchers - -```js -await element(by.id('UniqueId345').and(by.text('some text'))); -``` -##### Choose from multiple elements matching the same matcher using index - -The first valid index is 0. - -```js -await element(by.text('Product')).atIndex(2); -``` - -**Tip**: To find the back button on iOS use: - -```js - await element(by.traits(['button']).and(by.label('Back'))); -``` diff --git a/website/versioned_docs/version-6.X/APIRef.MockingOpenFromURL.md b/website/versioned_docs/version-6.X/APIRef.MockingOpenFromURL.md deleted file mode 100644 index 25b0f5c7b0..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.MockingOpenFromURL.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -id: version-6.X-APIRef.MockingOpenFromURL -title: Mocking Open from URL (Deep Links) -original_id: APIRef.MockingOpenFromURL ---- - -You can mock opening the app from URL to test your app's deep link handling mechanism. - -#### Mocking App Launch from a URL - -```js -await device.relaunchApp({url: url, sourceApp: bundleId}); //sourceApp is optional -``` - -**Example:** - -```js -describe('relaunchApp', () => { - before(async () => { - await device.relaunchApp({url: 'scheme://some.url', sourceApp: 'com.apple.mobilesafari'}); - }); - - it('should tap successfully', async () => { - await expect(element(by.text('a label'))).toBeVisible(); - }); - }); -``` - -#### Mocking Opening URL on a Launched App -```js -await device.openURL({url: 'scheme://some.url', sourceApp: 'com.apple.mobilesafari'}); -``` - -## iOS Requirements - -This API requires that the [`application:openURL:options:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623112-application?language=objc) method is implemented in the application delegate. The legacy deprecated [`application:openURL:sourceApplication:annotation:`](https://developer.apple.com/documentation/uikit/uiapplicationdelegate/1623073-application?language=objc) method is not supported. diff --git a/website/versioned_docs/version-6.X/APIRef.MockingUserNotifications.md b/website/versioned_docs/version-6.X/APIRef.MockingUserNotifications.md deleted file mode 100644 index 4db9faba94..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.MockingUserNotifications.md +++ /dev/null @@ -1,129 +0,0 @@ ---- -id: version-6.X-APIRef.MockingUserNotifications -title: Mocking User Notifications -original_id: APIRef.MockingUserNotifications ---- - -Detox supports mocking user notifications for iOS apps. - ->NOTE: The mocking mechanism will not mimic the UI of a user notification. Instead, it will only simulate the flow of a user-selected notifications. - -### Mocking App Launch with a Notification - -Using `relauchApp()` with custom params will trigger the mocking mechanism. - -```js -await device.relaunchApp({userNotification: notification}); -``` -**Example:** - -```js -describe('Background push notification', () => { - beforeEach(async () => { - await device.relaunchApp({userNotification: userNotificationPushTrigger}) - }); - - it('push notification from background', async () => { - await expect(element(by.text('From push'))).toBeVisible(); - }); -}); -``` - -### Mocking Notification Reception on a Launched App - -Use the `sendUserNotification()` method to send notification to running app. - -```js -await device.sendUserNotification(notification) -``` - -**Example:** - -```js - -describe('Foreground user notifications', () => { - -beforeEach(async () => { - await device.relaunchApp(); -}); - -it('Local notification from inside the app', async () => { - await device.sendUserNotification(localNotification); - await expect(element(by.text('from local notificaton'))).toBeVisible(); - }); -}); -``` - -## Notification JSON Format - - -User notifications are passed as JSON objects to detox, which then parses them and creates native objects representing the passed information. - -The JSON object passed to Detox needs to provide some required data, but can also provide additional, optional data. - - - -| Key | Required | Value Type | Description | -|---------------------|----------|------------|---------------------------------------------------------------------------------------------------| -| `trigger` | Yes | Object | The conditions that trigger the delivery of the notification. See the [Triggers section](https://github.com/wix/detox/wiki/User-Notifications-JSON-Format-Documentation#triggers) below. | -| `title` | No | String | A short description of the reason for the alert. | -| `subtitle` | No | String | A secondary description of the reason for the alert. | -| `body` | No | String | The body of the notification. | -| `badge` | No | Integer | The number to display as the app’s icon badge. | -| `payload` | No | Object | An object of custom information associated with the notification. | -| `category` | No | String | The identifier of the app-defined category object. | -| `content-available` | No | Integer | Include this key with a value of 1 to configure a silent notification. | -| `user-text` | No | String | The text response provided by the user. | -| `action-identifier` | No | String | The identifier for the action that the user selected. | - -### Triggers - -Triggers are objects representing the trigger. - -| Key | Required | Value Type | Description | -|-------------------|-------------------------------------|------------|-------------------------------------------------------------------------------------------------------------| -| `type` | Yes | String | The conditions that trigger the delivery of the notification.

There are four types of triggers supported by Detox at this time:
• `push`
• `calendar`
• `timeInterval`
• `location`
| -| `repeats` | No | Boolean | Indicates whether the event repeats. Only used for `calendar`, `timeInterval` and `location` trigger types. | -| `timeInterval` | Yes for `timeInterval` trigger type | Number | The time interval used to create the trigger. | -| `date-components` | Yes for `calendar` trigger type | Object | The date components used to construct this object. See the [Date Components section](https://github.com/wix/detox/wiki/User-Notifications-JSON-Format-Documentation#date-components) below. | -| `region` | Yes for `location` trigger type | Object | The region used to determine when the notification is sent. See the [Region section](https://github.com/wix/detox/wiki/User-Notifications-JSON-Format-Documentation#region) below. | - -### Date Components - -| Key | Required | Value Type | Description | -|------------------|----------|------------|-------------------------------------------------------| -| `era` | No | Integer | The number of era units for the receiver. | -| `year` | No | Integer | The number of year units for the receiver. | -| `month` | No | Integer | The number of month units for the receiver. | -| `day` | No | Integer | The number of day units for the receiver. | -| `hour` | No | Integer | The number of hour units for the receiver. | -| `minute` | No | Integer | The number of minute units for the receiver. | -| `second` | No | Integer | The number of second units for the receiver. | -| `weekday` | No | Integer | The number of the weekday unit for the receiver. | -| `weekdayOrdinal` | No | Integer | The ordinal number of weekday units for the receiver. | -| `quarter` | No | Integer | The number of quarters for the receiver. | -| `weekOfMonth` | No | Integer | The week number of the month for the receiver. | -| `leapMonth` | No | Boolean | Indicates whether the month is a leap month. | - -### Region - -| Key | Required | Value Type | Description | -|-----------------|----------|------------|------------------------------------------------------------------------------------| -| `center` | Yes | Object | The center point of the geographic area. See the [Coordinate section](https://github.com/wix/detox/wiki/User-Notifications-JSON-Format-Documentation#coordinate) below. | -| `radius` | Yes | Number | The radius (measured in meters) that defines the geographic area’s outer boundary. | -| `notifyOnEntry` | No | Boolean | Indicates that notifications are generated upon entry into the region. | -| `notifyOnExit` | No | Boolean | Indicates that notifications are generated upon exit from the region. | - -### Coordinate - -| Key | Required | Value Type | Description | -|-------------|----------|------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `latitude` | Yes | Number | The latitude in degrees. Positive values indicate latitudes north of the equator. Negative values indicate latitudes south of the equator. | -| `longitude` | Yes | Number | The longitude in degrees. Measurements are relative to the zero meridian, with positive values extending east of the meridian and negative values extending west of the meridian. | - -### Examples - -1. [Calendar Trigger](https://github.com/wix/detox/blob/master/detox/ios/DetoxUserNotificationTests/user_notification_calendar_trigger.json) -2. [Location Trigger](https://github.com/wix/detox/blob/master/detox/ios/DetoxUserNotificationTests/user_notification_location_trigger.json) -3. [Time Interval Trigger](https://github.com/wix/detox/blob/master/detox/ios/DetoxUserNotificationTests/user_notification_timeInterval_trigger.json) -4. [Push Trigger](https://github.com/wix/detox/blob/master/detox/ios/DetoxUserNotificationTests/user_notification_push_trigger.json) diff --git a/website/versioned_docs/version-6.X/APIRef.TestLifecycle.md b/website/versioned_docs/version-6.X/APIRef.TestLifecycle.md deleted file mode 100644 index 1ca71d32bc..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.TestLifecycle.md +++ /dev/null @@ -1,50 +0,0 @@ ---- -id: version-6.X-APIRef.TestLifecycle -title: Test Lifecycle -original_id: APIRef.TestLifecycle ---- - -Detox is test runner independent, and we encourge you to choose your own test runner, but for the sake of demonstration we will use `mocha`'s syntax. - - -### Initial Setup -The setup phase happens inside `detox.init()`. This is the phase where detox reads its configuration, starts a server, loads its expection library and starts a simulator. - -```js -const config = require('../package.json').detox; - -before(async () => { - await detox.init(config); -}); -``` - -Of course, you can add any of your initilizations in this phase. - -### Teardown -The cleanup phase should happen after all the tests have finished, can be initiated using `detox.cleanup()`. This is the phase where detox-server shuts down. The simulator will also shut itself down if `--cleanup` flag is added to `detox test` - -```js -after(async () => { - await detox.cleanup(); -}); -``` - -### Repeating Setup For All Tests - -A good practice for testing in general is to have decoupled tests, meaning that each test has the same starting point, and the tests can run in any order and still produce the same results. We strongly encourage either restarting your application or restart react-native (if your application is built with it). - -##### Reloading React Native - -```js - beforeEach(async () => { - await device.reloadReactNative(); - }); -``` - -##### Reloading The Entire App - -```js - beforeEach(async () => { - await device.relaunchApp(); - }); -``` diff --git a/website/versioned_docs/version-6.X/APIRef.waitFor.md b/website/versioned_docs/version-6.X/APIRef.waitFor.md deleted file mode 100644 index 96b0e774f3..0000000000 --- a/website/versioned_docs/version-6.X/APIRef.waitFor.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: version-6.X-APIRef.waitFor -title: Manual Synchronization Using `waitFor` -original_id: APIRef.waitFor ---- - -In most cases, tests should be automatically synchronized with the app. When synchronization doesn't work, you have a fail-safe by using `waitFor`. This API polls using the given expectation continuously until the expectation is met. Use manual synchronization with `waitFor` only as a **last resort**. Polling for expectations isn't exactly a best practice. - -Test async code with waitFor.
-**Hang the test until an expectation is met.** - -### Methods - -- [`.toBeVisible()`](#tobevisible) -- [`.toBeNotVisible()`](#tobenotvisible) -- [`.toExist()`](#toexist) -- [`.toNotExist()`](#tonotexist) -- [`.toHaveText()`](#tohavetexttext) -- [`.toHaveValue()`](#tohavevaluevalue) -- [`.withTimeout()`](#withtimeoutmillis) -- [`.whileElement()`](#whileelement) - ->NOTE: Every `waitFor` call must set a timeout using `withTimeout()`. Calling `waitFor` without setting a timeout **will do nothing**. - ->NOTE: `waitFor` will not throw when reaching timeout, instead it will just continue to the next line. To make sure your tests work as you expect them to add `expect()` at the following line. - -### `toBeVisible()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toBeVisible()`](APIRef.Expect.md#tobevisible)
-Wait for the view to be at least 75% visible. - -```js -await waitFor(element(by.id('UniqueId204'))).toBeVisible().withTimeout(2000); -await expect(element(by.id('UniqueId204'))).toBeVisible(); -``` - -### `toBeNotVisible()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toBeNotVisible()`](APIRef.Expect.md#tobenotvisible)
-Wait for the view to not be visible. - -```js -await waitFor(element(by.id('UniqueId205'))).toBeNotVisible().withTimeout(2000); -await expect(element(by.id('UniqueId205'))).toBeNotVisible(); -``` - -### `toExist()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toExist()`](APIRef.Expect.md#toexist)
-Wait for the view to exist in the UI hierarchy. - -```js -await waitFor(element(by.id('UniqueId205'))).toExist().withTimeout(2000); -await expect(element(by.id('UniqueId205'))).toExist(); -``` - -### `toNotExist()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toNotExist()`](APIRef.Expect.md#tonotexist)
-Wait for the view to not exist in the UI hierarchy. - -```js -await waitFor(element(by.id('RandomJunk959'))).toNotExist().withTimeout(2000); -await expect(element(by.id('RandomJunk959'))).toNotExist(); -``` - -### `toHaveText(text)` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toHaveText(text)`](APIRef.Expect.md#tohavetexttext)
-- In React Native apps, expect UI component of type `` to have text. -- In native iOS apps, expect UI elements of type UIButton, UILabel, UITextField or UITextViewIn to have inputText with text. - -```js -await waitFor(element(by.id('UniqueId204'))).toHaveText('I contain some text').withTimeout(2000); -await expect(element(by.id('UniqueId204'))).toHaveText('I contain some text'); -``` - -### `toHaveValue(value)` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toHaveValue(value)`](APIRef.Expect.md#tohavevaluevalue)
- -- In React Native apps, expect UI component to have [`testID`](https://facebook.github.io/react-native/docs/view.html#testid) with that id. -- In native iOS apps, expect UI element to have accesibilityIdentifier with that id. - -```js -await waitFor(element(by.id('uniqueId'))).toHaveValue('Some value').withTimeout(2000); -await expect(element(by.id('uniqueId'))).toHaveValue('Some value'); -``` - - -### `withTimeout(millis)` -Waits for the condition to be met until the specified time (millis) have elapsed. - -```js -await waitFor(element(by.id('UniqueId336'))).toExist().withTimeout(2000); -await expect(element(by.id('UniqueId336'))).toExist(); -``` - - -### `whileElement(element)` -Performs the action repeatedly on the element until an expectation is met. - -```js -await waitFor(element(by.text('Text5'))).toBeVisible().whileElement(by.id('ScrollView630')).scroll(50, 'down'); -await expect(element(by.text('Text5'))).toBeVisible(); -``` diff --git a/website/versioned_docs/version-6.X/Guide.Contributing.md b/website/versioned_docs/version-6.X/Guide.Contributing.md deleted file mode 100644 index 161b012189..0000000000 --- a/website/versioned_docs/version-6.X/Guide.Contributing.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: version-6.X-Guide.Contributing -title: Contributing -original_id: Guide.Contributing ---- - -## Prerequisites - -### Install `node` v7.6 or higher (to support async-await natively) - -``` -brew install node -``` - -### Install global node libraries `lerna` and `react-native-cli` - -```sh -npm install -g lerna -npm install -g react-native-cli -``` - -For all the internal projects (detox, detox-server, detox-cli, demos, test) `lerna` will create symbolic links in `node_modules` instead of `npm` copying the content of the projects. This way, any change you do on any code is there immediately. There is no need to update node modules or copy files between projects. - -### Install `xcpretty` - -```sh -gem install xcpretty -``` - -Alternatively, run `scripts/install.ios.sh` / `scripts/android.sh` to install all prerequisites. - -## Detox - -### Clone Detox and submodules - -```sh -git clone git@github.com:wix/detox.git -cd detox -git submodule update --init --recursive -``` -(this makes sure all git submodule dependencies are properly checked out) - -### Installing and linking internal projects - -```sh -lerna bootstrap -``` - -### Building - -```sh -lerna run build -``` - -### Testing - -### 1. Unit tests - -```sh -lerna run test -``` - -Detox JS code is 100% test covered and is set to break the build if coverage gets below, so make sure you run unit tests (`lerna run test`) locally before pushing. - -Alternatively, to run only the JS tests, run the following from the `detox/detox` directory: - -```sh -npm run unit --or- -npm run unit:watch -``` - -#### How to read the coverage report -After running the tests, jest will create a coverage report. - -```sh -cd detox -open coverage/lcov-report/index.html -``` - -### 2. Running Detox e2e coverage tests -Detox has a suite of e2e tests to test its own API while developing (and for regression). The way we do is is by maintaining a special application that is "tested" against Detox's API, but essentially, it's the API that is tested, not the app. -To run the e2e tests, go to `detox/detox/test` - -```sh -cd detox/test -``` - - -```sh -npm run build -``` - -To run the e2e tests, after the application was built. - -#### iOS -```sh -npm run build:ios -npm run e2e:ios -``` - -#### Android -```sh -npm run build:android -npm run e2e:android -``` - -### 3. Android Native tests - -0. Install Java and Android SDK 25 -1. In `detox/android` run `./gradlew install` run - - ```sh - ./gradlew test - ``` - -### 4. Code Generation - -We are using a code generator based on `babel` and `objective-c-parser` to generate a Javascript Interface for `EarlGrey` (the testing library we use on iOS). -This interface allows us to call Objective-C methods through the WebSocket connection directly on the testing device. - -This approach is currently limited to `GREYActions`, but we plan on extending it to cover more functionality of `EarlGrey`. -You may see the generated files under [`detox/src/ios/earlgreyapi/`](../detox/src/ios/earlgreyapi). - -What happens under the hood can be seen in [`generation/`](../generation); it boils down to these steps for each input file: - -1. Convert Objective-C header file in a JSON Representation -2. Build an Abstract Syntax Tree: Create Class & for each method - 1. Check if the type can be expressed simpler (`NSString *` => `NSString`) - 2. Get the type checks for the arguments - 2. Get the return value - 4. Assemble type checks and return value to complete function -3. Generate the code for the syntax tree & add helpers - -If you would like to extend the code generation, please make sure to read the [`generation/README.md`](../generation#generation) diff --git a/website/versioned_docs/version-6.X/Guide.DebuggingInXcode.md b/website/versioned_docs/version-6.X/Guide.DebuggingInXcode.md deleted file mode 100644 index d7b3286080..0000000000 --- a/website/versioned_docs/version-6.X/Guide.DebuggingInXcode.md +++ /dev/null @@ -1,85 +0,0 @@ ---- -id: version-6.X-Guide.DebuggingInXcode -title: Debugging Apps in Xcode During a Test -original_id: Guide.DebuggingInXcode ---- - -> Advanced users might need to natively debug their app inside Xcode during a Detox test. This is mostly useful for invesigating weird crahses or when contributing to Detox itself. - -This workflow isn't standard. Don't use it unless you have a good reason. - -
- -## Step 1: Add Detox framework to your project - -Open your Xcode project and drag `Detox.framework` from `node_modules/detox/Detox.framework` to your project. - -> NOTE: Apps should not be submitted to the App Store with the Detox framework linked. Follow this guide only to debug Detox issues in your project. Once finished, make sure to remove `Detox.framework` from your project. - -
- -## Step 2: Add launch arguments - -Edit your project scheme and add the following arguments to **Arguments Passed On Launch**: - -``` --detoxServer -ws://localhost:8099 --detoxSessionId -test -``` - -
- -## Step 3: Add custom session to Detox config - -Edit Detox config in `package.json` to [add a custom session](/docs/APIRef.Configuration.md#server-configuration) by adding the `session` key under the `detox` section: - -```json -"detox": { - "session": { - "server": "ws://localhost:8099", - "sessionId": "test" - } -} -``` - -
- -## Step 4: Add a special xcode configuration to Detox config - -Edit Detox config in `package.json` by adding a new configuration with type `ios.none` to the `configurations` key under the `detox` section: - -```json -"detox": { - "configurations": { - "xcode": { - "type": "ios.none" - } - } -} -``` - -> NOTE: This configuration will not handle simulator and application lifecycle, they will have to be provided manually (via Xcode "Play" button or `react-native run-ios`). - -
- -## Step 5: Run Detox server manually - -Type the following inside your project root: - -```sh -detox run-server -``` - -
- -## Step 6: Run Detox tests - -Type the following inside your project root: - -```sh -detox test --configuration xcode -``` - -> NOTE: Tests that expect the app to be restarted via `device.relaunchApp()` will fail. diff --git a/website/versioned_docs/version-6.X/Guide.DevelopingWhileWritingTests.md b/website/versioned_docs/version-6.X/Guide.DevelopingWhileWritingTests.md deleted file mode 100644 index 2521d0d339..0000000000 --- a/website/versioned_docs/version-6.X/Guide.DevelopingWhileWritingTests.md +++ /dev/null @@ -1,75 +0,0 @@ ---- -id: version-6.X-Guide.DevelopingWhileWritingTests -title: Developing Your App While Writing Tests -original_id: Guide.DevelopingWhileWritingTests ---- - -> If your app requires active development, such as adding testID fields for tests, this is a good workflow. It allows you to work both on your app and your tests at the same time. - -The main idea behind this workflow is to run your app in debug with Detox on a simulator. Once the app is up and running, it will still be connected to the React Native packager. This means that you'll be able to do JavaScript code modifications in your app codebase and press CMD+R to reload the bundle inside the Detox simulator. - -
- -## Step 1: Build your app in debug - -Detox is going to need the executable for your app. This means we need to build it first. Since we want a build that's connected to the live React Native packager (to update bundle changes), we're going to need a *debug* build. - -There are multiple ways to build your app, let's find the alternative you like best: - -* **I like to build my app by clicking "Play" in Xcode**
This isn't a great approach here because using Xcode IDE to build your app will place the executable in an internal directory which path that is difficult to predict (`~/Library/Developer/Xcode/DerivedData/...`). This means we won't be able to tell Detox where to find it. Although you can change the default derivedData path by altering your Xcode settings, we encourge you to try the alternative ways to build. - -* **I like to build my app with `react-native run-ios`**
The official React Native command line tools provide a script to build your app from terminal. Go to your project root and type `react-native run-ios`. This will build the app in debug and place the executable in the folder `ios/build/Build/Products/Debug-iphonesimulator`. This is a great way to build because it's easy to specify this path in Detox configuration inside `package.json`. This is actually the path we specified in the getting started tutorial. - - ```sh - react-native run-ios - ``` - -* **I like to build my app with `detox build`**
During the installation instructions, we provided Detox configuration in `package.json` with a command line to build your app executable. We can execute this build command by going to the project root and typing `detox build`. Please make sure that you're using a Detox configuration that builds a debug version of your app. The default we specified in the getting started tutorial should work. - - ```sh - detox build - ``` - -> TIP: Running `react-native run-ios` will also start a simulator and install your app on it, running `detox test` later will possibly start a different simulator, so you'll find yourself with two open simulators. You can safely close the simulator started by `react-native`, everything will continue working as expected. - -
- -## Step 2: Make sure your react-native packager is running - -If you can't see a React Native packager instance running in a terminal, you can run it manually by typing: - -```sh -react-native start -``` - -The packager instance will reload the JavaScript bundle of your app when you press CMD+R in the simulator window. This will allow you to make modifications in your app codebase. - -
- -## Step 3: Run Detox tests - -Type the following inside your project root: - -```sh -detox test -``` - -This will use Detox to find the app executable we've built in step 1, install it on a simulator and run Detox tests against it. - -
- -## Step 4: Make changes to your app codebase as usual - -You can keep working on the JavaScript codebase of your app as usual. As long as you keep the simulator from step 3 running, you'll be able to press CMD+R inside and reload your app with the new changes. - -
- -## Step 5: Re-run Detox tests without re-installing the app - -You can make changes to your Detox tests as well. When you want to run your tests on the simulator, we recommed using the following command: - -```sh -detox test --reuse -``` - -The reuse option will prevent Detox from compiling and re-installing your app again in the simulator. The tests will simply run against the current app instance currently running in the simulator. This will make the process much faster. diff --git a/website/versioned_docs/version-6.X/Guide.Jest.md b/website/versioned_docs/version-6.X/Guide.Jest.md deleted file mode 100644 index 2a41430ec0..0000000000 --- a/website/versioned_docs/version-6.X/Guide.Jest.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: version-6.X-Guide.Jest -title: Jest -original_id: Guide.Jest ---- - -## Usage - -### 0. Use the [Getting Started](Introduction.GettingStarted.md) Guide to set up detox - -Except that you need to skip the install mocha step. - -### 1. Install Jest - -```sh -npm install --save-dev jest -``` - -### 2. Remove mocha specific files - -You should remove `e2e/mocha.opts`, you no longer need it. - -### 3. Replace generated detox setup file (e2e/init.js) - -```js -const detox = require('detox'); -const config = require('../package.json').detox; - -// Set the default timeout -jasmine.DEFAULT_TIMEOUT_INTERVAL = 120000; - -beforeAll(async () => { - await detox.init(config); -}); - -afterAll(async () => { - await detox.cleanup(); -}); -``` - -### 4. Configure Detox to run with Jest - -Add a Jest config file `e2e/config.json`: - -```json -{ - "setupTestFrameworkScriptFile" : "./init.js" -} -``` - - -In `package.json`: - -```json -"scripts": { - "test:e2e": "detox test -c ios.sim.debug", - "test:e2e:build": "detox build" -}, -"detox": { - "test-runner": "jest", - "runner-config": "e2e/config.json" - ... -} -``` - -### Writing Tests - -There are some things you should notice: - -- Don't worry about mocks being used, detox works on the compiled version of your app. -- Detox exposes it's primitives (`expect`, `device`, ...) globally, it will override Jest's global `expect` object. - -## How to run unit test and E2E tests in the same project - -- If you have a setup file for the unit tests pass `./jest/setup` implementation into your unit setup. -- Call your E2E tests using `detox-cli`: `detox test` diff --git a/website/versioned_docs/version-6.X/Guide.Migration.md b/website/versioned_docs/version-6.X/Guide.Migration.md deleted file mode 100644 index 6178c12395..0000000000 --- a/website/versioned_docs/version-6.X/Guide.Migration.md +++ /dev/null @@ -1,156 +0,0 @@ ---- -id: version-6.X-Guide.Migration -title: Migration Guide -original_id: Guide.Migration ---- - -We are improving detox API as we go along, sometimes these changes require us to break the API in order for it to make more sense and. These migration guides refer to breaking changes. - -## Migrating from detox 4.x.x to 5.x.x -The clearest example for for the 4->5 API changes is the change log of detox's own test suite. -Check [detox test change log](https://github.com/wix/detox/commit/c636e2281d83d07fe0b479681c1a8a6b809823ff#diff-bf5e338e4f0bb49210688c7691dc8589) for a real life example. - -###Version 5.x.x breaks detox's API in 4 different places - -#### 1. Promise based flow -All of the API calls are now promise based, and must use either promise chains or async-await.
- -Here's an example of async call to tap an element - -```js -// <=4.x.x -beforeEach(() => { - element(by.text('Sanity')).tap(); -}); - -``` - -```js -// 5.x.x -beforeEach(async () => { - await element(by.text('Sanity')).tap(); -}); -``` - -Same thing with expectations - -```js -// <=4.x.x -it('should have welcome screen', () => { - expect(element(by.text('Welcome'))).toBeVisible(); - expect(element(by.text('Say Hello'))).toBeVisible(); - expect(element(by.text('Say World'))).toBeVisible(); -}; -``` - -```js -// 5.x.x -it('should have welcome screen', async () => { - await expect(element(by.text('Welcome'))).toBeVisible(); - await expect(element(by.text('Say Hello'))).toBeVisible(); - await expect(element(by.text('Say World'))).toBeVisible(); -}); -``` - -#### 2. `detox` object has a leaner API - -Configure and init detox with just one promise based function. - -```js -// <=4.x.x -detox.config(config); -detox.start(done); -``` - -```js -// 5.x.x -await detox.init(config); -``` - -No need to wait for test result after each test, you can safely remove `detox.waitForTestResult` - -```js -// <=4.x.x -afterEach((done) => { - detox.waitForTestResult(done); -}); -``` - -cleanup is promise based -```js -// <=4.x.x -detox.cleanup(done); -``` - -```js -// 5.x.x -await detox.cleanup(); -``` - -#### 3. `simulator` is now `device` -The global object `simulator` is now `device`, this change makes sense when thinking about multi-platform tests (Android support). -Along with the new promise based API, this is how we now control the attached device - -<=4.x.x | 5.x.x -------|-------- -`simulator.reloadReactNativeApp(done)` | `await device.reloadReactNative()` -`simulator.relaunchApp(done)` | `await device.relaunchApp()` -`simulator.sendUserNotification(params, done)` | `await device.sendUserNotification(params)` -`simulator.openURL(url)` | `await device.openURL(url)` - -#### 4. Detox config scheme -In order for our API to support multiple platforms and devices, and to be able to provide a valid command line tool, we changed the the detox configuration scheme (in package.json) - -Previous config looked like this: - -```json -//<=4.x.x - "detox": { - "session": { - "server": "ws://localhost:8099", - "sessionId": "test" - }, - "ios-simulator": { - "app": "ios/build/Build/Products/Release-iphonesimulator/example.app", - "device": "iPhone 7 Plus" - } - } -``` - -The new configuration holds a dictionary of `configurations`. - -1. Each configuration must state `type` - currently only simulator is supported -2. `app` is now `binaryPath` -3. `build` - **[optional]** build command (either `xcodebuild`, `react-native run-ios`, etc...), will be later available through detox CLI tool. -4. **session object is not mandatory anymore**, if is not provided detox will handle server creation by itself. - -```json -//5.x.x - "detox": { - "configurations": { - "ios.sim.release": { - "binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app", - "build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Release -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.simulator", - "name": "iPhone 7 Plus" - } - } - } -``` - -#### 3.1 Start using detox-cli -You will now be able to run builds and tests from your command line `detox build` and `detox test`, read more about CLI tools [here]() - -## Migrating from detox 3.x.x to 4.x.x -If you have integrated with detox in version 3.x.x, you will need to clean your project from previously generated targets. - -* Use the provided `cleanup_4.0.rb` to remove unneeded changes made with Detox 4.x.x. - - ```sh - ruby node_modules/detox/scripts/cleanup_4.0.rb - ``` - -* The script will delete previously configured project targets `*_Detox`. The targets are not used by detox anymore since the framework is now injected at runtime and doesn't need to be linked in a different target. -* Make sure to add changes performed by running this script to version control. - - diff --git a/website/versioned_docs/version-6.X/Guide.Mocking.md b/website/versioned_docs/version-6.X/Guide.Mocking.md deleted file mode 100644 index cadb0e68f4..0000000000 --- a/website/versioned_docs/version-6.X/Guide.Mocking.md +++ /dev/null @@ -1,21 +0,0 @@ ---- -id: version-6.X-Guide.Mocking -title: Mocking -original_id: Guide.Mocking ---- - -Mocking is an important part of testing. You may want to alter some behavior of your app during test and replace it with a mock. Here are some example reasons why this could be useful: - -* Change server endpoints to point to a mock/staging server instead of the regular production server -* Stub a feature the simulator doesn't support, like push notifications -* Prepare mock environment data like GPS position, Contacts/Photos found on the device, etc - -Note that mocking in end-to-end tests like in Detox is very different from mocking in unit tests like in Jest. With unit tests, the mocks can change between test case to test case. With Detox, remember that we're building the app once before all tests start. This means that mocks cannot be replaced between test cases. We'll have to assume our mock remains static during all test cases. - -We'll only concentrate on mocking by changing JavaScript files under React Native apps. - -[`react-native-repackager`](https://github.com/wix/react-native-repackager) is a great tool for this job. It extends the React Native packager’s ability to override JavaScript files with different extensions. Just like you can create `myFile.ios.js` and `myFile.android.js`, you'll be able to create `myFile.e2e.js` that will take over during Detox tests. This even works under `node_modules` which means we can publish libraries that contain ready-made mock implementations. - -This replacement mechanism provides a lot of flexibility to change implementations for testing without affecting your production code. For more information and detailed usage instructions, [read the docs](https://github.com/wix/react-native-repackager/blob/master/README.md). - -**Note:** Repackager is currently only available for RN 0.44. We are planning to update it soon for modern RN versions. diff --git a/website/versioned_docs/version-6.X/Guide.RunningLocally.md b/website/versioned_docs/version-6.X/Guide.RunningLocally.md deleted file mode 100644 index 44fa3249ed..0000000000 --- a/website/versioned_docs/version-6.X/Guide.RunningLocally.md +++ /dev/null @@ -1,36 +0,0 @@ ---- -id: version-6.X-Guide.RunningLocally -title: Running Locally -sidebar_label: Running Tests Locally -original_id: Guide.RunningLocally ---- - -> If your app is ready and does not require any active development, you can write your tests using this workflow and run them locally on your machine. This is convenient for developing your test suite without actively developing your app. - -This is the basic workflow. It takes your app executable and runs Detox tests against it. - -
- -## Step 1: Build your app - -Detox is going to need the executable for your app. This means we need to build it first. We're going to use the Detox command line tools to build the app. During the installation, we've specified the actual build command line inside `package.json` under the `detox` configuration section. - -Build the app by typing in terminal inside your project root: - -```sh -detox build -``` - -> TIP: After build, the app executable should be found in the path specified inside `package.json` under the `detox` configuration section (`binaryPath`). That's where Detox is going to look for it. - -
- -## Step 2: Run Detox tests - -Type the following inside your project root: - -```sh -detox test -``` - -This will use Detox to find the app executable we've built in step 1, install it on a simulator and run Detox tests against it. diff --git a/website/versioned_docs/version-6.X/Guide.RunningOnCI.md b/website/versioned_docs/version-6.X/Guide.RunningOnCI.md deleted file mode 100644 index 26cd252fba..0000000000 --- a/website/versioned_docs/version-6.X/Guide.RunningOnCI.md +++ /dev/null @@ -1,159 +0,0 @@ ---- -id: version-6.X-Guide.RunningOnCI -title: Running On CI -original_id: Guide.RunningOnCI ---- - -> When your test suite is finally ready, it should be set up to run automatically on your CI server on every git push. This will alert you if new changes to the app break existing functionality. - -Running detox on CI is not that different from running it locally. There are two main differences: -1. We will test a release build rather than a debug build -2. We will tell Detox to shut down the simulator when test is over - -
- -## Step 1: Prepare a release configuration for your app - -We will need to create a [release device configuration for Detox](/docs/APIRef.Configuration.md#device-configuration) inside `package.json` under the `detox` section. - -**Example:** - -```json -"detox": { - "configurations": { - "ios.sim.release": { - "binaryPath": "ios/build/Build/Products/Release-iphonesimulator/example.app", - "build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Release -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.simulator", - "name": "iPhone 7" - } - } -} -``` - -> TIP: Notice that the name `example` above should be replaced with your actual project name. - -
- -## Step 2: Add build and test commands to your CI script - -Assuming your CI is executing some sort of shell script, add the following commands that should run inside the project root: - -```sh -detox build --configuration ios.sim.release -detox test --configuration ios.sim.release --cleanup -``` - -> TIP: Adding `--cleanup` to the test command will make sure detox exits cleanly by shutting down the simulator when the test is over. - -
- -## Appendix - -### • Running Detox on [Travis CI](https://travis-ci.org/) - -Detox's own build is running on Travis, check out Detox's [.travis.yml](/.travis.yml) file to see how it's done. - -This is a simple example configuration to get you started with Detox on Travis: - -```yaml -language: objective-c -osx_image: xcode8.3 - -branches: - only: - - master - -env: - global: - - NODE_VERSION=stable - -install: -- curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.2/install.sh | bash -- export NVM_DIR="$HOME/.nvm" && [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh" -- nvm install $NODE_VERSION -- nvm use $NODE_VERSION - -- npm install -g react-native-cli -- npm install -g detox-cli - -script: -- detox build --configuration ios.sim.release -- detox test --configuration ios.sim.release --cleanup - -``` - -### • Running Detox on [Bitrise](https://www.bitrise.io/) - -Bitrise is a popular CI service for automating React Native apps. If you are looking to get started with Bitrise, check out [this](http://blog.bitrise.io/2017/07/25/how-to-set-up-a-react-native-app-on-bitrise.html) guide. - -You can run Detox on Bitrise by creating a new workflow. Below is an example of the Bitrise **.yml** file for a workflow called `tests`. - -Additionally, you can use a [webhook](http://devcenter.bitrise.io/webhooks/) on Bitrise to post the build status directly into your Slack channel. - -```yml ---- -format_version: 1.1.0 -default_step_lib_source: https://github.com/bitrise-io/bitrise-steplib.git -trigger_map: -- push_branch: "*" - workflow: tests -workflows: - _tests_setup: - steps: - - activate-ssh-key: {} - - git-clone: - inputs: - - clone_depth: '' - title: Git Clone Repo - - script: - inputs: - - content: |- - #!/bin/bash - - npm cache verify - - npm install - title: Install NPM Packages - before_run: - after_run: - _detox_tests: - before_run: [] - after_run: [] - steps: - - npm: - inputs: - - command: install -g detox-cli - title: Install Detox CLI - - npm: - inputs: - - command: install -g react-native-cli - title: Install React Native CLI - - script: - inputs: - - content: |- - #!/bin/bash - - brew tap wix/brew - brew install applesimutils --HEAD - title: Install Detox Utils - - script: - inputs: - - content: |- - #!/bin/bash - - detox build --configuration ios.sim.release - title: Detox - Build Release App - - script: - inputs: - - content: |- - #!/bin/bash - - detox test --configuration ios.sim.release --cleanup - title: Detox - Run E2E Tests - tests: - before_run: - - _tests_setup - - _detox_tests - after_run: [] -``` diff --git a/website/versioned_docs/version-6.X/Introduction.Android.md b/website/versioned_docs/version-6.X/Introduction.Android.md deleted file mode 100644 index 58df85294a..0000000000 --- a/website/versioned_docs/version-6.X/Introduction.Android.md +++ /dev/null @@ -1,143 +0,0 @@ ---- -id: version-6.X-Introduction.Android -title: Detox for Android -original_id: Introduction.Android ---- - -## Setup -Detox 7 was updated to support Android gradle plugin 3.0.0. This is a breaking change that makes it impossible to support previous Android gradle plugin versions. - -https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html - -For older Android gradle plugin support use `detox@6.x.x` instead ([previous setup guide here](https://github.com/wix/detox/blob/97654071573053def90e8207be8eba011408f977/docs/Introduction.Android.md)).
-**Detox 6 will not continue to be updated, to continue getting updates and features, update your Android gradle config and migrate to Detox 7.** - -### 1. Do the initial setup described in the Getting Started Guide - -- [Getting Started](Introduction.GettingStarted.md) - -### 2. Add Detox dependency to an Android project - -In `android/settings.gradle` add: - -```gradle -include ':detox' -project(':detox').projectDir = new File(rootProject.projectDir, '../node_modules/detox/android/detox') -``` - -In `android/app/build.gradle` add this to `defaultConfig` section: - -```gradle - defaultConfig { - ... - testBuildType System.getProperty('testBuildType', 'debug') //this will later be used to control the test apk build type - missingDimensionStrategy "minReactNative", "minReactNative46" //read note - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - ... - } -``` -Please be aware that the `minSdkVersion` needs to be at least 18. - -> ###### Choosing the right build type (in missingDimensionStrategy) ->Detox runs on multiple React Native versions, choose the correct build type to support the version you use.
->**Available versions:** -> ->* `minReactNative44`: Support for React Native 0.44-0.45 ->* `minReactNative46`: Support for React Native 0.46+ - - -In `android/app/build.gradle` add this in `dependencies` section: - -```gradle -dependencies { - ... - androidTestImplementation(project(path: ":detox")) - androidTestImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test:rules:1.0.1' - ... -} -``` - -In `android/build.gradle` add this to`buildscript > dependencies`: - -```gradle -classpath 'com.palantir:jacoco-coverage:0.4.0' -``` - -And in the same file you need to add this under `allprojects > repositories`: - -```gradle -buildscript { - repositories { - ... - google() - ... - } -} -``` - -### 3. Create Android Test class - -You need to add the file `android/app/src/androidTest/java/com/[your.package]/DetoxTest.java` and fill it like [this](../detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java), expect that you need to change the package to your projects name. - -### 4. Add Android configuration - -Add this part to your `package.json`: - -```json -"detox" : { - "configurations": { - "android.emu.debug": { - "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", - "build": - "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", - "type": "android.emulator", - "name": "Nexus_5X_API_24" - }, - "android.emu.release": { - "binaryPath": "android/app/build/outputs/apk/release/app-release.apk", - "build": - "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..", - "type": "android.emulator", - "name": "Nexus_5X_API_26" - } - } -} -``` -Pay attention to `-DtestBuildType`, set either to `debug` or `release` according to the main apk type. - - -Following device types could be used to control Android devices: - -`android.emulator`. Boot stock SDK emulator with provided `name`, for example `Nexus_5X_API_25`. After booting connect to it. - -`android.attached`. Connect to already-attached android device. The device should be listed in the output of `adb devices` command under provided `name`. -Use this type to connect to Genymotion emulator. - -### 5. Run the tests - -Using the `android.emu.debug` configuration from above, you can invoke it in the standard way. - -```sh -detox test -c android.emu.debug -``` - -## Troubleshooting - -### Problem: `Duplicate files copied in ...` - -If you get an error like this: - -```sh -Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'. -> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/LICENSE -``` - -You need to add this to the `android` section of your `android/app/build.gradle`: - -```gradle -packagingOptions { - exclude 'META-INF/LICENSE' -} -``` diff --git a/website/versioned_docs/version-6.X/Introduction.GettingStarted.md b/website/versioned_docs/version-6.X/Introduction.GettingStarted.md deleted file mode 100644 index 14a7249fd9..0000000000 --- a/website/versioned_docs/version-6.X/Introduction.GettingStarted.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: version-6.X-Introduction.GettingStarted -title: Getting Started -original_id: Introduction.GettingStarted ---- - -This is a step-by-step guide for adding Detox to your React Native project. - -> TIP: You can also check out this [awesome tutorial](https://medium.com/@bogomolnyelad/how-to-test-your-react-native-app-like-a-real-user-ecfc72e9b6bc) on Medium with video by [@bogomolnyelad](https://medium.com/@bogomolnyelad) - -
- -## Prerequisites - -Running Detox (on iOS) requires the following: - -* Mac with macOS (at least macOS El Capitan 10.11) - -* Xcode 8.3+ with Xcode command line tools -> TIP: Verify Xcode command line tools is installed by typing `gcc -v` in terminal (shows a popup if not installed) - -* A working [React Native](https://facebook.github.io/react-native/docs/getting-started.html) app you want to test - -
- -## Step 1: Install dependencies - -#### 1. Install the latest version of [Homebrew](http://brew.sh) - -Homebrew is a package manager for macOS, we'll need it to install other command line tools. - -> TIP: Verify it works by typing in terminal `brew -h` to output list of available commands - -#### 2. Install [Node.js](https://nodejs.org/en/) - -Node is the JavaScript runtime Detox will run on. **Install Node 7.6.0 or above for native async-await support** - - ```sh - brew update && brew install node - ``` - -> TIP: Verify it works by typing in terminal `node -v` to output current node version, should be higher than 7.6.0 - -#### 3. Install [appleSimUtils](https://github.com/wix/AppleSimulatorUtils) - -A collection of utils for Apple simulators, Detox uses it communicate with the simulator. - -```sh -brew tap wix/brew -brew install --HEAD applesimutils -``` - -> TIP: Verify it works by typing in terminal `applesimutils` to output the tool help screen - -#### 4. Install Detox command line tools (detox-cli) - -This package makes it easier to operate Detox from the command line. `detox-cli` should be installed globally, enabling usage of the command line tools outside of your npm scripts. - - ```sh - npm install -g detox-cli - ``` -> TIP: Verify it works by typing in terminal `detox -h` to output the list of available commands - -
- -## Step 2: Add Detox to your project - -#### 1. Install detox - -Go to the root folder of your React Native app (where `package.json` is found): - -```sh -npm install detox --save-dev -``` - -#### 2. Install mocha - -You can use any JavaScript test runner -- [Jest](Guide.Jest.md) -- [Mocha](https://mochajs.org/) is a good one we recommend: - -```sh -npm install mocha --save-dev -``` - -#### 3. Add Detox config to package.json - -The basic configuration for Detox should be in your `package.json` file under the `detox` property: - -```json -"detox": { - "configurations": { - "ios.sim.debug": { - "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app", - "build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.simulator", - "name": "iPhone 7" - } - } -} -``` - -In the above configuration example, change `example` to your actual project name. Under the key `"binaryPath"`, `example.app` should be `.app`. Under the key `"build"`, `example.xcodeproj` should be `.xcodeproj` and `-scheme example` should be `-scheme `. - -For iOS apps in a workspace (eg: Cocoapods) use `-workspace ios/example.xcworkspace` instead of `-project`. - -Also make sure the simulator model specified under the key `"name"` (`iPhone 7` above) is actually available on your machine (it was installed by Xcode). Check this by typing `xcrun simctl list` in terminal to display all available simulators. - -> TIP: To test a release version, replace 'Debug' with 'Release' in the binaryPath and build properties. For full configuration options see Configuration under the API Reference. - -
- -## Step 3: Create your first test (using mocha test runner) - -You can do this automatically by running: - -```sh -detox init -``` - -Or you can do this manually instead by following these steps: - -* Create an `e2e` folder in your project root -* Create `mocha.opts` file inside with this [content](/examples/demo-react-native/e2e/mocha.opts) -* Create `init.js` file inside with this [content](/examples/demo-react-native/e2e/init.js) -* Create your first test `firstTest.spec.js` inside with content similar to [this](/examples/demo-react-native/e2e/example.spec.js) - -> TIP: Detox is not tightly coupled to Mocha or this directory structure, both are just a recommendation and are easy to replace without touching the internal implementation of Detox itself. - -
- -## Step 4: Build your app and run Detox tests - -#### 1. Build your app - -Use the Detox command line tools to build your project easily: - -```sh -detox build -``` - -> TIP: Notice that the actual build command was specified in the Detox configuration above - -#### 2. Run the tests (finally) - -Use the Detox command line tools to test your project easily: - -```sh -detox test -``` - -That's it. Your first failing Detox test is running! - -Next, we'll go over usage and how to make this test [actually pass](Introduction.WritingFirstTest.md). diff --git a/website/versioned_docs/version-6.X/Introduction.HowDetoxWorks.md b/website/versioned_docs/version-6.X/Introduction.HowDetoxWorks.md deleted file mode 100644 index f2abc3a2f1..0000000000 --- a/website/versioned_docs/version-6.X/Introduction.HowDetoxWorks.md +++ /dev/null @@ -1,53 +0,0 @@ ---- -id: version-6.X-Introduction.HowDetoxWorks -title: How Detox Works -original_id: Introduction.HowDetoxWorks ---- - -Detox is an end-to-end testing framework. This means it runs your app on an actual device/simulator and interacts with it just like a real user would. This type of tests can give a lot of confidence for releasing your app and help automate a manual QA process. If you're coming from a web background, it's very similar in concept to [protractor](http://www.protractortest.org/#/). - -When a Detox test executes, you actually have two different parts running side by side: - -* **The mobile app itself.** Usually running on a simulator. Real devices will also be supported soon. A regular native build of your app is installed and executed on the device. Your app is usually built once before the tests start running. - -* **The test suite.** Running on Node.js using a test runner like Mocha. The tests are normally written in JavaScript. This part is running outside the app and communicates with the app on the device over the network using a websocket (HTTP). Because the tests are asynchronous in nature (every test line requires to access the app and wait for a response), the tests rely heavily on [async-await](https://ponyfoo.com/articles/understanding-javascript-async-await). - -The two parts are usually running in separate processes on your machine. It is also possible to run the two parts on different machines. Communication between the two parts takes place over the network using a websocket. - -In practice, to make the communication more resilient, both parts are implemented as clients and communicate with a Detox server that acts as proxy. This allows some nice behaviors like allowing one side to disconnect (during a simulator boot for example or app restart) without disconnecting the other side and losing its state. - -### How Detox Automatically Synchronizes With Your App - -One of the key features of Detox is its ability to automatically synchronize the test execution with your app. The most annoying aspect of end-to-end tests is flakiness - tests sometimes fail without anything changing. Flakiness happens because tests are nondeterministic. Every time a test is running, things take place in a slightly different order inside your app. - -Consider a scenario where the app is making multiple network requests at the same time. What is the order of execution? It depends on which request completes first. This is an external concern depending on network congestion and how busy the server is. - -The traditional method of dealing with flakiness is adding various "sleep" commands throughout the test in an attempt to force a certain execution order. This is a bad practice riddled with fragile magic values that often change if the machine running the tests becomes faster or slower. - -Detox eliminates flakiness by automatically synchronizing your tests with the app. A test cannot continue to the next line if the app is busy. The test will only resume when the app becomes idle. Detox monitors your app very closely in order to know when it's idle. It tracks several asynchronous operations and waits until they complete. This includes: - -* Keeping track of all network requests that are currently in-flight and waiting until they complete -* Keeping track of pending animations and waiting until they complete -* Keeping track of timers (like `setTimeout`) and waiting until they expire -* Keeping track of the React Native bridge which carries asynchronous messages -* Keeping track of asynchronous React Native layout and the shadow queue -* Keeping track of the JavaScript event loop which may contain pending asynchronous actions - - -### Architecture -The sequence diagram below shows the general communication scheme between the components in Detox. -![architecture overview](img/action-sequence.mmd.png) - -To understand this topic more thoroughly we need to have a look at an example action in detail. The numbers in the listing below correlate with the ones in the diagram. - -### Action (`element.tap`) - -1. `element.tap()` in your test case is invoked. -2. `TapAction` in [`expect.js`](https://github.com/wix/detox/blob/master/detox/src/ios/expect.js) gets invoked -3. `TapAction` instance gets passed to [`invoke.js`](https://github.com/wix/detox/blob/master/detox/src/invoke.js), where it gets transformed to JSON. The resulting JSON correlates more with the native code than with the JS code for better extensibility. -4. JSON gets send to detox-server by [`Client.js`](https://github.com/wix/detox/blob/master/detox/src/client/Client.js) -6. detox-server forwards it to the testee in [`DetoxServer.js`](https://github.com/wix/detox/blob/master/detox-server/src/DetoxServer.js) -7. [`DetoxManager.m`](https://github.com/wix/detox/blob/master/detox/ios/Detox/DetoxManager.m) invokes the [`TestRunner.m`](https://github.com/wix/detox/blob/master/detox/ios/Detox/TestRunner.m). `TestRunner.m` uses [`MethodInvocation.m`](https://github.com/wix/detox/blob/master/detox/ios/Detox/MethodInvocation.m) to map the JSON representation of the native commands into the actual native command and executes it. *(8)* - - -*NOTE: the images can be updated with [mermaid](http://knsv.github.io/mermaid/#mermaid). The files can be found under `img-src`* diff --git a/website/versioned_docs/version-6.X/Introduction.Workflows.md b/website/versioned_docs/version-6.X/Introduction.Workflows.md deleted file mode 100644 index 92ca8cc605..0000000000 --- a/website/versioned_docs/version-6.X/Introduction.Workflows.md +++ /dev/null @@ -1,15 +0,0 @@ ---- -id: version-6.X-Introduction.Workflows -title: Workflows -original_id: Introduction.Workflows ---- - -There are multiple recommended ways to work with Detox and make it a part of your development process. Choose the best workflow for your needs: - -* [Running Tests Locally on Your Machine](Guide.RunningLocally.md)
If your app is ready and does not require any active development, you can write your tests using this workflow and run them locally on your machine. This is convenient for developing your test suite without actively developing your app. - -* [Developing Your App While Writing Tests](Guide.DevelopingWhileWritingTests.md)
If your app requires active development, such as adding [testID](https://facebook.github.io/react-native/docs/view.html#testid) fields for tests, this is a good workflow. It allows you to work both on your app and your tests at the same time. - -* [Running Tests on CI (like Travis)](Guide.RunningOnCI.md)
When your test suite is finally ready, it should be set up to run automatically on your CI server on every git push. This will alert you if new changes to the app break existing functionality. - -* [Debugging Apps in Xcode During a Test](Guide.DebuggingInXcode.md)
Advanced users might need to natively debug their app inside Xcode during a Detox test. This is mostly useful for invesigating weird crahses or when contributing to Detox itself. diff --git a/website/versioned_docs/version-6.X/Introduction.WritingFirstTest.md b/website/versioned_docs/version-6.X/Introduction.WritingFirstTest.md deleted file mode 100644 index a8f91135e0..0000000000 --- a/website/versioned_docs/version-6.X/Introduction.WritingFirstTest.md +++ /dev/null @@ -1,89 +0,0 @@ ---- -id: version-6.X-Introduction.WritingFirstTest -title: Writing Your First Test -original_id: Introduction.WritingFirstTest ---- - -This tutorial assumes you've already installed Detox successfully on a working React Native project. - -> TIP: You can also check out this [awesome tutorial](https://medium.com/@bogomolnyelad/how-to-test-your-react-native-app-like-a-real-user-ecfc72e9b6bc) on Medium with video by [@bogomolnyelad](https://medium.com/@bogomolnyelad) - -
- -## Step 1: Prepare a JavaScript file to hold your scenario (spec) - -Every Detox test scenario is usually placed in its own JavaScript file. If you've followed the [installation tutorial](Introduction.GettingStarted.md), these files are located in `/e2e/*.spec.js` under your React Native project root. Feel free to place these files wherever you like, this directory structure is just a recommendation. - -If you're using Mocha as your test runner, these files will simply be executed one by one when you run your tests. - -If you've followed the installation tutorial, you should already have `firstTest.spec.js` as a placeholder to start from. - -
- -## Step 2: Decide how to reset your app for the beginning of the scenario - -In order to start the scenario from a predictable app state and reset the state from any previous scenarios that may have been running, it's customary to start the scenario by restarting the app. - -The fastest way to reset is by calling `await device.reloadReactNative();`. This is equivalent to pressing CMD+R in the simulator window - it will just reload the React Native bundle. You can find other alternatives that may be slower but more thorough [here](APIRef.DeviceObjectAPI.md). - -Our scenario is made from multiple different test cases (`it()` clauses). We usually want to reset before each one is running. This can be accomplished by placing the reset logic inside a `beforeEach()` clause. - -
- -## Step 3: Add testIDs to your app to assist in matching elements - -Most test cases start by finding a UI element on screen (*matching*) and performing some user interaction on it (*action*). To assist in finding the correct UI element, it's recommended to mark it in some way. The best practice is to use the [`testID`](https://facebook.github.io/react-native/docs/view.html#testid) prop for this purpose. This means we'll modify the app code and add these props to various elements. - -Note that not all React components support this prop. Most of the built-in native components in React Native like `View`, `Text`, `TextInput`, `Switch`, `ScrollView` have support though. If you create your own composite components, you will have to propagate this prop manually to the correct native component. - -```jsx - - - Some button - - -``` - -
- -## Step 4: Match an element and perform an action - -Choose a method to match your element, the various alternatives are documented [here](APIRef.Matchers.md). You will most likely be relying on `testID` which means our matching code will look like `element(by.id('MyUniqueId123'))`. - -Choose an action to perform on the element, the various alternatives are documented [here](APIRef.ActionsOnElement.md). If we have a button, a `tap` is probably what you're looking for, resulting in this code: - -```jsx -await element(by.id('MyUniqueId123')).tap(); -``` - -
- -## Step 5: Set an expectation on the result - -After perfoming the action, the app will most likely do something. The process might also take a little time - for example if we're logging in, there would be a server request. The great thing about detox is that you're not supposed to worry about synchronization and how much time actions take. Detox will monitor the app and continue to the next line in your test only when the app completes pending operations and becomes idle. - -The most natural expectation is to verify that some UI element has eventually appeared on screen as a result. Like before, we'll need to match this element first. We can keep using `testID` for this purpose with `element(by.id('AnotherUniqueId456'))`. - -The various available expectations are documented [here](APIRef.Expect.md). If we want to make sure an element is visible, we'll get: - -```jsx -await expect(element(by.id('AnotherUniqueId456'))).toBeVisible(); -``` - -Note that the visibilty matcher makes sure the element is actually visible on screen (at least 75% of it to be exact). If it appears under the fold (eg. the user has to scroll to see it), this specific matcher will fail. - -
- -## Step 6: Rinse and repeat - -Create more complicated test cases by stringing actions and expectations one after the other. Explore the rest of the API to see what other things you can do in your tests. - -Add more test cases to your file by adding `it()` clauses. Add new scenarios by adding new `*.spec.js` files. - -
- -## Step 7: Run your tests and make sure they pass - -This is usually done by running `detox test` in terminal. If your test is not passing and you don't understand why, take a look at the [troubleshooting tutorial](Troubleshooting.RunningTests.md). - -How do you continue from here? Read about the various recommended workflows with detox documented [here](Introduction.Workflows.md). Hopefully you'll find a workflow that makes sense moving forward and complements your development process. diff --git a/website/versioned_docs/version-6.X/More.AndroidSupportStatus.md b/website/versioned_docs/version-6.X/More.AndroidSupportStatus.md deleted file mode 100644 index 2cd7b26e8e..0000000000 --- a/website/versioned_docs/version-6.X/More.AndroidSupportStatus.md +++ /dev/null @@ -1,106 +0,0 @@ ---- -id: version-6.X-More.AndroidSupportStatus -title: Android Support - Status Page -original_id: More.AndroidSupportStatus ---- - -As we are wrapping up Android support for Detox, there's already a pretty hefty chunk of Detox for Android already implemented, we decided to start releasing it as we go along, just like we did with the iOS implementation. - -This page should give an updated status of what's working and what's not (yet)... - -## Setup & Configuration -Setup is not fully figured out yet. Our goal is to make it dead simple for pure React Native projects. We are not there yet. - -### Step by step guide - -For a step by step guide, check out [Introduction.Android](Introduction.Android.md). - -### High level overview -- Update to the latest Detox. -- Detox Android is shipped in source code in `node_modules/detox`. -- Add the detox Android project as an androidTestCompile dependency. -- Add an integration test case to your test suite. [Example.](../examples/demo-react-native/android/app/src/androidTest/java/com/example/DetoxTest.java) - -```gradle -androidTestCompile(project(path: ":detox", configuration: "oldOkhttpDebug"), { - exclude group: 'com.android.support', module: 'support-annotations' -}) -``` - -### Details - -Detox Android is a standard Android integration test with many twists. For example, it is completely asynchronous. The test cases are not compiled, they come through a websocket from the JS test runner via a json protocol. They are evaulated inside the app and the result along with a possible debug informations are sent back to the JS test runner. - -It uses Espresso internally, therefore you must use an AndroidJUnitRunner as your test runner (or a subclass of it). - -```gradle -android { - defaultConfig { - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - } -} -``` - -Please take a look at the [demo-react-native](../examples/demo-react-native) project to see a minimal project set up for Android. If you want to browse a more complex example you can take a look at detox's internal test suite [here.](https://github.com/wix/detox/tree/master/detox/test/e2e) - -In case your project's RN version is at least 0.46.0 change the `oldOkhttp` configuration string to `newOkhttp`, in the `app/build.gradle` [here.](../examples/demo-react-native/android/app/build.gradle#L65) - -It's sad, that we had to expose this okhttp flag, the reason behind this too long to describe here. - -## Hybrid apps - -Detox test is a NO-OP in case it's not triggered by detox itself. So, it's safe to add it to your existing test suite. - -## Synchronization -Detox uses [Espresso's Idling Resource](https://developer.android.com/training/testing/espresso/idling-resource.html) mechanism to deeply sync with the app. - -One of the advantage of using standard tools like Espresso is that you can register your own Idling Resources and Detox will fully respect them. Just register them in the Detox instrumentation test case before calling `Detox.runTests(...)`. - -## Core APIs (Matchers, Expectations, Actions) -All Core APIs are 100% implemented. - -## Emulator control -1. **Emulators** are fully supported, to choose an emulator to run your tests on check `emulator -list-avds`. If none exist, create one. -2. **Devices** - Coming soon! -3. **Genymotion** -To utilize Genymotion you should use 'android.attached' as configuration type parameter and Genymotion emulator name as configuration name parameter. For example, - -```json -"android": { - "binaryPath": "./android/app/build/outputs/apk/app-debug.apk", - "build": "pushd ./android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && popd", - "type": "android.attached", - "name": "192.168.57.101:5555" -} -``` - -Type 'android.attached' could be used to connect to any of already attached devices that are visible through 'adb devices' command. - -## Mocking -1. Deep Links - Done -2. User Notifications - Missing -3. Location - Coming soon - -## Debugging -1. `--loglevel verbose` can give you pretty good insight on what going on. -2. `--debug-synchronization [ms]`, our tool to identify synchronization issues works on Android too. - -## Cross platform support -Detox is being developed on Macs, but there is no Mac specifc command on any of the Android drivers, or anything related to Android. Detox should work on both Linux and Windows. - -## Differences between iOS and Android -- Detox Android doesn't wait for Timers scheduled less than 1.5sec in the future. Its look ahead threshold is only 15ms. -- Contrary to iOS, synchronization can not be completely turned off by [device.disablesynchronization()](https://github.com/wix/detox/blob/master/docs/APIRef.DeviceObjectAPI.md#devicedisablesynchronization). It turns off only the monitoring of the network operation at the moment. This feature will never be fully implemented as Espresso syncs can not be turned off completely. It is planned to tie the Animation syncronization too to it. -- Detox Android doesn't wait for delayed animations. (iOS waits for 1.5sec for delayed animations) -- Please be aware that the order of the elements using the `atIndex()` API can be different between the two platforms. You can use the `getPlatform()` API to use different indexes in your tests. See below. - -## General remarks -- For a technical reason related to React Native, Detox can not synchronize with native driver animations prior to RN 45. -- Infinite animations (looped animations) can make detox wait forever. Please consider turning looped animations off for testing. It's also a good practice to speed up all animations for testing. -- With the addition of Android we introduced an API to be able to differentiate between the two platforms in your test cases. - -```js -if (device.getPlatform() === 'ios') { - await expect(loopSwitch).toHaveValue('1'); -} -``` diff --git a/website/versioned_docs/version-6.X/More.DesignPrinciples.md b/website/versioned_docs/version-6.X/More.DesignPrinciples.md deleted file mode 100644 index 8d154f2a58..0000000000 --- a/website/versioned_docs/version-6.X/More.DesignPrinciples.md +++ /dev/null @@ -1,27 +0,0 @@ ---- -id: version-6.X-More.DesignPrinciples -title: Design Principles -original_id: More.DesignPrinciples ---- - -Traditionally, end-to-end tests on mobile are riddled with inherent issues, making the testing process difficult and lowering ROI for developers. We believe that the only way to solve these issues at the core is by changing some of the basic principles of our approach. - -
- -* **Detox does not rely on WebDriver**

Detox is built from the ground up to integrate with native layers of your mobile app directly. We try to avoid generic cross-platform interfaces that are often the lowest common denominator. We want to optimize per platform. - -* **Detox does gray box, not black box**

Theoretically, it sounds better to test exactly what you ship as a black box. In practice, switching to gray box allows the test framework to monitor the app from the inside and delivers critical wins like fighting flakiness at the core. - -* **Detox relies on EarlGrey and Espresso**

The leading native gray box drivers are developed by Google - EarlGrey for iOS and Espresso for Android. Detox relies on them using a JSON-based reflection mechanism which allows a common JavaScript implementation to invoke their native methods directly. - -* **Friendly Protractor-like API for tests**

Tests in Detox are implemented in human-readable JavaScript and can even be shared between platforms. This easy to use API completely abstracts the complex native driver invocations taking place under the hood. - -* **Detox controls devices through low-level APIs**

Let's take iOS simulators for example, which are difficult to control efficiently since multiple concurrent instances aren't supported. Detox uses [AppleSimulatorUtils](https://github.com/wix/AppleSimulatorUtils) (another opensource library by Wix) to work around these issues and support test sharding. - -* **Built from the ground up for mobile and React Native**

Detox is inspired by web testing methodologies but is not a direct translation of a solution designed for a different platform. Detox is built from the ground up for native mobile and has deep first-class support for React Native apps. - -* **Detox relies on websockets for communication**

Communication between the test script running on Node.js and the tested app running on device uses websockets. This provides true bi-directional communication and is much faster and resilient than REST-like protocols. - -* **Both tester and testee are websocket clients**

The test script running on Node.js and the tested app running on device are both clients. This allows one side to disconnect without affecting the other. A separate proxy websocket server is used to connect them. - -* **Expectations run on the testee, not the tester**

Traditionally, test frameworks evalutate expectations in the test script running on Node.js. Detox evaluates expectations natively directly in the tested app running on device. This enables operations that were impossible before due to performance reasons. diff --git a/website/versioned_docs/version-6.X/More.Roadmap.md b/website/versioned_docs/version-6.X/More.Roadmap.md deleted file mode 100644 index eacb4480fd..0000000000 --- a/website/versioned_docs/version-6.X/More.Roadmap.md +++ /dev/null @@ -1,38 +0,0 @@ ---- -id: version-6.X-More.Roadmap -title: Roadmap -original_id: More.Roadmap ---- - -We have some very interesting plans for Detox, this is the place to discuss and share them. - -### Android support - read more [here](More.AndroidSupportStatus.md) -The current API supports addition of multiple platforms, Android is next. This is the biggest feature we'll be working on in the near future. Supporting both Android emulators and devices. Our plan is to use both Espresso and UIAutomator as drivers. Espresso for core in-app interactions and synchronization with react-native, and UIAutomator for peripherals (notification panel, permission dialogs etc.). This will grant us both the speed and precision of Espresso, and the flexibility of UIAutomator. - -### iOS physical device support -Currently detox only supports running on iOS simulators, we plan on adding support for running on devices as well. - -### Expectations on device logs -One of our most wanted features, being able to assert log outputs. - -### Performance probing - [DetoxInstruments](https://github.com/wix/detoxinstruments) -Maintaining performance is hard, The main issue with it is that by the time you notice there's a degradation in performance there's already so much changed it's hard to find a clear culprit for this regression (probably many small ones). Just like in BI, you won’t know if your change degrades or improves performance unless it is measured. - -* **Measure vital signs while running tests.** -E2E is the perfect environment to measure, tests are repetitive, isolated, and run in lab conditions, and remove lots of variables from the equation. -* **Set threshold for measurements.** -Expect your E2E scenario to use a specific amount of resources. -* **Compare measurements to previous builds.** -Know exactly when the regression have happened - -#### (Partial) list of measurements we'd like to have: -network bandwidth/calls, thread count, js thread cpu ticks, memory cpu, size on disk, binary size, react component render count, message count on the bridge, disk I/O - - -### Failed test artifacts -Add the following to an artifact directory for each failed test. This has - -1. Video of the test from start to finish -2. Screenshot when a test failed -2. Device log -3. Print hierarchy with testIDs diff --git a/website/versioned_docs/version-6.X/README.md b/website/versioned_docs/version-6.X/README.md deleted file mode 100644 index d187694a35..0000000000 --- a/website/versioned_docs/version-6.X/README.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: version-6.X-README -title: detox -sidebar_label: Overview -original_id: README ---- - -# Detox Documentation - -## Introduction - -- [Getting Started](Introduction.GettingStarted.md) -- [Writing You First Passing Test](Introduction.WritingFirstTest.md) -- [Adding Android](Introduction.Android.md) -- [How Detox Works](Introduction.HowDetoxWorks.md) -- [Recommended Workflows With Detox](Introduction.Workflows.md) - -## API Reference - -- [Detox Configuration](APIRef.Configuration.md) -- [The `detox` Object](APIRef.DetoxObjectAPI.md) -- [The `device` Object](APIRef.DeviceObjectAPI.md) -- [Test Lifecycle](APIRef.TestLifecycle.md) -- [Matchers](APIRef.Matchers.md) -- [Actions](APIRef.ActionsOnElement.md) -- [Expectations](APIRef.Expect.md) -- [Manual Synchronization](APIRef.waitFor.md) -- [Mocking Deep Links (App Launch From URL)](APIRef.MockingOpenFromURL.md) -- [Mocking User Notifications](APIRef.MockingUserNotifications.md) -- [Detox Command Line Tools (detox-cli)](APIRef.DetoxCLI.md) - -## Troubleshooting - -- [Troubleshooting Detox Installation](Troubleshooting.Installation.md) -- [Troubleshooting a Test That Keeps Failing](Troubleshooting.RunningTests.md) -- [Dealing With Synchronization Issues in Tests](Troubleshooting.Synchronization.md) -- [Dealing With Flakiness in Tests](Troubleshooting.Flakiness.md) - -## Guides - -- [Running Tests Locally on Your Machine](Guide.RunningLocally.md) -- [Developing Your App While Writing Tests](Guide.DevelopingWhileWritingTests.md) -- [Running Tests on CI (like Travis)](Guide.RunningOnCI.md) -- [Debugging Apps in Xcode During a Test](Guide.DebuggingInXcode.md) -- [Advanced Mocking With Detox](Guide.Mocking.md) -- [Migration Between Detox Versions](Guide.Migration.md) -- [Use Jest as Test Runner](Guide.Jest.md) - -## Under The Hood - -- [Detox Design Principles](More.DesignPrinciples.md) - -## Contributing to Detox - -- [Detox Contribution Guide](Guide.Contributing.md) -- [Detox Development Roadmap](More.Roadmap.md) -- [Android Support - Current Status](More.AndroidSupportStatus.md) diff --git a/website/versioned_docs/version-6.X/Troubleshooting.Flakiness.md b/website/versioned_docs/version-6.X/Troubleshooting.Flakiness.md deleted file mode 100644 index d1a29a66af..0000000000 --- a/website/versioned_docs/version-6.X/Troubleshooting.Flakiness.md +++ /dev/null @@ -1,37 +0,0 @@ ---- -id: version-6.X-Troubleshooting.Flakiness -title: Dealing With Flakiness in Tests -original_id: Troubleshooting.Flakiness ---- - -> What is a flaky test? - -A flaky test is a test that passes most of the time, and sometimes without any appearant reason and without any changes to your app - it fails. This can even happen only on certain machines. For example, on your own machine it always passes, but on a different slower machine, like the CI, it fails. - -### 1. We Feel Your Pain - -Flakiness is the greatest challenge in E2E. The good news is that Detox was designed with this mission in mind: dealing with flakiness head on. - -Assume you have a suite of 100 tests and each test is flaky in 0.5% of executions (failing without an actual bug in your app). The total flakiness of your entire suite is about 40% (the exact formula is `1 - (1 - 0.005)^100`). This means that there's 40% chance your suite will fail without an actual bug! This makes your entire suite useless. - -### 2. Sources of Flakiness - -It's important to identify the various sources of flakiness in Detox tests. - -* Control of the device / simulator - in order to run your tests, Detox must communicate with a simulator and instruct it to install the app, restart it, etc. Simulators don't always behave and controlling them might occasionally fail.
Detox's underlying simulator control is [`AppleSimulatorUtils`](https://github.com/wix/AppleSimulatorUtils), it is a tool that supports both basic and advanced simulator and device interaction options, it uses some core simulator features which are not always stable and may need time to "warm up" (booting, shutting down, etc.). Detox is set to have a few retries on any of these actions before failing. It will also print all the `exec` commands when using verbose log level. - -* Asynchronous operations inside your app - every time an E2E test runs, operations might take place in a different order inside your app. This makes E2E tests nondeterministic. Consider an HTTP request made to a server, this request may take a variable time to complete due to external concerns like network congestion and server load.
Detox takes this into account by monitoring all asynchronous operations that take place in your app from the inside. Detox knows which network requests are currently in-flight. Detox knows how busy the React Native bridge is. Tests are automatically synchronized to the app and only move forward when the app is idle. - -### 3. Get More Data About the Problem - -In order to identify the source of flakiness you're suffering from you need more data. If you catch a failing test that should be passing, you need to record as much information as possible in order to investigate. - -* Enable verbose mode in Detox. This will output a lot of information about what happening during the test.
- 1. `exec` commands - 2. All communication going over the websocket, both from tester and testee - -To enable verbose mode run your tests in verbose log mode: - -```sh -detox test --loglevel verbose -``` diff --git a/website/versioned_docs/version-6.X/Troubleshooting.Installation.md b/website/versioned_docs/version-6.X/Troubleshooting.Installation.md deleted file mode 100644 index 763f4d4b3d..0000000000 --- a/website/versioned_docs/version-6.X/Troubleshooting.Installation.md +++ /dev/null @@ -1,17 +0,0 @@ ---- -id: version-6.X-Troubleshooting.Installation -title: Installation -original_id: Troubleshooting.Installation ---- - -* [No simulators found](#no-simulators-found) - -
- -### No simulators found - -In order to run tests on a simulator, you need to have simulator images installed on your machine. This process is performed by Xcode itself. You can list all available simulators using simctl by typing `xcrun simctl list` in terminal. - -If you're missing a simulator, make sure Xcode is installed and use it to download the simulator. Take a look at the Preferences screen, some screenshots can be seen [here](http://stackoverflow.com/questions/33738113/how-to-install-ios-9-1-simulator-in-xcode-version-7-1-1-7b1005). - -Once the desired simulator is installed and returned by `xcrun simctl list`, double check its name in the list and make sure this name is found in the `detox` configuraton entry in `package.json`. The reference for the configuration options is available [here](APIRef.Configuration.md). diff --git a/website/versioned_docs/version-6.X/Troubleshooting.RunningTests.md b/website/versioned_docs/version-6.X/Troubleshooting.RunningTests.md deleted file mode 100644 index 60d7e6b5b2..0000000000 --- a/website/versioned_docs/version-6.X/Troubleshooting.RunningTests.md +++ /dev/null @@ -1,236 +0,0 @@ ---- -id: version-6.X-Troubleshooting.RunningTests -title: Failing Tests -original_id: Troubleshooting.RunningTests ---- -* [Enable verbose mode](#enable-verbose-mode) -* [Syntax Error: Unxpected Token](#syntax-error-unxpected-token) -* [Can't find my component even though I added testID to its props](#cant-find-my-component-even-though-i-added-testid-to-its-props) -* [Test tries to find my component before it's created](#test-tries-to-find-my-component-before-its-created) -* [Can't synchronize the test with my app](#cant-synchronize-the-test-with-my-app) -* [detox build or detox test are failing to run](#detox-build-or-detox-test-are-failing-to-run) -* [Debug view hierarchy](#debug-view-hierarchy) -* [Compare to a working setup](#compare-to-a-working-setup) -* [Take a look at past issues](#take-a-look-at-past-issues) -* [How to open a new issue](#how-to-open-a-new-issue) - -
- -### Enable verbose mode - -It's a good idea to get as much information as possible about what's going on. We can enable verbose mode during tests by running our tests with: - -``` -detox test --loglevel verbose -``` - - -### Enable deugging of synchronization issues - -See [here](https://github.com/wix/detox/blob/master/docs/Troubleshooting.Synchronization.md#identifying-which-synchronization-mechanism-causes-us-to-wait-too-much). - -### Syntax Error: Unexpected Token - -**Issue:** Running tests immediately throws the following error: - -``` -beforeEach(async () => { - ^ -SyntaxError: Unexpected token ( - at Object.exports.runInThisContext (vm.js:76:16) - at Module._compile (module.js:545:28) - at loader (/Users/builduser/buildAgent/work/34eee2d16ef6c34b/node_modules/babel-register/lib/node.js:144:5) - at Object.require.extensions.(anonymous function) [as .js] (/Users/builduser/buildAgent/work/34eee2d16ef6c34b/node_modules/babel-register/lib/node.js:154:7) - at Module.load (module.js:490:32) - at tryModuleLoad (module.js:449:12) - at Function.Module._load (module.js:441:3) - at Module.require (module.js:500:17) - at require (internal/module.js:20:19) - at /Users/builduser/buildAgent/work/34eee2d16ef6c34b/node_modules/mocha/lib/mocha.js:230:27 - at Array.forEach (native) - at Mocha.loadFiles (/Users/builduser/buildAgent/work/34eee2d16ef6c34b/node_modules/mocha/lib/mocha.js:227:14) - at Mocha.run (/Users/builduser/buildAgent/work/34eee2d16ef6c34b/node_modules/mocha/lib/mocha.js:495:10) - at Object. (/Users/builduser/buildAgent/work/34eee2d16ef6c34b/node_modules/mocha/bin/_mocha:460:18) - at Module._compile (module.js:573:32) - at Object.Module._extensions..js (module.js:582:10) - at Module.load (module.js:490:32) - at tryModuleLoad (module.js:449:12) - at Function.Module._load (module.js:441:3) - at Module.runMain (module.js:607:10) - at run (bootstrap_node.js:382:7) - at startup (bootstrap_node.js:137:9) - at bootstrap_node.js:497:3 -child_process.js:531 - throw err; -``` - -**Solution:** This error means that your version of Node does not support `async-await` syntax. You should do one of the two: - -1. Update Node to a version **higher than 7.6.0**, these versions will provide native support for async-await. - -
- -### Can't find my component even though I added testID to its props - -**Issue:** Detox fails to match a component even though it has a `testID`. Detox will throw the following error: - -``` -Error: Cannot find UI Element. -Exception with Assertion: { - "Assertion Criteria" : "assertWithMatcher: matcherForSufficientlyVisible(>=0.750000)", - "Element Matcher" : "(((respondsToSelector(accessibilityIdentifier) && accessibilityID('Welcome')) && !kindOfClass('RCTScrollView')) || (kindOfClass('UIScrollView') && ((kindOfClass('UIView') || respondsToSelector(accessibilityContainer)) && ancestorThatMatches(((respondsToSelector(accessibilityIdentifier) && accessibilityID('Welcome')) && kindOfClass('RCTScrollView'))))))", - "Recovery Suggestion" : "Check if element exists in the UI, modify assert criteria, or adjust the matcher" -} - -Error Trace: [ - { - "Description" : "Interaction cannot continue because the desired element was not found.", - "Domain" : "com.google.earlgrey.ElementInteractionErrorDomain", - "Code" : "0", - "File Name" : "GREYElementInteraction.m", - "Function Name" : "-[GREYElementInteraction matchedElementsWithTimeout:error:]", - "Line" : "119" - } -] -``` - -**Solution:** React Native only supports the `testID` prop on the native built-in components. If you've created a custom composite component, you will have to support this prop yourself. You should probably propagate the `testID` prop to one of your rendered children (a built-in component): - -```jsx -export class MyCompositeComponent extends Component { - render() { - return ( - - - Something something - - - ); - } -} -``` - -Now, adding `testID` to your composite component should work: - -```jsx -render() { - return ; -} -``` - -
- -### Test tries to find my component before it's created - -**Issue:** Due to a synchronization issue, the test tries to perform an expectation and fails because it runs the expectation too soon. Consider this example: - -```js -await element(by.text('Login')).tap(); -await expect(element(by.text('Welcome'))).toBeVisible(); -``` - -In the test above, after tapping the Login button, the app performs several complex asynchronous operations until the Welcome message is displayed post-login. These can include querying a server, waiting for a response and then running an animated transition to the Welcome screen. Detox attempts to simplify your test code by synchronizing *automatically* with these asynchronous operations. What happens if for some reason the automatic synchronization doesn't work? As a result, Detox will not wait correctly until the Welcome screen appears and instead will continue immediately to the next line and try to run the expectation. Since the screen is not there yet, the test will fail. - -**Solution:** When you suspect that automatic synchronization didn't work, you have a fail-safe by synchronizing manually with `waitFor`. Using `waitFor` will poll until the expectation is met. This isn't a recommended approach so please use it as a workaround and open and issue to resolve the synchronization issue. - -Full documentation about `waitFor` is available [here](/docs/APIRef.waitFor.md). This is what the fixed test would look like: - -```js -await element(by.text('Login')).tap(); -await waitFor(element(by.text('Welcome'))).toBeVisible().withTimeout(2000); -``` - -
- -### Can't synchronize the test with my app - -If you suspect that the test is failing because Detox fails to synchronize the test steps with your app, take a look at this in-depth [synchronization troubleshooting tutorial](/docs/Troubleshooting.Synchronization.md). - -
- -### detox build or detox test are failing to run - -**Issue:** Trying to run `detox build` or `detox test` throws the following error: - -``` -Error: Cannot determine which configuration to use. use --configuration to choose one of the following: - ios.sim.release,ios.sim.debug - at Detox.initConfiguration (/Users/rotemm/git/github/detox/detox/src/Detox.js:73:13) - at Detox.init (/Users/rotemm/git/github/detox/detox/src/Detox.js:49:16) - at process._tickCallback (internal/process/next_tick.js:103:7) -``` - -**Solution:** You have configured more than one configuration in your package.json and detox cannot understand which one of them you want to run. The error will print a list of available configurations, choose one by using `--configuration` option. - -Run your commands with one of these configurations, for example: - -`detox build --configuration ios.sim.debug`
-`detox test --configuration ios.sim.debug` - -
- -### Debug view hierarchy - -**Issue:** I added the `testID` prop but I still can't find the view by id in my tests. - -**Solution:** You can investigate the app's native view hierarchy, this might shed some light on how the app's view hierarchy is laid out. - -Do the following: - -1. Start a debuggable app (not a release build) in your simulator - -2. Open Xcode - -3. Attach Xcode to your app's process - - -4. Press the `Debug View Hierarchy` button - - -5. This will open the hierarchy viewer, and will show a breakdown of your app's native view hierarchy. Here you can browse through the views - -6. React Native testIDs are manifested as *accessibility indentifiers* in the native view hierarchy - -Let's see an example. We will find the following view in the native hierarchy: - -```jsx - - ID - -``` - -This is the hierarchy viewer, pointing to the native view just mentioned: - - - -
- -### Compare to a working setup - -If you feel lost, try starting from a working example for sanity. - -There are multiple working examples included in this repo, such as [demo-react-native](/examples/demo-react-native). - -First, install, build and make sure the tests are indeed passing. If they are, try comparing this setup with what you have. - -
- -### Take a look at past issues - -Before opening a new issue, search the [list of issues](https://github.com/wix/detox/issues?utf8=%E2%9C%93&q=is%3Aissue) on GitHub. There's a good chance somebody faced the same problem you are. - -
- -### How to open a new issue - -Before opening a new issue, please follow the entire troubleshooting guide and go over past issues. - -Include the following information in your issue to increase the chances of resolving it: - -1. Versions of all dependencies - iOS version you're working on, simulator model, React Native version, Detox version, etc - -2. The verbose log of the test (see above) - -3. Source code of your test scenario - -4. If possible, try to extract a reproducable example of your issue in a git repo that you can share diff --git a/website/versioned_docs/version-6.X/Troubleshooting.Synchronization.md b/website/versioned_docs/version-6.X/Troubleshooting.Synchronization.md deleted file mode 100644 index 4384e2e35f..0000000000 --- a/website/versioned_docs/version-6.X/Troubleshooting.Synchronization.md +++ /dev/null @@ -1,124 +0,0 @@ ---- -id: version-6.X-Troubleshooting.Synchronization -title: Dealing With Synchronization Issues in Tests -original_id: Troubleshooting.Synchronization ---- - -Traditionally, one of the most difficult aspects of E2E testing is synchronizing the test scenario with the app. Complex operations inside the app (like accessing servers or performing animations) often take variable amount of time to complete. We can't continue the test until they've completed. How can we synchronize the test with these operations? - -Synchronizing manually with `sleep()` commands is a bad idea. It's flaky, complicates the tests, behaves differently on different machines and makes tests needlessly slow. - -Instead, Detox tries to synchronize the test with the app completely *automatically*. - -When this works it's like magic. You simply execute actions one after the other without worrying about timing, and Detox waits for the app to stabilize before moving to the next test line. If there's an in-flight request to a server, for example, the test will not move forward until the request completes. - -
- -### Automatic synchronization works most of the time - -It's difficult for an automatic mechanism to be correct in 100% of the cases. There are always exceptions. We are optimizing for the common case so most of your scenarios will not have to deal with synchronization issues. - -For the rest of this tutorial, we'll assume the test is having some sort of a synchronization issue. - -
- -### Are we waiting too much or not waiting enough? - -When the automatic synchronization mechanism doesn't work, we have 2 potential problems: - -* We are waiting too much - The test will appear to hang and fail with timeout. This happens because Detox thinks an asychronous operations is currently taking place and is waiting for it endlessly. - -* We are not waiting enough - The test will appear to fail at some point becuase an element isn't found according to an expectation or isn't found when attempting to perform an action on it. This happens because Detox didn't take some asynchronous operation into account and isn't waiting until it completes. - -
- -### Switching to manual synchronization as a workaround - -We always have the fail-safe of turning off automatic synchronization and waiting manually by ourselves. This isn't the recommended approach but sometimes we don't have a choice. - -#### How do we turn off automatic synchronization? - -This makes sense only if we're waiting too much. - -##### [Controlling the entire synchronization mechanism](https://github.com/wix/detox/blob/master/docs/APIRef.DeviceObjectAPI.md#devicedisablesynchronization) -The synchronization mechanism can be shut down using - -```js -await device.disableSynchronization(); -``` - -to turn it on again use - -```js -await device.enableSynchronization(); -``` - -##### [Controlling network synchronization](https://github.com/wix/detox/blob/master/docs/APIRef.DeviceObjectAPI.md#deviceseturlblacklisturls) -You can skip over synchronizing on certain URLs (for long polling tasks, or websocket connections) - -```js -await device.setURLBlacklist(['.*127.0.0.1.*']); -``` - -In order to gain sync back on an endpoint, just remove it from the blacklist - -```js -await device.setURLBlacklist([]); -``` - - -#### How do we wait manually? - -This makes sense only if we're not waiting enough (or if we've disabled automatic synchronization). Use the `waitFor` API to poll until an expectation is met. The API is documented [here](/docs/APIRef.waitFor.md). - -
- -### What operations do we try to synchronize with automatically - -* **Network requests** - Detox monitors in-flight requests over the network. - -* **Main thread (native)** - Detox monitors pending native operations on the main thread (main dispatch queue and main NSOperationQueue). - -* **Layout of UI** - Detox monitors UI layout operations. There's also special support for React Native layout which includes the Shadow Queue where [yoga](https://github.com/facebook/yoga) runs. - -* **Timers** - Detox monitors timers (explicit asynchronous delays). There's special support for JavaScript timers like setTimeout and setInterval. - -* **Animations** - Detox monitors active animations and transitions. There's special support for React Native animations with the Animated library. - -* **React Native JavaScript thread** - Detox monitors pending operations on the JavaScript thread in RN apps. - -* **React Native bridge** - Detox monitors the React Native bridge and asynchronous messages sent on it. - -
- -### Identifying which synchronization mechanism causes us to wait too much - -Interactions with the application are synchronized, meaning that they will not execute unless the app is idle. You may encounter situations where the tests just hang. -When an action/expectation takes a significant amount of time use this option to print device synchronization status. -The status will be printed if the action takes more than [value]ms to complete - -``` -detox test --debug-synchronization [value in ms] -``` - -
- -### Tweaking and fine-tuning the synchronization mechanisms - -> This isn't exposed yet, TBD - -
- -### Modifying your app to avoid waiting too much - -When facing a synchronization issue and tweaking doesn't help, consider modifying your app. When Detox is having trouble synchronizing due to intense non-stopping activity, it may be a sign that your app is abusing resources. - -You can also modify your app for the sake of tests only. If you're building a React Native app, you can use [react-native-repackager](https://github.com/wix/react-native-repackager) to override specific files only in your E2E build. - -#### setTimeout and setInterval - -By default, Detox is designed to ignore `setInterval` and will only wait for `setTimeout` of up to 1 second. If you have an endless polling loop with short intervals implemented with `setTimeout`, switch the implementation to `setInterval`. If possible, avoid agressive polling in your app altogether, the poor single JavaScript thread we have doesn't like it. - -#### Endless looping animations - -By default, Detox will wait until animations complete. If you have an endless looping animation, this may cause Detox to hang. In this case, consider turning off the animation synchronization or remove the endless loop in your E2E build with [react-native-repackager](https://github.com/wix/react-native-repackager). diff --git a/website/versioned_docs/version-7.X/APIRef.DetoxCLI.md b/website/versioned_docs/version-7.X/APIRef.DetoxCLI.md deleted file mode 100644 index 158192493c..0000000000 --- a/website/versioned_docs/version-7.X/APIRef.DetoxCLI.md +++ /dev/null @@ -1,98 +0,0 @@ ---- -id: version-7.X-APIRef.DetoxCLI -title: Detox Command Line Tools (detox-cli) -original_id: APIRef.DetoxCLI ---- - -`detox-cli` lets you operate Detox from command line. - -## Installation -Install `detox-cli` globally via npm: - -```sh -npm install -g detox-cli -``` - -## Usage -```sh -detox [options] [command] -``` - -## Commands: -| Command | Description | -| --- | --- | -| [test](#test) | Initiating your test suite | -| [build](#build) | Run the command defined in `configuration.build` | -| [run-server](#run-server) | Starts a standalone detox server | -| [init](#init) | Create initial e2e tests folder | -| clean-framework-cache | Delete all compiled framework binaries from ~/Library/Detox, they will be rebuilt on 'npm install' or when running 'build-framework-cache' -| build-framework-cache | Build Detox.framework to ~/Library/Detox. The framework cache is specific for each combination of Xcode and Detox versions -| [help](#help) | Display help for specific command | - -## Options: - -| Options | Description | -| --- | --- | -| -h
--help | Output usage information | - -## Commands - -### test -Initiating your test suite - -`detox test [options]` - - - -| Option| Description | -| --- | --- | -| -h, --help | output usage information | -| -o, --runner-config \ | Test runner config file, defaults to 'e2e/mocha.opts' for mocha and 'e2e/config.json' for jest | -| -l, --loglevel [value] | info, debug, verbose, silly, wss | -| -c, -configuration \ | Select a device configuration from your defined configurations,if not supplied, and there's only one configuration, detox will default to it | -| -r, --reuse | Reuse existing installed app (do not delete and re-tall) for a faster run. | -| -u, --cleanup | Shutdown simulator when test is over, useful for CI ipts, to make sure detox exists cleanly with no residue | -| -d, --debug-synchronization \ | When an action/expectation takes a significant amount time use this option to print device synchronization status. The status will be printed if the ion takes more than [value]ms to complete | -| -a, --artifacts-location \ | Artifacts destination path (currently contains only logs). For more details, please check the [Artifacts doc](APIRef.Artifacts.md#artifacts) | -|-p, --platform [ios/android] | Run platform specific tests. Runs tests with invert grep on `:platform:`, e.g test with substring `:ios:` in its name will not run when passing `--platform android` -|                  || - - - -### build -Run a command defined in 'configuration.build' - -`detox build [options]` - -| Option | Description | -| --- | --- | -| -h, --help | output usage information | -| -c, --configuration \ | Select a device configuration from your defined configurations,if not supplied, and there's only one configuration, detox will default to it | -|                  || - - -### run-server -Start a standalone detox server - -`detox run-server [options]` - -| Option | Description | -| --- | --- | -| -h, --help | output usage information | - - -### init -Create initial e2e tests folder - -`detox init [options` - -| Option | Description | -| --- | --- | -| -h, --help | output usage information | -| -r, --runner | Test runner (currently supports only `mocha`) | - -### help -Display help for a command - -`detox help [command]` - diff --git a/website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md b/website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md deleted file mode 100644 index 5fdfae074a..0000000000 --- a/website/versioned_docs/version-7.X/APIRef.DetoxObjectAPI.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: version-7.X-APIRef.DetoxObjectAPI -title: The `detox` Object -original_id: APIRef.DetoxObjectAPI ---- - -`detox` is globally available in every test file, though currently it is only used in the setup/init file. - ->NOTE: detox is test runner independent, and we encourge you to choose your own test runner, but for the sake of demonstration we will use `mocha`'s syntax. - -### Methods - -- [`detox.init()`](#detox.init) -- [`detox.cleanup()`](#detox.cleanup) - -### `detox.init()` -The setup phase happens inside `detox.init()`. This is the phase where detox reads its configuration, starts a server, loads its expection library and starts a simulator. - -##### (if you're using mocha) In your `init.js` add: - -```js -const config = require('../package.json').detox; - -before(async () => { - await detox.init(config); -}); -``` - -##### Explicit imports during initialization -Detox exports `device `, `expect`, `element`, `by` and `waitFor` as globals by default, if you want to control their initialization manually, set init detox with `initGlobals` set to `false`. This is useful when during E2E tests you also need to run regular expectations in node. jest `Expect` for instance, will not be overriden by Detox when this option is used. - -```js -before(async () => { - await detox.init(config, {initGlobals: false}); -}); -``` - -Then import them manually: - -```js -const {device, expect, element, by, waitFor} = require('detox'); -``` - -Use [this example](../examples/demo-react-native/e2eExplicitRequire) for initial setup - - - -#### Controlling first app intialization -By default `await detox.init(config);` will launch the installed app. If you wish to control when your app is launched, add `{launchApp: false}` param to your init. - -```js -const config = require('../package.json').detox; - -before(async () => { - await detox.init(config, {launchApp: false}); -}); -``` - ->NOTE: Detox 6.X.X introduced a **breaking change** , setting `launchApp` to `false` by default. In order to prevent any breaking changes to your tests when you upgrade (and if you still would like `init` to launch the app for you) do the following: - -```js -before(async () => { - await detox.init(config, {launchApp: true}); -}); -``` - -### `detox.cleanup()` -The cleanup phase should happen after all the tests have finished. This is the phase where detox-server shuts down. The simulator will also shut itself down if `--cleanup` flag is added to `detox test` - -##### (if you're using mocha) In your `init.js` add: - -```js -after(async () => { - await detox.cleanup(); -}); -``` diff --git a/website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md b/website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md deleted file mode 100644 index 2e7d9e9754..0000000000 --- a/website/versioned_docs/version-7.X/APIRef.DeviceObjectAPI.md +++ /dev/null @@ -1,220 +0,0 @@ ---- -id: version-7.X-APIRef.DeviceObjectAPI -title: The `device` Object -original_id: APIRef.DeviceObjectAPI ---- - -`device` is globally available in every test file, it enables control over the current attached device (currently only simulators are supported). - -### Methods - -- [`device.launchApp()`](#devicelaunchappparams) -- [`device.relaunchApp()` **Deprecated**](#devicerelaunchappparams) -- [`device.terminateApp()`](#deviceterminateapp) -- [`device.reloadReactNative()`](#devicereloadreactnative) -- [`device.sendToHome()`](#devicesendtohome) -- [`device.installApp()`](#deviceinstallapp) -- [`device.uninstallApp()`](#deviceuninstallapp) -- [`device.openURL(url)`](#deviceopenurlurl-sourceappoptional) -- [`device.sendUserNotification(params)`](#devicesendusernotificationparams) -- [`device.setOrientation(orientation)`](#devicesetorientationorientation) -- [`device.setLocation(lat, lon)`](#devicesetlocationlat-lon) -- [`device.setURLBlacklist([urls])`](#deviceseturlblacklisturls) -- [`device.enableSynchronization()`](#deviceenablesynchronization) -- [`device.disableSynchronization()`](#devicedisablesynchronization) -- [`device.resetContentAndSettings()`](#deviceresetcontentandsettings) -- [`device.getPlatform()`](#devicegetplatform) - -### `device.launchApp(params)` -Launch the app defined in the current [`configuration`](APIRef.Configuration.md). - -**Options:** - -##### 1. Restart the app -Terminate the app and launch it again. -If set to `false`, the simulator will try to bring app from background, if the app isn't running, it will launch a new instance. default is `false` - -```js -await device.launchApp({newInstance: true}); -``` - -##### 2. Set runtime permissions -Grant or deny runtime permissions for your application. - -```js -await device.launchApp({permissions: {calendar: 'YES'}}); -``` -Detox uses [AppleSimUtils](https://github.com/wix/AppleSimulatorUtils) on iOS to support this functionality. Read about the different types of permissions and how to set them in AppleSimUtils' Readme. -Check out Detox's [own test suite](../detox/test/e2e/l-permissions.js) - -##### 3. Launch from URL -Mock opening the app from URL to test your app's deep link handling mechanism. - -```js -await device.launchApp({url: url}); -``` -###### Mock opening from a URL when app is not running -```js -await device.launchApp({url: url, newInstance: true}); -``` -This will launch a new instance of the app and handle the deep link. - -###### Mock opening from a URL when app is in background - -```js -await device.launchApp({url: url, newInstance: false}); -``` -This will launch the app from background and handle the deep link. - -Read more in [Mocking Open From URL](APIRef.MockingOpenFromURL.md) section. - -##### 4. Launch from user notifications - -```js -await device.launchApp({userNotification: notification}); -``` - -###### Mock receiving a notifications when app is not running -```js -await device.launchApp({userNotification: notification, newInstance: true}); -``` -This will launch a new instance of the app and handle the notification. - -###### Mock receiving a notifications when app is in background - -```js -await device.launchApp({userNotification: notification, newInstance: false}); -``` -This will launch the app from background and handle the notification. - -Read more in [Mocking User Notifications](APIRef.MockingUserNotifications.md) section. - -##### 5. Launch into a fresh installation -A flag that enables relaunching into a fresh installation of the app (it will uninstall and install the binary again), default is `false`. - -```js -await device.launchApp({delete: true}); -``` - -##### 6. Additional launch arguments -Detox can start the app with additional launch arguments - -```js -await device.launchApp({launchArgs: {arg1: 1, arg2: "2"}}); -``` - -The added `launchArgs` will be passed through the launch command to the device and be accessible via `[[NSProcessInfo processInfo] arguments]` - -### `device.relaunchApp(params)` -**Deprecated** Use `device.launchApp(params)` instead. This method is now calling `launchApp({newInstance: true})` for backwards compatibility, it will be removed in Detox 6.X.X.
-Kill and relaunch the app defined in the current [`configuration`](APIRef.Configuration.md). - -### `device.terminateApp()` -By default, `terminateApp()` with no params will terminate the app file defined in the current [`configuration`](APIRef.Configuration.md). - -To terminate another app, specify its bundle id - -```js -await device.terminateApp('other.bundle.id'); -``` - -### `device.sendToHome()` -Send application to background by bringing `com.apple.springboard` to the foreground.
-Combining `sendToHome()` with `launchApp({newInstance: false})` will simulate app coming back from background.
-Check out Detox's [own test suite](../detox/test/e2e/f-simulator.js) - -```js -await device.sendToHome(); -await device.launchApp({newInstance: false}); -// app returned from background, do stuff -``` -Check out Detox's [own test suite](../detox/test/e2e/f-device.js) - -### `device.reloadReactNative()` -If this is a react native app, reload react native JS bundle. This action is much faster than `device.relaunchApp()`, and is recommended if you just need to reset your react native logic. - -### `device.installApp()` -By default, `installApp()` with no params will install the app file defined in the current [`configuration`](APIRef.Configuration.md). - -To install another app, specify its path - -```js -await device.installApp('path/to/other/app'); -``` - -### `device.uninstallApp()` -By default, `uninstallApp()` with no params will uninstall the app defined in the current [`configuration`](APIRef.Configuration.md). - -To uninstall another app, specify its bundle id - -```js -await device.installApp('other.bundle.id'); -``` - -### `device.openURL({url, sourceApp[optional]})` -Mock opening the app from URL. `sourceApp` is an optional parameter to specify source application bundle id.
-Read more in [Mocking Open From URL](APIRef.MockingOpenFromURL.md) section.
-Check out Detox's [own test suite](../detox/test/e2e/n-deep-links.js) - -### `device.sendUserNotification(params)` -Mock handling of received user notification when app is in foreground.
-Read more in [Mocking User Notifications](APIRef.MockingUserNotifications.md) section.
-Check out Detox's [own test suite](../detox/test/e2e/k-user-notifications.js) - -### `device.setOrientation(orientation)` -Takes `"portrait"` or `"landscape"` and rotates the device to the given orientation. -Currently only available in the iOS Simulator.
-Check out Detox's [own test suite](../detox/test/e2e/f-device.js) - -### `device.setLocation(lat, lon)` ->Note: `setLocation` is dependent on `fbsimctl`. if `fbsimctl` is not installed, the command will fail, asking for it to be installed. -Sets the simulator location to the given latitude and longitude. -```js -await device.setLocation(32.0853, 34.7818); -``` - -### `device.setURLBlacklist([urls])` - -Disable [EarlGrey's network synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#network) on preffered endpoints. Usful if you want to on skip over synchronizing on certain URLs. - -```js -await device.setURLBlacklist(['.*127.0.0.1.*']); -``` - -```js -await device.setURLBlacklist(['.*my.ignored.endpoint.*']); -``` - -### `device.enableSynchronization()` -Enable [EarlGrey's synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#synchronization -) (enabled by default). **This is being reset on every new instance of the app.** -```js -await device.enableSynchronization(); -``` - - -### `device.disableSynchronization()` -Disable [EarlGrey's synchronization mechanism](https://github.com/google/EarlGrey/blob/master/docs/api.md#synchronization -) (enabled by default) **This is being reset on every new instance of the app.** - -```js -await device.disableSynchronization(); -``` - - -### `device.resetContentAndSettings()` -Resets the Simulator to clean state (like the Simulator > Reset Content and Settings... menu item), especially removing -previously set permissions. - -```js -await device.resetContentAndSettings(); -``` - -### `device.getPlatform()` -Returns the current device, `ios` or `android`. - -```js -if (device.getPlatform() === 'ios') { - await expect(loopSwitch).toHaveValue('1'); -} -``` diff --git a/website/versioned_docs/version-7.X/APIRef.waitFor.md b/website/versioned_docs/version-7.X/APIRef.waitFor.md deleted file mode 100644 index 92213b1184..0000000000 --- a/website/versioned_docs/version-7.X/APIRef.waitFor.md +++ /dev/null @@ -1,100 +0,0 @@ ---- -id: version-7.X-APIRef.waitFor -title: Manual Synchronization Using `waitFor` -original_id: APIRef.waitFor ---- - -In most cases, tests should be automatically synchronized with the app. When synchronization doesn't work, you have a fail-safe by using `waitFor`. This API polls using the given expectation continuously until the expectation is met. Use manual synchronization with `waitFor` only as a **last resort**. Polling for expectations isn't exactly a best practice. - -Test async code with waitFor.
-**Hang the test until an expectation is met.** - -### Methods - -- [`.toBeVisible()`](#tobevisible) -- [`.toBeNotVisible()`](#tobenotvisible) -- [`.toExist()`](#toexist) -- [`.toNotExist()`](#tonotexist) -- [`.toHaveText()`](#tohavetexttext) -- [`.toHaveValue()`](#tohavevaluevalue) -- [`.withTimeout()`](#withtimeoutmillis) -- [`.whileElement()`](#whileelementelement) - ->NOTE: Every `waitFor` call must set a timeout using `withTimeout()`. Calling `waitFor` without setting a timeout **will do nothing**. - ->NOTE: `waitFor` will not throw when reaching timeout, instead it will just continue to the next line. To make sure your tests work as you expect them to add `expect()` at the following line. - -### `toBeVisible()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toBeVisible()`](APIRef.Expect.md#tobevisible)
-Wait for the view to be at least 75% visible. - -```js -await waitFor(element(by.id('UniqueId204'))).toBeVisible().withTimeout(2000); -await expect(element(by.id('UniqueId204'))).toBeVisible(); -``` - -### `toBeNotVisible()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toBeNotVisible()`](APIRef.Expect.md#tobenotvisible)
-Wait for the view to not be visible. - -```js -await waitFor(element(by.id('UniqueId205'))).toBeNotVisible().withTimeout(2000); -await expect(element(by.id('UniqueId205'))).toBeNotVisible(); -``` - -### `toExist()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toExist()`](APIRef.Expect.md#toexist)
-Wait for the view to exist in the UI hierarchy. - -```js -await waitFor(element(by.id('UniqueId205'))).toExist().withTimeout(2000); -await expect(element(by.id('UniqueId205'))).toExist(); -``` - -### `toNotExist()` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toNotExist()`](APIRef.Expect.md#tonotexist)
-Wait for the view to not exist in the UI hierarchy. - -```js -await waitFor(element(by.id('RandomJunk959'))).toNotExist().withTimeout(2000); -await expect(element(by.id('RandomJunk959'))).toNotExist(); -``` - -### `toHaveText(text)` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toHaveText(text)`](APIRef.Expect.md#tohavetexttext)
-- In React Native apps, expect UI component of type `` to have text. -- In native iOS apps, expect UI elements of type UIButton, UILabel, UITextField or UITextViewIn to have inputText with text. - -```js -await waitFor(element(by.id('UniqueId204'))).toHaveText('I contain some text').withTimeout(2000); -await expect(element(by.id('UniqueId204'))).toHaveText('I contain some text'); -``` - -### `toHaveValue(value)` -Test will hang until expectation is met or a timeout has occurred. Should be accompanied with [`expect.toHaveValue(value)`](APIRef.Expect.md#tohavevaluevalue)
- -- In React Native apps, expect UI component to have [`testID`](https://facebook.github.io/react-native/docs/view.html#testid) with that id. -- In native iOS apps, expect UI element to have accesibilityIdentifier with that id. - -```js -await waitFor(element(by.id('uniqueId'))).toHaveValue('Some value').withTimeout(2000); -await expect(element(by.id('uniqueId'))).toHaveValue('Some value'); -``` - - -### `withTimeout(millis)` -Waits for the condition to be met until the specified time (millis) have elapsed. - -```js -await waitFor(element(by.id('UniqueId336'))).toExist().withTimeout(2000); -await expect(element(by.id('UniqueId336'))).toExist(); -``` - - -### `whileElement(element)` -Performs the action repeatedly on the element until an expectation is met. - -```js -await waitFor(element(by.text('Text5'))).toBeVisible().whileElement(by.id('ScrollView630')).scroll(50, 'down'); -await expect(element(by.text('Text5'))).toBeVisible(); -``` diff --git a/website/versioned_docs/version-7.X/Guide.Contributing.md b/website/versioned_docs/version-7.X/Guide.Contributing.md deleted file mode 100644 index fc8860ce16..0000000000 --- a/website/versioned_docs/version-7.X/Guide.Contributing.md +++ /dev/null @@ -1,135 +0,0 @@ ---- -id: version-7.X-Guide.Contributing -title: Contributing -original_id: Guide.Contributing ---- - -## Prerequisites - -### Install `node` v7.6 or higher (to support async-await natively) - -``` -brew install node -``` - -### Install global node libraries `lerna` and `react-native-cli` - -```sh -npm install -g lerna -npm install -g react-native-cli -``` - -For all the internal projects (detox, detox-server, detox-cli, demos, test) `lerna` will create symbolic links in `node_modules` instead of `npm` copying the content of the projects. This way, any change you do on any code is there immediately. There is no need to update node modules or copy files between projects. - -### Install `xcpretty` - -```sh -gem install xcpretty -``` - -Alternatively, run `scripts/install.ios.sh` / `scripts/install.android.sh` to install all prerequisites. - -## Detox - -### Clone Detox and submodules - -```sh -git clone git@github.com:wix/detox.git -cd detox -git submodule update --init --recursive -``` -(this makes sure all git submodule dependencies are properly checked out) - -### Installing and linking internal projects - -```sh -scripts/bootstrap.sh -``` - -### Building - -```sh -lerna run build -``` - -### Testing - -### 1. Unit tests - -```sh -lerna run test -``` - -Detox JS code is 100% test covered and is set to break the build if coverage gets below, so make sure you run unit tests (`lerna run test`) locally before pushing. - -Alternatively, to run only the JS tests, run the following from the `detox/detox` directory: - -```sh -npm run unit --or- -npm run unit:watch -``` - -#### How to read the coverage report -After running the tests, jest will create a coverage report. - -```sh -cd detox -open coverage/lcov-report/index.html -``` - -### 2. Running Detox e2e coverage tests -Detox has a suite of e2e tests to test its own API while developing (and for regression). The way we do is is by maintaining a special application that is "tested" against Detox's API, but essentially, it's the API that is tested, not the app. -To run the e2e tests, go to `detox/detox/test` - -```sh -cd detox/test -``` - - -```sh -npm run build -``` - -To run the e2e tests, after the application was built. - -#### iOS -```sh -npm run build:ios -npm run e2e:ios -``` - -#### Android -```sh -npm run build:android -npm run e2e:android -``` - -### 3. Android Native tests - -0. Install Java and Android SDK 25 -1. In `detox/android` run `./gradlew install` run - - ```sh - ./gradlew test - ``` - -### 4. Code Generation - -We are using a code generator based on `babel` and `objective-c-parser` to generate a Javascript Interface for `EarlGrey` (the testing library we use on iOS). -This interface allows us to call Objective-C methods through the WebSocket connection directly on the testing device. - -This approach is currently limited to `GREYActions`, but we plan on extending it to cover more functionality of `EarlGrey`. -You may see the generated files under [`detox/src/ios/earlgreyapi/`](../detox/src/ios/earlgreyapi). - -What happens under the hood can be seen in [`generation/`](../generation); it boils down to these steps for each input file: - -1. Convert Objective-C header file in a JSON Representation -2. Build an Abstract Syntax Tree: Create Class & for each method - 1. Check if the type can be expressed simpler (`NSString *` => `NSString`) - 2. Get the type checks for the arguments - 2. Get the return value - 4. Assemble type checks and return value to complete function -3. Generate the code for the syntax tree & add helpers - -If you would like to extend the code generation, please make sure to read the [`generation/README.md`](../generation#generation) diff --git a/website/versioned_docs/version-7.X/Guide.Jest.md b/website/versioned_docs/version-7.X/Guide.Jest.md deleted file mode 100644 index 4cd9a5605d..0000000000 --- a/website/versioned_docs/version-7.X/Guide.Jest.md +++ /dev/null @@ -1,76 +0,0 @@ ---- -id: version-7.X-Guide.Jest -title: Jest -original_id: Guide.Jest ---- - -## Usage - -### 0. Use the [Getting Started](Introduction.GettingStarted.md) Guide to set up detox - -Except that you need to skip the install mocha step. - -### 1. Install Jest - -```sh -npm install --save-dev jest -``` - -### 2. Remove mocha specific files - -You should remove `e2e/mocha.opts`, you no longer need it. - -### 3. Replace generated detox setup file (e2e/init.js) - -```js -const detox = require('detox'); -const config = require('../package.json').detox; - -// Set the default test timeout of 120s -jest.setTimeout(120000); - -beforeAll(async () => { - await detox.init(config); -}); - -afterAll(async () => { - await detox.cleanup(); -}); -``` - -### 4. Configure Detox to run with Jest - -Add a Jest config file `e2e/config.json`: - -```json -{ - "setupTestFrameworkScriptFile" : "./init.js" -} -``` - - -In `package.json`: - -```json -"scripts": { - "test:e2e": "detox test -c ios.sim.debug", - "test:e2e:build": "detox build" -}, -"detox": { - "test-runner": "jest", - "runner-config": "e2e/config.json" - ... -} -``` - -### Writing Tests - -There are some things you should notice: - -- Don't worry about mocks being used, detox works on the compiled version of your app. -- Detox exposes it's primitives (`expect`, `device`, ...) globally, it will override Jest's global `expect` object. - -## How to run unit test and E2E tests in the same project - -- If you have a setup file for the unit tests pass `./jest/setup` implementation into your unit setup. -- Call your E2E tests using `detox-cli`: `detox test` diff --git a/website/versioned_docs/version-7.X/Introduction.Android.md b/website/versioned_docs/version-7.X/Introduction.Android.md deleted file mode 100644 index e063c9d8c9..0000000000 --- a/website/versioned_docs/version-7.X/Introduction.Android.md +++ /dev/null @@ -1,137 +0,0 @@ ---- -id: version-7.X-Introduction.Android -title: Detox for Android -original_id: Introduction.Android ---- - -## Setup -Detox 7 was updated to support Android gradle plugin 3.0.0. This is a breaking change that makes it impossible to support previous Android gradle plugin versions. - -https://developer.android.com/studio/build/gradle-plugin-3-0-0-migration.html - -For older Android gradle plugin support use `detox@6.x.x` instead ([previous setup guide here](https://github.com/wix/detox/blob/97654071573053def90e8207be8eba011408f977/docs/Introduction.Android.md)).
-**Detox 6 will not continue to be updated, to continue getting updates and features, update your Android gradle config and migrate to Detox 7.** - -### 1. Do the initial setup described in the Getting Started Guide - -- [Getting Started](Introduction.GettingStarted.md) - -### 2. Add Detox dependency to an Android project - -In `android/settings.gradle` add: - -```gradle -include ':detox' -project(':detox').projectDir = new File(rootProject.projectDir, '../node_modules/detox/android/detox') -``` - -In `android/app/build.gradle` add this to `defaultConfig` section: - -```gradle - defaultConfig { - ... - testBuildType System.getProperty('testBuildType', 'debug') //this will later be used to control the test apk build type - missingDimensionStrategy "minReactNative", "minReactNative46" //read note - testInstrumentationRunner "android.support.test.runner.AndroidJUnitRunner" - ... - } -``` -Please be aware that the `minSdkVersion` needs to be at least 18. - -> ###### Choosing the right build type (in missingDimensionStrategy) ->Detox runs on multiple React Native versions, choose the correct build type to support the version you use.
->**Available versions:** -> ->* `minReactNative44`: Support for React Native 0.44-0.45 ->* `minReactNative46`: Support for React Native 0.46+ - - -In `android/app/build.gradle` add this in `dependencies` section: - -```gradle -dependencies { - ... - androidTestImplementation(project(path: ":detox")) - androidTestImplementation 'junit:junit:4.12' - androidTestImplementation 'com.android.support.test:runner:1.0.1' - androidTestImplementation 'com.android.support.test:rules:1.0.1' - ... -} -``` - -And in the same file you need to add this under `allprojects > repositories`: - -```gradle -buildscript { - repositories { - ... - google() - ... - } -} -``` - -### 3. Create Android Test class - -You need to add the file `android/app/src/androidTest/java/com/[your.package]/DetoxTest.java` and fill it like [this](../detox/test/android/app/src/androidTest/java/com/example/DetoxTest.java), expect that you need to change the package to your projects name. - -### 4. Add Android configuration - -Add this part to your `package.json`: - -```json -"detox" : { - "configurations": { - "android.emu.debug": { - "binaryPath": "android/app/build/outputs/apk/debug/app-debug.apk", - "build": - "cd android && ./gradlew assembleDebug assembleAndroidTest -DtestBuildType=debug && cd ..", - "type": "android.emulator", - "name": "Nexus_5X_API_24" - }, - "android.emu.release": { - "binaryPath": "android/app/build/outputs/apk/release/app-release.apk", - "build": - "cd android && ./gradlew assembleRelease assembleAndroidTest -DtestBuildType=release && cd ..", - "type": "android.emulator", - "name": "Nexus_5X_API_26" - } - } -} -``` -Pay attention to `-DtestBuildType`, set either to `debug` or `release` according to the main apk type. - - -Following device types could be used to control Android devices: - -`android.emulator`. Boot stock SDK emulator with provided `name`, for example `Nexus_5X_API_25`. After booting connect to it. - -`android.attached`. Connect to already-attached android device. The device should be listed in the output of `adb devices` command under provided `name`. -Use this type to connect to Genymotion emulator. - -### 5. Run the tests - -Using the `android.emu.debug` configuration from above, you can invoke it in the standard way. - -```sh -detox test -c android.emu.debug -``` - -## Troubleshooting - -### Problem: `Duplicate files copied in ...` - -If you get an error like this: - -```sh -Execution failed for task ':app:transformResourcesWithMergeJavaResForDebug'. -> com.android.build.api.transform.TransformException: com.android.builder.packaging.DuplicateFileException: Duplicate files copied in APK META-INF/LICENSE -``` - -You need to add this to the `android` section of your `android/app/build.gradle`: - -```gradle -packagingOptions { - exclude 'META-INF/LICENSE' -} -``` diff --git a/website/versioned_docs/version-7.X/Introduction.GettingStarted.md b/website/versioned_docs/version-7.X/Introduction.GettingStarted.md deleted file mode 100644 index 3172b998d3..0000000000 --- a/website/versioned_docs/version-7.X/Introduction.GettingStarted.md +++ /dev/null @@ -1,154 +0,0 @@ ---- -id: version-7.X-Introduction.GettingStarted -title: Getting Started -original_id: Introduction.GettingStarted ---- - -This is a step-by-step guide for adding Detox to your React Native project. - -> TIP: You can also check out this [awesome tutorial](https://medium.com/@bogomolnyelad/how-to-test-your-react-native-app-like-a-real-user-ecfc72e9b6bc) on Medium with video by [@bogomolnyelad](https://medium.com/@bogomolnyelad) - -
- -## Prerequisites - -Running Detox (on iOS) requires the following: - -* Mac with macOS (at least macOS El Capitan 10.11) - -* Xcode 8.3+ with Xcode command line tools -> TIP: Verify Xcode command line tools is installed by typing `gcc -v` in terminal (shows a popup if not installed) - -* A working [React Native](https://facebook.github.io/react-native/docs/getting-started.html) app you want to test - -
- -## Step 1: Install dependencies - -#### 1. Install the latest version of [Homebrew](http://brew.sh) - -Homebrew is a package manager for macOS, we'll need it to install other command line tools. - -> TIP: Verify it works by typing in terminal `brew -h` to output list of available commands - -#### 2. Install [Node.js](https://nodejs.org/en/) - -Node is the JavaScript runtime Detox will run on. **Install Node 7.6.0 or above for native async-await support** - - ```sh - brew update && brew install node - ``` - -> TIP: Verify it works by typing in terminal `node -v` to output current node version, should be higher than 7.6.0 - -#### 3. Install [appleSimUtils](https://github.com/wix/AppleSimulatorUtils) - -A collection of utils for Apple simulators, Detox uses it communicate with the simulator. - -```sh -brew tap wix/brew -brew install --HEAD applesimutils -``` - -> TIP: Verify it works by typing in terminal `applesimutils` to output the tool help screen - -#### 4. Install Detox command line tools (detox-cli) - -This package makes it easier to operate Detox from the command line. `detox-cli` should be installed globally, enabling usage of the command line tools outside of your npm scripts. - - ```sh - npm install -g detox-cli - ``` -> TIP: Verify it works by typing in terminal `detox -h` to output the list of available commands - -
- -## Step 2: Add Detox to your project - -#### 1. Install detox - -Go to the root folder of your React Native app (where `package.json` is found): - -```sh -npm install detox --save-dev -``` - -#### 2. Install mocha - -You can use any JavaScript test runner -- [Jest](Guide.Jest.md) -- [Mocha](https://mochajs.org/) is a good one we recommend: - -```sh -npm install mocha --save-dev -``` - -#### 3. Add Detox config to package.json - -The basic configuration for Detox should be in your `package.json` file under the `detox` property: - -```json -"detox": { - "configurations": { - "ios.sim.debug": { - "binaryPath": "ios/build/Build/Products/Debug-iphonesimulator/example.app", - "build": "xcodebuild -project ios/example.xcodeproj -scheme example -configuration Debug -sdk iphonesimulator -derivedDataPath ios/build", - "type": "ios.simulator", - "name": "iPhone 7" - } - } -} -``` - -In the above configuration example, change `example` to your actual project name. Under the key `"binaryPath"`, `example.app` should be `.app`. Under the key `"build"`, `example.xcodeproj` should be `.xcodeproj` and `-scheme example` should be `-scheme `. - -For iOS apps in a workspace (eg: CocoaPods) use `-workspace ios/example.xcworkspace` instead of `-project`. - -Also make sure the simulator model specified under the key `"name"` (`iPhone 7` above) is actually available on your machine (it was installed by Xcode). Check this by typing `xcrun simctl list` in terminal to display all available simulators. - -> TIP: To test a release version, replace 'Debug' with 'Release' in the binaryPath and build properties. For full configuration options see Configuration under the API Reference. - -
- -## Step 3: Create your first test (using mocha test runner) - -You can do this automatically by running: - -```sh -detox init -``` - -Or you can do this manually instead by following these steps: - -* Create an `e2e` folder in your project root -* Create `mocha.opts` file inside with this [content](/examples/demo-react-native/e2e/mocha.opts) -* Create `init.js` file inside with this [content](/examples/demo-react-native/e2e/init.js) -* Create your first test `firstTest.spec.js` inside with content similar to [this](/examples/demo-react-native/e2e/example.spec.js) - -> TIP: Detox is not tightly coupled to Mocha or this directory structure, both are just a recommendation and are easy to replace without touching the internal implementation of Detox itself. - -
- -## Step 4: Build your app and run Detox tests - -#### 1. Build your app - -Use the Detox command line tools to build your project easily: - -```sh -detox build -``` - -> TIP: Notice that the actual build command was specified in the Detox configuration above - -#### 2. Run the tests (finally) - -Use the Detox command line tools to test your project easily: - -```sh -detox test -``` - -That's it. Your first failing Detox test is running! - -Next, we'll go over usage and how to make this test [actually pass](Introduction.WritingFirstTest.md). diff --git a/website/versioned_docs/version-7.X/README.md b/website/versioned_docs/version-7.X/README.md deleted file mode 100644 index e2121c829a..0000000000 --- a/website/versioned_docs/version-7.X/README.md +++ /dev/null @@ -1,57 +0,0 @@ ---- -id: version-7.X-README -title: detox -sidebar_label: Overview -original_id: README ---- - -# Detox Documentation - -## Introduction - -- [Getting Started](Introduction.GettingStarted.md) -- [Writing Your First Passing Test](Introduction.WritingFirstTest.md) -- [Adding Android](Introduction.Android.md) -- [How Detox Works](Introduction.HowDetoxWorks.md) -- [Recommended Workflows With Detox](Introduction.Workflows.md) - -## API Reference - -- [Detox Configuration](APIRef.Configuration.md) -- [The `detox` Object](APIRef.DetoxObjectAPI.md) -- [The `device` Object](APIRef.DeviceObjectAPI.md) -- [Test Lifecycle](APIRef.TestLifecycle.md) -- [Matchers](APIRef.Matchers.md) -- [Actions](APIRef.ActionsOnElement.md) -- [Expectations](APIRef.Expect.md) -- [Manual Synchronization](APIRef.waitFor.md) -- [Mocking Deep Links (App Launch From URL)](APIRef.MockingOpenFromURL.md) -- [Mocking User Notifications](APIRef.MockingUserNotifications.md) -- [Detox Command Line Tools (detox-cli)](APIRef.DetoxCLI.md) - -## Troubleshooting - -- [Troubleshooting Detox Installation](Troubleshooting.Installation.md) -- [Troubleshooting a Test That Keeps Failing](Troubleshooting.RunningTests.md) -- [Dealing With Synchronization Issues in Tests](Troubleshooting.Synchronization.md) -- [Dealing With Flakiness in Tests](Troubleshooting.Flakiness.md) - -## Guides - -- [Running Tests Locally on Your Machine](Guide.RunningLocally.md) -- [Developing Your App While Writing Tests](Guide.DevelopingWhileWritingTests.md) -- [Running Tests on CI (like Travis)](Guide.RunningOnCI.md) -- [Debugging Apps in Xcode During a Test](Guide.DebuggingInXcode.md) -- [Advanced Mocking With Detox](Guide.Mocking.md) -- [Migration Between Detox Versions](Guide.Migration.md) -- [Use Jest as Test Runner](Guide.Jest.md) - -## Under The Hood - -- [Detox Design Principles](More.DesignPrinciples.md) - -## Contributing to Detox - -- [Detox Contribution Guide](Guide.Contributing.md) -- [Detox Development Roadmap](More.Roadmap.md) -- [Android Support - Current Status](More.AndroidSupportStatus.md) diff --git a/website/versioned_sidebars/version-6.X-sidebars.json b/website/versioned_sidebars/version-6.X-sidebars.json deleted file mode 100644 index 114a5dd468..0000000000 --- a/website/versioned_sidebars/version-6.X-sidebars.json +++ /dev/null @@ -1,47 +0,0 @@ -{ - "version-6.X-docs": { - "Introduction": [ - "version-6.X-Introduction.GettingStarted", - "version-6.X-Introduction.WritingFirstTest", - "version-6.X-Introduction.Android", - "version-6.X-Introduction.HowDetoxWorks", - "version-6.X-Introduction.Workflows" - ], - "Guide": [ - "version-6.X-Guide.RunningLocally", - "version-6.X-Guide.DevelopingWhileWritingTests", - "version-6.X-Guide.RunningOnCI", - "version-6.X-Guide.DebuggingInXcode", - "version-6.X-Guide.Mocking", - "version-6.X-Guide.Migration", - "version-6.X-Guide.Jest" - ], - "API": [ - "version-6.X-APIRef.Configuration", - "version-6.X-APIRef.DetoxObjectAPI", - "version-6.X-APIRef.DeviceObjectAPI", - "version-6.X-APIRef.TestLifecycle", - "version-6.X-APIRef.Matchers", - "version-6.X-APIRef.ActionsOnElement", - "version-6.X-APIRef.Expect", - "version-6.X-APIRef.waitFor", - "version-6.X-APIRef.MockingOpenFromURL", - "version-6.X-APIRef.MockingUserNotifications", - "version-6.X-APIRef.DetoxCLI" - ], - "Troubleshooting": [ - "version-6.X-Troubleshooting.Installation", - "version-6.X-Troubleshooting.RunningTests", - "version-6.X-Troubleshooting.Synchronization", - "version-6.X-Troubleshooting.Flakiness" - ], - "Under the Hood": [ - "version-6.X-More.DesignPrinciples" - ], - "Contributing to Detox": [ - "version-6.X-Guide.Contributing", - "version-6.X-More.Roadmap", - "version-6.X-More.AndroidSupportStatus" - ] - } -} diff --git a/website/versions.json b/website/versions.json deleted file mode 100644 index 1cf1cd1125..0000000000 --- a/website/versions.json +++ /dev/null @@ -1,4 +0,0 @@ -[ - "7.X", - "6.X" -] From cc2b436497a5a3812bfffceab7758d324fa6512c Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Wed, 25 Apr 2018 22:16:45 +0200 Subject: [PATCH 04/10] refactor semver parsing --- website/gatherDocs.js | 8 +++----- website/package.json | 3 ++- 2 files changed, 5 insertions(+), 6 deletions(-) diff --git a/website/gatherDocs.js b/website/gatherDocs.js index 126ec8d1f1..af4ae099ec 100644 --- a/website/gatherDocs.js +++ b/website/gatherDocs.js @@ -2,6 +2,7 @@ const fs = require("fs-extra"); const git = require("nodegit"); const execSync = require('child_process').execSync; +const { major } = require("semver"); const REPO_URL = "https://github.com/wix/detox.git" // From https://gist.github.com/joerx/3296d972735adc5b4ec1 @@ -11,17 +12,14 @@ function clearRequireCache() { }); } -function getMajorVersion(tag) { - return parseInt(tag.split('.')[0], 10) -} - async function getVersions() { const tmp = fs.mkdtempSync('detox-versions'); const repo = await git.Clone(REPO_URL, tmp); const tags = await git.Tag.list(repo); const semverTags = tags - .filter(tag => tag.split('.').length === 3 && getMajorVersion(tag) >= 6) + .filter(tag => !tag.includes("@")) + .filter(tag => tag.split(".").length === 3 && major(tag) >= 6) .sort() .reverse(); await fs.remove(tmp); diff --git a/website/package.json b/website/package.json index d45abbc1cb..f1233aeb90 100644 --- a/website/package.json +++ b/website/package.json @@ -15,6 +15,7 @@ }, "dependencies": { "fs-extra": "^5.0.0", - "nodegit": "^0.21.0" + "nodegit": "^0.21.0", + "semver": "^5.5.0" } } From 056027fb61ed1c8427276ba12e8c930e5012c8cf Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Sat, 28 Apr 2018 08:26:27 +0200 Subject: [PATCH 05/10] refactor gathering documents functionality into smaller chunks --- website/gatherDocs.js | 98 ++++++++++++++++++++++++++----------------- 1 file changed, 60 insertions(+), 38 deletions(-) diff --git a/website/gatherDocs.js b/website/gatherDocs.js index af4ae099ec..30bb5ee410 100644 --- a/website/gatherDocs.js +++ b/website/gatherDocs.js @@ -1,19 +1,12 @@ #!/usr/bin/env node const fs = require("fs-extra"); const git = require("nodegit"); -const execSync = require('child_process').execSync; +const execSync = require("child_process").execSync; const { major } = require("semver"); -const REPO_URL = "https://github.com/wix/detox.git" - -// From https://gist.github.com/joerx/3296d972735adc5b4ec1 -function clearRequireCache() { - Object.keys(require.cache).forEach(function (key) { - delete require.cache[key]; - }); -} +const REPO_URL = "https://github.com/wix/detox.git"; async function getVersions() { - const tmp = fs.mkdtempSync('detox-versions'); + const tmp = fs.mkdtempSync("detox-versions"); const repo = await git.Clone(REPO_URL, tmp); const tags = await git.Tag.list(repo); @@ -28,44 +21,73 @@ async function getVersions() { const sidebars = []; -(async function () { - const versions = await getVersions(); +async function cleanupExistingVersions() { console.log("Cleanup versioned docs"); - await fs.remove("./versions.json") + await fs.remove("./versions.json"); await fs.emptyDir("./versioned_docs"); await fs.emptyDir("./versioned_sidebars"); +} - fs.writeFileSync("./versions.json", JSON.stringify(versions), "utf8"); - for (let version of versions) { - const tempDir = fs.mkdtempSync(`detox-${version}`); - console.log("Clone repository into tmp directory"); - const repo = await git.Clone(REPO_URL, tempDir); +async function checkoutVersion(version) { + const tempDir = fs.mkdtempSync(`detox-${version}`); + const repo = await git.Clone(REPO_URL, tempDir); + + console.log("Checking out version", version); + await repo.checkoutBranch(version); + return tempDir; +} + +function applyTemporalFix(tempDir) { + // We need to do this as we forgot the header in this one file, but added git tags with it included + console.log("Temporary fix for Guide.DebuggingInXcode"); + const header = + "---\nid: Guide.DebuggingInXcode\ntitle: Debugging in Xcode During Detox Tests\n---"; + execSync( + `echo "${header}" | cat - Guide.DebuggingInXcode.md > /tmp/out && mv /tmp/out Guide.DebuggingInXcode.md`, + { + cwd: tempDir + "/docs" + } + ); +} + +function generateAndCopyDocusaurusVersion(tempDir, version) { + console.log("Generating versioned doc for", version); + execSync( + `npm install && rm versions.json && rm -rf {versioned_docs,versioned_sidebars} && npm run version ${version}`, + { cwd: tempDir + "/website" } + ); - console.log("Checking out version", version); - await repo.checkoutBranch(version); + console.log("Copy versioned doc"); + fs.copySync( + `${tempDir}/website/versioned_docs/version-${version}`, + `./versioned_docs/version-${version}` + ); - // We need to do this as we forgot the header in this one file, but added git tags with it included - console.log("Temporary fix for Guide.DebuggingInXcode") - const header = '---\nid: Guide.DebuggingInXcode\ntitle: Debugging in Xcode During Detox Tests\n---'; - execSync( - `echo "${header}" | cat - Guide.DebuggingInXcode.md > /tmp/out && mv /tmp/out Guide.DebuggingInXcode.md`, - { - cwd: tempDir + "/docs" - } - ); + console.log("Copy sidebar into versioned_sidebars"); + fs.copyFileSync( + `${tempDir}/website/versioned_sidebars/version-${version}-sidebars.json`, + `./versioned_sidebars/version-${version}-sidebars.json` + ); +} + +async function cleanUp(tempDir) { + console.log("Cleanup temporary clone"); + await fs.remove(tempDir); +} - console.log("Generating versioned doc for", version) - execSync(`npm install && rm versions.json && rm -rf {versioned_docs,versioned_sidebars} && npm run version ${version}`, { cwd: tempDir + '/website' }) +(async function() { + const versions = await getVersions(); + await cleanupExistingVersions(); - console.log("Copy versioned doc"); - fs.copySync(`${tempDir}/website/versioned_docs/version-${version}`, `./versioned_docs/version-${version}`); + fs.writeFileSync("./versions.json", JSON.stringify(versions), "utf8"); - console.log("Copy sidebar into versioned_sidebars"); - fs.copyFileSync(`${tempDir}/website/versioned_sidebars/version-${version}-sidebars.json`, `./versioned_sidebars/version-${version}-sidebars.json`) + for (let version of versions) { + console.log("Clone repository into tmp directory"); + const tempDir = await checkoutVersion(version); + applyTemporalFix(tempDir); + generateAndCopyDocusaurusVersion(tempDir, version); - console.log("Cleanup temporary clone"); - await fs.remove(tempDir); + await cleanUp(tempDir); console.log(`Done with ${version}\n\n`); } })(); - From 87e40191bc0d488a1b433364c50fa6ebc8516715 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Sat, 28 Apr 2018 08:51:07 +0200 Subject: [PATCH 06/10] only clone the repository once instead of multiple times --- website/gatherDocs.js | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/website/gatherDocs.js b/website/gatherDocs.js index 30bb5ee410..a64c47ba0d 100644 --- a/website/gatherDocs.js +++ b/website/gatherDocs.js @@ -28,13 +28,9 @@ async function cleanupExistingVersions() { await fs.emptyDir("./versioned_sidebars"); } -async function checkoutVersion(version) { - const tempDir = fs.mkdtempSync(`detox-${version}`); - const repo = await git.Clone(REPO_URL, tempDir); - +async function checkoutVersion(repo, version) { console.log("Checking out version", version); await repo.checkoutBranch(version); - return tempDir; } function applyTemporalFix(tempDir) { @@ -80,14 +76,16 @@ async function cleanUp(tempDir) { await cleanupExistingVersions(); fs.writeFileSync("./versions.json", JSON.stringify(versions), "utf8"); + const tempDir = fs.mkdtempSync("detox-documentation-generation"); + const repo = await git.Clone(REPO_URL, tempDir); for (let version of versions) { console.log("Clone repository into tmp directory"); - const tempDir = await checkoutVersion(version); + await checkoutVersion(repo, version); applyTemporalFix(tempDir); generateAndCopyDocusaurusVersion(tempDir, version); - - await cleanUp(tempDir); + repo.cleanup(tempDir); console.log(`Done with ${version}\n\n`); } + await cleanUp(tempDir); })(); From a0d2cd3ab98ce0f35feec9a7ad8991fbd81e322a Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Fri, 4 May 2018 07:43:41 +0200 Subject: [PATCH 07/10] fix checkout process --- website/gatherDocs.js | 23 ++++++++++++++++++++++- 1 file changed, 22 insertions(+), 1 deletion(-) diff --git a/website/gatherDocs.js b/website/gatherDocs.js index a64c47ba0d..bae4a84891 100644 --- a/website/gatherDocs.js +++ b/website/gatherDocs.js @@ -28,9 +28,30 @@ async function cleanupExistingVersions() { await fs.emptyDir("./versioned_sidebars"); } +// https://stackoverflow.com/questions/29569913/switch-branch-tag-with-nodegit?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa +function checkOutTag(repo, tag) { + return git.Reference + .dwim(repo, "refs/tags/" + tag) + .then(function (ref) { + return ref.peel(git.Object.TYPE.COMMIT); + }) + .then(function (ref) { + return repo.getCommit(ref); + }) + .then(function (commit) { + return git.Checkout + .tree(repo, commit, { checkoutStrategy: git.Checkout.STRATEGY.FORCE }) + .then(function () { + return repo.setHeadDetached(commit, repo.defaultSignature, + "Checkout: HEAD " + commit.id()); + }) + }); +} + async function checkoutVersion(repo, version) { console.log("Checking out version", version); - await repo.checkoutBranch(version); + repo.cleanup(); + await checkOutTag(repo, version); } function applyTemporalFix(tempDir) { From cade110fd305da1e13f3990e777c151c4a84a844 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Fri, 4 May 2018 07:44:21 +0200 Subject: [PATCH 08/10] only apply fix when needed --- website/gatherDocs.js | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/website/gatherDocs.js b/website/gatherDocs.js index bae4a84891..e8f93105b4 100644 --- a/website/gatherDocs.js +++ b/website/gatherDocs.js @@ -2,7 +2,7 @@ const fs = require("fs-extra"); const git = require("nodegit"); const execSync = require("child_process").execSync; -const { major } = require("semver"); +const { major, lt } = require("semver"); const REPO_URL = "https://github.com/wix/detox.git"; async function getVersions() { @@ -12,7 +12,7 @@ async function getVersions() { const semverTags = tags .filter(tag => !tag.includes("@")) - .filter(tag => tag.split(".").length === 3 && major(tag) >= 6) + .filter(tag => tag.split(".").length === 3 && major(tag) >= 7) .sort() .reverse(); await fs.remove(tmp); @@ -54,7 +54,7 @@ async function checkoutVersion(repo, version) { await checkOutTag(repo, version); } -function applyTemporalFix(tempDir) { +function fixMarkdownForPre7_3_4_versions(tempDir) { // We need to do this as we forgot the header in this one file, but added git tags with it included console.log("Temporary fix for Guide.DebuggingInXcode"); const header = @@ -103,7 +103,9 @@ async function cleanUp(tempDir) { for (let version of versions) { console.log("Clone repository into tmp directory"); await checkoutVersion(repo, version); - applyTemporalFix(tempDir); + if (lt(version, "7.3.4")) { + fixMarkdownForPre7_3_4_versions(tempDir); + } generateAndCopyDocusaurusVersion(tempDir, version); repo.cleanup(tempDir); console.log(`Done with ${version}\n\n`); From 52dab8756dec43bbb5163abb0f6695e55469f44d Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Fri, 4 May 2018 07:48:37 +0200 Subject: [PATCH 09/10] remove autogenerated fragment --- website/pages/en/versions.js | 7 ------- 1 file changed, 7 deletions(-) diff --git a/website/pages/en/versions.js b/website/pages/en/versions.js index ddd6e53463..2a9d80dac7 100644 --- a/website/pages/en/versions.js +++ b/website/pages/en/versions.js @@ -1,10 +1,3 @@ -/** - * Copyright (c) 2017-present, Facebook, Inc. - * - * This source code is licensed under the MIT license found in the - * LICENSE file in the root directory of this source tree. - */ - const React = require('react'); const CompLibrary = require('../../core/CompLibrary'); From 70e8de1ede7fadd7ed127c4d1c78a18c7ac18a21 Mon Sep 17 00:00:00 2001 From: Daniel Schmidt Date: Fri, 4 May 2018 08:31:18 +0200 Subject: [PATCH 10/10] fix link to stackoverflow snippet --- website/gatherDocs.js | 26 ++++++++++++++------------ 1 file changed, 14 insertions(+), 12 deletions(-) diff --git a/website/gatherDocs.js b/website/gatherDocs.js index e8f93105b4..d2ac79713b 100644 --- a/website/gatherDocs.js +++ b/website/gatherDocs.js @@ -28,23 +28,25 @@ async function cleanupExistingVersions() { await fs.emptyDir("./versioned_sidebars"); } -// https://stackoverflow.com/questions/29569913/switch-branch-tag-with-nodegit?utm_medium=organic&utm_source=google_rich_qa&utm_campaign=google_rich_qa +// https://stackoverflow.com/a/46140283/1559386 function checkOutTag(repo, tag) { - return git.Reference - .dwim(repo, "refs/tags/" + tag) - .then(function (ref) { + return git.Reference.dwim(repo, "refs/tags/" + tag) + .then(function(ref) { return ref.peel(git.Object.TYPE.COMMIT); }) - .then(function (ref) { + .then(function(ref) { return repo.getCommit(ref); }) - .then(function (commit) { - return git.Checkout - .tree(repo, commit, { checkoutStrategy: git.Checkout.STRATEGY.FORCE }) - .then(function () { - return repo.setHeadDetached(commit, repo.defaultSignature, - "Checkout: HEAD " + commit.id()); - }) + .then(function(commit) { + return git.Checkout.tree(repo, commit, { + checkoutStrategy: git.Checkout.STRATEGY.FORCE + }).then(function() { + return repo.setHeadDetached( + commit, + repo.defaultSignature, + "Checkout: HEAD " + commit.id() + ); + }); }); }