@gnuechtel/nx-cucumber 2.0.0-beta.3 → 2.0.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/README.md +204 -51
- package/migrations.json +10 -0
- package/package.json +6 -9
- package/src/adapters/registry.js +6 -1
- package/src/adapters/registry.js.map +1 -1
- package/src/core/cucumber-run-metadata-formatter.js +111 -0
- package/src/generators/project/files/all/cucumber.js.template +17 -5
- package/src/generators/project/files/playwright/run-e2e.js.template +112 -0
- package/src/generators/project/project.js +72 -29
- package/src/generators/project/project.js.map +1 -1
- package/src/index.d.ts +1 -4
- package/src/index.js +3 -6
- package/src/index.js.map +1 -1
- package/src/migrations/update-2-0-0/migrate-cucumber-api-to-inferred-tasks.d.ts +20 -0
- package/src/migrations/update-2-0-0/migrate-cucumber-api-to-inferred-tasks.js +222 -0
- package/src/migrations/update-2-0-0/migrate-cucumber-api-to-inferred-tasks.js.map +1 -0
- package/src/plugin/create-nodes.d.ts +14 -0
- package/src/plugin/create-nodes.js +4 -0
- package/src/plugin/create-nodes.js.map +1 -1
- package/src/core/cucumber-report-html.d.ts +0 -11
- package/src/core/cucumber-report-html.js +0 -58
- package/src/core/cucumber-report-html.js.map +0 -1
- package/src/core/web-server.d.ts +0 -29
- package/src/core/web-server.js +0 -139
- package/src/core/web-server.js.map +0 -1
|
@@ -0,0 +1,112 @@
|
|
|
1
|
+
// Generated by @gnuechtel/nx-cucumber — do not edit manually.
|
|
2
|
+
// Manages the Playwright e2e server lifecycle for use with cucumber-js.
|
|
3
|
+
// Modelled after Playwright's own launchProcess for cross-platform correctness.
|
|
4
|
+
'use strict';
|
|
5
|
+
|
|
6
|
+
const cp = require('node:child_process');
|
|
7
|
+
const net = require('node:net');
|
|
8
|
+
const { setTimeout: sleep } = require('node:timers/promises');
|
|
9
|
+
|
|
10
|
+
const PORT = <%= port %>;
|
|
11
|
+
const SERVE_CMD = <%- serveCommandJson %>;
|
|
12
|
+
const TEST_CMD = <%- testCommandJson %>;
|
|
13
|
+
const TIMEOUT_MS = 60_000;
|
|
14
|
+
|
|
15
|
+
async function run() {
|
|
16
|
+
await clearPort();
|
|
17
|
+
|
|
18
|
+
// Detached on Unix creates a new process group so we can kill the entire
|
|
19
|
+
// tree with process.kill(-pid). On Windows we use taskkill /T instead.
|
|
20
|
+
const server = cp.spawn(SERVE_CMD, {
|
|
21
|
+
shell: true,
|
|
22
|
+
stdio: 'inherit',
|
|
23
|
+
detached: process.platform !== 'win32',
|
|
24
|
+
});
|
|
25
|
+
if (process.platform !== 'win32') server.unref();
|
|
26
|
+
|
|
27
|
+
// Track whether the server exited on its own before we try to kill it.
|
|
28
|
+
// This is the key pattern from Playwright's launchProcess: never call
|
|
29
|
+
// taskkill on a process that is already gone.
|
|
30
|
+
let processClosed = false;
|
|
31
|
+
server.once('close', () => { processClosed = true; });
|
|
32
|
+
|
|
33
|
+
const onSignal = () => { teardown(); process.exit(130); };
|
|
34
|
+
process.once('SIGINT', onSignal);
|
|
35
|
+
process.once('SIGTERM', onSignal);
|
|
36
|
+
|
|
37
|
+
function teardown() {
|
|
38
|
+
process.off('SIGINT', onSignal);
|
|
39
|
+
process.off('SIGTERM', onSignal);
|
|
40
|
+
if (!server.pid || server.killed || processClosed) return;
|
|
41
|
+
try {
|
|
42
|
+
if (process.platform === 'win32') {
|
|
43
|
+
// spawnSync captures output and does not throw on non-zero exit,
|
|
44
|
+
// unlike execSync — so a "not found" from taskkill is silently ignored.
|
|
45
|
+
cp.spawnSync(`taskkill /pid ${server.pid} /T /F`, { shell: true, stdio: 'pipe' });
|
|
46
|
+
} else {
|
|
47
|
+
process.kill(-server.pid, 'SIGKILL');
|
|
48
|
+
}
|
|
49
|
+
} catch { /* process already exited */ }
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
// Wait until the dev server is reachable.
|
|
53
|
+
const deadline = Date.now() + TIMEOUT_MS;
|
|
54
|
+
while (!(await portOpen(PORT))) {
|
|
55
|
+
if (processClosed) {
|
|
56
|
+
console.error('[nx-cucumber] Server process exited before becoming ready');
|
|
57
|
+
process.exit(1);
|
|
58
|
+
}
|
|
59
|
+
if (Date.now() > deadline) {
|
|
60
|
+
teardown();
|
|
61
|
+
console.error(`[nx-cucumber] Server did not respond on port ${PORT} within ${TIMEOUT_MS / 1000}s`);
|
|
62
|
+
process.exit(1);
|
|
63
|
+
}
|
|
64
|
+
await sleep(500);
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Run cucumber. TS_NODE_PROJECT is cleared to prevent ts-node config
|
|
68
|
+
// leakage from any parent Nx process that set it for a different project.
|
|
69
|
+
const { status } = cp.spawnSync(TEST_CMD, {
|
|
70
|
+
shell: true,
|
|
71
|
+
stdio: 'inherit',
|
|
72
|
+
env: { ...process.env, TS_NODE_PROJECT: '' },
|
|
73
|
+
});
|
|
74
|
+
|
|
75
|
+
teardown();
|
|
76
|
+
process.exit(status ?? 1);
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
// Kill whatever process is currently holding the port so a fresh server
|
|
80
|
+
// can bind to it without a port-conflict error.
|
|
81
|
+
async function clearPort() {
|
|
82
|
+
if (!(await portOpen(PORT))) return;
|
|
83
|
+
if (process.platform === 'win32') {
|
|
84
|
+
try {
|
|
85
|
+
const lines = cp.execSync('netstat -ano', { encoding: 'utf8', stdio: ['pipe', 'pipe', 'pipe'] }).split('\n');
|
|
86
|
+
const pid = lines
|
|
87
|
+
.find((l) => new RegExp(`[: ]${PORT}\\s`).test(l))
|
|
88
|
+
?.trim()
|
|
89
|
+
.split(/\s+/)
|
|
90
|
+
.at(-1);
|
|
91
|
+
if (pid && pid !== '0') cp.spawnSync(`taskkill /pid ${pid} /T /F`, { shell: true, stdio: 'pipe' });
|
|
92
|
+
} catch { /* port already free */ }
|
|
93
|
+
} else {
|
|
94
|
+
try { cp.execSync(`lsof -ti :${PORT} | xargs kill -9`, { shell: true, stdio: 'pipe' }); } catch { /* port already free */ }
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
|
|
98
|
+
// Returns true when something is actively listening on the port.
|
|
99
|
+
// Tries IPv4 first, then IPv6 localhost as a fallback.
|
|
100
|
+
function portOpen(port) {
|
|
101
|
+
return new Promise((resolve) => {
|
|
102
|
+
const conn = net.connect(port, '127.0.0.1');
|
|
103
|
+
conn.once('connect', () => { conn.destroy(); resolve(true); });
|
|
104
|
+
conn.once('error', () => {
|
|
105
|
+
const conn6 = net.connect(port, '::1');
|
|
106
|
+
conn6.once('connect', () => { conn6.destroy(); resolve(true); });
|
|
107
|
+
conn6.once('error', () => resolve(false));
|
|
108
|
+
});
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
|
|
112
|
+
run();
|
|
@@ -7,12 +7,12 @@ const path = tslib_1.__importStar(require("path"));
|
|
|
7
7
|
const fs_1 = require("fs");
|
|
8
8
|
const test_run_options_1 = require("../../core/test-run-options");
|
|
9
9
|
async function cucumberJsGenerator(tree, options) {
|
|
10
|
-
if (!options.name)
|
|
11
|
-
options.name = `${options.project}-e2e`;
|
|
12
|
-
if (!options.directory)
|
|
13
|
-
options.directory = options.name;
|
|
14
10
|
if (!options.testRunner)
|
|
15
11
|
options.testRunner = test_run_options_1.defaultTestRunner;
|
|
12
|
+
ensureProjectExists(tree, options.project);
|
|
13
|
+
options.name = normalizeGeneratedProjectName(options.project, options.name);
|
|
14
|
+
if (!options.directory)
|
|
15
|
+
options.directory = defaultProjectDirectory(options.name);
|
|
16
16
|
const isPlaywright = options.testRunner === 'playwright';
|
|
17
17
|
const baseUrl = isPlaywright ? 'http://localhost:4200' : undefined;
|
|
18
18
|
const serveTarget = isPlaywright ? `${options.project}:serve` : undefined;
|
|
@@ -22,9 +22,7 @@ async function cucumberJsGenerator(tree, options) {
|
|
|
22
22
|
const parentDir = workspaceLayout.appsDir && !skipAppsDir ? workspaceLayout.appsDir + '/' : '';
|
|
23
23
|
const projectRoot = `${parentDir}${normalizedDirectory}`;
|
|
24
24
|
const workspaceRootRelative = (0, devkit_1.offsetFromRoot)(projectRoot).replace(/\/$/, '');
|
|
25
|
-
const playwrightTargets = isPlaywright && baseUrl && serveTarget
|
|
26
|
-
? buildPlaywrightTargets(tree, options.project, options.name, serveTarget, baseUrl, projectRoot)
|
|
27
|
-
: {};
|
|
25
|
+
const playwrightTargets = isPlaywright && baseUrl && serveTarget ? buildPlaywrightTargets(options.name, projectRoot) : {};
|
|
28
26
|
(0, devkit_1.addProjectConfiguration)(tree, options.name, {
|
|
29
27
|
root: projectRoot,
|
|
30
28
|
sourceRoot: `${projectRoot}/src`,
|
|
@@ -47,14 +45,22 @@ async function cucumberJsGenerator(tree, options) {
|
|
|
47
45
|
'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-hooks.js',
|
|
48
46
|
]
|
|
49
47
|
: [];
|
|
48
|
+
const serveCommand = isPlaywright && baseUrl && serveTarget ? buildServeCommand(tree, options.project, serveTarget, baseUrl) : '';
|
|
49
|
+
const testCommand = `npx cucumber-js --config ${projectRoot}/cucumber.js`;
|
|
50
|
+
const templateProjectName = parseScopedProjectName(options.project).name;
|
|
50
51
|
const substitutions = {
|
|
51
52
|
...options,
|
|
53
|
+
project: templateProjectName,
|
|
54
|
+
testedProject: options.project,
|
|
52
55
|
workspaceRootRelative,
|
|
53
56
|
projectRoot,
|
|
54
57
|
playwrightRequires: JSON.stringify(playwrightRequires),
|
|
55
58
|
isPlaywright,
|
|
56
59
|
baseUrl: baseUrl || '',
|
|
57
60
|
serveTarget: serveTarget || '',
|
|
61
|
+
port: baseUrl ? readPortFromUrl(baseUrl) : 0,
|
|
62
|
+
serveCommandJson: JSON.stringify(serveCommand),
|
|
63
|
+
testCommandJson: JSON.stringify(testCommand),
|
|
58
64
|
};
|
|
59
65
|
(0, devkit_1.generateFiles)(tree, path.join(__dirname, 'files', 'all'), projectRoot, substitutions);
|
|
60
66
|
(0, devkit_1.generateFiles)(tree, path.join(__dirname, 'files', options.testRunner), projectRoot, substitutions);
|
|
@@ -62,53 +68,41 @@ async function cucumberJsGenerator(tree, options) {
|
|
|
62
68
|
if (options.customWorld && (0, fs_1.existsSync)(customWorldFiles)) {
|
|
63
69
|
(0, devkit_1.generateFiles)(tree, customWorldFiles, projectRoot, substitutions);
|
|
64
70
|
}
|
|
71
|
+
registerPlugin(tree);
|
|
65
72
|
await (0, devkit_1.formatFiles)(tree);
|
|
66
73
|
const additionalDevDependencies = {
|
|
67
74
|
'ts-node': '10.9.1',
|
|
68
75
|
'tsconfig-paths': '4.2.0',
|
|
69
76
|
};
|
|
70
|
-
if (isPlaywright) {
|
|
71
|
-
additionalDevDependencies['kill-port'] = '2.0.1';
|
|
72
|
-
additionalDevDependencies['start-server-and-test'] = '3.0.0';
|
|
73
|
-
}
|
|
74
77
|
const installTask = (0, devkit_1.addDependenciesToPackageJson)(tree, {}, additionalDevDependencies);
|
|
75
78
|
return options.skipInstall ? () => undefined : installTask;
|
|
76
79
|
}
|
|
77
|
-
function buildPlaywrightTargets(
|
|
78
|
-
const prepareCommand = buildPlaywrightPrepareCommand();
|
|
79
|
-
const e2eCommand = buildPlaywrightE2eCommand(tree, projectName, serveTarget, baseUrl, projectRoot);
|
|
80
|
-
const e2eCiCommand = `npx nx run ${e2eProjectName}:e2e-prepare && npx nx run ${e2eProjectName}:e2e`;
|
|
80
|
+
function buildPlaywrightTargets(e2eProjectName, projectRoot) {
|
|
81
81
|
return {
|
|
82
82
|
'e2e-prepare': {
|
|
83
|
-
|
|
83
|
+
cache: false,
|
|
84
|
+
command: buildPlaywrightPrepareCommand(),
|
|
84
85
|
},
|
|
85
86
|
e2e: {
|
|
86
|
-
command:
|
|
87
|
+
command: `node ${projectRoot}/run-e2e.js`,
|
|
87
88
|
},
|
|
88
89
|
'e2e-ci': {
|
|
89
|
-
command:
|
|
90
|
+
command: `npx nx run ${e2eProjectName}:e2e-prepare && npx nx run ${e2eProjectName}:e2e`,
|
|
90
91
|
},
|
|
91
92
|
};
|
|
92
93
|
}
|
|
93
94
|
function buildPlaywrightPrepareCommand() {
|
|
94
95
|
return `node -e "const { execSync } = require('node:child_process'); const installCommand = process.platform === 'linux' ? 'npx playwright install --with-deps chromium' : 'npx playwright install chromium'; execSync(installCommand, { stdio: 'inherit' });"`;
|
|
95
96
|
}
|
|
96
|
-
function
|
|
97
|
+
function buildServeCommand(tree, projectName, serveTarget, baseUrl) {
|
|
97
98
|
const port = readPortFromUrl(baseUrl);
|
|
98
|
-
const
|
|
99
|
-
|
|
99
|
+
const executor = readServeExecutor(tree, projectName);
|
|
100
|
+
return executor === '@nx/vite:dev-server'
|
|
100
101
|
? `npx nx run ${serveTarget} --port=${port} --strictPort`
|
|
101
102
|
: `npx nx run ${serveTarget}`;
|
|
102
|
-
const testCommand = `npx cucumber-js --config ${projectRoot}/cucumber.js`;
|
|
103
|
-
return `npx kill-port ${port} && start-server-and-test "${serveCommand}" ${baseUrl} "${testCommand}"`;
|
|
104
103
|
}
|
|
105
104
|
function readServeExecutor(tree, projectName) {
|
|
106
|
-
|
|
107
|
-
return (0, devkit_1.readProjectConfiguration)(tree, projectName).targets?.['serve']?.executor;
|
|
108
|
-
}
|
|
109
|
-
catch {
|
|
110
|
-
return undefined;
|
|
111
|
-
}
|
|
105
|
+
return (0, devkit_1.readProjectConfiguration)(tree, projectName).targets?.['serve']?.executor;
|
|
112
106
|
}
|
|
113
107
|
function readPortFromUrl(url) {
|
|
114
108
|
const parsedUrl = new URL(url);
|
|
@@ -116,5 +110,54 @@ function readPortFromUrl(url) {
|
|
|
116
110
|
return parsedUrl.port;
|
|
117
111
|
return parsedUrl.protocol === 'https:' ? '443' : '80';
|
|
118
112
|
}
|
|
113
|
+
function ensureProjectExists(tree, projectName) {
|
|
114
|
+
try {
|
|
115
|
+
(0, devkit_1.readProjectConfiguration)(tree, projectName);
|
|
116
|
+
}
|
|
117
|
+
catch {
|
|
118
|
+
throw new Error(`Project "${projectName}" does not exist in this workspace.`);
|
|
119
|
+
}
|
|
120
|
+
}
|
|
121
|
+
function normalizeGeneratedProjectName(projectName, requestedName) {
|
|
122
|
+
const sourceProject = parseScopedProjectName(projectName);
|
|
123
|
+
const requestedProject = parseScopedProjectName(requestedName?.trim() || '');
|
|
124
|
+
if (requestedProject.raw.length < 1) {
|
|
125
|
+
const inferredName = `${sourceProject.name}-e2e`;
|
|
126
|
+
return sourceProject.scope ? `${sourceProject.scope}/${inferredName}` : inferredName;
|
|
127
|
+
}
|
|
128
|
+
if (requestedProject.scope)
|
|
129
|
+
return requestedProject.raw;
|
|
130
|
+
return sourceProject.scope ? `${sourceProject.scope}/${requestedProject.name}` : requestedProject.name;
|
|
131
|
+
}
|
|
132
|
+
function defaultProjectDirectory(projectName) {
|
|
133
|
+
return parseScopedProjectName(projectName).name;
|
|
134
|
+
}
|
|
135
|
+
function parseScopedProjectName(value) {
|
|
136
|
+
const raw = value.trim();
|
|
137
|
+
if (!raw.startsWith('@')) {
|
|
138
|
+
return { raw, scope: '', name: raw };
|
|
139
|
+
}
|
|
140
|
+
const separatorIndex = raw.indexOf('/');
|
|
141
|
+
if (separatorIndex < 1 || separatorIndex >= raw.length - 1) {
|
|
142
|
+
return { raw, scope: '', name: raw };
|
|
143
|
+
}
|
|
144
|
+
return {
|
|
145
|
+
raw,
|
|
146
|
+
scope: raw.slice(0, separatorIndex),
|
|
147
|
+
name: raw.slice(separatorIndex + 1),
|
|
148
|
+
};
|
|
149
|
+
}
|
|
150
|
+
function registerPlugin(tree) {
|
|
151
|
+
if (!tree.exists('nx.json'))
|
|
152
|
+
return;
|
|
153
|
+
(0, devkit_1.updateJson)(tree, 'nx.json', (json) => {
|
|
154
|
+
if (!Array.isArray(json.plugins))
|
|
155
|
+
json.plugins = [];
|
|
156
|
+
if (!json.plugins.includes('@gnuechtel/nx-cucumber')) {
|
|
157
|
+
json.plugins.push('@gnuechtel/nx-cucumber');
|
|
158
|
+
}
|
|
159
|
+
return json;
|
|
160
|
+
});
|
|
161
|
+
}
|
|
119
162
|
exports.default = cucumberJsGenerator;
|
|
120
163
|
//# sourceMappingURL=project.js.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../../../../libs/nx-cucumber/src/generators/project/project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addProjectConfiguration,\n formatFiles,\n generateFiles,\n Tree,\n addDependenciesToPackageJson,\n normalizePath,\n offsetFromRoot,\n getWorkspaceLayout,\n readProjectConfiguration,\n} from '@nx/devkit';\nimport * as path from 'path';\nimport { CucumberJsGeneratorSchema } from './schema';\nimport { existsSync } from 'fs';\nimport { defaultTestRunner } from '../../core/test-run-options';\n\nexport async function cucumberJsGenerator(tree: Tree, options: CucumberJsGeneratorSchema) {\n if (!options.name) options.name = `${options.project}-e2e`;\n if (!options.directory) options.directory = options.name;\n if (!options.testRunner) options.testRunner = defaultTestRunner;\n const isPlaywright = options.testRunner === 'playwright';\n const baseUrl = isPlaywright ? 'http://localhost:4200' : undefined;\n const serveTarget = isPlaywright ? `${options.project}:serve` : undefined;\n\n const normalizedDirectory = normalizePath(options.directory);\n const workspaceLayout = getWorkspaceLayout(tree);\n const skipAppsDir = workspaceLayout.appsDir === '.' || options.ignoreWorkspaceLayout;\n const parentDir = workspaceLayout.appsDir && !skipAppsDir ? workspaceLayout.appsDir + '/' : '';\n const projectRoot = `${parentDir}${normalizedDirectory}`;\n const workspaceRootRelative = offsetFromRoot(projectRoot).replace(/\\/$/, '');\n const playwrightTargets =\n isPlaywright && baseUrl && serveTarget\n ? buildPlaywrightTargets(tree, options.project, options.name, serveTarget, baseUrl, projectRoot)\n : {};\n\n addProjectConfiguration(tree, options.name, {\n root: projectRoot,\n sourceRoot: `${projectRoot}/src`,\n projectType: 'application',\n targets: {\n lint: {\n executor: '@nx/eslint:lint',\n outputs: ['{options.outputFile}'],\n options: {\n lintFilePatterns: [`${projectRoot}/**/*.ts`],\n },\n },\n ...playwrightTargets,\n },\n implicitDependencies: [options.project],\n });\n\n const playwrightRequires =\n options.testRunner === 'playwright'\n ? [\n 'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-world-default.js',\n 'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-hooks.js',\n ]\n : [];\n\n const substitutions = {\n ...options,\n workspaceRootRelative,\n projectRoot,\n playwrightRequires: JSON.stringify(playwrightRequires),\n isPlaywright,\n baseUrl: baseUrl || '',\n serveTarget: serveTarget || '',\n };\n\n generateFiles(tree, path.join(__dirname, 'files', 'all'), projectRoot, substitutions);\n generateFiles(tree, path.join(__dirname, 'files', options.testRunner), projectRoot, substitutions);\n\n const customWorldFiles = path.join(__dirname, 'files', `${options.testRunner}.custom-world`);\n if (options.customWorld && existsSync(customWorldFiles)) {\n generateFiles(tree, customWorldFiles, projectRoot, substitutions);\n }\n\n await formatFiles(tree);\n\n const additionalDevDependencies: Record<string, string> = {\n 'ts-node': '10.9.1',\n 'tsconfig-paths': '4.2.0',\n };\n if (isPlaywright) {\n additionalDevDependencies['kill-port'] = '2.0.1';\n additionalDevDependencies['start-server-and-test'] = '3.0.0';\n }\n\n const installTask = addDependenciesToPackageJson(tree, {}, additionalDevDependencies);\n return options.skipInstall ? () => undefined : installTask;\n}\n\nfunction buildPlaywrightTargets(\n tree: Tree,\n projectName: string,\n e2eProjectName: string,\n serveTarget: string,\n baseUrl: string,\n projectRoot: string\n) {\n const prepareCommand = buildPlaywrightPrepareCommand();\n const e2eCommand = buildPlaywrightE2eCommand(tree, projectName, serveTarget, baseUrl, projectRoot);\n const e2eCiCommand = `npx nx run ${e2eProjectName}:e2e-prepare && npx nx run ${e2eProjectName}:e2e`;\n return {\n 'e2e-prepare': {\n command: prepareCommand,\n },\n e2e: {\n command: e2eCommand,\n },\n 'e2e-ci': {\n command: e2eCiCommand,\n },\n };\n}\n\nfunction buildPlaywrightPrepareCommand() {\n return `node -e \"const { execSync } = require('node:child_process'); const installCommand = process.platform === 'linux' ? 'npx playwright install --with-deps chromium' : 'npx playwright install chromium'; execSync(installCommand, { stdio: 'inherit' });\"`;\n}\n\nfunction buildPlaywrightE2eCommand(\n tree: Tree,\n projectName: string,\n serveTarget: string,\n baseUrl: string,\n projectRoot: string\n) {\n const port = readPortFromUrl(baseUrl);\n const serveExecutor = readServeExecutor(tree, projectName);\n const serveCommand =\n serveExecutor === '@nx/vite:dev-server'\n ? `npx nx run ${serveTarget} --port=${port} --strictPort`\n : `npx nx run ${serveTarget}`;\n const testCommand = `npx cucumber-js --config ${projectRoot}/cucumber.js`;\n return `npx kill-port ${port} && start-server-and-test \"${serveCommand}\" ${baseUrl} \"${testCommand}\"`;\n}\n\nfunction readServeExecutor(tree: Tree, projectName: string) {\n try {\n return readProjectConfiguration(tree, projectName).targets?.['serve']?.executor;\n } catch {\n return undefined;\n }\n}\n\nfunction readPortFromUrl(url: string) {\n const parsedUrl = new URL(url);\n if (parsedUrl.port) return parsedUrl.port;\n return parsedUrl.protocol === 'https:' ? '443' : '80';\n}\n\nexport default cucumberJsGenerator;\n"]}
|
|
1
|
+
{"version":3,"file":"project.js","sourceRoot":"","sources":["../../../../../../libs/nx-cucumber/src/generators/project/project.ts"],"names":[],"mappings":"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","sourcesContent":["import {\n addProjectConfiguration,\n formatFiles,\n generateFiles,\n Tree,\n addDependenciesToPackageJson,\n normalizePath,\n offsetFromRoot,\n getWorkspaceLayout,\n readProjectConfiguration,\n updateJson,\n} from '@nx/devkit';\nimport * as path from 'path';\nimport { CucumberJsGeneratorSchema } from './schema';\nimport { existsSync } from 'fs';\nimport { defaultTestRunner } from '../../core/test-run-options';\n\nexport async function cucumberJsGenerator(tree: Tree, options: CucumberJsGeneratorSchema) {\n if (!options.testRunner) options.testRunner = defaultTestRunner;\n ensureProjectExists(tree, options.project);\n options.name = normalizeGeneratedProjectName(options.project, options.name);\n if (!options.directory) options.directory = defaultProjectDirectory(options.name);\n const isPlaywright = options.testRunner === 'playwright';\n const baseUrl = isPlaywright ? 'http://localhost:4200' : undefined;\n const serveTarget = isPlaywright ? `${options.project}:serve` : undefined;\n\n const normalizedDirectory = normalizePath(options.directory);\n const workspaceLayout = getWorkspaceLayout(tree);\n const skipAppsDir = workspaceLayout.appsDir === '.' || options.ignoreWorkspaceLayout;\n const parentDir = workspaceLayout.appsDir && !skipAppsDir ? workspaceLayout.appsDir + '/' : '';\n const projectRoot = `${parentDir}${normalizedDirectory}`;\n const workspaceRootRelative = offsetFromRoot(projectRoot).replace(/\\/$/, '');\n const playwrightTargets =\n isPlaywright && baseUrl && serveTarget ? buildPlaywrightTargets(options.name, projectRoot) : {};\n\n addProjectConfiguration(tree, options.name, {\n root: projectRoot,\n sourceRoot: `${projectRoot}/src`,\n projectType: 'application',\n targets: {\n lint: {\n executor: '@nx/eslint:lint',\n outputs: ['{options.outputFile}'],\n options: {\n lintFilePatterns: [`${projectRoot}/**/*.ts`],\n },\n },\n ...playwrightTargets,\n },\n implicitDependencies: [options.project],\n });\n\n const playwrightRequires =\n options.testRunner === 'playwright'\n ? [\n 'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-world-default.js',\n 'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-hooks.js',\n ]\n : [];\n\n const serveCommand =\n isPlaywright && baseUrl && serveTarget ? buildServeCommand(tree, options.project, serveTarget, baseUrl) : '';\n const testCommand = `npx cucumber-js --config ${projectRoot}/cucumber.js`;\n const templateProjectName = parseScopedProjectName(options.project).name;\n\n const substitutions = {\n ...options,\n project: templateProjectName,\n testedProject: options.project,\n workspaceRootRelative,\n projectRoot,\n playwrightRequires: JSON.stringify(playwrightRequires),\n isPlaywright,\n baseUrl: baseUrl || '',\n serveTarget: serveTarget || '',\n port: baseUrl ? readPortFromUrl(baseUrl) : 0,\n serveCommandJson: JSON.stringify(serveCommand),\n testCommandJson: JSON.stringify(testCommand),\n };\n\n generateFiles(tree, path.join(__dirname, 'files', 'all'), projectRoot, substitutions);\n generateFiles(tree, path.join(__dirname, 'files', options.testRunner), projectRoot, substitutions);\n\n const customWorldFiles = path.join(__dirname, 'files', `${options.testRunner}.custom-world`);\n if (options.customWorld && existsSync(customWorldFiles)) {\n generateFiles(tree, customWorldFiles, projectRoot, substitutions);\n }\n\n registerPlugin(tree);\n\n await formatFiles(tree);\n\n const additionalDevDependencies: Record<string, string> = {\n 'ts-node': '10.9.1',\n 'tsconfig-paths': '4.2.0',\n };\n\n const installTask = addDependenciesToPackageJson(tree, {}, additionalDevDependencies);\n return options.skipInstall ? () => undefined : installTask;\n}\n\nfunction buildPlaywrightTargets(e2eProjectName: string, projectRoot: string) {\n return {\n 'e2e-prepare': {\n cache: false,\n command: buildPlaywrightPrepareCommand(),\n },\n e2e: {\n command: `node ${projectRoot}/run-e2e.js`,\n },\n 'e2e-ci': {\n command: `npx nx run ${e2eProjectName}:e2e-prepare && npx nx run ${e2eProjectName}:e2e`,\n },\n };\n}\n\nfunction buildPlaywrightPrepareCommand() {\n return `node -e \"const { execSync } = require('node:child_process'); const installCommand = process.platform === 'linux' ? 'npx playwright install --with-deps chromium' : 'npx playwright install chromium'; execSync(installCommand, { stdio: 'inherit' });\"`;\n}\n\nfunction buildServeCommand(tree: Tree, projectName: string, serveTarget: string, baseUrl: string) {\n const port = readPortFromUrl(baseUrl);\n const executor = readServeExecutor(tree, projectName);\n return executor === '@nx/vite:dev-server'\n ? `npx nx run ${serveTarget} --port=${port} --strictPort`\n : `npx nx run ${serveTarget}`;\n}\n\nfunction readServeExecutor(tree: Tree, projectName: string) {\n return readProjectConfiguration(tree, projectName).targets?.['serve']?.executor;\n}\n\nfunction readPortFromUrl(url: string) {\n const parsedUrl = new URL(url);\n if (parsedUrl.port) return parsedUrl.port;\n return parsedUrl.protocol === 'https:' ? '443' : '80';\n}\n\nfunction ensureProjectExists(tree: Tree, projectName: string) {\n try {\n readProjectConfiguration(tree, projectName);\n } catch {\n throw new Error(`Project \"${projectName}\" does not exist in this workspace.`);\n }\n}\n\nfunction normalizeGeneratedProjectName(projectName: string, requestedName?: string) {\n const sourceProject = parseScopedProjectName(projectName);\n const requestedProject = parseScopedProjectName(requestedName?.trim() || '');\n if (requestedProject.raw.length < 1) {\n const inferredName = `${sourceProject.name}-e2e`;\n return sourceProject.scope ? `${sourceProject.scope}/${inferredName}` : inferredName;\n }\n if (requestedProject.scope) return requestedProject.raw;\n return sourceProject.scope ? `${sourceProject.scope}/${requestedProject.name}` : requestedProject.name;\n}\n\nfunction defaultProjectDirectory(projectName: string) {\n return parseScopedProjectName(projectName).name;\n}\n\nfunction parseScopedProjectName(value: string) {\n const raw = value.trim();\n if (!raw.startsWith('@')) {\n return { raw, scope: '', name: raw };\n }\n const separatorIndex = raw.indexOf('/');\n if (separatorIndex < 1 || separatorIndex >= raw.length - 1) {\n return { raw, scope: '', name: raw };\n }\n return {\n raw,\n scope: raw.slice(0, separatorIndex),\n name: raw.slice(separatorIndex + 1),\n };\n}\n\nfunction registerPlugin(tree: Tree) {\n if (!tree.exists('nx.json')) return;\n updateJson(tree, 'nx.json', (json) => {\n if (!Array.isArray(json.plugins)) json.plugins = [];\n if (!json.plugins.includes('@gnuechtel/nx-cucumber')) {\n json.plugins.push('@gnuechtel/nx-cucumber');\n }\n return json;\n });\n}\n\nexport default cucumberJsGenerator;\n"]}
|
package/src/index.d.ts
CHANGED
|
@@ -1,11 +1,8 @@
|
|
|
1
1
|
export * from './playwright/playwright-world';
|
|
2
2
|
export * from './core/test-run-options';
|
|
3
|
-
export { createBeautifulHtmlReport } from './core/cucumber-report-html';
|
|
4
|
-
export { startWebServer, stopWebServer } from './core/web-server';
|
|
5
|
-
export type { WebServerConfig } from './core/web-server';
|
|
6
|
-
export type { BeautifulReportOptions } from './core/cucumber-report-html';
|
|
7
3
|
export * from './adapters/contract';
|
|
8
4
|
export * from './adapters/validation';
|
|
9
5
|
export * from './adapters/registry';
|
|
10
6
|
export { createNodesV2 } from './plugin/create-nodes';
|
|
11
7
|
export type { NxCucumberPluginOptions } from './plugin/create-nodes';
|
|
8
|
+
export { migrateCucumberApiToInferredTasks } from './migrations/update-2-0-0/migrate-cucumber-api-to-inferred-tasks';
|
package/src/index.js
CHANGED
|
@@ -1,17 +1,14 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
exports.migrateCucumberApiToInferredTasks = exports.createNodesV2 = void 0;
|
|
4
4
|
const tslib_1 = require("tslib");
|
|
5
5
|
tslib_1.__exportStar(require("./playwright/playwright-world"), exports);
|
|
6
6
|
tslib_1.__exportStar(require("./core/test-run-options"), exports);
|
|
7
|
-
var cucumber_report_html_1 = require("./core/cucumber-report-html");
|
|
8
|
-
Object.defineProperty(exports, "createBeautifulHtmlReport", { enumerable: true, get: function () { return cucumber_report_html_1.createBeautifulHtmlReport; } });
|
|
9
|
-
var web_server_1 = require("./core/web-server");
|
|
10
|
-
Object.defineProperty(exports, "startWebServer", { enumerable: true, get: function () { return web_server_1.startWebServer; } });
|
|
11
|
-
Object.defineProperty(exports, "stopWebServer", { enumerable: true, get: function () { return web_server_1.stopWebServer; } });
|
|
12
7
|
tslib_1.__exportStar(require("./adapters/contract"), exports);
|
|
13
8
|
tslib_1.__exportStar(require("./adapters/validation"), exports);
|
|
14
9
|
tslib_1.__exportStar(require("./adapters/registry"), exports);
|
|
15
10
|
var create_nodes_1 = require("./plugin/create-nodes");
|
|
16
11
|
Object.defineProperty(exports, "createNodesV2", { enumerable: true, get: function () { return create_nodes_1.createNodesV2; } });
|
|
12
|
+
var migrate_cucumber_api_to_inferred_tasks_1 = require("./migrations/update-2-0-0/migrate-cucumber-api-to-inferred-tasks");
|
|
13
|
+
Object.defineProperty(exports, "migrateCucumberApiToInferredTasks", { enumerable: true, get: function () { return migrate_cucumber_api_to_inferred_tasks_1.migrateCucumberApiToInferredTasks; } });
|
|
17
14
|
//# sourceMappingURL=index.js.map
|
package/src/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/nx-cucumber/src/index.ts"],"names":[],"mappings":";;;;AAAA,wEAA8C;AAC9C,kEAAwC;AACxC,
|
|
1
|
+
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../../../libs/nx-cucumber/src/index.ts"],"names":[],"mappings":";;;;AAAA,wEAA8C;AAC9C,kEAAwC;AACxC,8DAAoC;AACpC,gEAAsC;AACtC,8DAAoC;AACpC,sDAAsD;AAA7C,6GAAA,aAAa,OAAA;AAEtB,2HAAqH;AAA5G,2JAAA,iCAAiC,OAAA","sourcesContent":["export * from './playwright/playwright-world';\nexport * from './core/test-run-options';\nexport * from './adapters/contract';\nexport * from './adapters/validation';\nexport * from './adapters/registry';\nexport { createNodesV2 } from './plugin/create-nodes';\nexport type { NxCucumberPluginOptions } from './plugin/create-nodes';\nexport { migrateCucumberApiToInferredTasks } from './migrations/update-2-0-0/migrate-cucumber-api-to-inferred-tasks';\n"]}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { Tree } from '@nx/devkit';
|
|
2
|
+
interface MigratedProjectReport {
|
|
3
|
+
project: string;
|
|
4
|
+
projectRoot: string;
|
|
5
|
+
removedTargets: string[];
|
|
6
|
+
createdCucumberConfig: boolean;
|
|
7
|
+
manualFollowUps: string[];
|
|
8
|
+
}
|
|
9
|
+
interface MigrationReport {
|
|
10
|
+
dryRun: boolean;
|
|
11
|
+
pluginAdded: boolean;
|
|
12
|
+
removedLegacyTargetDefaults: boolean;
|
|
13
|
+
migratedProjects: MigratedProjectReport[];
|
|
14
|
+
}
|
|
15
|
+
interface MigrationOptions {
|
|
16
|
+
dryRun?: boolean;
|
|
17
|
+
}
|
|
18
|
+
export declare function migrateCucumberApiToInferredTasks(tree: Tree, options?: MigrationOptions): Promise<MigrationReport>;
|
|
19
|
+
export default function migrateCucumberApiToInferredTasksEntry(tree: Tree): Promise<void>;
|
|
20
|
+
export {};
|
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.migrateCucumberApiToInferredTasks = migrateCucumberApiToInferredTasks;
|
|
4
|
+
exports.default = migrateCucumberApiToInferredTasksEntry;
|
|
5
|
+
const devkit_1 = require("@nx/devkit");
|
|
6
|
+
const LEGACY_EXECUTOR = '@gnuechtel/nx-cucumber:cucumber-api';
|
|
7
|
+
const REPORT_PATH = 'tmp/nx-cucumber-migration-report.json';
|
|
8
|
+
const PLUGIN_NAME = '@gnuechtel/nx-cucumber';
|
|
9
|
+
function isDryRunRequested() {
|
|
10
|
+
const arg = process.argv.some((v) => v === '--dry-run' || v === '--dryRun');
|
|
11
|
+
const env = `${process.env['NX_CUCUMBER_MIGRATION_DRY_RUN'] || ''}`.toLowerCase();
|
|
12
|
+
return arg || env === '1' || env === 'true' || env === 'yes';
|
|
13
|
+
}
|
|
14
|
+
function normalizePath(p) {
|
|
15
|
+
return p.replace(/\\/g, '/');
|
|
16
|
+
}
|
|
17
|
+
function resolveTsNodeProject(projectRoot, tsConfig) {
|
|
18
|
+
if (!tsConfig)
|
|
19
|
+
return `${projectRoot}/tsconfig.json`;
|
|
20
|
+
if (tsConfig.includes('/'))
|
|
21
|
+
return normalizePath(tsConfig);
|
|
22
|
+
return `${projectRoot}/${tsConfig}`;
|
|
23
|
+
}
|
|
24
|
+
function hasNxCucumberPlugin(nxJson) {
|
|
25
|
+
if (!nxJson)
|
|
26
|
+
return false;
|
|
27
|
+
return (nxJson.plugins?.some((plugin) => typeof plugin === 'string' ? plugin === PLUGIN_NAME : plugin?.plugin === PLUGIN_NAME) ?? false);
|
|
28
|
+
}
|
|
29
|
+
function getLegacyTargetNames(project) {
|
|
30
|
+
return Object.entries(project.targets ?? {})
|
|
31
|
+
.filter(([, target]) => target.executor === LEGACY_EXECUTOR)
|
|
32
|
+
.map(([targetName]) => targetName);
|
|
33
|
+
}
|
|
34
|
+
function pickLegacyOptions(project) {
|
|
35
|
+
const targets = project.targets ?? {};
|
|
36
|
+
const legacyTarget = targets['e2e-cucumber']?.executor === LEGACY_EXECUTOR
|
|
37
|
+
? targets['e2e-cucumber']
|
|
38
|
+
: Object.values(targets).find((target) => target.executor === LEGACY_EXECUTOR);
|
|
39
|
+
return (legacyTarget?.options ?? {});
|
|
40
|
+
}
|
|
41
|
+
function extractWorldParameters(options) {
|
|
42
|
+
const worldParameters = {};
|
|
43
|
+
const allowedKeys = [
|
|
44
|
+
'baseUrl',
|
|
45
|
+
'browser',
|
|
46
|
+
'headed',
|
|
47
|
+
'debug',
|
|
48
|
+
'disableAnimations',
|
|
49
|
+
'disableCoverage',
|
|
50
|
+
'disableScreenshotAttachments',
|
|
51
|
+
'disableScreenshotFiles',
|
|
52
|
+
'enableSuccessfulScreenshotFiles',
|
|
53
|
+
'disableVideoAttachments',
|
|
54
|
+
'disableVideoFiles',
|
|
55
|
+
'disableJavaScript',
|
|
56
|
+
'additionalPlaywrightConfiguration',
|
|
57
|
+
'viewport',
|
|
58
|
+
'videoSize',
|
|
59
|
+
];
|
|
60
|
+
for (const key of allowedKeys) {
|
|
61
|
+
if (options[key] !== undefined) {
|
|
62
|
+
worldParameters[key] = options[key];
|
|
63
|
+
}
|
|
64
|
+
}
|
|
65
|
+
return worldParameters;
|
|
66
|
+
}
|
|
67
|
+
function createWorldParametersLiteral(worldParameters) {
|
|
68
|
+
const lines = ['{', ' outputDirectory: outputDir,'];
|
|
69
|
+
for (const [key, value] of Object.entries(worldParameters)) {
|
|
70
|
+
lines.push(` ${key}: ${JSON.stringify(value)},`);
|
|
71
|
+
}
|
|
72
|
+
lines.push('}');
|
|
73
|
+
return lines.join('\n');
|
|
74
|
+
}
|
|
75
|
+
function createCucumberConfigContent(projectRoot, options) {
|
|
76
|
+
const outputDir = `dist/e2e/${projectRoot}`;
|
|
77
|
+
const featuresDirectory = normalizePath(options.featuresDirectory || `${projectRoot}/features`);
|
|
78
|
+
const testRunner = options.testRunner === 'playwright' ? 'playwright' : 'core';
|
|
79
|
+
const tsNodeProject = resolveTsNodeProject(projectRoot, typeof options.tsConfig === 'string' ? options.tsConfig : undefined);
|
|
80
|
+
const requireEntries = [`'${projectRoot}/src/**/*.ts'`];
|
|
81
|
+
if (testRunner === 'playwright') {
|
|
82
|
+
requireEntries.push(`'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-world-default.js'`);
|
|
83
|
+
requireEntries.push(`'node_modules/@gnuechtel/nx-cucumber/src/playwright/playwright-hooks.js'`);
|
|
84
|
+
}
|
|
85
|
+
const worldParametersLiteral = createWorldParametersLiteral(extractWorldParameters(options));
|
|
86
|
+
const lines = [
|
|
87
|
+
`process.env.TS_NODE_PROJECT = '${tsNodeProject}';`,
|
|
88
|
+
`const outputDir = 'dist/e2e/${projectRoot}';`,
|
|
89
|
+
`const { pathToFileURL } = require('url');`,
|
|
90
|
+
`const runMetadataFormatter = pathToFileURL(require.resolve('@gnuechtel/nx-cucumber/src/core/cucumber-run-metadata-formatter.js')).href;`,
|
|
91
|
+
`const worldParameters = ${worldParametersLiteral};`,
|
|
92
|
+
'module.exports = {',
|
|
93
|
+
' default: {',
|
|
94
|
+
` paths: ['${featuresDirectory}/**/*.feature'],`,
|
|
95
|
+
` requireModule: ['ts-node/register', 'tsconfig-paths/register'],`,
|
|
96
|
+
` require: [${requireEntries.join(', ')}],`,
|
|
97
|
+
` tags: '${typeof options.tags === 'string' ? options.tags : 'not @ignore'}',`,
|
|
98
|
+
' format: [',
|
|
99
|
+
` 'summary',`,
|
|
100
|
+
` 'progress-bar',`,
|
|
101
|
+
` \`json:\${outputDir}/reports/cucumber-json/cucumber-test-report.json\`,`,
|
|
102
|
+
` \`message:\${outputDir}/reports/cucumber-messages/cucumber-messages.ndjson\`,`,
|
|
103
|
+
` \`html:\${outputDir}/reports/html/cucumber-test-report-builtin.html\`,`,
|
|
104
|
+
` [runMetadataFormatter, \`\${outputDir}/reports/metadata/cucumber-run-metadata.json\`],`,
|
|
105
|
+
` \`junit:\${outputDir}/reports/test-results/cucumber-test-report.xml\`,`,
|
|
106
|
+
' ],',
|
|
107
|
+
' formatOptions: {',
|
|
108
|
+
' nxCucumberRunMetadata: {',
|
|
109
|
+
' worldParameters,',
|
|
110
|
+
' },',
|
|
111
|
+
' },',
|
|
112
|
+
' worldParameters,',
|
|
113
|
+
...(typeof options.cucumberTimeout === 'number' ? [` timeout: ${options.cucumberTimeout},`] : []),
|
|
114
|
+
' publishQuiet: true,',
|
|
115
|
+
' },',
|
|
116
|
+
'};',
|
|
117
|
+
'',
|
|
118
|
+
];
|
|
119
|
+
return lines.join('\n');
|
|
120
|
+
}
|
|
121
|
+
function shouldFlagWatchTarget(targets) {
|
|
122
|
+
const watchCommand = targets?.['e2e-watch']?.options?.['commands'];
|
|
123
|
+
if (!Array.isArray(watchCommand))
|
|
124
|
+
return false;
|
|
125
|
+
return watchCommand.some((cmd) => typeof cmd === 'string' && cmd.includes('watch-message'));
|
|
126
|
+
}
|
|
127
|
+
function shouldRemoveLegacyE2eRunCommand(targets) {
|
|
128
|
+
const e2e = targets?.['e2e'];
|
|
129
|
+
if (!e2e || e2e.executor !== 'nx:run-commands')
|
|
130
|
+
return false;
|
|
131
|
+
const command = e2e.options?.['command'];
|
|
132
|
+
return typeof command === 'string' && command.includes('e2e-cucumber');
|
|
133
|
+
}
|
|
134
|
+
async function migrateCucumberApiToInferredTasks(tree, options = {}) {
|
|
135
|
+
const dryRun = options.dryRun ?? isDryRunRequested();
|
|
136
|
+
const nxJson = ((0, devkit_1.readNxJson)(tree) ?? {});
|
|
137
|
+
const report = {
|
|
138
|
+
dryRun,
|
|
139
|
+
pluginAdded: false,
|
|
140
|
+
removedLegacyTargetDefaults: false,
|
|
141
|
+
migratedProjects: [],
|
|
142
|
+
};
|
|
143
|
+
const hadPlugin = hasNxCucumberPlugin(nxJson);
|
|
144
|
+
if (!hadPlugin) {
|
|
145
|
+
report.pluginAdded = true;
|
|
146
|
+
if (!dryRun) {
|
|
147
|
+
nxJson.plugins ??= [];
|
|
148
|
+
nxJson.plugins.push(PLUGIN_NAME);
|
|
149
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
if (nxJson.targetDefaults?.[LEGACY_EXECUTOR]) {
|
|
153
|
+
report.removedLegacyTargetDefaults = true;
|
|
154
|
+
if (!dryRun) {
|
|
155
|
+
delete nxJson.targetDefaults[LEGACY_EXECUTOR];
|
|
156
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
for (const [projectName, projectConfig] of (0, devkit_1.getProjects)(tree).entries()) {
|
|
160
|
+
const legacyTargets = getLegacyTargetNames(projectConfig);
|
|
161
|
+
const removeLegacyRunCommandTarget = shouldRemoveLegacyE2eRunCommand(projectConfig.targets);
|
|
162
|
+
const removeLegacyWatchTarget = shouldFlagWatchTarget(projectConfig.targets);
|
|
163
|
+
if (legacyTargets.length === 0 && !removeLegacyRunCommandTarget && !removeLegacyWatchTarget)
|
|
164
|
+
continue;
|
|
165
|
+
const manualFollowUps = [];
|
|
166
|
+
const removedTargets = [...legacyTargets];
|
|
167
|
+
if (removeLegacyRunCommandTarget && !removedTargets.includes('e2e')) {
|
|
168
|
+
removedTargets.push('e2e');
|
|
169
|
+
}
|
|
170
|
+
if (removeLegacyWatchTarget && !removedTargets.includes('e2e-watch')) {
|
|
171
|
+
removedTargets.push('e2e-watch');
|
|
172
|
+
}
|
|
173
|
+
const cucumberConfigPath = `${projectConfig.root}/cucumber.js`;
|
|
174
|
+
const hasCucumberConfig = tree.exists(cucumberConfigPath);
|
|
175
|
+
const legacyOptions = pickLegacyOptions(projectConfig);
|
|
176
|
+
if (hasCucumberConfig) {
|
|
177
|
+
manualFollowUps.push(`Existing ${cucumberConfigPath} was kept. Verify tags/paths/worldParameters still reflect prior executor options.`);
|
|
178
|
+
}
|
|
179
|
+
const updatedProject = {
|
|
180
|
+
...projectConfig,
|
|
181
|
+
targets: {
|
|
182
|
+
...(projectConfig.targets ?? {}),
|
|
183
|
+
},
|
|
184
|
+
};
|
|
185
|
+
for (const targetName of removedTargets) {
|
|
186
|
+
delete updatedProject.targets?.[targetName];
|
|
187
|
+
}
|
|
188
|
+
if (!dryRun) {
|
|
189
|
+
(0, devkit_1.updateProjectConfiguration)(tree, projectName, updatedProject);
|
|
190
|
+
if (!hasCucumberConfig) {
|
|
191
|
+
tree.write(cucumberConfigPath, createCucumberConfigContent(projectConfig.root, legacyOptions));
|
|
192
|
+
}
|
|
193
|
+
}
|
|
194
|
+
report.migratedProjects.push({
|
|
195
|
+
project: projectName,
|
|
196
|
+
projectRoot: projectConfig.root,
|
|
197
|
+
removedTargets,
|
|
198
|
+
createdCucumberConfig: !hasCucumberConfig,
|
|
199
|
+
manualFollowUps,
|
|
200
|
+
});
|
|
201
|
+
}
|
|
202
|
+
if (!dryRun) {
|
|
203
|
+
tree.write(REPORT_PATH, JSON.stringify(report, null, 2));
|
|
204
|
+
}
|
|
205
|
+
devkit_1.logger.info(`[nx-cucumber migration] migrated projects: ${report.migratedProjects.length}, pluginAdded: ${report.pluginAdded}, dryRun: ${report.dryRun}`);
|
|
206
|
+
if (report.migratedProjects.length > 0) {
|
|
207
|
+
for (const project of report.migratedProjects) {
|
|
208
|
+
devkit_1.logger.info(`[nx-cucumber migration] ${project.project}: removed targets [${project.removedTargets.join(', ')}], created cucumber.js: ${project.createdCucumberConfig}`);
|
|
209
|
+
for (const followUp of project.manualFollowUps) {
|
|
210
|
+
devkit_1.logger.warn(`[nx-cucumber migration] ${project.project}: ${followUp}`);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
if (!dryRun) {
|
|
215
|
+
devkit_1.logger.info(`[nx-cucumber migration] report written to ${REPORT_PATH}`);
|
|
216
|
+
}
|
|
217
|
+
return report;
|
|
218
|
+
}
|
|
219
|
+
async function migrateCucumberApiToInferredTasksEntry(tree) {
|
|
220
|
+
await migrateCucumberApiToInferredTasks(tree);
|
|
221
|
+
}
|
|
222
|
+
//# sourceMappingURL=migrate-cucumber-api-to-inferred-tasks.js.map
|