From 0311f6d914025230f654f9d3057a19c8126a7fd8 Mon Sep 17 00:00:00 2001 From: up73k Date: Fri, 23 Dec 2016 14:04:26 +0300 Subject: [PATCH] feat: Add test filename to html report's metaInfo section --- lib/reporters/html/view-model.js | 1 + lib/suite.js | 1 + lib/test-reader.js | 17 ++- lib/tests-api/index.js | 14 +- test/unit/reporters/html/view-model.js | 38 +++++ test/unit/test-reader.js | 13 ++ test/unit/tests-api/index.js | 199 ++++++++++++++----------- 7 files changed, 183 insertions(+), 100 deletions(-) create mode 100644 test/unit/reporters/html/view-model.js diff --git a/lib/reporters/html/view-model.js b/lib/reporters/html/view-model.js index 89e0ce2f6..080237181 100644 --- a/lib/reporters/html/view-model.js +++ b/lib/reporters/html/view-model.js @@ -123,6 +123,7 @@ module.exports = class ViewModel { const suite = result.suite; const metaInfo = suite ? suite.metaInfo : {}; metaInfo.sessionId = result.sessionId || 'unknown session id'; + metaInfo.file = suite.file; const testResult = _.assign({ suiteUrl: rootUrl + suite.url, diff --git a/lib/suite.js b/lib/suite.js index 9198d3226..200b27581 100644 --- a/lib/suite.js +++ b/lib/suite.js @@ -24,6 +24,7 @@ module.exports = class Suite { this.afterActions = []; this.browsers = []; this.context = {}; + this.file = null; definePrivate(this); } diff --git a/lib/test-reader.js b/lib/test-reader.js index 13b958196..ddeba9f59 100644 --- a/lib/test-reader.js +++ b/lib/test-reader.js @@ -1,6 +1,7 @@ 'use strict'; const _ = require('lodash'); +const path = require('path'); const SetsBuilder = require('gemini-core').SetsBuilder; const Suite = require('./suite'); const Events = require('./constants/events'); @@ -9,15 +10,17 @@ const utils = require('./utils'); const DEFAULT_DIR = require('../package').name; -const loadSuites = (sets, emitter) => { +const loadSuites = (sets, emitter, projectRoot) => { const rootSuite = Suite.create(''); - _.forEach(sets.groupByFile(), (browsers, path) => { - global.gemini = testsApi(rootSuite, browsers); + _.forEach(sets.groupByFile(), (browsers, filePath) => { + const relativeFilePath = path.relative(projectRoot, filePath); - emitter.emit(Events.BEFORE_FILE_READ, path); - utils.requireWithNoCache(path); - emitter.emit(Events.AFTER_FILE_READ, path); + global.gemini = testsApi(rootSuite, browsers, relativeFilePath); + + emitter.emit(Events.BEFORE_FILE_READ, filePath); + utils.requireWithNoCache(filePath); + emitter.emit(Events.AFTER_FILE_READ, filePath); delete global.gemini; }); @@ -32,5 +35,5 @@ module.exports = (emitter, config, opts) => { .useFiles(opts.paths) .useBrowsers(opts.browsers) .build(config.system.projectRoot, {ignore: config.system.exclude}) - .then((setCollection) => loadSuites(setCollection, emitter)); + .then((setCollection) => loadSuites(setCollection, emitter, config.system.projectRoot)); }; diff --git a/lib/tests-api/index.js b/lib/tests-api/index.js index 40912d62f..c8b59b539 100644 --- a/lib/tests-api/index.js +++ b/lib/tests-api/index.js @@ -4,7 +4,7 @@ const Suite = require('../suite'); const SuiteBuilder = require('./suite-builder'); const keysCodes = require('./keys-codes'); -module.exports = (suite, browsers) => { +module.exports = (suite, browsers, file) => { let suiteId = 1; const testsAPI = keysCodes; @@ -25,9 +25,17 @@ module.exports = (suite, browsers) => { suite = Suite.create(name, parent); parent.addChild(suite); suite.id = suiteId++; - if (browsers && suite.parent.isRoot) { - suite.browsers = browsers; + + if (suite.parent.isRoot) { + if (browsers) { + suite.browsers = browsers; + } + + if (file) { + suite.file = file; + } } + callback(new SuiteBuilder(suite)); if (suite.hasStates) { if (!suite.url) { diff --git a/test/unit/reporters/html/view-model.js b/test/unit/reporters/html/view-model.js new file mode 100644 index 000000000..1a1324d97 --- /dev/null +++ b/test/unit/reporters/html/view-model.js @@ -0,0 +1,38 @@ +'use strict'; + +const _ = require('lodash'); + +const ViewModel = require('lib/reporters/html/view-model'); + +describe('ViewModel', () => { + const sandbox = sinon.sandbox.create(); + const stubTest_ = (opts) => { + opts = opts || {}; + + return _.defaultsDeep(opts, { + state: {name: 'name-default'}, + suite: { + path: ['suite'], + metaInfo: {sessionId: 'sessionId-default'}, + file: 'default/path/file.js' + } + }); + }; + const getResult_ = (model) => model.getResult().suites[0].children[0].browsers[0].result; + const createViewModel_ = () =>{ + const config = {forBrowser: sandbox.stub().returns({})}; + return new ViewModel(config); + }; + + it('should contain "file" in "metaInfo"', () => { + const model = createViewModel_(); + + model.addSuccess(stubTest_({ + suite: {file: '/path/file.js'} + })); + + const metaInfo = JSON.parse(getResult_(model).metaInfo); + + assert.equal(metaInfo.file, '/path/file.js'); + }); +}); diff --git a/test/unit/test-reader.js b/test/unit/test-reader.js index 2c05617e2..e9aab9c42 100644 --- a/test/unit/test-reader.js +++ b/test/unit/test-reader.js @@ -135,6 +135,19 @@ describe('test-reader', () => { ); }); }); + + it('should call "testsApi" with relative file path', () => { + const groupByFile = () => ({'/project/root/path/file1.js': []}); + + const config = mkConfigStub({ + system: {projectRoot: '/project/root'} + }); + + SetsBuilder.prototype.build.returns(Promise.resolve({groupByFile})); + + return readTests_({config}) + .then(() => assert.calledWith(testsApi, sinon.match.any, sinon.match.any, 'path/file1.js')); + }); }); describe('global "gemini" variable', () => { diff --git a/test/unit/tests-api/index.js b/test/unit/tests-api/index.js index dc2f885bc..347f01568 100644 --- a/test/unit/tests-api/index.js +++ b/test/unit/tests-api/index.js @@ -1,58 +1,54 @@ 'use strict'; -var testsAPI = require('lib/tests-api'), - Suite = require('lib/suite'); +const testsAPI = require('lib/tests-api'); +const Suite = require('lib/suite'); -describe('tests-api', function() { - beforeEach(function() { - this.suite = Suite.create(''); +describe('tests-api', () => { + let rootSuite; + + beforeEach(() => { + rootSuite = Suite.create(''); }); - describe('.suite method', function() { - var gemini; + describe('.suite method', () => { + let gemini; - beforeEach(function() { - gemini = testsAPI(this.suite); + beforeEach(() => { + gemini = testsAPI(rootSuite); }); - it('should throw an error if first argument is not a string', function() { - assert.throws(function() { - gemini.suite(123, function() {}); - }, TypeError); + it('should throw an error if first argument is not a string', () => { + assert.throws(() => gemini.suite(123, () => {}), TypeError); }); - it('should throw an error if second argument is not a function', function() { - assert.throws(function() { - gemini.suite('name'); - }, TypeError); + it('should throw an error if second argument is not a function', () => { + assert.throws(() => gemini.suite('name'), TypeError); }); - it('should create new suite with corresponding name', function() { - gemini.suite('name', function() {}); + it('should create new suite with corresponding name', () => { + gemini.suite('name', () => {}); - assert.equal(this.suite.children[0].name, 'name'); + assert.equal(rootSuite.children[0].name, 'name'); }); - it('should call callback', function() { - var spy = sinon.spy(); + it('should call callback', () => { + const spy = sinon.spy(); gemini.suite('name', spy); assert.called(spy); }); - it('should created nested suites when called nestedly', function() { - gemini.suite('name', function() { - gemini.suite('child', function() {}); - }); + it('should created nested suites when called nestedly', () => { + gemini.suite('name', () => gemini.suite('child', () => {})); - assert.equal(this.suite.children[0].children[0].name, 'child'); + assert.equal(rootSuite.children[0].children[0].name, 'child'); }); describe('child suites of the same name', () => { - beforeEach(function() { - gemini = testsAPI(this.suite, ['browser1']); + beforeEach(() => { + gemini = testsAPI(rootSuite, ['browser1']); }); - it('should not allow to create with intersect browsers', function() { + it('should not allow to create with intersect browsers', () => { assert.throws(() => { gemini.suite('name', () => { gemini.suite('child', () => {}); @@ -61,12 +57,10 @@ describe('tests-api', function() { }); }); - it('should allow to create with not intersecting browser sets', function() { - gemini.suite('name', () => { - gemini.suite('child', () => {}); - }); + it('should allow to create with not intersecting browser sets', () => { + gemini.suite('name', () => gemini.suite('child', () => {})); - gemini = testsAPI(this.suite, ['browser2']); + gemini = testsAPI(rootSuite, ['browser2']); assert.doesNotThrow(() => { gemini.suite('name', () => { @@ -76,35 +70,35 @@ describe('tests-api', function() { }); }); - it('should create non-nested suite at the root level', function() { - gemini.suite('first', function() {}); - gemini.suite('second', function() {}); + it('should create non-nested suite at the root level', () => { + gemini.suite('first', () => {}); + gemini.suite('second', () => {}); - assert.equal(this.suite.children[1].name, 'second'); + assert.equal(rootSuite.children[1].name, 'second'); }); - it('should throw when suite has states but does not has URL', function() { - assert.throws(function() { - gemini.suite('first', function(suite) { + it('should throw when suite has states but does not has URL', () => { + assert.throws(() => { + gemini.suite('first', (suite) => { suite.setCaptureElements('.element') .capture('plain'); }); }); }); - it('should throw when suite has no states nor URL', function() { - assert.doesNotThrow(function() { - gemini.suite('first', function(suite) { + it('should throw when suite has no states nor URL', () => { + assert.doesNotThrow(() => { + gemini.suite('first', (suite) => { suite.setCaptureElements('.element'); }); }); }); - it('should not throw when suite has states and url is inherited from parent', function() { - assert.doesNotThrow(function() { - gemini.suite('first', function(suite) { + it('should not throw when suite has states and url is inherited from parent', () => { + assert.doesNotThrow(() => { + gemini.suite('first', (suite) => { suite.setUrl('/url'); - gemini.suite('child', function(suite) { + gemini.suite('child', (suite) => { suite.setCaptureElements('.element') .capture('plain'); }); @@ -112,28 +106,28 @@ describe('tests-api', function() { }); }); - it('should throw if suite has states but does not has captureSelectors', function() { - assert.throws(function() { - gemini.suite('first', function(suite) { + it('should throw if suite has states but does not has captureSelectors', () => { + assert.throws(() => { + gemini.suite('first', (suite) => { suite.setUrl('/url') .capture('plain'); }); }); }); - it('should not throw if suite has no states nor captureSelectors', function() { - assert.doesNotThrow(function() { - gemini.suite('first', function(suite) { + it('should not throw if suite has no states nor captureSelectors', () => { + assert.doesNotThrow(() => { + gemini.suite('first', (suite) => { suite.setUrl('/url'); }); }); }); - it('should not throw when suite has states and captureSelectors are inherited from parent', function() { - assert.doesNotThrow(function() { - gemini.suite('first', function(suite) { + it('should not throw when suite has states and captureSelectors are inherited from parent', () => { + assert.doesNotThrow(() => { + gemini.suite('first', (suite) => { suite.setCaptureElements('.element'); - gemini.suite('child', function(suite) { + gemini.suite('child', (suite) => { suite.setUrl('/url') .capture('plain'); }); @@ -141,58 +135,83 @@ describe('tests-api', function() { }); }); - it('should assign suite ids', function() { - gemini.suite('suite', function() {}); - assert.equal(this.suite.children[0].id, 1); + it('should assign suite ids', () => { + gemini.suite('suite', () => {}); + assert.equal(rootSuite.children[0].id, 1); }); - it('should assign incrementing suite ids for following suites', function() { - gemini.suite('suite', function() {}); - gemini.suite('suite2', function() {}); - assert.equal(this.suite.children[1].id, 2); + it('should assign incrementing suite ids for following suites', () => { + gemini.suite('suite', () => {}); + gemini.suite('suite2', () => {}); + assert.equal(rootSuite.children[1].id, 2); }); - it('should assign incrementing suite ids for child suites', function() { - gemini.suite('suite', function() { - gemini.suite('suite2', function() {}); + it('should assign incrementing suite ids for child suites', () => { + gemini.suite('suite', () => { + gemini.suite('suite2', () => {}); }); - assert.equal(this.suite.children[0].children[0].id, 2); + assert.equal(rootSuite.children[0].children[0].id, 2); }); - it('should assign child suite ids before siblings', function() { - gemini.suite('suite', function() { - gemini.suite('suite2', function() {}); + it('should assign child suite ids before siblings', () => { + gemini.suite('suite', () => { + gemini.suite('suite2', () => {}); }); - gemini.suite('suite3', function() {}); + gemini.suite('suite3', () => {}); + + assert.equal(rootSuite.children[0].children[0].id, 2); + assert.equal(rootSuite.children[1].id, 3); + }); + }); + + describe('browsers', () => { + const browsers = ['some-browser', 'other-browser']; + let gemini; + + beforeEach(() => { + gemini = testsAPI(rootSuite, browsers); + }); + + it('should be set for top level suite', () => { + gemini.suite('suite', () => {}); + + assert.equal(rootSuite.children[0].browsers, browsers); + assert.isTrue(rootSuite.children[0].hasOwnProperty('browsers')); + }); + + it('should not be set for not top level suite', () => { + gemini.suite('suite', () => { + gemini.suite('child', () => {}); + }); - assert.equal(this.suite.children[0].children[0].id, 2); - assert.equal(this.suite.children[1].id, 3); + assert.equal(rootSuite.children[0].children[0].browsers, browsers); + assert.isFalse(rootSuite.children[0].children[0].hasOwnProperty('browsers')); }); }); - describe('browsers', function() { - var browsers = ['some-browser', 'other-browser'], - gemini; + describe('file path', () => { + const file = 'path/file.js'; + let gemini; - beforeEach(function() { - gemini = testsAPI(this.suite, browsers); + beforeEach(() => { + gemini = testsAPI(rootSuite, [], file); }); - it('should be set for top level suite', function() { - gemini.suite('suite', function() {}); + it('should be set for suite', () => { + gemini.suite('suite', () => {}); - assert.equal(this.suite.children[0].browsers, browsers); - assert.isTrue(this.suite.children[0].hasOwnProperty('browsers')); + assert.equal(rootSuite.children[0].file, file); + assert.isTrue(rootSuite.children[0].hasOwnProperty('file')); }); - it('should not be set for not top level suite', function() { - gemini.suite('suite', function() { - gemini.suite('child', function() {}); + it('should not be set for not top level suite', () => { + gemini.suite('suite', () => { + gemini.suite('child', () => {}); }); - assert.equal(this.suite.children[0].children[0].browsers, browsers); - assert.isFalse(this.suite.children[0].children[0].hasOwnProperty('browsers')); + assert.equal(rootSuite.children[0].children[0].file, file); + assert.isFalse(rootSuite.children[0].children[0].hasOwnProperty('file')); }); }); });