@nx/playwright 20.1.0-canary.20241031-ce05a98 → 20.1.0-canary.20241102-c290b37

Sign up to get free protection for your applications and to get access to all the features.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/playwright",
3
- "version": "20.1.0-canary.20241031-ce05a98",
3
+ "version": "20.1.0-canary.20241102-c290b37",
4
4
  "type": "commonjs",
5
5
  "homepage": "https://nx.dev",
6
6
  "private": false,
@@ -35,11 +35,11 @@
35
35
  },
36
36
  "dependencies": {
37
37
  "@phenomnomnominal/tsquery": "~5.0.1",
38
- "@nx/devkit": "20.1.0-canary.20241031-ce05a98",
39
- "@nx/eslint": "20.1.0-canary.20241031-ce05a98",
40
- "@nx/webpack": "20.1.0-canary.20241031-ce05a98",
41
- "@nx/vite": "20.1.0-canary.20241031-ce05a98",
42
- "@nx/js": "20.1.0-canary.20241031-ce05a98",
38
+ "@nx/devkit": "20.1.0-canary.20241102-c290b37",
39
+ "@nx/eslint": "20.1.0-canary.20241102-c290b37",
40
+ "@nx/webpack": "20.1.0-canary.20241102-c290b37",
41
+ "@nx/vite": "20.1.0-canary.20241102-c290b37",
42
+ "@nx/js": "20.1.0-canary.20241102-c290b37",
43
43
  "tslib": "^2.3.0",
44
44
  "minimatch": "9.0.3"
45
45
  },
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.createNodes = exports.createNodesV2 = void 0;
4
- const fs_1 = require("fs");
5
- const path_1 = require("path");
4
+ const node_fs_1 = require("node:fs");
5
+ const node_path_1 = require("node:path");
6
6
  const devkit_1 = require("@nx/devkit");
7
7
  const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
8
8
  const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
@@ -14,7 +14,7 @@ const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
14
14
  const file_hasher_1 = require("nx/src/hasher/file-hasher");
15
15
  const pmc = (0, devkit_1.getPackageManagerCommand)();
