@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.
Files changed (116) hide show
  1. package/LICENSE +22 -0
  2. package/README.md +68 -0
  3. package/executors.json +9 -0
  4. package/generators.json +37 -0
  5. package/index.d.ts +11 -0
  6. package/index.js +20 -0
  7. package/migrations.json +111 -0
  8. package/package.json +58 -0
  9. package/plugin.d.ts +1 -0
  10. package/plugin.js +6 -0
  11. package/plugins/cypress-preset.d.ts +69 -0
  12. package/plugins/cypress-preset.js +154 -0
  13. package/src/executors/cypress/cypress.impl.d.ts +40 -0
  14. package/src/executors/cypress/cypress.impl.js +182 -0
  15. package/src/executors/cypress/schema.json +186 -0
  16. package/src/generators/base-setup/base-setup.d.ts +12 -0
  17. package/src/generators/base-setup/base-setup.js +80 -0
  18. package/src/generators/base-setup/files/common/__directory__/fixtures/example.json +5 -0
  19. package/src/generators/base-setup/files/common/__directory__/support/commands.ts__ext__ +35 -0
  20. package/src/generators/base-setup/files/common/__directory__/tsconfig.json__ext__ +20 -0
  21. package/src/generators/base-setup/files/config-js-cjs/__directory__/support/commands.js__ext__ +35 -0
  22. package/src/generators/base-setup/files/config-js-cjs/cypress.config.js__ext__ +3 -0
  23. package/src/generators/base-setup/files/config-js-esm/__directory__/support/commands.js__ext__ +35 -0
  24. package/src/generators/base-setup/files/config-js-esm/cypress.config.js__ext__ +3 -0
  25. package/src/generators/base-setup/files/config-ts/__directory__/support/commands.ts__ext__ +35 -0
  26. package/src/generators/base-setup/files/config-ts/cypress.config.ts__ext__ +3 -0
  27. package/src/generators/component-configuration/component-configuration.d.ts +6 -0
  28. package/src/generators/component-configuration/component-configuration.js +165 -0
  29. package/src/generators/component-configuration/files/__directory__/support/component-index.html +16 -0
  30. package/src/generators/component-configuration/files/__directory__/support/component.ts__ext__ +27 -0
  31. package/src/generators/component-configuration/schema.d.ts +14 -0
  32. package/src/generators/component-configuration/schema.json +43 -0
  33. package/src/generators/configuration/configuration.d.ts +23 -0
  34. package/src/generators/configuration/configuration.js +220 -0
  35. package/src/generators/configuration/files/v10/__directory__/e2e/app.cy.ts__tmpl__ +13 -0
  36. package/src/generators/configuration/files/v10/__directory__/support/app.po.ts__tmpl__ +1 -0
  37. package/src/generators/configuration/files/v10/__directory__/support/e2e.ts__tmpl__ +17 -0
  38. package/src/generators/configuration/files/v9/__directory__/fixtures/example.json__tmpl__ +4 -0
  39. package/src/generators/configuration/files/v9/__directory__/integration/app.spec.ts__tmpl__ +13 -0
  40. package/src/generators/configuration/files/v9/__directory__/plugins/index.js +22 -0
  41. package/src/generators/configuration/files/v9/__directory__/support/app.po.ts__tmpl__ +1 -0
  42. package/src/generators/configuration/files/v9/__directory__/support/commands.ts__tmpl__ +33 -0
  43. package/src/generators/configuration/files/v9/__directory__/support/index.ts__tmpl__ +17 -0
  44. package/src/generators/configuration/files/v9/__directory__/tsconfig.json +10 -0
  45. package/src/generators/configuration/files/v9/cypress.json +12 -0
  46. package/src/generators/configuration/schema.json +96 -0
  47. package/src/generators/cypress-project/cypress-project.d.ts +16 -0
  48. package/src/generators/cypress-project/cypress-project.js +213 -0
  49. package/src/generators/cypress-project/files/v10-and-after/cypress.config.ts__tmpl__ +10 -0
  50. package/src/generators/cypress-project/files/v10-and-after/src/e2e/app.cy.ts__tmpl__ +13 -0
  51. package/src/generators/cypress-project/files/v10-and-after/src/fixtures/example.json__tmpl__ +4 -0
  52. package/src/generators/cypress-project/files/v10-and-after/src/support/app.po.ts__tmpl__ +1 -0
  53. package/src/generators/cypress-project/files/v10-and-after/src/support/commands.ts__tmpl__ +33 -0
  54. package/src/generators/cypress-project/files/v10-and-after/src/support/e2e.ts__tmpl__ +17 -0
  55. package/src/generators/cypress-project/files/v10-and-after/tsconfig.json +10 -0
  56. package/src/generators/cypress-project/files/v9-and-under/cypress.json +12 -0
  57. package/src/generators/cypress-project/files/v9-and-under/src/fixtures/example.json__tmpl__ +4 -0
  58. package/src/generators/cypress-project/files/v9-and-under/src/integration/app.spec.ts__tmpl__ +13 -0
  59. package/src/generators/cypress-project/files/v9-and-under/src/plugins/index.js +22 -0
  60. package/src/generators/cypress-project/files/v9-and-under/src/support/app.po.ts__tmpl__ +1 -0
  61. package/src/generators/cypress-project/files/v9-and-under/src/support/commands.ts__tmpl__ +33 -0
  62. package/src/generators/cypress-project/files/v9-and-under/src/support/index.ts__tmpl__ +17 -0
  63. package/src/generators/cypress-project/files/v9-and-under/tsconfig.json +10 -0
  64. package/src/generators/cypress-project/schema.d.ts +17 -0
  65. package/src/generators/cypress-project/schema.json +78 -0
  66. package/src/generators/init/init.d.ts +6 -0
  67. package/src/generators/init/init.js +97 -0
  68. package/src/generators/init/schema.d.ts +7 -0
  69. package/src/generators/init/schema.json +34 -0
  70. package/src/generators/migrate-to-cypress-11/conversion.util.d.ts +39 -0
  71. package/src/generators/migrate-to-cypress-11/conversion.util.js +246 -0
  72. package/src/generators/migrate-to-cypress-11/migrate-to-cypress-11.d.ts +3 -0
  73. package/src/generators/migrate-to-cypress-11/migrate-to-cypress-11.js +93 -0
  74. package/src/generators/migrate-to-cypress-11/schema.json +15 -0
  75. package/src/migrations/update-15-0-0/add-cypress-inputs.d.ts +2 -0
  76. package/src/migrations/update-15-0-0/add-cypress-inputs.js +42 -0
  77. package/src/migrations/update-15-0-0/update-cy-mount-usage.d.ts +5 -0
  78. package/src/migrations/update-15-0-0/update-cy-mount-usage.js +119 -0
  79. package/src/migrations/update-15-1-0/cypress-11.d.ts +6 -0
  80. package/src/migrations/update-15-1-0/cypress-11.js +114 -0
  81. package/src/migrations/update-15-5-0/helpers.d.ts +3 -0
  82. package/src/migrations/update-15-5-0/helpers.js +39 -0
  83. package/src/migrations/update-15-5-0/update-to-cypress-12.d.ts +24 -0
  84. package/src/migrations/update-15-5-0/update-to-cypress-12.js +180 -0
  85. package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.d.ts +2 -0
  86. package/src/migrations/update-16-0-0-add-nx-packages/update-16-0-0-add-nx-packages.js +9 -0
  87. package/src/migrations/update-16-2-0/update-cy-tsconfig.d.ts +3 -0
  88. package/src/migrations/update-16-2-0/update-cy-tsconfig.js +77 -0
  89. package/src/migrations/update-16-4-0/tsconfig-sourcemaps.d.ts +3 -0
  90. package/src/migrations/update-16-4-0/tsconfig-sourcemaps.js +62 -0
  91. package/src/migrations/update-16-8-0/cypress-13.d.ts +7 -0
  92. package/src/migrations/update-16-8-0/cypress-13.js +179 -0
  93. package/src/migrations/update-18-1-0/update-cypress-version-13-6-6.d.ts +2 -0
  94. package/src/migrations/update-18-1-0/update-cypress-version-13-6-6.js +12 -0
  95. package/src/plugins/plugin.d.ts +8 -0
  96. package/src/plugins/plugin.js +195 -0
  97. package/src/plugins/preprocessor-vite.d.ts +32 -0
  98. package/src/plugins/preprocessor-vite.js +97 -0
  99. package/src/utils/add-linter.d.ts +22 -0
  100. package/src/utils/add-linter.js +93 -0
  101. package/src/utils/config.d.ts +17 -0
  102. package/src/utils/config.js +115 -0
  103. package/src/utils/constants.d.ts +4 -0
  104. package/src/utils/constants.js +7 -0
  105. package/src/utils/ct-helpers.d.ts +16 -0
  106. package/src/utils/ct-helpers.js +86 -0
  107. package/src/utils/cypress-version.d.ts +5 -0
  108. package/src/utils/cypress-version.js +33 -0
  109. package/src/utils/find-target-options.d.ts +17 -0
  110. package/src/utils/find-target-options.js +136 -0
  111. package/src/utils/project-name.d.ts +3 -0
  112. package/src/utils/project-name.js +19 -0
  113. package/src/utils/start-dev-server.d.ts +9 -0
  114. package/src/utils/start-dev-server.js +157 -0
  115. package/src/utils/versions.d.ts +9 -0
  116. 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;
@@ -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>
@@ -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,4 @@
1
+ {
2
+ "name": "Using fixtures to represent data",
3
+ "email": "hello@cypress.io"
4
+ }
@@ -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';
@@ -0,0 +1,10 @@
1
+ {
2
+ "extends": "<%= tsConfigPath %>",
3
+ "compilerOptions": {
4
+ "sourceMap": false,
5
+ "outDir": "<%= offsetFromRoot %>dist/out-tsc",
6
+ "allowJs": true,
7
+ "types": ["cypress", "node"]
8
+ },
9
+ "include": ["src/**/*.ts", "src/**/*.js"]
10
+ }