From e3a6e85ad8150b76cd361e724329ee62cecc8611 Mon Sep 17 00:00:00 2001 From: Yaroslav Serhieiev Date: Fri, 1 Apr 2022 09:59:59 +0300 Subject: [PATCH] feat: drop old Jest integrations BREAKING CHANGE: please upgrade to jest-circus https://wix.github.io/Detox/docs/guide/jest/ --- detox/local-cli/templates/jest.js | 3 +- detox/runners/jest-circus/index.js | 9 +-- .../listeners/DetoxCoreListener.js | 2 +- .../listeners/SpecReporter.js} | 55 +++++++++++-- .../listeners/WorkerAssignReporter.js | 33 ++++++++ detox/runners/jest-circus/reporter.js | 1 + .../jest-circus/reporters/DetoxReporter.js | 16 ++++ .../reporters}/DetoxStreamlineJestReporter.js | 7 +- .../reporters}/FailingTestsReporter.js | 2 +- .../utils/getFullTestName.js | 0 .../utils/hasTimedOut.js | 0 .../{jest => jest-circus}/utils/index.js | 0 .../{jest => jest-circus}/utils/stdout.js | 0 detox/runners/jest/DetoxAdapterCircus.js | 60 -------------- detox/runners/jest/DetoxAdapterImpl.js | 81 ------------------- detox/runners/jest/DetoxAdapterJasmine.js | 67 --------------- detox/runners/jest/JestCircusEnvironment.js | 37 +-------- detox/runners/jest/SpecReporterCircus.js | 51 ------------ detox/runners/jest/SpecReporterJasmine.js | 39 --------- .../jest/WorkerAssignReporterCircus.js | 17 ---- .../runners/jest/WorkerAssignReporterImpl.js | 21 ----- .../jest/WorkerAssignReporterJasmine.js | 15 ---- detox/runners/jest/adapter.js | 7 +- detox/runners/jest/assignReporter.js | 7 +- detox/runners/jest/deprecation.js | 46 +++++++++++ detox/runners/jest/runnerInfo.js | 9 --- detox/runners/jest/specReporter.js | 11 +-- detox/runners/jest/streamlineReporter.js | 23 +----- .../{jest-circus => }/config.js | 2 +- .../{jest-circus => }/environment.js | 12 +-- .../detox-init-timeout/jest-jasmine/config.js | 16 ---- .../detox-init-timeout/jest-jasmine/init.js | 44 ---------- detox/test/e2e/config-jasmine.js | 7 -- detox/test/e2e/environment.js | 12 +-- detox/test/e2e/init-jasmine.js | 40 --------- detox/test/scripts/ci_unhappy.sh | 10 +-- examples/demo-plugin/e2e/config.json | 9 ++- examples/demo-plugin/e2e/environment.js | 23 ++++++ examples/demo-plugin/e2e/init.js | 30 ------- 39 files changed, 204 insertions(+), 620 deletions(-) rename detox/runners/{jest/SpecReporterImpl.js => jest-circus/listeners/SpecReporter.js} (60%) create mode 100644 detox/runners/jest-circus/listeners/WorkerAssignReporter.js create mode 100644 detox/runners/jest-circus/reporter.js create mode 100644 detox/runners/jest-circus/reporters/DetoxReporter.js rename detox/runners/{jest => jest-circus/reporters}/DetoxStreamlineJestReporter.js (94%) rename detox/runners/{jest => jest-circus/reporters}/FailingTestsReporter.js (83%) rename detox/runners/{jest => jest-circus}/utils/getFullTestName.js (100%) rename detox/runners/{jest => jest-circus}/utils/hasTimedOut.js (100%) rename detox/runners/{jest => jest-circus}/utils/index.js (100%) rename detox/runners/{jest => jest-circus}/utils/stdout.js (100%) delete mode 100644 detox/runners/jest/DetoxAdapterCircus.js delete mode 100644 detox/runners/jest/DetoxAdapterImpl.js delete mode 100644 detox/runners/jest/DetoxAdapterJasmine.js delete mode 100644 detox/runners/jest/SpecReporterCircus.js delete mode 100644 detox/runners/jest/SpecReporterJasmine.js delete mode 100644 detox/runners/jest/WorkerAssignReporterCircus.js delete mode 100644 detox/runners/jest/WorkerAssignReporterImpl.js delete mode 100644 detox/runners/jest/WorkerAssignReporterJasmine.js create mode 100644 detox/runners/jest/deprecation.js delete mode 100644 detox/runners/jest/runnerInfo.js rename detox/test/e2e-unhappy/detox-init-timeout/{jest-circus => }/config.js (90%) rename detox/test/e2e-unhappy/detox-init-timeout/{jest-circus => }/environment.js (72%) delete mode 100644 detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/config.js delete mode 100644 detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/init.js delete mode 100644 detox/test/e2e/config-jasmine.js delete mode 100644 detox/test/e2e/init-jasmine.js create mode 100644 examples/demo-plugin/e2e/environment.js delete mode 100644 examples/demo-plugin/e2e/init.js diff --git a/detox/local-cli/templates/jest.js b/detox/local-cli/templates/jest.js index a777340ffc..56e833865f 100644 --- a/detox/local-cli/templates/jest.js +++ b/detox/local-cli/templates/jest.js @@ -3,10 +3,9 @@ const firstTestContent = require('./firstTestContent'); const runnerConfig = `{ "maxWorkers": 1, "testEnvironment": "./environment", - "testRunner": "jest-circus/runner", "testTimeout": 120000, "testRegex": "\\\\.e2e\\\\.js$", - "reporters": ["detox/runners/jest/streamlineReporter"], + "reporters": ["detox/runners/jest-circus/reporter"], "verbose": true } `; diff --git a/detox/runners/jest-circus/index.js b/detox/runners/jest-circus/index.js index 75a956bccf..950cce91e0 100644 --- a/detox/runners/jest-circus/index.js +++ b/detox/runners/jest-circus/index.js @@ -1,10 +1,9 @@ -const SpecReporterCircus = require('../jest/SpecReporterCircus'); -const WorkerAssignReporterCircus = require('../jest/WorkerAssignReporterCircus'); - const DetoxCircusEnvironment = require('./environment'); +const SpecReporter = require('./listeners/SpecReporter'); +const WorkerAssignReporter = require('./listeners/WorkerAssignReporter'); module.exports = { DetoxCircusEnvironment, - SpecReporter: SpecReporterCircus, - WorkerAssignReporter: WorkerAssignReporterCircus, + SpecReporter, + WorkerAssignReporter, }; diff --git a/detox/runners/jest-circus/listeners/DetoxCoreListener.js b/detox/runners/jest-circus/listeners/DetoxCoreListener.js index 1c860189fe..06be005930 100644 --- a/detox/runners/jest-circus/listeners/DetoxCoreListener.js +++ b/detox/runners/jest-circus/listeners/DetoxCoreListener.js @@ -9,7 +9,7 @@ const { onTestDone, onRunDescribeFinish, } = require('../../integration').lifecycle; -const { getFullTestName, hasTimedOut } = require('../../jest/utils'); +const { getFullTestName, hasTimedOut } = require('../utils'); const RETRY_TIMES = Symbol.for('RETRY_TIMES'); diff --git a/detox/runners/jest/SpecReporterImpl.js b/detox/runners/jest-circus/listeners/SpecReporter.js similarity index 60% rename from detox/runners/jest/SpecReporterImpl.js rename to detox/runners/jest-circus/listeners/SpecReporter.js index fb4d99f99f..47cb75f89a 100644 --- a/detox/runners/jest/SpecReporterImpl.js +++ b/detox/runners/jest-circus/listeners/SpecReporter.js @@ -1,8 +1,7 @@ const chalk = require('chalk').default; -const log = require('../../src/utils/logger').child(); - -const { traceln } = require('./utils/stdout'); +const log = require('../../../src/utils/logger').child(); +const { traceln } = require('../utils/stdout'); const RESULT_SKIPPED = chalk.yellow('SKIPPED'); const RESULT_FAILED = chalk.red('FAIL'); @@ -16,12 +15,50 @@ class SpecReporter { this._suitesDesc = ''; } - onSuiteStart({ description }) { + run_describe_start(event) { + if (event.describeBlock.parent !== undefined) { + this._onSuiteStart({ + description: event.describeBlock.name, + }); + } + } + + run_describe_finish(event) { + if (event.describeBlock.parent !== undefined) { + this._onSuiteEnd(); + } + } + + test_start(event) { + const { test } = event; + this._onTestStart({ + description: test.name, + invocations: test.invocations, + }); + } + + test_done(event) { + const { test } = event; + const testInfo = { + description: test.name, + invocations: test.invocations, + }; + this._onTestEnd(testInfo, test.errors.length ? 'failed' : 'success'); + } + + test_skip(event) { + const testInfo = { + description: event.test.name, + }; + this._onTestEnd(testInfo, 'skipped'); + } + + _onSuiteStart({ description }) { this._suites.push({ description }); this._regenerateSuitesDesc(); } - onSuiteEnd() { + _onSuiteEnd() { this._suites.pop(); this._regenerateSuitesDesc(); @@ -30,11 +67,11 @@ class SpecReporter { } } - onTestStart({ description, invocations = 1 }) { + _onTestStart({ description, invocations = 1 }) { this._traceTest({ description, invocations }); } - onTestEnd({ description, invocations = 1 }, result) { + _onTestEnd({ description, invocations = 1 }, result) { let status; switch (result) { case 'skipped': status = RESULT_SKIPPED; break; @@ -68,4 +105,6 @@ class SpecReporter { } } -module.exports = SpecReporter; +module.exports = process.env.DETOX_REPORT_SPECS === 'true' + ? SpecReporter + : class {}; diff --git a/detox/runners/jest-circus/listeners/WorkerAssignReporter.js b/detox/runners/jest-circus/listeners/WorkerAssignReporter.js new file mode 100644 index 0000000000..ea6eda746a --- /dev/null +++ b/detox/runners/jest-circus/listeners/WorkerAssignReporter.js @@ -0,0 +1,33 @@ +const path = require('path'); + +const chalk = require('chalk').default; +const _ = require('lodash'); + +const log = require('../../../src/utils/logger').child(); + +class WorkerAssignReporter { + constructor({ detox, env }) { + this._detox = detox; + this._env = env; + } + + run_start() { + log.info({ event: 'WORKER_ASSIGN' }, `${this._formatTestName()} is assigned to ${this._formatDeviceName()}`); + } + + _formatDeviceName() { + const deviceName = _.attempt(() => this._detox.device.name); + const formattedDeviceName = _.isError(deviceName) + ? chalk.redBright('undefined') + : chalk.blueBright(deviceName); + + return formattedDeviceName; + } + + _formatTestName() { + const testName = path.basename(this._env.testPath); + return chalk.whiteBright(testName); + } +} + +module.exports = WorkerAssignReporter; diff --git a/detox/runners/jest-circus/reporter.js b/detox/runners/jest-circus/reporter.js new file mode 100644 index 0000000000..a6f87d9914 --- /dev/null +++ b/detox/runners/jest-circus/reporter.js @@ -0,0 +1 @@ +module.exports = require('./reporters/DetoxReporter'); diff --git a/detox/runners/jest-circus/reporters/DetoxReporter.js b/detox/runners/jest-circus/reporters/DetoxReporter.js new file mode 100644 index 0000000000..2e7de9c12f --- /dev/null +++ b/detox/runners/jest-circus/reporters/DetoxReporter.js @@ -0,0 +1,16 @@ +const DetoxStreamlineJestReporter = require('./DetoxStreamlineJestReporter'); +const FailingTestsReporter = require('./FailingTestsReporter'); + +class DetoxReporter extends DetoxStreamlineJestReporter { + constructor(globalConfig) { + super(globalConfig); + this._failingTestsReporter = new FailingTestsReporter(); + } + + async onRunComplete(contexts, results) { + await super.onRunComplete(contexts, results); + await this._failingTestsReporter.onRunComplete(contexts, results); + } +} + +module.exports = DetoxReporter; diff --git a/detox/runners/jest/DetoxStreamlineJestReporter.js b/detox/runners/jest-circus/reporters/DetoxStreamlineJestReporter.js similarity index 94% rename from detox/runners/jest/DetoxStreamlineJestReporter.js rename to detox/runners/jest-circus/reporters/DetoxStreamlineJestReporter.js index ee83b2e763..e31f22da69 100644 --- a/detox/runners/jest/DetoxStreamlineJestReporter.js +++ b/detox/runners/jest-circus/reporters/DetoxStreamlineJestReporter.js @@ -1,7 +1,6 @@ -// @ts-nocheck const { VerboseReporter: JestVerboseReporter } = require('@jest/reporters'); // eslint-disable-line node/no-extraneous-require -const DetoxRuntimeError = require('../../src/errors/DetoxRuntimeError'); +const DetoxRuntimeError = require('../../../src/errors/DetoxRuntimeError'); class DetoxStreamlineJestReporter extends JestVerboseReporter { @@ -30,7 +29,7 @@ class DetoxStreamlineJestReporter extends JestVerboseReporter { * * 1. Jest suite-level lifecycle logging, typically done by the super-class' impl. * Note: Jest does not notify spec-level events to reporters. - * 2. Jasmine real-time, spec-level lifecycle logging. + * 2. Jest Circus real-time, spec-level lifecycle logging. * 3. User in-test logging (e.g. for debugging). * * It's easy to see that this cannot be done while stderr and stdout are not of equal priority. @@ -67,7 +66,7 @@ class DetoxStreamlineJestReporter extends JestVerboseReporter { _assertConfig() { if (!this._isVerboseEnabled()) { // Non-verbose mode makes Jest swizzle 'console' with a buffered output impl, which prevents - // user and detox' jasmine-lifecycle logs from showing in real time. + // from showing logs (from the user and Detox) in real time. throw new DetoxRuntimeError({ message: 'Cannot run properly unless Jest is in verbose mode', hint: 'See https://jestjs.io/docs/en/configuration#verbose-boolean for more details', diff --git a/detox/runners/jest/FailingTestsReporter.js b/detox/runners/jest-circus/reporters/FailingTestsReporter.js similarity index 83% rename from detox/runners/jest/FailingTestsReporter.js rename to detox/runners/jest-circus/reporters/FailingTestsReporter.js index 2b286fc8b3..ff840dd022 100644 --- a/detox/runners/jest/FailingTestsReporter.js +++ b/detox/runners/jest-circus/reporters/FailingTestsReporter.js @@ -1,6 +1,6 @@ const path = require('path'); -const { saveLastFailedTests } = require('../../src/utils/lastFailedTests'); +const { saveLastFailedTests } = require('../../../src/utils/lastFailedTests'); class FailingTestsReporter { async onRunComplete(_contexts, { testResults }) { diff --git a/detox/runners/jest/utils/getFullTestName.js b/detox/runners/jest-circus/utils/getFullTestName.js similarity index 100% rename from detox/runners/jest/utils/getFullTestName.js rename to detox/runners/jest-circus/utils/getFullTestName.js diff --git a/detox/runners/jest/utils/hasTimedOut.js b/detox/runners/jest-circus/utils/hasTimedOut.js similarity index 100% rename from detox/runners/jest/utils/hasTimedOut.js rename to detox/runners/jest-circus/utils/hasTimedOut.js diff --git a/detox/runners/jest/utils/index.js b/detox/runners/jest-circus/utils/index.js similarity index 100% rename from detox/runners/jest/utils/index.js rename to detox/runners/jest-circus/utils/index.js diff --git a/detox/runners/jest/utils/stdout.js b/detox/runners/jest-circus/utils/stdout.js similarity index 100% rename from detox/runners/jest/utils/stdout.js rename to detox/runners/jest-circus/utils/stdout.js diff --git a/detox/runners/jest/DetoxAdapterCircus.js b/detox/runners/jest/DetoxAdapterCircus.js deleted file mode 100644 index afe016226e..0000000000 --- a/detox/runners/jest/DetoxAdapterCircus.js +++ /dev/null @@ -1,60 +0,0 @@ -const DetoxAdapter = require('./DetoxAdapterImpl'); -const { getFullTestName, hasTimedOut } = require('./utils'); - -class DetoxAdapterCircus { - constructor(detox) { - this._adapter = new DetoxAdapter(detox, DetoxAdapterCircus._describeInitError); - } - - static _describeInitError() { - return { - message: 'Detox adapter to Jest is malfunctioning.', - hint: `Make sure you register it as a test-event listener inside init.js:\n` + - `-------------------------------------------------------------\n` + - 'detoxCircus.getEnv().addEventsListener(adapter);', - }; - } - - async beforeEach() { - await this._adapter.beforeEach(); - } - - async afterAll() { - await this._adapter.afterAll(); - } - - async run_describe_start({ describeBlock: { name, children } }, state) { // eslint-disable-line no-unused-vars - if (children.length) await this._adapter.suiteStart({ name }); - } - - async run_describe_finish({ describeBlock: { name, children } }, state) { // eslint-disable-line no-unused-vars - if (children.length) await this._adapter.suiteEnd({ name }); - } - - test_start(event) { - const { test } = event; - if (test.mode === 'skip' || test.mode === 'todo' || test.errors.length > 0) { - return; - } - - this._adapter.testStart({ - title: test.name, - fullName: getFullTestName(test), - status: 'running', - }); - } - - test_done(event) { - const { test } = event; - this._adapter.testComplete({ - status: test.errors.length ? 'failed' : 'passed', - timedOut: hasTimedOut(test) - }); - } - - test_skip(event) { // eslint-disable-line no-unused-vars - // Ignored (for clarity) - } -} - -module.exports = DetoxAdapterCircus; diff --git a/detox/runners/jest/DetoxAdapterImpl.js b/detox/runners/jest/DetoxAdapterImpl.js deleted file mode 100644 index a8cc1dc8a5..0000000000 --- a/detox/runners/jest/DetoxAdapterImpl.js +++ /dev/null @@ -1,81 +0,0 @@ -const DetoxRuntimeError = require('../../src/errors/DetoxRuntimeError'); -const log = require('../../src/utils/logger').child({ __filename }); - -class DetoxAdapterImpl { - constructor(detox, describeInitErrorFn) { - if (process.env.DETOX_RERUN_INDEX) { - log.warn( - 'While Detox CLI supports "-R , --retries " mechanism, ' + - 'this outdated Jest integration does not — expect artifacts issues. ' + - 'Please migrate to the new Jest Circus integration.\n\n' + - 'See: https://wix.github.io/Detox/docs/api/guide/jest\n'); - } - - this.detox = detox; - this._describeInitError = describeInitErrorFn; - this._currentTest = null; - this._todos = []; - } - - async beforeEach() { - if (!this._currentTest) { - throw new DetoxRuntimeError(this._describeInitError()); - } - - const currentTest = this._currentTest; - - await this._flush(); - await this.detox.beforeEach(currentTest); - } - - async afterAll() { - await this._flush(); - } - - async suiteStart({ name }) { - this._enqueue(() => this.detox.suiteStart({ name })); - } - - async suiteEnd({ name }) { - this._enqueue(() => this.detox.suiteEnd({ name })); - } - - testStart({ title, fullName, status }) { - this._currentTest = { - title, - fullName, - status, - }; - } - - testComplete({ status, timedOut }) { - if (this._currentTest) { - const _test = { - ...this._currentTest, - status, - timedOut, - }; - - this._currentTest = null; - this._enqueue(() => this._afterEach(_test)); - } - } - - async _afterEach(previousTest) { - await this.detox.afterEach(previousTest); - } - - _enqueue(fn) { - this._todos.push(fn); - } - - async _flush() { - const t = this._todos; - - while (t.length > 0) { - await Promise.resolve().then(t.shift()).catch(()=>{}); - } - } -} - -module.exports = DetoxAdapterImpl; diff --git a/detox/runners/jest/DetoxAdapterJasmine.js b/detox/runners/jest/DetoxAdapterJasmine.js deleted file mode 100644 index a4f09572ed..0000000000 --- a/detox/runners/jest/DetoxAdapterJasmine.js +++ /dev/null @@ -1,67 +0,0 @@ -const _ = require('lodash'); - -const DetoxAdapter = require('./DetoxAdapterImpl'); - -class DetoxAdapterJasmine /* extends JasmineReporter */ { - constructor(detox) { - this._adapter = new DetoxAdapter(detox, DetoxAdapterJasmine._describeInitError); - } - - static _describeInitError() { - return { - message: 'Detox adapter to Jest is malfunctioning.', - hint: `Make sure you register it as Jasmine reporter inside init.js:\n` + - `-------------------------------------------------------------\n` + - 'jasmine.getEnv().addReporter(adapter);', - }; - } - - async beforeEach() { - await this._adapter.beforeEach(); - } - - async afterAll() { - await this._adapter.afterAll(); - } - - async suiteStarted(result) { - await this._adapter.suiteStart({ name: result.description }); - } - - async suiteDone(result) { - await this._adapter.suiteEnd({ name: result.description }); - } - - specStarted(result) { - if (result.pendingReason) { - return; - } - - this._adapter.testStart({ - title: result.description, - fullName: result.fullName, - status: 'running', - }); - } - - specDone(result) { - if (result.status === 'disabled' || result.pendingReason) { - return; - } - - this._adapter.testComplete({ - status: result.status, - timedOut: this._hasTimedOut(result), - }); - } - - _hasTimedOut(result) { - return _.chain(result.failedExpectations) - .map('error') - .compact() - .some(e => _.includes(e.message, 'Timeout')) - .value(); - } -} - -module.exports = DetoxAdapterJasmine; diff --git a/detox/runners/jest/JestCircusEnvironment.js b/detox/runners/jest/JestCircusEnvironment.js index 273236b53a..aac212fbb6 100644 --- a/detox/runners/jest/JestCircusEnvironment.js +++ b/detox/runners/jest/JestCircusEnvironment.js @@ -1,36 +1 @@ -const NodeEnvironment = require('jest-environment-node'); - -/** - * @see https://www.npmjs.com/package/jest-circus#overview - */ -class JestCircusEnvironment extends NodeEnvironment { - constructor(config) { - super(config); - this.testEventListeners = []; - - // Enable access to this instance (single in each worker's scope) by exposing a get-function. - // Note: whatever's set into this.global will be exported in that way. The reason behind it is that - // each suite is run inside a sandboxed JS context which scope is in fact this specific instance. See - // NodeEnvironment's constructor for more info, or https://jestjs.io/docs/en/configuration#testenvironment-string - // for additional ref. - this.global.detoxCircus = { - getEnv: () => this, - }; - } - - addEventsListener(listener) { - this.testEventListeners.push(listener); - } - - async handleTestEvent(event, state) { - const name = event.name; - - for (const listener of this.testEventListeners) { - if (typeof listener[name] === 'function') { - await listener[name](event, state); - } - } - } -} - -module.exports = JestCircusEnvironment; +require('./deprecation'); diff --git a/detox/runners/jest/SpecReporterCircus.js b/detox/runners/jest/SpecReporterCircus.js deleted file mode 100644 index fe01ae21f4..0000000000 --- a/detox/runners/jest/SpecReporterCircus.js +++ /dev/null @@ -1,51 +0,0 @@ -const argparse = require('../../src/utils/argparse'); - -const SpecReporter = require('./SpecReporterImpl'); - -class SpecReporterCircus { - constructor() { - this._specReporter = new SpecReporter(); - } - - run_describe_start(event) { - if (event.describeBlock.parent !== undefined) { - this._specReporter.onSuiteStart({ - description: event.describeBlock.name, - }); - } - } - - run_describe_finish(event) { - if (event.describeBlock.parent !== undefined) { - this._specReporter.onSuiteEnd(); - } - } - - test_start(event) { - const { test } = event; - this._specReporter.onTestStart({ - description: test.name, - invocations: test.invocations, - }); - } - - test_done(event) { - const { test } = event; - const testInfo = { - description: test.name, - invocations: test.invocations, - }; - this._specReporter.onTestEnd(testInfo, test.errors.length ? 'failed' : 'success'); - } - - test_skip(event) { - const testInfo = { - description: event.test.name, - }; - this._specReporter.onTestEnd(testInfo, 'skipped'); - } -} - -module.exports = argparse.getArgValue('reportSpecs') === 'true' - ? SpecReporterCircus - : class {}; diff --git a/detox/runners/jest/SpecReporterJasmine.js b/detox/runners/jest/SpecReporterJasmine.js deleted file mode 100644 index dfbae93526..0000000000 --- a/detox/runners/jest/SpecReporterJasmine.js +++ /dev/null @@ -1,39 +0,0 @@ -const SpecReporter = require('./SpecReporterImpl'); - -/*** - * @see {@link https://jasmine.github.io/api/2.9/Reporter.html} - */ -class SpecReporterJasmine { - constructor() { - this._specReporter = new SpecReporter(); - } - - suiteStarted(suiteInfo) { - this._specReporter.onSuiteStart(suiteInfo); - } - - suiteDone() { - this._specReporter.onSuiteEnd(); - } - - specStarted(specInfo) { - this._specReporter.onTestStart(specInfo); - } - - specDone(specResult) { - let result; - if (specResult.status === 'disabled') { - result = 'skipped'; - } else if (specResult.status === 'failed') { - result = 'failed'; - } else if (specResult.pendingReason) { - result = 'pending'; - } else { - result = 'success'; - } - - this._specReporter.onTestEnd(specResult, result); - } -} - -module.exports = SpecReporterJasmine; diff --git a/detox/runners/jest/WorkerAssignReporterCircus.js b/detox/runners/jest/WorkerAssignReporterCircus.js deleted file mode 100644 index 6385ea51a6..0000000000 --- a/detox/runners/jest/WorkerAssignReporterCircus.js +++ /dev/null @@ -1,17 +0,0 @@ -const WorkerAssignReporter = require('./WorkerAssignReporterImpl'); - -class WorkerAssignReporterCircus { - constructor({ detox }) { - this._reporter = new WorkerAssignReporter(detox); - } - - run_describe_start(event) { - const { describeBlock } = event; - - if (describeBlock.parent && describeBlock.parent.parent === undefined) { - this._reporter.report(describeBlock.name); - } - } -} - -module.exports = WorkerAssignReporterCircus; diff --git a/detox/runners/jest/WorkerAssignReporterImpl.js b/detox/runners/jest/WorkerAssignReporterImpl.js deleted file mode 100644 index ea7757878e..0000000000 --- a/detox/runners/jest/WorkerAssignReporterImpl.js +++ /dev/null @@ -1,21 +0,0 @@ -const chalk = require('chalk').default; -const _ = require('lodash'); - -const log = require('../../src/utils/logger').child(); - -class WorkerAssignReporterImpl { - constructor(detox) { - this.device = detox && detox.device; - } - - report(workerName) { - const deviceName = _.attempt(() => this.device.name); - const formattedDeviceName = _.isError(deviceName) - ? chalk.redBright('undefined') - : chalk.blueBright(deviceName); - - log.info({ event: 'WORKER_ASSIGN' }, `${chalk.whiteBright(workerName)} is assigned to ${formattedDeviceName}`); - } -} - -module.exports = WorkerAssignReporterImpl; diff --git a/detox/runners/jest/WorkerAssignReporterJasmine.js b/detox/runners/jest/WorkerAssignReporterJasmine.js deleted file mode 100644 index d5b5591dfe..0000000000 --- a/detox/runners/jest/WorkerAssignReporterJasmine.js +++ /dev/null @@ -1,15 +0,0 @@ -const path = require('path'); - -const WorkerAssignReporter = require('./WorkerAssignReporterImpl'); - -class WorkerAssignReporterJasmine { - constructor({ detox }) { - this._reporter = new WorkerAssignReporter(detox); - } - - suiteStarted(suiteInfo) { - const workerName = path.basename(suiteInfo.testPath); - this._reporter.report(workerName); - } -} -module.exports = WorkerAssignReporterJasmine; diff --git a/detox/runners/jest/adapter.js b/detox/runners/jest/adapter.js index 4d9b4f124a..aac212fbb6 100644 --- a/detox/runners/jest/adapter.js +++ b/detox/runners/jest/adapter.js @@ -1,6 +1 @@ -const detox = require('../../src/index'); - -const runnerInfo = require('./runnerInfo'); -const DetoxAdapter = runnerInfo.isJestCircus ? require('./DetoxAdapterCircus') : require('./DetoxAdapterJasmine'); - -module.exports = new DetoxAdapter(detox); +require('./deprecation'); diff --git a/detox/runners/jest/assignReporter.js b/detox/runners/jest/assignReporter.js index 55bf48dc1d..aac212fbb6 100644 --- a/detox/runners/jest/assignReporter.js +++ b/detox/runners/jest/assignReporter.js @@ -1,6 +1 @@ -const detox = require('../../src/index'); - -const runnerInfo = require('./runnerInfo'); - -const Reporter = runnerInfo.isJestCircus ? require('./WorkerAssignReporterCircus') : require('./WorkerAssignReporterJasmine'); -module.exports = new Reporter({ detox }); +require('./deprecation'); diff --git a/detox/runners/jest/deprecation.js b/detox/runners/jest/deprecation.js new file mode 100644 index 0000000000..cb88e418f4 --- /dev/null +++ b/detox/runners/jest/deprecation.js @@ -0,0 +1,46 @@ +const chalk = require('chalk'); + +console.error(chalk.yellow(` +========================= THE NEW JOURNEY BEGINS ============================= + + https://github.com/wix/Detox/blob/master/docs/Guide.Jest.md + + _.-;-._ Sorry, traveler from the lands of Detox 19! + ;_.JL___; + F"-/\\_-7L Detox 20 comes without old adapters for Jest. + | a/ e | \\ You have to rearrange your init code before + ,L,c;,.='/;, you can continue your journey. + _,-;;S:;:S;;:' '--._ + ;. \\;;s:::s;;: .' /\\ Navigate to the link above and follow the + / \\ ;::::;; / / \\ migration guide steps. + / , k ;S';;'S.' j __,l + ,---/| / /S /S '. |' ; Sincerely yours, + ,Ljjj |/|.' s .' s \\ L | Detox team. + LL,_ ]( \\ / '. '.|| ; + ||\\ > / ;-.'_.-.___\\.-'(|=="( + JJ," / |_ [ ] _]| / + LL\\/ ,' '--'-'-----' \\ ( + || ; | | > + JJ | |\\ |,/ + LL | || ' | + || | || . | + JJ /_ || ;_| + LL L "==='|i======='_| + || i----' '-------'; + JJ ';-----.------,-' + LL L_.__J,'---;' + || | ,| ( + JJ .'= (| ,_| + LL / .'L_ \\ +snd || '---' '.___> +Credit: "Gimli" by Shanaka Dias + + https://github.com/wix/Detox/blob/master/docs/Guide.Jest.md + +========================= THE NEW JOURNEY BEGINS ============================= + +`)); + +throw Object.assign(new Error( + '\n\nPlease follow the new Jest setup guide:\nhttps://github.com/wix/Detox/blob/master/docs/Guide.Jest.md\n\n' +), { stack: '' }); diff --git a/detox/runners/jest/runnerInfo.js b/detox/runners/jest/runnerInfo.js deleted file mode 100644 index 5cefb427b8..0000000000 --- a/detox/runners/jest/runnerInfo.js +++ /dev/null @@ -1,9 +0,0 @@ -// @ts-nocheck -const isJasmine = !!global.jasmine; -const isJestCircus = !!global.detoxCircus; - -module.exports = { - type: isJestCircus ? 'jest-circus' : 'jasmine', - isJasmine, - isJestCircus, -}; diff --git a/detox/runners/jest/specReporter.js b/detox/runners/jest/specReporter.js index ff98306b98..aac212fbb6 100644 --- a/detox/runners/jest/specReporter.js +++ b/detox/runners/jest/specReporter.js @@ -1,10 +1 @@ -const argparse = require('../../src/utils/argparse'); - -const runnerInfo = require('./runnerInfo'); - -if (argparse.getArgValue('reportSpecs') === 'true') { - const Reporter = runnerInfo.isJestCircus ? require('./SpecReporterCircus') : require('./SpecReporterJasmine'); - module.exports = new Reporter(); -} else { - module.exports = {}; -} +require('./deprecation'); diff --git a/detox/runners/jest/streamlineReporter.js b/detox/runners/jest/streamlineReporter.js index cd334eee58..196e6cc370 100644 --- a/detox/runners/jest/streamlineReporter.js +++ b/detox/runners/jest/streamlineReporter.js @@ -1,22 +1 @@ -// @ts-nocheck -/* - * This is here to make it easier for users to apply this reporter in config.json (naming-wise) - * TODO: rename this file to reporter.js in the next major version (Detox 18) - */ - -const DetoxStreamlineJestReporter = require('./DetoxStreamlineJestReporter'); -const FailingTestsReporter = require('./FailingTestsReporter'); - -class DetoxReporter extends DetoxStreamlineJestReporter { - constructor(globalConfig) { - super(globalConfig); - this._failingTestsReporter = new FailingTestsReporter(); - } - - async onRunComplete(contexts, results) { - await super.onRunComplete(contexts, results); - await this._failingTestsReporter.onRunComplete(contexts, results); - } -} - -module.exports = DetoxReporter; +module.exports = require('../jest-circus/reporter'); diff --git a/detox/test/e2e-unhappy/detox-init-timeout/jest-circus/config.js b/detox/test/e2e-unhappy/detox-init-timeout/config.js similarity index 90% rename from detox/test/e2e-unhappy/detox-init-timeout/jest-circus/config.js rename to detox/test/e2e-unhappy/detox-init-timeout/config.js index c36dca7874..56a1ded2f2 100644 --- a/detox/test/e2e-unhappy/detox-init-timeout/jest-circus/config.js +++ b/detox/test/e2e-unhappy/detox-init-timeout/config.js @@ -1,6 +1,6 @@ const path = require('path').posix; -const rootDir = '../../../..'; +const rootDir = '../../..'; const dirname = './' + path.relative(path.join(__dirname, rootDir), __dirname); module.exports = { diff --git a/detox/test/e2e-unhappy/detox-init-timeout/jest-circus/environment.js b/detox/test/e2e-unhappy/detox-init-timeout/environment.js similarity index 72% rename from detox/test/e2e-unhappy/detox-init-timeout/jest-circus/environment.js rename to detox/test/e2e-unhappy/detox-init-timeout/environment.js index 3658837a55..71a9d9ee8a 100644 --- a/detox/test/e2e-unhappy/detox-init-timeout/jest-circus/environment.js +++ b/detox/test/e2e-unhappy/detox-init-timeout/environment.js @@ -1,6 +1,8 @@ -const WorkerAssignReporterCircus = require('detox/runners/jest/WorkerAssignReporterCircus'); -const SpecReporterCircus = require('detox/runners/jest/SpecReporterCircus'); -const DetoxCircusEnvironment = require('detox/runners/jest-circus/environment'); +const { + DetoxCircusEnvironment, + SpecReporter, + WorkerAssignReporter, +} = require('detox/runners/jest-circus'); class CustomDetoxEnvironment extends DetoxCircusEnvironment { constructor(config, context) { @@ -8,8 +10,8 @@ class CustomDetoxEnvironment extends DetoxCircusEnvironment { this.initTimeout = 30000; this.registerListeners({ - SpecReporterCircus, - WorkerAssignReporterCircus, + SpecReporter, + WorkerAssignReporter, }); } diff --git a/detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/config.js b/detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/config.js deleted file mode 100644 index bb690ceac0..0000000000 --- a/detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/config.js +++ /dev/null @@ -1,16 +0,0 @@ -const path = require('path').posix; - -const rootDir = '../../../..'; -const dirname = './' + path.relative(path.join(__dirname, rootDir), __dirname); - -module.exports = { - ...require(`../../../e2e/config.js`), - - rootDir, - - setupFilesAfterEnv: [`${dirname}/init.js`], - - testRunner: 'jasmine2', - testMatch: ["**/detox-init-timeout/timeout.test.js"], - testEnvironment: 'node', -}; diff --git a/detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/init.js b/detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/init.js deleted file mode 100644 index 235d4ed878..0000000000 --- a/detox/test/e2e-unhappy/detox-init-timeout/jest-jasmine/init.js +++ /dev/null @@ -1,44 +0,0 @@ -const detox = require('detox'); -const adapter = require('detox/runners/jest/adapter'); -const specReporter = require('detox/runners/jest/specReporter'); -const assignReporter = require('detox/runners/jest/assignReporter'); - -jasmine.getEnv().addReporter(adapter); - -// This takes care of generating status logs on a per-spec basis. By default, jest only reports at file-level. -// This is strictly optional. -jasmine.getEnv().addReporter(specReporter); - -// This will post which device has assigned to run a suite, which can be useful in a multiple-worker tests run. -// This is strictly optional. -jasmine.getEnv().addReporter(assignReporter); - -beforeAll(async () => { - await detox.init(); - await device.selectApp('example'); - await device.launchApp(); -}, 30000); - -beforeEach(async () => { - try { - await adapter.beforeEach(); - } catch (err) { - await detox.cleanup(); - throw err; - } -}); - -afterAll(async () => { - await adapter.afterAll(); - await detox.cleanup(); -}); - -// simulate app-is-never-ready state - -const DetoxConnection = require('detox/src/server/DetoxConnection'); -const originalFn = DetoxConnection.prototype.sendAction; -DetoxConnection.prototype.sendAction = function (action) { - if (action.type !== 'ready') { - originalFn.call(this, action); - } -}; diff --git a/detox/test/e2e/config-jasmine.js b/detox/test/e2e/config-jasmine.js deleted file mode 100644 index 1987812e29..0000000000 --- a/detox/test/e2e/config-jasmine.js +++ /dev/null @@ -1,7 +0,0 @@ -module.exports = { - ...require('./config'), - - setupFilesAfterEnv: ['./test/e2e/init-jasmine.js'], - testRunner: 'jasmine2', - testEnvironment: 'node', -}; diff --git a/detox/test/e2e/environment.js b/detox/test/e2e/environment.js index dceeabb60d..0f7a09ff08 100644 --- a/detox/test/e2e/environment.js +++ b/detox/test/e2e/environment.js @@ -1,14 +1,16 @@ -const WorkerAssignReporterCircus = require('detox/runners/jest/WorkerAssignReporterCircus'); -const SpecReporterCircus = require('detox/runners/jest/SpecReporterCircus'); -const DetoxCircusEnvironment = require('detox/runners/jest-circus/environment'); +const { + DetoxCircusEnvironment, + SpecReporter, + WorkerAssignReporter, +} = require('detox/runners/jest-circus'); class CustomDetoxEnvironment extends DetoxCircusEnvironment { constructor(config, context) { super(config, context); this.registerListeners({ - SpecReporterCircus, - WorkerAssignReporterCircus, + SpecReporter, + WorkerAssignReporter, }); } diff --git a/detox/test/e2e/init-jasmine.js b/detox/test/e2e/init-jasmine.js deleted file mode 100644 index f6c7442b02..0000000000 --- a/detox/test/e2e/init-jasmine.js +++ /dev/null @@ -1,40 +0,0 @@ -const detox = require('detox'); -const adapter = require('detox/runners/jest/adapter'); -const specReporter = require('detox/runners/jest/specReporter'); -const assignReporter = require('detox/runners/jest/assignReporter'); -const timeoutUtils = require('./utils/timeoutUtils'); - -jasmine.getEnv().addReporter(adapter); - -// This takes care of generating status logs on a per-spec basis. By default, jest only reports at file-level. -// This is strictly optional. -jasmine.getEnv().addReporter(specReporter); - -// This will post which device has assigned to run a suite, which can be useful in a multiple-worker tests run. -// This is strictly optional. -jasmine.getEnv().addReporter(assignReporter); - -// Set the default timeout -jest.setTimeout(timeoutUtils.testTimeout); - -beforeAll(async () => { - await detox.init(); -}, timeoutUtils.initTimeout); - -beforeEach(async () => { - try { - await adapter.beforeEach(); - } catch (err) { - await detox.cleanup(); - throw err; - } -}); - -afterAll(async () => { - await adapter.afterAll(); - await detox.cleanup(); -}); - -process.on('unhandledRejection', (reason, p) => { - console.log('Unhandled Rejection at: Promise', p, 'reason:', reason); -}); diff --git a/detox/test/scripts/ci_unhappy.sh b/detox/test/scripts/ci_unhappy.sh index ea983d756b..cd4202c44a 100755 --- a/detox/test/scripts/ci_unhappy.sh +++ b/detox/test/scripts/ci_unhappy.sh @@ -6,19 +6,15 @@ export DISABLE_JUNIT_REPORTER=1 platform=$1 -echo "Running e2e test for jest-circus timeout handling..." -node scripts/assert_timeout.js npm run "e2e:$platform" -- -H -o e2e-unhappy/detox-init-timeout/jest-circus/config.js e2e-unhappy +echo "Running e2e test for timeout handling..." +node scripts/assert_timeout.js npm run "e2e:$platform" -- -H -o e2e-unhappy/detox-init-timeout/config.js e2e-unhappy cp coverage/lcov.info "../../coverage/e2e-$platform-timeout-ci.lcov" -echo "Running e2e test for jest-jasmine timeout handling..." -node scripts/assert_timeout.js npm run "e2e:$platform" -- -H -o e2e-unhappy/detox-init-timeout/jest-jasmine/config.js e2e-unhappy -cp coverage/lcov.info "../../coverage/e2e-legacy-jasmine-$platform-timeout-ci.lcov" - echo "Running early syntax error test..." node scripts/assert_timeout.js npm run "e2e:$platform" -- -H e2e-unhappy/early-syntax-error.test.js cp coverage/lcov.info "../../coverage/e2e-early-syntax-error-$platform-ci.lcov" -echo "Running e2e stack trace mangling test (Client.js)..." +echo "Running e2e stack trace mangling test..." runnerOutput="$(npm run "e2e:$platform" -- -H e2e-unhappy/failing-matcher.test.js 2>&1 | tee /dev/stdout)" if grep -q "await.*element.*supercalifragilisticexpialidocious" <<< "$runnerOutput" ; diff --git a/examples/demo-plugin/e2e/config.json b/examples/demo-plugin/e2e/config.json index 52e4ca0d27..288fc0c937 100644 --- a/examples/demo-plugin/e2e/config.json +++ b/examples/demo-plugin/e2e/config.json @@ -1,6 +1,7 @@ { - "setupFilesAfterEnv": ["./init.js"], - "testRunner": "jasmine2", - "reporters": ["detox/runners/jest/streamlineReporter"], - "verbose": true + "testEnvironment": "./environment", + "testTimeout": 120000, + "testRegex": "\\.test\\.js$", + "reporters": ["detox/runners/jest/streamlineReporter"], + "verbose": true } diff --git a/examples/demo-plugin/e2e/environment.js b/examples/demo-plugin/e2e/environment.js new file mode 100644 index 0000000000..7f4fc942fc --- /dev/null +++ b/examples/demo-plugin/e2e/environment.js @@ -0,0 +1,23 @@ +const { + DetoxCircusEnvironment, + SpecReporter, + WorkerAssignReporter, +} = require('detox/runners/jest-circus'); + +class CustomDetoxEnvironment extends DetoxCircusEnvironment { + constructor(config, context) { + super(config, context); + + // Can be safely removed, if you are content with the default value (=300000ms) + this.initTimeout = 300000; + + // This takes care of generating status logs on a per-spec basis. By default, Jest only reports at file-level. + // This is strictly optional. + this.registerListeners({ + SpecReporter, + WorkerAssignReporter, + }); + } +} + +module.exports = CustomDetoxEnvironment; diff --git a/examples/demo-plugin/e2e/init.js b/examples/demo-plugin/e2e/init.js deleted file mode 100644 index 8007485c62..0000000000 --- a/examples/demo-plugin/e2e/init.js +++ /dev/null @@ -1,30 +0,0 @@ -const detox = require('detox'); -const adapter = require('detox/runners/jest/adapter'); -const specReporter = require('detox/runners/jest/specReporter'); -const assignReporter = require('detox/runners/jest/assignReporter'); - -jasmine.getEnv().addReporter(adapter); - -// This takes care of generating status logs on a per-spec basis. By default, jest only reports at file-level. -// This is strictly optional. -jasmine.getEnv().addReporter(specReporter); - -// This will post which device has assigned to run a suite, which can be useful in a multiple-worker tests run. -// This is strictly optional. -jasmine.getEnv().addReporter(assignReporter); - -// Set the default timeout -jest.setTimeout(90000); - -beforeAll(async () => { - await detox.init(); -}, 300000); - -beforeEach(async () => { - await adapter.beforeEach(); -}); - -afterAll(async () => { - await adapter.afterAll(); - await detox.cleanup(); -});