Skip to content

Commit

Permalink
Reporter is now EventEmitter; You can also defined custom reporters; …
Browse files Browse the repository at this point in the history
…Dropped progress bars
  • Loading branch information
Filipoliko committed Nov 16, 2018
1 parent 9fad8ab commit 3b2881d
Show file tree
Hide file tree
Showing 30 changed files with 514 additions and 472 deletions.
2 changes: 2 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ example/
lib/
node_modules/
report/
docs/
html-docs/
.dockerignore
.gitignore
Dockerfile
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,4 @@
/lib/
/coverage/
/report/
/html-docs/
1 change: 1 addition & 0 deletions .npmignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
/qape.conf.js
/example/
/src/
/html-docs/
/.dockerignore
/Dockerfile
/.gitignore
Expand Down
9 changes: 7 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,8 +49,8 @@ module.exports = {
// only user defined scenarios will be executed
randomScenariosDisabled: false,
// When user defined scenario recieves an error,
// it will no longer try to minify the steps to reproduce this error.
minifyUserDefinedScenariosDisabled: false,
// it will try to minify the steps to reproduce this error.
minifyUserDefinedScenarios: true,
// Disables chromium headless mode and will display browser GUI.
headlessModeDisabled: false,
// Preview mode will overwrite other config values
Expand Down Expand Up @@ -82,6 +82,11 @@ module.exports = {
},
// A browser websocket endpoint to connect to (i.e. ws://5.5.5.5:3505)
browserWebSocketEndpoint: null,
// Define your reporters for the QApe run.
// You can pass a string for reporters in npm registry,
// i.e. if you pass \'super\', QApe will look for
// reporter 'qape-reporter-super'. You can also pass Class.
reporters: ['default'],
// Relative path for the report output
reportPath: './report',
}
Expand Down
49 changes: 49 additions & 0 deletions docs/Reporters.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
# Reporters
You can define reporters via config.reporters.

```
var LocalCool = require('/path/to/LocalCool');
export default {
reporters: [
// For reporter published in npm registry as 'qape-reporter-cool'
'cool',
// LocalCool is Class extending EventEmitter
LocalCool
]
}
```

