This repository has been archived by the owner on Sep 21, 2022. It is now read-only.
/
insistent-suite-runner.js
100 lines (77 loc) 路 2.83 KB
/
insistent-suite-runner.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
'use strict';
const _ = require('lodash');
const SuiteRunner = require('./suite-runner');
const RegularSuiteRunner = require('./regular-suite-runner');
const SuiteCollection = require('../../suite-collection');
const Events = require('../../constants/events');
const NoRefImageError = require('../../errors/no-ref-image-error');
module.exports = class InsistentSuiteRunner extends SuiteRunner {
static create(suite, browserAgent, config) {
return new InsistentSuiteRunner(suite, browserAgent, config);
}
constructor(suite, browserAgent, config) {
super(suite, browserAgent);
this._config = config;
this._retriesPerformed = 0;
}
_doRun(stateProcessor) {
this._suiteRunner = this._initSuiteRunner();
this._statesToRetry = [];
return this._suiteRunner.run(stateProcessor)
.then(() => this._retry(stateProcessor));
}
_initSuiteRunner() {
this._disablePassedStates(this._suite);
const runner = RegularSuiteRunner.create(this._suite, this._browserAgent);
this._handleEvent(runner, Events.ERROR, (e) => e instanceof NoRefImageError);
this._handleEvent(runner, Events.TEST_RESULT, (r) => r.equal);
this.passthroughEvent(runner, [
Events.BEGIN_STATE,
Events.SKIP_STATE,
Events.END_STATE,
Events.UPDATE_RESULT
]);
return runner;
}
_handleEvent(runner, event, shouldPassthrough) {
runner.on(event, (data) => {
if (shouldPassthrough(data) || !this._submitForRetry(data)) {
this._emit(event, data);
}
});
}
_retry(stateProcessor) {
if (_.isEmpty(this._statesToRetry) || this._cancelled) {
return;
}
++this._retriesPerformed;
return this._doRun(stateProcessor);
}
_disablePassedStates(suite) {
if (_.isEmpty(this._statesToRetry)) {
return;
}
const browser = this._browserAgent.browserId;
const collection = new SuiteCollection([suite]);
suite.states.forEach((state) => collection.disable(suite, {state: state.name}));
this._statesToRetry.forEach((state) => collection.enable(suite, {state, browser}));
}
_shouldRetry(data) {
if (typeof this._config.shouldRetry === 'function') {
return this._config.shouldRetry(data);
}
return data.retriesLeft > 0;
}
_submitForRetry(data) {
Object.assign(data, {
attempt: this._retriesPerformed,
retriesLeft: this._config.retry - this._retriesPerformed
});
if (!this._shouldRetry(data)) {
return false;
}
this._statesToRetry = this._statesToRetry.concat(data.state.name);
this._emit(Events.RETRY, data);
return true;
}
};