@qavajs/cypress-runner-adapter 1.2.1 → 1.4.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 +18 -0
- package/README.md +16 -1
- package/adapter/index.js +14 -131
- package/adapter/make_mocha_tests_describe.js +119 -0
- package/adapter/make_mocha_tests_it.js +135 -0
- package/index.d.ts +1 -0
- package/package.json +19 -7
- package/supportCodeLibrary/index.js +24 -0
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,24 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|
|
14
14
|
|
|
15
15
|
:microscope: - experimental
|
|
16
16
|
|
|
17
|
+
## [1.4.0]
|
|
18
|
+
- :rocket: added `Template` utility function
|
|
19
|
+
```typescript
|
|
20
|
+
import { When, Template } from '@qavajs/playwright-runner-adapter';
|
|
21
|
+
|
|
22
|
+
When('I click {string} and verify {string}', Template((locator, expected) => `
|
|
23
|
+
I click '${locator}'
|
|
24
|
+
I expect '${locator} > Value' to equal '${expected}'
|
|
25
|
+
`));
|
|
26
|
+
```
|
|
27
|
+
|
|
28
|
+
## [1.3.0]
|
|
29
|
+
- :rocket: added tags support
|
|
30
|
+
- :rocket: added alternative 'it mode' to translate gherkin tests to mocha `it` instead of `describe`
|
|
31
|
+
```bash
|
|
32
|
+
MODE=it npx cypress open
|
|
33
|
+
```
|
|
34
|
+
|
|
17
35
|
## [1.2.1]
|
|
18
36
|
- :pencil: updated to cypress 15.3
|
|
19
37
|
|
package/README.md
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
# @qavajs/cypress-runner-adapter
|
|
2
|
-
Adapter to run
|
|
2
|
+
Adapter to run Gherkin tests via cypress test runner
|
|
3
3
|
|
|
4
4
|
## Installation
|
|
5
5
|
|
|
@@ -39,3 +39,18 @@ When('open {string} url', function (url) {
|
|
|
39
39
|
cy.visit(url);
|
|
40
40
|
});
|
|
41
41
|
```
|
|
42
|
+
|
|
43
|
+
## Tags
|
|
44
|
+
Test can be filtered using Cucumber tag expressions provided via environment variable `TAGS`
|
|
45
|
+
```
|
|
46
|
+
TAGS='@first and @second' npx cypress run
|
|
47
|
+
```
|
|
48
|
+
|
|
49
|
+
## Translation Mode
|
|
50
|
+
Gherkin tests can be translated in different modes
|
|
51
|
+
- `describe` - default mode. Scenario will be translated as `describe`, each step will be translated as `it`
|
|
52
|
+
- `it` - Scenario will be translated as `it`
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
MODE=it npx cypress open
|
|
56
|
+
```
|
package/adapter/index.js
CHANGED
|
@@ -1,149 +1,32 @@
|
|
|
1
|
-
const {
|
|
2
|
-
ensureFileSync,
|
|
3
|
-
writeFileSync,
|
|
4
|
-
readFileSync,
|
|
5
|
-
} = require('fs-extra');
|
|
1
|
+
const { ensureFileSync, writeFileSync, readFileSync } = require('fs-extra');
|
|
6
2
|
const { randomUUID } = require('node:crypto');
|
|
7
3
|
const { AstBuilder, compile, GherkinClassicTokenMatcher, Parser } = require('@cucumber/gherkin');
|
|
8
4
|
const webpackPreprocessor = require('@cypress/webpack-preprocessor')();
|
|
5
|
+
const tagExpressionParser = require('@cucumber/tag-expressions').default;
|
|
6
|
+
const makeMochaTestDescribe = require('./make_mocha_tests_describe');
|
|
7
|
+
const makeMochaTestIt = require('./make_mocha_tests_it');
|
|
9
8
|
|
|
10
9
|
const uuidFn = () => randomUUID();
|
|
11
|
-
const builder = new AstBuilder(uuidFn)
|
|
10
|
+
const builder = new AstBuilder(uuidFn);
|
|
12
11
|
const matcher = new GherkinClassicTokenMatcher();
|
|
13
|
-
const parser = new Parser(builder, matcher)
|
|
12
|
+
const parser = new Parser(builder, matcher);
|
|
14
13
|
|
|
15
|
-
|
|
16
|
-
return `
|
|
17
|
-
const tests = ${JSON.stringify(testCases)};
|
|
14
|
+
const makeMochaTest = process.env.MODE === 'it' ? makeMochaTestIt : makeMochaTestDescribe;
|
|
18
15
|
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
case 'Context': return 'Given';
|
|
22
|
-
case 'Action': return 'When';
|
|
23
|
-
case 'Outcome': return 'Then';
|
|
24
|
-
default: return 'Step';
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
function executeStepByText(text, argument) {
|
|
29
|
-
const steps = supportCodeLibrary.stepDefinitions
|
|
30
|
-
.filter(stepDefinition => stepDefinition.matchesStepName(text));
|
|
31
|
-
if (steps.length === 0) throw new Error(\`Step '\${text}' is not defined\`);
|
|
32
|
-
if (steps.length > 1) throw new Error(\`Step '\${text}' matches multiple step definitions\`);
|
|
33
|
-
const [step] = steps;
|
|
34
|
-
const { parameters } = step.getInvocationParameters({
|
|
35
|
-
step: { text, argument },
|
|
36
|
-
world: this
|
|
37
|
-
});
|
|
38
|
-
step.code.apply(this, parameters);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
function executeStep(pickle, world) {
|
|
42
|
-
if (pickle.argument && pickle.argument.dataTable) {
|
|
43
|
-
Cypress.log({ displayName: 'DataTable', message: pickle.argument.dataTable })
|
|
44
|
-
}
|
|
45
|
-
if (pickle.argument && pickle.argument.docString) {
|
|
46
|
-
Cypress.log({ displayName: 'Multiline', message: pickle.argument.docString.content })
|
|
47
|
-
}
|
|
48
|
-
executeStepByText.call(world, pickle.text, pickle.argument);
|
|
49
|
-
}
|
|
50
|
-
|
|
51
|
-
if (supportCodeLibrary.beforeTestRunHookDefinitions.length > 0) {
|
|
52
|
-
describe('Before All', function () {
|
|
53
|
-
for (const beforeRun of supportCodeLibrary.beforeTestRunHookDefinitions) {
|
|
54
|
-
it('Before All', function () {
|
|
55
|
-
beforeRun.code.apply();
|
|
56
|
-
});
|
|
57
|
-
}
|
|
58
|
-
})
|
|
59
|
-
}
|
|
60
|
-
for (const test of tests) {
|
|
61
|
-
describe('Scenario: ' + test.name, { testIsolation: false }, function () {
|
|
62
|
-
const world = new supportCodeLibrary.World();
|
|
63
|
-
world.executeStep = executeStepByText;
|
|
64
|
-
let skip = false;
|
|
65
|
-
let result = 'passed';
|
|
66
|
-
afterEach(function() {
|
|
67
|
-
if (this.step) {
|
|
68
|
-
for (const afterStep of supportCodeLibrary.afterTestStepHookDefinitions) {
|
|
69
|
-
if (afterStep.appliesToTestCase(this.step)) {
|
|
70
|
-
afterStep.code.apply(world, [{
|
|
71
|
-
pickle: test,
|
|
72
|
-
pickleStep: this.step,
|
|
73
|
-
gherkinDocument: tests,
|
|
74
|
-
result: this.currentTest.state
|
|
75
|
-
}]);
|
|
76
|
-
}
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
if (this.currentTest.state !== 'passed') {
|
|
80
|
-
skip = true;
|
|
81
|
-
}
|
|
82
|
-
result = this.currentTest.state;
|
|
83
|
-
});
|
|
84
|
-
for (const beforeTest of supportCodeLibrary.beforeTestCaseHookDefinitions) {
|
|
85
|
-
if (beforeTest.appliesToTestCase(test)) {
|
|
86
|
-
it(beforeTest.name, function () {
|
|
87
|
-
if (skip) return this.skip();
|
|
88
|
-
beforeTest.code.apply(world, [{
|
|
89
|
-
pickle: test,
|
|
90
|
-
gherkinDocument: tests,
|
|
91
|
-
willBeRetried: false
|
|
92
|
-
}]);
|
|
93
|
-
});
|
|
94
|
-
}
|
|
95
|
-
}
|
|
96
|
-
for (const step of test.steps) {
|
|
97
|
-
it(keyword(step) + ': ' + step.text, function () {
|
|
98
|
-
this.step = step;
|
|
99
|
-
if (skip) return this.skip();
|
|
100
|
-
for (const beforeStep of supportCodeLibrary.beforeTestStepHookDefinitions) {
|
|
101
|
-
if (beforeStep.appliesToTestCase(step)) {
|
|
102
|
-
beforeStep.code.apply(world, [{
|
|
103
|
-
pickle: test,
|
|
104
|
-
pickleStep: step,
|
|
105
|
-
gherkinDocument: tests
|
|
106
|
-
}]);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
executeStep(step, world);
|
|
110
|
-
})
|
|
111
|
-
}
|
|
112
|
-
for (const afterTest of supportCodeLibrary.afterTestCaseHookDefinitions) {
|
|
113
|
-
if (afterTest.appliesToTestCase(test)) {
|
|
114
|
-
it(afterTest.name, function () {
|
|
115
|
-
afterTest.code.apply(world, [{
|
|
116
|
-
pickle: test,
|
|
117
|
-
result,
|
|
118
|
-
gherkinDocument: tests,
|
|
119
|
-
willBeRetried: false
|
|
120
|
-
}]);
|
|
121
|
-
});
|
|
122
|
-
}
|
|
123
|
-
}
|
|
124
|
-
});
|
|
125
|
-
}
|
|
126
|
-
if (supportCodeLibrary.afterTestRunHookDefinitions.length > 0) {
|
|
127
|
-
describe('After All', function () {
|
|
128
|
-
for (const afterRun of supportCodeLibrary.afterTestRunHookDefinitions) {
|
|
129
|
-
it('After All', function () {
|
|
130
|
-
afterRun.code.apply();
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
})
|
|
134
|
-
}
|
|
135
|
-
`;
|
|
16
|
+
function adapter(testCases) {
|
|
17
|
+
return `(${makeMochaTest.toString()})(${JSON.stringify(testCases)});`;
|
|
136
18
|
}
|
|
137
19
|
|
|
138
20
|
module.exports = async function cucumber(file) {
|
|
139
21
|
const { filePath, outputPath, shouldWatch } = file;
|
|
140
22
|
if (!filePath.endsWith('.feature')) {
|
|
141
|
-
return webpackPreprocessor(file)
|
|
23
|
+
return webpackPreprocessor(file);
|
|
142
24
|
}
|
|
143
25
|
const gherkinDocument = parser.parse(readFileSync(filePath, 'utf-8'));
|
|
144
|
-
const
|
|
26
|
+
const tagExpression = tagExpressionParser(process.env.TAGS || '');
|
|
27
|
+
const testCases = compile(gherkinDocument, filePath, uuidFn)
|
|
28
|
+
.filter(test => tagExpression.evaluate(test.tags.map(tag => tag.name)));
|
|
145
29
|
ensureFileSync(outputPath);
|
|
146
30
|
writeFileSync(outputPath, adapter(testCases), 'utf-8');
|
|
147
|
-
|
|
148
|
-
return outputPath
|
|
31
|
+
return outputPath;
|
|
149
32
|
}
|
|
@@ -0,0 +1,119 @@
|
|
|
1
|
+
module.exports = function makeMochaTest(tests) {
|
|
2
|
+
function keyword(step) {
|
|
3
|
+
switch (step.type) {
|
|
4
|
+
case 'Context': return 'Given';
|
|
5
|
+
case 'Action': return 'When';
|
|
6
|
+
case 'Outcome': return 'Then';
|
|
7
|
+
default: return 'Step';
|
|
8
|
+
}
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
function executeStepByText(text, argument) {
|
|
12
|
+
const steps = supportCodeLibrary.stepDefinitions
|
|
13
|
+
.filter(stepDefinition => stepDefinition.matchesStepName(text));
|
|
14
|
+
if (steps.length === 0) throw new Error(`Step '${text}' is not defined`);
|
|
15
|
+
if (steps.length > 1) throw new Error(`Step '${text}' matches multiple step definitions`);
|
|
16
|
+
const [step] = steps;
|
|
17
|
+
const { parameters } = step.getInvocationParameters({
|
|
18
|
+
step: { text, argument },
|
|
19
|
+
world: this
|
|
20
|
+
});
|
|
21
|
+
step.code.apply(this, parameters);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
function executeStep(pickle, world) {
|
|
25
|
+
if (pickle.argument && pickle.argument.dataTable) {
|
|
26
|
+
Cypress.log({ displayName: 'DataTable', message: pickle.argument.dataTable });
|
|
27
|
+
}
|
|
28
|
+
if (pickle.argument && pickle.argument.docString) {
|
|
29
|
+
Cypress.log({ displayName: 'Multiline', message: pickle.argument.docString.content });
|
|
30
|
+
}
|
|
31
|
+
executeStepByText.call(world, pickle.text, pickle.argument);
|
|
32
|
+
}
|
|
33
|
+
|
|
34
|
+
if (supportCodeLibrary.beforeTestRunHookDefinitions.length > 0) {
|
|
35
|
+
describe('Before All', function () {
|
|
36
|
+
for (const beforeRun of supportCodeLibrary.beforeTestRunHookDefinitions) {
|
|
37
|
+
it('Before All', function () {
|
|
38
|
+
beforeRun.code.apply();
|
|
39
|
+
});
|
|
40
|
+
}
|
|
41
|
+
})
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
for (const test of tests) {
|
|
45
|
+
describe('Scenario: ' + test.name, { testIsolation: false }, function () {
|
|
46
|
+
const world = new supportCodeLibrary.World();
|
|
47
|
+
world.executeStep = executeStepByText;
|
|
48
|
+
let skip = false;
|
|
49
|
+
let result = 'passed';
|
|
50
|
+
afterEach(function () {
|
|
51
|
+
if (this.step) {
|
|
52
|
+
for (const afterStep of supportCodeLibrary.afterTestStepHookDefinitions) {
|
|
53
|
+
if (afterStep.appliesToTestCase(this.step)) {
|
|
54
|
+
afterStep.code.apply(world, [{
|
|
55
|
+
pickle: test,
|
|
56
|
+
pickleStep: this.step,
|
|
57
|
+
gherkinDocument: tests,
|
|
58
|
+
result: this.currentTest.state
|
|
59
|
+
}]);
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
if (this.currentTest.state !== 'passed') {
|
|
64
|
+
skip = true;
|
|
65
|
+
}
|
|
66
|
+
result = this.currentTest.state;
|
|
67
|
+
});
|
|
68
|
+
for (const beforeTest of supportCodeLibrary.beforeTestCaseHookDefinitions) {
|
|
69
|
+
if (beforeTest.appliesToTestCase(test)) {
|
|
70
|
+
it(beforeTest.name, function () {
|
|
71
|
+
if (skip) return this.skip();
|
|
72
|
+
beforeTest.code.apply(world, [{
|
|
73
|
+
pickle: test,
|
|
74
|
+
gherkinDocument: tests,
|
|
75
|
+
willBeRetried: false
|
|
76
|
+
}]);
|
|
77
|
+
});
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
for (const step of test.steps) {
|
|
81
|
+
it(keyword(step) + ': ' + step.text, function () {
|
|
82
|
+
this.step = step;
|
|
83
|
+
if (skip) return this.skip();
|
|
84
|
+
for (const beforeStep of supportCodeLibrary.beforeTestStepHookDefinitions) {
|
|
85
|
+
if (beforeStep.appliesToTestCase(step)) {
|
|
86
|
+
beforeStep.code.apply(world, [{
|
|
87
|
+
pickle: test,
|
|
88
|
+
pickleStep: step,
|
|
89
|
+
gherkinDocument: tests
|
|
90
|
+
}]);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
executeStep(step, world);
|
|
94
|
+
});
|
|
95
|
+
}
|
|
96
|
+
for (const afterTest of supportCodeLibrary.afterTestCaseHookDefinitions) {
|
|
97
|
+
if (afterTest.appliesToTestCase(test)) {
|
|
98
|
+
it(afterTest.name, function () {
|
|
99
|
+
afterTest.code.apply(world, [{
|
|
100
|
+
pickle: test,
|
|
101
|
+
result,
|
|
102
|
+
gherkinDocument: tests,
|
|
103
|
+
willBeRetried: false
|
|
104
|
+
}]);
|
|
105
|
+
});
|
|
106
|
+
}
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
if (supportCodeLibrary.afterTestRunHookDefinitions.length > 0) {
|
|
111
|
+
describe('After All', function () {
|
|
112
|
+
for (const afterRun of supportCodeLibrary.afterTestRunHookDefinitions) {
|
|
113
|
+
it('After All', function () {
|
|
114
|
+
afterRun.code.apply();
|
|
115
|
+
});
|
|
116
|
+
}
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
@@ -0,0 +1,135 @@
|
|
|
1
|
+
module.exports = function makeMochaTest(tests) {
|
|
2
|
+
function keyword(step) {
|
|
3
|
+
switch (step.type) {
|
|
4
|
+
case 'Context':
|
|
5
|
+
return 'Given';
|
|
6
|
+
case 'Action':
|
|
7
|
+
return 'When';
|
|
8
|
+
case 'Outcome':
|
|
9
|
+
return 'Then';
|
|
10
|
+
default:
|
|
11
|
+
return 'Step';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
function executeStepByText(text, argument) {
|
|
16
|
+
const steps = supportCodeLibrary.stepDefinitions
|
|
17
|
+
.filter(stepDefinition => stepDefinition.matchesStepName(text));
|
|
18
|
+
if (steps.length === 0) throw new Error(`Step '${text}' is not defined`);
|
|
19
|
+
if (steps.length > 1) throw new Error(`Step '${text}' matches multiple step definitions`);
|
|
20
|
+
const [ step ] = steps;
|
|
21
|
+
const { parameters } = step.getInvocationParameters({
|
|
22
|
+
step: {text, argument},
|
|
23
|
+
world: this
|
|
24
|
+
});
|
|
25
|
+
step.code.apply(this, parameters);
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
function executeStep(pickle, world) {
|
|
29
|
+
cy.then(() => {
|
|
30
|
+
if (pickle.argument && pickle.argument.dataTable) {
|
|
31
|
+
Cypress.log({displayName: 'DataTable', message: pickle.argument.dataTable});
|
|
32
|
+
}
|
|
33
|
+
if (pickle.argument && pickle.argument.docString) {
|
|
34
|
+
Cypress.log({displayName: 'Multiline', message: pickle.argument.docString.content});
|
|
35
|
+
}
|
|
36
|
+
});
|
|
37
|
+
executeStepByText.call(world, pickle.text, pickle.argument);
|
|
38
|
+
}
|
|
39
|
+
|
|
40
|
+
supportCodeLibrary.World.prototype.executeStep = executeStepByText;
|
|
41
|
+
|
|
42
|
+
function runStep(name, callback) {
|
|
43
|
+
cy.then(() => {
|
|
44
|
+
Cypress.log({displayName: name, message: ''});
|
|
45
|
+
})
|
|
46
|
+
callback();
|
|
47
|
+
}
|
|
48
|
+
|
|
49
|
+
function findTest(tests, name) {
|
|
50
|
+
const testName = name.replace(/Scenario:\s+/, '');
|
|
51
|
+
return tests.find(test => test.name === testName);
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (supportCodeLibrary.beforeTestRunHookDefinitions.length > 0) {
|
|
55
|
+
before(function () {
|
|
56
|
+
for (const beforeRun of supportCodeLibrary.beforeTestRunHookDefinitions) {
|
|
57
|
+
beforeRun.code.apply();
|
|
58
|
+
}
|
|
59
|
+
})
|
|
60
|
+
}
|
|
61
|
+
|
|
62
|
+
beforeEach(function () {
|
|
63
|
+
const test = findTest(tests, this.currentTest.title);
|
|
64
|
+
const world = this.world = new supportCodeLibrary.World();
|
|
65
|
+
for (const beforeTest of supportCodeLibrary.beforeTestCaseHookDefinitions) {
|
|
66
|
+
if (beforeTest.appliesToTestCase(test)) {
|
|
67
|
+
runStep(beforeTest.name, function () {
|
|
68
|
+
beforeTest.code.apply(world, [{
|
|
69
|
+
pickle: test,
|
|
70
|
+
gherkinDocument: tests,
|
|
71
|
+
willBeRetried: false
|
|
72
|
+
}]);
|
|
73
|
+
});
|
|
74
|
+
}
|
|
75
|
+
}
|
|
76
|
+
});
|
|
77
|
+
|
|
78
|
+
afterEach( function () {
|
|
79
|
+
const test = findTest(tests, this.currentTest.title);
|
|
80
|
+
const world = this.world;
|
|
81
|
+
for (const afterTest of supportCodeLibrary.afterTestCaseHookDefinitions) {
|
|
82
|
+
if (afterTest.appliesToTestCase(test)) {
|
|
83
|
+
runStep(afterTest.name, function () {
|
|
84
|
+
afterTest.code.apply(world, [{
|
|
85
|
+
pickle: test,
|
|
86
|
+
result: null,
|
|
87
|
+
gherkinDocument: tests,
|
|
88
|
+
willBeRetried: false
|
|
89
|
+
}]);
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
});
|
|
94
|
+
|
|
95
|
+
for (const test of tests) {
|
|
96
|
+
it('Scenario: ' + test.name, function () {
|
|
97
|
+
const world = this.world;
|
|
98
|
+
for (const step of test.steps) {
|
|
99
|
+
const stepName = keyword(step) + ': ' + step.text;
|
|
100
|
+
runStep(stepName, function () {
|
|
101
|
+
this.step = step;
|
|
102
|
+
this.currentTest = { state: 'passed' };
|
|
103
|
+
for (const beforeStep of supportCodeLibrary.beforeTestStepHookDefinitions) {
|
|
104
|
+
if (beforeStep.appliesToTestCase(step)) {
|
|
105
|
+
beforeStep.code.apply(world, [{
|
|
106
|
+
pickle: test,
|
|
107
|
+
pickleStep: step,
|
|
108
|
+
gherkinDocument: tests
|
|
109
|
+
}]);
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
executeStep(step, world);
|
|
113
|
+
for (const afterStep of supportCodeLibrary.afterTestStepHookDefinitions) {
|
|
114
|
+
if (afterStep.appliesToTestCase(this.step)) {
|
|
115
|
+
afterStep.code.apply(world, [{
|
|
116
|
+
pickle: test,
|
|
117
|
+
pickleStep: this.step,
|
|
118
|
+
gherkinDocument: tests,
|
|
119
|
+
result: this.currentTest.state
|
|
120
|
+
}]);
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
});
|
|
124
|
+
}
|
|
125
|
+
});
|
|
126
|
+
}
|
|
127
|
+
|
|
128
|
+
if (supportCodeLibrary.afterTestRunHookDefinitions.length > 0) {
|
|
129
|
+
after(function () {
|
|
130
|
+
for (const afterRun of supportCodeLibrary.afterTestRunHookDefinitions) {
|
|
131
|
+
afterRun.code.apply();
|
|
132
|
+
}
|
|
133
|
+
});
|
|
134
|
+
}
|
|
135
|
+
}
|
package/index.d.ts
CHANGED
|
@@ -29,3 +29,4 @@ export function BeforeAll(fn: Function): void;
|
|
|
29
29
|
export function AfterAll(fn: Function): void;
|
|
30
30
|
export function setWorldConstructor(world: IWorld): void;
|
|
31
31
|
export function defineParameterType(option: ParameterTypeOption): void;
|
|
32
|
+
export function Template(template: (...args: any[]) => string): () => void;
|
package/package.json
CHANGED
|
@@ -1,10 +1,12 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qavajs/cypress-runner-adapter",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.4.0",
|
|
4
4
|
"main": "index.js",
|
|
5
5
|
"scripts": {
|
|
6
6
|
"debug": "cypress open --config-file test/cypress.config.js",
|
|
7
|
-
"test": "cypress run --config-file test/cypress.config.js"
|
|
7
|
+
"test": "cypress run --config-file test/cypress.config.js",
|
|
8
|
+
"debug:it": "MODE=it cypress open --config-file test/cypress.config.js",
|
|
9
|
+
"test:it": "MODE=it cypress run --config-file test/cypress.config.js"
|
|
8
10
|
},
|
|
9
11
|
"license": "MIT",
|
|
10
12
|
"description": "feature file preprocessor",
|
|
@@ -18,15 +20,25 @@
|
|
|
18
20
|
"bugs": {
|
|
19
21
|
"url": "https://github.com/qavajs/cypress-runner-adapter/issues"
|
|
20
22
|
},
|
|
21
|
-
"homepage": "https://github.
|
|
23
|
+
"homepage": "https://qavajs.github.io/docs/intro",
|
|
22
24
|
"dependencies": {
|
|
23
25
|
"@cucumber/cucumber-expressions": "^18.0.1",
|
|
24
|
-
"@cucumber/gherkin": "^
|
|
25
|
-
"@cucumber/tag-expressions": "^
|
|
26
|
+
"@cucumber/gherkin": "^36.0.0",
|
|
27
|
+
"@cucumber/tag-expressions": "^8.0.0",
|
|
26
28
|
"@cypress/webpack-preprocessor": "^7.0.1",
|
|
27
29
|
"fs-extra": "^11.3.2"
|
|
28
30
|
},
|
|
29
31
|
"devDependencies": {
|
|
30
|
-
"cypress": "^15.
|
|
31
|
-
}
|
|
32
|
+
"cypress": "^15.5.0"
|
|
33
|
+
},
|
|
34
|
+
"keywords": [
|
|
35
|
+
"cypress",
|
|
36
|
+
"cypress-plugin",
|
|
37
|
+
"cypress-preprocessor",
|
|
38
|
+
"qavajs",
|
|
39
|
+
"cucumber",
|
|
40
|
+
"gherkin",
|
|
41
|
+
"test",
|
|
42
|
+
"test-automation"
|
|
43
|
+
]
|
|
32
44
|
}
|
|
@@ -103,4 +103,28 @@ export function defineParameterType(options) {
|
|
|
103
103
|
supportCodeLibrary.parameterTypeRegistry.defineSourcedParameterType(parameterType, {})
|
|
104
104
|
}
|
|
105
105
|
|
|
106
|
+
/**
|
|
107
|
+
* Define template step
|
|
108
|
+
* @param {() => string} scenario - multiline string with steps
|
|
109
|
+
* @example
|
|
110
|
+
* When('I click {string} and verify {string}', Template((locator, expected) => `
|
|
111
|
+
* I click '${locator}'
|
|
112
|
+
* I expect '${locator} > Value' to equal '${expected}'
|
|
113
|
+
* `));
|
|
114
|
+
*/
|
|
115
|
+
export function Template(scenario) {
|
|
116
|
+
return new Proxy(scenario, {
|
|
117
|
+
apply: function (template, world, args) {
|
|
118
|
+
const scenario = template(...args) ;
|
|
119
|
+
const steps = scenario
|
|
120
|
+
.split('\n')
|
|
121
|
+
.map(step => step.trim())
|
|
122
|
+
.filter(Boolean);
|
|
123
|
+
for (const step of steps) {
|
|
124
|
+
world.executeStep(step);
|
|
125
|
+
}
|
|
126
|
+
},
|
|
127
|
+
})
|
|
128
|
+
}
|
|
129
|
+
|
|
106
130
|
|