diff --git a/android/app/build.gradle b/android/app/build.gradle
index 7f5ff51cdb0d3286c27108f768f807841caac3d3..0ecb77f4fd6c87e28f924e2b09925e9c2d72099f 100644
--- a/android/app/build.gradle
+++ b/android/app/build.gradle
@@ -105,8 +105,10 @@ android {
         versionCode 3
         versionName "0.1905.29-beta"
         ndk {
-            abiFilters "armeabi-v7a"
+            abiFilters "armeabi-v7a", "x86"
         }
+        testBuildType System.getProperty('testBuildType', 'debug')  // This will later be used to control the test apk build type
+        testInstrumentationRunner 'androidx.test.runner.AndroidJUnitRunner'
     }
     signingConfigs {
         release {
@@ -160,6 +162,8 @@ dependencies {
     compile fileTree(dir: "libs", include: ["*.jar"])
     compile "com.android.support:appcompat-v7:${rootProject.ext.supportLibVersion}"
     compile "com.facebook.react:react-native:+"  // From node_modules
+    androidTestImplementation('com.wix:detox:+') { transitive = true }
+    androidTestImplementation 'junit:junit:4.12'
 }
 
 // Run this once to be able to run the application with BUCK
diff --git a/android/app/src/androidTest/java/com/drip/DetoxTest.java b/android/app/src/androidTest/java/com/drip/DetoxTest.java
new file mode 100644
index 0000000000000000000000000000000000000000..b7a7068b59de66fcda6984eaf9bbafa32591b609
--- /dev/null
+++ b/android/app/src/androidTest/java/com/drip/DetoxTest.java
@@ -0,0 +1,24 @@
+package com.drip;
+
+import com.wix.detox.Detox;
+
+import org.junit.Rule;
+import org.junit.Test;
+import org.junit.runner.RunWith;
+
+import androidx.test.ext.junit.runners.AndroidJUnit4;
+import androidx.test.filters.LargeTest;
+import androidx.test.rule.ActivityTestRule;
+
+@RunWith(AndroidJUnit4.class)
+@LargeTest
+public class DetoxTest {
+
+    @Rule
+    public ActivityTestRule<MainActivity> mActivityRule = new ActivityTestRule<>(MainActivity.class, false, false);
+
+    @Test
+    public void runDetoxTests() {
+        Detox.runTests(mActivityRule);
+    }
+}
\ No newline at end of file
diff --git a/android/build.gradle b/android/build.gradle
index 82725d52a1e62c5c48e37475e7cab9a5ce9933f9..c158eca9d5d2be974450b90f8d3aee1d079cc175 100644
--- a/android/build.gradle
+++ b/android/build.gradle
@@ -5,11 +5,13 @@ buildscript {
         jcenter()
         google()
     }
+    ext.kotlinVersion = '1.3.0'
     dependencies {
         classpath 'com.android.tools.build:gradle:3.1.0'
 
         // NOTE: Do not place your application dependencies here; they belong
         // in the individual module build.gradle files
+        classpath "org.jetbrains.kotlin:kotlin-gradle-plugin:$kotlinVersion"
     }
 }
 
@@ -25,6 +27,11 @@ allprojects {
             url 'https://maven.google.com/'
             name 'Google'
         }
+        google()
+        maven {
+            // All of Detox' artifacts are provided via the npm module
+            url "$rootDir/../node_modules/detox/Detox-android"
+        }
     }
 }
 
diff --git a/components/button.js b/components/button.js
index 70d778ee72ddaf3056bc6ebad13d730d7fd3098f..41d5344967269ef96827b18e4f797047bb1004e6 100644
--- a/components/button.js
+++ b/components/button.js
@@ -11,7 +11,9 @@ export default function Button(props) {
         styles.button,
         props.style,
         {backgroundColor: props.backgroundColor}
-      ]}>
+      ]}
+      testID={props.testID}
+    >
       <AppText style={styles.homeButtonText}>
         {props.children}
       </AppText>
