Skip to content

Commit

Permalink
Merge pull request #273 from sergcen/hermione-node-debug
Browse files Browse the repository at this point in the history
Nodejs debug for tests
  • Loading branch information
DudaGod authored Sep 17, 2018
2 parents cbc4841 + aaa42b7 commit 36f611a
Show file tree
Hide file tree
Showing 7 changed files with 96 additions and 6 deletions.
15 changes: 15 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,6 +76,7 @@ Hermione is a utility for integration testing of web pages using [WebdriverIO](h
- [Test Collection](#test-collection)
- [Test Parser API](#test-parser-api)
- [setController(name, methods)](#setcontrollername-methods)
- [Debug mode](#debug-mode)

<!-- END doctoc generated TOC please keep comment here to allow auto update -->

Expand Down Expand Up @@ -767,6 +768,8 @@ Configuration data can be changed depending on extra conditions in the `prepareE
-r, --reporter <reporter> Test reporter
-b, --browser <browser> Run tests only in specified browser
--grep <grep> Run only tests matching string or regexp
--inspect[=[host:]port] Run tests in debug mode
--inspect-brk[=[host:]port] Run tests in debug mode with break at the start
```

For example,
Expand Down Expand Up @@ -1001,3 +1004,15 @@ describe('foo', () => {
```

**Note**: controller will be removed as soon as current file will be parsed

## Debug mode

In order to understand what is going on in the test step by step, there is a debug mode. You can run tests in this mode using these options: --inspect and --inspect-brk. The difference between them is that the second one stops before executing the code.

Example:
```
hermione path/to/mytest.js --inspect
```

**Note**: In the debugging mode, only one worker is started and all tests are performed only in it.
Use this mode with option `sessionsPerBrowser=1` in order to debug tests one at a time.
8 changes: 7 additions & 1 deletion lib/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,8 @@ exports.run = () => {
.option('-s, --set <set>', 'run tests only in the specified set', collect)
.option('--grep <grep>', 'run only tests matching the pattern')
.option('--update-refs', 'update screenshot references or gather them if they do not exist ("assertView" command)')
.option('--inspect [inspect]', 'nodejs inspector on [=[host:]port]')
.option('--inspect-brk [inspect-brk]', 'nodejs inspector with break at the start')
.arguments('[paths...]')
.action(async (paths) => {
try {
Expand All @@ -39,7 +41,11 @@ exports.run = () => {
browsers: program.browser,
sets: program.set,
grep: program.grep,
updateRefs: program.updateRefs
updateRefs: program.updateRefs,
inspectMode: (program.inspect || program.inspectBrk) && {
inspect: program.inspect,
inspectBrk: program.inspectBrk
}
});

process.exit(isTestsSuccess ? 0 : 1);
Expand Down
4 changes: 2 additions & 2 deletions lib/hermione.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ module.exports = class Hermione extends BaseHermione {
this.emit(RunnerEvents.CLI, parser);
}

async run(testPaths, {browsers, sets, grep, updateRefs, reporters} = {}) {
async run(testPaths, {browsers, sets, grep, updateRefs, reporters, inspectMode} = {}) {
validateUnknownBrowsers(browsers, _.keys(this._config.browsers));

this._runner = Runner.create(this._config)
Expand All @@ -37,7 +37,7 @@ module.exports = class Hermione extends BaseHermione {
eventsUtils.passthroughEventAsync(this._runner, this, _.values(RunnerEvents.getAsync()));
eventsUtils.passthroughEventAsync(signalHandler, this, RunnerEvents.EXIT);

RuntimeConfig.getInstance().extend({updateRefs});
RuntimeConfig.getInstance().extend({updateRefs, inspectMode});

await this._init();

Expand Down
25 changes: 24 additions & 1 deletion lib/runner/workers.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,18 +26,41 @@ module.exports = class Workers {

_createWorkerFarm() {
const workerFilepath = require.resolve('../worker');

const params = {
maxConcurrentWorkers: this._config.system.workers,
maxCallsPerWorker: this._config.system.testsPerWorker,
maxConcurrentCallsPerWorker: Infinity,
autoStart: true,
maxRetries: 0,
onChild: (child) => this._initChild(child)
onChild: (child) => this._initChild(child),
...this._inspectParams()
};

return workerFarm(params, workerFilepath, ['runTest']);
}

_inspectParams() {
const runtimeConfig = RuntimeConfig.getInstance();

if (!runtimeConfig || !runtimeConfig.inspectMode) {
return;
}

const {inspect, inspectBrk} = runtimeConfig.inspectMode;

const inspectName = inspectBrk ? 'inspect-brk' : 'inspect';
let inspectValue = inspectBrk ? inspectBrk : inspect;

inspectValue = typeof inspectValue === 'string' ? `=${inspectValue}` : '';

return {
workerOptions: {execArgv: [`--${inspectName}${inspectValue}`]},
maxConcurrentWorkers: 1,
maxCallsPerWorker: Infinity
};
}

_initChild(child) {
child.on('message', ({event} = {}) => {
switch (event) {
Expand Down
18 changes: 18 additions & 0 deletions test/lib/cli/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -205,4 +205,22 @@ describe('cli', () => {

assert.calledWith(logger.error, 'some-error');
});

it('should turn on debug mode from cli', async () => {
onParse((parser) => parser.inspect = true);

hermioneCli.run();
await actionPromise;

assert.calledWithMatch(Hermione.prototype.run, any, {inspectMode: {inspect: true}});
});

it('should turn on debug mode from cli with params', async () => {
onParse((parser) => parser.inspectBrk = '9229');

hermioneCli.run();
await actionPromise;

assert.calledWithMatch(Hermione.prototype.run, any, {inspectMode: {inspectBrk: '9229'}});
});
});
7 changes: 5 additions & 2 deletions test/lib/hermione.js
Original file line number Diff line number Diff line change
Expand Up @@ -131,10 +131,13 @@ describe('hermione', () => {
it('should init runtime config', () => {
mkRunnerStub_();

return runHermione([], {updateRefs: true})
return runHermione([], {updateRefs: true, inspectMode: {inspect: true}})
.then(() => {
assert.calledOnce(RuntimeConfig.getInstance);
assert.calledOnceWith(RuntimeConfig.getInstance.lastCall.returnValue.extend, {updateRefs: true});
assert.calledOnceWith(
RuntimeConfig.getInstance.lastCall.returnValue.extend,
{updateRefs: true, inspectMode: {inspect: true}}
);
});
});

Expand Down
25 changes: 25 additions & 0 deletions test/lib/runner/workers.js
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,31 @@ describe('Workers', () => {
['runTest']
);
});

it('should init worker farm in debug mode', () => {
RuntimeConfig.getInstance.returns({inspectMode: {inspect: '9229'}});

mkWorkers_({
system: {
workers: 100500,
testsPerWorker: 500100
}
});

assert.calledOnceWith(workerFarm,
{
workerOptions: {execArgv: ['--inspect=9229']},
maxConcurrentWorkers: 1,
maxCallsPerWorker: Infinity,
maxConcurrentCallsPerWorker: Infinity,
autoStart: true,
maxRetries: 0,
onChild: sinon.match.func
},
sinon.match('lib/worker/index.js'),
['runTest']
);
});
});

describe('communication with worker', () => {
Expand Down

0 comments on commit 36f611a

Please sign in to comment.