From f2a5593cedde036da84f9c4fdb82ec5c373ef1c1 Mon Sep 17 00:00:00 2001 From: Anton Usmansky <cody0@yandex-team.ru> Date: Sun, 12 Feb 2017 00:10:15 +0300 Subject: [PATCH] feat: BEFORE_FILE_READ and AFTER_FILE_READ events --- README.md | 4 ++- lib/constants/runner-events.js | 3 +++ lib/runner/index.js | 3 +++ lib/runner/mocha-runner/index.js | 4 +-- lib/runner/mocha-runner/mocha-adapter.js | 9 +++++++ test/lib/runner/index.js | 5 +++- test/lib/runner/mocha-runner/index.js | 8 ++++++ test/lib/runner/mocha-runner/mocha-adapter.js | 27 +++++++++++++++++++ 8 files changed, 59 insertions(+), 4 deletions(-) diff --git a/README.md b/README.md index 1fad97d2c..2e0a390a2 100644 --- a/README.md +++ b/README.md @@ -391,7 +391,7 @@ sets: { common: { // run tests associated with this path in all browsers files: 'tests/common' // which are configured in the `browsers` option }, - desktop: { + desktop: { files: [ 'tests/desktop/*.hermione.js', 'tests/common/*.hermione.js' @@ -547,6 +547,8 @@ Property name | Description Event | Description ------------------------- | ------------- +`BEFORE_FILE_READ` | Will be triggered on test files parsing before reading the file. The handler accepts data object with `file`, `browser` (browser id string) and `hermione` (helper which will be available in test file) fields. +`AFTER_FILE_READ` | Will be triggered on test files parsing right after reading the file. The handler accepts data object with `file`, `browser` (browser id string) and `hermione` (helper which will be available in test file) fields. `RUNNER_START` | Will be triggered before test execution. If a handler returns a promise, tests will be executed only after the promise is resolved. The handler accepts an instance of a runner as the first argument. You can use this instance to emit and subscribe to any other available events. `RUNNER_END` | Will be triggered after test execution. If a handler returns a promise, tests will be executed only after the promise is resolved. `SESSION_START` | Will be triggered after browser session initialization. If a handler returns a promise, tests will be executed only after the promise is resolved. The handler accepts an instance of webdriverIO as the first argument and an object with a browser identifier as the second. diff --git a/lib/constants/runner-events.js b/lib/constants/runner-events.js index 91c38be96..71d24eafb 100644 --- a/lib/constants/runner-events.js +++ b/lib/constants/runner-events.js @@ -13,6 +13,9 @@ const getAsyncEvents = () => ({ }); const getSyncEvents = () => ({ + BEFORE_FILE_READ: 'beforeFileRead', + AFTER_FILE_READ: 'afterFileRead', + SUITE_BEGIN: 'beginSuite', SUITE_END: 'endSuite', diff --git a/lib/runner/index.js b/lib/runner/index.js index 49340ff83..11a189c10 100644 --- a/lib/runner/index.js +++ b/lib/runner/index.js @@ -73,6 +73,9 @@ module.exports = class MainRunner extends QEmitter { const mochaRunner = MochaRunner.create(this._config, browserAgent, this._testSkipper); qUtils.passthroughEvent(mochaRunner, this, [ + RunnerEvents.BEFORE_FILE_READ, + RunnerEvents.AFTER_FILE_READ, + RunnerEvents.SUITE_BEGIN, RunnerEvents.SUITE_END, diff --git a/lib/runner/mocha-runner/index.js b/lib/runner/mocha-runner/index.js index 82b167149..73658cafb 100644 --- a/lib/runner/mocha-runner/index.js +++ b/lib/runner/mocha-runner/index.js @@ -45,7 +45,7 @@ module.exports = class MochaRunner extends QEmitter { .attachTestFilter(filterFn) .attachTitleValidator(titles) .applySkip(this._testSkipper) - .addFiles(suiteFiles) - .attachEmitFn(this.emit.bind(this)); + .attachEmitFn(this.emit.bind(this)) + .addFiles(suiteFiles); } }; diff --git a/lib/runner/mocha-runner/mocha-adapter.js b/lib/runner/mocha-runner/mocha-adapter.js index b85d86767..f4fe5e135 100644 --- a/lib/runner/mocha-runner/mocha-adapter.js +++ b/lib/runner/mocha-runner/mocha-adapter.js @@ -5,6 +5,7 @@ const logger = require('../../utils').logger; const Skip = require('./skip/'); const SkipBuilder = require('./skip/skip-builder'); const OnlyBuilder = require('./skip/only-builder'); +const RunnerEvents = require('../../constants/runner-events'); const Mocha = require('mocha'); const path = require('path'); const clearRequire = require('clear-require'); @@ -94,6 +95,14 @@ module.exports = class MochaAdapter { const Reporter = _.partial(ProxyReporter, emit, () => this._getBrowser()); this._mocha.reporter(Reporter); + const emit_ = (event, file) => emit(event, { + file, + hermione: global.hermione, + browser: this._browserAgent.browserId + }); + this.suite.on('pre-require', (ctx, file) => emit_(RunnerEvents.BEFORE_FILE_READ, file)); + this.suite.on('post-require', (ctx, file) => emit_(RunnerEvents.AFTER_FILE_READ, file)); + return this; } diff --git a/test/lib/runner/index.js b/test/lib/runner/index.js index c7cee5f35..98b87ed8a 100644 --- a/test/lib/runner/index.js +++ b/test/lib/runner/index.js @@ -198,6 +198,9 @@ describe('Runner', () => { describe('events', () => { const mochaRunnerEvents = [ + RunnerEvents.BEFORE_FILE_READ, + RunnerEvents.AFTER_FILE_READ, + RunnerEvents.SUITE_BEGIN, RunnerEvents.SUITE_END, @@ -243,7 +246,7 @@ describe('Runner', () => { }); }); - describe('passing of events from browser agent', () => { + describe('passing events from browser agent', () => { beforeEach(() => sandbox.stub(BrowserAgent, 'create').returns(sinon.createStubInstance(BrowserAgent))); [RunnerEvents.SESSION_START, RunnerEvents.SESSION_END].forEach((event) => { diff --git a/test/lib/runner/mocha-runner/index.js b/test/lib/runner/mocha-runner/index.js index 3b3cd61a5..0a6ff4d07 100644 --- a/test/lib/runner/mocha-runner/index.js +++ b/test/lib/runner/mocha-runner/index.js @@ -105,6 +105,14 @@ describe('mocha-runner', () => { )); }); + it('should attach emit function before file adding', () => { + return run_() + .then(() => assert.callOrder( + MochaAdapter.prototype.attachEmitFn, + MochaAdapter.prototype.addFiles + )); + }); + it('should call title vaidator for each file', () => { return run_(['some/path/file.js', 'other/path/file.js']) .then(() => { diff --git a/test/lib/runner/mocha-runner/mocha-adapter.js b/test/lib/runner/mocha-runner/mocha-adapter.js index 41f1bf18a..fb627c2de 100644 --- a/test/lib/runner/mocha-runner/mocha-adapter.js +++ b/test/lib/runner/mocha-runner/mocha-adapter.js @@ -7,6 +7,7 @@ const SkipBuilder = require('../../../../lib/runner/mocha-runner/skip/skip-build const OnlyBuilder = require('../../../../lib/runner/mocha-runner/skip/only-builder'); const Skip = require('../../../../lib/runner/mocha-runner/skip/'); const TestSkipper = require('../../../../lib/runner/test-skipper'); +const RunnerEvents = require('../../../../lib/constants/runner-events'); const proxyquire = require('proxyquire').noCallThru(); const inherit = require('inherit'); const _ = require('lodash'); @@ -550,5 +551,31 @@ describe('mocha-runner/mocha-adapter', () => { const getBrowser = ProxyReporter.prototype.__constructor.lastCall.args[1]; assert.deepEqual(getBrowser(), {id: 'some-browser'}); }); + + describe('file events', () => { + beforeEach(() => MochaAdapter.init()); + afterEach(() => delete global.hermione); + + _.forEach({ + 'pre-require': 'BEFORE_FILE_READ', + 'post-require': 'AFTER_FILE_READ' + }, (hermioneEvent, mochaEvent) => { + it(`should emit ${hermioneEvent} on mocha ${mochaEvent}`, () => { + const emit = sinon.spy(); + browserAgent.browserId = 'bro'; + + mochaAdapter.attachEmitFn(emit); + + MochaStub.prototype.suite.emit(mochaEvent, {}, '/some/file.js'); + + assert.calledOnce(emit); + assert.calledWith(emit, RunnerEvents[hermioneEvent], sinon.match({ + file: '/some/file.js', + hermione: global.hermione, + browser: 'bro' + })); + }); + }); + }); }); });