16
16
  function readTargetsCache(cachePath) {
17
- return (0, fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
17
+ return (0, node_fs_1.existsSync)(cachePath) ? (0, devkit_1.readJsonFile)(cachePath) : {};
18
18
  }
19
19
  function writeTargetsToCache(cachePath, results) {
20
20
  (0, devkit_1.writeJsonFile)(cachePath, results);
@@ -24,7 +24,7 @@ exports.createNodesV2 = [
24
24
  playwrightConfigGlob,
25
25
  async (configFilePaths, options, context) => {
26
26
  const optionsHash = (0, file_hasher_1.hashObject)(options);
27
- const cachePath = (0, path_1.join)(cache_directory_1.workspaceDataDirectory, `playwright-${optionsHash}.hash`);
27
+ const cachePath = (0, node_path_1.join)(cache_directory_1.workspaceDataDirectory, `playwright-${optionsHash}.hash`);
28
28
  const targetsCache = readTargetsCache(cachePath);
29
29
  try {
30
30
  return await (0, devkit_1.createNodesFromFiles)((configFile, options, context) => createNodesInternal(configFile, options, context, targetsCache), configFilePaths, options, context);
@@ -46,9 +46,9 @@ exports.createNodes = [
46
46
  },
47
47
  ];
48
48
  async function createNodesInternal(configFilePath, options, context, targetsCache) {
49
- const projectRoot = (0, path_1.dirname)(configFilePath);
49
+ const projectRoot = (0, node_path_1.dirname)(configFilePath);
50
50
  // Do not create a project if package.json and project.json isn't there.
51
- const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
51
+ const siblingFiles = (0, node_fs_1.readdirSync)((0, node_path_1.join)(context.workspaceRoot, projectRoot));
52
52
  if (!siblingFiles.includes('package.json') &&
53
53
  !siblingFiles.includes('project.json')) {
54
54
  return {};
@@ -72,10 +72,12 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
72
72
  // but we're just reading the config so let's delete the variable they are using to detect this.
73
73
  // See: https://github.com/microsoft/playwright/pull/11218/files
74
74
  delete process['__pw_initiator__'];
75
- const playwrightConfig = await (0, config_utils_1.loadConfigFile)((0, path_1.join)(context.workspaceRoot, configFilePath));
75
+ const playwrightConfig = await (0, config_utils_1.loadConfigFile)((0, node_path_1.join)(context.workspaceRoot, configFilePath));
76
76
  const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
77
77
  const targets = {};
78
78
  let metadata;
79
+ const testOutput = getTestOutput(playwrightConfig);
80
+ const reporterOutputs = getReporterOutputs(playwrightConfig);
79
81
  const baseTargetConfig = {
80
82
  command: 'playwright test',
81
83
  options: {
@@ -104,7 +106,7 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
104
106
  : ['default', '^default']),
105
107
  { externalDependencies: ['@playwright/test'] },
106
108
  ],
107
- outputs: getOutputs(projectRoot, playwrightConfig),
109
+ outputs: getTargetOutputs(testOutput, reporterOutputs, projectRoot),
108
110
  };
109
111
  if (options.ciTargetName) {
110
112
  const ciBaseTargetConfig = {
@@ -116,7 +118,7 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
116
118
  : ['default', '^default']),
117
119
  { externalDependencies: ['@playwright/test'] },
118
120
  ],
119
- outputs: getOutputs(projectRoot, playwrightConfig),
121
+ outputs: getTargetOutputs(testOutput, reporterOutputs, projectRoot),
120
122
  };
121
123
  const groupName = 'E2E (CI)';
122
124
  metadata = { targetGroups: { [groupName]: [] } };
@@ -128,12 +130,20 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
128
130
  playwrightConfig.testMatch ??= '**/*.@(spec|test).?(c|m)[jt]s?(x)';
129
131
  const dependsOn = [];
130
132
  await forEachTestFile((testFile) => {
131
- const relativeSpecFilePath = (0, devkit_1.normalizePath)((0, path_1.relative)(projectRoot, testFile));
133
+ const outputSubfolder = (0, node_path_1.relative)(projectRoot, testFile)
134
+ .replace(/[\/\\]/g, '-')
135
+ .replace(/\./g, '-');
136
+ const relativeSpecFilePath = (0, devkit_1.normalizePath)((0, node_path_1.relative)(projectRoot, testFile));
132
137
  const targetName = `${options.ciTargetName}--${relativeSpecFilePath}`;
133
138
  ciTargetGroup.push(targetName);
134
139
  targets[targetName] = {
135
140
  ...ciBaseTargetConfig,
136
- command: `${baseTargetConfig.command} ${relativeSpecFilePath}`,
141
+ options: {
142
+ ...ciBaseTargetConfig.options,
143
+ env: getOutputEnvVars(reporterOutputs, outputSubfolder),
144
+ },
145
+ outputs: getTargetOutputs(testOutput, reporterOutputs, projectRoot, outputSubfolder),
146
+ command: `${baseTargetConfig.command} ${relativeSpecFilePath} --output=${(0, node_path_1.join)(testOutput, outputSubfolder)}`,
137
147
  metadata: {
138
148
  technologies: ['playwright'],
139
149
  description: `Runs Playwright Tests in ${relativeSpecFilePath} in CI`,
@@ -214,58 +224,84 @@ function createMatcher(pattern) {
214
224
  };
215
225
  }
216
226
  }
217
- function getOutputs(projectRoot, playwrightConfig) {
218
- function getOutput(path) {
219
- if (path.startsWith('..')) {
220
- return (0, path_1.join)('{workspaceRoot}', (0, path_1.join)(projectRoot, path));
221
- }
222
- else {
223
- return (0, path_1.join)('{projectRoot}', path);
224
- }
227
+ function normalizeOptions(options) {
228
+ return {
229
+ ...options,
230
+ targetName: options.targetName ?? 'e2e',
231
+ ciTargetName: options.ciTargetName ?? 'e2e-ci',
232
+ };
233
+ }
234
+ function getTestOutput(playwrightConfig) {
235
+ const { outputDir } = playwrightConfig;
236
+ if (outputDir) {
237
+ return outputDir;
238
+ }
239
+ else {
240
+ return './test-results';
225
241
  }
242
+ }
243
+ function getReporterOutputs(playwrightConfig) {
226
244
  const outputs = [];
227
- const { reporter, outputDir } = playwrightConfig;
245
+ const { reporter } = playwrightConfig;
228
246
  if (reporter) {
229
- const DEFAULT_REPORTER_OUTPUT = getOutput('playwright-report');
230
- if (reporter === 'html' || reporter === 'json') {
231
- // Reporter is a string, so it uses the default output directory.
232
- outputs.push(DEFAULT_REPORTER_OUTPUT);
247
+ const DEFAULT_REPORTER_OUTPUT = 'playwright-report';
248
+ if (reporter === 'html') {
249
+ outputs.push([reporter, DEFAULT_REPORTER_OUTPUT]);
250
+ }
251
+ else if (reporter === 'json') {
252
+ outputs.push([reporter, DEFAULT_REPORTER_OUTPUT]);
233
253
  }
234
254
  else if (Array.isArray(reporter)) {
235
255
  for (const r of reporter) {
236
- const [, opts] = r;
256
+ const [reporter, opts] = r;
237
257
  // There are a few different ways to specify an output file or directory
238
258
  // depending on the reporter. This is a best effort to find the output.
239
- if (!opts) {
240
- outputs.push(DEFAULT_REPORTER_OUTPUT);
241
- }
242
- else if (opts.outputFile) {
243
- outputs.push(getOutput(opts.outputFile));
259
+ if (opts?.outputFile) {
260
+ outputs.push([reporter, opts.outputFile]);
244
261
  }
245
- else if (opts.outputDir) {
246
- outputs.push(getOutput(opts.outputDir));
262
+ else if (opts?.outputDir) {
263
+ outputs.push([reporter, opts.outputDir]);
247
264
  }
248
- else if (opts.outputFolder) {
249
- outputs.push(getOutput(opts.outputFolder));
265
+ else if (opts?.outputFolder) {
266
+ outputs.push([reporter, opts.outputFolder]);
250
267
  }
251
268
  else {
252
- outputs.push(DEFAULT_REPORTER_OUTPUT);
269
+ outputs.push([reporter, DEFAULT_REPORTER_OUTPUT]);
253
270
  }
254
271
  }
255
272
  }
256
273
  }
257
- if (outputDir) {
258
- outputs.push(getOutput(outputDir));
274
+ return outputs;
275
+ }
276
+ function getTargetOutputs(testOutput, reporterOutputs, projectRoot, scope) {
277
+ const outputs = new Set();
278
+ outputs.add(normalizeOutput(projectRoot, scope ? (0, node_path_1.join)(testOutput, scope) : testOutput));
279
+ for (const [, output] of reporterOutputs) {
280
+ outputs.add(normalizeOutput(projectRoot, scope ? (0, node_path_1.join)(output, scope) : output));
281
+ }
282
+ return Array.from(outputs);
283
+ }
284
+ function normalizeOutput(projectRoot, path) {
285
+ if (path.startsWith('..')) {
286
+ return (0, node_path_1.join)('{workspaceRoot}', (0, node_path_1.join)(projectRoot, path));
259
287
  }
260
288
  else {
261
- outputs.push(getOutput('./test-results'));
289
+ return (0, node_path_1.join)('{projectRoot}', path);
262
290
  }
263
- return outputs;
264
291
  }
265
- function normalizeOptions(options) {
266
- return {
267
- ...options,
268
- targetName: options.targetName ?? 'e2e',
269
- ciTargetName: options.ciTargetName ?? 'e2e-ci',
270
- };
292
+ function getOutputEnvVars(reporterOutputs, outputSubfolder) {
293
+ const env = {};
294
+ for (let [reporter, output] of reporterOutputs) {
295
+ if (outputSubfolder) {
296
+ const isFile = (0, node_path_1.parse)(output).ext !== '';
297
+ const envVarName = `PLAYWRIGHT_${reporter.toUpperCase()}_OUTPUT_${isFile ? 'FILE' : 'DIR'}`;
298
+ env[envVarName] = (0, node_path_1.join)(output, outputSubfolder);
299
+ // Also set PLAYWRIGHT_HTML_REPORT for Playwright prior to 1.45.0.
300
+ // HTML prior to this version did not follow the pattern of "PLAYWRIGHT_<REPORTER>_OUTPUT_<FILE|DIR>".
301
+ if (reporter === 'html') {
302
+ env['PLAYWRIGHT_HTML_REPORT'] = env[envVarName];
303
+ }
304
+ }
305
+ }
306
+ return env;
271
307
  }