diff --git a/components/cycle-day/cycle-day-overview.js b/components/cycle-day/cycle-day-overview.js
index 0ab4526ef82b95c82dd41dbfcdcd63861c1fe3ba..407aac2b1280d8b2102cb7a27899425e53d86d25 100644
--- a/components/cycle-day/cycle-day-overview.js
+++ b/components/cycle-day/cycle-day-overview.js
@@ -278,6 +278,7 @@ class SymptomBox extends Component {
       <TouchableOpacity
         onPress={this.props.onPress}
         disabled={this.props.disabled}
+        testID={this.props.iconName}
       >
         <View style={[styles.symptomBox, boxActive, disabledStyle]}>
           <DripIcon name={this.props.iconName} size={50} color={hasData ? 'white' : 'black'}/>
diff --git a/components/cycle-day/symptoms/info-symptom.js b/components/cycle-day/symptoms/info-symptom.js
index e21c7adea7fba53f4d70161e83f4d14e10d0852c..887b22910b8dc541452a5a743c44a3cda20a9ea3 100644
--- a/components/cycle-day/symptoms/info-symptom.js
+++ b/components/cycle-day/symptoms/info-symptom.js
@@ -9,7 +9,7 @@ export default function InfoSymptom(props) {
   return (
     <View style={styles.infoPopUpWrapper}>
       <View style={styles.dimmed}></View>
-      <View style={styles.infoPopUp}>
+      <View style={styles.infoPopUp} testID="symptomInfoPopup">
         <TouchableOpacity onPress={props.close} style={styles.infoSymptomClose}>
           <Icon name='close' {...iconStyles.infoPopUpClose}/>
         </TouchableOpacity>
diff --git a/components/cycle-day/symptoms/symptom-view.js b/components/cycle-day/symptoms/symptom-view.js
index 28ddf4bbd867bacde7bc98c454b20862d19ba17e..d78b995922a9ef637935fea93955d11535397fdb 100644
--- a/components/cycle-day/symptoms/symptom-view.js
+++ b/components/cycle-day/symptoms/symptom-view.js
@@ -78,6 +78,7 @@ export default class SymptomView extends Component {
               this.setState({showInfo: true})
             }}
             style={styles.infoButtonSymptomView}
+            testID="symptomInfoButton"
           >
             <Icon
               name="info-with-circle"
diff --git a/components/header/back-button.js b/components/header/back-button.js
index db5e3e10fc736f0c99579309b8a84386b6b1efc7..be828027184f0aa791aa1d6c6c50f37bb427366c 100644
--- a/components/header/back-button.js
+++ b/components/header/back-button.js
@@ -13,9 +13,9 @@ export default function BackButtonHeader(props) {
         style={styles.accentCircle}
         left={props.middle - styles.accentCircle.width / 2}
       />
-      <NavigationArrow direction='left' {...props}/>
+      <NavigationArrow testID='backButton' direction='left' {...props}/>
       <View>
-        <Text style={styles.headerText}>
+        <Text style={styles.headerText} testID='pageTitle'>
           {props.title}
         </Text>
       </View>
diff --git a/components/header/cycle-day.js b/components/header/cycle-day.js
index 0cb32526084b8563f85038dd4be9d1a18ccf907d..33abfb104e0df8d4df94a83e39522e2f1bec99a0 100644
--- a/components/header/cycle-day.js
+++ b/components/header/cycle-day.js
@@ -14,7 +14,7 @@ export default function CycleDayHeader({ date, ...props }) {
     />
     <NavigationArrow direction='left' {...props}/>
     <View>
-      <Text style={styles.dateHeader}>
+      <Text style={styles.dateHeader} testID='cycleDayTitleDate'>
         {formatDate(date)}
       </Text>
       {props.cycleDayNumber &&
diff --git a/components/header/default.js b/components/header/default.js
index 8729c25c99e26ce0331c182b41063de7adfc97f1..ab2ecafbe1c548d3aa958f2660f0815f529585bd 100644
--- a/components/header/default.js
+++ b/components/header/default.js
@@ -8,7 +8,7 @@ export default function DefaultHeader(props) {
   return (
     <View style={styles.header}>
       <View style={styles.accentCircle} />
-      <Text style={styles.headerText}>
+      <Text testID='pageTitle' style={styles.headerText}>
         {props.title}
       </Text>
     </View >
diff --git a/components/header/navigation-arrow.js b/components/header/navigation-arrow.js
index b574142214b335f0b5d9ff2c086f5df9a4dc9b18..336e2f6a417dac593878a5653ffe7eb3575ff32b 100644
--- a/components/header/navigation-arrow.js
+++ b/components/header/navigation-arrow.js
@@ -25,6 +25,7 @@ export default function NavigationArrow(props) {
     <TouchableOpacity
       style={[styles.navigationArrow, styles[iconPosition]]}
       onPress={pressHandler}
+      testID={props.testID}
     >
       <Icon
         name={iconName}
diff --git a/components/header/symptom-view.js b/components/header/symptom-view.js
index 1d56a8194c80ed5caa93678a24a1b80c4e8c130e..f2797de0249e7b845c07a3e6f35874fc05fc72ca 100644
--- a/components/header/symptom-view.js
+++ b/components/header/symptom-view.js
@@ -23,10 +23,10 @@ export default function SymptomViewHeader(props) {
         {...props}
       />
       <View>
-        <Text style={styles.dateHeader}>
+        <Text style={styles.dateHeader} testID='symptomViewTitleName'>
           {props.title}
         </Text>
-        <Text style={styles.cycleDayNumber}>
+        <Text style={styles.cycleDayNumber} testID='symptomViewTitleDate'>
           {formatDate(props.date)}
         </Text>
       </View >
diff --git a/components/license.js b/components/license.js
index a908c5cc96dba5e90bc815ed6c7ea808d7f8c9b9..5a95ad1407856502ac9153edf9980dbf55c64276 100644
--- a/components/license.js
+++ b/components/license.js
@@ -10,14 +10,15 @@ import { saveLicenseFlag } from '../local-storage'
 const labels = settingsLabels.license
 export default function License({setLicense}) {
   return (
-    <ScrollView style={styles.licensePage}>
+    <ScrollView testID='licensePage' style={styles.licensePage}>
       <AppText style={styles.framedSegmentTitle}>{labels.title}</AppText>
-      <AppText>{labels.text}</AppText>
+      <AppText testID='test'>{labels.text}</AppText>
       <View style={styles.licenseButtons}>
         <Button
           style={styles.licenseButton}
           backgroundColor={'grey'}
           onPress={() => BackHandler.exitApp()}
+          testID='licenseCancelButton'
         >
           {shared.cancel}
         </Button>
@@ -28,6 +29,7 @@ export default function License({setLicense}) {
             await saveLicenseFlag()
             setLicense()
           }}
+          testID='licenseOkButton'
         >
           {shared.ok}
         </Button>
diff --git a/components/menu.js b/components/menu.js
index 26a752da7fcb08d83223c2ec82a423c17053e213..3664e153e28e6ddb3fed2699a4ab154ba72110dd 100644
--- a/components/menu.js
+++ b/components/menu.js
@@ -54,7 +54,10 @@ const MenuItem = ({ icon, labelKey, active, onPress }) => {
       onPress={onPress}
     >
       <Icon name={icon} {...iconStyles.menuIcon} {...styleActive} />
-      <Text style={[styles.menuText, styleActive]}>
+      <Text
+        testID={active ? 'activeMenuItem' : `menuItem${labelKey}`}
+        style={[styles.menuText, styleActive]}
+      >
         {menuTitlesLowerCase[labelKey]}
       </Text>
     </TouchableOpacity>
diff --git a/e2e/.eslintrc b/e2e/.eslintrc
new file mode 100644
index 0000000000000000000000000000000000000000..65e1a2a7681c7bf69d4a05d5791a3367e8adb2b2
--- /dev/null
+++ b/e2e/.eslintrc
@@ -0,0 +1,8 @@
+{
+  "globals": {
+    "expect": true,
+    "element": true,
+    "by": true,
+    "device": true,
+  }
+}
\ No newline at end of file
diff --git a/e2e/homeNavigation.spec.js b/e2e/homeNavigation.spec.js
new file mode 100644
index 0000000000000000000000000000000000000000..ae39b9a1b56b4d286900ee9bd58514015d028094
--- /dev/null
+++ b/e2e/homeNavigation.spec.js
@@ -0,0 +1,132 @@
+const isOnPage = async (page, parentPage) => {
+  await expect(
+    element(by.id('pageTitle').and(by.text(page)))
+  ).toBeVisible()
+  await expect(
+    element(
+      by.id('activeMenuItem').and(by.text(parentPage ? parentPage : page))
+    )
+  ).toBeVisible()
+}
+
+describe('Home Navigation', () => {
+  beforeEach(async () => {
+    await device.reloadReactNative()
+  })
+
+  // TODO: clarify how to test that exiting from the app happened
+  // https://stackoverflow.com/questions/57133730/how-to-test-an-exit-app-scenario-using-detox
+  // it('should exit the app when license agreement declined', async () => {
+  //   await expect(element(by.id('licensePage'))).toBeVisible();
+  //   await element(by.id('licenseOkCance')).tap();
+  // });
+
+  it('should navigate to home on accepting the license agreement', async () => {
+    await expect(element(by.id('licensePage'))).toBeVisible()
+    await element(by.id('licenseOkButton')).tap()
+    await isOnPage('home')
+  })
+
+  it('should navigate to today bleeding symptom', async () => {
+    await element(by.text('track your period')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('bleeding')))
+    ).toBeVisible()
+    await expect(
+      element(by.id('symptomViewTitleDate').and(by.text('today')))
+    ).toBeVisible()
+  })
+
+  it('should navigate to chart to check your fertility', async () => {
+    await element(by.text('check your fertility')).tap()
+    await isOnPage('chart')
+  })
+
+  it('should navigate to settings, its sub pages and back', async () => {
+    await element(by.id('menuItemSettings')).tap()
+    await isOnPage('settings')
+    await element(by.text('reminders')).tap()
+    await isOnPage('reminders', 'settings')
+    await element(by.id('backButton')).tap()
+    await element(by.text('nfp settings')).tap()
+    await isOnPage('nfp settings', 'settings')
+    await device.pressBack()
+  })
+
+  it('should navigate to today cycle day page and all its symptoms', async () => {
+    await element(by.text('add data for today')).tap()
+    await expect(
+      element(by.id('cycleDayTitleDate').and(by.text('today')))
+    ).toBeVisible()
+
+    await element(by.id('drip-icon-bleeding')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('bleeding')))
+    ).toBeVisible()
+    await device.pressBack()
+
+    await element(by.id('drip-icon-temperature')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('temperature')))
+    ).toBeVisible()
+    // first back press removes the focus from the field and the input keyboard
+    await device.pressBack()
+    // second back press goes back to the cycle day view
+    await device.pressBack()
+
+    await element(by.id('drip-icon-mucus')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('cervical mucus')))
+    ).toBeVisible()
+    await device.pressBack()
+
+    await element(by.id('drip-icon-cervix')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('cervix')))
+    ).toBeVisible()
+    await device.pressBack()
+
+    await element(by.id('drip-icon-desire')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('desire')))
+    ).toBeVisible()
+    await device.pressBack()
+
+    await element(by.id('drip-icon-sex')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('sex')))
+    ).toBeVisible()
+    await device.pressBack()
+
+    await element(by.id('drip-icon-pain')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('pain')))
+    ).toBeVisible()
+    await device.pressBack()
+
+    await element(by.id('drip-icon-mood')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('mood')))
+    ).toBeVisible()
+    await device.pressBack()
+
+    await element(by.id('drip-icon-note')).tap()
+    await expect(
+      element(by.id('symptomViewTitleName').and(by.text('note')))
+    ).toBeVisible()
+    await element(by.id('symptomInfoButton')).tap()
+    await expect(element(by.id('symptomInfoPopup'))).toBeVisible()
+
+    // first back press removes the focus from the field and the input keyboard
+    await device.pressBack()
+    // second back press goes back to the cycle day view
+    await device.pressBack()
+
+    await expect(
+      element(by.id('cycleDayTitleDate').and(by.text('today')))
+    ).toBeVisible()
+
+    // waiting for a feedback on what should happen on pressing back
+
+  })
+})
diff --git a/e2e/init.js b/e2e/init.js
new file mode 100644
index 0000000000000000000000000000000000000000..b7b58350e87b53f741350c1575e5dd13ff87968f
--- /dev/null
+++ b/e2e/init.js
@@ -0,0 +1,19 @@
+const detox = require('detox');
+const config = require('../package.json').detox;
+const adapter = require('detox/runners/mocha/adapter');
+
+before(async () => {
+  await detox.init(config);
+});
+
+beforeEach(async function () {
+  await adapter.beforeEach(this);
+});
+
+afterEach(async function () {
+  await adapter.afterEach(this);
+});
+
+after(async () => {
+  await detox.cleanup();
+});
diff --git a/e2e/mocha.opts b/e2e/mocha.opts
new file mode 100644
index 0000000000000000000000000000000000000000..b82090cee0548ac2a57eabd5af92c7e5f66e59d9
--- /dev/null
+++ b/e2e/mocha.opts
@@ -0,0 +1 @@
+--recursive --timeout 120000 --bail --file e2e/init.js
diff --git a/package-lock.json b/package-lock.json
index c0ed0b19c5e4e68d18435f653c019a524d005e54..5f7b26ea9ada6984ae3c1c5493a049548ec47890 100644
--- a/package-lock.json
+++ b/package-lock.json
@@ -1657,6 +1657,28 @@
       "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
       "integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A=="
     },
