Repository: wix/Detox
Pull request #2139 (2020-06-19 16:13:06)

fix(jest-circus): reinitialize custom logger on every Environment.setup
- [x] This is a small change 

---

**Description:**

Fixes a regression bug that has popped after DetoxCircusEnvironment rewrite.

Before the fix (regression):

![Screenshot from 2020-06-19 19-11-35](https://user-images.githubusercontent.com/1962469/85154907-be727c80-b260-11ea-9a17-88d60a40d3ff.png)

After the fix:

![Screenshot from 2020-06-19 19-11-11](https://user-images.githubusercontent.com/1962469/85154932-c7634e00-b260-11ea-9f24-74bfce5eda6f.png)


coveralls: ## Pull Request Test Coverage Report for [Build 2317](https://coveralls.io/builds/31565389)

* **60** of **66**   **(90.91%)**  changed or added relevant lines in **4** files are covered.
* **8** unchanged lines in **2** files lost coverage.
* Overall coverage decreased (**-0.01%**) to **62.846%**

---

|  Changes Missing Coverage | Covered Lines | Changed/Added Lines | % |
| :-----|--------------|--------|---: |
| [detox/src/utils/customConsoleLogger.js](https://coveralls.io/builds/31565389/source?filename=detox%2Fsrc%2Futils%2FcustomConsoleLogger.js#L21) | 38 | 39 | 97.44%
| [detox/src/utils/callsites.js](https://coveralls.io/builds/31565389/source?filename=detox%2Fsrc%2Futils%2Fcallsites.js#L6) | 12 | 17 | 70.59%
<!-- | **Total:** | **60** | **66** | **90.91%** | -->

|  Files with Coverage Reduction | New Missed Lines | % |
| :-----|--------------|--: |
| [detox/src/utils/callsites.js](https://coveralls.io/builds/31565389/source?filename=detox%2Fsrc%2Futils%2Fcallsites.js#L16) | 4 | 77.78% |
| [detox/src/utils/customConsoleLogger.js](https://coveralls.io/builds/31565389/source?filename=detox%2Fsrc%2Futils%2FcustomConsoleLogger.js#L23) | 4 | 82.29% |
<!-- | **Total:** | **8** |  | -->

|  Totals | [![Coverage Status](https://coveralls.io/builds/31565389/badge)](https://coveralls.io/builds/31565389) |
| :-- | --: |
| Change from base [Build 1236](https://coveralls.io/builds/31531137): |  -0.01% |
| Covered Lines: | 7879 |
| Relevant Lines: | 13062 |

---
##### 💛  - [Coveralls](https://coveralls.io)


Patch:
diff --git a/detox/runners/jest-circus/environment.js b/detox/runners/jest-circus/environment.js
index 90f079ac6..aa1473c3d 100644
--- a/detox/runners/jest-circus/environment.js
+++ b/detox/runners/jest-circus/environment.js
@@ -34,18 +34,15 @@ class DetoxCircusEnvironment extends NodeEnvironment {
     this.initTimeout = 300000;
   }
 
-  get detox() {
-    if (!this.global.detox) {
-      // NOTE: require() is deferred on purpose,
-      // to enable calculating line hit coverage
-      // while running internal E2E tests in Detox.
-      // Ideally, it can happen in setup() method.
-
-      this.global.detox = require('../../src')
-        ._setGlobal(this.global)
-        ._suppressLoggingInitErrors();
-    }
+  async setup() {
+    await super.setup();
 
+    this.global.detox = require('../../src')
+      ._setGlobal(this.global)
+      ._suppressLoggingInitErrors();
+  }
+
+  get detox() {
     return this.global.detox;
   }
 
diff --git a/detox/src/DetoxExportWrapper.js b/detox/src/DetoxExportWrapper.js
index 6c4fd30b1..066c58d74 100644
--- a/detox/src/DetoxExportWrapper.js
+++ b/detox/src/DetoxExportWrapper.js
@@ -3,7 +3,8 @@ const funpermaproxy = require('funpermaproxy');
 const Detox = require('./Detox');
 const DetoxConstants = require('./DetoxConstants');
 const configuration = require('./configuration');
-const log = require('./utils/logger').child({ __filename });
+const logger = require('./utils/logger');
+const log = logger.child({ __filename });
 
 const _detox = Symbol('detox');
 const _shouldLogInitError = Symbol('shouldLogInitError');
@@ -34,7 +35,7 @@ class DetoxExportWrapper {
   async init(configOverride, userParams) {
     let configError, exposeGlobals, resolvedConfig;
 
-    log.ensureLogFiles();
+    logger.reinitialize(Detox.global);
 
     try {
       resolvedConfig = await configuration.composeDetoxConfig({
diff --git a/detox/src/utils/__mocks__/logger.js b/detox/src/utils/__mocks__/logger.js
index 5278d2ddc..2555a5670 100644
--- a/detox/src/utils/__mocks__/logger.js
+++ b/detox/src/utils/__mocks__/logger.js
@@ -6,7 +6,7 @@ class FakeLogger {
   constructor(opts = {}) {
     this.opts = opts;
     this.log = jest.fn();
-    this.ensureLogFiles = jest.fn();
+    this.reinitialize = jest.fn();
 
     for (const method of METHODS) {
       this[method] = jest.fn().mockImplementation((...args) => {
diff --git a/detox/src/utils/callsites.js b/detox/src/utils/callsites.js
index 725854408..45b144755 100644
--- a/detox/src/utils/callsites.js
+++ b/detox/src/utils/callsites.js
@@ -3,18 +3,32 @@ const {escapeRegExp} = require('lodash');
 const cwd = process.cwd() + path.sep;
 
 // Taken from https://github.com/sindresorhus/callsites
-module.exports = () => {
+function getCallSites() {
   const _prepareStackTrace = Error.prepareStackTrace;
   Error.prepareStackTrace = (_, stack) => stack;
   const stack = new Error().stack.slice(1);
   Error.prepareStackTrace = _prepareStackTrace;
   return stack;
-};
+}
 
-module.exports.stackdump = (endFrame = 0) => {
+function getStackDump(endFrame = 0) {
   return new Error().stack
     .split('\n')
     .slice(2 + endFrame) // 2 = 1 for 'Error:' prefix and 1 for this function's frame
     .join('\n')
     .replace(new RegExp(escapeRegExp(cwd), 'g'), '');
+}
+
+function getOrigin(callSite) {
+  const callsiteFilename = callSite && callSite.getFileName();
+  const callsiteLine = callSite && callSite.getLineNumber();
+  const callsiteCol = callSite && callSite.getColumnNumber();
+  const filename = callsiteFilename ? path.relative(process.cwd(), callsiteFilename) : '<unknown>';
+  return `at ${filename}:${callsiteLine || '?'}:${callsiteCol || '?'}`;
+}
+
+module.exports = {
+  getCallSites,
+  getOrigin,
+  getStackDump,
 };
diff --git a/detox/src/utils/customConsoleLogger.js b/detox/src/utils/customConsoleLogger.js
index 4318716a3..e3ab4df49 100644
--- a/detox/src/utils/customConsoleLogger.js
+++ b/detox/src/utils/customConsoleLogger.js
@@ -1,56 +1,64 @@
 const util = require('util');
-const path = require('path');
 const callsites = require('./callsites');
 
 const USER_STACK_FRAME_INDEX = 2;
 
-function getStackDump() {
-  return callsites.stackdump(USER_STACK_FRAME_INDEX);
+function override(console, method, bunyanLoggerFn) {
+  if (method === 'trace') {
+    console.trace = proxyTracing(bunyanLoggerFn);
+  } else if (method === 'assert') {
+    console.assert = proxyAssert(bunyanLoggerFn);
+  } else {
+    console[method] = proxyLog(bunyanLoggerFn);
+  }
 }
 
 function getOrigin() {
-  const userCallsite = callsites()[USER_STACK_FRAME_INDEX];
-  const callsiteFilename = userCallsite && userCallsite.getFileName();
-  const callsiteLine = userCallsite && userCallsite.getLineNumber();
-  const callsiteCol = userCallsite && userCallsite.getColumnNumber();
-  const filename = callsiteFilename ? path.relative(process.cwd(), callsiteFilename) : '<unknown>';
-  return `at ${filename}:${callsiteLine || '?'}:${callsiteCol || '?'}`;
+  const userCallSite = callsites.getCallSites()[USER_STACK_FRAME_INDEX];
+  return callsites.getOrigin(userCallSite);
+}
+
+function getStackDump() {
+  return callsites.getStackDump(USER_STACK_FRAME_INDEX);
 }
 
-function override(consoleLevel, bunyanFn) {
-  console[consoleLevel] = (...args) => {
-    bunyanFn({ event: 'USER_LOG' }, getOrigin(), '\n', util.format(...args));
+function proxyLog(bunyanLoggerFn) {
+  return (...args) => {
+    bunyanLoggerFn({ event: 'USER_LOG' }, getOrigin(), '\n', util.format(...args));
   };
 }
 
-function overrideTrace(consoleLevel, bunyanFn) {
-  console[consoleLevel] = (...args) => {
-    bunyanFn({ event: 'USER_LOG' }, getOrigin(), '\n  Trace:', util.format(...args), '\n\r' + getStackDump());
+function proxyTracing(bunyanLoggerFn) {
+  return (...args) => {
+    bunyanLoggerFn({ event: 'USER_LOG' }, getOrigin(), '\n  Trace:', util.format(...args), '\n\r' + getStackDump());
   };
 }
 
-function overrideAssertion(consoleLevel, bunyanFn) {
-  console[consoleLevel] = (...args) => {
-    const [condition, ...message] = args;
+function proxyAssert(bunyanLoggerFn) {
+  return (condition, ...args) => {
     if (!condition) {
-      bunyanFn({ event: 'USER_LOG' }, getOrigin(), '\n  AssertionError:', util.format(...message));
+      bunyanLoggerFn({ event: 'USER_LOG' }, getOrigin(), '\n  AssertionError:', util.format(...args));
     }
   };
 }
 
-function overrideAllLevels(bunyanLogger) {
-  const log = bunyanLogger;
-  override('debug', log.debug.bind(log));
-  override('log', log.info.bind(log));
-  override('warn', log.warn.bind(log));
-  override('error', log.error.bind(log));
-  overrideTrace('trace', log.info.bind(log));
-  overrideAssertion('assert', log.error.bind(log));
+function overrideConsoleMethods(console, bunyanLogger) {
+  if (!console.__detox_log__) {
+    const log = bunyanLogger;
+
+    override(console, 'log', log.info.bind(log));
+    override(console, 'warn', log.warn.bind(log));
+    override(console, 'trace', log.info.bind(log));
+    override(console, 'error', log.error.bind(log));
+    override(console, 'debug', log.debug.bind(log));
+    override(console, 'assert', log.error.bind(log));
+
+    console.__detox_log__ = log;
+  }
+
+  return console;
 }
 
 module.exports = {
-  override,
-  overrideTrace,
-  overrideAssertion,
-  overrideAllLevels,
+  overrideConsoleMethods,
 };
diff --git a/detox/src/utils/logger.js b/detox/src/utils/logger.js
index bf12e79fa..1aa28b3ef 100644
--- a/detox/src/utils/logger.js
+++ b/detox/src/utils/logger.js
@@ -25,9 +25,11 @@ function adaptLogLevelName(level) {
   }
 }
 
-function overrideConsoleLogger(logger) {
-  const log = logger.child({component: 'USER_LOG'});
-  customConsoleLogger.overrideAllLevels(log);
+function tryOverrideConsole(logger, global) {
+  if (argparse.getArgValue('use-custom-logger') === 'true') {
+    const userLogger = logger.child({ component: 'USER_LOG' });
+    customConsoleLogger.overrideConsoleMethods(global.console, userLogger);
+  }
 }
 
 function createPlainBunyanStream({ logPath, level }) {
@@ -40,6 +42,10 @@ function createPlainBunyanStream({ logPath, level }) {
     out: process.stderr,
     prefixers: {
       '__filename': (filename, { entry }) => {
+        if (entry.event === 'USER_LOG') {
+          return '';
+        }
+
         const suffix = entry.event ? `/${entry.event}` : '';
         return path.basename(filename) + suffix;
       },
@@ -109,11 +115,9 @@ function init() {
     logger.plainFileStreamPath = plainFileStreamPath;
   }
 
-  if (argparse.getArgValue('use-custom-logger') === 'true') {
-    overrideConsoleLogger(logger);
-  }
+  tryOverrideConsole(logger, global);
 
-  Object.getPrototypeOf(logger).ensureLogFiles = () => {
+  logger.reinitialize = (global) => {
     if (jsonFileStreamPath) {
       fs.ensureFileSync(jsonFileStreamPath);
     }
@@ -121,6 +125,8 @@ function init() {
     if (plainFileStreamPath) {
       fs.ensureFileSync(plainFileStreamPath);
     }
+
+    tryOverrideConsole(logger, global);
   };
 
   return logger;


Test patch:
diff --git a/detox/src/utils/callsites.test.js b/detox/src/utils/callsites.test.js
index 58cd2dd91..3fa1d7fba 100644
--- a/detox/src/utils/callsites.test.js
+++ b/detox/src/utils/callsites.test.js
@@ -1,16 +1,15 @@
 const path = require('path');
 
 describe('callsites', () => {
-
   let callsites;
+
   beforeEach(() => {
     callsites = require('./callsites');
   });
 
-  describe('call-sites query', () => {
-    const callFromWrapperFn = () => callsites();
-
+  describe('.getCallSites()', () => {
     it('should return a query-able callsites array', function it() {
+      const callFromWrapperFn = () => callsites.getCallSites();
       const [callsite0, callsite1] = callFromWrapperFn();
 
       const expectedFileName = path.normalize('src/utils/callsites.test.js');
@@ -18,13 +17,14 @@ describe('callsites', () => {
       expect(callsite0.getFileName()).toEqual(expect.stringContaining(expectedFileName));
       expect(callsite0.getFunctionName()).toEqual('callFromWrapperFn');
       expect(callsite0.isToplevel()).toEqual(true);
+
       expect(callsite1.getFunctionName()).toEqual('it');
       expect(callsite1.isToplevel()).toEqual(false);
     });
   });
 
-  describe('stack-dump', () => {
-    const callStackDumpFromWrapperFn = (endFrame) => callsites.stackdump(endFrame);
+  describe('.getStackDump', () => {
+    const callStackDumpFromWrapperFn = (endFrame) => callsites.getStackDump(endFrame);
     const callStackDumpFromTwoWrapperFn = (endFrame) => callStackDumpFromWrapperFn(endFrame);
 
     const expectedTopFrameRegExp = /^ {4}at callStackDumpFromWrapperFn \(src[\\/]utils[\\/]callsites\.test\.js:[0-9][0-9]?:[0-9][0-9]?\)/;
@@ -43,4 +43,63 @@ describe('callsites', () => {
       expect(stackdump).toEqual(expect.stringMatching(_expectedTopLineRegExp));
     });
   });
+
+  describe('.getOrigin(callSite)', () => {
+    it('should include log origin', () => {
+      const fakeCallSite = {
+        getFileName: () => 'MOCK_FILE',
+        getLineNumber: () => 200,
+        getColumnNumber: () => 100,
+      };
+
+      const origin = callsites.getOrigin(fakeCallSite);
+      expect(origin).toBe('at MOCK_FILE:200:100');
+    });
+
+    it('should use relative file-name rather than absolute in origin', () => {
+      const fakeCallSite = {
+        getFileName: () => path.join(process.cwd(), 'src/index.js'),
+        getLineNumber: () => 1,
+        getColumnNumber: () => 1,
+      };
+
+      const origin = callsites.getOrigin(fakeCallSite);
+      expect(origin).toBe(`at ${path.normalize('src/index.js')}:1:1`);
+    });
+
+    it('should handle null callsite', () => {
+      const origin = callsites.getOrigin(null);
+      expect(origin).toBe('at <unknown>:?:?');
+    });
+
+    it('should handle null fileName', () => {
+      const origin = callsites.getOrigin({
+        getFileName: () => null,
+        getLineNumber: () => 42,
+        getColumnNumber: () => 42,
+      });
+
+      expect(origin).toBe('at <unknown>:42:42');
+    });
+
+    it('should handle null lineNumber', () => {
+      const origin = callsites.getOrigin({
+        getFileName: () => 'index.js',
+        getLineNumber: () => null,
+        getColumnNumber: () => 42,
+      });
+
+      expect(origin).toBe('at index.js:?:42');
+    });
+
+    it('should handle null columnNumber', () => {
+      const origin = callsites.getOrigin({
+        getFileName: () => 'index.js',
+        getLineNumber: () => 42,
+        getColumnNumber: () => null,
+      });
+
+      expect(origin).toBe('at index.js:42:?');
+    });
+  });
 });
diff --git a/detox/src/utils/customConsoleLogger.test.js b/detox/src/utils/customConsoleLogger.test.js
index 0da3a8862..d5fcd0215 100644
--- a/detox/src/utils/customConsoleLogger.test.js
+++ b/detox/src/utils/customConsoleLogger.test.js
@@ -1,159 +1,85 @@
-const path = require('path');
-const ignored = expect.anything;
+describe('customConsoleLogger.overrideConsoleMethods(console, bunyanLogger)', () => {
+  let overrideConsoleMethods;
+  let fakeConsole, bunyanLogger;
 
-describe('customConsoleLogger', () => {
-  let bunyanLogger;
+  const USER_LOG_EVENT = { event: 'USER_LOG' };
 
   beforeEach(() => {
-    jest.unmock('./callsites');
+    overrideConsoleMethods = require('./customConsoleLogger').overrideConsoleMethods;
 
-    bunyanLogger = {
-      mock: jest.fn(),
+    fakeConsole = {
+      log: jest.fn(),
+      warn: jest.fn(),
+      trace: jest.fn(),
+      error: jest.fn(),
+      debug: jest.fn(),
+      assert: jest.fn(),
     };
-  });
-
-  afterEach(() => {
-    delete console.__log;
-  });
-
-  it('should log an event as the prefix', () => {
-    const logger = require('./customConsoleLogger');
-    logger.override('__log', bunyanLogger.mock);
-    console.__log();
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith({ event: 'USER_LOG' }, ignored(), ignored(), ignored());
-  });
-
-  it('should log multiple args', () => {
-    const logger = require('./customConsoleLogger');
-    logger.override('__log', bunyanLogger.mock);
-    console.__log('Testing123');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith(ignored(), ignored(), ignored(), 'Testing123');
-  });
-
-  it('should support string formatting', () => {
-    const logger = require('./customConsoleLogger');
-    logger.override('__log', bunyanLogger.mock);
-    console.__log('Tada! this %s', 'worx');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith(ignored(), ignored(), ignored(), 'Tada! this worx');
-  });
-
-  it('should include log origin', () => {
-    mockCallsites({file: 'mockfilename', line: 'mocklinenumber', col: 'mockcolnumber'});
-
-    const expectedOrigin = 'mockfilename:mocklinenumber:mockcolnumber';
-
-    const logger = require('./customConsoleLogger');
-    logger.override('__log', bunyanLogger.mock);
-    console.__log('');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith(ignored(), expect.stringContaining(expectedOrigin), ignored(), ignored());
-  });
-
-  it('should use relative file-name rather than absolute in origin', () => {
-    const expectedOrigin = `at ${path.normalize('src/utils/customConsoleLogger.test.js')}:`;
-
-    const logger = require('./customConsoleLogger');
-    logger.override('__log', bunyanLogger.mock);
-    console.__log('');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith(ignored(), expect.stringContaining(expectedOrigin), ignored(), ignored());
-  });
 
-  it('should handle unknown file in origin', () => {
-    mockCallsites({file: undefined, line: undefined, col: undefined});
-
-    const logger = require('./customConsoleLogger');
-    logger.override('__log', bunyanLogger.mock);
-    console.__log('');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith(ignored(), expect.stringContaining('<unknown>:?:?'), ignored(), ignored());
-  });  
-  
-  it('should handle missing file line/column in origin', () => {
-    mockCallsites({file: 'mockfilename', line: undefined, col: undefined});
-
-    const logger = require('./customConsoleLogger');
-    logger.override('__log', bunyanLogger.mock);
-    console.__log('');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith(ignored(), expect.stringContaining('mockfilename:?:?'), ignored(), ignored());
-  });
-
-  it('should support assertion logging', () => {
-    const logger = require('./customConsoleLogger');
-    logger.overrideAssertion('__log', bunyanLogger.mock);
-    console.__log(false, 'Testing456');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith({ event: 'USER_LOG' }, ignored(), ignored(), 'Testing456');
-  });
-
-  it('should limit assertion logging to false-conditions', () => {
-    const logger = require('./customConsoleLogger');
-    logger.overrideAssertion('__log', bunyanLogger.mock);
-    console.__log(true, 'Testing456');
-
-    expect(bunyanLogger.mock).not.toHaveBeenCalled();
-  });
-
-  it('should support trace-logging', () => {
-    const logger = require('./customConsoleLogger');
-    logger.overrideTrace('__log', bunyanLogger.mock);
-    console.__log('Testing789');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith({ event: 'USER_LOG' }, ignored(), ignored(), 'Testing789', ignored());
-  });
-
-  it('should log stack-trace dump when trace-logging', () => {
-    mockCallsites();
-    const callsites = require('./callsites');
-    callsites.stackdump = jest.fn().mockReturnValue('mockstack\ntrace');
-
-    const logger = require('./customConsoleLogger');
-    logger.overrideTrace('__log', bunyanLogger.mock);
-    console.__log('');
-
-    expect(bunyanLogger.mock).toHaveBeenCalledWith(ignored(), ignored(), ignored(), ignored(), '\n\rmockstack\ntrace');
-  });
-
-  it('should override all levels', () => {
-    const bunyanLogger = {
+    bunyanLogger = {
       debug: jest.fn(),
-      info: jest.fn(),
       warn: jest.fn(),
+      info: jest.fn(),
       error: jest.fn(),
     };
+  });
 
-    const _console = console;
-
-    try {
-      global.console = {};
+  describe('- override safety -', () => {
+    it('should override console methods, if it has no internal property __detox_log__', () => {
+      expect(overrideConsoleMethods({ ...fakeConsole }, bunyanLogger)).not.toEqual(fakeConsole);
+    });
 
-      const logger = require('./customConsoleLogger');
-      logger.overrideAllLevels(bunyanLogger);
+    it('should not override console methods, if it has an internal property __detox_log__', () => {
+      fakeConsole.__detox_log__ = {};
+      expect(overrideConsoleMethods({ ...fakeConsole }, bunyanLogger)).toEqual(fakeConsole);
+    });
 
-      expect(console.debug).toEqual(expect.any(Function));
-      expect(console.log).toEqual(expect.any(Function));
-      expect(console.warn).toEqual(expect.any(Function));
-      expect(console.error).toEqual(expect.any(Function));
-      expect(console.trace).toEqual(expect.any(Function));
-      expect(console.assert).toEqual(expect.any(Function));
-    } finally {
-      global.console = _console;
-    }
+    it('should set an internal property __detox_log__ after override', () => {
+      expect(overrideConsoleMethods({ ...fakeConsole }, bunyanLogger).__detox_log__).toBeDefined();
+    });
   });
 
-  const mockCallsites = (callsite) => {
-    const mockCallsite = mockACallsite(callsite);
-    jest.mock('./callsites', () => jest.fn().mockReturnValue([{}, {}, mockCallsite]));
-  };
-
-  const mockACallsite = ({func, file, line, col} = {}) => ({
-    getFunctionName: jest.fn().mockReturnValue(func || ''),
-    getFileName: jest.fn().mockReturnValue(file || ''),
-    getLineNumber: jest.fn().mockReturnValue(line),
-    getColumnNumber: jest.fn().mockReturnValue(col),
+  describe('- proxying to bunyan -', () => {
+    const expectedOrigin = expect.stringMatching(/at src[\\\/]utils[\\\/]customConsoleLogger\.test\.js:\d+:\d+/);
+    const expectedStackDump = expect.stringMatching(/at.*src[\\\/]utils[\\\/]customConsoleLogger\.test\.js:\d+:\d+/m);
+
+    beforeEach(() => {
+      overrideConsoleMethods(fakeConsole, bunyanLogger);
+    });
+
+    it('should connect: console.log -> logger.info', () => {
+      fakeConsole.log('OK %d', 200);
+      expect(bunyanLogger.info).toHaveBeenCalledWith(USER_LOG_EVENT, expectedOrigin, '\n', 'OK 200');
+    });
+
+    it('should connect: console.warn -> logger.warn', () => {
+      fakeConsole.warn('Warning %d', 301);
+      expect(bunyanLogger.warn).toHaveBeenCalledWith(USER_LOG_EVENT, expectedOrigin, '\n', 'Warning 301');
+    });
+
+    it('should connect: console.trace -> logger.info', () => {
+      fakeConsole.trace('TraceMe %d', 100500);
+      expect(bunyanLogger.info).toHaveBeenCalledWith(USER_LOG_EVENT, expectedOrigin, '\n  Trace:', 'TraceMe 100500', expectedStackDump);
+    });
+
+    it('should connect: console.error -> logger.error', () => {
+      fakeConsole.error('MyError %d', 500);
+      expect(bunyanLogger.error).toHaveBeenCalledWith(USER_LOG_EVENT, expectedOrigin, '\n', 'MyError 500');
+    });
+
+    it('should connect: console.debug -> logger.debug', () => {
+      fakeConsole.debug('Debug %d', 0);
+      expect(bunyanLogger.debug).toHaveBeenCalledWith(USER_LOG_EVENT, expectedOrigin, '\n', 'Debug 0');
+    });
+
+    it('should connect: console.assert -> logger.error', () => {
+      fakeConsole.assert(false, 'Failed condition %s', false);
+      expect(bunyanLogger.error).toHaveBeenCalledWith(USER_LOG_EVENT, expectedOrigin, '\n  AssertionError:', 'Failed condition false');
+    });
+
+    it('should not connect console.assert to logger.error, if the condition is true', () => {
+      fakeConsole.assert(true, 'Nothing to say');
+      expect(bunyanLogger.error).not.toHaveBeenCalled();
+    });
   });
 });
diff --git a/detox/test/e2e/config.js b/detox/test/e2e/config.js
index b256c1fc5..a49946724 100644
--- a/detox/test/e2e/config.js
+++ b/detox/test/e2e/config.js
@@ -16,7 +16,6 @@ module.exports = {
     "!**/*.mock.js",
     "!**/*.test.js"
   ],
-  "coverageProvider": "v8",
   "coverageDirectory": "test/coverage",
   "coverageReporters": [["lcov", {"projectRoot": "../.." }], "html"]
 };