@gnuechtel/nx-cucumber 0.0.35

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/README.md ADDED
@@ -0,0 +1,11 @@
1
+ # nx-cucumber
2
+
3
+ This library was generated with [Nx](https://nx.dev).
4
+
5
+ ## Building
6
+
7
+ Run `nx build nx-cucumber` to build the library.
8
+
9
+ ## Running unit tests
10
+
11
+ Run `nx test nx-cucumber` to execute the unit tests via [Jest](https://jestjs.io).
package/executors.json ADDED
@@ -0,0 +1,10 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "executors": {
4
+ "cucumber-js": {
5
+ "implementation": "./src/executors/cucumber-js/executor",
6
+ "schema": "./src/executors/cucumber-js/schema.json",
7
+ "description": "cucumber-js executor"
8
+ }
9
+ }
10
+ }
@@ -0,0 +1,6 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "name": "nx-cucumber",
4
+ "version": "0.0.1",
5
+ "generators": {}
6
+ }
package/package.json ADDED
@@ -0,0 +1,19 @@
1
+ {
2
+ "name": "@gnuechtel/nx-cucumber",
3
+ "version": "0.0.35",
4
+ "dependencies": {
5
+ "tslib": "^2.3.0",
6
+ "cucumber-html-reporter": "^7.1.0",
7
+ "@cucumber/messages": "^22.0.0",
8
+ "@nx/devkit": "^16.0.0",
9
+ "@gnuechtel/shared-nx": "^0.0.33",
10
+ "@gnuechtel/shared-coverage": "^0.0.33",
11
+ "@cucumber/cucumber": "^9.3.0",
12
+ "playwright": "^1.21.1"
13
+ },
14
+ "type": "commonjs",
15
+ "main": "./src/index.js",
16
+ "generators": "./generators.json",
17
+ "executors": "./executors.json",
18
+ "typings": "./src/index.d.ts"
19
+ }
@@ -0,0 +1,2 @@
1
+ import { TestRunOptions } from './test-run-options';
2
+ export declare function createCucumberHtmlReport(options: TestRunOptions): boolean;
@@ -0,0 +1,54 @@
1
+ "use strict";
2
+ /*
3
+ * Helper module to generate HTML report from Cucumber JSON results
4
+ */
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.createCucumberHtmlReport = void 0;
7
+ const tslib_1 = require("tslib");
8
+ /* eslint-disable @typescript-eslint/no-explicit-any */
9
+ const cucumber_html_reporter_1 = tslib_1.__importDefault(require("cucumber-html-reporter"));
10
+ const fs_1 = tslib_1.__importDefault(require("fs"));
11
+ const path_1 = tslib_1.__importDefault(require("path"));
12
+ const cucumber_runner_1 = require("./cucumber-runner");
13
+ function createCucumberHtmlReport(options) {
14
+ var _a, _b;
15
+ if (!options.outputDirectory)
16
+ throw new Error("Output directory is not set");
17
+ const e2eApplicationName = path_1.default.basename(options.outputDirectory);
18
+ const projectName = e2eApplicationName.replace(/-e2e$/, '');
19
+ const testKind = options.testRunner != 'core' ? 'End-to-end tests' : 'Component tests';
20
+ const reportTitle = `${testKind} ${projectName}`;
21
+ const metadata = Object.assign(Object.assign({ 'Project name': projectName, 'Test kind': testKind, 'Test application': e2eApplicationName, 'Test runner': options.testRunner, URL: options.baseUrl, 'Features directory': options.featuresDirectory }, (options.tags ? { Tags: options.tags } : {})), (((_a = options.name) === null || _a === void 0 ? void 0 : _a.length) && ((_b = options.name) === null || _b === void 0 ? void 0 : _b.length) > 0 ? { 'Name filter': options.name.join(', ') } : {}));
22
+ for (const env in options.env) {
23
+ // Add every environment variable as single meta data
24
+ metadata[env] = options.env[env];
25
+ }
26
+ const { cucumberJsonDirectory: inputDir, htmlDirectory: outputDir } = (0, cucumber_runner_1.getOutputDirectories)(options.outputDirectory);
27
+ if (!fs_1.default.existsSync(outputDir)) {
28
+ fs_1.default.mkdirSync(outputDir, { recursive: true });
29
+ }
30
+ if (!fs_1.default.existsSync(inputDir)) {
31
+ console.error(`Cucumber JSON directory ${inputDir} does not exist`);
32
+ return false;
33
+ }
34
+ try {
35
+ cucumber_html_reporter_1.default.generate({
36
+ name: reportTitle,
37
+ brandTitle: ' ',
38
+ theme: 'bootstrap',
39
+ columnLayout: 1,
40
+ jsonDir: inputDir,
41
+ output: `${outputDir}/cucumber-test-report.html`,
42
+ reportSuiteAsScenarios: true,
43
+ launchReport: false,
44
+ metadata,
45
+ });
46
+ }
47
+ catch (e) {
48
+ console.error(`Could not create cucumber HTML report: ${e === null || e === void 0 ? void 0 : e.message}`);
49
+ return false;
50
+ }
51
+ return true;
52
+ }
53
+ exports.createCucumberHtmlReport = createCucumberHtmlReport;
54
+ //# sourceMappingURL=cucumber-report-html.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cucumber-report-html.js","sourceRoot":"","sources":["../../../../../libs/nx-cucumber/src/core/cucumber-report-html.ts"],"names":[],"mappings":";AAAA;;GAEG;;;;AAEH,uDAAuD;AAEvD,4FAA8C;AAC9C,oDAAoB;AACpB,wDAAwB;AACxB,uDAAyD;AAGzD,SAAgB,wBAAwB,CAAC,OAAuB;;IAC9D,IAAI,CAAC,OAAO,CAAC,eAAe;QAAE,MAAM,IAAI,KAAK,CAAC,6BAA6B,CAAC,CAAC;IAC7E,MAAM,kBAAkB,GAAG,cAAI,CAAC,QAAQ,CAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IAClE,MAAM,WAAW,GAAG,kBAAkB,CAAC,OAAO,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC;IAC5D,MAAM,QAAQ,GAAG,OAAO,CAAC,UAAU,IAAI,MAAM,CAAC,CAAC,CAAC,kBAAkB,CAAC,CAAC,CAAC,iBAAiB,CAAC;IACvF,MAAM,WAAW,GAAG,GAAG,QAAQ,IAAI,WAAW,EAAE,CAAC;IACjD,MAAM,QAAQ,GAAG,8BACf,cAAc,EAAE,WAAW,EAC3B,WAAW,EAAE,QAAQ,EACrB,kBAAkB,EAAE,kBAAkB,EACtC,aAAa,EAAE,OAAO,CAAC,UAAU,EACjC,GAAG,EAAE,OAAO,CAAC,OAAO,EACpB,oBAAoB,EAAE,OAAO,CAAC,iBAAiB,IAC5C,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,OAAO,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,GAC5C,CAAC,CAAA,MAAA,OAAO,CAAC,IAAI,0CAAE,MAAM,KAAI,CAAA,MAAA,OAAO,CAAC,IAAI,0CAAE,MAAM,IAAG,CAAC,CAAC,CAAC,CAAC,EAAE,aAAa,EAAE,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,EAAE,CAAC,CACjG,CAAC;IACT,KAAK,MAAM,GAAG,IAAI,OAAO,CAAC,GAAG,EAAE;QAC7B,qDAAqD;QACrD,QAAQ,CAAC,GAAG,CAAC,GAAG,OAAO,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;KAClC;IAED,MAAM,EAAE,qBAAqB,EAAE,QAAQ,EAAE,aAAa,EAAE,SAAS,EAAE,GAAG,IAAA,sCAAoB,EAAC,OAAO,CAAC,eAAe,CAAC,CAAC;IACpH,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,SAAS,CAAC,EAAE;QAC7B,YAAE,CAAC,SAAS,CAAC,SAAS,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;KAC9C;IAED,IAAI,CAAC,YAAE,CAAC,UAAU,CAAC,QAAQ,CAAC,EAAE;QAC5B,OAAO,CAAC,KAAK,CAAC,2BAA2B,QAAQ,iBAAiB,CAAC,CAAC;QACpE,OAAO,KAAK,CAAC;KACd;IAED,IAAI;QACF,gCAAQ,CAAC,QAAQ,CAAC;YAChB,IAAI,EAAE,WAAW;YACjB,UAAU,EAAE,GAAG;YACf,KAAK,EAAE,WAAW;YAClB,YAAY,EAAE,CAAC;YACf,OAAO,EAAE,QAAQ;YACjB,MAAM,EAAE,GAAG,SAAS,4BAA4B;YAChD,sBAAsB,EAAE,IAAI;YAC5B,YAAY,EAAE,KAAK;YACnB,QAAQ;SACT,CAAC,CAAC;KACJ;IAAC,OAAO,CAAM,EAAE;QACf,OAAO,CAAC,KAAK,CAAC,0CAA0C,CAAC,aAAD,CAAC,uBAAD,CAAC,CAAE,OAAO,EAAE,CAAC,CAAC;QACtE,OAAO,KAAK,CAAC;KACd;IAED,OAAO,IAAI,CAAC;AACd,CAAC;AAjDD,4DAiDC"}
@@ -0,0 +1,24 @@
1
+ import { IRunEnvironment, IRunOptions } from '@cucumber/cucumber/api';
2
+ import { TestRunOptions } from './test-run-options';
3
+ /**
4
+ * Run cucumber either regularly or in watch mode.
5
+ * Watch mode will be enabled, if the related command line parameter is set.
6
+ *
7
+ * @returns `true` on successful execution, `false` otherwise
8
+ */
9
+ export declare function runCucumber(options: TestRunOptions, cwd: string): Promise<boolean>;
10
+ /**
11
+ * Runs **Cucumber.js** via the interfaces from `@cucumber/cucumber/api`.
12
+ * Also creates JUnit and HTML reports.
13
+ * @param options the cucumber options which are used to build the configuration and are passed as world parameters
14
+ * @returns `true` on successful execution, `false` otherwise
15
+ */
16
+ export declare function runCucumberInternal(options: TestRunOptions, configuration: IRunOptions, environment: IRunEnvironment): Promise<boolean>;
17
+ export declare function getOutputDirectories(outputDirectory: string): {
18
+ reportsDirectory: string;
19
+ htmlDirectory: string;
20
+ cucumberJsonDirectory: string;
21
+ testResultsDirectory: string;
22
+ screenshotsDirectory: string;
23
+ videosDirectory: string;
24
+ };
@@ -0,0 +1,161 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.getOutputDirectories = exports.runCucumberInternal = exports.runCucumber = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const api_1 = require("@cucumber/cucumber/api");
6
+ const fs_1 = tslib_1.__importDefault(require("fs"));
7
+ const path_1 = tslib_1.__importDefault(require("path"));
8
+ const cucumber_report_html_1 = require("./cucumber-report-html");
9
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
10
+ const debug = require('debug')('e2e:cucumber');
11
+ const rootDirectory = path_1.default.resolve(path_1.default.join(__dirname, '..', '..', '..', '..', '..'));
12
+ /**
13
+ * Run cucumber either regularly or in watch mode.
14
+ * Watch mode will be enabled, if the related command line parameter is set.
15
+ *
16
+ * @returns `true` on successful execution, `false` otherwise
17
+ */
18
+ function runCucumber(options, cwd) {
19
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
20
+ const cucumberEnvironment = { cwd };
21
+ const cucumberConfiguration = yield buildCucumberConfiguration(options, cucumberEnvironment);
22
+ if (!options.outputDirectory)
23
+ throw new Error("Output directory is not set");
24
+ createOutputDirectories(options.outputDirectory);
25
+ if (!options.watch) {
26
+ // Run Cucumber.js one time
27
+ return yield runCucumberInternal(options, cucumberConfiguration, cucumberEnvironment);
28
+ }
29
+ // Run Cucumber.js in watch mode
30
+ return yield runCucumberWatch(options, cucumberConfiguration, cucumberEnvironment);
31
+ });
32
+ }
33
+ exports.runCucumber = runCucumber;
34
+ function runCucumberWatch(options, configuration, environment) {
35
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
36
+ process.stdout.write('Starting Cucumber.js in watch mode ...\n');
37
+ let success = false;
38
+ do {
39
+ success = yield runCucumberInternal(options, configuration, environment);
40
+ } while (!(yield watch()));
41
+ const message = success ? 'successfully' : 'with error';
42
+ process.stdout.write(`Watch mode finished ${message}\n`);
43
+ return success;
44
+ });
45
+ }
46
+ /**
47
+ * Runs **Cucumber.js** via the interfaces from `@cucumber/cucumber/api`.
48
+ * Also creates JUnit and HTML reports.
49
+ * @param options the cucumber options which are used to build the configuration and are passed as world parameters
50
+ * @returns `true` on successful execution, `false` otherwise
51
+ */
52
+ function runCucumberInternal(options, configuration, environment) {
53
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
54
+ const onMessage = (message) => tslib_1.__awaiter(this, void 0, void 0, function* () {
55
+ if (message.testStepFinished) {
56
+ debug(message.testStepFinished.testStepResult.status); // For now, we only print out the test step result
57
+ }
58
+ });
59
+ const { success } = yield (0, api_1.runCucumber)(configuration, environment, onMessage);
60
+ // We create a beautiful HTML report
61
+ const successReport = (0, cucumber_report_html_1.createCucumberHtmlReport)(options);
62
+ return success && successReport;
63
+ });
64
+ }
65
+ exports.runCucumberInternal = runCucumberInternal;
66
+ function getOutputDirectories(outputDirectory) {
67
+ const fullOutputDirectory = path_1.default.join(rootDirectory, outputDirectory);
68
+ const reportsDirectory = path_1.default.join(fullOutputDirectory, 'reports');
69
+ const testResultsDirectory = path_1.default.join(reportsDirectory, 'test-results');
70
+ const screenshotsDirectory = path_1.default.join(fullOutputDirectory, 'screenshots');
71
+ const videosDirectory = path_1.default.join(fullOutputDirectory, 'videos');
72
+ const cucumberJsonDirectory = path_1.default.join(reportsDirectory, 'cucumber-json');
73
+ const htmlDirectory = path_1.default.join(reportsDirectory, 'html');
74
+ return {
75
+ reportsDirectory,
76
+ htmlDirectory,
77
+ cucumberJsonDirectory,
78
+ testResultsDirectory,
79
+ screenshotsDirectory,
80
+ videosDirectory,
81
+ };
82
+ }
83
+ exports.getOutputDirectories = getOutputDirectories;
84
+ function createOutputDirectories(outputDirectory) {
85
+ const { reportsDirectory, cucumberJsonDirectory, testResultsDirectory, screenshotsDirectory, videosDirectory } = getOutputDirectories(outputDirectory);
86
+ createNonExistingDirectory(reportsDirectory);
87
+ createNonExistingDirectory(cucumberJsonDirectory);
88
+ createNonExistingDirectory(testResultsDirectory);
89
+ createNonExistingDirectory(screenshotsDirectory);
90
+ createNonExistingDirectory(videosDirectory);
91
+ }
92
+ function buildCucumberConfiguration(options, environment) {
93
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
94
+ for (const envKey in options.env) {
95
+ process.env[envKey] = options.env[envKey]; // Set process environment variables from options
96
+ }
97
+ if (options.testRunner == 'playwright' && options.debug) {
98
+ process.env['PWDEBUG'] = '1'; // Use playwright inspector
99
+ }
100
+ // We have to give cucumber a hint where to find the typescript configuration
101
+ // We use the environment variable TS_NODE_PROJECT to pass the config to the cucumber runtime
102
+ // If no tsConfig option is set, we use current-working-directory + 'tsconfig.json'
103
+ process.env['TS_NODE_PROJECT'] = options.tsConfig || `${environment.cwd}/tsconfig.json`;
104
+ if (!options.outputDirectory)
105
+ throw new Error("Output directory is not set");
106
+ const { cucumberJsonDirectory, htmlDirectory, testResultsDirectory } = getOutputDirectories(options.outputDirectory);
107
+ const provided = {
108
+ format: [
109
+ `json:${path_1.default.join(cucumberJsonDirectory, 'cucumber-test-report.json')}`,
110
+ 'summary',
111
+ `html:${path_1.default.join(htmlDirectory, 'cucumber-test-report-builtin.html')}`,
112
+ `junit:${path_1.default.join(testResultsDirectory, 'cucumber-test-report.xml')}`,
113
+ ],
114
+ publishQuiet: true,
115
+ formatOptions: { snippetInterface: 'async-await' },
116
+ };
117
+ const { runConfiguration } = yield (0, api_1.loadConfiguration)({ provided });
118
+ runConfiguration.sources.paths = [path_1.default.join(rootDirectory, `${options.featuresDirectory}/**/*.{feature,feature.md}`)];
119
+ runConfiguration.sources.tagExpression = options.tags || '';
120
+ runConfiguration.sources.names = options.name || [];
121
+ runConfiguration.runtime.worldParameters = options;
122
+ const require = ['src/steps/**/*.[jt]s']; // Load step files
123
+ if (options.testRunner == 'playwright') {
124
+ // Register playwright hooks (and playwright world implicitly)
125
+ require.push(path_1.default.resolve(path_1.default.join(__dirname, '../playwright/playwright-hooks.js')));
126
+ }
127
+ // Load typescript config and typescript paths (either default tsconfig.json or options.tsConfig)
128
+ runConfiguration.support.requireModules = ['ts-node/register', 'tsconfig-paths/register'];
129
+ runConfiguration.support.requirePaths = require;
130
+ const support = yield (0, api_1.loadSupport)(runConfiguration, environment);
131
+ return Object.assign(Object.assign({}, runConfiguration), { support });
132
+ });
133
+ }
134
+ function createNonExistingDirectory(directory) {
135
+ if (!fs_1.default.existsSync(directory)) {
136
+ // Always create non-existing directory recursively
137
+ fs_1.default.mkdirSync(directory, { recursive: true });
138
+ }
139
+ }
140
+ function watch(exitKey = 'q') {
141
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
142
+ process.stdout.write(`\n\nWatch mode is active\nPress '${exitKey}' to exit or any other key to continue\n\n`);
143
+ if (process.stdin.isTTY) {
144
+ process.stdin.setRawMode(true);
145
+ }
146
+ process.stdin.setEncoding('utf8');
147
+ process.stdin.resume();
148
+ return new Promise((resolve) => process.stdin.once('data', (key) => {
149
+ const rKey = key.replace(/\s+/, '');
150
+ if (process.stdin.isTTY) {
151
+ process.stdin.setRawMode(false);
152
+ }
153
+ process.stdin.pause();
154
+ if (key === '\u0003' || rKey === exitKey) {
155
+ resolve(true);
156
+ }
157
+ resolve(false);
158
+ }));
159
+ });
160
+ }
161
+ //# sourceMappingURL=cucumber-runner.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"cucumber-runner.js","sourceRoot":"","sources":["../../../../../libs/nx-cucumber/src/core/cucumber-runner.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,21 @@
1
+ export interface TestRunOptions {
2
+ baseUrl?: string;
3
+ watch: boolean;
4
+ debug?: boolean;
5
+ featuresDirectory?: string;
6
+ tags?: string;
7
+ name?: string[];
8
+ outputDirectory?: string;
9
+ disableAnimations: boolean;
10
+ disableCoverage: boolean;
11
+ disableScreenshotAttachments: boolean;
12
+ disableScreenshotFiles: boolean;
13
+ disableVideoAttachments: boolean;
14
+ disableVideoFiles: boolean;
15
+ disableJavaScript: boolean;
16
+ default: Omit<TestRunOptions, 'default'>;
17
+ testRunner?: TestRunner;
18
+ env?: Record<string, string>;
19
+ tsConfig?: string;
20
+ }
21
+ export type TestRunner = 'core' | 'playwright';
@@ -0,0 +1,3 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ //# sourceMappingURL=test-run-options.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test-run-options.js","sourceRoot":"","sources":["../../../../../libs/nx-cucumber/src/core/test-run-options.ts"],"names":[],"mappings":""}
@@ -0,0 +1,5 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ import { CucumberJsExecutorSchema } from './schema';
3
+ export default function cucumberExecutor(inputOptions: CucumberJsExecutorSchema, context: ExecutorContext): Promise<{
4
+ success: boolean;
5
+ }>;
@@ -0,0 +1,144 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const devkit_1 = require("@nx/devkit");
5
+ const shared_nx_1 = require("@gnuechtel/shared-nx");
6
+ const cucumber_runner_1 = require("../../core/cucumber-runner");
7
+ function cucumberExecutor(inputOptions, context) {
8
+ var _a, e_1, _b, _c;
9
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
+ if (!context || !context.workspace || !context.projectName)
11
+ throw new Error('Invalid executor state');
12
+ const project = context.workspace.projects[context.projectName];
13
+ const projectRoot = project.root;
14
+ const cucumberCwd = projectRoot;
15
+ const cucumberOptions = buildCucumberOptions(inputOptions, cucumberCwd);
16
+ const options = Object.assign(Object.assign({}, inputOptions), cucumberOptions);
17
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
18
+ const { default: _ } = options, optionsDisplay = tslib_1.__rest(options, ["default"]);
19
+ console.log('Cucumber execution directory: %s', cucumberCwd);
20
+ console.log('Executor options: %o', optionsDisplay);
21
+ console.log('');
22
+ let success = false;
23
+ if (!options.devServerKind) {
24
+ try {
25
+ // -----------------------------------------------------------------------
26
+ // Method 1: Nx way to start a dev server
27
+ // -----------------------------------------------------------------------
28
+ //
29
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
30
+ for (var _d = true, _e = tslib_1.__asyncValues((0, shared_nx_1.startDevServer)(options, context)), _f; _f = yield _e.next(), _a = _f.done, !_a; _d = true) {
31
+ _c = _f.value;
32
+ _d = false;
33
+ const baseUrl = _c;
34
+ try {
35
+ success = yield (0, cucumber_runner_1.runCucumber)(options, cucumberCwd);
36
+ break;
37
+ }
38
+ catch (e) {
39
+ devkit_1.logger.error(e.message);
40
+ break;
41
+ }
42
+ }
43
+ }
44
+ catch (e_1_1) { e_1 = { error: e_1_1 }; }
45
+ finally {
46
+ try {
47
+ if (!_d && !_a && (_b = _e.return)) yield _b.call(_e);
48
+ }
49
+ finally { if (e_1) throw e_1.error; }
50
+ }
51
+ return { success }; // End of method 1
52
+ }
53
+ if (!options.devServerTarget) {
54
+ throw new Error('Required dev server target is not set');
55
+ }
56
+ // Use wait-on
57
+ let alreadyRunning = false;
58
+ try {
59
+ // We support already running servers
60
+ // Maybe it was started by the developer or it was started by another cucumber execution.
61
+ yield (0, shared_nx_1.waitForUrl)(options.baseUrl, 1000);
62
+ console.log(`Server is already running on ${options.baseUrl}`);
63
+ alreadyRunning = true;
64
+ }
65
+ catch (err) {
66
+ console.log(`Server is not yet running on ${options.baseUrl}`);
67
+ }
68
+ if (!alreadyRunning) {
69
+ // -----------------------------------------------------------------------
70
+ // Method 2: Wait-on, but not yet running
71
+ // -----------------------------------------------------------------------
72
+ //
73
+ // Create process, but do not await it
74
+ // Since node.js is terrible about process killing, the process will be alive after cucumber execution
75
+ const runDevServer = (0, shared_nx_1.createProcess)(`npx nx run ${options.devServerTarget}`, '', cucumberCwd);
76
+ // Wait until server is ready
77
+ yield (0, shared_nx_1.waitForUrl)(options.baseUrl);
78
+ try {
79
+ // Start a promise race where run-cucumber will always win
80
+ success = yield Promise.race([runDevServer, (0, cucumber_runner_1.runCucumber)(options, cucumberCwd)]);
81
+ }
82
+ catch (e) {
83
+ devkit_1.logger.error(e.message);
84
+ }
85
+ return { success }; // End of method 2
86
+ }
87
+ // -----------------------------------------------------------------------
88
+ // Method 3: Wait-on - already running
89
+ // -----------------------------------------------------------------------
90
+ //
91
+ try {
92
+ success = yield (0, cucumber_runner_1.runCucumber)(options, cucumberCwd);
93
+ }
94
+ catch (e) {
95
+ devkit_1.logger.error(e.message);
96
+ }
97
+ return { success }; // End of method 3
98
+ });
99
+ }
100
+ exports.default = cucumberExecutor;
101
+ function buildCucumberOptions(options, cwd) {
102
+ const baseUrl = options.baseUrl || 'http://localhost:4200';
103
+ const outputDirectory = options.outputDirectory || `dist/cucumber-js/${cwd}`;
104
+ const watch = options.watch ? true : false;
105
+ const autoDebug = options.debug === undefined;
106
+ const debug = autoDebug ? watch : options.debug;
107
+ const disableAnimations = options.disableAnimations || false;
108
+ const disableCoverage = options.disableCoverage || watch; // coverage is disabled in watch mode
109
+ const disableScreenshotAttachments = options.disableScreenshotAttachments || false; // screenshot attachments are enabled in watch mode
110
+ const disableScreenshotFiles = options.disableScreenshotFiles || watch; // screenshot files,
111
+ const disableVideoAttachments = options.disableVideoAttachments || watch; // video attachments,
112
+ const disableVideoFiles = options.disableVideoFiles || watch; // and video files are disabled in watch mode
113
+ const disableJavaScript = options.disableJavaScript || false;
114
+ const featuresDirectory = options.featuresDirectory || 'features';
115
+ const tags = options.tags;
116
+ // the name command-line parameter could be string or array
117
+ const name = typeof options.name === 'string' ? [options.name] : options.name;
118
+ const testRunner = options.testRunner || 'core';
119
+ const env = options.env || {};
120
+ const cucumberOptions = {
121
+ baseUrl,
122
+ watch,
123
+ debug,
124
+ disableAnimations,
125
+ disableCoverage,
126
+ outputDirectory,
127
+ disableScreenshotAttachments,
128
+ disableScreenshotFiles,
129
+ disableVideoAttachments,
130
+ disableVideoFiles,
131
+ disableJavaScript,
132
+ default: {},
133
+ featuresDirectory,
134
+ tags,
135
+ name,
136
+ testRunner,
137
+ env,
138
+ };
139
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars
140
+ const { default: _ } = cucumberOptions, allOtherOptions = tslib_1.__rest(cucumberOptions, ["default"]);
141
+ cucumberOptions.default = allOtherOptions;
142
+ return cucumberOptions;
143
+ }
144
+ //# sourceMappingURL=executor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"executor.js","sourceRoot":"","sources":["../../../../../../libs/nx-cucumber/src/executors/cucumber-js/executor.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,7 @@
1
+ import { TestRunOptions } from '../../core/test-run-options';
2
+
3
+ export interface CucumberJsExecutorSchema extends TestRunOptions {
4
+ devServerTarget: string;
5
+ devServerKind?: undefined | 'wait-on';
6
+ skipServe?: boolean;
7
+ }
@@ -0,0 +1,10 @@
1
+ {
2
+ "version": 2,
3
+ "outputCapture": "direct-nodejs",
4
+ "$schema": "http://json-schema.org/schema",
5
+ "title": "CucumberJs executor",
6
+ "description": "",
7
+ "type": "object",
8
+ "properties": {},
9
+ "required": []
10
+ }
package/src/index.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './playwright/playwright-world';
package/src/index.js ADDED
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./playwright/playwright-world"), exports);
5
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/nx-cucumber/src/index.ts"],"names":[],"mappings":";;;AAAA,wEAA8C"}
@@ -0,0 +1 @@
1
+ export {};
@@ -0,0 +1,170 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ const cucumber_1 = require("@cucumber/cucumber");
5
+ const path_1 = tslib_1.__importDefault(require("path"));
6
+ const playwright_1 = require("playwright");
7
+ const shared_coverage_1 = require("@gnuechtel/shared-coverage");
8
+ const playwright_world_1 = require("./playwright-world");
9
+ const shared_coverage_2 = require("@gnuechtel/shared-coverage");
10
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
11
+ const debug = require('debug')('e2e:hooks');
12
+ // Disable timeout on playwright debugging, otherwise we use a default timeout of 5 seconds (the default cucumber timeout)
13
+ (0, cucumber_1.setDefaultTimeout)(process.env['PWDEBUG'] ? -1 : 5000);
14
+ // We ignore all SSL errors, because we have self signed developer certificates
15
+ process.env['NODE_TLS_REJECT_UNAUTHORIZED'] = '0';
16
+ const browserOptions = {
17
+ slowMo: 0,
18
+ args: ['--use-fake-ui-for-media-stream', '--use-fake-device-for-media-stream'],
19
+ };
20
+ function launchBrowser(label, headless) {
21
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
22
+ if (!global.browserState.isStarted) {
23
+ debug(`${label} - Creating new ${headless ? 'headless' : 'headed'} Chromium instance`);
24
+ browserOptions.headless = headless;
25
+ global.browser = yield playwright_1.chromium.launch(browserOptions);
26
+ global.browserState.isHeadless = headless;
27
+ global.browserState.isStarted = true;
28
+ debug(`${label} - Chromium instance created`);
29
+ }
30
+ });
31
+ }
32
+ function closeBrowser(label) {
33
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
34
+ if (global.browserState.isStarted) {
35
+ debug(`${label} - Closing Chromium instance`);
36
+ try {
37
+ yield global.browser.close();
38
+ global.browserState.isStarted = false;
39
+ debug(`${label} - Chromium instance closed`);
40
+ }
41
+ catch (e) {
42
+ debug(`${label} - Could not close browser: %O`, e);
43
+ }
44
+ }
45
+ });
46
+ }
47
+ /**
48
+ * Launches the browser if it is not yet started or if the running headless state is different from `launchHeadless`.
49
+ * Closes any existing browser before. This function has no effect, if a browser is currently running and has the same
50
+ * headless state like `launchHeadless`.
51
+ *
52
+ * In other words, a new browser is launched
53
+ * - headed, if running browser is headless
54
+ * - headless, if running browser is headed
55
+ * - headless/headed, if browser is not yet started.
56
+ *
57
+ * @param label the label for debugging
58
+ * @param launchHeadless true, if browser should be launched headless, false otherwise
59
+ */
60
+ function launchBrowserIfRequired(label, launchHeadless) {
61
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
62
+ if (global.browserState.isHeadless != launchHeadless || !global.browserState.isStarted) {
63
+ // The closeBrowser invocation has only an effect, if browser is already running
64
+ yield closeBrowser(label);
65
+ yield launchBrowser(label, launchHeadless);
66
+ }
67
+ });
68
+ }
69
+ (0, cucumber_1.BeforeAll)(function () {
70
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
71
+ global.browserState = {
72
+ isStarted: false,
73
+ isHeadless: true,
74
+ };
75
+ debug('BeforeAll - Deleting existing coverage files');
76
+ (0, shared_coverage_2.deleteExistingPlaywrightCoverageFiles)();
77
+ debug('BeforeAll - Existing coverage files deleted');
78
+ });
79
+ });
80
+ (0, cucumber_1.AfterAll)(function () {
81
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
82
+ debug('AfterAll - Creating Istanbul coverage report');
83
+ try {
84
+ const rootDirectory = path_1.default.resolve(path_1.default.join(__dirname, '..', '..', '..', '..', '..'));
85
+ const projectDirectory = path_1.default.resolve(process.cwd());
86
+ yield (0, shared_coverage_1.createIstanbulCoverageReports)(rootDirectory, projectDirectory);
87
+ debug('AfterAll - Istanbul coverage report created');
88
+ }
89
+ catch (e) {
90
+ debug('AfterAll - Could not create Istanbul coverage report: %O', e);
91
+ }
92
+ yield closeBrowser('AfterAll');
93
+ });
94
+ });
95
+ (0, cucumber_1.Before)(function (testCase) {
96
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
97
+ debug('Before - Cleaning up');
98
+ // Always clean-up any running stuff
99
+ yield this.cleanUp();
100
+ this.setItem(playwright_world_1.scenarioName, testCase.pickle.name);
101
+ debug('Before - Cleaned up');
102
+ });
103
+ });
104
+ (0, cucumber_1.Before)({ tags: '@javascript' }, function () {
105
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
106
+ // When javascript is disabled by default, we enable it only for scenarios which are tagged by @javascript
107
+ this.parameters.disableJavaScript = false;
108
+ });
109
+ });
110
+ (0, cucumber_1.Before)({ tags: '@noscript' }, function () {
111
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
112
+ // When javascript is enabled by default, we disable it only for scenarios which are tagged by @noscript
113
+ this.parameters.disableJavaScript = true;
114
+ });
115
+ });
116
+ (0, cucumber_1.Before)({ tags: '@headed' }, function () {
117
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
118
+ yield launchBrowserIfRequired('Before @headed', false);
119
+ });
120
+ });
121
+ (0, cucumber_1.Before)({ tags: 'not @headed' }, function () {
122
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
123
+ yield launchBrowserIfRequired('Before not @headed', !this.parameters.watch);
124
+ });
125
+ });
126
+ (0, cucumber_1.BeforeStep)(function () {
127
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
128
+ debug('BeforeStep');
129
+ this.prepareStep();
130
+ });
131
+ });
132
+ (0, cucumber_1.AfterStep)(function () {
133
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
134
+ if (!this.parameters.disableScreenshotAttachments || !this.parameters.disableScreenshotFiles) {
135
+ try {
136
+ debug('AfterStep - Creating screenshots');
137
+ yield this.createScreenshots(undefined);
138
+ debug('AfterStep - Screenshots created');
139
+ }
140
+ catch (e) {
141
+ debug('AfterStep - Could not create screenshots: %O', e);
142
+ }
143
+ }
144
+ });
145
+ });
146
+ (0, cucumber_1.After)(function () {
147
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
148
+ if (!this.parameters.disableCoverage) {
149
+ try {
150
+ debug('After - Collecting coverage');
151
+ yield this.collectIstanbulCoverage();
152
+ debug('After - Coverage collected');
153
+ }
154
+ catch (e) {
155
+ debug('After - Could not create coverage: %O', e);
156
+ }
157
+ }
158
+ try {
159
+ debug('After - Cleaning up');
160
+ yield this.cleanUp();
161
+ debug('After - Cleaned up');
162
+ }
163
+ catch (e) {
164
+ debug('After - Could not clean up properly: %O', e);
165
+ }
166
+ });
167
+ });
168
+ // Enable playwright world in all cucumber-js hooks
169
+ (0, cucumber_1.setWorldConstructor)(playwright_world_1.PlaywrightWorld);
170
+ //# sourceMappingURL=playwright-hooks.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright-hooks.js","sourceRoot":"","sources":["../../../../../libs/nx-cucumber/src/playwright/playwright-hooks.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,97 @@
1
+ import { World, IWorldOptions } from '@cucumber/cucumber';
2
+ import { ChromiumBrowser, Page, PageScreenshotOptions } from 'playwright';
3
+ import { TestRunOptions } from '../core/test-run-options';
4
+ declare global {
5
+ var browser: ChromiumBrowser;
6
+ var browserState: {
7
+ isHeadless: boolean;
8
+ isStarted: boolean;
9
+ };
10
+ }
11
+ /**
12
+ * Provides a lot of useful functions to use inside our own step definitions.
13
+ * Also used in `playwright-hooks.ts`.
14
+ */
15
+ export declare class PlaywrightWorld extends World<TestRunOptions> {
16
+ constructor(options: IWorldOptions);
17
+ /**
18
+ * Creates a fresh {@link BrowserContext} with one {@link Page}.
19
+ * Adds the created page to {@link pages}.
20
+ */
21
+ setupContext(locale?: string): Promise<void>;
22
+ private setupPageIfRequired;
23
+ /**
24
+ * Convenience method which combines {@link setupContext} and {@link Page.goto}.
25
+ * @param subPath the relative URL to visit
26
+ */
27
+ visit(subPath: string): Promise<void>;
28
+ /**
29
+ * Gets all created pages of all contexts
30
+ */
31
+ get pages(): ReadonlyArray<Page>;
32
+ /**
33
+ * Convenience method to get the first page created
34
+ */
35
+ get page(): Page | undefined;
36
+ /**
37
+ * Convenience method to get the API request context from the first page, set ups the browser context, if not yet done
38
+ */
39
+ request(): Promise<import("playwright-core").APIRequestContext | undefined>;
40
+ /**
41
+ * Sets a custom item which is available in this world instance
42
+ * @param key a custom key to retrieve the item
43
+ * @param value a custom value
44
+ */
45
+ setItem<T>(key: string, value: T): void;
46
+ /**
47
+ * Gets a custom item of this world instance which was set before
48
+ * @param key the retrieval key
49
+ * @param defaultValue the default value, if the item does not exist
50
+ * @returns the custom value or the default value
51
+ */
52
+ getItem<T>(key: string, defaultValue?: T): T;
53
+ /**
54
+ * Prepares this world for the current step.
55
+ * For example, the counter for attached screenshots will be reset.
56
+ * Invoked in `playwright-hooks.ts`.
57
+ */
58
+ prepareStep(): void;
59
+ /**
60
+ * Creates screenshots and attaches them to this world instance.
61
+ * Those screenshots will be integrated in HTML reports for example.
62
+ * Also stores screenshots in the file system, if the current scenario failed.
63
+ * Invoked in `playwright-hooks.ts`.
64
+ * @param result the test result of the current scenario
65
+ */
66
+ createScreenshots(screenshotOptions?: PageScreenshotOptions): Promise<void>;
67
+ /**
68
+ * Helper function to disable screenshots temporarily for the current step.
69
+ * This avoids intermediate screenshots from other shared test code
70
+ */
71
+ disableScreenshots(): void;
72
+ /**
73
+ * The counterpart of {@link disableScreenshots}.
74
+ */
75
+ restoreScreenshots(): void;
76
+ private getScenarioFileName;
77
+ /**
78
+ * Renames the playwright generated videos and them to the reports.
79
+ */
80
+ createVideos(index: number): Promise<void>;
81
+ /**
82
+ * Collects the coverage for the current scenario.
83
+ * Invoked in `playwright-hooks.ts`.
84
+ */
85
+ collectIstanbulCoverage(): Promise<void>;
86
+ /**
87
+ * Closes and resets all created contexts.
88
+ * Resets all pages and items.
89
+ * Invoked in `playwright-hooks.ts`.
90
+ */
91
+ cleanUp(): Promise<void>;
92
+ private _contexts;
93
+ private _pages;
94
+ private _items;
95
+ private _attachedScreenshots;
96
+ }
97
+ export declare const scenarioName = "scenarioName";
@@ -0,0 +1,321 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.scenarioName = exports.PlaywrightWorld = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const cucumber_1 = require("@cucumber/cucumber");
6
+ const shared_coverage_1 = require("@gnuechtel/shared-coverage");
7
+ const cucumber_runner_1 = require("../core/cucumber-runner");
8
+ const fs_1 = tslib_1.__importDefault(require("fs"));
9
+ const path_1 = tslib_1.__importDefault(require("path"));
10
+ // eslint-disable-next-line @typescript-eslint/no-var-requires
11
+ const debug = require('debug')('e2e:world');
12
+ /**
13
+ * Provides a lot of useful functions to use inside our own step definitions.
14
+ * Also used in `playwright-hooks.ts`.
15
+ */
16
+ class PlaywrightWorld extends cucumber_1.World {
17
+ constructor(options) {
18
+ var _a, _b;
19
+ super(options);
20
+ this._contexts = [];
21
+ this._pages = [];
22
+ this._items = {};
23
+ this._attachedScreenshots = 0;
24
+ if (!((_a = this.parameters) === null || _a === void 0 ? void 0 : _a.outputDirectory)) {
25
+ throw new Error('Please specify output directory as world parameter');
26
+ }
27
+ if (!((_b = this.parameters) === null || _b === void 0 ? void 0 : _b.baseUrl)) {
28
+ throw new Error('Please specify base URL as world parameter');
29
+ }
30
+ if (!isFullUrl(this.parameters.baseUrl)) {
31
+ throw new Error('Please specify a valid base URL');
32
+ }
33
+ }
34
+ /**
35
+ * Creates a fresh {@link BrowserContext} with one {@link Page}.
36
+ * Adds the created page to {@link pages}.
37
+ */
38
+ setupContext(locale = 'en') {
39
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
40
+ if (!this.parameters.outputDirectory)
41
+ throw new Error("Output directory is not set");
42
+ const { videosDirectory } = (0, cucumber_runner_1.getOutputDirectories)(this.parameters.outputDirectory);
43
+ const options = {
44
+ acceptDownloads: true,
45
+ locale,
46
+ };
47
+ if (!this.parameters.disableVideoAttachments || !this.parameters.disableVideoFiles) {
48
+ options.recordVideo = {
49
+ dir: videosDirectory,
50
+ size: {
51
+ width: 1920,
52
+ height: 1080,
53
+ },
54
+ };
55
+ options.viewport = {
56
+ width: 1920,
57
+ height: 1080,
58
+ };
59
+ }
60
+ if (this.parameters.disableJavaScript) {
61
+ // Yes, we disable JavaScript by default, since our application should work without scripts in the browser
62
+ options.javaScriptEnabled = false;
63
+ }
64
+ const newContext = yield global.browser.newContext(options);
65
+ this._contexts.push(newContext);
66
+ if (!this.parameters.disableCoverage) {
67
+ yield (0, shared_coverage_1.prepareContextForIstanbulCoverage)(newContext);
68
+ }
69
+ const newPage = yield newContext.newPage();
70
+ this._pages.push(newPage);
71
+ if (this.parameters.disableAnimations) {
72
+ // By default, we disable all animations
73
+ newPage.on('load', (page) => tslib_1.__awaiter(this, void 0, void 0, function* () {
74
+ yield page.addStyleTag({ content: '* { animation: none !important; } }' });
75
+ }));
76
+ }
77
+ });
78
+ }
79
+ setupPageIfRequired() {
80
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
81
+ if (!this.page)
82
+ yield this.setupContext();
83
+ if (!this.page)
84
+ throw new Error('Unexpected error: page is not initialized');
85
+ });
86
+ }
87
+ /**
88
+ * Convenience method which combines {@link setupContext} and {@link Page.goto}.
89
+ * @param subPath the relative URL to visit
90
+ */
91
+ visit(subPath) {
92
+ var _a;
93
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
94
+ yield this.setupPageIfRequired(); // Setup context, if this is our first goto in the current world
95
+ const start = !isFullUrl(subPath) ? this.parameters.baseUrl : '';
96
+ yield ((_a = this.page) === null || _a === void 0 ? void 0 : _a.goto(`${start}${subPath}`));
97
+ });
98
+ }
99
+ /**
100
+ * Gets all created pages of all contexts
101
+ */
102
+ get pages() {
103
+ return this._pages;
104
+ }
105
+ /**
106
+ * Convenience method to get the first page created
107
+ */
108
+ get page() {
109
+ return this._pages && this._pages.length > 0 ? this._pages[0] : undefined;
110
+ }
111
+ /**
112
+ * Convenience method to get the API request context from the first page, set ups the browser context, if not yet done
113
+ */
114
+ request() {
115
+ var _a;
116
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
117
+ yield this.setupPageIfRequired();
118
+ return (_a = this.page) === null || _a === void 0 ? void 0 : _a.request;
119
+ });
120
+ }
121
+ /**
122
+ * Sets a custom item which is available in this world instance
123
+ * @param key a custom key to retrieve the item
124
+ * @param value a custom value
125
+ */
126
+ setItem(key, value) {
127
+ this._items[key] = value;
128
+ }
129
+ /**
130
+ * Gets a custom item of this world instance which was set before
131
+ * @param key the retrieval key
132
+ * @param defaultValue the default value, if the item does not exist
133
+ * @returns the custom value or the default value
134
+ */
135
+ getItem(key, defaultValue) {
136
+ var _a;
137
+ return (_a = this._items[key]) !== null && _a !== void 0 ? _a : defaultValue;
138
+ }
139
+ /**
140
+ * Prepares this world for the current step.
141
+ * For example, the counter for attached screenshots will be reset.
142
+ * Invoked in `playwright-hooks.ts`.
143
+ */
144
+ prepareStep() {
145
+ this._attachedScreenshots = 0;
146
+ }
147
+ /**
148
+ * Creates screenshots and attaches them to this world instance.
149
+ * Those screenshots will be integrated in HTML reports for example.
150
+ * Also stores screenshots in the file system, if the current scenario failed.
151
+ * Invoked in `playwright-hooks.ts`.
152
+ * @param result the test result of the current scenario
153
+ */
154
+ createScreenshots(screenshotOptions) {
155
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
156
+ if (this.parameters.disableScreenshotAttachments && this.parameters.disableScreenshotFiles) {
157
+ debug('Screenshots are disabled');
158
+ return;
159
+ }
160
+ if (!this.parameters.outputDirectory)
161
+ throw new Error("Output directory is not set");
162
+ const { screenshotsDirectory } = (0, cucumber_runner_1.getOutputDirectories)(this.parameters.outputDirectory);
163
+ if (this._pages.length > 0) {
164
+ debug('Storing screenshots');
165
+ for (let i = 0; i < this._pages.length; i++) {
166
+ const image = yield this._pages[i].screenshot(screenshotOptions);
167
+ if (image) {
168
+ if (!this.parameters.disableScreenshotAttachments) {
169
+ debug('Attaching image to current step');
170
+ this.attach(image, 'image/png');
171
+ this._attachedScreenshots++;
172
+ debug('Image attached');
173
+ }
174
+ else {
175
+ debug('Screenshot attachments are disabled');
176
+ }
177
+ if (!this.parameters.disableScreenshotFiles) {
178
+ const screenshotPath = getUniqueFileName(screenshotsDirectory, this.getScenarioFileName(), 'png');
179
+ fs_1.default.writeFileSync(screenshotPath, image);
180
+ debug(`Screenshot stored to ${screenshotPath}`);
181
+ }
182
+ else {
183
+ debug('Screenshot files are disabled');
184
+ }
185
+ }
186
+ }
187
+ debug('Screenshots stored');
188
+ }
189
+ });
190
+ }
191
+ /**
192
+ * Helper function to disable screenshots temporarily for the current step.
193
+ * This avoids intermediate screenshots from other shared test code
194
+ */
195
+ disableScreenshots() {
196
+ this.setItem('disableScreenshotAttachmentsBefore', this.parameters.disableScreenshotAttachments); // use a world item for the restore function
197
+ this.setItem('disableScreenshotFilesBefore', this.parameters.disableScreenshotFiles); // use a world item for the restore function
198
+ this.parameters.disableScreenshotAttachments = true;
199
+ this.parameters.disableScreenshotFiles = true;
200
+ }
201
+ /**
202
+ * The counterpart of {@link disableScreenshots}.
203
+ */
204
+ restoreScreenshots() {
205
+ const disableScreenshotAttachmentsBefore = this.getItem('disableScreenshotAttachmentsBefore');
206
+ const disableScreenshotFilesBefore = this.getItem('disableScreenshotFilesBefore');
207
+ this.parameters.disableScreenshotAttachments = disableScreenshotAttachmentsBefore;
208
+ this.parameters.disableScreenshotFiles = disableScreenshotFilesBefore;
209
+ }
210
+ getScenarioFileName() {
211
+ // Use encoded scenario name in image and video file names, only the * characters will be removed
212
+ return encodeURIComponent(this.getItem(exports.scenarioName)).replace(/\*/g, '');
213
+ }
214
+ /**
215
+ * Renames the playwright generated videos and them to the reports.
216
+ */
217
+ createVideos(index) {
218
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
219
+ if (this.parameters.disableVideoAttachments && this.parameters.disableVideoFiles) {
220
+ debug('Videos are disabled');
221
+ return;
222
+ }
223
+ if (!this.parameters.outputDirectory)
224
+ throw new Error("Output directory is not set");
225
+ const { videosDirectory } = (0, cucumber_runner_1.getOutputDirectories)(this.parameters.outputDirectory);
226
+ debug('Storing videos');
227
+ const page = this._pages[index];
228
+ const video = page.video();
229
+ if (!video)
230
+ throw new Error("No video found");
231
+ const videoPath = !this.parameters.disableVideoFiles
232
+ ? getUniqueFileName(videosDirectory, this.getScenarioFileName(), 'webm')
233
+ : yield video.path();
234
+ if (!this.parameters.disableVideoFiles) {
235
+ yield video.saveAs(videoPath); // save video path under new name
236
+ debug(`Video stored to ${videoPath}`);
237
+ }
238
+ else {
239
+ debug('Video files are disabled');
240
+ }
241
+ if (!this.parameters.disableVideoAttachments) {
242
+ const fileName = path_1.default.basename(videoPath); // Use file name without path as attachment name
243
+ const videoBuffer = fs_1.default.readFileSync(videoPath);
244
+ this.attach(videoBuffer.toString('base64'), { mediaType: 'base64:video/webm', fileName });
245
+ }
246
+ else {
247
+ debug('Video attachments are disabled');
248
+ }
249
+ yield video.delete(); // always delete original video
250
+ debug('Videos stored');
251
+ });
252
+ }
253
+ /**
254
+ * Collects the coverage for the current scenario.
255
+ * Invoked in `playwright-hooks.ts`.
256
+ */
257
+ collectIstanbulCoverage() {
258
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
259
+ for (const context of this._contexts) {
260
+ yield (0, shared_coverage_1.collectIstanbulCoverageForContext)(context);
261
+ }
262
+ });
263
+ }
264
+ /**
265
+ * Closes and resets all created contexts.
266
+ * Resets all pages and items.
267
+ * Invoked in `playwright-hooks.ts`.
268
+ */
269
+ cleanUp() {
270
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
271
+ // Restore current parameters to default parameters
272
+ const defaultParameters = this.parameters.default;
273
+ for (const key in defaultParameters) {
274
+ // eslint-disable-next-line @typescript-eslint/ban-ts-comment
275
+ // @ts-ignore
276
+ this.parameters[key] = defaultParameters[key];
277
+ }
278
+ debug('Cleaning up world instance');
279
+ for (let i = 0; i < this._contexts.length; i++) {
280
+ const context = this._contexts[i];
281
+ try {
282
+ // Close context and all its pages
283
+ debug('Closing browser context');
284
+ yield context.close();
285
+ debug('Browser context closed');
286
+ if (!this.parameters.disableVideoAttachments || !this.parameters.disableVideoFiles) {
287
+ yield this.createVideos(i);
288
+ }
289
+ }
290
+ catch (e) {
291
+ debug('Could not close browser context: %O', e);
292
+ }
293
+ }
294
+ this._contexts = [];
295
+ this._pages = [];
296
+ this._items = {};
297
+ debug('World instance cleaned up');
298
+ });
299
+ }
300
+ }
301
+ exports.PlaywrightWorld = PlaywrightWorld;
302
+ function isFullUrl(url) {
303
+ return url.match(/^https?:\/\//);
304
+ }
305
+ function getUniqueFileName(directory, baseName, extension) {
306
+ let completeBaseName = '';
307
+ let fullPath = '';
308
+ let n = 1;
309
+ do {
310
+ const extra = n == 1 ? '' : '-' + ('00' + n).slice(-2);
311
+ if (n > 1) {
312
+ debug(`File ${completeBaseName} already exists`);
313
+ }
314
+ completeBaseName = `${baseName}${extra}.${extension}`;
315
+ fullPath = path_1.default.join(directory, completeBaseName);
316
+ n++;
317
+ } while (fs_1.default.existsSync(fullPath));
318
+ return fullPath;
319
+ }
320
+ exports.scenarioName = 'scenarioName';
321
+ //# sourceMappingURL=playwright-world.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"playwright-world.js","sourceRoot":"","sources":["../../../../../libs/nx-cucumber/src/playwright/playwright-world.ts"],"names":[],"mappings":"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"}