@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,6 @@
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
+ import { Schema } from './schema';
3
+ export declare function addPlugin(tree: Tree): void;
4
+ export declare function cypressInitGenerator(tree: Tree, options: Schema): Promise<GeneratorCallback>;
5
+ export declare function cypressInitGeneratorInternal(tree: Tree, options: Schema): Promise<GeneratorCallback>;
6
+ export default cypressInitGenerator;
@@ -0,0 +1,97 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.cypressInitGeneratorInternal = exports.cypressInitGenerator = exports.addPlugin = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const update_package_scripts_1 = require("@nx/devkit/src/utils/update-package-scripts");
6
+ const plugin_1 = require("../../plugins/plugin");
7
+ const versions_1 = require("../../utils/versions");
8
+ function setupE2ETargetDefaults(tree) {
9
+ const nxJson = (0, devkit_1.readNxJson)(tree);
10
+ if (!nxJson.namedInputs) {
11
+ return;
12
+ }
13
+ // E2e targets depend on all their project's sources + production sources of dependencies
14
+ nxJson.targetDefaults ??= {};
15
+ const productionFileSet = !!nxJson.namedInputs?.production;
16
+ nxJson.targetDefaults.e2e ??= {};
17
+ nxJson.targetDefaults.e2e.cache ??= true;
18
+ nxJson.targetDefaults.e2e.inputs ??= [
19
+ 'default',
20
+ productionFileSet ? '^production' : '^default',
21
+ ];
22
+ (0, devkit_1.updateNxJson)(tree, nxJson);
23
+ }
24
+ function updateDependencies(tree, options) {
25
+ const tasks = [];
26
+ tasks.push((0, devkit_1.removeDependenciesFromPackageJson)(tree, ['@nx/cypress'], []));
27
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
28
+ ['@nx/cypress']: versions_1.nxVersion,
29
+ cypress: versions_1.cypressVersion,
30
+ }, undefined, options.keepExistingVersions));
31
+ return (0, devkit_1.runTasksInSerial)(...tasks);
32
+ }
33
+ function addPlugin(tree) {
34
+ const nxJson = (0, devkit_1.readNxJson)(tree);
35
+ nxJson.plugins ??= [];
36
+ for (const plugin of nxJson.plugins) {
37
+ if (typeof plugin === 'string'
38
+ ? plugin === '@nx/cypress/plugin'
39
+ : plugin.plugin === '@nx/cypress/plugin') {
40
+ return;
41
+ }
42
+ }
43
+ nxJson.plugins.push({
44
+ plugin: '@nx/cypress/plugin',
45
+ options: {
46
+ targetName: 'e2e',
47
+ componentTestingTargetName: 'component-test',
48
+ },
49
+ });
50
+ (0, devkit_1.updateNxJson)(tree, nxJson);
51
+ }
52
+ exports.addPlugin = addPlugin;
53
+ function updateProductionFileset(tree) {
54
+ const nxJson = (0, devkit_1.readNxJson)(tree);
55
+ const productionFileset = nxJson.namedInputs?.production;
56
+ if (productionFileset) {
57
+ nxJson.namedInputs.production = Array.from(new Set([
58
+ ...productionFileset,
59
+ '!{projectRoot}/cypress/**/*',
60
+ '!{projectRoot}/**/*.cy.[jt]s?(x)',
61
+ '!{projectRoot}/cypress.config.[jt]s',
62
+ ]));
63
+ }
64
+ (0, devkit_1.updateNxJson)(tree, nxJson);
65
+ }
66
+ async function cypressInitGenerator(tree, options) {
67
+ return cypressInitGeneratorInternal(tree, { addPlugin: false, ...options });
68
+ }
69
+ exports.cypressInitGenerator = cypressInitGenerator;
70
+ async function cypressInitGeneratorInternal(tree, options) {
71
+ updateProductionFileset(tree);
72
+ const nxJson = (0, devkit_1.readNxJson)(tree);
73
+ options.addPlugin ??=
74
+ process.env.NX_ADD_PLUGINS !== 'false' &&
75
+ nxJson.useInferencePlugins !== false;
76
+ if (options.addPlugin) {
77
+ addPlugin(tree);
78
+ }
79
+ else {
80
+ setupE2ETargetDefaults(tree);
81
+ }
82
+ let installTask = () => { };
83
+ if (!options.skipPackageJson) {
84
+ installTask = updateDependencies(tree, options);
85
+ }
86
+ if (options.updatePackageScripts) {
87
+ global.NX_CYPRESS_INIT_GENERATOR_RUNNING = true;
88
+ await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
89
+ global.NX_CYPRESS_INIT_GENERATOR_RUNNING = false;
90
+ }
91
+ if (!options.skipFormat) {
92
+ await (0, devkit_1.formatFiles)(tree);
93
+ }
94
+ return installTask;
95
+ }
96
+ exports.cypressInitGeneratorInternal = cypressInitGeneratorInternal;
97
+ exports.default = cypressInitGenerator;
@@ -0,0 +1,7 @@
1
+ export interface Schema {
2
+ skipFormat?: boolean;
3
+ skipPackageJson?: boolean;
4
+ keepExistingVersions?: boolean;
5
+ updatePackageScripts?: boolean;
6
+ addPlugin?: boolean;
7
+ }
@@ -0,0 +1,34 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxCypressInit",
4
+ "cli": "nx",
5
+ "title": "Add Cypress Configuration to the workspace",
6
+ "description": "Add Cypress Configuration to the workspace.",
7
+ "type": "object",
8
+ "properties": {
9
+ "skipFormat": {
10
+ "description": "Skip formatting files.",
11
+ "type": "boolean",
12
+ "default": false,
13
+ "x-priority": "internal"
14
+ },
15
+ "skipPackageJson": {
16
+ "type": "boolean",
17
+ "default": false,
18
+ "description": "Do not add dependencies to `package.json`.",
19
+ "x-priority": "internal"
20
+ },
21
+ "keepExistingVersions": {
22
+ "type": "boolean",
23
+ "x-priority": "internal",
24
+ "description": "Keep existing dependencies versions",
25
+ "default": false
26
+ },
27
+ "updatePackageScripts": {
28
+ "type": "boolean",
29
+ "x-priority": "internal",
30
+ "description": "Update `package.json` scripts with inferred targets",
31
+ "default": false
32
+ }
33
+ }
34
+ }
@@ -0,0 +1,39 @@
1
+ import { ProjectConfiguration, Tree } from '@nx/devkit';
2
+ export declare function findCypressConfigs(tree: Tree, projectConfig: ProjectConfiguration, target: string, config: string): {
3
+ cypressConfigPathJson: string;
4
+ cypressConfigPathTs: string;
5
+ };
6
+ /**
7
+ * update the existing cypress.json config to the new cypress.config.ts structure.
8
+ * return both the old and new configs
9
+ */
10
+ export declare function createNewCypressConfig(tree: Tree, projectConfig: ProjectConfiguration, cypressConfigPathJson: string): {
11
+ cypressConfigTs: Record<string, any>;
12
+ cypressConfigJson: Record<string, any>;
13
+ };
14
+ export declare function createSupportFileImport(oldSupportFilePath: string, newSupportFilePath: string, projectSourceRoot: string): {
15
+ oldImportPathLeaf: string;
16
+ newImportPathLeaf: string;
17
+ };
18
+ export declare function updateProjectPaths(tree: Tree, projectConfig: ProjectConfiguration, { cypressConfigTs, cypressConfigJson, }: {
19
+ cypressConfigTs: Record<string, any>;
20
+ cypressConfigJson: Record<string, any>;
21
+ }): void;
22
+ export declare function updateImports(tree: Tree, filePath: string, oldImportPath: string, newImportPath: string): void;
23
+ export declare function writeNewConfig(tree: Tree, cypressConfigPathTs: string, cypressConfigs: {
24
+ cypressConfigTs: Record<string, any>;
25
+ cypressConfigJson: Record<string, any>;
26
+ }): void;
27
+ export declare function addConfigToTsConfig(tree: Tree, tsconfigPath: string, cypressConfigPath: string): void;
28
+ export declare function updatePluginFile(tree: Tree, projectConfig: ProjectConfiguration, cypressConfigs: {
29
+ cypressConfigTs: Record<string, any>;
30
+ cypressConfigJson: Record<string, any>;
31
+ }): {
32
+ cypressConfigTs: Record<string, any>;
33
+ cypressConfigJson: Record<string, any>;
34
+ } | {
35
+ cypressConfigTs: {
36
+ e2e: any;
37
+ };
38
+ cypressConfigJson: Record<string, any>;
39
+ };
@@ -0,0 +1,246 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.updatePluginFile = exports.addConfigToTsConfig = exports.writeNewConfig = exports.updateImports = exports.updateProjectPaths = exports.createSupportFileImport = exports.createNewCypressConfig = exports.findCypressConfigs = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const path_1 = require("path");
6
+ const ensure_typescript_1 = require("@nx/js/src/utils/typescript/ensure-typescript");
7
+ let tsModule;
8
+ let tsquery;
9
+ const validFilesEndingsToUpdate = [
10
+ '.js',
11
+ '.jsx',
12
+ '.ts',
13
+ '.tsx',
14
+ '.mjs',
15
+ '.cjs',
16
+ ];
17
+ function findCypressConfigs(tree, projectConfig, target, config) {
18
+ const cypressConfigPathJson = projectConfig.targets[target]?.configurations?.[config]?.cypressConfig ||
19
+ projectConfig.targets[target]?.options?.cypressConfig;
20
+ // make sure it's a json file, since it could have been updated to ts file from previous configuration migration
21
+ if (!cypressConfigPathJson || (0, path_1.extname)(cypressConfigPathJson) !== '.json') {
22
+ return {
23
+ cypressConfigPathJson: null,
24
+ cypressConfigPathTs: null,
25
+ };
26
+ }
27
+ const cypressConfigPathTs = (0, devkit_1.joinPathFragments)((0, path_1.dirname)(cypressConfigPathJson),
28
+ // create matching ts config for custom cypress config if present
29
+ cypressConfigPathJson?.endsWith('cypress.json')
30
+ ? 'cypress.config.ts' //default
31
+ : `${(0, path_1.basename)(cypressConfigPathJson, (0, path_1.extname)(cypressConfigPathJson))}.config.ts`);
32
+ return {
33
+ cypressConfigPathJson,
34
+ cypressConfigPathTs,
35
+ };
36
+ }
37
+ exports.findCypressConfigs = findCypressConfigs;
38
+ /**
39
+ * update the existing cypress.json config to the new cypress.config.ts structure.
40
+ * return both the old and new configs
41
+ */
42
+ function createNewCypressConfig(tree, projectConfig, cypressConfigPathJson) {
43
+ const cypressConfigJson = (0, devkit_1.readJson)(tree, cypressConfigPathJson);
44
+ const { modifyObstructiveCode = null, // no longer needed in configs
45
+ integrationFolder = 'src/e2e', // provide the new defaults if the value isn't present
46
+ supportFile = 'src/support/e2e.ts', ...restOfConfig } = cypressConfigJson;
47
+ const newIntegrationFolder = tree.exists((0, devkit_1.joinPathFragments)(projectConfig.sourceRoot, 'integration'))
48
+ ? 'src/e2e'
49
+ : integrationFolder;
50
+ const cypressConfigTs = {
51
+ e2e: {
52
+ ...restOfConfig,
53
+ specPattern: `${newIntegrationFolder}/**/*.cy.{js,jsx,ts,tsx}`,
54
+ // if supportFile is defined (can be false if not using it) and in the default location (or in the new default location),
55
+ // then use the new default location.
56
+ // otherwise we will use the existing folder location/falsey value
57
+ supportFile: (supportFile &&
58
+ tree.exists((0, devkit_1.joinPathFragments)(projectConfig.sourceRoot, 'support', 'index.ts'))) ||
59
+ tree.exists((0, devkit_1.joinPathFragments)(projectConfig.sourceRoot, 'support', 'e2e.ts'))
60
+ ? 'src/support/e2e.ts'
61
+ : supportFile,
62
+ // if the default location is used then will update to the new location otherwise keep the custom location
63
+ // this is used down the line, but won't be in the final config file since it's a deprecated option
64
+ integrationFolder: newIntegrationFolder,
65
+ },
66
+ };
67
+ return { cypressConfigTs, cypressConfigJson };
68
+ }
69
+ exports.createNewCypressConfig = createNewCypressConfig;
70
+ function createSupportFileImport(oldSupportFilePath, newSupportFilePath, projectSourceRoot) {
71
+ // need to get the new import path for the support file.
72
+ // before it was "<relative path>/support/index.ts" and the new path will be "<relative path>/support/e2e.ts"
73
+ // i.e. take ../support => ../support/e2e.ts
74
+ // 1. take apps/app-e2e/support/index.ts => support (this cant have a / in it. must grab the leaf for tsquery)
75
+ // 2. if the leaf value is index.ts then grab the parent directory (i.e. so we have support/index.ts => support)
76
+ // 3. take apps/app-e2e/support/e2e.ts => support/e2e
77
+ // apps/app-e2e/support/e2e.ts => support/e2e
78
+ const newFileExt = (0, path_1.extname)(newSupportFilePath);
79
+ const newImportPathLeaf = (0, path_1.relative)(projectSourceRoot, newSupportFilePath).replace(newFileExt, '');
80
+ // apps/app-e2e/support/index.ts => support/index
81
+ const oldFileExt = (0, path_1.extname)(oldSupportFilePath);
82
+ const oldImportPathLeaf = (0, path_1.relative)(projectSourceRoot, oldSupportFilePath).replace(oldFileExt, '');
83
+ // support/index => support
84
+ const oldRelativeImportPath = (0, path_1.basename)(oldImportPathLeaf, oldFileExt);
85
+ return {
86
+ newImportPathLeaf,
87
+ // don't import from 'support/index' it's just 'support'
88
+ oldImportPathLeaf: oldRelativeImportPath === 'index'
89
+ ? (0, path_1.dirname)(oldImportPathLeaf)
90
+ : oldImportPathLeaf,
91
+ };
92
+ }
93
+ exports.createSupportFileImport = createSupportFileImport;
94
+ function updateProjectPaths(tree, projectConfig, { cypressConfigTs, cypressConfigJson, }) {
95
+ const { integrationFolder, supportFile } = cypressConfigTs['e2e'];
96
+ const oldIntegrationFolder = (0, devkit_1.joinPathFragments)(projectConfig.root, cypressConfigJson.integrationFolder);
97
+ const newIntegrationFolder = (0, devkit_1.joinPathFragments)(projectConfig.root, integrationFolder);
98
+ let newSupportFile;
99
+ let oldSupportFile;
100
+ let oldImportLeafPath;
101
+ let newImportLeafPath;
102
+ let shouldUpdateSupportFileImports = false;
103
+ // supportFile can be falsey or a string path to the file
104
+ if (cypressConfigJson.supportFile) {
105
+ // we need to check the test files to see if
106
+ // support file import is used and then update it if so
107
+ shouldUpdateSupportFileImports = true;
108
+ oldSupportFile = (0, devkit_1.joinPathFragments)(projectConfig.root, cypressConfigJson.supportFile);
109
+ newSupportFile = (0, devkit_1.joinPathFragments)(projectConfig.root, supportFile);
110
+ // oldSupportFile might have already been updated
111
+ // to the new default location so must be guarded for
112
+ if (oldSupportFile !== newSupportFile && tree.exists(oldSupportFile)) {
113
+ tree.rename(oldSupportFile, newSupportFile);
114
+ }
115
+ }
116
+ else {
117
+ shouldUpdateSupportFileImports = false;
118
+ newSupportFile = supportFile;
119
+ // rename the default support file even if not in use to keep the system in sync with cypress v10
120
+ const defaultSupportFile = (0, devkit_1.joinPathFragments)(projectConfig.sourceRoot, 'support', 'index.ts');
121
+ if (tree.exists(defaultSupportFile)) {
122
+ const newSupportDefaultPath = (0, devkit_1.joinPathFragments)(projectConfig.sourceRoot, 'support', 'e2e.ts');
123
+ if (defaultSupportFile !== newSupportDefaultPath &&
124
+ tree.exists(defaultSupportFile)) {
125
+ tree.rename(defaultSupportFile, newSupportDefaultPath);
126
+ }
127
+ }
128
+ }
129
+ if (shouldUpdateSupportFileImports) {
130
+ const newImportPaths = createSupportFileImport(oldSupportFile, newSupportFile, projectConfig.sourceRoot);
131
+ oldImportLeafPath = newImportPaths.oldImportPathLeaf;
132
+ newImportLeafPath = newImportPaths.newImportPathLeaf;
133
+ }
134
+ // tree.rename doesn't work on directories must update each file within
135
+ // the directory to the new directory
136
+ (0, devkit_1.visitNotIgnoredFiles)(tree, projectConfig.sourceRoot, (path) => {
137
+ const normalizedPath = (0, devkit_1.normalizePath)(path);
138
+ if (!normalizedPath.includes(oldIntegrationFolder)) {
139
+ return;
140
+ }
141
+ const fileName = (0, path_1.basename)(normalizedPath);
142
+ let newPath = normalizedPath.replace(oldIntegrationFolder, newIntegrationFolder);
143
+ if (fileName.includes('.spec.')) {
144
+ newPath = newPath.replace('.spec.', '.cy.');
145
+ }
146
+ if (newPath !== normalizedPath && tree.exists(normalizedPath)) {
147
+ tree.rename(normalizedPath, newPath);
148
+ }
149
+ // if they weren't using the supportFile then there is no need to update the imports.
150
+ if (shouldUpdateSupportFileImports &&
151
+ validFilesEndingsToUpdate.some((e) => path.endsWith(e))) {
152
+ updateImports(tree, newPath, oldImportLeafPath, newImportLeafPath);
153
+ }
154
+ });
155
+ if (tree.children(oldIntegrationFolder).length === 0) {
156
+ tree.delete(oldIntegrationFolder);
157
+ }
158
+ }
159
+ exports.updateProjectPaths = updateProjectPaths;
160
+ function updateImports(tree, filePath, oldImportPath, newImportPath) {
161
+ if (!tsModule) {
162
+ tsModule = (0, ensure_typescript_1.ensureTypescript)();
163
+ }
164
+ if (!tsquery) {
165
+ (0, ensure_typescript_1.ensureTypescript)();
166
+ tsquery = require('@phenomnomnominal/tsquery').tsquery;
167
+ }
168
+ const { isCallExpression, isExportDeclaration, isImportDeclaration } = tsModule;
169
+ const endOfImportSelector = `StringLiteral[value=/${oldImportPath}$/]`;
170
+ const fileContent = tree.read(filePath, 'utf-8');
171
+ const newContent = tsquery.replace(fileContent, endOfImportSelector, (node) => {
172
+ // if node.parent is an CallExpression require() ||ImportDeclaration
173
+ if (node?.parent &&
174
+ (isCallExpression(node.parent) ||
175
+ isImportDeclaration(node.parent) ||
176
+ isExportDeclaration(node.parent))) {
177
+ return `'${node.text.replace(oldImportPath, newImportPath)}'`;
178
+ }
179
+ return node.text;
180
+ });
181
+ tree.write(filePath, newContent);
182
+ }
183
+ exports.updateImports = updateImports;
184
+ function writeNewConfig(tree, cypressConfigPathTs, cypressConfigs) {
185
+ // remove deprecated configs options
186
+ const { pluginsFile = false, integrationFolder = '', ...restOfConfig } = cypressConfigs.cypressConfigTs.e2e;
187
+ const pluginImport = pluginsFile
188
+ ? `import setupNodeEvents from '${pluginsFile}';`
189
+ : '';
190
+ const convertedConfig = JSON.stringify(restOfConfig, null, 2);
191
+ tree.write(cypressConfigPathTs, (0, devkit_1.stripIndents) `
192
+ import { defineConfig } from 'cypress'
193
+ import { nxE2EPreset } from '@nx/cypress/plugins/cypress-preset';
194
+ ${pluginImport}
195
+
196
+ const cypressJsonConfig = ${convertedConfig}
197
+ export default defineConfig({
198
+ e2e: {
199
+ ...nxE2EPreset(__dirname),
200
+ ...cypressJsonConfig,
201
+ ${pluginsFile ? 'setupNodeEvents' : ''}
202
+ }
203
+ })
204
+ `);
205
+ }
206
+ exports.writeNewConfig = writeNewConfig;
207
+ function addConfigToTsConfig(tree, tsconfigPath, cypressConfigPath) {
208
+ if (tree.exists(tsconfigPath)) {
209
+ (0, devkit_1.updateJson)(tree, tsconfigPath, (json) => {
210
+ json.include = Array.from(new Set([
211
+ ...(json.include || []),
212
+ (0, path_1.relative)((0, path_1.dirname)(tsconfigPath), cypressConfigPath),
213
+ ]));
214
+ return json;
215
+ }, { expectComments: true });
216
+ }
217
+ }
218
+ exports.addConfigToTsConfig = addConfigToTsConfig;
219
+ function updatePluginFile(tree, projectConfig, cypressConfigs) {
220
+ // if ts file change module.exports = to export default
221
+ // if js file don't do anything
222
+ // update cypressConfigTs.e2e to remove file extension
223
+ const pluginsFile = cypressConfigs.cypressConfigTs?.e2e?.pluginsFile;
224
+ if (!pluginsFile) {
225
+ return cypressConfigs;
226
+ }
227
+ const ext = (0, path_1.extname)(pluginsFile);
228
+ const updatedCypressConfigs = {
229
+ ...cypressConfigs,
230
+ cypressConfigTs: {
231
+ e2e: {
232
+ ...cypressConfigs.cypressConfigTs.e2e,
233
+ pluginsFile: pluginsFile.replace(ext, ''),
234
+ },
235
+ },
236
+ };
237
+ const pluginFilePath = (0, devkit_1.joinPathFragments)(projectConfig.root, pluginsFile);
238
+ if (ext === '.ts' && tree.exists(pluginFilePath)) {
239
+ const pluginFileContent = tree.read(pluginFilePath, 'utf-8');
240
+ tree.write(pluginFilePath, pluginFileContent
241
+ .replace('module.exports =', 'export default')
242
+ .replace(/module\.exports\.(.*?)=/g, 'export const $1='));
243
+ }
244
+ return updatedCypressConfigs;
245
+ }
246
+ exports.updatePluginFile = updatePluginFile;
@@ -0,0 +1,3 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export declare function migrateCypressProject(tree: Tree): Promise<() => void>;
3
+ export default migrateCypressProject;
@@ -0,0 +1,93 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.migrateCypressProject = void 0;
4
+ const cypress_version_1 = require("../../utils/cypress-version");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
7
+ const conversion_util_1 = require("./conversion.util");
8
+ function migrateCypressExecutorOptions(tree, projectName, target, configuration, previousCypressConfigs) {
9
+ try {
10
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, projectName);
11
+ const { cypressConfigPathJson, cypressConfigPathTs } = (0, conversion_util_1.findCypressConfigs)(tree, projectConfig, target, configuration);
12
+ if (!cypressConfigPathJson && !cypressConfigPathTs) {
13
+ return;
14
+ }
15
+ // a matching cypress ts file hasn't been made yet. need to migrate.
16
+ if (tree.exists(cypressConfigPathJson) &&
17
+ !tree.exists(cypressConfigPathTs)) {
18
+ let cypressConfigs = (0, conversion_util_1.createNewCypressConfig)(tree, projectConfig, cypressConfigPathJson);
19
+ cypressConfigs = (0, conversion_util_1.updatePluginFile)(tree, projectConfig, cypressConfigs);
20
+ (0, conversion_util_1.writeNewConfig)(tree, cypressConfigPathTs, cypressConfigs);
21
+ previousCypressConfigs.set(cypressConfigPathJson, cypressConfigs);
22
+ tree.delete(cypressConfigPathJson);
23
+ }
24
+ // ts file has been made and matching json file has been removed only need to update the project config
25
+ if (!tree.exists(cypressConfigPathJson) &&
26
+ tree.exists(cypressConfigPathTs)) {
27
+ const cypressConfigs = previousCypressConfigs.get(cypressConfigPathJson);
28
+ (0, conversion_util_1.updateProjectPaths)(tree, projectConfig, cypressConfigs);
29
+ (0, conversion_util_1.addConfigToTsConfig)(tree, (configuration
30
+ ? projectConfig.targets?.[target]?.configurations?.[configuration]
31
+ ?.tsConfig
32
+ : projectConfig.targets?.[target]?.options?.tsConfig) ||
33
+ (0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json'), cypressConfigPathTs);
34
+ if (configuration) {
35
+ projectConfig.targets[target].configurations[configuration] = {
36
+ ...projectConfig.targets[target].configurations[configuration],
37
+ cypressConfig: cypressConfigPathTs,
38
+ };
39
+ }
40
+ else {
41
+ projectConfig.targets[target].options = {
42
+ ...projectConfig.targets[target].options,
43
+ cypressConfig: cypressConfigPathTs,
44
+ };
45
+ }
46
+ projectConfig.targets[target].options.testingType = 'e2e';
47
+ (0, devkit_1.updateProjectConfiguration)(tree, projectName, projectConfig);
48
+ }
49
+ }
50
+ catch (e) {
51
+ devkit_1.logger.error((0, devkit_1.stripIndents) `
52
+ NX There was an error converting ${projectName}:${target}.
53
+ You can manually update the project by following the migration guide if need be.
54
+ https://nx.dev/cypress/v10-migration-guide
55
+ `);
56
+ throw e;
57
+ }
58
+ }
59
+ async function migrateCypressProject(tree) {
60
+ (0, cypress_version_1.assertMinimumCypressVersion)(8);
61
+ if ((0, cypress_version_1.installedCypressVersion)() >= 10) {
62
+ devkit_1.logger.info('NX This workspace is already using Cypress v10+');
63
+ return;
64
+ }
65
+ // keep history of cypress configs as some workspaces share configs
66
+ // if we don't have the already migrated configs
67
+ // it prevents us from being able to rename files for those projects
68
+ const previousCypressConfigs = new Map();
69
+ (0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nx/cypress:cypress', (currentValue, projectName, target, configuration) => {
70
+ migrateCypressExecutorOptions(tree, projectName, target, configuration, previousCypressConfigs);
71
+ });
72
+ (0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nrwl/cypress:cypress', (currentValue, projectName, target, configuration) => {
73
+ migrateCypressExecutorOptions(tree, projectName, target, configuration, previousCypressConfigs);
74
+ });
75
+ (0, devkit_1.updateJson)(tree, 'package.json', (json) => {
76
+ json.devDependencies['cypress'] = '^11.2.0';
77
+ return json;
78
+ });
79
+ await (0, devkit_1.formatFiles)(tree);
80
+ if (tree.exists('cypress.json')) {
81
+ devkit_1.logger.warn((0, devkit_1.stripIndents) `A root cypress.json file was found.
82
+ You should remove this file as it will cause an error when running Cypress.
83
+ If you want to share options between Cypress projects.
84
+ You can create a root ts file and import it into each project's cypress config file.
85
+ More Info: https://github.com/nrwl/nx/issues/11512#issuecomment-1213420638
86
+ `);
87
+ }
88
+ return () => {
89
+ (0, devkit_1.installPackagesTask)(tree);
90
+ };
91
+ }
92
+ exports.migrateCypressProject = migrateCypressProject;
93
+ exports.default = migrateCypressProject;
@@ -0,0 +1,15 @@
1
+ {
2
+ "$schema": "https://json-schema.org/schema",
3
+ "$id": "NxCypressMigrateTo11",
4
+ "cli": "nx",
5
+ "title": "Migrate e2e project to Cypress 11",
6
+ "description": "Migrate Cypress e2e project from v8/v9 to Cypress v11.",
7
+ "type": "object",
8
+ "examples": [
9
+ {
10
+ "command": "nx g @nx/cypress:migrate-to-cypress-11",
11
+ "description": "Migrate existing cypress projects to Cypress v11"
12
+ }
13
+ ],
14
+ "properties": {}
15
+ }
@@ -0,0 +1,2 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export default function (tree: Tree): Promise<void>;
@@ -0,0 +1,42 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const executor_options_utils_1 = require("@nx/devkit/src/generators/executor-options-utils");
5
+ async function default_1(tree) {
6
+ const nxJson = (0, devkit_1.readNxJson)(tree);
7
+ const { cypressTargets, hasComponentTesting } = getCypressTargetNames(tree);
8
+ const hasProductionFileset = !!nxJson.namedInputs?.production;
9
+ if (hasComponentTesting && hasProductionFileset && cypressTargets.size > 0) {
10
+ const productionFileset = new Set(nxJson.namedInputs.production);
11
+ for (const exclusion of [
12
+ '!{projectRoot}/cypress/**/*',
13
+ '!{projectRoot}/**/*.cy.[jt]s?(x)',
14
+ '!{projectRoot}/cypress.config.[jt]s',
15
+ ]) {
16
+ productionFileset.add(exclusion);
17
+ }
18
+ nxJson.namedInputs.production = Array.from(productionFileset);
19
+ }
20
+ for (const targetName of cypressTargets) {
21
+ nxJson.targetDefaults ??= {};
22
+ const cypressTargetDefaults = (nxJson.targetDefaults[targetName] ??= {});
23
+ cypressTargetDefaults.inputs ??= [
24
+ 'default',
25
+ hasProductionFileset ? '^production' : '^default',
26
+ ];
27
+ }
28
+ (0, devkit_1.updateNxJson)(tree, nxJson);
29
+ await (0, devkit_1.formatFiles)(tree);
30
+ }
31
+ exports.default = default_1;
32
+ function getCypressTargetNames(tree) {
33
+ const cypressTargets = new Set();
34
+ let hasComponentTesting = false;
35
+ (0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nrwl/cypress:cypress', (options, __, target) => {
36
+ cypressTargets.add(target);
37
+ if (options.testingType === 'component') {
38
+ hasComponentTesting = true;
39
+ }
40
+ });
41
+ return { cypressTargets, hasComponentTesting };
42
+ }
@@ -0,0 +1,5 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export declare function updateCyMountUsage(tree: Tree): Promise<void>;
3
+ export declare function addMountCommand(tree: Tree, projectRoot: string, framework: string): void;
4
+ export declare function updateCyFile(tree: Tree, filePath: string, framework: 'angular' | 'react' | 'react18'): void;
5
+ export default updateCyMountUsage;