+    "bunyan": {
+      "version": "1.8.12",
+      "resolved": "https://registry.npmjs.org/bunyan/-/bunyan-1.8.12.tgz",
+      "integrity": "sha1-8VDw9nSKvdcq6uhPBEA74u8RN5c=",
+      "dev": true,
+      "requires": {
+        "dtrace-provider": "~0.8",
+        "moment": "^2.10.6",
+        "mv": "~2",
+        "safe-json-stringify": "~1"
+      }
+    },
+    "bunyan-debug-stream": {
+      "version": "1.1.1",
+      "resolved": "https://registry.npmjs.org/bunyan-debug-stream/-/bunyan-debug-stream-1.1.1.tgz",
+      "integrity": "sha512-jJbQ1gXUL6vMmZVdbaTFK1v1sGa7axLrSQQwkB6HU9HCPTzsw2HsKcPHm1vgXZlEck/4IvEuRwg/9+083YelCg==",
+      "dev": true,
+      "requires": {
+        "colors": "^1.0.3",
+        "exception-formatter": "^1.0.4"
+      }
+    },
     "bytes": {
       "version": "3.0.0",
       "resolved": "https://registry.npmjs.org/bytes/-/bytes-3.0.0.tgz",
@@ -1784,6 +1806,29 @@
       "integrity": "sha1-V00xLt2Iu13YkS6Sht1sCu1KrII=",
       "dev": true
     },
+    "child-process-promise": {
+      "version": "2.2.1",
+      "resolved": "https://registry.npmjs.org/child-process-promise/-/child-process-promise-2.2.1.tgz",
+      "integrity": "sha1-RzChHvYQ+tRQuPIjx50x172tgHQ=",
+      "dev": true,
+      "requires": {
+        "cross-spawn": "^4.0.2",
+        "node-version": "^1.0.0",
+        "promise-polyfill": "^6.0.1"
+      },
+      "dependencies": {
+        "cross-spawn": {
+          "version": "4.0.2",
+          "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-4.0.2.tgz",
+          "integrity": "sha1-e5JHYhwjrf3ThWAEqCPL45dCTUE=",
+          "dev": true,
+          "requires": {
+            "lru-cache": "^4.0.1",
+            "which": "^1.2.9"
+          }
+        }
+      }
+    },
     "chownr": {
       "version": "1.1.1",
       "resolved": "https://registry.npmjs.org/chownr/-/chownr-1.1.1.tgz",
@@ -1881,6 +1926,12 @@
       "resolved": "https://registry.npmjs.org/color-support/-/color-support-1.1.3.tgz",
       "integrity": "sha512-qiBjkpbMLO/HL68y+lh4q0/O1MZFj2RX6X/KmMa3+gJD3z+WwI1ZzDHysvqHGS3mP6mznPckpXmw1nI9cJjyRg=="
     },
