@qavajs/playwright-runner-adapter 2.2.0 → 2.3.0
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/CHANGELOG.md +3 -0
- package/adapter/PlaywrightWorld.js +1 -0
- package/adapter/PlaywrightWorld.js.map +1 -1
- package/adapter/cucumberAdapter.js +129 -163
- package/adapter/cucumberAdapter.js.map +1 -1
- package/adapter/js/PlaywrightWorld.js +1 -0
- package/adapter/js/cucumberAdapter.js +129 -163
- package/package.json +1 -1
- package/src/PlaywrightWorld.ts +1 -0
- package/src/cucumberAdapter.ts +214 -207
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,9 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|
|
14
14
|
|
|
15
15
|
:microscope: - experimental
|
|
16
16
|
|
|
17
|
+
## [2.3.0]
|
|
18
|
+
- :rocket: simplified adapter by moving hook into test
|
|
19
|
+
|
|
17
20
|
## [2.2.0]
|
|
18
21
|
- :rocket: added `request` into default fixture import
|
|
19
22
|
- :beetle: fixed `attach` method type
|
|
@@ -18,6 +18,7 @@ class TestWorld {
|
|
|
18
18
|
this.attach = options.attach;
|
|
19
19
|
this.parameters = options.parameters;
|
|
20
20
|
this.supportCodeLibrary = options.supportCodeLibrary;
|
|
21
|
+
this.config = options.config;
|
|
21
22
|
}
|
|
22
23
|
async executeStep(text, extraParam) {
|
|
23
24
|
const steps = this.supportCodeLibrary.stepDefinitions.filter((s) => s.matchesStepName(text));
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"PlaywrightWorld.js","sourceRoot":"","sources":["../src/PlaywrightWorld.ts"],"names":[],"mappings":";;;AAAA,2CAAkG;AAElG;;GAEG;AACH,MAAa,SAAS;IAClB,GAAG,CAAuB;IAC1B,MAAM,CAAoF;IAC1F,UAAU,CAAU;IACpB,MAAM,CAAM;IACZ,kBAAkB,CAAO;IACzB,IAAI,GAAG,WAAI,CAAC;IACZ,MAAM,GAAG,aAAM,CAAC;IAEhB,YAAY,OAAY;QACpB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;
|
|
1
|
+
{"version":3,"file":"PlaywrightWorld.js","sourceRoot":"","sources":["../src/PlaywrightWorld.ts"],"names":[],"mappings":";;;AAAA,2CAAkG;AAElG;;GAEG;AACH,MAAa,SAAS;IAClB,GAAG,CAAuB;IAC1B,MAAM,CAAoF;IAC1F,UAAU,CAAU;IACpB,MAAM,CAAM;IACZ,kBAAkB,CAAO;IACzB,IAAI,GAAG,WAAI,CAAC;IACZ,MAAM,GAAG,aAAM,CAAC;IAEhB,YAAY,OAAY;QACpB,IAAI,CAAC,GAAG,GAAG,OAAO,CAAC,GAAG,CAAC;QACvB,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;QAC7B,IAAI,CAAC,UAAU,GAAG,OAAO,CAAC,UAAU,CAAC;QACrC,IAAI,CAAC,kBAAkB,GAAG,OAAO,CAAC,kBAAkB,CAAC;QACrD,IAAI,CAAC,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC;IACjC,CAAC;IAED,KAAK,CAAC,WAAW,CAAY,IAAY,EAAE,UAAgB;QACvD,MAAM,KAAK,GAAG,IAAI,CAAC,kBAAkB,CAAC,eAAe,CAAC,MAAM,CAAC,CAAC,CAAM,EAAE,EAAE,CAAC,CAAC,CAAC,eAAe,CAAC,IAAI,CAAC,CAAC,CAAC;QAClG,IAAI,KAAK,CAAC,MAAM,KAAK,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,kBAAkB,CAAC,CAAC;QACzE,IAAI,KAAK,CAAC,MAAM,GAAG,CAAC;YAAE,MAAM,IAAI,KAAK,CAAC,SAAS,IAAI,qCAAqC,CAAC,CAAC;QAC1F,MAAM,IAAI,GAAG,KAAK,CAAC,GAAG,EAAS,CAAC;QAChC,MAAM,EAAE,UAAU,EAAE,GAAG,MAAM,IAAI,CAAC,uBAAuB,CAAC,EAAE,IAAI,EAAE,EAAE,IAAI,EAAE,EAAE,KAAK,EAAE,IAAI,EAAS,CAAC,CAAC;QAClG,IAAI,CAAC;YACD,MAAM,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,GAAG,UAAU,EAAE,UAAU,CAAC,CAAC,CAAC;QAC7D,CAAC;QAAC,OAAO,GAAG,EAAE,CAAC;YACX,MAAM,IAAI,KAAK,CAAC,GAAG,IAAI,KAAK,GAAG,EAAE,CAAC,CAAC;QACvC,CAAC;IACL,CAAC;CACJ;AA7BD,8BA6BC;AAED;;GAEG;AACH,MAAa,eAAgB,SAAQ,SAAS;IAC1C,IAAI,CAAQ;IACZ,OAAO,CAAkB;IACzB,OAAO,CAAW;IAClB,WAAW,CAAU;IACrB,OAAO,CAAqB;IAE5B,IAAI,GAAiC,CAAC,EAAE,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,OAAO,EAAyF,EAAE,EAAE;QAChK,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;QACvB,IAAI,CAAC,IAAI,GAAG,IAAI,CAAC;QACjB,IAAI,CAAC,OAAO,GAAG,OAAO,CAAC;IAC3B,CAAC,CAAA;CACJ;AAbD,0CAaC"}
|
|
@@ -4,7 +4,6 @@ exports.defineConfig = defineConfig;
|
|
|
4
4
|
const loader_1 = require("./loader");
|
|
5
5
|
// Constants
|
|
6
6
|
const ANNOTATION_TYPES = {
|
|
7
|
-
TEST_ID: '_testId',
|
|
8
7
|
NAME: 'name',
|
|
9
8
|
URI: 'uri',
|
|
10
9
|
TAGS: 'tags'
|
|
@@ -31,31 +30,6 @@ const STEP_ARGUMENT_LABELS = {
|
|
|
31
30
|
DOC_STRING: ' [MultiLine]',
|
|
32
31
|
DATA_TABLE: ' [DataTable]'
|
|
33
32
|
};
|
|
34
|
-
/**
|
|
35
|
-
* Extracts the test ID from TestInfo annotations
|
|
36
|
-
*/
|
|
37
|
-
function getTestId(testInfo) {
|
|
38
|
-
const annotation = testInfo.annotations
|
|
39
|
-
.find((annotation) => annotation.type === ANNOTATION_TYPES.TEST_ID);
|
|
40
|
-
if (!annotation?.description) {
|
|
41
|
-
throw new Error('Test ID annotation not found');
|
|
42
|
-
}
|
|
43
|
-
return annotation.description;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Converts TestInfo to HookResult format
|
|
47
|
-
*/
|
|
48
|
-
function getResult(testInfo) {
|
|
49
|
-
const message = testInfo.errors.length > 0
|
|
50
|
-
? testInfo.errors.map((err) => err.message).join('\n')
|
|
51
|
-
: undefined;
|
|
52
|
-
return {
|
|
53
|
-
duration: testInfo.duration,
|
|
54
|
-
message,
|
|
55
|
-
status: testInfo.status?.toUpperCase() ?? 'UNKNOWN',
|
|
56
|
-
exception: testInfo.error
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
33
|
/**
|
|
60
34
|
* Creates a location object from step definition
|
|
61
35
|
*/
|
|
@@ -94,6 +68,85 @@ function stepName(pickleStep) {
|
|
|
94
68
|
}
|
|
95
69
|
return step;
|
|
96
70
|
}
|
|
71
|
+
function createTestExecutionResult() {
|
|
72
|
+
return {
|
|
73
|
+
status: 'passed',
|
|
74
|
+
start: Date.now()
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function createHookResult(result) {
|
|
78
|
+
return {
|
|
79
|
+
duration: (Date.now() - result.start),
|
|
80
|
+
message: result.error?.message,
|
|
81
|
+
status: result.status.toUpperCase(),
|
|
82
|
+
exception: result.error
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function createScenarioAnnotation(testCase) {
|
|
86
|
+
const tag = [...new Set(testCase.tags.map((item) => item.name))];
|
|
87
|
+
return [
|
|
88
|
+
{ type: ANNOTATION_TYPES.NAME, description: testCase.name },
|
|
89
|
+
{ type: ANNOTATION_TYPES.URI, description: testCase.uri },
|
|
90
|
+
{ type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tag) }
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
function createScenarioTags(testCase) {
|
|
94
|
+
return [...new Set(testCase.tags.map((item) => item.name))];
|
|
95
|
+
}
|
|
96
|
+
function createCaseHookPayload(feature, testCase) {
|
|
97
|
+
return {
|
|
98
|
+
gherkinDocument: feature.gherkinDocument,
|
|
99
|
+
pickle: testCase
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function executeCaseHooks(test, hooks, world, testCase, defaultHookName, createPayload) {
|
|
103
|
+
for (const hook of hooks) {
|
|
104
|
+
if (!hook.appliesToTestCase(testCase)) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const hookName = hook.name ?? defaultHookName;
|
|
108
|
+
const location = getLine(hook);
|
|
109
|
+
await test.step(hookName, () => hook.code.apply(world, [createPayload(hook)]), location);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function executeStepHooks(test, hooks, world, testCase, hookName, createPayload) {
|
|
113
|
+
for (const hook of hooks) {
|
|
114
|
+
if (!hook.appliesToTestCase(testCase)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const location = getLine(hook);
|
|
118
|
+
await test.step(hookName, () => hook.code.apply(world, [createPayload(hook)]), location);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function createStepHookParameter(feature, testCase, pickleStep, result) {
|
|
122
|
+
return {
|
|
123
|
+
gherkinDocument: feature.gherkinDocument,
|
|
124
|
+
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
125
|
+
testStepId: DEFAULT_VALUES.TEST_STEP_ID,
|
|
126
|
+
pickle: testCase,
|
|
127
|
+
pickleStep,
|
|
128
|
+
result: createHookResult(result)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function createCaseHookParameter(feature, testCase, result) {
|
|
132
|
+
return {
|
|
133
|
+
gherkinDocument: feature.gherkinDocument,
|
|
134
|
+
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
135
|
+
pickle: testCase,
|
|
136
|
+
result: createHookResult(result)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function findSingleStepDefinition(supportCodeLibrary, pickleStep) {
|
|
140
|
+
const matchingSteps = supportCodeLibrary.stepDefinitions
|
|
141
|
+
.filter((stepDefinition) => stepDefinition.matchesStepName(pickleStep.text));
|
|
142
|
+
if (matchingSteps.length === 0) {
|
|
143
|
+
throw new Error(`Step '${pickleStep.text}' is not defined`);
|
|
144
|
+
}
|
|
145
|
+
if (matchingSteps.length > 1) {
|
|
146
|
+
throw new Error(`Step '${pickleStep.text}' matches multiple step definitions`);
|
|
147
|
+
}
|
|
148
|
+
return matchingSteps[0];
|
|
149
|
+
}
|
|
97
150
|
/**
|
|
98
151
|
* Executes before all hooks
|
|
99
152
|
*/
|
|
@@ -120,18 +173,6 @@ function executeAfterAllHooks(test, hooks) {
|
|
|
120
173
|
}
|
|
121
174
|
});
|
|
122
175
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Creates test annotations from test case data
|
|
125
|
-
*/
|
|
126
|
-
function createTestAnnotations(testCase) {
|
|
127
|
-
const tags = [...new Set(testCase.tags.map((tag) => tag.name))];
|
|
128
|
-
return [
|
|
129
|
-
{ type: ANNOTATION_TYPES.NAME, description: testCase.name },
|
|
130
|
-
{ type: ANNOTATION_TYPES.URI, description: testCase.uri },
|
|
131
|
-
{ type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tags) },
|
|
132
|
-
{ type: ANNOTATION_TYPES.TEST_ID, description: testCase.id }
|
|
133
|
-
];
|
|
134
|
-
}
|
|
135
176
|
/**
|
|
136
177
|
* Main configuration function that sets up Cucumber adapter for Playwright
|
|
137
178
|
*/
|
|
@@ -140,138 +181,63 @@ function defineConfig(config) {
|
|
|
140
181
|
const fixture = new supportCodeLibrary.World({ config });
|
|
141
182
|
const test = fixture.test;
|
|
142
183
|
executeBeforeAllHooks(test, supportCodeLibrary.beforeTestRunHookDefinitions);
|
|
143
|
-
const worlds = new Map();
|
|
144
184
|
for (const feature of features) {
|
|
145
185
|
const tests = feature.tests;
|
|
146
|
-
test.describe(feature.feature,
|
|
147
|
-
/**
|
|
148
|
-
* Factory function to create and register world instances
|
|
149
|
-
*/
|
|
150
|
-
const worldFactory = (fixtures) => {
|
|
151
|
-
const world = new supportCodeLibrary.World({
|
|
152
|
-
log,
|
|
153
|
-
attach,
|
|
154
|
-
supportCodeLibrary,
|
|
155
|
-
config
|
|
156
|
-
});
|
|
157
|
-
world.init(fixtures);
|
|
158
|
-
worlds.set(getTestId(test.info()), world);
|
|
159
|
-
};
|
|
160
|
-
worldFactory.toString = () => fixture.init.toString();
|
|
161
|
-
test.beforeEach(HOOK_NAMES.WORLD, worldFactory);
|
|
162
|
-
test.beforeEach(HOOK_NAMES.BEFORE_HOOKS, async () => {
|
|
163
|
-
const testId = getTestId(test.info());
|
|
164
|
-
const world = worlds.get(testId);
|
|
165
|
-
const testCase = tests.find((t) => t.id === testId);
|
|
166
|
-
if (!testCase) {
|
|
167
|
-
throw new Error(`Test case with ID ${testId} not found`);
|
|
168
|
-
}
|
|
169
|
-
for (const beforeHook of supportCodeLibrary.beforeTestCaseHookDefinitions) {
|
|
170
|
-
if (beforeHook.appliesToTestCase(testCase)) {
|
|
171
|
-
const hookName = beforeHook.name ?? HOOK_NAMES.BEFORE;
|
|
172
|
-
const location = getLine(beforeHook);
|
|
173
|
-
await test.step(hookName, () => beforeHook.code.apply(world, [{
|
|
174
|
-
gherkinDocument: feature.gherkinDocument,
|
|
175
|
-
pickle: testCase
|
|
176
|
-
}]), location);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
});
|
|
186
|
+
test.describe(feature.feature, () => {
|
|
180
187
|
for (const testCase of tests) {
|
|
181
|
-
const tag =
|
|
182
|
-
const annotation =
|
|
183
|
-
|
|
184
|
-
const world =
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
const [step] = matchingSteps;
|
|
199
|
-
const location = getLine(step);
|
|
200
|
-
await test.step(stepName(pickleStep), async () => {
|
|
201
|
-
for (const beforeStep of supportCodeLibrary.beforeTestStepHookDefinitions) {
|
|
202
|
-
if (beforeStep.appliesToTestCase(testCase)) {
|
|
203
|
-
const location = getLine(beforeStep);
|
|
204
|
-
await test.step(HOOK_NAMES.BEFORE_STEP, () => beforeStep.code.apply(world, [{
|
|
205
|
-
gherkinDocument: feature.gherkinDocument,
|
|
206
|
-
pickle: testCase,
|
|
207
|
-
pickleStep
|
|
208
|
-
}]), location);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
const { parameters } = await step.getInvocationParameters({
|
|
212
|
-
step: {
|
|
213
|
-
text: pickleStep.text,
|
|
214
|
-
argument: pickleStep.argument
|
|
215
|
-
},
|
|
216
|
-
world
|
|
217
|
-
});
|
|
218
|
-
try {
|
|
219
|
-
await step.code.apply(world, parameters);
|
|
188
|
+
const tag = createScenarioTags(testCase);
|
|
189
|
+
const annotation = createScenarioAnnotation(testCase);
|
|
190
|
+
const testBody = async (fixtures) => {
|
|
191
|
+
const world = new supportCodeLibrary.World({
|
|
192
|
+
log,
|
|
193
|
+
attach,
|
|
194
|
+
supportCodeLibrary,
|
|
195
|
+
config
|
|
196
|
+
});
|
|
197
|
+
world.init(fixtures);
|
|
198
|
+
const result = createTestExecutionResult();
|
|
199
|
+
await executeCaseHooks(test, supportCodeLibrary.beforeTestCaseHookDefinitions, world, testCase, HOOK_NAMES.BEFORE, () => createCaseHookPayload(feature, testCase));
|
|
200
|
+
try {
|
|
201
|
+
for (const pickleStep of testCase.steps) {
|
|
202
|
+
if (result.status !== 'passed') {
|
|
203
|
+
break;
|
|
220
204
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
message: result.error?.message,
|
|
239
|
-
status: result.status.toUpperCase(),
|
|
240
|
-
exception: result.error
|
|
241
|
-
}
|
|
242
|
-
}]), location);
|
|
243
|
-
}
|
|
205
|
+
const step = findSingleStepDefinition(supportCodeLibrary, pickleStep);
|
|
206
|
+
const location = getLine(step);
|
|
207
|
+
await test.step(stepName(pickleStep), async () => {
|
|
208
|
+
await executeStepHooks(test, supportCodeLibrary.beforeTestStepHookDefinitions, world, testCase, HOOK_NAMES.BEFORE_STEP, () => ({
|
|
209
|
+
gherkinDocument: feature.gherkinDocument,
|
|
210
|
+
pickle: testCase,
|
|
211
|
+
pickleStep
|
|
212
|
+
}));
|
|
213
|
+
const { parameters } = await step.getInvocationParameters({
|
|
214
|
+
step: {
|
|
215
|
+
text: pickleStep.text,
|
|
216
|
+
argument: pickleStep.argument
|
|
217
|
+
},
|
|
218
|
+
world
|
|
219
|
+
});
|
|
220
|
+
try {
|
|
221
|
+
await step.code.apply(world, parameters);
|
|
244
222
|
}
|
|
245
|
-
|
|
246
|
-
|
|
223
|
+
catch (err) {
|
|
224
|
+
result.status = 'failed';
|
|
225
|
+
result.error = err;
|
|
226
|
+
throw err;
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
await executeStepHooks(test, supportCodeLibrary.afterTestStepHookDefinitions, world, testCase, HOOK_NAMES.AFTER_STEP, () => createStepHookParameter(feature, testCase, pickleStep, result));
|
|
230
|
+
}
|
|
231
|
+
}, location);
|
|
232
|
+
}
|
|
247
233
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
test.afterEach(HOOK_NAMES.AFTER_HOOKS, async () => {
|
|
251
|
-
const testInfo = test.info();
|
|
252
|
-
const testId = getTestId(testInfo);
|
|
253
|
-
const world = worlds.get(testId);
|
|
254
|
-
const testCase = tests.find((t) => t.id === testId);
|
|
255
|
-
if (!testCase) {
|
|
256
|
-
throw new Error(`Test case with ID ${testId} not found`);
|
|
257
|
-
}
|
|
258
|
-
for (const afterHook of supportCodeLibrary.afterTestCaseHookDefinitions) {
|
|
259
|
-
if (afterHook.appliesToTestCase(testCase)) {
|
|
260
|
-
const hookName = afterHook.name ?? HOOK_NAMES.AFTER;
|
|
261
|
-
const location = getLine(afterHook);
|
|
262
|
-
await test.step(hookName, () => afterHook.code.apply(world, [{
|
|
263
|
-
gherkinDocument: feature.gherkinDocument,
|
|
264
|
-
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
265
|
-
pickle: testCase,
|
|
266
|
-
result: getResult(testInfo)
|
|
267
|
-
}]), location);
|
|
234
|
+
finally {
|
|
235
|
+
await executeCaseHooks(test, supportCodeLibrary.afterTestCaseHookDefinitions, world, testCase, HOOK_NAMES.AFTER, () => createCaseHookParameter(feature, testCase, result));
|
|
268
236
|
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
worlds.delete(testId);
|
|
274
|
-
});
|
|
237
|
+
};
|
|
238
|
+
testBody.toString = () => fixture.init.toString();
|
|
239
|
+
test(testCase.name, { tag, annotation }, testBody);
|
|
240
|
+
}
|
|
275
241
|
});
|
|
276
242
|
}
|
|
277
243
|
executeAfterAllHooks(test, supportCodeLibrary.afterTestRunHookDefinitions);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cucumberAdapter.js","sourceRoot":"","sources":["../src/cucumberAdapter.ts"],"names":[],"mappings":";;
|
|
1
|
+
{"version":3,"file":"cucumberAdapter.js","sourceRoot":"","sources":["../src/cucumberAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@ class TestWorld {
|
|
|
18
18
|
this.attach = options.attach;
|
|
19
19
|
this.parameters = options.parameters;
|
|
20
20
|
this.supportCodeLibrary = options.supportCodeLibrary;
|
|
21
|
+
this.config = options.config;
|
|
21
22
|
}
|
|
22
23
|
async executeStep(text, extraParam) {
|
|
23
24
|
const steps = this.supportCodeLibrary.stepDefinitions.filter((s) => s.matchesStepName(text));
|
|
@@ -4,7 +4,6 @@ exports.defineConfig = defineConfig;
|
|
|
4
4
|
const loader_1 = require("./loader");
|
|
5
5
|
// Constants
|
|
6
6
|
const ANNOTATION_TYPES = {
|
|
7
|
-
TEST_ID: '_testId',
|
|
8
7
|
NAME: 'name',
|
|
9
8
|
URI: 'uri',
|
|
10
9
|
TAGS: 'tags'
|
|
@@ -31,31 +30,6 @@ const STEP_ARGUMENT_LABELS = {
|
|
|
31
30
|
DOC_STRING: ' [MultiLine]',
|
|
32
31
|
DATA_TABLE: ' [DataTable]'
|
|
33
32
|
};
|
|
34
|
-
/**
|
|
35
|
-
* Extracts the test ID from TestInfo annotations
|
|
36
|
-
*/
|
|
37
|
-
function getTestId(testInfo) {
|
|
38
|
-
const annotation = testInfo.annotations
|
|
39
|
-
.find((annotation) => annotation.type === ANNOTATION_TYPES.TEST_ID);
|
|
40
|
-
if (!annotation?.description) {
|
|
41
|
-
throw new Error('Test ID annotation not found');
|
|
42
|
-
}
|
|
43
|
-
return annotation.description;
|
|
44
|
-
}
|
|
45
|
-
/**
|
|
46
|
-
* Converts TestInfo to HookResult format
|
|
47
|
-
*/
|
|
48
|
-
function getResult(testInfo) {
|
|
49
|
-
const message = testInfo.errors.length > 0
|
|
50
|
-
? testInfo.errors.map((err) => err.message).join('\n')
|
|
51
|
-
: undefined;
|
|
52
|
-
return {
|
|
53
|
-
duration: testInfo.duration,
|
|
54
|
-
message,
|
|
55
|
-
status: testInfo.status?.toUpperCase() ?? 'UNKNOWN',
|
|
56
|
-
exception: testInfo.error
|
|
57
|
-
};
|
|
58
|
-
}
|
|
59
33
|
/**
|
|
60
34
|
* Creates a location object from step definition
|
|
61
35
|
*/
|
|
@@ -94,6 +68,85 @@ function stepName(pickleStep) {
|
|
|
94
68
|
}
|
|
95
69
|
return step;
|
|
96
70
|
}
|
|
71
|
+
function createTestExecutionResult() {
|
|
72
|
+
return {
|
|
73
|
+
status: 'passed',
|
|
74
|
+
start: Date.now()
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
function createHookResult(result) {
|
|
78
|
+
return {
|
|
79
|
+
duration: (Date.now() - result.start),
|
|
80
|
+
message: result.error?.message,
|
|
81
|
+
status: result.status.toUpperCase(),
|
|
82
|
+
exception: result.error
|
|
83
|
+
};
|
|
84
|
+
}
|
|
85
|
+
function createScenarioAnnotation(testCase) {
|
|
86
|
+
const tag = [...new Set(testCase.tags.map((item) => item.name))];
|
|
87
|
+
return [
|
|
88
|
+
{ type: ANNOTATION_TYPES.NAME, description: testCase.name },
|
|
89
|
+
{ type: ANNOTATION_TYPES.URI, description: testCase.uri },
|
|
90
|
+
{ type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tag) }
|
|
91
|
+
];
|
|
92
|
+
}
|
|
93
|
+
function createScenarioTags(testCase) {
|
|
94
|
+
return [...new Set(testCase.tags.map((item) => item.name))];
|
|
95
|
+
}
|
|
96
|
+
function createCaseHookPayload(feature, testCase) {
|
|
97
|
+
return {
|
|
98
|
+
gherkinDocument: feature.gherkinDocument,
|
|
99
|
+
pickle: testCase
|
|
100
|
+
};
|
|
101
|
+
}
|
|
102
|
+
async function executeCaseHooks(test, hooks, world, testCase, defaultHookName, createPayload) {
|
|
103
|
+
for (const hook of hooks) {
|
|
104
|
+
if (!hook.appliesToTestCase(testCase)) {
|
|
105
|
+
continue;
|
|
106
|
+
}
|
|
107
|
+
const hookName = hook.name ?? defaultHookName;
|
|
108
|
+
const location = getLine(hook);
|
|
109
|
+
await test.step(hookName, () => hook.code.apply(world, [createPayload(hook)]), location);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
async function executeStepHooks(test, hooks, world, testCase, hookName, createPayload) {
|
|
113
|
+
for (const hook of hooks) {
|
|
114
|
+
if (!hook.appliesToTestCase(testCase)) {
|
|
115
|
+
continue;
|
|
116
|
+
}
|
|
117
|
+
const location = getLine(hook);
|
|
118
|
+
await test.step(hookName, () => hook.code.apply(world, [createPayload(hook)]), location);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function createStepHookParameter(feature, testCase, pickleStep, result) {
|
|
122
|
+
return {
|
|
123
|
+
gherkinDocument: feature.gherkinDocument,
|
|
124
|
+
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
125
|
+
testStepId: DEFAULT_VALUES.TEST_STEP_ID,
|
|
126
|
+
pickle: testCase,
|
|
127
|
+
pickleStep,
|
|
128
|
+
result: createHookResult(result)
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
function createCaseHookParameter(feature, testCase, result) {
|
|
132
|
+
return {
|
|
133
|
+
gherkinDocument: feature.gherkinDocument,
|
|
134
|
+
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
135
|
+
pickle: testCase,
|
|
136
|
+
result: createHookResult(result)
|
|
137
|
+
};
|
|
138
|
+
}
|
|
139
|
+
function findSingleStepDefinition(supportCodeLibrary, pickleStep) {
|
|
140
|
+
const matchingSteps = supportCodeLibrary.stepDefinitions
|
|
141
|
+
.filter((stepDefinition) => stepDefinition.matchesStepName(pickleStep.text));
|
|
142
|
+
if (matchingSteps.length === 0) {
|
|
143
|
+
throw new Error(`Step '${pickleStep.text}' is not defined`);
|
|
144
|
+
}
|
|
145
|
+
if (matchingSteps.length > 1) {
|
|
146
|
+
throw new Error(`Step '${pickleStep.text}' matches multiple step definitions`);
|
|
147
|
+
}
|
|
148
|
+
return matchingSteps[0];
|
|
149
|
+
}
|
|
97
150
|
/**
|
|
98
151
|
* Executes before all hooks
|
|
99
152
|
*/
|
|
@@ -120,18 +173,6 @@ function executeAfterAllHooks(test, hooks) {
|
|
|
120
173
|
}
|
|
121
174
|
});
|
|
122
175
|
}
|
|
123
|
-
/**
|
|
124
|
-
* Creates test annotations from test case data
|
|
125
|
-
*/
|
|
126
|
-
function createTestAnnotations(testCase) {
|
|
127
|
-
const tags = [...new Set(testCase.tags.map((tag) => tag.name))];
|
|
128
|
-
return [
|
|
129
|
-
{ type: ANNOTATION_TYPES.NAME, description: testCase.name },
|
|
130
|
-
{ type: ANNOTATION_TYPES.URI, description: testCase.uri },
|
|
131
|
-
{ type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tags) },
|
|
132
|
-
{ type: ANNOTATION_TYPES.TEST_ID, description: testCase.id }
|
|
133
|
-
];
|
|
134
|
-
}
|
|
135
176
|
/**
|
|
136
177
|
* Main configuration function that sets up Cucumber adapter for Playwright
|
|
137
178
|
*/
|
|
@@ -140,138 +181,63 @@ function defineConfig(config) {
|
|
|
140
181
|
const fixture = new supportCodeLibrary.World({ config });
|
|
141
182
|
const test = fixture.test;
|
|
142
183
|
executeBeforeAllHooks(test, supportCodeLibrary.beforeTestRunHookDefinitions);
|
|
143
|
-
const worlds = new Map();
|
|
144
184
|
for (const feature of features) {
|
|
145
185
|
const tests = feature.tests;
|
|
146
|
-
test.describe(feature.feature,
|
|
147
|
-
/**
|
|
148
|
-
* Factory function to create and register world instances
|
|
149
|
-
*/
|
|
150
|
-
const worldFactory = (fixtures) => {
|
|
151
|
-
const world = new supportCodeLibrary.World({
|
|
152
|
-
log,
|
|
153
|
-
attach,
|
|
154
|
-
supportCodeLibrary,
|
|
155
|
-
config
|
|
156
|
-
});
|
|
157
|
-
world.init(fixtures);
|
|
158
|
-
worlds.set(getTestId(test.info()), world);
|
|
159
|
-
};
|
|
160
|
-
worldFactory.toString = () => fixture.init.toString();
|
|
161
|
-
test.beforeEach(HOOK_NAMES.WORLD, worldFactory);
|
|
162
|
-
test.beforeEach(HOOK_NAMES.BEFORE_HOOKS, async () => {
|
|
163
|
-
const testId = getTestId(test.info());
|
|
164
|
-
const world = worlds.get(testId);
|
|
165
|
-
const testCase = tests.find((t) => t.id === testId);
|
|
166
|
-
if (!testCase) {
|
|
167
|
-
throw new Error(`Test case with ID ${testId} not found`);
|
|
168
|
-
}
|
|
169
|
-
for (const beforeHook of supportCodeLibrary.beforeTestCaseHookDefinitions) {
|
|
170
|
-
if (beforeHook.appliesToTestCase(testCase)) {
|
|
171
|
-
const hookName = beforeHook.name ?? HOOK_NAMES.BEFORE;
|
|
172
|
-
const location = getLine(beforeHook);
|
|
173
|
-
await test.step(hookName, () => beforeHook.code.apply(world, [{
|
|
174
|
-
gherkinDocument: feature.gherkinDocument,
|
|
175
|
-
pickle: testCase
|
|
176
|
-
}]), location);
|
|
177
|
-
}
|
|
178
|
-
}
|
|
179
|
-
});
|
|
186
|
+
test.describe(feature.feature, () => {
|
|
180
187
|
for (const testCase of tests) {
|
|
181
|
-
const tag =
|
|
182
|
-
const annotation =
|
|
183
|
-
|
|
184
|
-
const world =
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
}
|
|
198
|
-
const [step] = matchingSteps;
|
|
199
|
-
const location = getLine(step);
|
|
200
|
-
await test.step(stepName(pickleStep), async () => {
|
|
201
|
-
for (const beforeStep of supportCodeLibrary.beforeTestStepHookDefinitions) {
|
|
202
|
-
if (beforeStep.appliesToTestCase(testCase)) {
|
|
203
|
-
const location = getLine(beforeStep);
|
|
204
|
-
await test.step(HOOK_NAMES.BEFORE_STEP, () => beforeStep.code.apply(world, [{
|
|
205
|
-
gherkinDocument: feature.gherkinDocument,
|
|
206
|
-
pickle: testCase,
|
|
207
|
-
pickleStep
|
|
208
|
-
}]), location);
|
|
209
|
-
}
|
|
210
|
-
}
|
|
211
|
-
const { parameters } = await step.getInvocationParameters({
|
|
212
|
-
step: {
|
|
213
|
-
text: pickleStep.text,
|
|
214
|
-
argument: pickleStep.argument
|
|
215
|
-
},
|
|
216
|
-
world
|
|
217
|
-
});
|
|
218
|
-
try {
|
|
219
|
-
await step.code.apply(world, parameters);
|
|
188
|
+
const tag = createScenarioTags(testCase);
|
|
189
|
+
const annotation = createScenarioAnnotation(testCase);
|
|
190
|
+
const testBody = async (fixtures) => {
|
|
191
|
+
const world = new supportCodeLibrary.World({
|
|
192
|
+
log,
|
|
193
|
+
attach,
|
|
194
|
+
supportCodeLibrary,
|
|
195
|
+
config
|
|
196
|
+
});
|
|
197
|
+
world.init(fixtures);
|
|
198
|
+
const result = createTestExecutionResult();
|
|
199
|
+
await executeCaseHooks(test, supportCodeLibrary.beforeTestCaseHookDefinitions, world, testCase, HOOK_NAMES.BEFORE, () => createCaseHookPayload(feature, testCase));
|
|
200
|
+
try {
|
|
201
|
+
for (const pickleStep of testCase.steps) {
|
|
202
|
+
if (result.status !== 'passed') {
|
|
203
|
+
break;
|
|
220
204
|
}
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
message: result.error?.message,
|
|
239
|
-
status: result.status.toUpperCase(),
|
|
240
|
-
exception: result.error
|
|
241
|
-
}
|
|
242
|
-
}]), location);
|
|
243
|
-
}
|
|
205
|
+
const step = findSingleStepDefinition(supportCodeLibrary, pickleStep);
|
|
206
|
+
const location = getLine(step);
|
|
207
|
+
await test.step(stepName(pickleStep), async () => {
|
|
208
|
+
await executeStepHooks(test, supportCodeLibrary.beforeTestStepHookDefinitions, world, testCase, HOOK_NAMES.BEFORE_STEP, () => ({
|
|
209
|
+
gherkinDocument: feature.gherkinDocument,
|
|
210
|
+
pickle: testCase,
|
|
211
|
+
pickleStep
|
|
212
|
+
}));
|
|
213
|
+
const { parameters } = await step.getInvocationParameters({
|
|
214
|
+
step: {
|
|
215
|
+
text: pickleStep.text,
|
|
216
|
+
argument: pickleStep.argument
|
|
217
|
+
},
|
|
218
|
+
world
|
|
219
|
+
});
|
|
220
|
+
try {
|
|
221
|
+
await step.code.apply(world, parameters);
|
|
244
222
|
}
|
|
245
|
-
|
|
246
|
-
|
|
223
|
+
catch (err) {
|
|
224
|
+
result.status = 'failed';
|
|
225
|
+
result.error = err;
|
|
226
|
+
throw err;
|
|
227
|
+
}
|
|
228
|
+
finally {
|
|
229
|
+
await executeStepHooks(test, supportCodeLibrary.afterTestStepHookDefinitions, world, testCase, HOOK_NAMES.AFTER_STEP, () => createStepHookParameter(feature, testCase, pickleStep, result));
|
|
230
|
+
}
|
|
231
|
+
}, location);
|
|
232
|
+
}
|
|
247
233
|
}
|
|
248
|
-
|
|
249
|
-
|
|
250
|
-
test.afterEach(HOOK_NAMES.AFTER_HOOKS, async () => {
|
|
251
|
-
const testInfo = test.info();
|
|
252
|
-
const testId = getTestId(testInfo);
|
|
253
|
-
const world = worlds.get(testId);
|
|
254
|
-
const testCase = tests.find((t) => t.id === testId);
|
|
255
|
-
if (!testCase) {
|
|
256
|
-
throw new Error(`Test case with ID ${testId} not found`);
|
|
257
|
-
}
|
|
258
|
-
for (const afterHook of supportCodeLibrary.afterTestCaseHookDefinitions) {
|
|
259
|
-
if (afterHook.appliesToTestCase(testCase)) {
|
|
260
|
-
const hookName = afterHook.name ?? HOOK_NAMES.AFTER;
|
|
261
|
-
const location = getLine(afterHook);
|
|
262
|
-
await test.step(hookName, () => afterHook.code.apply(world, [{
|
|
263
|
-
gherkinDocument: feature.gherkinDocument,
|
|
264
|
-
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
265
|
-
pickle: testCase,
|
|
266
|
-
result: getResult(testInfo)
|
|
267
|
-
}]), location);
|
|
234
|
+
finally {
|
|
235
|
+
await executeCaseHooks(test, supportCodeLibrary.afterTestCaseHookDefinitions, world, testCase, HOOK_NAMES.AFTER, () => createCaseHookParameter(feature, testCase, result));
|
|
268
236
|
}
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
worlds.delete(testId);
|
|
274
|
-
});
|
|
237
|
+
};
|
|
238
|
+
testBody.toString = () => fixture.init.toString();
|
|
239
|
+
test(testCase.name, { tag, annotation }, testBody);
|
|
240
|
+
}
|
|
275
241
|
});
|
|
276
242
|
}
|
|
277
243
|
executeAfterAllHooks(test, supportCodeLibrary.afterTestRunHookDefinitions);
|
package/package.json
CHANGED
package/src/PlaywrightWorld.ts
CHANGED
|
@@ -17,6 +17,7 @@ export class TestWorld {
|
|
|
17
17
|
this.attach = options.attach;
|
|
18
18
|
this.parameters = options.parameters;
|
|
19
19
|
this.supportCodeLibrary = options.supportCodeLibrary;
|
|
20
|
+
this.config = options.config;
|
|
20
21
|
}
|
|
21
22
|
|
|
22
23
|
async executeStep(this: any, text: string, extraParam?: any) {
|
package/src/cucumberAdapter.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
import {load} from './loader';
|
|
2
2
|
import type {TestInfo, TestType} from '@playwright/test';
|
|
3
|
-
import type {ITestCaseHookParameter} from '@cucumber/cucumber';
|
|
3
|
+
import type {ITestCaseHookParameter, ITestStepHookParameter} from '@cucumber/cucumber';
|
|
4
4
|
|
|
5
5
|
// Constants
|
|
6
6
|
const ANNOTATION_TYPES = {
|
|
7
|
-
TEST_ID: '_testId',
|
|
8
7
|
NAME: 'name',
|
|
9
8
|
URI: 'uri',
|
|
10
9
|
TAGS: 'tags'
|
|
@@ -52,41 +51,17 @@ interface TestResult {
|
|
|
52
51
|
error?: Error;
|
|
53
52
|
}
|
|
54
53
|
|
|
55
|
-
interface
|
|
56
|
-
|
|
57
|
-
message?: string;
|
|
58
|
-
status: string;
|
|
59
|
-
exception?: Error;
|
|
54
|
+
interface TestExecutionResult extends TestResult {
|
|
55
|
+
start: number;
|
|
60
56
|
}
|
|
61
57
|
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
*/
|
|
65
|
-
function getTestId(testInfo: TestInfo): string {
|
|
66
|
-
const annotation = testInfo.annotations
|
|
67
|
-
.find((annotation) => annotation.type === ANNOTATION_TYPES.TEST_ID);
|
|
68
|
-
|
|
69
|
-
if (!annotation?.description) {
|
|
70
|
-
throw new Error('Test ID annotation not found');
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return annotation.description;
|
|
58
|
+
interface FeatureContext {
|
|
59
|
+
gherkinDocument: unknown;
|
|
74
60
|
}
|
|
75
61
|
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
function getResult(testInfo: TestInfo): HookResult {
|
|
80
|
-
const message = testInfo.errors.length > 0
|
|
81
|
-
? testInfo.errors.map((err) => err.message).join('\n')
|
|
82
|
-
: undefined;
|
|
83
|
-
|
|
84
|
-
return {
|
|
85
|
-
duration: testInfo.duration,
|
|
86
|
-
message,
|
|
87
|
-
status: testInfo.status?.toUpperCase() ?? 'UNKNOWN',
|
|
88
|
-
exception: testInfo.error as any
|
|
89
|
-
};
|
|
62
|
+
interface PickleStep {
|
|
63
|
+
text: string;
|
|
64
|
+
argument?: { docString?: unknown };
|
|
90
65
|
}
|
|
91
66
|
|
|
92
67
|
/**
|
|
@@ -140,6 +115,134 @@ function stepName(pickleStep: {
|
|
|
140
115
|
return step;
|
|
141
116
|
}
|
|
142
117
|
|
|
118
|
+
function createTestExecutionResult(): TestExecutionResult {
|
|
119
|
+
return {
|
|
120
|
+
status: 'passed',
|
|
121
|
+
start: Date.now()
|
|
122
|
+
};
|
|
123
|
+
}
|
|
124
|
+
|
|
125
|
+
function createHookResult(result: TestExecutionResult): any {
|
|
126
|
+
return {
|
|
127
|
+
duration: (Date.now() - result.start) as any,
|
|
128
|
+
message: result.error?.message,
|
|
129
|
+
status: result.status.toUpperCase(),
|
|
130
|
+
exception: result.error
|
|
131
|
+
};
|
|
132
|
+
}
|
|
133
|
+
|
|
134
|
+
function createScenarioAnnotation(testCase: any): { type: string; description: string }[] {
|
|
135
|
+
const tag = [...new Set(testCase.tags.map((item: { name: string }) => item.name))];
|
|
136
|
+
return [
|
|
137
|
+
{type: ANNOTATION_TYPES.NAME, description: testCase.name},
|
|
138
|
+
{type: ANNOTATION_TYPES.URI, description: testCase.uri},
|
|
139
|
+
{type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tag)}
|
|
140
|
+
];
|
|
141
|
+
}
|
|
142
|
+
|
|
143
|
+
function createScenarioTags(testCase: any): string[] {
|
|
144
|
+
return [...new Set<string>(testCase.tags.map((item: { name: string }) => item.name))];
|
|
145
|
+
}
|
|
146
|
+
|
|
147
|
+
function createCaseHookPayload(feature: FeatureContext, testCase: any): ITestCaseHookParameter {
|
|
148
|
+
return {
|
|
149
|
+
gherkinDocument: feature.gherkinDocument,
|
|
150
|
+
pickle: testCase
|
|
151
|
+
} as ITestCaseHookParameter;
|
|
152
|
+
}
|
|
153
|
+
|
|
154
|
+
async function executeCaseHooks(
|
|
155
|
+
test: TestType<any, any>,
|
|
156
|
+
hooks: any[],
|
|
157
|
+
world: any,
|
|
158
|
+
testCase: any,
|
|
159
|
+
defaultHookName: string,
|
|
160
|
+
createPayload: (hook: any) => any
|
|
161
|
+
): Promise<void> {
|
|
162
|
+
for (const hook of hooks) {
|
|
163
|
+
if (!hook.appliesToTestCase(testCase)) {
|
|
164
|
+
continue;
|
|
165
|
+
}
|
|
166
|
+
|
|
167
|
+
const hookName = hook.name ?? defaultHookName;
|
|
168
|
+
const location = getLine(hook);
|
|
169
|
+
await test.step(
|
|
170
|
+
hookName,
|
|
171
|
+
() => hook.code.apply(world, [createPayload(hook)]),
|
|
172
|
+
location
|
|
173
|
+
);
|
|
174
|
+
}
|
|
175
|
+
}
|
|
176
|
+
|
|
177
|
+
async function executeStepHooks(
|
|
178
|
+
test: TestType<any, any>,
|
|
179
|
+
hooks: any[],
|
|
180
|
+
world: any,
|
|
181
|
+
testCase: any,
|
|
182
|
+
hookName: string,
|
|
183
|
+
createPayload: (hook: any) => any
|
|
184
|
+
): Promise<void> {
|
|
185
|
+
for (const hook of hooks) {
|
|
186
|
+
if (!hook.appliesToTestCase(testCase)) {
|
|
187
|
+
continue;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
const location = getLine(hook);
|
|
191
|
+
await test.step(
|
|
192
|
+
hookName,
|
|
193
|
+
() => hook.code.apply(world, [createPayload(hook)]),
|
|
194
|
+
location
|
|
195
|
+
);
|
|
196
|
+
}
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
function createStepHookParameter(
|
|
200
|
+
feature: any,
|
|
201
|
+
testCase: any,
|
|
202
|
+
pickleStep: any,
|
|
203
|
+
result: TestExecutionResult
|
|
204
|
+
): ITestStepHookParameter {
|
|
205
|
+
return {
|
|
206
|
+
gherkinDocument: feature.gherkinDocument,
|
|
207
|
+
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
208
|
+
testStepId: DEFAULT_VALUES.TEST_STEP_ID,
|
|
209
|
+
pickle: testCase,
|
|
210
|
+
pickleStep,
|
|
211
|
+
result: createHookResult(result)
|
|
212
|
+
} as any;
|
|
213
|
+
}
|
|
214
|
+
|
|
215
|
+
function createCaseHookParameter(
|
|
216
|
+
feature: any,
|
|
217
|
+
testCase: any,
|
|
218
|
+
result: TestExecutionResult
|
|
219
|
+
): ITestCaseHookParameter {
|
|
220
|
+
return {
|
|
221
|
+
gherkinDocument: feature.gherkinDocument,
|
|
222
|
+
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
223
|
+
pickle: testCase,
|
|
224
|
+
result: createHookResult(result)
|
|
225
|
+
} as any;
|
|
226
|
+
}
|
|
227
|
+
|
|
228
|
+
function findSingleStepDefinition(
|
|
229
|
+
supportCodeLibrary: any,
|
|
230
|
+
pickleStep: PickleStep
|
|
231
|
+
): any {
|
|
232
|
+
const matchingSteps = supportCodeLibrary.stepDefinitions
|
|
233
|
+
.filter((stepDefinition: any) => stepDefinition.matchesStepName(pickleStep.text));
|
|
234
|
+
|
|
235
|
+
if (matchingSteps.length === 0) {
|
|
236
|
+
throw new Error(`Step '${pickleStep.text}' is not defined`);
|
|
237
|
+
}
|
|
238
|
+
|
|
239
|
+
if (matchingSteps.length > 1) {
|
|
240
|
+
throw new Error(`Step '${pickleStep.text}' matches multiple step definitions`);
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
return matchingSteps[0];
|
|
244
|
+
}
|
|
245
|
+
|
|
143
246
|
/**
|
|
144
247
|
* Executes before all hooks
|
|
145
248
|
*/
|
|
@@ -180,20 +283,6 @@ function executeAfterAllHooks(
|
|
|
180
283
|
});
|
|
181
284
|
}
|
|
182
285
|
|
|
183
|
-
/**
|
|
184
|
-
* Creates test annotations from test case data
|
|
185
|
-
*/
|
|
186
|
-
function createTestAnnotations(testCase: any): any[] {
|
|
187
|
-
const tags = [...new Set(testCase.tags.map((tag: { name: string }) => tag.name))];
|
|
188
|
-
|
|
189
|
-
return [
|
|
190
|
-
{ type: ANNOTATION_TYPES.NAME, description: testCase.name },
|
|
191
|
-
{ type: ANNOTATION_TYPES.URI, description: testCase.uri },
|
|
192
|
-
{ type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tags) },
|
|
193
|
-
{ type: ANNOTATION_TYPES.TEST_ID, description: testCase.id }
|
|
194
|
-
];
|
|
195
|
-
}
|
|
196
|
-
|
|
197
286
|
/**
|
|
198
287
|
* Main configuration function that sets up Cucumber adapter for Playwright
|
|
199
288
|
*/
|
|
@@ -204,175 +293,93 @@ export function defineConfig(config: any): any {
|
|
|
204
293
|
const test: TestType<any, any> = fixture.test;
|
|
205
294
|
executeBeforeAllHooks(test, supportCodeLibrary.beforeTestRunHookDefinitions);
|
|
206
295
|
|
|
207
|
-
const worlds = new Map<string, any>();
|
|
208
|
-
|
|
209
296
|
for (const feature of features) {
|
|
210
297
|
const tests = feature.tests;
|
|
211
|
-
|
|
212
|
-
test.describe(feature.feature as string, async () => {
|
|
213
|
-
/**
|
|
214
|
-
* Factory function to create and register world instances
|
|
215
|
-
*/
|
|
216
|
-
const worldFactory = (fixtures: any): void => {
|
|
217
|
-
const world = new supportCodeLibrary.World({
|
|
218
|
-
log,
|
|
219
|
-
attach,
|
|
220
|
-
supportCodeLibrary,
|
|
221
|
-
config
|
|
222
|
-
});
|
|
223
|
-
world.init(fixtures);
|
|
224
|
-
worlds.set(getTestId(test.info()), world);
|
|
225
|
-
};
|
|
226
|
-
|
|
227
|
-
worldFactory.toString = (): string => fixture.init.toString();
|
|
228
|
-
|
|
229
|
-
test.beforeEach(HOOK_NAMES.WORLD, worldFactory);
|
|
230
|
-
|
|
231
|
-
test.beforeEach(HOOK_NAMES.BEFORE_HOOKS, async () => {
|
|
232
|
-
const testId = getTestId(test.info());
|
|
233
|
-
const world = worlds.get(testId);
|
|
234
|
-
const testCase = tests.find((t: any) => t.id === testId);
|
|
235
|
-
|
|
236
|
-
if (!testCase) {
|
|
237
|
-
throw new Error(`Test case with ID ${testId} not found`);
|
|
238
|
-
}
|
|
239
|
-
|
|
240
|
-
for (const beforeHook of supportCodeLibrary.beforeTestCaseHookDefinitions) {
|
|
241
|
-
if (beforeHook.appliesToTestCase(testCase)) {
|
|
242
|
-
const hookName = beforeHook.name ?? HOOK_NAMES.BEFORE;
|
|
243
|
-
const location = getLine(beforeHook);
|
|
244
|
-
await test.step(
|
|
245
|
-
hookName,
|
|
246
|
-
() => beforeHook.code.apply(world, [{
|
|
247
|
-
gherkinDocument: feature.gherkinDocument,
|
|
248
|
-
pickle: testCase
|
|
249
|
-
} as ITestCaseHookParameter]),
|
|
250
|
-
location
|
|
251
|
-
);
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
});
|
|
298
|
+
test.describe(feature.feature as string, () => {
|
|
255
299
|
|
|
256
300
|
for (const testCase of tests) {
|
|
257
|
-
const tag =
|
|
258
|
-
const annotation =
|
|
259
|
-
|
|
260
|
-
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
276
|
-
|
|
277
|
-
|
|
278
|
-
|
|
279
|
-
|
|
280
|
-
|
|
281
|
-
)
|
|
282
|
-
|
|
283
|
-
|
|
284
|
-
const [step] = matchingSteps;
|
|
285
|
-
const location = getLine(step);
|
|
286
|
-
await test.step(stepName(pickleStep), async () => {
|
|
287
|
-
for (const beforeStep of supportCodeLibrary.beforeTestStepHookDefinitions) {
|
|
288
|
-
if (beforeStep.appliesToTestCase(testCase)) {
|
|
289
|
-
const location = getLine(beforeStep);
|
|
290
|
-
await test.step(
|
|
291
|
-
HOOK_NAMES.BEFORE_STEP,
|
|
292
|
-
() => beforeStep.code.apply(world, [{
|
|
293
|
-
gherkinDocument: feature.gherkinDocument,
|
|
294
|
-
pickle: testCase,
|
|
295
|
-
pickleStep
|
|
296
|
-
}]),
|
|
297
|
-
location
|
|
298
|
-
);
|
|
299
|
-
}
|
|
301
|
+
const tag = createScenarioTags(testCase);
|
|
302
|
+
const annotation = createScenarioAnnotation(testCase);
|
|
303
|
+
const testBody = async (fixtures: any) => {
|
|
304
|
+
const world = new supportCodeLibrary.World({
|
|
305
|
+
log,
|
|
306
|
+
attach,
|
|
307
|
+
supportCodeLibrary,
|
|
308
|
+
config
|
|
309
|
+
});
|
|
310
|
+
world.init(fixtures);
|
|
311
|
+
|
|
312
|
+
const result = createTestExecutionResult();
|
|
313
|
+
|
|
314
|
+
await executeCaseHooks(
|
|
315
|
+
test,
|
|
316
|
+
supportCodeLibrary.beforeTestCaseHookDefinitions,
|
|
317
|
+
world,
|
|
318
|
+
testCase,
|
|
319
|
+
HOOK_NAMES.BEFORE,
|
|
320
|
+
() => createCaseHookPayload(feature, testCase)
|
|
321
|
+
);
|
|
322
|
+
|
|
323
|
+
try {
|
|
324
|
+
for (const pickleStep of testCase.steps) {
|
|
325
|
+
if (result.status !== 'passed') {
|
|
326
|
+
break;
|
|
300
327
|
}
|
|
301
|
-
const
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
328
|
+
const step = findSingleStepDefinition(supportCodeLibrary, pickleStep);
|
|
329
|
+
const location = getLine(step);
|
|
330
|
+
await test.step(stepName(pickleStep), async () => {
|
|
331
|
+
await executeStepHooks(
|
|
332
|
+
test,
|
|
333
|
+
supportCodeLibrary.beforeTestStepHookDefinitions,
|
|
334
|
+
world,
|
|
335
|
+
testCase,
|
|
336
|
+
HOOK_NAMES.BEFORE_STEP,
|
|
337
|
+
() => ({
|
|
338
|
+
gherkinDocument: feature.gherkinDocument,
|
|
339
|
+
pickle: testCase,
|
|
340
|
+
pickleStep
|
|
341
|
+
})
|
|
342
|
+
);
|
|
343
|
+
const {parameters} = await step.getInvocationParameters({
|
|
344
|
+
step: {
|
|
345
|
+
text: pickleStep.text,
|
|
346
|
+
argument: pickleStep.argument
|
|
347
|
+
},
|
|
348
|
+
world
|
|
349
|
+
} as any);
|
|
350
|
+
try {
|
|
351
|
+
await step.code.apply(world, parameters);
|
|
352
|
+
} catch (err: any) {
|
|
353
|
+
result.status = 'failed';
|
|
354
|
+
result.error = err;
|
|
355
|
+
throw err;
|
|
356
|
+
} finally {
|
|
357
|
+
await executeStepHooks(
|
|
358
|
+
test,
|
|
359
|
+
supportCodeLibrary.afterTestStepHookDefinitions,
|
|
360
|
+
world,
|
|
361
|
+
testCase,
|
|
362
|
+
HOOK_NAMES.AFTER_STEP,
|
|
363
|
+
() => createStepHookParameter(feature, testCase, pickleStep, result)
|
|
364
|
+
);
|
|
337
365
|
}
|
|
338
|
-
}
|
|
339
|
-
}
|
|
340
|
-
}
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
const testCase = tests.find((t) => t.id === testId);
|
|
349
|
-
|
|
350
|
-
if (!testCase) {
|
|
351
|
-
throw new Error(`Test case with ID ${testId} not found`);
|
|
352
|
-
}
|
|
353
|
-
|
|
354
|
-
for (const afterHook of supportCodeLibrary.afterTestCaseHookDefinitions) {
|
|
355
|
-
if (afterHook.appliesToTestCase(testCase)) {
|
|
356
|
-
const hookName = afterHook.name ?? HOOK_NAMES.AFTER;
|
|
357
|
-
const location = getLine(afterHook);
|
|
358
|
-
await test.step(
|
|
359
|
-
hookName,
|
|
360
|
-
() => afterHook.code.apply(world, [{
|
|
361
|
-
gherkinDocument: feature.gherkinDocument,
|
|
362
|
-
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
363
|
-
pickle: testCase,
|
|
364
|
-
result: getResult(testInfo)
|
|
365
|
-
} as any]),
|
|
366
|
-
location
|
|
366
|
+
}, location);
|
|
367
|
+
}
|
|
368
|
+
} finally {
|
|
369
|
+
await executeCaseHooks(
|
|
370
|
+
test,
|
|
371
|
+
supportCodeLibrary.afterTestCaseHookDefinitions,
|
|
372
|
+
world,
|
|
373
|
+
testCase,
|
|
374
|
+
HOOK_NAMES.AFTER,
|
|
375
|
+
() => createCaseHookParameter(feature, testCase, result)
|
|
367
376
|
);
|
|
368
377
|
}
|
|
369
|
-
}
|
|
370
|
-
});
|
|
371
378
|
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
}
|
|
379
|
+
}
|
|
380
|
+
testBody.toString = () => fixture.init.toString();
|
|
381
|
+
test(testCase.name, {tag, annotation}, testBody);
|
|
382
|
+
}
|
|
376
383
|
|
|
377
384
|
});
|
|
378
385
|
}
|