## Example
```javascript
import EventEmitter from 'events';

export default class DefaultReporter extends EventEmitter {
constructor(config) {
super();

// You will recieve configuration for current QApe run
this._config = config;

// runner:start is emitted after browser instance is initialized
// eventData contains scenario and browser instance
this.on('runner:start', eventData => console.log(eventData));
// scenarios:start is emitted after specific scenario starts
// eventData contains browser instance, scenario type
// For type 'defined' there is also scenario and name
// For type 'failing' there is also scenario and errors
this.on('scenario:start', eventData => console.log(eventData));
// scenarios:end is emitted after specific scenario is finished
// eventData contains browser instance, scenario type
// For type 'defined' there is also scenario, name and results
// For type 'failing' there is also scenario, errors and minified (boolean)
// For type 'random' there is also results
this.on('scenario:end', eventData => console.log(eventData));
// runner:end is emitted after browser instance is cleared
this.on('runner:end', () => console.log('it\'s done'));
// runner:error is emitted whenever an uncaught error occurred
// eventData contains scenario, and browser instance and error
this.on('runner:error', eventData => console.log(eventData));
}
}
```
11 changes: 6 additions & 5 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
"main": "index.js",
"scripts": {
"test": "jest",
"docs:build": "documentation build src/** -f html -o html-docs",
"build": "rm -rf lib && babel src --out-dir lib --ignore \"src/**/*Spec.js\" --copy-files --plugins=transform-es2015-modules-commonjs",
"dev": "npm run build -- --source-maps --watch",
"start": "node -r source-map-support/register bin/qape.js",
Expand All @@ -20,21 +21,21 @@
"monkey"
],
"repository": {
"type": "git",
"url": "https://github.com/seznam/qape.git"
},
"type": "git",
"url": "https://github.com/seznam/qape.git"
},
"author": "Filip Satek <[email protected]>",
"license": "MIT",
"dependencies": {
"commander": "2.17.1",
"glob-all": "3.1.0",
"lodash": "4.17.10",
"progress": "2.0.0",
"lodash.isequal": "4.5.0",
"puppeteer": "1.8.0"
},
"devDependencies": {
"babel-cli": "6.26.0",
"babel-plugin-transform-es2015-modules-commonjs": "6.26.2",
"documentation": "8.1.2",
"express": "4.16.3",
"jest": "23.6.0",
"serve-static": "1.13.2",
Expand Down
9 changes: 7 additions & 2 deletions qape.conf.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,8 +19,8 @@ module.exports = {
// only user defined scenarios will be executed
randomScenariosDisabled: false,
// When user defined scenario recieves an error,
// it will no longer try to minify the steps to reproduce this error.
minifyUserDefinedScenariosDisabled: false,
// it will try to minify the steps to reproduce this error.
minifyUserDefinedScenarios: true,
// Disables chromium headless mode and will display browser GUI.
headlessModeDisabled: false,
// Preview mode will overwrite other config values
Expand Down Expand Up @@ -52,6 +52,11 @@ module.exports = {
},
// A browser websocket endpoint to connect to (i.e. ws://5.5.5.5:3505)
browserWebSocketEndpoint: null,
// Define your reporters for the QApe run.
// You can pass a string for reporters in npm registry,
// i.e. if you pass \'super\', QApe will look for
// reporter 'qape-reporter-super'. You can also pass Class.
reporters: ['default'],
// Relative path for the report output
reportPath: './report',
}
57 changes: 23 additions & 34 deletions src/Runner.js
Original file line number Diff line number Diff line change
@@ -1,20 +1,19 @@
import Browser from './browser/Browser';
import Scenarios from './scenarios/Scenarios';
import Reporter from './reporter/Reporter';
import Reporter from './reporter/BaseReporter';
import ActionsHandler from './actions/ActionsHandler';
import Config from './config/Config';
import Progress from './progress/Progress';
import fs from 'fs';
import path from 'path';

export default class Runner {
constructor(config) {
this._config = config;
this._progress = null;
this._scenarios = null;
this._actionsHandler = null;
this._reporter = null;
this._initTime = null;
this._isSuccess = true;
}

start(files = []) {
Expand All @@ -27,15 +26,11 @@ export default class Runner {
let instances = [];

for (let i = 0; i < this._config.parallelInstances; i++) {
let progressBar = this._progress.newBar(this._config.actionsPerScenario);

instances.push(this._startScenario(progressBar));
instances.push(this._startInstance());
}

return Promise.all(instances).then(() => {
this._progress.terminate();

if (this._reporter.isSuccess()) {
if (this._isSuccess) {
return Promise.resolve();
}

Expand All @@ -58,40 +53,39 @@ export default class Runner {
});
}

async _startScenario(progressBar) {
async _startInstance() {
while (
!this._config.randomScenariosDisabled &&
this._isAllowedToStartNewScenario() ||
this._scenarios.hasScenario()
) {
let scenario = this._scenarios.getScenario();

if (!scenario) {
console.log('No scenario recieved.');
return;
}

let instance = await this._getBrowserInstance();
let log;
let results;

progressBar.tick(0, { info: '' });
this._reporter.emit('runner:start', {
scenario,
instance
});

try {
log = await scenario(instance, progressBar);
} catch (e) {
progressBar.tick(0, { info: e.toString() });
results = await scenario(instance);
} catch (error) {
this._reporter.emit('runner:error', {
scenario,
instance,
error
});
}

if (log && log.errors && log.errors.length > 0) {
this._scenarios.addFailingScenario(log);
}

if (log && log.executionError) {
console.log(log.executionError);
progressBar.tick(0, { info: log.executionError });
if (results && results.errors && results.errors.length > 0) {
this._isSuccess = false;
this._scenarios.addFailingScenario(results);
}

await instance.clear();

this._reporter.emit('runner:end');
}
}

Expand All @@ -105,7 +99,6 @@ export default class Runner {

_init() {
this._initConfig();
this._initProgress();
this._initActionsHandler();
this._initReporter();
this._initScenarios();
Expand All @@ -116,16 +109,12 @@ export default class Runner {
this._config = new Config().load(this._config);
}

_initProgress() {
this._progress = new Progress(this._config);
}

_initActionsHandler() {
this._actionsHandler = new ActionsHandler(this._config).init();
}

_initReporter() {
this._reporter = new Reporter(this._config, this._actionsHandler);
this._reporter = new Reporter(this._config).init();
}

_initScenarios() {
Expand Down
3 changes: 0 additions & 3 deletions src/__tests__/RunnerSpec.js
Original file line number Diff line number Diff line change
Expand Up @@ -9,20 +9,17 @@ describe('Runner', () => {

it('can be initialized', () => {
runner._initConfig = jest.fn();
runner._initProgress = jest.fn();
runner._initActionsHandler = jest.fn();
runner._initReporter = jest.fn();
runner._initScenarios = jest.fn();

runner._init();

expect(runner._initConfig).toHaveBeenCalledTimes(1);
expect(runner._initProgress).toHaveBeenCalledTimes(1);
expect(runner._initActionsHandler).toHaveBeenCalledTimes(1);
expect(runner._initReporter).toHaveBeenCalledTimes(1);
expect(runner._initScenarios).toHaveBeenCalledTimes(1);
expect(runner._config).toEqual({});
expect(runner._progress).toEqual(null);
expect(runner._scenarios).toEqual(null);
expect(runner._actionsHandler).toEqual(null);
expect(runner._reporter).toEqual(null);
Expand Down
15 changes: 1 addition & 14 deletions src/__tests__/helpersSpec.js
Original file line number Diff line number Diff line change
@@ -1,19 +1,6 @@
import {
sumPartialSeries,
formatDigits
} from '../helpers'
import { formatDigits } from '../helpers'

describe('Helpers', () => {
describe('sumPartialSeries', () => {
it('can sum partial series', () => {
expect(sumPartialSeries(1)).toEqual(1);
expect(sumPartialSeries(2)).toEqual(3);
expect(sumPartialSeries(3)).toEqual(6);
expect(sumPartialSeries(4)).toEqual(10);
expect(sumPartialSeries(5)).toEqual(15);
});
});

describe('formatDigits', () => {
it('can format digits', () => {
expect(formatDigits(1)).toEqual('01');
Expand Down
11 changes: 5 additions & 6 deletions src/actions/AbstractAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,11 @@ export default class AbstractAction {

this._actionConfig = {};

this._results = { action: this.constructor.id, errors: [] };
this._results = {
action: this.constructor.id,
errors: [],
message: `Action: ${this.constructor.id}; Config: ${this.actionConfig}`
};
}

async execute(instance) {
Expand Down Expand Up @@ -49,11 +53,6 @@ export default class AbstractAction {
return this._actionConfig;
}

log() {
console.log('Action:', this.constructor.id);
console.log('Config:', this.actionConfig);
}

_addErrorToResults(error) {
this._results.errors.push({
type: 'pageError',
Expand Down
1 change: 1 addition & 0 deletions src/actions/ClickAction.js
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@ export default class ClickAction extends AbstractAction {
let selector = await this._actionsHelper.getElementSelector(element);

this._results.config = { selector };
this._results.message = `Click on "${selector}"`;
}

_closeNewTab(target) {
Expand Down
2 changes: 1 addition & 1 deletion src/config/Config.js
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ export default class Config {
this._config = Object.assign(this._config, {
parallelInstances: 1,
randomScenariosDisabled: true,
minifyUserDefinedScenariosDisabled: true,
minifyUserDefinedScenarios: false,
headlessModeDisabled: true
});
}
Expand Down
Loading

0 comments on commit 3b2881d

Please sign in to comment.