@qavajs/playwright-runner-adapter 2.1.0 → 2.2.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 +4 -0
- package/adapter/PlaywrightWorld.d.ts +1 -1
- package/adapter/PlaywrightWorld.js +2 -1
- package/adapter/PlaywrightWorld.js.map +1 -1
- package/adapter/cucumberAdapter.js +4 -4
- package/adapter/cucumberAdapter.js.map +1 -1
- package/adapter/js/PlaywrightWorld.d.ts +31 -0
- package/adapter/js/PlaywrightWorld.js +55 -0
- package/adapter/js/Template.d.ts +10 -0
- package/adapter/js/Template.js +26 -0
- package/adapter/js/cucumberAdapter.d.ts +4 -0
- package/adapter/js/cucumberAdapter.js +278 -0
- package/adapter/js/filter.d.ts +19 -0
- package/adapter/js/filter.js +55 -0
- package/adapter/js/index.d.ts +5 -0
- package/adapter/js/index.js +21 -0
- package/adapter/js/loader.d.ts +14 -0
- package/adapter/js/loader.js +62 -0
- package/package.json +6 -6
- package/src/PlaywrightWorld.ts +3 -2
- package/src/cucumberAdapter.ts +5 -6
- package/tsconfig.js.json +23 -0
package/CHANGELOG.md
CHANGED
|
@@ -14,6 +14,10 @@ Check [Keep a Changelog](http://keepachangelog.com/) for recommendations on how
|
|
|
14
14
|
|
|
15
15
|
:microscope: - experimental
|
|
16
16
|
|
|
17
|
+
## [2.2.0]
|
|
18
|
+
- :rocket: added `request` into default fixture import
|
|
19
|
+
- :beetle: fixed `attach` method type
|
|
20
|
+
|
|
17
21
|
## [2.1.0]
|
|
18
22
|
- :rocket: made declaration of beforeAll/afterAll hooks optional to enable pure parallelism
|
|
19
23
|
|
|
@@ -45,10 +45,11 @@ class PlaywrightWorld extends TestWorld {
|
|
|
45
45
|
browser;
|
|
46
46
|
browserName;
|
|
47
47
|
request;
|
|
48
|
-
init = ({ browser, context, page }) => {
|
|
48
|
+
init = ({ browser, context, page, request }) => {
|
|
49
49
|
this.browser = browser;
|
|
50
50
|
this.context = context;
|
|
51
51
|
this.page = page;
|
|
52
|
+
this.request = request;
|
|
52
53
|
};
|
|
53
54
|
}
|
|
54
55
|
exports.PlaywrightWorld = PlaywrightWorld;
|
|
@@ -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,
|
|
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;IACzD,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;AA5BD,8BA4BC;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,7 @@ exports.defineConfig = defineConfig;
|
|
|
4
4
|
const loader_1 = require("./loader");
|
|
5
5
|
// Constants
|
|
6
6
|
const ANNOTATION_TYPES = {
|
|
7
|
-
TEST_ID: '
|
|
7
|
+
TEST_ID: '_testId',
|
|
8
8
|
NAME: 'name',
|
|
9
9
|
URI: 'uri',
|
|
10
10
|
TAGS: 'tags'
|
|
@@ -80,7 +80,7 @@ function log(data) {
|
|
|
80
80
|
function attach(body, details) {
|
|
81
81
|
const fileName = details?.fileName ?? DEFAULT_VALUES.ATTACHMENT_FILENAME;
|
|
82
82
|
const contentType = details?.mediaType ?? DEFAULT_VALUES.CONTENT_TYPE;
|
|
83
|
-
this.test.info().attach(fileName, { body, contentType });
|
|
83
|
+
return this.test.info().attach(fileName, { body, contentType });
|
|
84
84
|
}
|
|
85
85
|
/**
|
|
86
86
|
* Generates a human-readable step name with argument type indicator
|
|
@@ -128,8 +128,8 @@ function createTestAnnotations(testCase) {
|
|
|
128
128
|
return [
|
|
129
129
|
{ type: ANNOTATION_TYPES.NAME, description: testCase.name },
|
|
130
130
|
{ type: ANNOTATION_TYPES.URI, description: testCase.uri },
|
|
131
|
-
{ type: ANNOTATION_TYPES.
|
|
132
|
-
{ type: ANNOTATION_TYPES.
|
|
131
|
+
{ type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tags) },
|
|
132
|
+
{ type: ANNOTATION_TYPES.TEST_ID, description: testCase.id }
|
|
133
133
|
];
|
|
134
134
|
}
|
|
135
135
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cucumberAdapter.js","sourceRoot":"","sources":["../src/cucumberAdapter.ts"],"names":[],"mappings":";;AAuMA,
|
|
1
|
+
{"version":3,"file":"cucumberAdapter.js","sourceRoot":"","sources":["../src/cucumberAdapter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,31 @@
|
|
|
1
|
+
import { APIRequestContext, Browser, BrowserContext, Page } from '@playwright/test';
|
|
2
|
+
/**
|
|
3
|
+
* Cucumber world for playwright adapter
|
|
4
|
+
*/
|
|
5
|
+
export declare class TestWorld {
|
|
6
|
+
log: (data: any) => void;
|
|
7
|
+
attach: (data: any, details?: {
|
|
8
|
+
fileName?: string;
|
|
9
|
+
mediaType: string;
|
|
10
|
+
}) => Promise<void>;
|
|
11
|
+
parameters: string;
|
|
12
|
+
config: any;
|
|
13
|
+
supportCodeLibrary: any;
|
|
14
|
+
test: import("@playwright/test").TestType<import("@playwright/test").PlaywrightTestArgs & import("@playwright/test").PlaywrightTestOptions, import("@playwright/test").PlaywrightWorkerArgs & import("@playwright/test").PlaywrightWorkerOptions>;
|
|
15
|
+
expect: import("@playwright/test").Expect<{}>;
|
|
16
|
+
constructor(options: any);
|
|
17
|
+
executeStep(this: any, text: string, extraParam?: any): Promise<void>;
|
|
18
|
+
}
|
|
19
|
+
/**
|
|
20
|
+
* Cucumber Playwright world for playwright adapter
|
|
21
|
+
*/
|
|
22
|
+
export declare class PlaywrightWorld extends TestWorld {
|
|
23
|
+
page: Page;
|
|
24
|
+
context: BrowserContext;
|
|
25
|
+
browser: Browser;
|
|
26
|
+
browserName: string;
|
|
27
|
+
request: APIRequestContext;
|
|
28
|
+
init: ({
|
|
29
|
+
[fixture: string]: any;
|
|
30
|
+
});
|
|
31
|
+
}
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.PlaywrightWorld = exports.TestWorld = void 0;
|
|
4
|
+
const test_1 = require("@playwright/test");
|
|
5
|
+
/**
|
|
6
|
+
* Cucumber world for playwright adapter
|
|
7
|
+
*/
|
|
8
|
+
class TestWorld {
|
|
9
|
+
log;
|
|
10
|
+
attach;
|
|
11
|
+
parameters;
|
|
12
|
+
config;
|
|
13
|
+
supportCodeLibrary;
|
|
14
|
+
test = test_1.test;
|
|
15
|
+
expect = test_1.expect;
|
|
16
|
+
constructor(options) {
|
|
17
|
+
this.log = options.log;
|
|
18
|
+
this.attach = options.attach;
|
|
19
|
+
this.parameters = options.parameters;
|
|
20
|
+
this.supportCodeLibrary = options.supportCodeLibrary;
|
|
21
|
+
}
|
|
22
|
+
async executeStep(text, extraParam) {
|
|
23
|
+
const steps = this.supportCodeLibrary.stepDefinitions.filter((s) => s.matchesStepName(text));
|
|
24
|
+
if (steps.length === 0)
|
|
25
|
+
throw new Error(`Step "${text}" is not defined`);
|
|
26
|
+
if (steps.length > 1)
|
|
27
|
+
throw new Error(`Step "${text}" matches multiple step definitions`);
|
|
28
|
+
const step = steps.pop();
|
|
29
|
+
const { parameters } = await step.getInvocationParameters({ step: { text }, world: this });
|
|
30
|
+
try {
|
|
31
|
+
await step.code.apply(this, [...parameters, extraParam]);
|
|
32
|
+
}
|
|
33
|
+
catch (err) {
|
|
34
|
+
throw new Error(`${text}\n${err}`);
|
|
35
|
+
}
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
exports.TestWorld = TestWorld;
|
|
39
|
+
/**
|
|
40
|
+
* Cucumber Playwright world for playwright adapter
|
|
41
|
+
*/
|
|
42
|
+
class PlaywrightWorld extends TestWorld {
|
|
43
|
+
page;
|
|
44
|
+
context;
|
|
45
|
+
browser;
|
|
46
|
+
browserName;
|
|
47
|
+
request;
|
|
48
|
+
init = ({ browser, context, page, request }) => {
|
|
49
|
+
this.browser = browser;
|
|
50
|
+
this.context = context;
|
|
51
|
+
this.page = page;
|
|
52
|
+
this.request = request;
|
|
53
|
+
};
|
|
54
|
+
}
|
|
55
|
+
exports.PlaywrightWorld = PlaywrightWorld;
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Define template step
|
|
3
|
+
* @param {string} scenario - multiline string with steps
|
|
4
|
+
* @example
|
|
5
|
+
* When('I click {string} and verify {string}', Template((locator, expected) => `
|
|
6
|
+
* I click '${locator}'
|
|
7
|
+
* I expect '${locator} > Value' to equal '${expected}'
|
|
8
|
+
* `));
|
|
9
|
+
*/
|
|
10
|
+
export declare function Template(scenario: (...args: any[]) => string): (...args: string[]) => string;
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.Template = Template;
|
|
4
|
+
/**
|
|
5
|
+
* Define template step
|
|
6
|
+
* @param {string} scenario - multiline string with steps
|
|
7
|
+
* @example
|
|
8
|
+
* When('I click {string} and verify {string}', Template((locator, expected) => `
|
|
9
|
+
* I click '${locator}'
|
|
10
|
+
* I expect '${locator} > Value' to equal '${expected}'
|
|
11
|
+
* `));
|
|
12
|
+
*/
|
|
13
|
+
function Template(scenario) {
|
|
14
|
+
return new Proxy(scenario, {
|
|
15
|
+
apply: async function (template, world, args) {
|
|
16
|
+
const scenario = template(...args);
|
|
17
|
+
const steps = scenario
|
|
18
|
+
.split('\n')
|
|
19
|
+
.map(step => step.trim())
|
|
20
|
+
.filter(Boolean);
|
|
21
|
+
for (const step of steps) {
|
|
22
|
+
await world.executeStep(step);
|
|
23
|
+
}
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
@@ -0,0 +1,278 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.defineConfig = defineConfig;
|
|
4
|
+
const loader_1 = require("./loader");
|
|
5
|
+
// Constants
|
|
6
|
+
const ANNOTATION_TYPES = {
|
|
7
|
+
TEST_ID: '_testId',
|
|
8
|
+
NAME: 'name',
|
|
9
|
+
URI: 'uri',
|
|
10
|
+
TAGS: 'tags'
|
|
11
|
+
};
|
|
12
|
+
const HOOK_NAMES = {
|
|
13
|
+
BEFORE_ALL: 'Before All',
|
|
14
|
+
AFTER_ALL: 'After All',
|
|
15
|
+
BEFORE: 'Before',
|
|
16
|
+
AFTER: 'After',
|
|
17
|
+
BEFORE_STEP: 'Before Step',
|
|
18
|
+
AFTER_STEP: 'After Step',
|
|
19
|
+
WORLD: 'World',
|
|
20
|
+
BEFORE_HOOKS: 'Before Hooks',
|
|
21
|
+
AFTER_HOOKS: 'After Hooks'
|
|
22
|
+
};
|
|
23
|
+
const DEFAULT_VALUES = {
|
|
24
|
+
ATTACHMENT_FILENAME: 'attachment',
|
|
25
|
+
CONTENT_TYPE: 'text/plain',
|
|
26
|
+
COLUMN: 1,
|
|
27
|
+
TEST_CASE_ID: '0',
|
|
28
|
+
TEST_STEP_ID: '0'
|
|
29
|
+
};
|
|
30
|
+
const STEP_ARGUMENT_LABELS = {
|
|
31
|
+
DOC_STRING: ' [MultiLine]',
|
|
32
|
+
DATA_TABLE: ' [DataTable]'
|
|
33
|
+
};
|
|
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
|
+
/**
|
|
60
|
+
* Creates a location object from step definition
|
|
61
|
+
*/
|
|
62
|
+
function getLine(step) {
|
|
63
|
+
return {
|
|
64
|
+
location: {
|
|
65
|
+
column: DEFAULT_VALUES.COLUMN,
|
|
66
|
+
file: step.uri,
|
|
67
|
+
line: step.line
|
|
68
|
+
}
|
|
69
|
+
};
|
|
70
|
+
}
|
|
71
|
+
/**
|
|
72
|
+
* Logs data to console
|
|
73
|
+
*/
|
|
74
|
+
function log(data) {
|
|
75
|
+
console.log(data);
|
|
76
|
+
}
|
|
77
|
+
/**
|
|
78
|
+
* Attaches content to test report
|
|
79
|
+
*/
|
|
80
|
+
function attach(body, details) {
|
|
81
|
+
const fileName = details?.fileName ?? DEFAULT_VALUES.ATTACHMENT_FILENAME;
|
|
82
|
+
const contentType = details?.mediaType ?? DEFAULT_VALUES.CONTENT_TYPE;
|
|
83
|
+
return this.test.info().attach(fileName, { body, contentType });
|
|
84
|
+
}
|
|
85
|
+
/**
|
|
86
|
+
* Generates a human-readable step name with argument type indicator
|
|
87
|
+
*/
|
|
88
|
+
function stepName(pickleStep) {
|
|
89
|
+
let step = pickleStep.text;
|
|
90
|
+
if (pickleStep.argument) {
|
|
91
|
+
step += pickleStep.argument.docString
|
|
92
|
+
? STEP_ARGUMENT_LABELS.DOC_STRING
|
|
93
|
+
: STEP_ARGUMENT_LABELS.DATA_TABLE;
|
|
94
|
+
}
|
|
95
|
+
return step;
|
|
96
|
+
}
|
|
97
|
+
/**
|
|
98
|
+
* Executes before all hooks
|
|
99
|
+
*/
|
|
100
|
+
function executeBeforeAllHooks(test, hooks) {
|
|
101
|
+
if (hooks.length === 0)
|
|
102
|
+
return;
|
|
103
|
+
test.beforeAll(async () => {
|
|
104
|
+
for (const hook of hooks) {
|
|
105
|
+
const location = getLine(hook);
|
|
106
|
+
await test.step(HOOK_NAMES.BEFORE_ALL, () => hook.code.apply({}), location);
|
|
107
|
+
}
|
|
108
|
+
});
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* Executes after all hooks
|
|
112
|
+
*/
|
|
113
|
+
function executeAfterAllHooks(test, hooks) {
|
|
114
|
+
if (hooks.length === 0)
|
|
115
|
+
return;
|
|
116
|
+
test.afterAll(async () => {
|
|
117
|
+
for (const hook of hooks) {
|
|
118
|
+
const location = getLine(hook);
|
|
119
|
+
await test.step(HOOK_NAMES.AFTER_ALL, () => hook.code.apply({}), location);
|
|
120
|
+
}
|
|
121
|
+
});
|
|
122
|
+
}
|
|
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
|
+
/**
|
|
136
|
+
* Main configuration function that sets up Cucumber adapter for Playwright
|
|
137
|
+
*/
|
|
138
|
+
function defineConfig(config) {
|
|
139
|
+
const { features, supportCodeLibrary } = (0, loader_1.load)(config);
|
|
140
|
+
const fixture = new supportCodeLibrary.World({ config });
|
|
141
|
+
const test = fixture.test;
|
|
142
|
+
executeBeforeAllHooks(test, supportCodeLibrary.beforeTestRunHookDefinitions);
|
|
143
|
+
const worlds = new Map();
|
|
144
|
+
for (const feature of features) {
|
|
145
|
+
const tests = feature.tests;
|
|
146
|
+
test.describe(feature.feature, async () => {
|
|
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
|
+
});
|
|
180
|
+
for (const testCase of tests) {
|
|
181
|
+
const tag = [...new Set(testCase.tags.map((tag) => tag.name))];
|
|
182
|
+
const annotation = createTestAnnotations(testCase);
|
|
183
|
+
test(testCase.name, { tag, annotation }, async () => {
|
|
184
|
+
const world = worlds.get(testCase.id);
|
|
185
|
+
const result = { status: 'passed' };
|
|
186
|
+
for (const pickleStep of testCase.steps) {
|
|
187
|
+
if (result.status !== 'passed') {
|
|
188
|
+
break;
|
|
189
|
+
}
|
|
190
|
+
const matchingSteps = supportCodeLibrary.stepDefinitions
|
|
191
|
+
.filter((stepDef) => stepDef.matchesStepName(pickleStep.text));
|
|
192
|
+
if (matchingSteps.length === 0) {
|
|
193
|
+
throw new Error(`Step definition not found for: "${pickleStep.text}"`);
|
|
194
|
+
}
|
|
195
|
+
if (matchingSteps.length > 1) {
|
|
196
|
+
throw new Error(`Ambiguous step "${pickleStep.text}" matches ${matchingSteps.length} definitions`);
|
|
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);
|
|
220
|
+
}
|
|
221
|
+
catch (err) {
|
|
222
|
+
result.status = 'failed';
|
|
223
|
+
result.error = err;
|
|
224
|
+
throw err;
|
|
225
|
+
}
|
|
226
|
+
finally {
|
|
227
|
+
for (const afterStep of supportCodeLibrary.afterTestStepHookDefinitions) {
|
|
228
|
+
if (afterStep.appliesToTestCase(testCase)) {
|
|
229
|
+
const location = getLine(afterStep);
|
|
230
|
+
await test.step(HOOK_NAMES.AFTER_STEP, () => afterStep.code.apply(world, [{
|
|
231
|
+
gherkinDocument: feature.gherkinDocument,
|
|
232
|
+
testCaseStartedId: DEFAULT_VALUES.TEST_CASE_ID,
|
|
233
|
+
testStepId: DEFAULT_VALUES.TEST_STEP_ID,
|
|
234
|
+
pickle: testCase,
|
|
235
|
+
pickleStep,
|
|
236
|
+
result: {
|
|
237
|
+
duration: 0,
|
|
238
|
+
message: result.error?.message,
|
|
239
|
+
status: result.status.toUpperCase(),
|
|
240
|
+
exception: result.error
|
|
241
|
+
}
|
|
242
|
+
}]), location);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
}
|
|
246
|
+
}, location);
|
|
247
|
+
}
|
|
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);
|
|
268
|
+
}
|
|
269
|
+
}
|
|
270
|
+
});
|
|
271
|
+
test.afterEach(HOOK_NAMES.WORLD, async () => {
|
|
272
|
+
const testId = getTestId(test.info());
|
|
273
|
+
worlds.delete(testId);
|
|
274
|
+
});
|
|
275
|
+
});
|
|
276
|
+
}
|
|
277
|
+
executeAfterAllHooks(test, supportCodeLibrary.afterTestRunHookDefinitions);
|
|
278
|
+
}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Translate cucumber tag expression to playwright grep
|
|
3
|
+
* @param {string} tagExpression
|
|
4
|
+
* @example
|
|
5
|
+
* import { tags } from '@qavajs/playwright-runner-adapter';
|
|
6
|
+
* export default defineConfig({
|
|
7
|
+
* grep: tags('@oneTag and @anotherTag')
|
|
8
|
+
* });
|
|
9
|
+
*/
|
|
10
|
+
export declare function tags(tagExpression: string): RegExp;
|
|
11
|
+
/**
|
|
12
|
+
* Filter test cases by name
|
|
13
|
+
* @param {(testName: string) => boolean} predicate
|
|
14
|
+
* import { filter } from '@qavajs/playwright-runner-adapter';
|
|
15
|
+
* export default defineConfig({
|
|
16
|
+
* grep: filter(name => name.includes('login test'))
|
|
17
|
+
* });
|
|
18
|
+
*/
|
|
19
|
+
export declare function filter(predicate: (testName: string) => boolean): RegExp;
|
|
@@ -0,0 +1,55 @@
|
|
|
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
|
+
exports.tags = tags;
|
|
7
|
+
exports.filter = filter;
|
|
8
|
+
const tag_expressions_1 = __importDefault(require("@cucumber/tag-expressions"));
|
|
9
|
+
class TagExpression extends RegExp {
|
|
10
|
+
tagExpression;
|
|
11
|
+
expressionNode;
|
|
12
|
+
constructor(tagExpression) {
|
|
13
|
+
super('');
|
|
14
|
+
this.tagExpression = tagExpression;
|
|
15
|
+
this.expressionNode = (0, tag_expressions_1.default)(this.tagExpression);
|
|
16
|
+
}
|
|
17
|
+
test(testName) {
|
|
18
|
+
const tokens = testName.split(/\s+/);
|
|
19
|
+
return this.expressionNode.evaluate(tokens);
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Translate cucumber tag expression to playwright grep
|
|
24
|
+
* @param {string} tagExpression
|
|
25
|
+
* @example
|
|
26
|
+
* import { tags } from '@qavajs/playwright-runner-adapter';
|
|
27
|
+
* export default defineConfig({
|
|
28
|
+
* grep: tags('@oneTag and @anotherTag')
|
|
29
|
+
* });
|
|
30
|
+
*/
|
|
31
|
+
function tags(tagExpression) {
|
|
32
|
+
return new TagExpression(tagExpression);
|
|
33
|
+
}
|
|
34
|
+
class Filter extends RegExp {
|
|
35
|
+
predicate;
|
|
36
|
+
constructor(predicate) {
|
|
37
|
+
super('');
|
|
38
|
+
this.predicate = predicate;
|
|
39
|
+
this.predicate = predicate;
|
|
40
|
+
}
|
|
41
|
+
test(testName) {
|
|
42
|
+
return this.predicate(testName);
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
/**
|
|
46
|
+
* Filter test cases by name
|
|
47
|
+
* @param {(testName: string) => boolean} predicate
|
|
48
|
+
* import { filter } from '@qavajs/playwright-runner-adapter';
|
|
49
|
+
* export default defineConfig({
|
|
50
|
+
* grep: filter(name => name.includes('login test'))
|
|
51
|
+
* });
|
|
52
|
+
*/
|
|
53
|
+
function filter(predicate) {
|
|
54
|
+
return new Filter(predicate);
|
|
55
|
+
}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
3
|
+
if (k2 === undefined) k2 = k;
|
|
4
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
5
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
6
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
7
|
+
}
|
|
8
|
+
Object.defineProperty(o, k2, desc);
|
|
9
|
+
}) : (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
o[k2] = m[k];
|
|
12
|
+
}));
|
|
13
|
+
var __exportStar = (this && this.__exportStar) || function(m, exports) {
|
|
14
|
+
for (var p in m) if (p !== "default" && !Object.prototype.hasOwnProperty.call(exports, p)) __createBinding(exports, m, p);
|
|
15
|
+
};
|
|
16
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
17
|
+
__exportStar(require("./PlaywrightWorld"), exports);
|
|
18
|
+
__exportStar(require("./filter"), exports);
|
|
19
|
+
__exportStar(require("./Template"), exports);
|
|
20
|
+
__exportStar(require("@cucumber/cucumber"), exports);
|
|
21
|
+
__exportStar(require("./cucumberAdapter"), exports);
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
import type { Pickle, GherkinDocument } from '@cucumber/messages';
|
|
2
|
+
type Feature = {
|
|
3
|
+
feature?: string;
|
|
4
|
+
gherkinDocument: GherkinDocument;
|
|
5
|
+
tests: readonly Pickle[];
|
|
6
|
+
uri: string;
|
|
7
|
+
};
|
|
8
|
+
export declare function loadFeatures(globPattern: string[]): Feature[];
|
|
9
|
+
export declare function loadStepDefinitions(globPattern: string[]): import("@cucumber/cucumber/lib/support_code_library_builder/types").SupportCodeLibrary;
|
|
10
|
+
export declare function load(config: any): {
|
|
11
|
+
features: Feature[];
|
|
12
|
+
supportCodeLibrary: import("@cucumber/cucumber/lib/support_code_library_builder/types").SupportCodeLibrary;
|
|
13
|
+
};
|
|
14
|
+
export {};
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.loadFeatures = loadFeatures;
|
|
4
|
+
exports.loadStepDefinitions = loadStepDefinitions;
|
|
5
|
+
exports.load = load;
|
|
6
|
+
const node_fs_1 = require("node:fs");
|
|
7
|
+
const node_path_1 = require("node:path");
|
|
8
|
+
const node_crypto_1 = require("node:crypto");
|
|
9
|
+
const gherkin_1 = require("@cucumber/gherkin");
|
|
10
|
+
const cucumber_1 = require("@cucumber/cucumber");
|
|
11
|
+
const glob_1 = require("glob");
|
|
12
|
+
const PlaywrightWorld_1 = require("./PlaywrightWorld");
|
|
13
|
+
const uuidFn = () => (0, node_crypto_1.randomUUID)();
|
|
14
|
+
const builder = new gherkin_1.AstBuilder(uuidFn);
|
|
15
|
+
const matcher = new gherkin_1.GherkinClassicTokenMatcher();
|
|
16
|
+
const parser = new gherkin_1.Parser(builder, matcher);
|
|
17
|
+
function duplicates(tests) {
|
|
18
|
+
const counts = {};
|
|
19
|
+
return tests.map(item => {
|
|
20
|
+
const name = item.name;
|
|
21
|
+
if (!(name in counts)) {
|
|
22
|
+
counts[name] = 1;
|
|
23
|
+
}
|
|
24
|
+
if (counts[name] > 1) {
|
|
25
|
+
item.name = `${item.name} ${counts[name]}`;
|
|
26
|
+
}
|
|
27
|
+
counts[name] = counts[name] + 1;
|
|
28
|
+
return item;
|
|
29
|
+
});
|
|
30
|
+
}
|
|
31
|
+
function loadFeatures(globPattern) {
|
|
32
|
+
const files = (0, glob_1.globSync)(globPattern);
|
|
33
|
+
return files.map(file => {
|
|
34
|
+
const filePath = (0, node_path_1.resolve)(file);
|
|
35
|
+
const gherkinDocument = parser.parse((0, node_fs_1.readFileSync)(filePath, 'utf-8'));
|
|
36
|
+
return {
|
|
37
|
+
feature: gherkinDocument.feature?.name,
|
|
38
|
+
uri: filePath,
|
|
39
|
+
gherkinDocument,
|
|
40
|
+
tests: duplicates((0, gherkin_1.compile)(gherkinDocument, file, uuidFn))
|
|
41
|
+
};
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
function loadStepDefinitions(globPattern) {
|
|
45
|
+
cucumber_1.supportCodeLibraryBuilder.reset(process.cwd(), uuidFn);
|
|
46
|
+
cucumber_1.supportCodeLibraryBuilder.methods.setWorldConstructor(PlaywrightWorld_1.PlaywrightWorld);
|
|
47
|
+
const files = (0, glob_1.globSync)(globPattern);
|
|
48
|
+
for (const file of files) {
|
|
49
|
+
const filePath = (0, node_path_1.resolve)(file);
|
|
50
|
+
require(filePath);
|
|
51
|
+
}
|
|
52
|
+
return cucumber_1.supportCodeLibraryBuilder.finalize();
|
|
53
|
+
}
|
|
54
|
+
function load(config) {
|
|
55
|
+
const features = loadFeatures(config.paths);
|
|
56
|
+
const supportCodeLibrary = loadStepDefinitions([
|
|
57
|
+
...(config.requireModules ?? []),
|
|
58
|
+
...(config.require ?? []),
|
|
59
|
+
...(config.import ?? [])
|
|
60
|
+
]);
|
|
61
|
+
return { features, supportCodeLibrary };
|
|
62
|
+
}
|
package/package.json
CHANGED
|
@@ -1,13 +1,13 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@qavajs/playwright-runner-adapter",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.2.0",
|
|
4
4
|
"description": "adapter for playwright test runner",
|
|
5
5
|
"main": "adapter/index.js",
|
|
6
6
|
"types": "adapter/index.d.ts",
|
|
7
7
|
"scripts": {
|
|
8
|
-
"build": "tsc",
|
|
8
|
+
"build": "tsc && tsc --project tsconfig.js.json",
|
|
9
9
|
"test:ui": "playwright test --config test/playwright.config.ts --ui",
|
|
10
|
-
"test:e2e": "playwright test --config test/playwright
|
|
10
|
+
"test:e2e": "playwright test --config test/playwright.config.ts --project parallel --project serial"
|
|
11
11
|
},
|
|
12
12
|
"author": "Alexandr Galichenko",
|
|
13
13
|
"license": "MIT",
|
|
@@ -21,12 +21,12 @@
|
|
|
21
21
|
"dependencies": {
|
|
22
22
|
"@cucumber/gherkin": "^38.0.0",
|
|
23
23
|
"@cucumber/tag-expressions": "^9.0.0",
|
|
24
|
-
"glob": "^13.0.
|
|
24
|
+
"glob": "^13.0.3",
|
|
25
25
|
"@cucumber/cucumber": "^12.6.0"
|
|
26
26
|
},
|
|
27
27
|
"devDependencies": {
|
|
28
|
-
"@playwright/test": "^1.58.
|
|
29
|
-
"@types/node": "^25.2.
|
|
28
|
+
"@playwright/test": "^1.58.2",
|
|
29
|
+
"@types/node": "^25.2.3",
|
|
30
30
|
"typescript": "^5.9.3"
|
|
31
31
|
},
|
|
32
32
|
"keywords": [
|
package/src/PlaywrightWorld.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { APIRequestContext, Browser, BrowserContext, Page, test, expect } from '
|
|
|
5
5
|
*/
|
|
6
6
|
export class TestWorld {
|
|
7
7
|
log!: (data: any) => void;
|
|
8
|
-
attach!: (data: any, details?: { fileName?: string, mediaType: string }) => void
|
|
8
|
+
attach!: (data: any, details?: { fileName?: string, mediaType: string }) => Promise<void>;
|
|
9
9
|
parameters!: string;
|
|
10
10
|
config: any;
|
|
11
11
|
supportCodeLibrary!: any;
|
|
@@ -43,9 +43,10 @@ export class PlaywrightWorld extends TestWorld {
|
|
|
43
43
|
browserName!: string;
|
|
44
44
|
request!: APIRequestContext;
|
|
45
45
|
|
|
46
|
-
init: ({ [fixture: string]: any }) = ({ browser, context, page }: { browser: Browser, context: BrowserContext, page: Page }) => {
|
|
46
|
+
init: ({ [fixture: string]: any }) = ({ browser, context, page, request }: { browser: Browser, context: BrowserContext, page: Page, request: APIRequestContext }) => {
|
|
47
47
|
this.browser = browser;
|
|
48
48
|
this.context = context;
|
|
49
49
|
this.page = page;
|
|
50
|
+
this.request = request;
|
|
50
51
|
}
|
|
51
52
|
}
|
package/src/cucumberAdapter.ts
CHANGED
|
@@ -4,7 +4,7 @@ import type {ITestCaseHookParameter} from '@cucumber/cucumber';
|
|
|
4
4
|
|
|
5
5
|
// Constants
|
|
6
6
|
const ANNOTATION_TYPES = {
|
|
7
|
-
TEST_ID: '
|
|
7
|
+
TEST_ID: '_testId',
|
|
8
8
|
NAME: 'name',
|
|
9
9
|
URI: 'uri',
|
|
10
10
|
TAGS: 'tags'
|
|
@@ -116,10 +116,10 @@ function attach(
|
|
|
116
116
|
this: { test: { info: () => TestInfo } },
|
|
117
117
|
body: string | Buffer,
|
|
118
118
|
details?: { fileName?: string; mediaType?: string }
|
|
119
|
-
): void {
|
|
119
|
+
): Promise<void> {
|
|
120
120
|
const fileName = details?.fileName ?? DEFAULT_VALUES.ATTACHMENT_FILENAME;
|
|
121
121
|
const contentType = details?.mediaType ?? DEFAULT_VALUES.CONTENT_TYPE;
|
|
122
|
-
this.test.info().attach(fileName, { body, contentType });
|
|
122
|
+
return this.test.info().attach(fileName, { body, contentType });
|
|
123
123
|
}
|
|
124
124
|
|
|
125
125
|
/**
|
|
@@ -189,8 +189,8 @@ function createTestAnnotations(testCase: any): any[] {
|
|
|
189
189
|
return [
|
|
190
190
|
{ type: ANNOTATION_TYPES.NAME, description: testCase.name },
|
|
191
191
|
{ type: ANNOTATION_TYPES.URI, description: testCase.uri },
|
|
192
|
-
{ type: ANNOTATION_TYPES.
|
|
193
|
-
{ type: ANNOTATION_TYPES.
|
|
192
|
+
{ type: ANNOTATION_TYPES.TAGS, description: JSON.stringify(tags) },
|
|
193
|
+
{ type: ANNOTATION_TYPES.TEST_ID, description: testCase.id }
|
|
194
194
|
];
|
|
195
195
|
}
|
|
196
196
|
|
|
@@ -202,7 +202,6 @@ export function defineConfig(config: any): any {
|
|
|
202
202
|
|
|
203
203
|
const fixture = new supportCodeLibrary.World({config});
|
|
204
204
|
const test: TestType<any, any> = fixture.test;
|
|
205
|
-
|
|
206
205
|
executeBeforeAllHooks(test, supportCodeLibrary.beforeTestRunHookDefinitions);
|
|
207
206
|
|
|
208
207
|
const worlds = new Map<string, any>();
|
package/tsconfig.js.json
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
{
|
|
2
|
+
"include": [
|
|
3
|
+
"src/**/*.ts"
|
|
4
|
+
],
|
|
5
|
+
"exclude": [
|
|
6
|
+
"test/**/*.spec.ts"
|
|
7
|
+
],
|
|
8
|
+
"compilerOptions": {
|
|
9
|
+
"target": "es2023",
|
|
10
|
+
"module": "node16",
|
|
11
|
+
"moduleResolution": "node16",
|
|
12
|
+
"outDir": "./adapter/js",
|
|
13
|
+
"esModuleInterop": true,
|
|
14
|
+
"sourceMap": false,
|
|
15
|
+
"forceConsistentCasingInFileNames": true,
|
|
16
|
+
"strict": true,
|
|
17
|
+
"skipLibCheck": true,
|
|
18
|
+
"declaration": true,
|
|
19
|
+
"types": [
|
|
20
|
+
"node"
|
|
21
|
+
]
|
|
22
|
+
}
|
|
23
|
+
}
|