@nx/cypress 23.0.0-beta.15 → 23.0.0-beta.16

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/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/cypress",
3
- "version": "23.0.0-beta.15",
3
+ "version": "23.0.0-beta.16",
4
4
  "private": false,
5
5
  "description": "The Nx Plugin for Cypress contains executors and generators allowing your workspace to use the powerful Cypress integration testing capabilities.",
6
6
  "repository": {
@@ -24,6 +24,45 @@
24
24
  "main": "./index.js",
25
25
  "type": "commonjs",
26
26
  "types": "./index.d.ts",
27
+ "exports": {
28
+ ".": {
29
+ "types": "./index.d.ts",
30
+ "default": "./index.js"
31
+ },
32
+ "./package.json": "./package.json",
33
+ "./package": "./package.json",
34
+ "./generators.json": "./generators.json",
35
+ "./executors.json": "./executors.json",
36
+ "./migrations.json": "./migrations.json",
37
+ "./generators": "./generators.json",
38
+ "./executors": "./executors.json",
39
+ "./migrations": "./migrations.json",
40
+ "./plugin": {
41
+ "types": "./plugin.d.ts",
42
+ "default": "./plugin.js"
43
+ },
44
+ "./plugin.js": {
45
+ "types": "./plugin.d.ts",
46
+ "default": "./plugin.js"
47
+ },
48
+ "./plugins/*": {
49
+ "types": "./plugins/*.d.ts",
50
+ "default": "./plugins/*.js"
51
+ },
52
+ "./plugins/*.js": {
53
+ "types": "./plugins/*.d.ts",
54
+ "default": "./plugins/*.js"
55
+ },
56
+ "./src/*/schema.json": "./src/*/schema.json",
57
+ "./src/*": {
58
+ "types": "./src/*.d.ts",
59
+ "default": "./src/*.js"
60
+ },
61
+ "./src/*.js": {
62
+ "types": "./src/*.d.ts",
63
+ "default": "./src/*.js"
64
+ }
65
+ },
27
66
  "author": "Victor Savkin",
28
67
  "license": "MIT",
29
68
  "bugs": {
@@ -37,9 +76,9 @@
37
76
  "migrations": "./migrations.json"
38
77
  },
39
78
  "dependencies": {
40
- "@nx/devkit": "23.0.0-beta.15",
41
- "@nx/eslint": "23.0.0-beta.15",
42
- "@nx/js": "23.0.0-beta.15",
79
+ "@nx/devkit": "23.0.0-beta.16",
80
+ "@nx/eslint": "23.0.0-beta.16",
81
+ "@nx/js": "23.0.0-beta.16",
43
82
  "@phenomnomnominal/tsquery": "~6.2.0",
44
83
  "detect-port": "^2.1.0",
45
84
  "semver": "^7.6.3",
@@ -47,7 +86,7 @@
47
86
  "tslib": "^2.3.0"
48
87
  },
49
88
  "devDependencies": {
50
- "nx": "23.0.0-beta.15"
89
+ "nx": "23.0.0-beta.16"
51
90
  },
52
91
  "peerDependencies": {
53
92
  "cypress": ">= 13 < 16"
@@ -1 +1 @@
1
- {"version":3,"file":"cypress-preset.d.ts","sourceRoot":"","sources":["../../../../packages/cypress/plugins/cypress-preset.ts"],"names":[],"mappings":"AAUA,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAYxC,UAAU,iBAAiB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CAC5B;AAID,MAAM,WAAW,+BACf,SAAQ,IAAI,CAAC,yBAAyB,EAAE,SAAS,CAAC;CAAG;AAEvD,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;IAAE,WAAW,EAAE,WAAW,GAAG,KAAK,CAAA;CAAE,GAC7C,iBAAiB,CAwBnB;AA6CD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,yBAAyB,OAkEpC;AA0DD,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;QAII;IACJ,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3C;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,mBAAmB,CAAC,EAAE,YAAY,CAAC;CACpC,CAAC"}
1
+ {"version":3,"file":"cypress-preset.d.ts","sourceRoot":"","sources":["../../../../packages/cypress/plugins/cypress-preset.ts"],"names":[],"mappings":"AAWA,KAAK,YAAY,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAC;AAYxC,UAAU,iBAAiB;IACzB,YAAY,EAAE,MAAM,CAAC;IACrB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,iBAAiB,EAAE,OAAO,CAAC;CAC5B;AAED,MAAM,WAAW,yBAAyB;IACxC;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,OAAO,CAAC,EAAE,MAAM,GAAG,SAAS,CAAC;IAC7B,QAAQ,CAAC,EAAE,KAAK,GAAG,OAAO,CAAC;CAC5B;AAID,MAAM,WAAW,+BACf,SAAQ,IAAI,CAAC,yBAAyB,EAAE,SAAS,CAAC;CAAG;AAEvD,wBAAgB,mBAAmB,CACjC,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE;IAAE,WAAW,EAAE,WAAW,GAAG,KAAK,CAAA;CAAE,GAC7C,iBAAiB,CAiCnB;AA6CD;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,WAAW,CACzB,YAAY,EAAE,MAAM,EACpB,OAAO,CAAC,EAAE,yBAAyB,OAkEpC;AA0DD,MAAM,WAAW,eAAe;IAC9B;;OAEG;IACH,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;OAGG;IACH,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,MAAM,MAAM,yBAAyB,GAAG;IACtC,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB;;;;QAII;IACJ,UAAU,CAAC,EAAE,MAAM,CAAC;IAEpB;;;OAGG;IACH,iBAAiB,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;IAE3C;;OAEG;IACH,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAE5B;;OAEG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;IAEnB;;OAEG;IACH,eAAe,CAAC,EAAE,eAAe,CAAC;IAElC;;OAEG;IACH,mBAAmB,CAAC,EAAE,YAAY,CAAC;CACpC,CAAC"}
@@ -10,6 +10,7 @@ const fs_1 = require("fs");
10
10
  const http_1 = require("http");
11
11
  const https_1 = require("https");
12
12
  const path_1 = require("path");
13
+ const url_1 = require("url");
13
14
  const preprocessor_vite_1 = tslib_1.__importDefault(require("../src/plugins/preprocessor-vite"));
14
15
  const constants_1 = require("../src/utils/constants");
15
16
  const treeKill = require('tree-kill');
@@ -17,11 +18,20 @@ function nxBaseCypressPreset(pathToConfig, options) {
17
18
  // used to set babel settings for react CT.
18
19
  process.env.NX_CYPRESS_COMPONENT_TEST =
19
20
  options?.testingType === 'component' ? 'true' : 'false';
21
+ // ESM-shape configs pass `import.meta.url` (a `file://...` URL string) so
22
+ // the same expression works under both Node's native TS strip (ESM,
23
+ // import.meta.url defined) and Cypress's bundled tsx CJS loader, which
24
+ // exposes `import.meta.url` but not `import.meta.dirname`. CJS-shape
25
+ // configs still pass `__filename` directly. Normalize either form to a
26
+ // filesystem path before stat-checking.
27
+ const resolvedPath = pathToConfig?.startsWith('file://')
28
+ ? (0, url_1.fileURLToPath)(pathToConfig)
29
+ : pathToConfig;
20
30
  // prevent from placing path outside the root of the workspace
21
31
  // if they pass in a file or directory
22
- const normalizedPath = (0, fs_1.lstatSync)(pathToConfig).isDirectory()
23
- ? pathToConfig
24
- : (0, path_1.dirname)(pathToConfig);
32
+ const normalizedPath = (0, fs_1.lstatSync)(resolvedPath).isDirectory()
33
+ ? resolvedPath
34
+ : (0, path_1.dirname)(resolvedPath);
25
35
  const projectPath = (0, path_1.relative)(devkit_1.workspaceRoot, normalizedPath);
26
36
  const offset = (0, path_1.relative)(normalizedPath, devkit_1.workspaceRoot);
27
37
  const isTsSolutionSetup = (0, internal_1.isUsingTsSolutionSetup)();
@@ -1 +1 @@
1
- {"version":3,"file":"base-setup.d.ts","sourceRoot":"","sources":["../../../../../../packages/cypress/src/generators/base-setup/base-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,IAAI,EAOL,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB;;;SAGK;IACL,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,sBAAsB,QAuGhC"}
1
+ {"version":3,"file":"base-setup.d.ts","sourceRoot":"","sources":["../../../../../../packages/cypress/src/generators/base-setup/base-setup.ts"],"names":[],"mappings":"AAAA,OAAO,EAEL,IAAI,EAOL,MAAM,YAAY,CAAC;AAKpB,MAAM,WAAW,sBAAsB;IACrC,OAAO,EAAE,MAAM,CAAC;IAChB;;;SAGK;IACL,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,EAAE,CAAC,EAAE,OAAO,CAAC;IACb,GAAG,CAAC,EAAE,OAAO,CAAC;CACf;AAED,wBAAgB,mBAAmB,CACjC,IAAI,EAAE,IAAI,EACV,OAAO,EAAE,sBAAsB,QA+FhC"}
@@ -35,16 +35,12 @@ function addBaseCypressSetup(tree, options) {
35
35
  (0, devkit_1.generateFiles)(tree, isUsingTsSolutionConfig
36
36
  ? (0, path_1.join)(__dirname, 'files/tsconfig/ts-solution')
37
37
  : (0, path_1.join)(__dirname, 'files/tsconfig/non-ts-solution'), projectConfig.root, templateVars);
38
+ const isEsm = (0, internal_1.isEsmProject)(tree, projectConfig.root);
38
39
  if (options.js) {
39
- if (isEsmProject(tree, projectConfig.root)) {
40
- (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/config-js-esm'), projectConfig.root, templateVars);
41
- }
42
- else {
43
- (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/config-js-cjs'), projectConfig.root, templateVars);
44
- }
40
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, isEsm ? 'files/config-js-esm' : 'files/config-js-cjs'), projectConfig.root, templateVars);
45
41
  }
46
42
  else {
47
- (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, 'files/config-ts'), projectConfig.root, templateVars);
43
+ (0, devkit_1.generateFiles)(tree, (0, path_1.join)(__dirname, isEsm ? 'files/config-ts-esm' : 'files/config-ts-cjs'), projectConfig.root, templateVars);
48
44
  }
49
45
  if (opts.hasTsConfig) {
50
46
  (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json'), (json) => {
@@ -80,16 +76,6 @@ function normalizeOptions(tree, projectConfig, options) {
80
76
  hasTsConfig,
81
77
  };
82
78
  }
83
- function isEsmProject(tree, projectRoot) {
84
- let packageJson;
85
- if (tree.exists((0, devkit_1.joinPathFragments)(projectRoot, 'package.json'))) {
86
- packageJson = (0, devkit_1.readJson)(tree, (0, devkit_1.joinPathFragments)(projectRoot, 'package.json'));
87
- }
88
- else {
89
- packageJson = (0, devkit_1.readJson)(tree, 'package.json');
90
- }
91
- return packageJson.type === 'module';
92
- }
93
79
  function isEslintInstalled(tree) {
94
80
  const { dependencies, devDependencies } = (0, devkit_1.readJson)(tree, 'package.json');
95
81
  return !!(dependencies?.eslint || devDependencies?.eslint);
@@ -0,0 +1,3 @@
1
+ const { defineConfig } = require('cypress');
2
+
3
+ module.exports = defineConfig({});
@@ -0,0 +1,35 @@
1
+ /// <reference types="cypress" />
2
+
3
+ // ***********************************************
4
+ // This example commands.ts shows you how to
5
+ // create various custom commands and overwrite
6
+ // existing commands.
7
+ //
8
+ // For more comprehensive examples of custom
9
+ // commands please read more here:
10
+ // https://on.cypress.io/custom-commands
11
+ // ***********************************************
12
+ <% if (linter === 'eslint') { %>
13
+ // eslint-disable-next-line @typescript-eslint/no-namespace<% } %>
14
+ declare namespace Cypress {<% if (linter === 'eslint') { %>
15
+ // eslint-disable-next-line @typescript-eslint/no-unused-vars<% } %>
16
+ interface Chainable<Subject> {
17
+ login(email: string, password: string): void;
18
+ }
19
+ }
20
+
21
+ // -- This is a parent command --
22
+ Cypress.Commands.add('login', (email, password) => {
23
+ console.log('Custom command example: Login', email, password);
24
+ });
25
+ //
26
+ // -- This is a child command --
27
+ // Cypress.Commands.add("drag", { prevSubject: 'element'}, (subject, options) => { ... })
28
+ //
29
+ //
30
+ // -- This is a dual command --
31
+ // Cypress.Commands.add("dismiss", { prevSubject: 'optional'}, (subject, options) => { ... })
32
+ //
33
+ //
34
+ // -- This will overwrite an existing command --
35
+ // Cypress.Commands.overwrite("visit", (originalFn, url, options) => { ... })
@@ -4,11 +4,17 @@ import type { NxComponentTestingOptions, NxCypressE2EPresetOptions } from '../..
4
4
  export declare const CYPRESS_CONFIG_FILE_NAME_PATTERN = "cypress.config.{js,ts,mjs,cjs}";
5
5
  export declare function addDefaultE2EConfig(cyConfigContents: string, options: NxCypressE2EPresetOptions, baseUrl: string): Promise<string>;
6
6
  /**
7
- * Adds the nxComponentTestingPreset to the cypress config file
8
- * Make sure after calling this the correct import statement is addeda
9
- * to bring in the nxComponentTestingPreset function
7
+ * Adds the nxComponentTestingPreset to the cypress config file.
8
+ *
9
+ * Pass `presetImportPath` (e.g. `@nx/angular/plugins/component-testing`) to
10
+ * have the matching `import` (ESM) or `const { ... } = require(...)` (CJS)
11
+ * statement prepended automatically based on the detected module shape.
12
+ * Without it, the caller is responsible for prepending the import - but
13
+ * doing so unconditionally produces mixed-syntax files in CJS workspaces
14
+ * (an ESM `import` followed by a CJS `module.exports`), so prefer passing
15
+ * `presetImportPath`.
10
16
  **/
11
- export declare function addDefaultCTConfig(cyConfigContents: string, options?: NxComponentTestingOptions): Promise<string>;
17
+ export declare function addDefaultCTConfig(cyConfigContents: string, options?: NxComponentTestingOptions, presetImportPath?: string): Promise<string>;
12
18
  /**
13
19
  * Adds the mount command for Cypress
14
20
  * Make sure after calling this the correct import statement is added
@@ -1 +1 @@
1
- {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/cypress/src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,KAAK,EAOV,uBAAuB,EAIxB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,8BAA8B,CAAC;AAEtC,eAAO,MAAM,gCAAgC,mCACX,CAAC;AAMnC,wBAAsB,mBAAmB,CACvC,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,yBAAyB,EAClC,OAAO,EAAE,MAAM,mBAsDhB;AAED;;;;IAII;AACJ,wBAAsB,kBAAkB,CACtC,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,yBAA8B,mBA8CxC;AAED;;;;IAII;AACJ,wBAAsB,kBAAkB,CAAC,sBAAsB,EAAE,MAAM,mBAgCtE;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,GAClB,MAAM,CASR;AAED,wBAAgB,0BAA0B,CACxC,qBAAqB,EAAE,MAAM,GAC5B,uBAAuB,GAAG,IAAI,CAqChC"}
1
+ {"version":3,"file":"config.d.ts","sourceRoot":"","sources":["../../../../../packages/cypress/src/utils/config.ts"],"names":[],"mappings":"AAAA,OAAO,EAA2B,KAAK,IAAI,EAAE,MAAM,YAAY,CAAC;AAEhE,OAAO,KAAK,EAOV,uBAAuB,EAIxB,MAAM,YAAY,CAAC;AACpB,OAAO,KAAK,EACV,yBAAyB,EACzB,yBAAyB,EAC1B,MAAM,8BAA8B,CAAC;AAEtC,eAAO,MAAM,gCAAgC,mCACX,CAAC;AAMnC,wBAAsB,mBAAmB,CACvC,gBAAgB,EAAE,MAAM,EACxB,OAAO,EAAE,yBAAyB,EAClC,OAAO,EAAE,MAAM,mBAmEhB;AAED;;;;;;;;;;IAUI;AACJ,wBAAsB,kBAAkB,CACtC,gBAAgB,EAAE,MAAM,EACxB,OAAO,GAAE,yBAA8B,EACvC,gBAAgB,CAAC,EAAE,MAAM,mBAmE1B;AAED;;;;IAII;AACJ,wBAAsB,kBAAkB,CAAC,sBAAsB,EAAE,MAAM,mBAgCtE;AAED,wBAAgB,2BAA2B,CACzC,IAAI,EAAE,IAAI,EACV,WAAW,EAAE,MAAM,GAClB,MAAM,CASR;AAED,wBAAgB,0BAA0B,CACxC,qBAAqB,EAAE,MAAM,GAC5B,uBAAuB,GAAG,IAAI,CAqChC"}
@@ -54,7 +54,17 @@ async function addDefaultE2EConfig(cyConfigContents, options, baseUrl) {
54
54
  const testingTypeConfig = tsquery.query(cyConfigContents, `${TS_QUERY_EXPORT_CONFIG_PREFIX} PropertyAssignment:has(Identifier[name="e2e"])`);
55
55
  let updatedConfigContents = cyConfigContents;
56
56
  if (testingTypeConfig.length === 0) {
57
- const configValue = `nxE2EPreset(__filename, ${JSON.stringify(options, null, 2)
57
+ // ESM-shape configs use `import.meta.url` (a `file://...` URL string)
58
+ // because it's the most universally available `import.meta` field:
59
+ // Node's native TS strip exposes it in ESM scope, and Cypress's bundled
60
+ // tsx CJS loader provides it too (unlike `import.meta.dirname`, which
61
+ // older tsx versions don't shim). CJS-shape configs use `__filename`
62
+ // since `import.meta` isn't defined in plain CJS scope. The base
63
+ // template is selected to match the workspace's `type` field, so the
64
+ // shape detected here is consistent with how the file will actually be
65
+ // evaluated at runtime. `nxBaseCypressPreset` normalizes either form.
66
+ const pathToConfig = isCommonJS ? '__filename' : 'import.meta.url';
67
+ const configValue = `nxE2EPreset(${pathToConfig}, ${JSON.stringify(options, null, 2)
58
68
  .split('\n')
59
69
  .join('\n ')})`;
60
70
  updatedConfigContents = tsquery.replace(cyConfigContents, `${TS_QUERY_EXPORT_CONFIG_PREFIX} ObjectLiteralExpression:first-child`, (node) => {
@@ -64,7 +74,7 @@ async function addDefaultE2EConfig(cyConfigContents, options, baseUrl) {
64
74
  ${node.properties.map((p) => p.getText()).join(',\n')},
65
75
  e2e: {
66
76
  ...${configValue}${baseUrlContents}
67
- }
77
+ }
68
78
  }`;
69
79
  }
70
80
  return `{
@@ -73,6 +83,9 @@ async function addDefaultE2EConfig(cyConfigContents, options, baseUrl) {
73
83
  }
74
84
  }`;
75
85
  });
86
+ // @nx/cypress's package exports cover both bare and `.js`-suffixed
87
+ // subpath forms, so emit the bare path - matches addDefaultCTConfig and
88
+ // keeps generated configs free of incidental `.js` noise.
76
89
  return isCommonJS
77
90
  ? `const { nxE2EPreset } = require('@nx/cypress/plugins/cypress-preset');
78
91
  ${updatedConfigContents}`
@@ -82,33 +95,44 @@ ${updatedConfigContents}`;
82
95
  return updatedConfigContents;
83
96
  }
84
97
  /**
85
- * Adds the nxComponentTestingPreset to the cypress config file
86
- * Make sure after calling this the correct import statement is addeda
87
- * to bring in the nxComponentTestingPreset function
98
+ * Adds the nxComponentTestingPreset to the cypress config file.
99
+ *
100
+ * Pass `presetImportPath` (e.g. `@nx/angular/plugins/component-testing`) to
101
+ * have the matching `import` (ESM) or `const { ... } = require(...)` (CJS)
102
+ * statement prepended automatically based on the detected module shape.
103
+ * Without it, the caller is responsible for prepending the import - but
104
+ * doing so unconditionally produces mixed-syntax files in CJS workspaces
105
+ * (an ESM `import` followed by a CJS `module.exports`), so prefer passing
106
+ * `presetImportPath`.
88
107
  **/
89
- async function addDefaultCTConfig(cyConfigContents, options = {}) {
108
+ async function addDefaultCTConfig(cyConfigContents, options = {}, presetImportPath) {
90
109
  if (!cyConfigContents) {
91
110
  throw new Error('The passed in cypress config file is empty!');
92
111
  }
93
112
  const { tsquery } = await Promise.resolve().then(() => __importStar(require('@phenomnomnominal/tsquery')));
113
+ const isCommonJS = tsquery.query(cyConfigContents, TS_QUERY_COMMON_JS_EXPORT_SELECTOR).length >
114
+ 0;
94
115
  const testingTypeConfig = tsquery.query(cyConfigContents, `${TS_QUERY_EXPORT_CONFIG_PREFIX} PropertyAssignment:has(Identifier[name="component"])`);
95
116
  let updatedConfigContents = cyConfigContents;
96
117
  if (testingTypeConfig.length === 0) {
97
- let configValue = 'nxComponentTestingPreset(__filename)';
118
+ // See addDefaultE2EConfig for the rationale on __filename vs
119
+ // import.meta.url.
120
+ const pathToConfig = isCommonJS ? '__filename' : 'import.meta.url';
121
+ let configValue = `nxComponentTestingPreset(${pathToConfig})`;
98
122
  if (options) {
99
123
  if (options.bundler !== 'vite') {
100
124
  // vite is the default bundler, so we don't need to set it
101
125
  delete options.bundler;
102
126
  }
103
127
  if (Object.keys(options).length) {
104
- configValue = `nxComponentTestingPreset(__filename, ${JSON.stringify(options)})`;
128
+ configValue = `nxComponentTestingPreset(${pathToConfig}, ${JSON.stringify(options)})`;
105
129
  }
106
130
  }
107
131
  updatedConfigContents = tsquery.replace(cyConfigContents, `${TS_QUERY_EXPORT_CONFIG_PREFIX} ObjectLiteralExpression:first-child`, (node) => {
108
132
  if (node.properties.length > 0) {
109
133
  return `{
110
134
  ${node.properties.map((p) => p.getText()).join(',\n')},
111
- component: ${configValue}
135
+ component: ${configValue}
112
136
  }`;
113
137
  }
114
138
  return `{
@@ -116,6 +140,19 @@ async function addDefaultCTConfig(cyConfigContents, options = {}) {
116
140
  }`;
117
141
  });
118
142
  }
143
+ if (presetImportPath) {
144
+ // Use the path verbatim - callers pass the public exported subpath. Don't
145
+ // append `.js`: @nx/react and @nx/angular's package exports only declare
146
+ // the bare `./plugins/component-testing` subpath, so a `.js` suffix
147
+ // breaks strict ESM resolution with ERR_PACKAGE_PATH_NOT_EXPORTED.
148
+ // (addDefaultE2EConfig hard-codes `.js` because @nx/cypress has no
149
+ // exports map - it can get away with the suffix; subpath-exporting
150
+ // packages cannot.)
151
+ const prefix = isCommonJS
152
+ ? `const { nxComponentTestingPreset } = require('${presetImportPath}');\n`
153
+ : `import { nxComponentTestingPreset } from '${presetImportPath}';\n`;
154
+ return `${prefix}${updatedConfigContents}`;
155
+ }
119
156
  return updatedConfigContents;
120
157
  }
121
158
  /**