+    "colors": {
+      "version": "1.3.3",
+      "resolved": "https://registry.npmjs.org/colors/-/colors-1.3.3.tgz",
+      "integrity": "sha512-mmGt/1pZqYRjMxB1axhTo16/snVZ5krrKkcmMeVKxzECMMXoCgnvTPp10QgHfcbQZw8Dq2jMNG6je4JlWU0gWg==",
+      "dev": true
+    },
     "combined-stream": {
       "version": "1.0.7",
       "resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.7.tgz",
@@ -2307,6 +2358,358 @@
       "resolved": "https://registry.npmjs.org/detect-libc/-/detect-libc-1.0.3.tgz",
       "integrity": "sha1-+hN8S9aY7fVc1c0CrFWfkaTEups="
     },
+    "detox": {
+      "version": "13.1.1",
+      "resolved": "https://registry.npmjs.org/detox/-/detox-13.1.1.tgz",
+      "integrity": "sha512-dDtV64wMryeHk/+Np339Gm5uEzjxFySUHxLmz9iMsDFgkPn+XDkBdPZtb76pRQwJnpSWlbKVP1zhcN9B6vfsJg==",
+      "dev": true,
+      "requires": {
+        "@babel/core": "^7.4.5",
+        "bunyan": "^1.8.12",
+        "bunyan-debug-stream": "^1.1.0",
+        "chalk": "^2.4.2",
+        "child-process-promise": "^2.2.0",
+        "fs-extra": "^4.0.2",
+        "funpermaproxy": "^1.0.1",
+        "get-port": "^2.1.0",
+        "ini": "^1.3.4",
+        "lodash": "^4.17.5",
+        "minimist": "^1.2.0",
+        "proper-lockfile": "^3.0.2",
+        "sanitize-filename": "^1.6.1",
+        "shell-utils": "^1.0.9",
+        "tail": "^2.0.0",
+        "telnet-client": "0.15.3",
+        "tempfile": "^2.0.0",
+        "ws": "^3.3.1",
+        "yargs": "^13.0.0",
+        "yargs-parser": "^13.0.0"
+      },
+      "dependencies": {
+        "@babel/core": {
+          "version": "7.5.4",
+          "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.5.4.tgz",
+          "integrity": "sha512-+DaeBEpYq6b2+ZmHx3tHspC+ZRflrvLqwfv8E3hNr5LVQoyBnL8RPKSBCg+rK2W2My9PWlujBiqd0ZPsR9Q6zQ==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.0.0",
+            "@babel/generator": "^7.5.0",
+            "@babel/helpers": "^7.5.4",
+            "@babel/parser": "^7.5.0",
+            "@babel/template": "^7.4.4",
+            "@babel/traverse": "^7.5.0",
+            "@babel/types": "^7.5.0",
+            "convert-source-map": "^1.1.0",
+            "debug": "^4.1.0",
+            "json5": "^2.1.0",
+            "lodash": "^4.17.11",
+            "resolve": "^1.3.2",
+            "semver": "^5.4.1",
+            "source-map": "^0.5.0"
+          }
+        },
+        "@babel/generator": {
+          "version": "7.5.0",
+          "resolved": "https://registry.npmjs.org/@babel/generator/-/generator-7.5.0.tgz",
+          "integrity": "sha512-1TTVrt7J9rcG5PMjvO7VEG3FrEoEJNHxumRq66GemPmzboLWtIjjcJgk8rokuAS7IiRSpgVSu5Vb9lc99iJkOA==",
+          "dev": true,
+          "requires": {
+            "@babel/types": "^7.5.0",
+            "jsesc": "^2.5.1",
+            "lodash": "^4.17.11",
+            "source-map": "^0.5.0",
+            "trim-right": "^1.0.1"
+          }
+        },
+        "@babel/helpers": {
+          "version": "7.5.4",
+          "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.5.4.tgz",
+          "integrity": "sha512-6LJ6xwUEJP51w0sIgKyfvFMJvIb9mWAfohJp0+m6eHJigkFdcH8duZ1sfhn0ltJRzwUIT/yqqhdSfRpCpL7oow==",
+          "dev": true,
+          "requires": {
+            "@babel/template": "^7.4.4",
+            "@babel/traverse": "^7.5.0",
+            "@babel/types": "^7.5.0"
+          }
+        },
+        "@babel/parser": {
+          "version": "7.5.0",
+          "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.5.0.tgz",
+          "integrity": "sha512-I5nW8AhGpOXGCCNYGc+p7ExQIBxRFnS2fd/d862bNOKvmoEPjYPcfIjsfdy0ujagYOIYPczKgD9l3FsgTkAzKA==",
+          "dev": true
+        },
+        "@babel/traverse": {
+          "version": "7.5.0",
+          "resolved": "https://registry.npmjs.org/@babel/traverse/-/traverse-7.5.0.tgz",
+          "integrity": "sha512-SnA9aLbyOCcnnbQEGwdfBggnc142h/rbqqsXcaATj2hZcegCl903pUD/lfpsNBlBSuWow/YDfRyJuWi2EPR5cg==",
+          "dev": true,
+          "requires": {
+            "@babel/code-frame": "^7.0.0",
+            "@babel/generator": "^7.5.0",
+            "@babel/helper-function-name": "^7.1.0",
+            "@babel/helper-split-export-declaration": "^7.4.4",
+            "@babel/parser": "^7.5.0",
+            "@babel/types": "^7.5.0",
+            "debug": "^4.1.0",
+            "globals": "^11.1.0",
+            "lodash": "^4.17.11"
+          }
+        },
+        "@babel/types": {
+          "version": "7.5.0",
+          "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.5.0.tgz",
+          "integrity": "sha512-UFpDVqRABKsW01bvw7/wSUe56uy6RXM5+VJibVVAybDGxEW25jdwiFJEf7ASvSaC7sN7rbE/l3cLp2izav+CtQ==",
+          "dev": true,
+          "requires": {
+            "esutils": "^2.0.2",
+            "lodash": "^4.17.11",
+            "to-fast-properties": "^2.0.0"
+          }
+        },
+        "ansi-regex": {
+          "version": "4.1.0",
+          "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.0.tgz",
+          "integrity": "sha512-1apePfXM1UOSqw0o9IiFAovVz9M5S1Dg+4TrDwfMewQ6p/rmMueb7tWZjQ1rx4Loy1ArBggoqGpfqqdI4rondg==",
+          "dev": true
+        },
+        "ansi-styles": {
+          "version": "3.2.1",
+          "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
+          "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
+          "dev": true,
+          "requires": {
+            "color-convert": "^1.9.0"
+          }
+        },
+        "camelcase": {
+          "version": "5.3.1",
+          "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz",
+          "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==",
+          "dev": true
+        },
+        "chalk": {
+          "version": "2.4.2",
+          "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
+          "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.1",
+            "escape-string-regexp": "^1.0.5",
+            "supports-color": "^5.3.0"
+          }
+        },
+        "cliui": {
+          "version": "5.0.0",
+          "resolved": "https://registry.npmjs.org/cliui/-/cliui-5.0.0.tgz",
+          "integrity": "sha512-PYeGSEmmHM6zvoef2w8TPzlrnNpXIjTipYK780YswmIP9vjxmd6Y2a3CB2Ks6/AU8NHjZugXvo8w3oWM2qnwXA==",
+          "dev": true,
+          "requires": {
+            "string-width": "^3.1.0",
+            "strip-ansi": "^5.2.0",
+            "wrap-ansi": "^5.1.0"
+          }
+        },
+        "debug": {
+          "version": "4.1.1",
+          "resolved": "https://registry.npmjs.org/debug/-/debug-4.1.1.tgz",
+          "integrity": "sha512-pYAIzeRo8J6KPEaJ0VWOh5Pzkbw/RetuzehGM7QRRX5he4fPHx2rdKMB256ehJCkX+XRQm16eZLqLNS8RSZXZw==",
+          "dev": true,
+          "requires": {
+            "ms": "^2.1.1"
+          }
+        },
+        "find-up": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/find-up/-/find-up-3.0.0.tgz",
+          "integrity": "sha512-1yD6RmLI1XBfxugvORwlck6f75tYL+iR0jqwsOrOxMZyGYqUuDhJ0l4AXdO1iX/FTs9cBAMEk1gWSEx1kSbylg==",
+          "dev": true,
+          "requires": {
+            "locate-path": "^3.0.0"
+          }
+        },
+        "fs-extra": {
+          "version": "4.0.3",
+          "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-4.0.3.tgz",
+          "integrity": "sha512-q6rbdDd1o2mAnQreO7YADIxf/Whx4AHBiRf6d+/cVT8h44ss+lHgxf1FemcqDnQt9X3ct4McHr+JMGlYSsK7Cg==",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.2",
+            "jsonfile": "^4.0.0",
+            "universalify": "^0.1.0"
+          }
+        },
+        "get-caller-file": {
+          "version": "2.0.5",
+          "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-2.0.5.tgz",
+          "integrity": "sha512-DyFP3BM/3YHTQOCUL/w0OZHR0lpKeGrxotcHWcqNEdnltqFwXVfhEBQ94eIo34AfQpo0rGki4cyIiftY06h2Fg==",
+          "dev": true
+        },
+        "is-fullwidth-code-point": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-2.0.0.tgz",
+          "integrity": "sha1-o7MKXE8ZkYMWeqq5O+764937ZU8=",
+          "dev": true
+        },
+        "jsonfile": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/jsonfile/-/jsonfile-4.0.0.tgz",
+          "integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
+          "dev": true,
+          "requires": {
+            "graceful-fs": "^4.1.6"
+          }
+        },
+        "locate-path": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-3.0.0.tgz",
+          "integrity": "sha512-7AO748wWnIhNqAuaty2ZWHkQHRSNfPVIsPIfwEOWO22AmaoVrWavlOcMR5nzTLNYvp36X220/maaRsrec1G65A==",
+          "dev": true,
+          "requires": {
+            "p-locate": "^3.0.0",
+            "path-exists": "^3.0.0"
+          }
+        },
+        "minimist": {
+          "version": "1.2.0",
+          "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.0.tgz",
+          "integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
+          "dev": true
+        },
+        "ms": {
+          "version": "2.1.2",
+          "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz",
+          "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==",
+          "dev": true
+        },
+        "p-limit": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.0.tgz",
+          "integrity": "sha512-pZbTJpoUsCzV48Mc9Nh51VbwO0X9cuPFE8gYwx9BTCt9SF8/b7Zljd2fVgOxhIF/HDTKgpVzs+GPhyKfjLLFRQ==",
+          "dev": true,
+          "requires": {
+            "p-try": "^2.0.0"
+          }
+        },
+        "p-locate": {
+          "version": "3.0.0",
+          "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-3.0.0.tgz",
+          "integrity": "sha512-x+12w/To+4GFfgJhBEpiDcLozRJGegY+Ei7/z0tSLkMmxGZNybVMSfWj9aJn8Z5Fc7dBUNJOOVgPv2H7IwulSQ==",
+          "dev": true,
+          "requires": {
+            "p-limit": "^2.0.0"
+          }
+        },
+        "p-try": {
+          "version": "2.2.0",
+          "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz",
+          "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==",
+          "dev": true
+        },
+        "require-main-filename": {
+          "version": "2.0.0",
+          "resolved": "https://registry.npmjs.org/require-main-filename/-/require-main-filename-2.0.0.tgz",
+          "integrity": "sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg==",
+          "dev": true
+        },
+        "semver": {
+          "version": "5.7.0",
+          "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
+          "integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
+          "dev": true
+        },
+        "string-width": {
+          "version": "3.1.0",
+          "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz",
+          "integrity": "sha512-vafcv6KjVZKSgz06oM/H6GDBrAtz8vdhQakGjFIvNrHA6y3HCF1CInLy+QLq8dTJPQ1b+KDUqDFctkdRW44e1w==",
+          "dev": true,
+          "requires": {
+            "emoji-regex": "^7.0.1",
+            "is-fullwidth-code-point": "^2.0.0",
+            "strip-ansi": "^5.1.0"
+          }
+        },
+        "strip-ansi": {
+          "version": "5.2.0",
+          "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-5.2.0.tgz",
+          "integrity": "sha512-DuRs1gKbBqsMKIZlrffwlug8MHkcnpjs5VPmL1PAh+mA30U0DTotfDZ0d2UUsXpPmPmMMJ6W773MaA3J+lbiWA==",
+          "dev": true,
+          "requires": {
+            "ansi-regex": "^4.1.0"
+          }
+        },
+        "supports-color": {
+          "version": "5.5.0",
+          "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
+          "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
+          "dev": true,
+          "requires": {
+            "has-flag": "^3.0.0"
+          }
+        },
+        "ultron": {
+          "version": "1.1.1",
+          "resolved": "https://registry.npmjs.org/ultron/-/ultron-1.1.1.tgz",
+          "integrity": "sha512-UIEXBNeYmKptWH6z8ZnqTeS8fV74zG0/eRU9VGkpzz+LIJNs8W/zM/L+7ctCkRrgbNnnR0xxw4bKOr0cW0N0Og==",
+          "dev": true
+        },
+        "wrap-ansi": {
+          "version": "5.1.0",
+          "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-5.1.0.tgz",
+          "integrity": "sha512-QC1/iN/2/RPVJ5jYK8BGttj5z83LmSKmvbvrXPNCLZSEb32KKVDJDl/MOt2N01qU2H/FkzEa9PKto1BqDjtd7Q==",
+          "dev": true,
+          "requires": {
+            "ansi-styles": "^3.2.0",
+            "string-width": "^3.0.0",
+            "strip-ansi": "^5.0.0"
+          }
+        },
+        "ws": {
+          "version": "3.3.3",
+          "resolved": "https://registry.npmjs.org/ws/-/ws-3.3.3.tgz",
+          "integrity": "sha512-nnWLa/NwZSt4KQJu51MYlCcSQ5g7INpOrOMt4XV8j4dqTXdmlUmSHQ8/oLC069ckre0fRsgfvsKwbTdtKLCDkA==",
+          "dev": true,
+          "requires": {
+            "async-limiter": "~1.0.0",
+            "safe-buffer": "~5.1.0",
+            "ultron": "~1.1.0"
+          }
+        },
+        "y18n": {
+          "version": "4.0.0",
+          "resolved": "https://registry.npmjs.org/y18n/-/y18n-4.0.0.tgz",
+          "integrity": "sha512-r9S/ZyXu/Xu9q1tYlpsLIsa3EeLXXk0VwlxqTcFRfg9EhMW+17kbt9G0NrgCmhGb5vT2hyhJZLfDGx+7+5Uj/w==",
+          "dev": true
+        },
+        "yargs": {
+          "version": "13.3.0",
+          "resolved": "https://registry.npmjs.org/yargs/-/yargs-13.3.0.tgz",
+          "integrity": "sha512-2eehun/8ALW8TLoIl7MVaRUrg+yCnenu8B4kBlRxj3GJGDKU1Og7sMXPNm1BYyM1DOJmTZ4YeN/Nwxv+8XJsUA==",
+          "dev": true,
+          "requires": {
+            "cliui": "^5.0.0",
+            "find-up": "^3.0.0",
+            "get-caller-file": "^2.0.1",
+            "require-directory": "^2.1.1",
+            "require-main-filename": "^2.0.0",
+            "set-blocking": "^2.0.0",
+            "string-width": "^3.0.0",
+            "which-module": "^2.0.0",
+            "y18n": "^4.0.0",
+            "yargs-parser": "^13.1.1"
+          }
+        },
+        "yargs-parser": {
+          "version": "13.1.1",
+          "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-13.1.1.tgz",
+          "integrity": "sha512-oVAVsHz6uFrg3XQheFII8ESO2ssAf9luWuAd6Wexsu4F3OtIW0o8IribPXYrD4WC24LWtPrJlGy87y5udK+dxQ==",
+          "dev": true,
+          "requires": {
+            "camelcase": "^5.0.0",
+            "decamelize": "^1.2.0"
+          }
+        }
+      }
+    },
     "diff": {
       "version": "3.5.0",
       "resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
@@ -2339,6 +2742,16 @@
       "integrity": "sha512-ch5OQgvGDK2u8pSZeSYAQaV/lczImd7pMJ7BcEPXmnFVjy4yJIzP6CsODJUTH8mg1tyH1Z2abOiuJO3DjZ/GBw==",
       "dev": true
     },
