@wdio/cucumber-framework 7.17.0 → 7.17.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/build/constants.d.ts +21 -0
- package/build/constants.d.ts.map +1 -0
- package/build/constants.js +32 -0
- package/build/cucumberEventListener.d.ts +37 -0
- package/build/cucumberEventListener.d.ts.map +1 -0
- package/build/cucumberEventListener.js +419 -0
- package/build/index.d.ts +87 -0
- package/build/index.d.ts.map +1 -0
- package/build/index.js +328 -0
- package/build/reporter.d.ts +33 -0
- package/build/reporter.d.ts.map +1 -0
- package/build/reporter.js +211 -0
- package/build/types.d.ts +187 -0
- package/build/types.d.ts.map +1 -0
- package/build/types.js +2 -0
- package/build/utils.d.ts +91 -0
- package/build/utils.d.ts.map +1 -0
- package/build/utils.js +210 -0
- package/package.json +5 -5
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import { CucumberOptions } from './types';
|
|
2
|
+
import { Pickle, PickleStep } from '@cucumber/messages';
|
|
3
|
+
export declare const DEFAULT_TIMEOUT = 60000;
|
|
4
|
+
export declare const DEFAULT_OPTS: CucumberOptions;
|
|
5
|
+
export declare const NOOP: () => void;
|
|
6
|
+
export declare const CUCUMBER_HOOK_DEFINITION_TYPES: readonly ["beforeTestRunHookDefinitionConfigs", "beforeTestCaseHookDefinitionConfigs", "afterTestCaseHookDefinitionConfigs", "afterTestRunHookDefinitionConfigs"];
|
|
7
|
+
/**
|
|
8
|
+
* The pickle step needs to have a keyword for the reporters, otherwise reporters like
|
|
9
|
+
* the allure or spec reporter won't show the `Given|When|Then` words
|
|
10
|
+
*/
|
|
11
|
+
export interface ReporterStep extends PickleStep {
|
|
12
|
+
keyword?: string;
|
|
13
|
+
}
|
|
14
|
+
/**
|
|
15
|
+
* The pickle scenario needs to have a rule for the reporters, otherwise reporters like
|
|
16
|
+
* the allure or spec reporter won't show the rule
|
|
17
|
+
*/
|
|
18
|
+
export interface ReporterScenario extends Pickle {
|
|
19
|
+
rule?: string;
|
|
20
|
+
}
|
|
21
|
+
//# sourceMappingURL=constants.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"constants.d.ts","sourceRoot":"","sources":["../src/constants.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,SAAS,CAAA;AACzC,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,oBAAoB,CAAA;AAEvD,eAAO,MAAM,eAAe,QAAQ,CAAA;AAEpC,eAAO,MAAM,YAAY,EAAE,eAkB1B,CAAA;AAGD,eAAO,MAAM,IAAI,YAAiB,CAAA;AAElC,eAAO,MAAM,8BAA8B,mKAKjC,CAAA;AAEV;;;GAGG;AACH,MAAM,WAAW,YAAa,SAAQ,UAAU;IAC5C,OAAO,CAAC,EAAE,MAAM,CAAA;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,gBAAiB,SAAQ,MAAM;IAC5C,IAAI,CAAC,EAAE,MAAM,CAAA;CAChB"}
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.CUCUMBER_HOOK_DEFINITION_TYPES = exports.NOOP = exports.DEFAULT_OPTS = exports.DEFAULT_TIMEOUT = void 0;
|
|
4
|
+
exports.DEFAULT_TIMEOUT = 60000;
|
|
5
|
+
exports.DEFAULT_OPTS = {
|
|
6
|
+
backtrace: false,
|
|
7
|
+
requireModule: [],
|
|
8
|
+
failAmbiguousDefinitions: false,
|
|
9
|
+
failFast: false,
|
|
10
|
+
ignoreUndefinedDefinitions: false,
|
|
11
|
+
names: [],
|
|
12
|
+
require: [],
|
|
13
|
+
order: 'defined',
|
|
14
|
+
snippets: true,
|
|
15
|
+
source: true,
|
|
16
|
+
strict: false,
|
|
17
|
+
tagExpression: '',
|
|
18
|
+
tagsInTitle: false,
|
|
19
|
+
timeout: exports.DEFAULT_TIMEOUT,
|
|
20
|
+
retry: 0,
|
|
21
|
+
scenarioLevelReporter: false,
|
|
22
|
+
featureDefaultLanguage: 'en'
|
|
23
|
+
};
|
|
24
|
+
/* istanbul ignore next */
|
|
25
|
+
const NOOP = function () { };
|
|
26
|
+
exports.NOOP = NOOP;
|
|
27
|
+
exports.CUCUMBER_HOOK_DEFINITION_TYPES = [
|
|
28
|
+
'beforeTestRunHookDefinitionConfigs',
|
|
29
|
+
'beforeTestCaseHookDefinitionConfigs',
|
|
30
|
+
'afterTestCaseHookDefinitionConfigs',
|
|
31
|
+
'afterTestRunHookDefinitionConfigs',
|
|
32
|
+
];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
import { EventEmitter } from 'events';
|
|
3
|
+
import { PickleFilter } from '@cucumber/cucumber';
|
|
4
|
+
import { Pickle, TestCase, TestStepResult, TestCaseStarted, GherkinDocument, TestStepStarted, TestStepFinished } from '@cucumber/messages';
|
|
5
|
+
import type { Capabilities } from '@wdio/types';
|
|
6
|
+
import { HookParams } from './types';
|
|
7
|
+
export default class CucumberEventListener extends EventEmitter {
|
|
8
|
+
private _pickleFilter;
|
|
9
|
+
private _gherkinDocEvents;
|
|
10
|
+
private _scenarios;
|
|
11
|
+
private _testCases;
|
|
12
|
+
private _currentTestCase?;
|
|
13
|
+
private _currentPickle?;
|
|
14
|
+
private _suiteMap;
|
|
15
|
+
private _pickleMap;
|
|
16
|
+
private _currentDoc;
|
|
17
|
+
private _startedFeatures;
|
|
18
|
+
constructor(eventBroadcaster: EventEmitter, _pickleFilter: PickleFilter);
|
|
19
|
+
usesSpecGrouping(): boolean;
|
|
20
|
+
featureIsStarted(feature: string): boolean;
|
|
21
|
+
onGherkinDocument(gherkinDocEvent: GherkinDocument): void;
|
|
22
|
+
onPickleAccepted(pickleEvent: Pickle): void;
|
|
23
|
+
onTestRunStarted(): void;
|
|
24
|
+
onTestCasePrepared(testCase: TestCase): void;
|
|
25
|
+
onTestCaseStarted(testcase: TestCaseStarted): void;
|
|
26
|
+
onTestStepStarted(testStepStartedEvent: TestStepStarted): void;
|
|
27
|
+
onTestStepFinished(testStepFinishedEvent: TestStepFinished): void;
|
|
28
|
+
onTestCaseFinished(results: TestStepResult[]): void;
|
|
29
|
+
onTestRunFinished(): void;
|
|
30
|
+
getHookParams(): HookParams | undefined;
|
|
31
|
+
/**
|
|
32
|
+
* returns a list of pickles to run based on capability tags
|
|
33
|
+
* @param caps session capabilities
|
|
34
|
+
*/
|
|
35
|
+
getPickleIds(caps: Capabilities.RemoteCapability): string[];
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=cucumberEventListener.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"cucumberEventListener.d.ts","sourceRoot":"","sources":["../src/cucumberEventListener.ts"],"names":[],"mappings":";AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AACrC,OAAO,EAAU,YAAY,EAAE,MAAM,oBAAoB,CAAA;AACzD,OAAO,EACH,MAAM,EAAE,QAAQ,EAAY,cAAc,EAAE,eAAe,EAAE,eAAe,EAC5E,eAAe,EAAE,gBAAgB,EACpC,MAAM,oBAAoB,CAAA;AAE3B,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAE/C,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAMpC,MAAM,CAAC,OAAO,OAAO,qBAAsB,SAAQ,YAAY;IAWd,OAAO,CAAC,aAAa;IAVlE,OAAO,CAAC,iBAAiB,CAAwB;IACjD,OAAO,CAAC,UAAU,CAAe;IACjC,OAAO,CAAC,UAAU,CAAiB;IACnC,OAAO,CAAC,gBAAgB,CAAC,CAAiB;IAC1C,OAAO,CAAC,cAAc,CAAC,CAAiB;IACxC,OAAO,CAAC,SAAS,CAAiC;IAClD,OAAO,CAAC,UAAU,CAAiC;IACnD,OAAO,CAAC,WAAW,CAAoC;IACvD,OAAO,CAAC,gBAAgB,CAAe;gBAE1B,gBAAgB,EAAE,YAAY,EAAU,aAAa,EAAE,YAAY;IAuChF,gBAAgB;IAIhB,gBAAgB,CAAC,OAAO,EAAE,MAAM;IAoDhC,iBAAiB,CAAE,eAAe,EAAE,eAAe;IAgCnD,gBAAgB,CAAE,WAAW,EAAE,MAAM;IAgBrC,gBAAgB;IA4EhB,kBAAkB,CAAE,QAAQ,EAAE,QAAQ;IAetC,iBAAiB,CAAE,QAAQ,EAAE,eAAe;IAkD5C,iBAAiB,CAAE,oBAAoB,EAAE,eAAe;IAoCxD,kBAAkB,CAAE,qBAAqB,EAAE,gBAAgB;IA6B3D,kBAAkB,CACd,OAAO,EAAE,cAAc,EAAE;IA4B7B,iBAAiB;IAkBjB,aAAa;IAIb;;;OAGG;IACH,YAAY,CAAE,IAAI,EAAE,YAAY,CAAC,gBAAgB;CAgBpD"}
|
|
@@ -0,0 +1,419 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __importDefault = (this && this.__importDefault) || function (mod) {
|
|
3
|
+
return (mod && mod.__esModule) ? mod : { "default": mod };
|
|
4
|
+
};
|
|
5
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
6
|
+
const events_1 = require("events");
|
|
7
|
+
const cucumber_1 = require("@cucumber/cucumber");
|
|
8
|
+
const logger_1 = __importDefault(require("@wdio/logger"));
|
|
9
|
+
const utils_1 = require("./utils");
|
|
10
|
+
const log = (0, logger_1.default)('CucumberEventListener');
|
|
11
|
+
class CucumberEventListener extends events_1.EventEmitter {
|
|
12
|
+
constructor(eventBroadcaster, _pickleFilter) {
|
|
13
|
+
super();
|
|
14
|
+
this._pickleFilter = _pickleFilter;
|
|
15
|
+
this._gherkinDocEvents = [];
|
|
16
|
+
this._scenarios = [];
|
|
17
|
+
this._testCases = [];
|
|
18
|
+
this._currentPickle = {};
|
|
19
|
+
this._suiteMap = new Map();
|
|
20
|
+
this._pickleMap = new Map();
|
|
21
|
+
this._currentDoc = { comments: [] };
|
|
22
|
+
this._startedFeatures = [];
|
|
23
|
+
let results = [];
|
|
24
|
+
eventBroadcaster.on('envelope', (envelope) => {
|
|
25
|
+
if (envelope.gherkinDocument) {
|
|
26
|
+
this.onGherkinDocument(envelope.gherkinDocument);
|
|
27
|
+
}
|
|
28
|
+
else if (envelope.testRunStarted) {
|
|
29
|
+
this.onTestRunStarted();
|
|
30
|
+
}
|
|
31
|
+
else if (envelope.pickle) {
|
|
32
|
+
this.onPickleAccepted(envelope.pickle);
|
|
33
|
+
}
|
|
34
|
+
else if (envelope.testCase) {
|
|
35
|
+
this.onTestCasePrepared(envelope.testCase);
|
|
36
|
+
}
|
|
37
|
+
else if (envelope.testCaseStarted) {
|
|
38
|
+
results = [];
|
|
39
|
+
this.onTestCaseStarted(envelope.testCaseStarted);
|
|
40
|
+
}
|
|
41
|
+
else if (envelope.testStepStarted) {
|
|
42
|
+
this.onTestStepStarted(envelope.testStepStarted);
|
|
43
|
+
}
|
|
44
|
+
else if (envelope.testStepFinished) {
|
|
45
|
+
results.push(envelope.testStepFinished.testStepResult);
|
|
46
|
+
this.onTestStepFinished(envelope.testStepFinished);
|
|
47
|
+
}
|
|
48
|
+
else if (envelope.testCaseFinished) {
|
|
49
|
+
/**
|
|
50
|
+
* only store result if step isn't retried
|
|
51
|
+
*/
|
|
52
|
+
if (envelope.testCaseFinished.willBeRetried) {
|
|
53
|
+
return log.debug(`test case with id ${envelope.testCaseFinished.testCaseStartedId} will be retried, ignoring result`);
|
|
54
|
+
}
|
|
55
|
+
this.onTestCaseFinished(results);
|
|
56
|
+
}
|
|
57
|
+
else if (envelope.testRunFinished) {
|
|
58
|
+
this.onTestRunFinished();
|
|
59
|
+
}
|
|
60
|
+
else if (envelope.source) {
|
|
61
|
+
// do nothing for step definition patterns
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
/* istanbul ignore next */
|
|
65
|
+
log.debug(`Unknown envelope received: ${JSON.stringify(envelope, null, 4)}`);
|
|
66
|
+
}
|
|
67
|
+
});
|
|
68
|
+
}
|
|
69
|
+
usesSpecGrouping() {
|
|
70
|
+
return this._gherkinDocEvents.length > 1;
|
|
71
|
+
}
|
|
72
|
+
featureIsStarted(feature) {
|
|
73
|
+
return this._startedFeatures.includes(feature);
|
|
74
|
+
}
|
|
75
|
+
// {
|
|
76
|
+
// "gherkinDocument": {
|
|
77
|
+
// "uri": "/Users/christianbromann/Sites/WebdriverIO/webdriverio/examples/wdio/cucumber/features/my-feature.feature",
|
|
78
|
+
// "feature": {
|
|
79
|
+
// "location": {
|
|
80
|
+
// "line": 1,
|
|
81
|
+
// "column": 1
|
|
82
|
+
// },
|
|
83
|
+
// "language": "en",
|
|
84
|
+
// "keyword": "Feature",
|
|
85
|
+
// "name": "Example feature",
|
|
86
|
+
// "description": " As a user of WebdriverIO\n I should be able to use different commands\n to get informations about elements on the page",
|
|
87
|
+
// "children": [
|
|
88
|
+
// {
|
|
89
|
+
// "scenario": {
|
|
90
|
+
// "location": {
|
|
91
|
+
// "line": 6,
|
|
92
|
+
// "column": 3
|
|
93
|
+
// },
|
|
94
|
+
// "keyword": "Scenario",
|
|
95
|
+
// "name": "Get size of an element",
|
|
96
|
+
// "steps": [
|
|
97
|
+
// {
|
|
98
|
+
// "location": {
|
|
99
|
+
// "line": 7,
|
|
100
|
+
// "column": 5
|
|
101
|
+
// },
|
|
102
|
+
// "keyword": "Given ",
|
|
103
|
+
// "text": "I go on the website \"https://github.com/\"",
|
|
104
|
+
// "id": "0"
|
|
105
|
+
// },
|
|
106
|
+
// {
|
|
107
|
+
// "location": {
|
|
108
|
+
// "line": 8,
|
|
109
|
+
// "column": 5
|
|
110
|
+
// },
|
|
111
|
+
// "keyword": "Then ",
|
|
112
|
+
// "text": "should the element \".header-logged-out a\" be 32px wide and 35px high",
|
|
113
|
+
// "id": "1"
|
|
114
|
+
// }
|
|
115
|
+
// ],
|
|
116
|
+
// "id": "2"
|
|
117
|
+
// }
|
|
118
|
+
// }
|
|
119
|
+
// ]
|
|
120
|
+
// }
|
|
121
|
+
// }
|
|
122
|
+
// }
|
|
123
|
+
onGherkinDocument(gherkinDocEvent) {
|
|
124
|
+
this._currentPickle = { uri: gherkinDocEvent.uri, feature: gherkinDocEvent.feature };
|
|
125
|
+
this._gherkinDocEvents.push(gherkinDocEvent);
|
|
126
|
+
}
|
|
127
|
+
// {
|
|
128
|
+
// "pickle": {
|
|
129
|
+
// "id": "5",
|
|
130
|
+
// "uri": "/Users/christianbromann/Sites/WebdriverIO/webdriverio/examples/wdio/cucumber/features/my-feature.feature",
|
|
131
|
+
// "name": "Get size of an element",
|
|
132
|
+
// "language": "en",
|
|
133
|
+
// "steps": [
|
|
134
|
+
// {
|
|
135
|
+
// "text": "I go on the website \"https://github.com/\"",
|
|
136
|
+
// "id": "3",
|
|
137
|
+
// "astNodeIds": [
|
|
138
|
+
// "0"
|
|
139
|
+
// ]
|
|
140
|
+
// },
|
|
141
|
+
// {
|
|
142
|
+
// "text": "should the element \".header-logged-out a\" be 32px wide and 35px high",
|
|
143
|
+
// "id": "4",
|
|
144
|
+
// "astNodeIds": [
|
|
145
|
+
// "1"
|
|
146
|
+
// ]
|
|
147
|
+
// }
|
|
148
|
+
// ],
|
|
149
|
+
// "astNodeIds": [
|
|
150
|
+
// "2"
|
|
151
|
+
// ]
|
|
152
|
+
// }
|
|
153
|
+
// }
|
|
154
|
+
onPickleAccepted(pickleEvent) {
|
|
155
|
+
const id = this._suiteMap.size.toString();
|
|
156
|
+
this._suiteMap.set(pickleEvent.id, id);
|
|
157
|
+
this._pickleMap.set(id, pickleEvent.astNodeIds[0]);
|
|
158
|
+
const scenario = { ...pickleEvent, id };
|
|
159
|
+
this._scenarios.push(scenario);
|
|
160
|
+
}
|
|
161
|
+
// {
|
|
162
|
+
// "testRunStarted": {
|
|
163
|
+
// "timestamp": {
|
|
164
|
+
// "seconds": "1609002214",
|
|
165
|
+
// "nanos": 447000000
|
|
166
|
+
// }
|
|
167
|
+
// }
|
|
168
|
+
// }
|
|
169
|
+
onTestRunStarted() {
|
|
170
|
+
if (this.usesSpecGrouping()) {
|
|
171
|
+
return;
|
|
172
|
+
}
|
|
173
|
+
const doc = this._gherkinDocEvents[this._gherkinDocEvents.length - 1];
|
|
174
|
+
this.emit('before-feature', doc.uri, doc.feature);
|
|
175
|
+
}
|
|
176
|
+
// {
|
|
177
|
+
// "testCase": {
|
|
178
|
+
// "id": "15",
|
|
179
|
+
// "pickleId": "5",
|
|
180
|
+
// "testSteps": [
|
|
181
|
+
// {
|
|
182
|
+
// "id": "16",
|
|
183
|
+
// "hookId": "13"
|
|
184
|
+
// },
|
|
185
|
+
// {
|
|
186
|
+
// "id": "17",
|
|
187
|
+
// "pickleStepId": "3",
|
|
188
|
+
// "stepDefinitionIds": [
|
|
189
|
+
// "6"
|
|
190
|
+
// ],
|
|
191
|
+
// "stepMatchArgumentsLists": [
|
|
192
|
+
// {
|
|
193
|
+
// "stepMatchArguments": [
|
|
194
|
+
// {
|
|
195
|
+
// "group": {
|
|
196
|
+
// "start": 21,
|
|
197
|
+
// "value": "https://github.com/"
|
|
198
|
+
// }
|
|
199
|
+
// }
|
|
200
|
+
// ]
|
|
201
|
+
// }
|
|
202
|
+
// ]
|
|
203
|
+
// },
|
|
204
|
+
// {
|
|
205
|
+
// "id": "18",
|
|
206
|
+
// "pickleStepId": "4",
|
|
207
|
+
// "stepDefinitionIds": [
|
|
208
|
+
// "8"
|
|
209
|
+
// ],
|
|
210
|
+
// "stepMatchArgumentsLists": [
|
|
211
|
+
// {
|
|
212
|
+
// "stepMatchArguments": [
|
|
213
|
+
// {
|
|
214
|
+
// "group": {
|
|
215
|
+
// "start": 20,
|
|
216
|
+
// "value": ".header-logged-out a"
|
|
217
|
+
// }
|
|
218
|
+
// },
|
|
219
|
+
// {
|
|
220
|
+
// "parameterTypeName": "int",
|
|
221
|
+
// "group": {
|
|
222
|
+
// "start": 45,
|
|
223
|
+
// "value": "32"
|
|
224
|
+
// }
|
|
225
|
+
// },
|
|
226
|
+
// {
|
|
227
|
+
// "parameterTypeName": "int",
|
|
228
|
+
// "group": {
|
|
229
|
+
// "start": 59,
|
|
230
|
+
// "value": "35"
|
|
231
|
+
// }
|
|
232
|
+
// }
|
|
233
|
+
// ]
|
|
234
|
+
// }
|
|
235
|
+
// ]
|
|
236
|
+
// },
|
|
237
|
+
// {
|
|
238
|
+
// "id": "19",
|
|
239
|
+
// "hookId": "11"
|
|
240
|
+
// }
|
|
241
|
+
// ]
|
|
242
|
+
// }
|
|
243
|
+
// }
|
|
244
|
+
onTestCasePrepared(testCase) {
|
|
245
|
+
this._testCases.push(testCase);
|
|
246
|
+
}
|
|
247
|
+
// {
|
|
248
|
+
// "testCaseStarted": {
|
|
249
|
+
// "timestamp": {
|
|
250
|
+
// "seconds": "1609002214",
|
|
251
|
+
// "nanos": 453000000
|
|
252
|
+
// },
|
|
253
|
+
// "attempt": 0,
|
|
254
|
+
// "testCaseId": "15",
|
|
255
|
+
// "id": "20"
|
|
256
|
+
// }
|
|
257
|
+
// }
|
|
258
|
+
onTestCaseStarted(testcase) {
|
|
259
|
+
this._currentTestCase = testcase;
|
|
260
|
+
const tc = this._testCases.find(tc => tc.id === testcase.testCaseId);
|
|
261
|
+
const scenario = this._scenarios.find(sc => sc.id === this._suiteMap.get(tc === null || tc === void 0 ? void 0 : tc.pickleId));
|
|
262
|
+
/* istanbul ignore if */
|
|
263
|
+
if (!scenario) {
|
|
264
|
+
return;
|
|
265
|
+
}
|
|
266
|
+
const doc = this._gherkinDocEvents.find(gde => gde.uri === (scenario === null || scenario === void 0 ? void 0 : scenario.uri));
|
|
267
|
+
const uri = doc === null || doc === void 0 ? void 0 : doc.uri;
|
|
268
|
+
const feature = doc === null || doc === void 0 ? void 0 : doc.feature;
|
|
269
|
+
if (this._currentDoc.uri && this._currentDoc.feature && this.usesSpecGrouping() && doc != this._currentDoc && this.featureIsStarted(this._currentDoc.uri)) {
|
|
270
|
+
this.emit('after-feature', this._currentDoc.uri, this._currentDoc.feature);
|
|
271
|
+
}
|
|
272
|
+
if (this.usesSpecGrouping() && doc && doc.uri && !this.featureIsStarted(doc.uri)) {
|
|
273
|
+
this.emit('before-feature', doc.uri, doc.feature);
|
|
274
|
+
this._currentDoc = doc;
|
|
275
|
+
this._startedFeatures.push(doc.uri);
|
|
276
|
+
}
|
|
277
|
+
/**
|
|
278
|
+
* The reporters need to have the keywords, like `Given|When|Then`. They are NOT available
|
|
279
|
+
* on the scenario, they ARE on the feature.
|
|
280
|
+
* This will aad them
|
|
281
|
+
*/
|
|
282
|
+
if (scenario.steps && feature) {
|
|
283
|
+
scenario.steps = (0, utils_1.addKeywordToStep)(scenario.steps, feature);
|
|
284
|
+
}
|
|
285
|
+
this._currentPickle = { uri, feature, scenario };
|
|
286
|
+
let reporterScenario = scenario;
|
|
287
|
+
reporterScenario.rule = (0, utils_1.getRule)(doc === null || doc === void 0 ? void 0 : doc.feature, this._pickleMap.get(scenario.id));
|
|
288
|
+
this.emit('before-scenario', scenario.uri, doc === null || doc === void 0 ? void 0 : doc.feature, reporterScenario);
|
|
289
|
+
}
|
|
290
|
+
// {
|
|
291
|
+
// "testStepStarted": {
|
|
292
|
+
// "timestamp": {
|
|
293
|
+
// "seconds": "1609002214",
|
|
294
|
+
// "nanos": 454000000
|
|
295
|
+
// },
|
|
296
|
+
// "testStepId": "16",
|
|
297
|
+
// "testCaseStartedId": "20"
|
|
298
|
+
// }
|
|
299
|
+
// }
|
|
300
|
+
onTestStepStarted(testStepStartedEvent) {
|
|
301
|
+
var _a, _b;
|
|
302
|
+
const testcase = this._testCases.find((testcase) => this._currentTestCase && testcase.id === this._currentTestCase.testCaseId);
|
|
303
|
+
const scenario = this._scenarios.find(sc => sc.id === this._suiteMap.get(testcase === null || testcase === void 0 ? void 0 : testcase.pickleId));
|
|
304
|
+
const teststep = (_a = testcase === null || testcase === void 0 ? void 0 : testcase.testSteps) === null || _a === void 0 ? void 0 : _a.find((step) => step.id === testStepStartedEvent.testStepId);
|
|
305
|
+
const step = ((_b = scenario === null || scenario === void 0 ? void 0 : scenario.steps) === null || _b === void 0 ? void 0 : _b.find((s) => s.id === (teststep === null || teststep === void 0 ? void 0 : teststep.pickleStepId))) || teststep;
|
|
306
|
+
const doc = this._gherkinDocEvents.find(gde => gde.uri === (scenario === null || scenario === void 0 ? void 0 : scenario.uri));
|
|
307
|
+
const uri = doc === null || doc === void 0 ? void 0 : doc.uri;
|
|
308
|
+
const feature = doc === null || doc === void 0 ? void 0 : doc.feature;
|
|
309
|
+
/* istanbul ignore if */
|
|
310
|
+
if (!step) {
|
|
311
|
+
return;
|
|
312
|
+
}
|
|
313
|
+
this._currentPickle = { uri, feature, scenario, step };
|
|
314
|
+
this.emit('before-step', uri, feature, scenario, step);
|
|
315
|
+
}
|
|
316
|
+
// {
|
|
317
|
+
// "testStepFinished": {
|
|
318
|
+
// "testStepResult": {
|
|
319
|
+
// "status": "PASSED",
|
|
320
|
+
// "duration": {
|
|
321
|
+
// "seconds": "0",
|
|
322
|
+
// "nanos": 1000000
|
|
323
|
+
// }
|
|
324
|
+
// },
|
|
325
|
+
// "timestamp": {
|
|
326
|
+
// "seconds": "1609002214",
|
|
327
|
+
// "nanos": 455000000
|
|
328
|
+
// },
|
|
329
|
+
// "testStepId": "16",
|
|
330
|
+
// "testCaseStartedId": "20"
|
|
331
|
+
// }
|
|
332
|
+
// }
|
|
333
|
+
onTestStepFinished(testStepFinishedEvent) {
|
|
334
|
+
var _a, _b;
|
|
335
|
+
const testcase = this._testCases.find((testcase) => { var _a; return testcase.id === ((_a = this._currentTestCase) === null || _a === void 0 ? void 0 : _a.testCaseId); });
|
|
336
|
+
const scenario = this._scenarios.find(sc => sc.id === this._suiteMap.get(testcase === null || testcase === void 0 ? void 0 : testcase.pickleId));
|
|
337
|
+
const teststep = (_a = testcase === null || testcase === void 0 ? void 0 : testcase.testSteps) === null || _a === void 0 ? void 0 : _a.find((step) => step.id === testStepFinishedEvent.testStepId);
|
|
338
|
+
const step = ((_b = scenario === null || scenario === void 0 ? void 0 : scenario.steps) === null || _b === void 0 ? void 0 : _b.find((s) => s.id === (teststep === null || teststep === void 0 ? void 0 : teststep.pickleStepId))) || teststep;
|
|
339
|
+
const result = testStepFinishedEvent.testStepResult;
|
|
340
|
+
const doc = this._gherkinDocEvents.find(gde => gde.uri === (scenario === null || scenario === void 0 ? void 0 : scenario.uri));
|
|
341
|
+
const uri = doc === null || doc === void 0 ? void 0 : doc.uri;
|
|
342
|
+
const feature = doc === null || doc === void 0 ? void 0 : doc.feature;
|
|
343
|
+
/* istanbul ignore if */
|
|
344
|
+
if (!step) {
|
|
345
|
+
return;
|
|
346
|
+
}
|
|
347
|
+
this.emit('after-step', uri, feature, scenario, step, result);
|
|
348
|
+
delete this._currentPickle;
|
|
349
|
+
}
|
|
350
|
+
// {
|
|
351
|
+
// "testCaseFinished": {
|
|
352
|
+
// "timestamp": {
|
|
353
|
+
// "seconds": "1609002223",
|
|
354
|
+
// "nanos": 913000000
|
|
355
|
+
// },
|
|
356
|
+
// "testCaseStartedId": "20"
|
|
357
|
+
// }
|
|
358
|
+
// }
|
|
359
|
+
onTestCaseFinished(results) {
|
|
360
|
+
const tc = this._testCases.find(tc => { var _a; return tc.id === ((_a = this._currentTestCase) === null || _a === void 0 ? void 0 : _a.testCaseId); });
|
|
361
|
+
const scenario = this._scenarios.find(sc => sc.id === this._suiteMap.get(tc === null || tc === void 0 ? void 0 : tc.pickleId));
|
|
362
|
+
/* istanbul ignore if */
|
|
363
|
+
if (!scenario) {
|
|
364
|
+
return;
|
|
365
|
+
}
|
|
366
|
+
/**
|
|
367
|
+
* propagate the first non passing result or the last one
|
|
368
|
+
*/
|
|
369
|
+
const finalResult = results.find((r) => r.status !== cucumber_1.Status.PASSED) || results.pop();
|
|
370
|
+
const doc = this._gherkinDocEvents.find(gde => gde.uri === (scenario === null || scenario === void 0 ? void 0 : scenario.uri));
|
|
371
|
+
const uri = doc === null || doc === void 0 ? void 0 : doc.uri;
|
|
372
|
+
const feature = doc === null || doc === void 0 ? void 0 : doc.feature;
|
|
373
|
+
this._currentPickle = { uri, feature, scenario };
|
|
374
|
+
this.emit('after-scenario', doc === null || doc === void 0 ? void 0 : doc.uri, doc === null || doc === void 0 ? void 0 : doc.feature, scenario, finalResult);
|
|
375
|
+
}
|
|
376
|
+
// testRunFinishedEvent = {
|
|
377
|
+
// "timestamp": {
|
|
378
|
+
// "seconds": "1609000747",
|
|
379
|
+
// "nanos": 793000000
|
|
380
|
+
// }
|
|
381
|
+
// }
|
|
382
|
+
onTestRunFinished() {
|
|
383
|
+
delete this._currentTestCase;
|
|
384
|
+
if (this.usesSpecGrouping()) {
|
|
385
|
+
this.emit('after-feature', this._currentDoc.uri, this._currentDoc.feature);
|
|
386
|
+
return;
|
|
387
|
+
}
|
|
388
|
+
const gherkinDocEvent = this._gherkinDocEvents.pop(); // see .push() in `handleBeforeFeature()`
|
|
389
|
+
/* istanbul ignore if */
|
|
390
|
+
if (!gherkinDocEvent) {
|
|
391
|
+
return;
|
|
392
|
+
}
|
|
393
|
+
this.emit('after-feature', gherkinDocEvent.uri, gherkinDocEvent.feature);
|
|
394
|
+
}
|
|
395
|
+
getHookParams() {
|
|
396
|
+
return this._currentPickle;
|
|
397
|
+
}
|
|
398
|
+
/**
|
|
399
|
+
* returns a list of pickles to run based on capability tags
|
|
400
|
+
* @param caps session capabilities
|
|
401
|
+
*/
|
|
402
|
+
getPickleIds(caps) {
|
|
403
|
+
const gherkinDocument = this._gherkinDocEvents[this._gherkinDocEvents.length - 1];
|
|
404
|
+
return [...this._suiteMap.entries()]
|
|
405
|
+
/**
|
|
406
|
+
* match based on capability tags
|
|
407
|
+
*/
|
|
408
|
+
.filter(([, fakeId]) => (0, utils_1.filterPickles)(caps, this._scenarios.find(s => s.id === fakeId)))
|
|
409
|
+
/**
|
|
410
|
+
* match based on Cucumber pickle filter
|
|
411
|
+
*/
|
|
412
|
+
.filter(([, fakeId]) => this._pickleFilter.matches({
|
|
413
|
+
gherkinDocument,
|
|
414
|
+
pickle: this._scenarios.find(s => s.id === fakeId)
|
|
415
|
+
}))
|
|
416
|
+
.map(([id]) => id);
|
|
417
|
+
}
|
|
418
|
+
}
|
|
419
|
+
exports.default = CucumberEventListener;
|
package/build/index.d.ts
ADDED
|
@@ -0,0 +1,87 @@
|
|
|
1
|
+
/// <reference types="node" />
|
|
2
|
+
/// <reference types="expect-webdriverio/types/standalone" />
|
|
3
|
+
import { EventEmitter } from 'events';
|
|
4
|
+
import * as Cucumber from '@cucumber/cucumber';
|
|
5
|
+
import { After, AfterAll, AfterStep, Before, BeforeAll, BeforeStep, DataTable, defineParameterType, defineStep, Given, setDefaultTimeout, setDefinitionFunctionWrapper, setWorldConstructor, World, Then, When } from '@cucumber/cucumber';
|
|
6
|
+
import { Long } from 'long';
|
|
7
|
+
import type { Capabilities, Options } from '@wdio/types';
|
|
8
|
+
import type ExpectWebdriverIO from 'expect-webdriverio';
|
|
9
|
+
import { CucumberOptions, StepDefinitionOptions, HookFunctionExtension as HookFunctionExtensionImport } from './types';
|
|
10
|
+
declare class CucumberAdapter {
|
|
11
|
+
private _cid;
|
|
12
|
+
private _config;
|
|
13
|
+
private _specs;
|
|
14
|
+
private _capabilities;
|
|
15
|
+
private _reporter;
|
|
16
|
+
private _cwd;
|
|
17
|
+
private _newId;
|
|
18
|
+
private _cucumberOpts;
|
|
19
|
+
private _hasTests;
|
|
20
|
+
private _cucumberFeaturesWithLineNumbers;
|
|
21
|
+
private _eventBroadcaster;
|
|
22
|
+
private _cucumberReporter;
|
|
23
|
+
private _eventDataCollector;
|
|
24
|
+
private _pickleFilter;
|
|
25
|
+
getHookParams?: Function;
|
|
26
|
+
/**
|
|
27
|
+
* make sure TS loads `@types/long` otherwise it won't find it in `@cucumber/messages`
|
|
28
|
+
* see also https://github.com/cucumber/cucumber-js/issues/1491
|
|
29
|
+
*/
|
|
30
|
+
never?: Long;
|
|
31
|
+
constructor(_cid: string, _config: Options.Testrunner, _specs: string[], _capabilities: Capabilities.RemoteCapability, _reporter: EventEmitter);
|
|
32
|
+
init(): Promise<this>;
|
|
33
|
+
hasTests(): boolean;
|
|
34
|
+
run(): Promise<number>;
|
|
35
|
+
/**
|
|
36
|
+
* Transpilation https://github.com/cucumber/cucumber-js/blob/master/docs/cli.md#transpilation
|
|
37
|
+
* Usage: `['module']`
|
|
38
|
+
* we extend it a bit with ability to init and pass configuration to modules.
|
|
39
|
+
* Pass an array with path to module and its configuration instead:
|
|
40
|
+
* Usage: `[['module', {}]]`
|
|
41
|
+
* Or pass your own function
|
|
42
|
+
* Usage: `[() => { require('@babel/register')({ ignore: [] }) }]`
|
|
43
|
+
*/
|
|
44
|
+
registerRequiredModules(): void;
|
|
45
|
+
requiredFiles(): string[];
|
|
46
|
+
loadSpecFiles(): void;
|
|
47
|
+
/**
|
|
48
|
+
* set `beforeFeature`, `afterFeature`, `beforeScenario`, `afterScenario`, 'beforeStep', 'afterStep'
|
|
49
|
+
* @param {object} config config
|
|
50
|
+
*/
|
|
51
|
+
addWdioHooks(config: Options.Testrunner): void;
|
|
52
|
+
/**
|
|
53
|
+
* wraps step definition code with sync/async runner with a retry option
|
|
54
|
+
* @param {object} config
|
|
55
|
+
*/
|
|
56
|
+
wrapSteps(config: Options.Testrunner): void;
|
|
57
|
+
/**
|
|
58
|
+
* wrap step definition to enable retry ability
|
|
59
|
+
* @param {Function} code step definition
|
|
60
|
+
* @param {boolean} isStep
|
|
61
|
+
* @param {object} config
|
|
62
|
+
* @param {string} cid cid
|
|
63
|
+
* @param {StepDefinitionOptions} options
|
|
64
|
+
* @param {Function} getHookParams step definition
|
|
65
|
+
* @return {Function} wrapped step definition for sync WebdriverIO code
|
|
66
|
+
*/
|
|
67
|
+
wrapStep(code: Function, isStep: boolean, config: Options.Testrunner, cid: string, options: StepDefinitionOptions, getHookParams: Function): (this: Cucumber.World, ...args: any[]) => Promise<unknown>;
|
|
68
|
+
}
|
|
69
|
+
declare const adapterFactory: {
|
|
70
|
+
init?: Function;
|
|
71
|
+
};
|
|
72
|
+
export default adapterFactory;
|
|
73
|
+
export { CucumberAdapter, adapterFactory, After, AfterAll, AfterStep, Before, BeforeAll, BeforeStep, DataTable, defineParameterType, defineStep, Given, setDefaultTimeout, setDefinitionFunctionWrapper, setWorldConstructor, Then, When, World };
|
|
74
|
+
declare global {
|
|
75
|
+
namespace WebdriverIO {
|
|
76
|
+
interface CucumberOpts extends CucumberOptions {
|
|
77
|
+
}
|
|
78
|
+
interface HookFunctionExtension extends HookFunctionExtensionImport {
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
namespace NodeJS {
|
|
82
|
+
interface Global {
|
|
83
|
+
expect: ExpectWebdriverIO.Expect;
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
}
|
|
87
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AACA,OAAO,EAAE,YAAY,EAAE,MAAM,QAAQ,CAAA;AAMrC,OAAO,KAAK,QAAQ,MAAM,oBAAoB,CAAA;AAC9C,OAAO,EACH,KAAK,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,SAAS,EACT,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,UAAU,EACV,KAAK,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,mBAAmB,EACnB,KAAK,EACL,IAAI,EACJ,IAAI,EACP,MAAM,oBAAoB,CAAA;AAK3B,OAAO,EAAE,IAAI,EAAE,MAAM,MAAM,CAAA;AAI3B,OAAO,KAAK,EAAE,YAAY,EAAE,OAAO,EAAc,MAAM,aAAa,CAAA;AACpE,OAAO,KAAK,iBAAiB,MAAM,oBAAoB,CAAA;AAIvD,OAAO,EAAE,eAAe,EAAE,qBAAqB,EAAE,qBAAqB,IAAI,2BAA2B,EAAE,MAAM,SAAS,CAAA;AAatH,cAAM,eAAe;IAoBb,OAAO,CAAC,IAAI;IACZ,OAAO,CAAC,OAAO;IACf,OAAO,CAAC,MAAM;IACd,OAAO,CAAC,aAAa;IACrB,OAAO,CAAC,SAAS;IAvBrB,OAAO,CAAC,IAAI,CAAgB;IAC5B,OAAO,CAAC,MAAM,CAAiB;IAC/B,OAAO,CAAC,aAAa,CAA2B;IAChD,OAAO,CAAC,SAAS,CAAS;IAC1B,OAAO,CAAC,gCAAgC,CAAU;IAClD,OAAO,CAAC,iBAAiB,CAAc;IACvC,OAAO,CAAC,iBAAiB,CAAkB;IAC3C,OAAO,CAAC,mBAAmB,CAAoB;IAC/C,OAAO,CAAC,aAAa,CAAuB;IAE5C,aAAa,CAAC,EAAE,QAAQ,CAAA;IAExB;;;OAGG;IACH,KAAK,CAAC,EAAE,IAAI,CAAA;gBAGA,IAAI,EAAE,MAAM,EACZ,OAAO,EAAE,OAAO,CAAC,UAAU,EAC3B,MAAM,EAAE,MAAM,EAAE,EAChB,aAAa,EAAE,YAAY,CAAC,gBAAgB,EAC5C,SAAS,EAAE,YAAY;IA0B7B,IAAI;IAmCV,QAAQ;IAIF,GAAG;IAkET;;;;;;;;OAQG;IACH,uBAAuB;IAYvB,aAAa;IAUb,aAAa;IAsBb;;;OAGG;IACH,YAAY,CAAC,MAAM,EAAE,OAAO,CAAC,UAAU;IAkDvC;;;OAGG;IACH,SAAS,CAAE,MAAM,EAAE,OAAO,CAAC,UAAU;IAwBrC;;;;;;;;;OASG;IACH,QAAQ,CACJ,IAAI,EAAE,QAAQ,EACd,MAAM,EAAE,OAAO,EACf,MAAM,EAAE,OAAO,CAAC,UAAU,EAC1B,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,qBAAqB,EAC9B,aAAa,EAAE,QAAQ,UAEA,cAAc,WAAW,GAAG,EAAE;CAkB5D;AAGD,QAAA,MAAM,cAAc,EAAE;IAAE,IAAI,CAAC,EAAE,QAAQ,CAAA;CAAO,CAAA;AAa9C,eAAe,cAAc,CAAA;AAC7B,OAAO,EACH,eAAe,EACf,cAAc,EACd,KAAK,EACL,QAAQ,EACR,SAAS,EACT,MAAM,EACN,SAAS,EACT,UAAU,EACV,SAAS,EACT,mBAAmB,EACnB,UAAU,EACV,KAAK,EACL,iBAAiB,EACjB,4BAA4B,EAC5B,mBAAmB,EACnB,IAAI,EACJ,IAAI,EACJ,KAAK,EACR,CAAA;AAED,OAAO,CAAC,MAAM,CAAC;IACX,UAAU,WAAW,CAAC;QAClB,UAAU,YAAa,SAAQ,eAAe;SAAG;QACjD,UAAU,qBAAsB,SAAQ,2BAA2B;SAAG;KACzE;IACD,UAAU,MAAM,CAAC;QACb,UAAU,MAAM;YACZ,MAAM,EAAE,iBAAiB,CAAC,MAAM,CAAA;SACnC;KACJ;CACJ"}
|