@nx/cypress 21.6.1-beta.1 → 21.6.1-beta.3

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": "21.6.1-beta.1",
3
+ "version": "21.6.1-beta.3",
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": {
@@ -36,9 +36,9 @@
36
36
  "migrations": "./migrations.json"
37
37
  },
38
38
  "dependencies": {
39
- "@nx/devkit": "21.6.1-beta.1",
40
- "@nx/eslint": "21.6.1-beta.1",
41
- "@nx/js": "21.6.1-beta.1",
39
+ "@nx/devkit": "21.6.1-beta.3",
40
+ "@nx/eslint": "21.6.1-beta.3",
41
+ "@nx/js": "21.6.1-beta.3",
42
42
  "@phenomnomnominal/tsquery": "~5.0.1",
43
43
  "detect-port": "^1.5.1",
44
44
  "semver": "^7.6.3",
@@ -46,7 +46,7 @@
46
46
  "tslib": "^2.3.0"
47
47
  },
48
48
  "devDependencies": {
49
- "nx": "21.6.1-beta.1"
49
+ "nx": "21.6.1-beta.3"
50
50
  },
51
51
  "peerDependencies": {
52
52
  "cypress": ">= 3 < 15"
@@ -1,9 +1,10 @@
1
- import { CreateNodes, CreateNodesV2 } from '@nx/devkit';
1
+ import { type CreateNodes, type CreateNodesV2 } from '@nx/devkit';
2
2
  export interface CypressPluginOptions {
3
3
  ciTargetName?: string;
4
4
  targetName?: string;
5
5
  openTargetName?: string;
6
6
  componentTestingTargetName?: string;
7
+ ciComponentTestingTargetName?: string;
7
8
  }
8
9
  export declare const createNodesV2: CreateNodesV2<CypressPluginOptions>;
9
10
  /**
@@ -1 +1 @@
1
- {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../packages/cypress/src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,WAAW,EAGX,aAAa,EAWd,MAAM,YAAY,CAAC;AAepB,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0BAA0B,CAAC,EAAE,MAAM,CAAC;CACrC;AAoBD,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,oBAAoB,CAqB7D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,oBAAoB,CAQzD,CAAC"}
1
+ {"version":3,"file":"plugin.d.ts","sourceRoot":"","sources":["../../../../../packages/cypress/src/plugins/plugin.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,KAAK,WAAW,EAGhB,KAAK,aAAa,EAWnB,MAAM,YAAY,CAAC;AAYpB,MAAM,WAAW,oBAAoB;IACnC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,0BAA0B,CAAC,EAAE,MAAM,CAAC;IACpC,4BAA4B,CAAC,EAAE,MAAM,CAAC;CACvC;AA8BD,eAAO,MAAM,aAAa,EAAE,aAAa,CAAC,oBAAoB,CAqB7D,CAAC;AAEF;;;GAGG;AACH,eAAO,MAAM,WAAW,EAAE,WAAW,CAAC,oBAAoB,CAQzD,CAAC"}
@@ -2,16 +2,16 @@
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createNodes = exports.createNodesV2 = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
- const path_1 = require("path");
6
- const js_1 = require("@nx/js");
7
- const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
8
- const fs_1 = require("fs");
9
5
  const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
10
- const cache_directory_1 = require("nx/src/utils/cache-directory");
11
- const constants_1 = require("../utils/constants");
12
6
  const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
7
+ const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
8
+ const js_1 = require("@nx/js");
9
+ const fs_1 = require("fs");
13
10
  const devkit_internals_1 = require("nx/src/devkit-internals");
11
+ const cache_directory_1 = require("nx/src/utils/cache-directory");
14
12
  const workspace_context_1 = require("nx/src/utils/workspace-context");
13
+ const path_1 = require("path");
14
+ const constants_1 = require("../utils/constants");
15
15
  function readTargetsCache(cachePath) {
16
16
  try {
17
17
  return process.env.NX_CACHE_PROJECT_GRAPH !== 'false'
@@ -26,6 +26,16 @@ function writeTargetsToCache(cachePath, results) {
26
26
  (0, devkit_1.writeJsonFile)(cachePath, results);
27
27
  }
28
28
  const cypressConfigGlob = '**/cypress.config.{js,ts,mjs,cjs}';
29
+ const defaultPatterns = {
30
+ e2e: {
31
+ specPattern: 'cypress/e2e/**/*.cy.{js,jsx,ts,tsx}',
32
+ excludeSpecPattern: '*.hot-update.js',
33
+ },
34
+ component: {
35
+ specPattern: '**/*.cy.{js,jsx,ts,tsx}',
36
+ excludeSpecPattern: ['/snapshots/*', '/image_snapshots/*'],
37
+ },
38
+ };
29
39
  const pmc = (0, devkit_1.getPackageManagerCommand)();
30
40
  exports.createNodesV2 = [
31
41
  cypressConfigGlob,
@@ -214,16 +224,7 @@ async function buildCypressTargets(configFilePath, projectRoot, options, context
214
224
  }
215
225
  const ciWebServerCommand = pluginPresetOptions?.ciWebServerCommand;
216
226
  if (ciWebServerCommand) {
217
- const specPatterns = Array.isArray(cypressConfig.e2e.specPattern)
218
- ? cypressConfig.e2e.specPattern.map((p) => (0, path_1.join)(projectRoot, p))
219
- : [(0, path_1.join)(projectRoot, cypressConfig.e2e.specPattern)];
220
- const excludeSpecPatterns = !cypressConfig.e2e
221
- .excludeSpecPattern
222
- ? cypressConfig.e2e.excludeSpecPattern
223
- : Array.isArray(cypressConfig.e2e.excludeSpecPattern)
224
- ? cypressConfig.e2e.excludeSpecPattern.map((p) => (0, path_1.join)(projectRoot, p))
225
- : [(0, path_1.join)(projectRoot, cypressConfig.e2e.excludeSpecPattern)];
226
- const specFiles = await (0, workspace_context_1.globWithWorkspaceContext)(context.workspaceRoot, specPatterns, excludeSpecPatterns);
227
+ const { specFiles, specPatterns, excludeSpecPatterns } = await getSpecFilesAndPatternsForTestType(cypressConfig, 'e2e', context.workspaceRoot, projectRoot);
227
228
  const ciBaseUrl = pluginPresetOptions?.ciBaseUrl;
228
229
  const dependsOn = [];
229
230
  const outputs = getOutputs(projectRoot, cypressConfig, 'e2e');
@@ -276,6 +277,7 @@ async function buildCypressTargets(configFilePath, projectRoot, options, context
276
277
  target: targetName,
277
278
  projects: 'self',
278
279
  params: 'forward',
280
+ options: 'forward',
279
281
  });
280
282
  if (ciWebServerCommandTask) {
281
283
  targets[targetName].dependsOn = [
@@ -314,6 +316,8 @@ async function buildCypressTargets(configFilePath, projectRoot, options, context
314
316
  }
315
317
  }
316
318
  if ('component' in cypressConfig) {
319
+ const inputs = getInputs(namedInputs);
320
+ const outputs = getOutputs(projectRoot, cypressConfig, 'component');
317
321
  // This will not override the e2e target if it is the same
318
322
  targets[options.componentTestingTargetName] ??= {
319
323
  command: `cypress run --component`,
@@ -322,8 +326,8 @@ async function buildCypressTargets(configFilePath, projectRoot, options, context
322
326
  env: { TS_NODE_COMPILER_OPTIONS: tsNodeCompilerOptions },
323
327
  },
324
328
  cache: true,
325
- inputs: getInputs(namedInputs),
326
- outputs: getOutputs(projectRoot, cypressConfig, 'component'),
329
+ inputs,
330
+ outputs,
327
331
  metadata: {
328
332
  technologies: ['cypress'],
329
333
  description: 'Runs Cypress Component Tests',
@@ -335,6 +339,83 @@ async function buildCypressTargets(configFilePath, projectRoot, options, context
335
339
  },
336
340
  },
337
341
  };
342
+ if (options.ciComponentTestingTargetName) {
343
+ const { specFiles, specPatterns, excludeSpecPatterns } = await getSpecFilesAndPatternsForTestType(cypressConfig, 'component', context.workspaceRoot, projectRoot);
344
+ const dependsOn = [];
345
+ const groupName = 'Component Testing (CI)';
346
+ metadata ??= {};
347
+ metadata.targetGroups ??= {};
348
+ metadata.targetGroups[groupName] ??= [];
349
+ const ctCiTargetGroup = metadata.targetGroups[groupName];
350
+ for (const file of specFiles) {
351
+ const relativeSpecFilePath = (0, devkit_1.normalizePath)((0, path_1.relative)(projectRoot, file));
352
+ if (relativeSpecFilePath.includes('../')) {
353
+ throw new Error('@nx/cypress/plugin attempted to run tests outside of the project root. This is not supported and should not happen. Please open an issue at https://github.com/nrwl/nx/issues/new/choose with the following information:\n\n' +
354
+ `\n\n${JSON.stringify({
355
+ projectRoot,
356
+ relativeSpecFilePath,
357
+ specFiles,
358
+ context,
359
+ excludeSpecPatterns,
360
+ specPatterns,
361
+ }, null, 2)}`);
362
+ }
363
+ const targetName = options.ciComponentTestingTargetName + '--' + relativeSpecFilePath;
364
+ const outputSubfolder = relativeSpecFilePath
365
+ .replace(/[\/\\]/g, '-')
366
+ .replace(/\./g, '-');
367
+ ctCiTargetGroup.push(targetName);
368
+ targets[targetName] = {
369
+ outputs: getTargetOutputs(outputs, outputSubfolder),
370
+ inputs,
371
+ cache: true,
372
+ command: `cypress run --component --spec ${relativeSpecFilePath} --config=${getTargetConfig(cypressConfig, outputSubfolder)}`,
373
+ options: {
374
+ cwd: projectRoot,
375
+ env: { TS_NODE_COMPILER_OPTIONS: tsNodeCompilerOptions },
376
+ },
377
+ // Cypress handles starting the server, there's no separate server
378
+ // target we can use as continuous, so we need to disable parallelism
379
+ // to avoid port conflicts
380
+ parallelism: false,
381
+ metadata: {
382
+ technologies: ['cypress'],
383
+ description: `Runs Cypress Component Tests for ${relativeSpecFilePath} in CI`,
384
+ help: {
385
+ command: `${pmc.exec} cypress run --help`,
386
+ example: {
387
+ args: ['--dev', '--headed'],
388
+ },
389
+ },
390
+ },
391
+ };
392
+ dependsOn.push({
393
+ target: targetName,
394
+ projects: 'self',
395
+ params: 'forward',
396
+ options: 'forward',
397
+ });
398
+ }
399
+ targets[options.ciComponentTestingTargetName] = {
400
+ executor: 'nx:noop',
401
+ cache: true,
402
+ inputs,
403
+ outputs,
404
+ dependsOn,
405
+ metadata: {
406
+ technologies: ['cypress'],
407
+ description: 'Runs Cypress Component Tests in CI',
408
+ nonAtomizedTarget: options.componentTestingTargetName,
409
+ help: {
410
+ command: `${pmc.exec} cypress run --help`,
411
+ example: {
412
+ args: ['--dev', '--headed'],
413
+ },
414
+ },
415
+ },
416
+ };
417
+ ctCiTargetGroup.push(options.ciComponentTestingTargetName);
418
+ }
338
419
  }
339
420
  targets[options.openTargetName] = {
340
421
  command: `cypress open`,
@@ -361,6 +442,8 @@ function normalizeOptions(options) {
361
442
  options.openTargetName ??= 'open-cypress';
362
443
  options.componentTestingTargetName ??= 'component-test';
363
444
  options.ciTargetName ??= 'e2e-ci';
445
+ // must be explicitly provided to opt-in to atomized component testing
446
+ options.ciComponentTestingTargetName;
364
447
  return options;
365
448
  }
366
449
  function getInputs(namedInputs) {
@@ -388,3 +471,17 @@ function parseTaskFromCommand(command) {
388
471
  }
389
472
  return null;
390
473
  }
474
+ async function getSpecFilesAndPatternsForTestType(cypressConfig, testType, workspaceRoot, projectRoot) {
475
+ const specPattern = cypressConfig[testType].specPattern ??
476
+ defaultPatterns[testType].specPattern;
477
+ const specPatterns = Array.isArray(specPattern)
478
+ ? specPattern.map((p) => (0, path_1.join)(projectRoot, p))
479
+ : [(0, path_1.join)(projectRoot, specPattern)];
480
+ const excludeSpecPattern = cypressConfig[testType].excludeSpecPattern ??
481
+ defaultPatterns[testType].excludeSpecPattern;
482
+ const excludeSpecPatterns = Array.isArray(excludeSpecPattern)
483
+ ? excludeSpecPattern.map((p) => (0, path_1.join)(projectRoot, p))
484
+ : [(0, path_1.join)(projectRoot, excludeSpecPattern)];
485
+ const specFiles = await (0, workspace_context_1.globWithWorkspaceContext)(workspaceRoot, specPatterns, excludeSpecPatterns);
486
+ return { specFiles, specPatterns, excludeSpecPatterns };
487
+ }