+    "dtrace-provider": {
+      "version": "0.8.7",
+      "resolved": "https://registry.npmjs.org/dtrace-provider/-/dtrace-provider-0.8.7.tgz",
+      "integrity": "sha1-3JObTT4GIM/gwc2APQ0tftBP/QQ=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "nan": "^2.10.0"
+      }
+    },
     "ecc-jsbn": {
       "version": "0.1.2",
       "resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
@@ -2838,6 +3251,15 @@
       "resolved": "https://registry.npmjs.org/eventemitter3/-/eventemitter3-3.1.2.tgz",
       "integrity": "sha512-tvtQIeLVHjDkJYnzf2dgVMxfuSGJeM/7UCG17TT4EumTfNtF+0nebF/4zWOIkCreAbtNqhGEboB6BWrwqNaw4Q=="
     },
+    "exception-formatter": {
+      "version": "1.0.7",
+      "resolved": "https://registry.npmjs.org/exception-formatter/-/exception-formatter-1.0.7.tgz",
+      "integrity": "sha512-zV45vEsjytJrwfGq6X9qd1Ll56cW4NC2mhCO6lqwMk4ZpA1fZ6C3UiaQM/X7if+7wZFmCgss3ahp9B/uVFuLRw==",
+      "dev": true,
+      "requires": {
+        "colors": "^1.0.3"
+      }
+    },
     "exec-sh": {
       "version": "0.2.2",
       "resolved": "https://registry.npmjs.org/exec-sh/-/exec-sh-0.2.2.tgz",
@@ -3228,8 +3650,7 @@
         },
         "ansi-regex": {
           "version": "2.1.1",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "aproba": {
           "version": "1.2.0",
@@ -3247,13 +3668,11 @@
         },
         "balanced-match": {
           "version": "1.0.0",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "brace-expansion": {
           "version": "1.1.11",
           "bundled": true,
-          "optional": true,
           "requires": {
             "balanced-match": "^1.0.0",
             "concat-map": "0.0.1"
@@ -3266,18 +3685,15 @@
         },
         "code-point-at": {
           "version": "1.1.0",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "concat-map": {
           "version": "0.0.1",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "console-control-strings": {
           "version": "1.1.0",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "core-util-is": {
           "version": "1.0.2",
@@ -3380,8 +3796,7 @@
         },
         "inherits": {
           "version": "2.0.3",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "ini": {
           "version": "1.3.5",
@@ -3391,7 +3806,6 @@
         "is-fullwidth-code-point": {
           "version": "1.0.0",
           "bundled": true,
-          "optional": true,
           "requires": {
             "number-is-nan": "^1.0.0"
           }
@@ -3404,20 +3818,17 @@
         "minimatch": {
           "version": "3.0.4",
           "bundled": true,
-          "optional": true,
           "requires": {
             "brace-expansion": "^1.1.7"
           }
         },
         "minimist": {
           "version": "0.0.8",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "minipass": {
           "version": "2.3.5",
           "bundled": true,
-          "optional": true,
           "requires": {
             "safe-buffer": "^5.1.2",
             "yallist": "^3.0.0"
@@ -3434,7 +3845,6 @@
         "mkdirp": {
           "version": "0.5.1",
           "bundled": true,
-          "optional": true,
           "requires": {
             "minimist": "0.0.8"
           }
@@ -3507,8 +3917,7 @@
         },
         "number-is-nan": {
           "version": "1.0.1",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "object-assign": {
           "version": "4.1.1",
@@ -3518,7 +3927,6 @@
         "once": {
           "version": "1.4.0",
           "bundled": true,
-          "optional": true,
           "requires": {
             "wrappy": "1"
           }
@@ -3594,8 +4002,7 @@
         },
         "safe-buffer": {
           "version": "5.1.2",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "safer-buffer": {
           "version": "2.1.2",
@@ -3625,7 +4032,6 @@
         "string-width": {
           "version": "1.0.2",
           "bundled": true,
-          "optional": true,
           "requires": {
             "code-point-at": "^1.0.0",
             "is-fullwidth-code-point": "^1.0.0",
@@ -3643,7 +4049,6 @@
         "strip-ansi": {
           "version": "3.0.1",
           "bundled": true,
-          "optional": true,
           "requires": {
             "ansi-regex": "^2.0.0"
           }
@@ -3682,13 +4087,11 @@
         },
         "wrappy": {
           "version": "1.0.2",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         },
         "yallist": {
           "version": "3.0.3",
-          "bundled": true,
-          "optional": true
+          "bundled": true
         }
       }
     },
@@ -3704,6 +4107,12 @@
       "integrity": "sha1-GwqzvVU7Kg1jmdKcDj6gslIHgyc=",
       "dev": true
     },
+    "funpermaproxy": {
+      "version": "1.0.1",
+      "resolved": "https://registry.npmjs.org/funpermaproxy/-/funpermaproxy-1.0.1.tgz",
+      "integrity": "sha512-9pEzs5vnNtR7ZGihly98w/mQ7blsvl68Wj30ZCDAXy7qDN4CWLLjdfjtH/P2m6whsnaJkw15hysCNHMXue+wdA==",
+      "dev": true
+    },
     "gauge": {
       "version": "2.7.4",
       "resolved": "https://registry.npmjs.org/gauge/-/gauge-2.7.4.tgz",
@@ -3730,6 +4139,15 @@
       "integrity": "sha1-6td0q+5y4gQJQzoGY2YCPdaIekE=",
       "dev": true
     },
+    "get-port": {
+      "version": "2.1.0",
+      "resolved": "https://registry.npmjs.org/get-port/-/get-port-2.1.0.tgz",
+      "integrity": "sha1-h4P53OvR7qSVozThpqJR54iHqxo=",
+      "dev": true,
+      "requires": {
+        "pinkie-promise": "^2.0.0"
+      }
+    },
     "get-stream": {
       "version": "4.1.0",
       "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-4.1.0.tgz",
@@ -5473,6 +5891,44 @@
       "resolved": "https://registry.npmjs.org/mute-stream/-/mute-stream-0.0.7.tgz",
       "integrity": "sha1-MHXOk7whuPq0PhvE2n6BFe0ee6s="
     },
+    "mv": {
+      "version": "2.1.1",
+      "resolved": "https://registry.npmjs.org/mv/-/mv-2.1.1.tgz",
+      "integrity": "sha1-rmzg1vbV4KT32JN5jQPB6pVZtqI=",
+      "dev": true,
+      "optional": true,
+      "requires": {
+        "mkdirp": "~0.5.1",
+        "ncp": "~2.0.0",
+        "rimraf": "~2.4.0"
+      },
+      "dependencies": {
+        "glob": {
+          "version": "6.0.4",
+          "resolved": "https://registry.npmjs.org/glob/-/glob-6.0.4.tgz",
+          "integrity": "sha1-DwiGD2oVUSey+t1PnOJLGqtuTSI=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "inflight": "^1.0.4",
+            "inherits": "2",
+            "minimatch": "2 || 3",
+            "once": "^1.3.0",
+            "path-is-absolute": "^1.0.0"
+          }
+        },
+        "rimraf": {
+          "version": "2.4.5",
+          "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.4.5.tgz",
+          "integrity": "sha1-7nEM5dk6j9uFb7Xqj/Di11k0sto=",
+          "dev": true,
+          "optional": true,
+          "requires": {
+            "glob": "^6.0.1"
+          }
+        }
+      }
+    },
     "nan": {
       "version": "2.13.2",
       "resolved": "https://registry.npmjs.org/nan/-/nan-2.13.2.tgz",
@@ -5662,6 +6118,12 @@
         }
       }
     },
+    "node-version": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/node-version/-/node-version-1.2.0.tgz",
+      "integrity": "sha512-ma6oU4Sk0qOoKEAymVoTvk8EdXEobdS7m/mAGhDJ8Rouugho48crHBORAmy5BoOcv8wraPM6xumapQp5hl4iIQ==",
+      "dev": true
+    },
     "nodejs-mobile-gyp": {
       "version": "0.3.1",
       "resolved": "https://registry.npmjs.org/nodejs-mobile-gyp/-/nodejs-mobile-gyp-0.3.1.tgz",
@@ -6334,6 +6796,12 @@
         "asap": "~2.0.3"
       }
     },
+    "promise-polyfill": {
+      "version": "6.1.0",
+      "resolved": "https://registry.npmjs.org/promise-polyfill/-/promise-polyfill-6.1.0.tgz",
+      "integrity": "sha1-36lpQ+qcEh/KTem1hoyznTRy4Fc=",
+      "dev": true
+    },
     "prop-types": {
       "version": "15.7.2",
       "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz",
@@ -6344,6 +6812,17 @@
         "react-is": "^16.8.1"
       }
     },
+    "proper-lockfile": {
+      "version": "3.2.0",
+      "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-3.2.0.tgz",
+      "integrity": "sha512-iMghHHXv2bsxl6NchhEaFck8tvX3F9cknEEh1SUpguUOBjN7PAAW9BLzmbc1g/mCD1gY3EE2EABBHPJfFdHFmA==",
+      "dev": true,
+      "requires": {
+        "graceful-fs": "^4.1.11",
+        "retry": "^0.12.0",
+        "signal-exit": "^3.0.2"
+      }
+    },
     "proto-list": {
       "version": "1.2.4",
       "resolved": "https://registry.npmjs.org/proto-list/-/proto-list-1.2.4.tgz",
@@ -7361,6 +7840,12 @@
       "resolved": "https://registry.npmjs.org/ret/-/ret-0.1.15.tgz",
       "integrity": "sha512-TTlYpa+OL+vMMNG24xSlQGEJ3B/RzEfUlLct7b5G/ytav+wPrplCpVMFuwzXbkecJrb6IYo1iFb0S9v37754mg=="
     },
+    "retry": {
+      "version": "0.12.0",
+      "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz",
+      "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=",
+      "dev": true
+    },
     "rimraf": {
       "version": "2.6.3",
       "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.6.3.tgz",
@@ -7409,6 +7894,13 @@
       "resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
       "integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g=="
     },
+    "safe-json-stringify": {
+      "version": "1.2.0",
+      "resolved": "https://registry.npmjs.org/safe-json-stringify/-/safe-json-stringify-1.2.0.tgz",
+      "integrity": "sha512-gH8eh2nZudPQO6TytOvbxnuhYBOvDBBLW52tz5q6X58lJcd/tkmqFR+5Z9adS8aJtURSXWThWy/xJtJwixErvg==",
+      "dev": true,
+      "optional": true
+    },
     "safe-regex": {
       "version": "1.1.0",
       "resolved": "https://registry.npmjs.org/safe-regex/-/safe-regex-1.1.0.tgz",
@@ -7708,6 +8200,15 @@
         }
       }
     },
+    "sanitize-filename": {
+      "version": "1.6.1",
+      "resolved": "https://registry.npmjs.org/sanitize-filename/-/sanitize-filename-1.6.1.tgz",
+      "integrity": "sha1-YS2hyWRz+gLczaktzVtKsWSmdyo=",
+      "dev": true,
+      "requires": {
+        "truncate-utf8-bytes": "^1.0.0"
+      }
+    },
     "sax": {
       "version": "1.1.6",
       "resolved": "https://registry.npmjs.org/sax/-/sax-1.1.6.tgz",
@@ -7853,6 +8354,15 @@
         "jsonify": "~0.0.0"
       }
     },
+    "shell-utils": {
+      "version": "1.0.10",
+      "resolved": "https://registry.npmjs.org/shell-utils/-/shell-utils-1.0.10.tgz",
+      "integrity": "sha512-p1xuqhj3jgcXiV8wGoF1eL/NOvapN9tyGDoObqKwvZTUZn7fIzK75swLTEHfGa7sObeN9vxFplHw/zgYUYRTsg==",
+      "dev": true,
+      "requires": {
+        "lodash": "4.x.x"
+      }
+    },
     "shellwords": {
       "version": "0.1.1",
       "resolved": "https://registry.npmjs.org/shellwords/-/shellwords-0.1.1.tgz",
@@ -8333,6 +8843,12 @@
         }
       }
     },
+    "tail": {
+      "version": "2.0.2",
+      "resolved": "https://registry.npmjs.org/tail/-/tail-2.0.2.tgz",
+      "integrity": "sha512-raFipiKWdGKEzxbvZwnhUGqjvsv0gpa/1A479rL//NOxnNwYZDN4MPk6xJJdUFs8P2Xrff3nbH5fcyYRLU4UHQ==",
+      "dev": true
+    },
     "tar": {
       "version": "4.4.10",
       "resolved": "https://registry.npmjs.org/tar/-/tar-4.4.10.tgz",
@@ -8361,6 +8877,15 @@
         "xtend": "^4.0.0"
       }
     },
+    "telnet-client": {
+      "version": "0.15.3",
+      "resolved": "https://registry.npmjs.org/telnet-client/-/telnet-client-0.15.3.tgz",
+      "integrity": "sha512-GSfdzQV0BKIYsmeXq7bJFJ2wHeJud6icaIxCUf6QCGQUD6R0BBGbT1+yLDhq67JRdgRpwyPwUbV7JxFeRrZomQ==",
+      "dev": true,
+      "requires": {
+        "bluebird": "3.5.x"
+      }
+    },
     "temp": {
       "version": "0.8.3",
       "resolved": "https://registry.npmjs.org/temp/-/temp-0.8.3.tgz",
@@ -8377,6 +8902,22 @@
         }
       }
     },
+    "temp-dir": {
+      "version": "1.0.0",
+      "resolved": "https://registry.npmjs.org/temp-dir/-/temp-dir-1.0.0.tgz",
+      "integrity": "sha1-CnwOom06Oa+n4OvqnB/AvE2qAR0=",
+      "dev": true
+    },
+    "tempfile": {
+      "version": "2.0.0",
+      "resolved": "https://registry.npmjs.org/tempfile/-/tempfile-2.0.0.tgz",
+      "integrity": "sha1-awRGhWqbERTRhW/8vlCczLCXcmU=",
+      "dev": true,
+      "requires": {
+        "temp-dir": "^1.0.0",
+        "uuid": "^3.0.1"
+      }
+    },
     "test-value": {
       "version": "2.1.0",
       "resolved": "https://registry.npmjs.org/test-value/-/test-value-2.1.0.tgz",
@@ -8601,6 +9142,15 @@
       "integrity": "sha512-fwkLWH+DimvA4YCy+/nvJd61nWQQ2liO/nF/RjkTpiOGi+zxZzVkhb1mvbHIIW4b/8nDsYI8uTmAlc0nNkRMOw==",
       "dev": true
     },
+    "truncate-utf8-bytes": {
+      "version": "1.0.2",
+      "resolved": "https://registry.npmjs.org/truncate-utf8-bytes/-/truncate-utf8-bytes-1.0.2.tgz",
+      "integrity": "sha1-QFkjkJWS1W94pYGENLC3hInKXys=",
+      "dev": true,
+      "requires": {
+        "utf8-byte-length": "^1.0.1"
+      }
+    },
     "tslib": {
       "version": "1.9.3",
       "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
@@ -8908,6 +9458,12 @@
       "resolved": "https://registry.npmjs.org/utf8/-/utf8-2.1.2.tgz",
       "integrity": "sha1-H6DZJw6b6FDZsFAn9jUZv0ZFfZY="
     },
+    "utf8-byte-length": {
+      "version": "1.0.4",
+      "resolved": "https://registry.npmjs.org/utf8-byte-length/-/utf8-byte-length-1.0.4.tgz",
+      "integrity": "sha1-9F8VDExm7uloGGUFq5P8u4rWv2E=",
+      "dev": true
+    },
     "util": {
       "version": "0.10.3",
       "resolved": "https://registry.npmjs.org/util/-/util-0.10.3.tgz",
diff --git a/package.json b/package.json
index f228d5d6716b43a99debaaa43616810cc52dc1e9..2194d0cec898c969afd4900654a75d03e6982450 100644
--- a/package.json
+++ b/package.json
@@ -54,6 +54,7 @@
     "babel-eslint": "^10.0.1",
     "basic-changelog": "gitlab:bloodyhealth/basic-changelog",
     "chai": "^4.1.2",
+    "detox": "^13.1.1",
     "dirty-chai": "^2.0.1",
     "eslint": "^5.16.0",
     "eslint-plugin-react": "^7.8.2",
@@ -88,5 +89,16 @@
     "assets": [
       "assets/fonts"
     ]
+  },
+  "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_28"
+      }
+    },
+    "test-runner": "mocha"
   }
 }