@nx/cypress 0.0.0-pr-22179-271588f
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/LICENSE +22 -0
- package/README.md +68 -0
- package/executors.json +9 -0
- package/generators.json +37 -0
- package/index.d.ts +11 -0
- package/index.js +20 -0
- package/migrations.json +111 -0
- package/package.json +58 -0
- package/plugin.d.ts +1 -0
- package/plugin.js +6 -0
- package/plugins/cypress-preset.d.ts +69 -0
- package/plugins/cypress-preset.js +154 -0
- package/src/executors/cypress/cypress.impl.d.ts +40 -0
- package/src/executors/cypress/cypress.impl.js +182 -0
- package/src/executors/cypress/schema.json +186 -0
- package/src/generators/base-setup/base-setup.d.ts +12 -0
- package/src/generators/base-setup/base-setup.js +80 -0
- package/src/generators/base-setup/files/common/__directory__/fixtures/example.json +5 -0
- package/src/generators/base-setup/files/common/__directory__/support/commands.ts__ext__ +35 -0
- package/src/generators/base-setup/files/common/__directory__/tsconfig.json__ext__ +20 -0
- package/src/generators/base-setup/files/config-js-cjs/__directory__/support/commands.js__ext__ +35 -0
- package/src/generators/base-setup/files/config-js-cjs/cypress.config.js__ext__ +3 -0
- package/src/generators/base-setup/files/config-js-esm/__directory__/support/commands.js__ext__ +35 -0
- package/src/generators/base-setup/files/config-js-esm/cypress.config.js__ext__ +3 -0
- package/src/generators/base-setup/files/config-ts/__directory__/support/commands.ts__ext__ +35 -0
- package/src/generators/base-setup/files/config-ts/cypress.config.ts__ext__ +3 -0
- package/src/generators/component-configuration/component-configuration.d.ts +6 -0
- package/src/generators/component-configuration/component-configuration.js +165 -0
- package/src/generators/component-configuration/files/__directory__/support/component-index.html +16 -0
- package/src/generators/component-configuration/files/__directory__/support/component.ts__ext__ +27 -0
- package/src/generators/component-configuration/schema.d.ts +14 -0
- package/src/generators/component-configuration/schema.json +43 -0
- package/src/generators/configuration/configuration.d.ts +23 -0
- package/src/generators/configuration/configuration.js +220 -0
- package/src/generators/configuration/files/v10/__directory__/e2e/app.cy.ts__tmpl__ +13 -0
- package/src/generators/configuration/files/v10/__directory__/support/app.po.ts__tmpl__ +1 -0
- package/src/generators/configuration/files/v10/__directory__/support/e2e.ts__tmpl__ +17 -0
- package/src/generators/configuration/files/v9/__directory__/fixtures/example.json__tmpl__ +4 -0
- package/src/generators/configuration/files/v9/__directory__/integration/app.spec.ts__tmpl__ +13 -0
- package/src/generators/configuration/files/v9/__directory__/plugins/index.js +22 -0
- package/src/generators/configuration/files/v9/__directory__/support/app.po.ts__tmpl__ +1 -0
- package/src/generators/configuration/files/v9/__directory__/support/commands.ts__tmpl__ +33 -0
- package/src/generators/configuration/files/v9/__directory__/support/index.ts__tmpl__ +17 -0
- package/src/generators/configuration/files/v9/__directory__/tsconfig.json +10 -0
- package/src/generators/configuration/files/v9/cypress.json +12 -0
- package/src/generators/configuration/schema.json +96 -0
- package/src/generators/cypress-project/cypress-project.d.ts +16 -0
- package/src/generators/cypress-project/cypress-project.js +213 -0
- package/src/generators/cypress-project/files/v10-and-after/cypress.config.ts__tmpl__ +10 -0
- package/src/generators/cypress-project/files/v10-and-after/src/e2e/app.cy.ts__tmpl__ +13 -0
- package/src/generators/cypress-project/files/v10-and-after/src/fixtures/example.json__tmpl__ +4 -0
- package/src/generators/cypress-project/files/v10-and-after/src/support/app.po.ts__tmpl__ +1 -0
- package/src/generators/cypress-project/files/v10-and-after/src/support/commands.ts__tmpl__ +33 -0
- package/src/generators/cypress-project/files/v10-and-after/src/support/e2e.ts__tmpl__ +17 -0
- package/src/generators/cypress-project/files/v10-and-after/tsconfig.json +10 -0
- package/src/generators/cypress-project/files/v9-and-under/cypress.json +12 -0
- package/src/generators/cypress-project/files/v9-and-under/src/fixtures/example.json__tmpl__ +4 -0
- package/src/generators/cypress-project/files/v9-and-under/src/integration/app.spec.ts__tmpl__ +13 -0
- package/src/generators/cypress-project/files/v9-and-under/src/plugins/index.js +22 -0
- package/src/generators/cypress-project/files/v9-and-under/src/support/app.po.ts__tmpl__ +1 -0
- package/src/generators/cypress-project/files/v9-and-under/src/support/commands.ts__tmpl__ +33 -0
- package/src/generators/cypress-project/files/v9-and-under/src/support/index.ts__tmpl__ +17 -0
- package/src/generators/cypress-project/files/v9-and-under/tsconfig.json +10 -0
- package/src/generators/cypress-project/schema.d.ts +17 -0
- package/src/generators/cypress-project/schema.json +78 -0
- package/src/generators/init/init.d.ts +6 -0
- package/src/generators/init/init.js +97 -0
- package/src/generators/init/schema.d.ts +7 -0
- package/src/generators/init/schema.json +34 -0
- package/src/generators/migrate-to-cypress-11/conversion.util.d.ts +39 -0
- package/src/generators/migrate-to-cypress-11/conversion.util.js +246 -0
- package/src/generators/migrate-to-cypress-11/migrate-to-cypress-11.d.ts +3 -0
- package/src/generators/migrate-to-cypress-11/migrate-to-cypress-11.js +93 -0
- package/src/generators/migrate-to-cypress-11/schema.json +15 -0
- package/src/migrations/update-15-0-0/add-cypress-inputs.d.ts +2 -0
- package/src/migrations/update-15-0-0/add-cypress-inputs.js +42 -0
- package/src/migrations/update-15-0-0/update-cy-mount-usage.d.ts +5 -0
- package/src/migrations/update-15-0-0/update-cy-mount-usage.js +119 -0
- package/src/migrations/update-15-1-0/cypress-11.d.ts +6 -0
- package/src/migrations/update-15-1-0/cypress-11.js +114 -0
- package/src/migrations/update-15-5-0/helpers.d.ts +3 -0
- package/src/migrations/update-15-5-0/helpers.js +39 -0
- package/src/migrations/update-15-5-0/update-to-cypress-12.d.ts +24 -0
- package/src/migrations/update-15-5-0/update-to-cypress-12.js +180 -0
- package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.d.ts +2 -0
- package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +9 -0
- package/src/migrations/update-16-2-0/update-cy-tsconfig.d.ts +3 -0
- package/src/migrations/update-16-2-0/update-cy-tsconfig.js +77 -0
- package/src/migrations/update-16-4-0/tsconfig-sourcemaps.d.ts +3 -0
- package/src/migrations/update-16-4-0/tsconfig-sourcemaps.js +62 -0
- package/src/migrations/update-16-8-0/cypress-13.d.ts +7 -0
- package/src/migrations/update-16-8-0/cypress-13.js +179 -0
- package/src/migrations/update-18-1-0/update-cypress-version-13-6-6.d.ts +2 -0
- package/src/migrations/update-18-1-0/update-cypress-version-13-6-6.js +12 -0
- package/src/plugins/plugin.d.ts +8 -0
- package/src/plugins/plugin.js +195 -0
- package/src/plugins/preprocessor-vite.d.ts +32 -0
- package/src/plugins/preprocessor-vite.js +97 -0
- package/src/utils/add-linter.d.ts +22 -0
- package/src/utils/add-linter.js +93 -0
- package/src/utils/config.d.ts +17 -0
- package/src/utils/config.js +115 -0
- package/src/utils/constants.d.ts +4 -0
- package/src/utils/constants.js +7 -0
- package/src/utils/ct-helpers.d.ts +16 -0
- package/src/utils/ct-helpers.js +86 -0
- package/src/utils/cypress-version.d.ts +5 -0
- package/src/utils/cypress-version.js +33 -0
- package/src/utils/find-target-options.d.ts +17 -0
- package/src/utils/find-target-options.js +136 -0
- package/src/utils/project-name.d.ts +3 -0
- package/src/utils/project-name.js +19 -0
- package/src/utils/start-dev-server.d.ts +9 -0
- package/src/utils/start-dev-server.js +157 -0
- package/src/utils/versions.d.ts +9 -0
- package/src/utils/versions.js +12 -0
|
@@ -0,0 +1,165 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.updateTsConfigForComponentTesting = exports.componentConfigurationGeneratorInternal = exports.componentConfigurationGenerator = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const cypress_version_1 = require("../../utils/cypress-version");
|
|
6
|
+
const versions_1 = require("../../utils/versions");
|
|
7
|
+
const base_setup_1 = require("../base-setup/base-setup");
|
|
8
|
+
const init_1 = require("../init/init");
|
|
9
|
+
function componentConfigurationGenerator(tree, options) {
|
|
10
|
+
return componentConfigurationGeneratorInternal(tree, {
|
|
11
|
+
addPlugin: false,
|
|
12
|
+
...options,
|
|
13
|
+
});
|
|
14
|
+
}
|
|
15
|
+
exports.componentConfigurationGenerator = componentConfigurationGenerator;
|
|
16
|
+
async function componentConfigurationGeneratorInternal(tree, options) {
|
|
17
|
+
const tasks = [];
|
|
18
|
+
const opts = normalizeOptions(tree, options);
|
|
19
|
+
tasks.push(await (0, init_1.default)(tree, {
|
|
20
|
+
...opts,
|
|
21
|
+
skipFormat: true,
|
|
22
|
+
}));
|
|
23
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
24
|
+
const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
|
|
25
|
+
? p === '@nx/cypress/plugin'
|
|
26
|
+
: p.plugin === '@nx/cypress/plugin');
|
|
27
|
+
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, opts.project);
|
|
28
|
+
tasks.push(updateDeps(tree, opts));
|
|
29
|
+
addProjectFiles(tree, projectConfig, opts);
|
|
30
|
+
if (!hasPlugin || opts.addExplicitTargets) {
|
|
31
|
+
addTargetToProject(tree, projectConfig, opts);
|
|
32
|
+
}
|
|
33
|
+
updateNxJsonConfiguration(tree, hasPlugin);
|
|
34
|
+
updateTsConfigForComponentTesting(tree, projectConfig);
|
|
35
|
+
if (!opts.skipFormat) {
|
|
36
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
37
|
+
}
|
|
38
|
+
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
39
|
+
}
|
|
40
|
+
exports.componentConfigurationGeneratorInternal = componentConfigurationGeneratorInternal;
|
|
41
|
+
function normalizeOptions(tree, options) {
|
|
42
|
+
const cyVersion = (0, cypress_version_1.installedCypressVersion)();
|
|
43
|
+
if (cyVersion && cyVersion < 10) {
|
|
44
|
+
throw new Error('Cypress version of 10 or higher is required to use component testing. See the migration guide to upgrade. https://nx.dev/cypress/v11-migration-guide');
|
|
45
|
+
}
|
|
46
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
47
|
+
const addPlugin = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
48
|
+
nxJson.useInferencePlugins !== false;
|
|
49
|
+
return {
|
|
50
|
+
addPlugin,
|
|
51
|
+
...options,
|
|
52
|
+
framework: options.framework ?? null,
|
|
53
|
+
directory: options.directory ?? 'cypress',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
function updateDeps(tree, opts) {
|
|
57
|
+
const devDeps = {
|
|
58
|
+
cypress: versions_1.cypressVersion,
|
|
59
|
+
};
|
|
60
|
+
if (opts.bundler === 'vite') {
|
|
61
|
+
devDeps['@cypress/vite-dev-server'] = versions_1.cypressViteDevServerVersion;
|
|
62
|
+
}
|
|
63
|
+
else {
|
|
64
|
+
devDeps['@cypress/webpack-dev-server'] = versions_1.cypressWebpackVersion;
|
|
65
|
+
devDeps['html-webpack-plugin'] = versions_1.htmlWebpackPluginVersion;
|
|
66
|
+
}
|
|
67
|
+
return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, devDeps);
|
|
68
|
+
}
|
|
69
|
+
function addProjectFiles(tree, projectConfig, opts) {
|
|
70
|
+
(0, base_setup_1.addBaseCypressSetup)(tree, {
|
|
71
|
+
project: opts.project,
|
|
72
|
+
directory: opts.directory,
|
|
73
|
+
jsx: opts.jsx,
|
|
74
|
+
});
|
|
75
|
+
(0, devkit_1.generateFiles)(tree, (0, devkit_1.joinPathFragments)(__dirname, 'files'), projectConfig.root, {
|
|
76
|
+
...opts,
|
|
77
|
+
projectRoot: projectConfig.root,
|
|
78
|
+
offsetFromRoot: (0, devkit_1.offsetFromRoot)(projectConfig.root),
|
|
79
|
+
ext: '',
|
|
80
|
+
});
|
|
81
|
+
}
|
|
82
|
+
function addTargetToProject(tree, projectConfig, opts) {
|
|
83
|
+
projectConfig.targets['component-test'] = {
|
|
84
|
+
executor: '@nx/cypress:cypress',
|
|
85
|
+
options: {
|
|
86
|
+
cypressConfig: (0, devkit_1.joinPathFragments)(projectConfig.root, 'cypress.config.ts'),
|
|
87
|
+
testingType: 'component',
|
|
88
|
+
},
|
|
89
|
+
};
|
|
90
|
+
(0, devkit_1.updateProjectConfiguration)(tree, opts.project, projectConfig);
|
|
91
|
+
}
|
|
92
|
+
function updateNxJsonConfiguration(tree, hasPlugin) {
|
|
93
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
94
|
+
const productionFileSet = nxJson.namedInputs?.production;
|
|
95
|
+
if (productionFileSet) {
|
|
96
|
+
nxJson.namedInputs.production = Array.from(new Set([
|
|
97
|
+
...productionFileSet,
|
|
98
|
+
'!{projectRoot}/cypress/**/*',
|
|
99
|
+
'!{projectRoot}/**/*.cy.[jt]s?(x)',
|
|
100
|
+
'!{projectRoot}/cypress.config.[jt]s',
|
|
101
|
+
]));
|
|
102
|
+
}
|
|
103
|
+
if (!hasPlugin) {
|
|
104
|
+
const cacheableOperations = nxJson.tasksRunnerOptions?.default?.options?.cacheableOperations;
|
|
105
|
+
if (cacheableOperations &&
|
|
106
|
+
!cacheableOperations.includes('component-test')) {
|
|
107
|
+
cacheableOperations.push('component-test');
|
|
108
|
+
}
|
|
109
|
+
nxJson.targetDefaults ??= {};
|
|
110
|
+
nxJson.targetDefaults['component-test'] ??= {};
|
|
111
|
+
nxJson.targetDefaults['component-test'].cache ??= true;
|
|
112
|
+
nxJson.targetDefaults['component-test'] ??= {};
|
|
113
|
+
nxJson.targetDefaults['component-test'].inputs ??= [
|
|
114
|
+
'default',
|
|
115
|
+
productionFileSet ? '^production' : '^default',
|
|
116
|
+
];
|
|
117
|
+
}
|
|
118
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
119
|
+
}
|
|
120
|
+
function updateTsConfigForComponentTesting(tree, projectConfig) {
|
|
121
|
+
const tsConfigPath = (0, devkit_1.joinPathFragments)(projectConfig.root, projectConfig.projectType === 'library'
|
|
122
|
+
? 'tsconfig.lib.json'
|
|
123
|
+
: 'tsconfig.app.json');
|
|
124
|
+
if (tree.exists(tsConfigPath)) {
|
|
125
|
+
(0, devkit_1.updateJson)(tree, tsConfigPath, (json) => {
|
|
126
|
+
const excluded = new Set([
|
|
127
|
+
...(json.exclude || []),
|
|
128
|
+
'cypress/**/*',
|
|
129
|
+
'cypress.config.ts',
|
|
130
|
+
'**/*.cy.ts',
|
|
131
|
+
'**/*.cy.js',
|
|
132
|
+
'**/*.cy.tsx',
|
|
133
|
+
'**/*.cy.jsx',
|
|
134
|
+
]);
|
|
135
|
+
json.exclude = Array.from(excluded);
|
|
136
|
+
return json;
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
const projectBaseTsConfig = (0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json');
|
|
140
|
+
if (tree.exists(projectBaseTsConfig)) {
|
|
141
|
+
(0, devkit_1.updateJson)(tree, projectBaseTsConfig, (json) => {
|
|
142
|
+
if (json.references) {
|
|
143
|
+
const hasCyTsConfig = json.references.some((r) => r.path.includes('./cypress/tsconfig.json'));
|
|
144
|
+
if (!hasCyTsConfig) {
|
|
145
|
+
json.references.push({ path: './cypress/tsconfig.json' });
|
|
146
|
+
}
|
|
147
|
+
}
|
|
148
|
+
else {
|
|
149
|
+
const excluded = new Set([
|
|
150
|
+
...(json.exclude || []),
|
|
151
|
+
'cypress/**/*',
|
|
152
|
+
'cypress.config.ts',
|
|
153
|
+
'**/*.cy.ts',
|
|
154
|
+
'**/*.cy.js',
|
|
155
|
+
'**/*.cy.tsx',
|
|
156
|
+
'**/*.cy.jsx',
|
|
157
|
+
]);
|
|
158
|
+
json.exclude = Array.from(excluded);
|
|
159
|
+
}
|
|
160
|
+
return json;
|
|
161
|
+
});
|
|
162
|
+
}
|
|
163
|
+
}
|
|
164
|
+
exports.updateTsConfigForComponentTesting = updateTsConfigForComponentTesting;
|
|
165
|
+
exports.default = componentConfigurationGenerator;
|
package/src/generators/component-configuration/files/__directory__/support/component-index.html
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
<!DOCTYPE html>
|
|
2
|
+
<html>
|
|
3
|
+
<head>
|
|
4
|
+
<meta charset="utf-8">
|
|
5
|
+
<meta http-equiv="X-UA-Compatible" content="IE=edge">
|
|
6
|
+
<meta name="viewport" content="width=device-width,initial-scale=1.0">
|
|
7
|
+
<title><%= project %> Components App</title>
|
|
8
|
+
<% if(framework === 'next') { %>
|
|
9
|
+
<!-- Used by Next.js to inject CSS. -->
|
|
10
|
+
<div id="__next_css__DO_NOT_USE__"></div>
|
|
11
|
+
<% } %>
|
|
12
|
+
</head>
|
|
13
|
+
<body>
|
|
14
|
+
<div data-cy-root></div>
|
|
15
|
+
</body>
|
|
16
|
+
</html>
|
package/src/generators/component-configuration/files/__directory__/support/component.ts__ext__
ADDED
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
// ***********************************************************
|
|
2
|
+
// This example support/component.ts is processed and
|
|
3
|
+
// loaded automatically before your test files.
|
|
4
|
+
//
|
|
5
|
+
// This is a great place to put global configuration and
|
|
6
|
+
// behavior that modifies Cypress.
|
|
7
|
+
//
|
|
8
|
+
// You can change the location of this file or turn off
|
|
9
|
+
// automatically serving support files with the
|
|
10
|
+
// 'supportFile' configuration option.
|
|
11
|
+
//
|
|
12
|
+
// You can read more here:
|
|
13
|
+
// https://on.cypress.io/configuration
|
|
14
|
+
// ***********************************************************
|
|
15
|
+
|
|
16
|
+
// Import commands.ts using ES2015 syntax:
|
|
17
|
+
import './commands';
|
|
18
|
+
|
|
19
|
+
// add component testing only related command here, such as mount
|
|
20
|
+
declare global {
|
|
21
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace
|
|
22
|
+
namespace Cypress {
|
|
23
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars
|
|
24
|
+
interface Chainable<Subject> {
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
}
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
export interface CypressComponentConfigurationSchema {
|
|
2
|
+
project: string;
|
|
3
|
+
skipFormat: boolean;
|
|
4
|
+
directory?: string;
|
|
5
|
+
bundler?: 'webpack' | 'vite';
|
|
6
|
+
jsx?: boolean;
|
|
7
|
+
addPlugin?: boolean;
|
|
8
|
+
|
|
9
|
+
/**
|
|
10
|
+
* @internal
|
|
11
|
+
*/
|
|
12
|
+
addExplicitTargets?: boolean;
|
|
13
|
+
framework?: 'next';
|
|
14
|
+
}
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
{
|
|
2
|
+
"$schema": "https://json-schema.org/schema",
|
|
3
|
+
"$id": "NxCypressComponentConfiguration",
|
|
4
|
+
"cli": "nx",
|
|
5
|
+
"title": "Set up Cypress component testing for a project",
|
|
6
|
+
"description": "Set up Cypress component test for a project.",
|
|
7
|
+
"type": "object",
|
|
8
|
+
"examples": [
|
|
9
|
+
{
|
|
10
|
+
"command": "nx g @nx/cypress:component-configuration --project=my-cool-lib ",
|
|
11
|
+
"description": "Add cypress component testing to an existing project named my-cool-lib"
|
|
12
|
+
}
|
|
13
|
+
],
|
|
14
|
+
"properties": {
|
|
15
|
+
"project": {
|
|
16
|
+
"type": "string",
|
|
17
|
+
"description": "The name of the project to add cypress component testing to",
|
|
18
|
+
"$default": {
|
|
19
|
+
"$source": "projectName"
|
|
20
|
+
},
|
|
21
|
+
"x-prompt": "What project should we add Cypress component testing to?"
|
|
22
|
+
},
|
|
23
|
+
"bundler": {
|
|
24
|
+
"description": "The Cypress bundler to use.",
|
|
25
|
+
"type": "string",
|
|
26
|
+
"enum": ["vite", "webpack"],
|
|
27
|
+
"x-prompt": "Which Cypress bundler do you want to use for the dev-server?",
|
|
28
|
+
"default": "webpack"
|
|
29
|
+
},
|
|
30
|
+
"directory": {
|
|
31
|
+
"type": "string",
|
|
32
|
+
"description": "A directory where the project is placed relative from the project root",
|
|
33
|
+
"default": "cypress"
|
|
34
|
+
},
|
|
35
|
+
"jsx": {
|
|
36
|
+
"description": "Whether or not this project uses JSX.",
|
|
37
|
+
"type": "boolean",
|
|
38
|
+
"default": true
|
|
39
|
+
}
|
|
40
|
+
},
|
|
41
|
+
"required": ["project"],
|
|
42
|
+
"examplesFile": "../../../docs/cypress-component-configuration-examples.md"
|
|
43
|
+
}
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
import { GeneratorCallback, Tree } from '@nx/devkit';
|
|
2
|
+
import { Linter } from '@nx/eslint';
|
|
3
|
+
export interface CypressE2EConfigSchema {
|
|
4
|
+
project: string;
|
|
5
|
+
baseUrl?: string;
|
|
6
|
+
directory?: string;
|
|
7
|
+
js?: boolean;
|
|
8
|
+
skipFormat?: boolean;
|
|
9
|
+
setParserOptionsProject?: boolean;
|
|
10
|
+
skipPackageJson?: boolean;
|
|
11
|
+
bundler?: 'webpack' | 'vite' | 'none';
|
|
12
|
+
devServerTarget?: string;
|
|
13
|
+
linter?: Linter;
|
|
14
|
+
port?: number | 'cypress-auto';
|
|
15
|
+
jsx?: boolean;
|
|
16
|
+
rootProject?: boolean;
|
|
17
|
+
webServerCommands?: Record<string, string>;
|
|
18
|
+
ciWebServerCommand?: string;
|
|
19
|
+
addPlugin?: boolean;
|
|
20
|
+
}
|
|
21
|
+
export declare function configurationGenerator(tree: Tree, options: CypressE2EConfigSchema): Promise<GeneratorCallback>;
|
|
22
|
+
export declare function configurationGeneratorInternal(tree: Tree, options: CypressE2EConfigSchema): Promise<GeneratorCallback>;
|
|
23
|
+
export default configurationGenerator;
|
|
@@ -0,0 +1,220 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.configurationGeneratorInternal = exports.configurationGenerator = void 0;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const js_1 = require("@nx/js");
|
|
6
|
+
const eslint_1 = require("@nx/eslint");
|
|
7
|
+
const path_1 = require("path");
|
|
8
|
+
const add_linter_1 = require("../../utils/add-linter");
|
|
9
|
+
const config_1 = require("../../utils/config");
|
|
10
|
+
const cypress_version_1 = require("../../utils/cypress-version");
|
|
11
|
+
const versions_1 = require("../../utils/versions");
|
|
12
|
+
const init_1 = require("../init/init");
|
|
13
|
+
const base_setup_1 = require("../base-setup/base-setup");
|
|
14
|
+
function configurationGenerator(tree, options) {
|
|
15
|
+
return configurationGeneratorInternal(tree, {
|
|
16
|
+
addPlugin: false,
|
|
17
|
+
...options,
|
|
18
|
+
});
|
|
19
|
+
}
|
|
20
|
+
exports.configurationGenerator = configurationGenerator;
|
|
21
|
+
async function configurationGeneratorInternal(tree, options) {
|
|
22
|
+
const opts = normalizeOptions(tree, options);
|
|
23
|
+
opts.addPlugin ??= process.env.NX_ADD_PLUGINS !== 'false';
|
|
24
|
+
const tasks = [];
|
|
25
|
+
if (!(0, cypress_version_1.installedCypressVersion)()) {
|
|
26
|
+
tasks.push(await (0, js_1.initGenerator)(tree, { ...options, skipFormat: true }));
|
|
27
|
+
tasks.push(await (0, init_1.default)(tree, {
|
|
28
|
+
...opts,
|
|
29
|
+
skipFormat: true,
|
|
30
|
+
}));
|
|
31
|
+
}
|
|
32
|
+
else if (opts.addPlugin) {
|
|
33
|
+
(0, init_1.addPlugin)(tree);
|
|
34
|
+
}
|
|
35
|
+
const projectGraph = await (0, devkit_1.createProjectGraphAsync)();
|
|
36
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
37
|
+
const hasPlugin = nxJson.plugins?.some((p) => typeof p === 'string'
|
|
38
|
+
? p === '@nx/cypress/plugin'
|
|
39
|
+
: p.plugin === '@nx/cypress/plugin');
|
|
40
|
+
await addFiles(tree, opts, projectGraph, hasPlugin);
|
|
41
|
+
if (!hasPlugin) {
|
|
42
|
+
addTarget(tree, opts);
|
|
43
|
+
}
|
|
44
|
+
const linterTask = await (0, add_linter_1.addLinterToCyProject)(tree, {
|
|
45
|
+
...opts,
|
|
46
|
+
cypressDir: opts.directory,
|
|
47
|
+
});
|
|
48
|
+
tasks.push(linterTask);
|
|
49
|
+
if (!opts.skipPackageJson) {
|
|
50
|
+
tasks.push(ensureDependencies(tree, opts));
|
|
51
|
+
}
|
|
52
|
+
if (!opts.skipFormat) {
|
|
53
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
54
|
+
}
|
|
55
|
+
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
56
|
+
}
|
|
57
|
+
exports.configurationGeneratorInternal = configurationGeneratorInternal;
|
|
58
|
+
function ensureDependencies(tree, options) {
|
|
59
|
+
const devDependencies = {
|
|
60
|
+
'@types/node': versions_1.typesNodeVersion,
|
|
61
|
+
};
|
|
62
|
+
if (options.bundler === 'vite') {
|
|
63
|
+
devDependencies['vite'] = versions_1.viteVersion;
|
|
64
|
+
}
|
|
65
|
+
return (0, devkit_1.addDependenciesToPackageJson)(tree, {}, devDependencies);
|
|
66
|
+
}
|
|
67
|
+
function normalizeOptions(tree, options) {
|
|
68
|
+
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
69
|
+
if (projectConfig?.targets?.e2e) {
|
|
70
|
+
throw new Error(`Project ${options.project} already has an e2e target.
|
|
71
|
+
Rename or remove the existing e2e target.`);
|
|
72
|
+
}
|
|
73
|
+
if (!options.baseUrl &&
|
|
74
|
+
!options.devServerTarget &&
|
|
75
|
+
!projectConfig.targets.serve) {
|
|
76
|
+
throw new Error(`The project ${options.project} does not have a 'serve' target.
|
|
77
|
+
In this case you need to provide a devServerTarget,'<projectName>:<targetName>[:<configName>]', or a baseUrl option`);
|
|
78
|
+
}
|
|
79
|
+
options.directory ??= 'src';
|
|
80
|
+
const devServerTarget = options.devServerTarget ??
|
|
81
|
+
(projectConfig.targets.serve ? `${options.project}:serve` : undefined);
|
|
82
|
+
if (!options.baseUrl && !devServerTarget) {
|
|
83
|
+
throw new Error('Either baseUrl or devServerTarget must be provided');
|
|
84
|
+
}
|
|
85
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
86
|
+
options.addPlugin ??=
|
|
87
|
+
process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
88
|
+
nxJson.useInferencePlugins !== false;
|
|
89
|
+
return {
|
|
90
|
+
...options,
|
|
91
|
+
bundler: options.bundler ?? 'webpack',
|
|
92
|
+
rootProject: options.rootProject ?? projectConfig.root === '.',
|
|
93
|
+
linter: options.linter ?? eslint_1.Linter.EsLint,
|
|
94
|
+
devServerTarget,
|
|
95
|
+
};
|
|
96
|
+
}
|
|
97
|
+
async function addFiles(tree, options, projectGraph, hasPlugin) {
|
|
98
|
+
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
99
|
+
const cyVersion = (0, cypress_version_1.installedCypressVersion)();
|
|
100
|
+
const filesToUse = cyVersion && cyVersion < 10 ? 'v9' : 'v10';
|
|
101
|
+
const hasTsConfig = tree.exists((0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json'));
|
|
102
|
+
const offsetFromProjectRoot = options.directory
|
|
103
|
+
.split('/')
|
|
104
|
+
.map((_) => '..')
|
|
105
|
+
.join('/');
|
|
106
|
+
const fileOpts = {
|
|
107
|
+
...options,
|
|
108
|
+
dir: options.directory ?? 'src',
|
|
109
|
+
ext: options.js ? 'js' : 'ts',
|
|
110
|
+
offsetFromRoot: (0, devkit_1.offsetFromRoot)(projectConfig.root),
|
|
111
|
+
offsetFromProjectRoot,
|
|
112
|
+
projectRoot: projectConfig.root,
|
|
113
|
+
tsConfigPath: hasTsConfig
|
|
114
|
+
? `${offsetFromProjectRoot}/tsconfig.json`
|
|
115
|
+
: (0, js_1.getRelativePathToRootTsConfig)(tree, projectConfig.root),
|
|
116
|
+
tmpl: '',
|
|
117
|
+
};
|
|
118
|
+
(0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files', filesToUse), projectConfig.root, fileOpts);
|
|
119
|
+
if (filesToUse === 'v10') {
|
|
120
|
+
(0, base_setup_1.addBaseCypressSetup)(tree, {
|
|
121
|
+
project: options.project,
|
|
122
|
+
directory: options.directory,
|
|
123
|
+
jsx: options.jsx,
|
|
124
|
+
js: options.js,
|
|
125
|
+
});
|
|
126
|
+
const cyFile = (0, devkit_1.joinPathFragments)(projectConfig.root, options.js ? 'cypress.config.js' : 'cypress.config.ts');
|
|
127
|
+
let webServerCommands;
|
|
128
|
+
let ciWebServerCommand;
|
|
129
|
+
if (hasPlugin && options.webServerCommands && options.ciWebServerCommand) {
|
|
130
|
+
webServerCommands = options.webServerCommands;
|
|
131
|
+
ciWebServerCommand = options.ciWebServerCommand;
|
|
132
|
+
}
|
|
133
|
+
else if (hasPlugin && options.devServerTarget) {
|
|
134
|
+
webServerCommands = {};
|
|
135
|
+
webServerCommands.default = 'nx run ' + options.devServerTarget;
|
|
136
|
+
const parsedTarget = (0, devkit_1.parseTargetString)(options.devServerTarget, projectGraph);
|
|
137
|
+
const devServerProjectConfig = (0, devkit_1.readProjectConfiguration)(tree, parsedTarget.project);
|
|
138
|
+
// Add production e2e target if serve target is found
|
|
139
|
+
if (parsedTarget.configuration !== 'production' &&
|
|
140
|
+
devServerProjectConfig?.targets?.[parsedTarget.target]
|
|
141
|
+
?.configurations?.['production']) {
|
|
142
|
+
webServerCommands.production = `nx run ${parsedTarget.project}:${parsedTarget.target}:production`;
|
|
143
|
+
}
|
|
144
|
+
// Add ci/static e2e target if serve target is found
|
|
145
|
+
if (devServerProjectConfig?.targets?.['serve-static']) {
|
|
146
|
+
ciWebServerCommand = `nx run ${parsedTarget.project}:serve-static`;
|
|
147
|
+
}
|
|
148
|
+
}
|
|
149
|
+
const updatedCyConfig = await (0, config_1.addDefaultE2EConfig)(tree.read(cyFile, 'utf-8'), {
|
|
150
|
+
cypressDir: options.directory,
|
|
151
|
+
bundler: options.bundler === 'vite' ? 'vite' : undefined,
|
|
152
|
+
webServerCommands,
|
|
153
|
+
ciWebServerCommand: ciWebServerCommand,
|
|
154
|
+
}, options.baseUrl);
|
|
155
|
+
tree.write(cyFile, updatedCyConfig);
|
|
156
|
+
}
|
|
157
|
+
if (cyVersion &&
|
|
158
|
+
cyVersion < 7 &&
|
|
159
|
+
tree.exists((0, devkit_1.joinPathFragments)(projectConfig.root, 'src', 'plugins', 'index.js'))) {
|
|
160
|
+
(0, devkit_1.updateJson)(tree, (0, path_1.join)(projectConfig.root, 'cypress.json'), (json) => {
|
|
161
|
+
json.pluginsFile = './src/plugins/index';
|
|
162
|
+
return json;
|
|
163
|
+
});
|
|
164
|
+
}
|
|
165
|
+
else if (cyVersion < 10) {
|
|
166
|
+
const pluginPath = (0, path_1.join)(projectConfig.root, 'src/plugins/index.js');
|
|
167
|
+
if (tree.exists(pluginPath)) {
|
|
168
|
+
tree.delete(pluginPath);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
if (options.js) {
|
|
172
|
+
(0, devkit_1.toJS)(tree);
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
function addTarget(tree, opts) {
|
|
176
|
+
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, opts.project);
|
|
177
|
+
const cyVersion = (0, cypress_version_1.installedCypressVersion)();
|
|
178
|
+
projectConfig.targets ??= {};
|
|
179
|
+
projectConfig.targets.e2e = {
|
|
180
|
+
executor: '@nx/cypress:cypress',
|
|
181
|
+
options: {
|
|
182
|
+
cypressConfig: (0, devkit_1.joinPathFragments)(projectConfig.root, cyVersion && cyVersion < 10
|
|
183
|
+
? 'cypress.json'
|
|
184
|
+
: `cypress.config.${opts.js ? 'js' : 'ts'}`),
|
|
185
|
+
testingType: 'e2e',
|
|
186
|
+
},
|
|
187
|
+
};
|
|
188
|
+
if (opts.devServerTarget) {
|
|
189
|
+
const parsedTarget = (0, devkit_1.parseTargetString)(opts.devServerTarget);
|
|
190
|
+
projectConfig.targets.e2e.options = {
|
|
191
|
+
...projectConfig.targets.e2e.options,
|
|
192
|
+
devServerTarget: opts.devServerTarget,
|
|
193
|
+
port: opts.port,
|
|
194
|
+
};
|
|
195
|
+
const devServerProjectConfig = (0, devkit_1.readProjectConfiguration)(tree, parsedTarget.project);
|
|
196
|
+
// Add production e2e target if serve target is found
|
|
197
|
+
if (parsedTarget.configuration !== 'production' &&
|
|
198
|
+
devServerProjectConfig.targets?.[parsedTarget.target]?.configurations?.['production']) {
|
|
199
|
+
projectConfig.targets.e2e.configurations ??= {};
|
|
200
|
+
projectConfig.targets.e2e.configurations['production'] = {
|
|
201
|
+
devServerTarget: `${parsedTarget.project}:${parsedTarget.target}:production`,
|
|
202
|
+
};
|
|
203
|
+
}
|
|
204
|
+
// Add ci/static e2e target if serve target is found
|
|
205
|
+
if (devServerProjectConfig.targets?.['serve-static']) {
|
|
206
|
+
projectConfig.targets.e2e.configurations ??= {};
|
|
207
|
+
projectConfig.targets.e2e.configurations.ci = {
|
|
208
|
+
devServerTarget: `${parsedTarget.project}:serve-static`,
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
}
|
|
212
|
+
else if (opts.baseUrl) {
|
|
213
|
+
projectConfig.targets.e2e.options = {
|
|
214
|
+
...projectConfig.targets.e2e.options,
|
|
215
|
+
baseUrl: opts.baseUrl,
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
(0, devkit_1.updateProjectConfiguration)(tree, opts.project, projectConfig);
|
|
219
|
+
}
|
|
220
|
+
exports.default = configurationGenerator;
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getGreeting } from '../support/app.po';
|
|
2
|
+
|
|
3
|
+
describe('<%= project %>', () => {
|
|
4
|
+
beforeEach(() => cy.visit('/'));
|
|
5
|
+
|
|
6
|
+
it('should display welcome message', () => {
|
|
7
|
+
// Custom command example, see `../support/commands.ts` file
|
|
8
|
+
cy.login('my-email@something.com', 'myPassword');
|
|
9
|
+
|
|
10
|
+
// Function helper example, see `../support/app.po.ts` file
|
|
11
|
+
getGreeting().contains(/Welcome/);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const getGreeting = () => cy.get('h1');
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// ***********************************************************
|
|
2
|
+
// This example support/e2e.ts is processed and
|
|
3
|
+
// loaded automatically before your test files.
|
|
4
|
+
//
|
|
5
|
+
// This is a great place to put global configuration and
|
|
6
|
+
// behavior that modifies Cypress.
|
|
7
|
+
//
|
|
8
|
+
// You can change the location of this file or turn off
|
|
9
|
+
// automatically serving support files with the
|
|
10
|
+
// 'supportFile' configuration option.
|
|
11
|
+
//
|
|
12
|
+
// You can read more here:
|
|
13
|
+
// https://on.cypress.io/configuration
|
|
14
|
+
// ***********************************************************
|
|
15
|
+
|
|
16
|
+
// Import commands.ts using ES2015 syntax:
|
|
17
|
+
import './commands';
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { getGreeting } from '../support/app.po';
|
|
2
|
+
|
|
3
|
+
describe('<%= project %>', () => {
|
|
4
|
+
beforeEach(() => cy.visit('/'));
|
|
5
|
+
|
|
6
|
+
it('should display welcome message', () => {
|
|
7
|
+
// Custom command example, see `../support/commands.ts` file
|
|
8
|
+
cy.login('my-email@something.com', 'myPassword');
|
|
9
|
+
|
|
10
|
+
// Function helper example, see `../support/app.po.ts` file
|
|
11
|
+
getGreeting().contains(/Welcome/);
|
|
12
|
+
});
|
|
13
|
+
});
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
// ***********************************************************
|
|
2
|
+
// This example plugins/index.js can be used to load plugins
|
|
3
|
+
//
|
|
4
|
+
// You can change the location of this file or turn off loading
|
|
5
|
+
// the plugins file with the 'pluginsFile' configuration option.
|
|
6
|
+
//
|
|
7
|
+
// You can read more here:
|
|
8
|
+
// https://on.cypress.io/plugins-guide
|
|
9
|
+
// ***********************************************************
|
|
10
|
+
|
|
11
|
+
// This function is called when a project is opened or re-opened (e.g. due to
|
|
12
|
+
// the project's config changing)
|
|
13
|
+
|
|
14
|
+
const { preprocessTypescript } = require('@nx/cypress/plugins/preprocessor');
|
|
15
|
+
|
|
16
|
+
module.exports = (on, config) => {
|
|
17
|
+
// `on` is used to hook into various events Cypress emits
|
|
18
|
+
// `config` is the resolved Cypress config
|
|
19
|
+
|
|
20
|
+
// Preprocess Typescript file using Nx helper
|
|
21
|
+
on('file:preprocessor', preprocessTypescript(config));
|
|
22
|
+
};
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const getGreeting = () => cy.get('h1');
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
// ***********************************************
|
|
2
|
+
// This example commands.js shows you how to
|
|
3
|
+
// create various custom commands and overwrite
|
|
4
|
+
// existing commands.
|
|
5
|
+
//
|
|
6
|
+
// For more comprehensive examples of custom
|
|
7
|
+
// commands please read more here:
|
|
8
|
+
// https://on.cypress.io/custom-commands
|
|
9
|
+
// ***********************************************
|
|
10
|
+
<% if (linter === 'eslint') { %>
|
|
11
|
+
// eslint-disable-next-line @typescript-eslint/no-namespace<% } %>
|
|
12
|
+
declare namespace Cypress {<% if (linter === 'eslint') { %>
|
|
13
|
+
// eslint-disable-next-line @typescript-eslint/no-unused-vars<% } %>
|
|
14
|
+
interface Chainable<Subject> {
|
|
15
|
+
login(email: string, password: string): void;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
18
|
+
//
|
|
19
|
+
// -- This is a parent command --
|
|
20
|
+
Cypress.Commands.add('login', (email, password) => {
|
|
21
|
+
console.log('Custom command example: Login', email, password);
|
|
22
|
+
});
|
|
23
|
+
//
|
|
24
|
+
// -- This is a child command --
|
|
25
|
+
// Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
|
|
26
|
+
//
|
|
27
|
+
//
|
|
28
|
+
// -- This is a dual command --
|
|
29
|
+
// Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
|
|
30
|
+
//
|
|
31
|
+
//
|
|
32
|
+
// -- This will overwrite an existing command --
|
|
33
|
+
// Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
// ***********************************************************
|
|
2
|
+
// This example support/index.ts is processed and
|
|
3
|
+
// loaded automatically before your test files.
|
|
4
|
+
//
|
|
5
|
+
// This is a great place to put global configuration and
|
|
6
|
+
// behavior that modifies Cypress.
|
|
7
|
+
//
|
|
8
|
+
// You can change the location of this file or turn off
|
|
9
|
+
// automatically serving support files with the
|
|
10
|
+
// 'supportFile' configuration option.
|
|
11
|
+
//
|
|
12
|
+
// You can read more here:
|
|
13
|
+
// https://on.cypress.io/configuration
|
|
14
|
+
// ***********************************************************
|
|
15
|
+
|
|
16
|
+
// Import commands.ts using ES2015 syntax:
|
|
17
|
+
import './commands';
|