From d5d93cc918634eaa47c0317eb9c17009472634ea Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 11 Oct 2017 14:04:01 +0200 Subject: [PATCH 01/18] Add basic jest runner support --- detox/local-cli/detox-test.js | 3 +++ 1 file changed, 3 insertions(+) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index 11a38ece82..3aa6c80903 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -38,6 +38,9 @@ switch (program.runner) { case 'mocha': command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; break; + case 'jest': + command = `node_modules/.bin/${program.runner} ${testFolder}`; + break; default: throw new Error(`${program.runner} is not supported in detox cli tools. You can still run your tests with the runner's own cli tool`); } From ba08fba9491ce4a16e83e1b281a44cf1c5236cf0 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 11 Oct 2017 14:08:33 +0200 Subject: [PATCH 02/18] Adjust Jest documentation --- docs/Guide.Jest.md | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/docs/Guide.Jest.md b/docs/Guide.Jest.md index 7253f67225..c292099181 100644 --- a/docs/Guide.Jest.md +++ b/docs/Guide.Jest.md @@ -16,10 +16,9 @@ npm install --save-dev jest You should remove `e2e/mocha.opts`, you no longer need it. -### 3. Write a detox setup file +### 3. Replace generated detox setup file (e2e/init.js) ```js -// ./jest/setup/e2e.js const detox = require('detox'); const config = require('../package.json').detox; @@ -44,16 +43,14 @@ beforeEach(async () => { Add this part to your `package.json`: ```json "jest": { - "setupTestFrameworkScriptFile": "/jest/setup.js" + "setupTestFrameworkScriptFile": "./e2e/init.js" }, "scripts": { - "test:e2e": "jest __e2e__ --setupTestFrameworkScriptFile=./jest/setup/e2e-tests.js --runInBand", + "test:e2e": "detox test -r jest", "test:e2e:build": "detox build" } ``` -We need the `--runInBand` as detox doesn't support parallelism yet. - ### Writing Tests There are some things you should notice: From 8bf5abde5fcc2ff178244e4a411b1a72341c69a8 Mon Sep 17 00:00:00 2001 From: Alexey Date: Wed, 11 Oct 2017 14:24:45 +0200 Subject: [PATCH 03/18] Add missing --runInBand flag to jest command --- detox/local-cli/detox-test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index 3aa6c80903..1ae2059ee5 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -39,7 +39,7 @@ switch (program.runner) { command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; break; case 'jest': - command = `node_modules/.bin/${program.runner} ${testFolder}`; + command = `node_modules/.bin/${program.runner} ${testFolder} --runInBand`; break; default: throw new Error(`${program.runner} is not supported in detox cli tools. You can still run your tests with the runner's own cli tool`); From bcb0174cf7a1ae41b2f4b40ef65185e064dc134f Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 13 Oct 2017 14:33:08 +0200 Subject: [PATCH 04/18] Use process.env instead of process.argv (not supported in Jest) --- detox/local-cli/detox-test.js | 35 +++++++++++++++++++++-------------- detox/package.json | 7 +++---- detox/src/Detox.js | 4 ++-- detox/src/client/Client.js | 2 +- detox/src/utils/argparse.js | 5 +---- 5 files changed, 28 insertions(+), 25 deletions(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index 1ae2059ee5..3c23e54947 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -21,22 +21,19 @@ program const config = require(path.join(process.cwd(), 'package.json')).detox; const testFolder = config.specs || 'e2e'; -const loglevel = program.loglevel ? `--loglevel ${program.loglevel}` : ''; -const configuration = program.configuration ? `--configuration ${program.configuration}` : ''; -const cleanup = program.cleanup ? `--cleanup` : ''; -const reuse = program.reuse ? `--reuse` : ''; -const artifactsLocation = program.artifactsLocation ? `--artifacts-location ${program.artifactsLocation}` : ''; - -if (typeof program.debugSynchronization === "boolean") { - program.debugSynchronization = 3000; -} -let debugSynchronization = program.debugSynchronization ? `--debug-synchronization ${program.debugSynchronization}` : ''; - - let command; +const { + configuration, + loglevel, + cleanup, + reuse, + debugSynchronization, + artifactsLocation, +} = program; + switch (program.runner) { case 'mocha': - command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; + command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig}`; break; case 'jest': command = `node_modules/.bin/${program.runner} ${testFolder} --runInBand`; @@ -46,4 +43,14 @@ switch (program.runner) { } console.log(command); -cp.execSync(command, {stdio: 'inherit'}); +cp.execSync(command, { + stdio: 'inherit', + env: { + configuration, + loglevel, + cleanup, + reuse, + debugSynchronization, + artifactsLocation, + }, +}); diff --git a/detox/package.json b/detox/package.json index 22dd0b00c1..bc4bfcd534 100644 --- a/detox/package.json +++ b/detox/package.json @@ -42,7 +42,6 @@ "eslint-plugin-react": "^7.1.0", "eslint-plugin-react-native": "^2.3.2", "jest": "^20.0.4", - "minimist": "^1.2.0", "mockdate": "^2.0.1", "shelljs": "^0.7.3", "ttab": "^0.3.1" @@ -82,12 +81,12 @@ "GREYConfiguration.js", "src/ios/earlgreyapi", "src/utils/environment.js", - - + + "AAPT.js", "ADB.js", "fsext.js" - + ], "resetMocks": true, "resetModules": true, diff --git a/detox/src/Detox.js b/detox/src/Detox.js index 593de63683..8c06ebe1fa 100644 --- a/detox/src/Detox.js +++ b/detox/src/Detox.js @@ -32,7 +32,7 @@ class Detox { this.client = null; this.device = null; this._currentTestNumber = 0; - const artifactsLocation = argparse.getArgValue('artifacts-location'); + const artifactsLocation = argparse.getArgValue('artifactsLocation'); if(artifactsLocation !== undefined) { try { this._artifactsPathsProvider = new ArtifactsPathsProvider(artifactsLocation); @@ -130,7 +130,7 @@ class Detox { } if (!deviceConfig) { - throw new Error(`Cannot determine which configuration to use. use --configuration to choose one of the following: + throw new Error(`Cannot determine which configuration to use. use --configuration to choose one of the following: ${Object.keys(configurations)}`); } diff --git a/detox/src/client/Client.js b/detox/src/client/Client.js index 46da48f197..b59984a609 100644 --- a/detox/src/client/Client.js +++ b/detox/src/client/Client.js @@ -7,7 +7,7 @@ class Client { this.configuration = config; this.ws = new AsyncWebSocket(config.server); this.slowInvocationStatusHandler = null; - this.slowInvocationTimeout = argparse.getArgValue('debug-synchronization'); + this.slowInvocationTimeout = argparse.getArgValue('debugSynchronization'); this.successfulTestRun = true; // flag for cleanup } diff --git a/detox/src/utils/argparse.js b/detox/src/utils/argparse.js index 4196e77515..c5ad901290 100644 --- a/detox/src/utils/argparse.js +++ b/detox/src/utils/argparse.js @@ -1,8 +1,5 @@ -const argv = require('minimist')(process.argv.slice(2)); - function getArgValue(key) { - const value = argv ? argv[key] : undefined; - return value; + process.env[key]; } module.exports = { From efe3b39be74c2ad00545019edeb0b71cff383201 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 13 Oct 2017 16:05:37 +0200 Subject: [PATCH 05/18] Adjust tests to the new env approach --- detox/src/Detox.test.js | 47 +++++++++++++++----------------- detox/src/utils/argparse.js | 2 +- detox/src/utils/argparse.test.js | 6 ++-- 3 files changed, 25 insertions(+), 30 deletions(-) diff --git a/detox/src/Detox.test.js b/detox/src/Detox.test.js index ce8528d3dc..1d35fb3c00 100644 --- a/detox/src/Detox.test.js +++ b/detox/src/Detox.test.js @@ -4,17 +4,16 @@ describe('Detox', () => { let fs; let Detox; let detox; - let minimist; - let clientMockData = {lastConstructorArguments: null}; - let deviceMockData = {lastConstructorArguments: null}; + const clientMockData = {lastConstructorArguments: null}; + const deviceMockData = {lastConstructorArguments: null}; beforeEach(async () => { function setCustomMock(modulePath, dataObject) { const JestMock = jest.genMockFromModule(modulePath); class FinalMock extends JestMock { - constructor() { - super(...arguments); - dataObject.lastConstructorArguments = arguments; + constructor(...rest) { + super(rest); + dataObject.lastConstructorArguments = rest; } } jest.setMock(modulePath, FinalMock); @@ -23,12 +22,12 @@ describe('Detox', () => { jest.mock('npmlog'); jest.mock('fs'); fs = require('fs'); - jest.mock('minimist'); - minimist = require('minimist'); jest.mock('./ios/expect'); setCustomMock('./client/Client', clientMockData); setCustomMock('./devices/Device', deviceMockData); + process.env = {}; + jest.mock('./devices/IosDriver'); jest.mock('./devices/SimulatorDriver'); jest.mock('./devices/Device'); @@ -66,7 +65,7 @@ describe('Detox', () => { }); it(`Passing --cleanup should shutdown the currently running device`, async () => { - mockCommandLineArgs({cleanup: true}); + process.env.cleanup = true; Detox = require('./Detox'); detox = new Detox(schemes.validOneDeviceNoSession); @@ -99,7 +98,7 @@ describe('Detox', () => { }); it(`Two valid devices, detox should init with the device passed in '--configuration' cli option`, async () => { - mockCommandLineArgs({configuration: 'ios.sim.debug'}); + process.env.configuration = 'ios.sim.debug'; Detox = require('./Detox'); detox = new Detox(schemes.validTwoDevicesNoSession); @@ -108,7 +107,7 @@ describe('Detox', () => { }); it(`Two valid devices, detox should throw if device passed in '--configuration' cli option doesn't exist`, async () => { - mockCommandLineArgs({configuration: 'nonexistent'}); + process.env.configuration = 'nonexistent'; Detox = require('./Detox'); detox = new Detox(schemes.validTwoDevicesNoSession); @@ -121,7 +120,7 @@ describe('Detox', () => { }); it(`Two valid devices, detox should throw if device passed in '--configuration' cli option doesn't exist`, async () => { - mockCommandLineArgs({configuration: 'nonexistent'}); + process.env.configuration = 'nonexistent'; Detox = require('./Detox'); detox = new Detox(schemes.validTwoDevicesNoSession); @@ -165,22 +164,22 @@ describe('Detox', () => { }); it(`Detox should use session defined per configuration - none`, async () => { - mockCommandLineArgs({configuration: 'ios.sim.none'}); + process.env.configuration = 'ios.sim.none'; Detox = require('./Detox'); detox = new Detox(schemes.sessionPerConfiguration); await detox.init(); - let expectedSession = schemes.sessionPerConfiguration.configurations['ios.sim.none'].session; + const expectedSession = schemes.sessionPerConfiguration.configurations['ios.sim.none'].session; expect(clientMockData.lastConstructorArguments[0]).toBe(expectedSession); }); it(`Detox should use session defined per configuration - release`, async () => { - mockCommandLineArgs({configuration: 'ios.sim.release'}); + process.env.configuration = 'ios.sim.release'; Detox = require('./Detox'); detox = new Detox(schemes.sessionPerConfiguration); await detox.init(); - let expectedSession = schemes.sessionPerConfiguration.configurations['ios.sim.release'].session; + const expectedSession = schemes.sessionPerConfiguration.configurations['ios.sim.release'].session; expect(clientMockData.lastConstructorArguments[0]).toBe(expectedSession); }); @@ -189,12 +188,12 @@ describe('Detox', () => { detox = new Detox(schemes.sessionInCommonAndInConfiguration); await detox.init(); - let expectedSession = schemes.sessionInCommonAndInConfiguration.configurations['ios.sim.none'].session; + const expectedSession = schemes.sessionInCommonAndInConfiguration.configurations['ios.sim.none'].session; expect(clientMockData.lastConstructorArguments[0]).toBe(expectedSession); }); it(`beforeEach() - should set device artifacts destination`, async () => { - mockCommandLineArgs({'artifacts-location': '/tmp'}); + process.env.artifactsLocation = '/tmp'; Detox = require('./Detox'); detox = new Detox(schemes.validOneDeviceAndSession); await detox.init(); @@ -211,7 +210,7 @@ describe('Detox', () => { }); it(`afterEach() - should call device.finalizeArtifacts`, async () => { - mockCommandLineArgs({'artifacts-location': '/tmp'}); + process.env.artifactsLocation = '/tmp'; Detox = require('./Detox'); detox = new Detox(schemes.validOneDeviceAndSession); await detox.init(); @@ -228,13 +227,11 @@ describe('Detox', () => { }); it(`the constructor should catch exception from ArtifactsPathsProvider`, async () => { - mockCommandLineArgs({'artifacts-location': '/tmp'}); - fs.mkdirSync = jest.fn(() => {throw 'Could not create artifacts root dir'}); + process.env.artifactsLocation = '/tmp'; + fs.mkdirSync = jest.fn(() => { + throw Error('Could not create artifacts root dir'); + }); Detox = require('./Detox'); detox = new Detox(schemes.validOneDeviceAndSession); }); - - function mockCommandLineArgs(args) { - minimist.mockReturnValue(args); - } }); diff --git a/detox/src/utils/argparse.js b/detox/src/utils/argparse.js index c5ad901290..4769fd261d 100644 --- a/detox/src/utils/argparse.js +++ b/detox/src/utils/argparse.js @@ -1,5 +1,5 @@ function getArgValue(key) { - process.env[key]; + return process.env[key]; } module.exports = { diff --git a/detox/src/utils/argparse.test.js b/detox/src/utils/argparse.test.js index 32b9809e28..dbc242fdde 100644 --- a/detox/src/utils/argparse.test.js +++ b/detox/src/utils/argparse.test.js @@ -1,12 +1,10 @@ -const _ = require('lodash'); +jest.unmock('process'); describe('argparse', () => { let argparse; beforeEach(() => { - jest.mock('minimist'); - const minimist = require('minimist'); - minimist.mockReturnValue({test: 'a value'}); + process.env.test = 'a value'; argparse = require('./argparse'); }); From c3c0077f1b2179330e166235463ed974cb040f03 Mon Sep 17 00:00:00 2001 From: Alexey Date: Fri, 13 Oct 2017 16:30:39 +0200 Subject: [PATCH 06/18] Adjust indentation in package.json --- detox/test/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/detox/test/package.json b/detox/test/package.json index 019a91bc2c..4df2585f4d 100644 --- a/detox/test/package.json +++ b/detox/test/package.json @@ -51,9 +51,9 @@ "type": "android.emulator", "name": "Nexus_5X_API_24", "session": { - "server": "ws://localhost:8099", - "sessionId": "test" - } + "server": "ws://localhost:8099", + "sessionId": "test" + } }, "android.emu.release": { "binaryPath": "android/app/build/outputs/apk/app-release.apk", @@ -61,9 +61,9 @@ "type": "android.emulator", "name": "Nexus_5X_API_24", "session": { - "server": "ws://localhost:8099", - "sessionId": "test" - } + "server": "ws://localhost:8099", + "sessionId": "test" + } } } } From 92a1c49b88f0f0a9414f00f220874cb086a8a4e6 Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Sat, 14 Oct 2017 21:11:51 +0200 Subject: [PATCH 07/18] Add process.env to child process --- detox/local-cli/detox-test.js | 1 + 1 file changed, 1 insertion(+) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index 3c23e54947..f4e0726e33 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -46,6 +46,7 @@ console.log(command); cp.execSync(command, { stdio: 'inherit', env: { + ...process.env, configuration, loglevel, cleanup, From 14d69659201319199918e6cf14327ded76028459 Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Mon, 16 Oct 2017 00:32:51 +0200 Subject: [PATCH 08/18] Support runner option in detox config --- detox/local-cli/detox-test.js | 16 +++++++++++----- detox/test/e2e/mocha.opts | 4 ++-- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index f4e0726e33..c80d7db634 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -4,7 +4,7 @@ const program = require('commander'); const path = require('path'); const cp = require('child_process'); program - .option('-r, --runner [runner]', 'Test runner (currently supports mocha)', 'mocha') + .option('-r, --runner [runner]', 'Test runner (currently supports mocha)') .option('-o, --runner-config [config]', 'Test runner config file', 'mocha.opts') .option('-l, --loglevel [value]', 'info, debug, verbose, silly, wss') .option('-c, --configuration [device configuration]', 'Select a device configuration from your defined configurations,' @@ -21,6 +21,12 @@ program const config = require(path.join(process.cwd(), 'package.json')).detox; const testFolder = config.specs || 'e2e'; +let runner = config.runner || 'mocha'; + +if (program.runner) { + runner = program.runner; +} + let command; const { configuration, @@ -31,15 +37,15 @@ const { artifactsLocation, } = program; -switch (program.runner) { +switch (runner) { case 'mocha': - command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig}`; + command = `node_modules/.bin/${runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig}`; break; case 'jest': - command = `node_modules/.bin/${program.runner} ${testFolder} --runInBand`; + command = `node_modules/.bin/${runner} ${testFolder} --runInBand`; break; default: - throw new Error(`${program.runner} is not supported in detox cli tools. You can still run your tests with the runner's own cli tool`); + throw new Error(`${runner} is not supported in detox cli tools. You can still run your tests with the runner's own cli tool`); } console.log(command); diff --git a/detox/test/e2e/mocha.opts b/detox/test/e2e/mocha.opts index 4e8545b16a..d3fbb736f7 100644 --- a/detox/test/e2e/mocha.opts +++ b/detox/test/e2e/mocha.opts @@ -1,3 +1,3 @@ --recursive ---timeout 240000 ---bail \ No newline at end of file +--timeout 360000 +--bail From 256af2b61e2021338093c987535db345070a96d7 Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Mon, 16 Oct 2017 00:37:33 +0200 Subject: [PATCH 09/18] Update Guide.Jest to document a new way of changing runner --- docs/Guide.Jest.md | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/docs/Guide.Jest.md b/docs/Guide.Jest.md index c292099181..b1bc2fe3fe 100644 --- a/docs/Guide.Jest.md +++ b/docs/Guide.Jest.md @@ -46,11 +46,13 @@ Add this part to your `package.json`: "setupTestFrameworkScriptFile": "./e2e/init.js" }, "scripts": { - "test:e2e": "detox test -r jest", + "test:e2e": "detox test", "test:e2e:build": "detox build" } ``` +In the `detox` part of your `package.json`, add `"runner": "jest"` to tell detox that you want to use jest runner instead of mocha. + ### Writing Tests There are some things you should notice: From afcfc0e930a4a91b34e0cccac85beef92f2a510e Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Mon, 16 Oct 2017 00:54:38 +0200 Subject: [PATCH 10/18] Revert mocha.opts change (not a part of the scope) --- detox/test/e2e/mocha.opts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detox/test/e2e/mocha.opts b/detox/test/e2e/mocha.opts index d3fbb736f7..4e8545b16a 100644 --- a/detox/test/e2e/mocha.opts +++ b/detox/test/e2e/mocha.opts @@ -1,3 +1,3 @@ --recursive ---timeout 360000 ---bail +--timeout 240000 +--bail \ No newline at end of file From 8fde4233fee59d6f57223d2bd7a7fd38781489a6 Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Mon, 16 Oct 2017 00:56:22 +0200 Subject: [PATCH 11/18] Revert formatting changes (not a part of the scope) --- detox/test/package.json | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/detox/test/package.json b/detox/test/package.json index 4df2585f4d..019a91bc2c 100644 --- a/detox/test/package.json +++ b/detox/test/package.json @@ -51,9 +51,9 @@ "type": "android.emulator", "name": "Nexus_5X_API_24", "session": { - "server": "ws://localhost:8099", - "sessionId": "test" - } + "server": "ws://localhost:8099", + "sessionId": "test" + } }, "android.emu.release": { "binaryPath": "android/app/build/outputs/apk/app-release.apk", @@ -61,9 +61,9 @@ "type": "android.emulator", "name": "Nexus_5X_API_24", "session": { - "server": "ws://localhost:8099", - "sessionId": "test" - } + "server": "ws://localhost:8099", + "sessionId": "test" + } } } } From 8c9dc3b5b5f8d47a1ddd464e69c056f10962a640 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 16 Oct 2017 16:11:55 +0200 Subject: [PATCH 12/18] Use alternative flow to handle env variables --- detox/local-cli/detox-test.js | 47 ++++++++++++++++++-------------- detox/package.json | 1 + detox/src/utils/argparse.js | 4 ++- detox/src/utils/argparse.test.js | 39 ++++++++++++++++++++------ 4 files changed, 61 insertions(+), 30 deletions(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index c80d7db634..b54dc0bcc3 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -34,30 +34,37 @@ const { cleanup, reuse, debugSynchronization, - artifactsLocation, + artifactsLocation } = program; switch (runner) { case 'mocha': - command = `node_modules/.bin/${runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig}`; - break; - case 'jest': - command = `node_modules/.bin/${runner} ${testFolder} --runInBand`; + const loglevel = program.loglevel ? `--loglevel ${program.loglevel}` : ''; +let runner = config.runner || 'mocha'; + const configuration = program.configuration ? `--configuration ${program.configuration}` : ''; + const cleanup = program.cleanup ? `--cleanup` : ''; + const reuse = program.reuse ? `--reuse` : ''; + const artifactsLocation = program.artifactsLocation ? `--artifacts-location ${program.artifactsLocation}` : ''; + command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; + + console.log(command); + cp.execSync(command, { stdio: 'inherit' }); break; - default: + case 'jest': + command = `node_modules/.bin/${runner} ${testFolder} --runInBand`; + console.log(command); + cp.execSync(command, { + stdio: 'inherit', + env: { + ...process.env, + configuration, + loglevel, + cleanup, + reuse, + debugSynchronization, + artifactsLocation + } + }); + break; + default: throw new Error(`${runner} is not supported in detox cli tools. You can still run your tests with the runner's own cli tool`); } - -console.log(command); -cp.execSync(command, { - stdio: 'inherit', - env: { - ...process.env, - configuration, - loglevel, - cleanup, - reuse, - debugSynchronization, - artifactsLocation, - }, -}); diff --git a/detox/package.json b/detox/package.json index 5c99264f91..b45b1f04e0 100644 --- a/detox/package.json +++ b/detox/package.json @@ -42,6 +42,7 @@ "eslint-plugin-react": "^7.1.0", "eslint-plugin-react-native": "^2.3.2", "jest": "^20.0.4", + "minimist": "^1.2.0", "mockdate": "^2.0.1", "shelljs": "^0.7.3", "ttab": "^0.3.1" diff --git a/detox/src/utils/argparse.js b/detox/src/utils/argparse.js index 4769fd261d..3e9273abdf 100644 --- a/detox/src/utils/argparse.js +++ b/detox/src/utils/argparse.js @@ -1,5 +1,7 @@ +const argv = require('minimist')(process.argv.slice(2)); + function getArgValue(key) { - return process.env[key]; + return (argv && argv[key]) ? argv[key] : process.env[key]; } module.exports = { diff --git a/detox/src/utils/argparse.test.js b/detox/src/utils/argparse.test.js index dbc242fdde..2e99244b9a 100644 --- a/detox/src/utils/argparse.test.js +++ b/detox/src/utils/argparse.test.js @@ -1,18 +1,39 @@ jest.unmock('process'); describe('argparse', () => { - let argparse; + describe('using env variables', () => { + let argparse; - beforeEach(() => { - process.env.test = 'a value'; - argparse = require('./argparse'); - }); + beforeEach(() => { + process.env.test = 'a value'; + argparse = require('./argparse'); + }); + + it(`nonexistent key should return undefined result`, () => { + expect(argparse.getArgValue('blah')).not.toBeDefined(); + }); - it(`nonexistent key should return undefined result`, () => { - expect(argparse.getArgValue('blah')).not.toBeDefined(); + it(`existing key should return a result`, () => { + expect(argparse.getArgValue('test')).toBe('a value'); + }); }); - it(`existing key should return a result`, () => { - expect(argparse.getArgValue('test')).toBe('a value'); + describe('using arguments', () => { + let argparse; + + beforeEach(() => { + jest.mock('minimist'); + const minimist = require('minimist'); + minimist.mockReturnValue({test: 'a value'}); + argparse = require('./argparse'); + }); + + it(`nonexistent key should return undefined result`, () => { + expect(argparse.getArgValue('blah')).not.toBeDefined(); + }); + + it(`existing key should return a result`, () => { + expect(argparse.getArgValue('test')).toBe('a value'); + }); }); }); From 8092625ff011cd5b82344f63ad0a89e4af9e9336 Mon Sep 17 00:00:00 2001 From: Alexey Date: Mon, 16 Oct 2017 16:53:27 +0200 Subject: [PATCH 13/18] Support argv and priorotize them over env vars --- detox/src/Detox.js | 7 +++---- detox/src/client/Client.js | 2 +- detox/src/utils/argparse.js | 11 ++++++++++- detox/src/utils/argparse.test.js | 8 ++++---- 4 files changed, 18 insertions(+), 10 deletions(-) diff --git a/detox/src/Detox.js b/detox/src/Detox.js index 8c06ebe1fa..89d383edf6 100644 --- a/detox/src/Detox.js +++ b/detox/src/Detox.js @@ -22,7 +22,6 @@ const DEVICE_CLASSES = { }; class Detox { - constructor(userConfig) { if (!userConfig) { throw new Error(`No configuration was passed to detox, make sure you pass a config when calling 'detox.init(config)'`); @@ -32,11 +31,11 @@ class Detox { this.client = null; this.device = null; this._currentTestNumber = 0; - const artifactsLocation = argparse.getArgValue('artifactsLocation'); - if(artifactsLocation !== undefined) { + const artifactsLocation = argparse.getArgValue('artifacts-location'); + if (artifactsLocation !== undefined) { try { this._artifactsPathsProvider = new ArtifactsPathsProvider(artifactsLocation); - } catch(ex) { + } catch (ex) { log.warn(ex); } } diff --git a/detox/src/client/Client.js b/detox/src/client/Client.js index b59984a609..46da48f197 100644 --- a/detox/src/client/Client.js +++ b/detox/src/client/Client.js @@ -7,7 +7,7 @@ class Client { this.configuration = config; this.ws = new AsyncWebSocket(config.server); this.slowInvocationStatusHandler = null; - this.slowInvocationTimeout = argparse.getArgValue('debugSynchronization'); + this.slowInvocationTimeout = argparse.getArgValue('debug-synchronization'); this.successfulTestRun = true; // flag for cleanup } diff --git a/detox/src/utils/argparse.js b/detox/src/utils/argparse.js index 3e9273abdf..a2f1408d51 100644 --- a/detox/src/utils/argparse.js +++ b/detox/src/utils/argparse.js @@ -1,7 +1,16 @@ const argv = require('minimist')(process.argv.slice(2)); function getArgValue(key) { - return (argv && argv[key]) ? argv[key] : process.env[key]; + let value; + + if (argv && argv[key]) { + value = argv[key]; + } else { + const camelCasedKey = key.replace(/(\-\w)/g, (m) => m[1].toUpperCase()); + value = process.env[camelCasedKey]; + } + + return value; } module.exports = { diff --git a/detox/src/utils/argparse.test.js b/detox/src/utils/argparse.test.js index 2e99244b9a..b230418279 100644 --- a/detox/src/utils/argparse.test.js +++ b/detox/src/utils/argparse.test.js @@ -5,7 +5,7 @@ describe('argparse', () => { let argparse; beforeEach(() => { - process.env.test = 'a value'; + process.env.fooBar = 'a value'; argparse = require('./argparse'); }); @@ -14,7 +14,7 @@ describe('argparse', () => { }); it(`existing key should return a result`, () => { - expect(argparse.getArgValue('test')).toBe('a value'); + expect(argparse.getArgValue('foo-bar')).toBe('a value'); }); }); @@ -24,7 +24,7 @@ describe('argparse', () => { beforeEach(() => { jest.mock('minimist'); const minimist = require('minimist'); - minimist.mockReturnValue({test: 'a value'}); + minimist.mockReturnValue({'kebab-case-key': 'a value'}); argparse = require('./argparse'); }); @@ -33,7 +33,7 @@ describe('argparse', () => { }); it(`existing key should return a result`, () => { - expect(argparse.getArgValue('test')).toBe('a value'); + expect(argparse.getArgValue('kebab-case-key')).toBe('a value'); }); }); }); From dc45bc24936981e982c62d72fe8f151866f31c7f Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Tue, 17 Oct 2017 00:06:23 +0200 Subject: [PATCH 14/18] Cleanup detox-test.js --- detox/local-cli/detox-test.js | 68 +++++++++---------- .../ios/example.xcodeproj/project.pbxproj | 8 +-- 2 files changed, 37 insertions(+), 39 deletions(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index b54dc0bcc3..8b8bad77ea 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -27,44 +27,42 @@ if (program.runner) { runner = program.runner; } -let command; -const { - configuration, - loglevel, - cleanup, - reuse, - debugSynchronization, - artifactsLocation -} = program; +function runMocha() { + const loglevel = program.loglevel ? `--loglevel ${program.loglevel}` : ''; + const configuration = program.configuration ? `--configuration ${program.configuration}` : ''; + const cleanup = program.cleanup ? `--cleanup` : ''; + const reuse = program.reuse ? `--reuse` : ''; + const artifactsLocation = program.artifactsLocation ? `--artifacts-location ${program.artifactsLocation}` : ''; + const command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; + + console.log(command); + cp.execSync(command, {stdio: 'inherit'}); +} + +function runJest() { + const command = `node_modules/.bin/${runner} ${testFolder} --runInBand`; + console.log(command); + cp.execSync(command, { + stdio: 'inherit', + env: { + ...process.env, + configuration: program.configuration, + loglevel: program.loglevel, + cleanup: program.cleanup, + reuse: program.reuse, + debugSynchronization: program.debugSynchronization, + artifactsLocation: program.artifactsLocation + } + }); +} switch (runner) { case 'mocha': - const loglevel = program.loglevel ? `--loglevel ${program.loglevel}` : ''; +let runner = config.runner || 'mocha'; - const configuration = program.configuration ? `--configuration ${program.configuration}` : ''; - const cleanup = program.cleanup ? `--cleanup` : ''; - const reuse = program.reuse ? `--reuse` : ''; - const artifactsLocation = program.artifactsLocation ? `--artifacts-location ${program.artifactsLocation}` : ''; - command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; - - console.log(command); - cp.execSync(command, { stdio: 'inherit' }); + runMocha(); + break; + case 'jest': + runJest(); break; - case 'jest': - command = `node_modules/.bin/${runner} ${testFolder} --runInBand`; - console.log(command); - cp.execSync(command, { - stdio: 'inherit', - env: { - ...process.env, - configuration, - loglevel, - cleanup, - reuse, - debugSynchronization, - artifactsLocation - } - }); - break; - default: + default: throw new Error(`${runner} is not supported in detox cli tools. You can still run your tests with the runner's own cli tool`); } diff --git a/detox/test/ios/example.xcodeproj/project.pbxproj b/detox/test/ios/example.xcodeproj/project.pbxproj index 358fcfdc95..7149129e5f 100644 --- a/detox/test/ios/example.xcodeproj/project.pbxproj +++ b/detox/test/ios/example.xcodeproj/project.pbxproj @@ -975,7 +975,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEAD_CODE_STRIPPING = NO; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = J966JLDEF9; INFOPLIST_FILE = example/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -992,7 +992,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = J966JLDEF9; INFOPLIST_FILE = example/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1010,7 +1010,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEAD_CODE_STRIPPING = NO; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = J966JLDEF9; INFOPLIST_FILE = "$(SRCROOT)/example/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1027,7 +1027,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = ""; + DEVELOPMENT_TEAM = J966JLDEF9; INFOPLIST_FILE = "$(SRCROOT)/example/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; From 63b45194a3bfb305467b79f47e537a3d92e6e148 Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Tue, 17 Oct 2017 01:15:55 +0200 Subject: [PATCH 15/18] Setup debug-synchronization value --- detox/local-cli/detox-test.js | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index 8b8bad77ea..c54c9f663b 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -33,6 +33,12 @@ function runMocha() { const cleanup = program.cleanup ? `--cleanup` : ''; const reuse = program.reuse ? `--reuse` : ''; const artifactsLocation = program.artifactsLocation ? `--artifacts-location ${program.artifactsLocation}` : ''; + + if (typeof program.debugSynchronization === "boolean") { + program.debugSynchronization = 3000; + } + + const debugSynchronization = program.debugSynchronization ? `--debug-synchronization ${program.debugSynchronization}` : ''; const command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; console.log(command); @@ -50,7 +56,7 @@ function runJest() { loglevel: program.loglevel, cleanup: program.cleanup, reuse: program.reuse, - debugSynchronization: program.debugSynchronization, + debugSynchronization: program.debugSynchronization ? 3000 : '', artifactsLocation: program.artifactsLocation } }); From 35e0f6574ddc6a73ba20cf033e1df6cc6ad758fe Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Tue, 17 Oct 2017 02:04:20 +0200 Subject: [PATCH 16/18] Fix runner problem --- detox/local-cli/detox-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index c54c9f663b..441fac9777 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -39,14 +39,14 @@ function runMocha() { } const debugSynchronization = program.debugSynchronization ? `--debug-synchronization ${program.debugSynchronization}` : ''; - const command = `node_modules/.bin/${program.runner} ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; + const command = `node_modules/.bin/mocha ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; console.log(command); cp.execSync(command, {stdio: 'inherit'}); } function runJest() { - const command = `node_modules/.bin/${runner} ${testFolder} --runInBand`; + const command = `node_modules/.bin/jest ${testFolder} --runInBand`; console.log(command); cp.execSync(command, { stdio: 'inherit', From 3803b473d1464cc12cf2e756e6989abc32f948c3 Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Tue, 17 Oct 2017 02:39:06 +0200 Subject: [PATCH 17/18] Reset example.xcodeproj --- detox/test/ios/example.xcodeproj/project.pbxproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/detox/test/ios/example.xcodeproj/project.pbxproj b/detox/test/ios/example.xcodeproj/project.pbxproj index 7149129e5f..358fcfdc95 100644 --- a/detox/test/ios/example.xcodeproj/project.pbxproj +++ b/detox/test/ios/example.xcodeproj/project.pbxproj @@ -975,7 +975,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEAD_CODE_STRIPPING = NO; - DEVELOPMENT_TEAM = J966JLDEF9; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = example/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -992,7 +992,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = J966JLDEF9; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = example/Info.plist; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1010,7 +1010,7 @@ buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; DEAD_CODE_STRIPPING = NO; - DEVELOPMENT_TEAM = J966JLDEF9; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/example/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; @@ -1027,7 +1027,7 @@ isa = XCBuildConfiguration; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; - DEVELOPMENT_TEAM = J966JLDEF9; + DEVELOPMENT_TEAM = ""; INFOPLIST_FILE = "$(SRCROOT)/example/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; LD_RUNPATH_SEARCH_PATHS = "$(inherited) @executable_path/Frameworks"; From 5fcfa4a66baf83c33070ee9595fb21994e036de2 Mon Sep 17 00:00:00 2001 From: Alexey Kureev Date: Tue, 17 Oct 2017 20:30:20 +0200 Subject: [PATCH 18/18] Remove constant override --- detox/local-cli/detox-test.js | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/detox/local-cli/detox-test.js b/detox/local-cli/detox-test.js index 441fac9777..164f31b0b9 100644 --- a/detox/local-cli/detox-test.js +++ b/detox/local-cli/detox-test.js @@ -34,10 +34,6 @@ function runMocha() { const reuse = program.reuse ? `--reuse` : ''; const artifactsLocation = program.artifactsLocation ? `--artifacts-location ${program.artifactsLocation}` : ''; - if (typeof program.debugSynchronization === "boolean") { - program.debugSynchronization = 3000; - } - const debugSynchronization = program.debugSynchronization ? `--debug-synchronization ${program.debugSynchronization}` : ''; const command = `node_modules/.bin/mocha ${testFolder} --opts ${testFolder}/${program.runnerConfig} ${configuration} ${loglevel} ${cleanup} ${reuse} ${debugSynchronization} ${artifactsLocation}`; @@ -56,12 +52,16 @@ function runJest() { loglevel: program.loglevel, cleanup: program.cleanup, reuse: program.reuse, - debugSynchronization: program.debugSynchronization ? 3000 : '', + debugSynchronization: program.debugSynchronization, artifactsLocation: program.artifactsLocation } }); } +if (typeof program.debugSynchronization === "boolean") { + program.debugSynchronization = 3000; +} + switch (runner) { case 'mocha': runMocha();