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" } }