@nx/playwright 17.0.3 → 17.0.5

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 (32) hide show
  1. package/LICENSE +1 -1
  2. package/README.md +9 -4
  3. package/executors.json +1 -1
  4. package/generators.json +2 -2
  5. package/index.d.ts +1 -1
  6. package/index.js +2 -2
  7. package/migrations.json +16 -0
  8. package/package.json +11 -4
  9. package/plugin.d.ts +1 -0
  10. package/plugin.js +6 -0
  11. package/src/executors/playwright/{playwright.d.ts → playwright.impl.d.ts} +2 -1
  12. package/src/executors/playwright/{playwright.js → playwright.impl.js} +6 -2
  13. package/src/executors/playwright/schema.json +10 -2
  14. package/src/generators/configuration/configuration.d.ts +1 -0
  15. package/src/generators/configuration/configuration.js +90 -10
  16. package/src/generators/configuration/files/playwright.config.ts.template +39 -2
  17. package/src/generators/configuration/schema.d.ts +2 -0
  18. package/src/generators/configuration/schema.json +6 -1
  19. package/src/generators/init/init.d.ts +1 -0
  20. package/src/generators/init/init.js +34 -30
  21. package/src/generators/init/schema.d.ts +5 -3
  22. package/src/generators/init/schema.json +10 -3
  23. package/src/migrations/update-17-3-1/add-project-to-config.d.ts +2 -0
  24. package/src/migrations/update-17-3-1/add-project-to-config.js +95 -0
  25. package/src/migrations/update-18-1-0/remove-baseUrl-from-project-json.d.ts +2 -0
  26. package/src/migrations/update-18-1-0/remove-baseUrl-from-project-json.js +42 -0
  27. package/src/plugins/plugin.d.ts +7 -0
  28. package/src/plugins/plugin.js +205 -0
  29. package/src/utils/add-linter.d.ts +1 -0
  30. package/src/utils/add-linter.js +1 -3
  31. package/src/utils/preset.d.ts +1 -10
  32. package/src/utils/preset.js +1 -39
package/LICENSE CHANGED
@@ -1,6 +1,6 @@
1
1
  (The MIT License)
2
2
 
3
- Copyright (c) 2017-2023 Narwhal Technologies Inc.
3
+ Copyright (c) 2017-2024 Narwhal Technologies Inc.
4
4
 
5
5
  Permission is hereby granted, free of charge, to any person obtaining
6
6
  a copy of this software and associated documentation files (the
package/README.md CHANGED
@@ -1,4 +1,9 @@
1
- <p style="text-align: center;"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx.png" width="600" alt="Nx - Smart, Fast and Extensible Build System"></p>
1
+ <p style="text-align: center;">
2
+ <picture>
3
+ <source media="(prefers-color-scheme: dark)" srcset="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-dark.svg">
4
+ <img alt="Nx - Smart Monorepos · Fast CI" src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-light.svg" width="100%">
5
+ </picture>
6
+ </p>
2
7
 
3
8
  <div style="text-align: center;">
4
9
 
@@ -15,9 +20,9 @@
15
20
 
16
21
  <hr>
17
22
 
18
- # Nx: Smart, Fast and Extensible Build System
23
+ # Nx: Smart Monorepos · Fast CI
19
24
 
20
- Nx is a next generation build system with first class monorepo support and powerful integrations.
25
+ Nx is a build system with built-in tooling and advanced CI capabilities. It helps you maintain and scale monorepos, both locally and on CI.
21
26
 
22
27
  ## Getting Started
23
28
 
@@ -57,5 +62,5 @@ npx nx@latest init
57
62
  - [Blog Posts About Nx](https://blog.nrwl.io/nx/home)
58
63
 
59
64
  <p style="text-align: center;"><a href="https://nx.dev/#learning-materials" target="_blank" rel="noreferrer"><img src="https://raw.githubusercontent.com/nrwl/nx/master/images/nx-courses-and-videos.svg"
60
- width="100%" alt="Nx - Smart, Fast and Extensible Build System"></a></p>
65
+ width="100%" alt="Nx - Smart Monorepos · Fast CI"></a></p>
61
66
 
package/executors.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "executors": {
3
3
  "playwright": {
4
- "implementation": "./src/executors/playwright/playwright",
4
+ "implementation": "./src/executors/playwright/playwright.impl",
5
5
  "schema": "./src/executors/playwright/schema.json",
6
6
  "description": "Run Playwright tests."
7
7
  }
package/generators.json CHANGED
@@ -3,12 +3,12 @@
3
3
  "version": "0.1",
4
4
  "generators": {
5
5
  "configuration": {
6
- "factory": "./src/generators/configuration/configuration",
6
+ "factory": "./src/generators/configuration/configuration#configurationGeneratorInternal",
7
7
  "schema": "./src/generators/configuration/schema.json",
8
8
  "description": "Add Nx Playwright configuration to your project"
9
9
  },
10
10
  "init": {
11
- "factory": "./src/generators/init/init",
11
+ "factory": "./src/generators/init/init#initGeneratorInternal",
12
12
  "schema": "./src/generators/init/schema.json",
13
13
  "description": "Initializes a Playwright project in the current workspace"
14
14
  }
package/index.d.ts CHANGED
@@ -1,3 +1,3 @@
1
- export { playwrightExecutor, PlaywrightExecutorSchema, } from './src/executors/playwright/playwright';
1
+ export { playwrightExecutor, PlaywrightExecutorSchema, } from './src/executors/playwright/playwright.impl';
2
2
  export { initGenerator } from './src/generators/init/init';
3
3
  export { configurationGenerator } from './src/generators/configuration/configuration';
package/index.js CHANGED
@@ -1,8 +1,8 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.configurationGenerator = exports.initGenerator = exports.playwrightExecutor = void 0;
4
- var playwright_1 = require("./src/executors/playwright/playwright");
5
- Object.defineProperty(exports, "playwrightExecutor", { enumerable: true, get: function () { return playwright_1.playwrightExecutor; } });
4
+ var playwright_impl_1 = require("./src/executors/playwright/playwright.impl");
5
+ Object.defineProperty(exports, "playwrightExecutor", { enumerable: true, get: function () { return playwright_impl_1.playwrightExecutor; } });
6
6
  var init_1 = require("./src/generators/init/init");
7
7
  Object.defineProperty(exports, "initGenerator", { enumerable: true, get: function () { return init_1.initGenerator; } });
8
8
  var configuration_1 = require("./src/generators/configuration/configuration");
@@ -0,0 +1,16 @@
1
+ {
2
+ "generators": {
3
+ "17-3-1-add-project-to-config": {
4
+ "cli": "nx",
5
+ "version": "17.3.1-beta.0",
6
+ "description": "Add project property to playwright config",
7
+ "implementation": "./src/migrations/update-17-3-1/add-project-to-config"
8
+ },
9
+ "18-1-0-remove-baseUrl-from-project-json": {
10
+ "cli": "nx",
11
+ "version": "18.1.0-beta.3",
12
+ "description": "Remove invalid baseUrl option from @nx/playwright:playwright targets in project.json.",
13
+ "implementation": "./src/migrations/update-18-1-0/remove-baseUrl-from-project-json"
14
+ }
15
+ }
16
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@nx/playwright",
3
- "version": "17.0.3",
3
+ "version": "17.0.5",
4
4
  "type": "commonjs",
5
5
  "homepage": "https://nx.dev",
6
6
  "private": false,
@@ -32,9 +32,12 @@
32
32
  "directory": "packages/playwright"
33
33
  },
34
34
  "dependencies": {
35
- "@nx/devkit": "17.0.3",
36
- "@nx/eslint": "17.0.3",
37
- "tslib": "^2.3.0"
35
+ "@phenomnomnominal/tsquery": "~5.0.1",
36
+ "@nx/devkit": "17.0.5",
37
+ "@nx/eslint": "17.0.5",
38
+ "@nx/js": "17.0.5",
39
+ "tslib": "^2.3.0",
40
+ "minimatch": "9.0.3"
38
41
  },
39
42
  "peerDependencies": {
40
43
  "@playwright/test": "^1.36.0"
@@ -54,6 +57,10 @@
54
57
  "./generators/*/schema.json": "./src/generators/*/schema.json",
55
58
  "./executors.json": "./executors.json",
56
59
  "./executors/*/schema.json": "./src/executors/*/schema.json",
60
+ "./plugin": "./plugin.js",
57
61
  "./preset": "./src/utils/preset.js"
62
+ },
63
+ "nx-migrations": {
64
+ "migrations": "./migrations.json"
58
65
  }
59
66
  }
package/plugin.d.ts ADDED
@@ -0,0 +1 @@
1
+ export { createNodes, PlaywrightPluginOptions, createDependencies, } from './src/plugins/plugin';
package/plugin.js ADDED
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createDependencies = exports.createNodes = void 0;
4
+ var plugin_1 = require("./src/plugins/plugin");
5
+ Object.defineProperty(exports, "createNodes", { enumerable: true, get: function () { return plugin_1.createNodes; } });
6
+ Object.defineProperty(exports, "createDependencies", { enumerable: true, get: function () { return plugin_1.createDependencies; } });
@@ -8,6 +8,7 @@ export interface PlaywrightExecutorSchema {
8
8
  grep?: string;
9
9
  globalTimeout?: number;
10
10
  grepInvert?: string;
11
+ testFiles?: string[];
11
12
  headed?: boolean;
12
13
  ignoreSnapshots?: boolean;
13
14
  workers?: string;
@@ -27,7 +28,7 @@ export interface PlaywrightExecutorSchema {
27
28
  updateSnapshots?: boolean;
28
29
  ui?: boolean;
29
30
  uiHost?: string;
30
- uiPort?: string;
31
+ uiPort?: number;
31
32
  skipInstall?: boolean;
32
33
  }
33
34
  export declare function playwrightExecutor(options: PlaywrightExecutorSchema, context: ExecutorContext): Promise<{
@@ -36,14 +36,18 @@ async function playwrightExecutor(options, context) {
36
36
  exports.playwrightExecutor = playwrightExecutor;
37
37
  function createArgs(opts, exclude = ['skipInstall']) {
38
38
  const args = [];
39
- for (const key in opts) {
39
+ const { testFiles, ...rest } = opts;
40
+ if (testFiles) {
41
+ args.push(...testFiles);
42
+ }
43
+ for (const key in rest) {
40
44
  if (exclude.includes(key))
41
45
  continue;
42
46
  const value = opts[key];
43
47
  // NOTE: playwright doesn't accept pascalCase args, only kebab-case
44
48
  const arg = (0, devkit_1.names)(key).fileName;
45
49
  if (Array.isArray(value)) {
46
- args.push(`--${arg}=${value.map((v) => v.trim()).join(',')}`);
50
+ args.push(...value.map((v) => `--${arg}=${v.trim()}`));
47
51
  }
48
52
  else if (typeof value === 'boolean') {
49
53
  // NOTE: playwright don't accept --arg=false, instead just don't pass the arg.
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "version": 2,
4
4
  "title": "Playwright executor",
5
5
  "description": "Run Playwright tests.",
@@ -43,6 +43,14 @@
43
43
  "type": "string",
44
44
  "description": "Only run tests that do not match this regular expression"
45
45
  },
46
+ "testFiles": {
47
+ "alias": "t",
48
+ "type": "array",
49
+ "description": "Test files to run",
50
+ "items": {
51
+ "type": "string"
52
+ }
53
+ },
46
54
  "headed": {
47
55
  "type": "boolean",
48
56
  "description": "Run tests in headed browsers",
@@ -147,7 +155,7 @@
147
155
  "description": "Host to serve UI on; specifying this option opens UI in a browser tab"
148
156
  },
149
157
  "uiPort": {
150
- "type": "string",
158
+ "type": "number",
151
159
  "description": "Port to serve UI on, 0 for any free port; specifying this option opens UI in a browser tab"
152
160
  },
153
161
  "skipInstall": {
@@ -1,4 +1,5 @@
1
1
  import { GeneratorCallback, Tree } from '@nx/devkit';
2
2
  import { ConfigurationGeneratorSchema } from './schema';
3
3
  export declare function configurationGenerator(tree: Tree, options: ConfigurationGeneratorSchema): Promise<GeneratorCallback>;
4
+ export declare function configurationGeneratorInternal(tree: Tree, options: ConfigurationGeneratorSchema): Promise<GeneratorCallback>;
4
5
  export default configurationGenerator;
@@ -1,26 +1,67 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.configurationGenerator = void 0;
3
+ exports.configurationGeneratorInternal = exports.configurationGenerator = void 0;
4
4
  const devkit_1 = require("@nx/devkit");
5
+ const js_1 = require("@nx/js");
6
+ const versions_1 = require("@nx/js/src/utils/versions");
7
+ const child_process_1 = require("child_process");
5
8
  const path = require("path");
6
- const init_1 = require("../init/init");
7
9
  const add_linter_1 = require("../../utils/add-linter");
8
- async function configurationGenerator(tree, options) {
10
+ const versions_2 = require("../../utils/versions");
11
+ const init_1 = require("../init/init");
12
+ function configurationGenerator(tree, options) {
13
+ return configurationGeneratorInternal(tree, { addPlugin: false, ...options });
14
+ }
15
+ exports.configurationGenerator = configurationGenerator;
16
+ async function configurationGeneratorInternal(tree, options) {
17
+ const nxJson = (0, devkit_1.readNxJson)(tree);
18
+ options.addPlugin ??=
19
+ process.env.NX_ADD_PLUGINS !== 'false' &&
20
+ nxJson.useInferencePlugins !== false;
9
21
  const tasks = [];
10
- tasks.push(await (0, init_1.default)(tree, {
22
+ tasks.push(await (0, init_1.initGenerator)(tree, {
11
23
  skipFormat: true,
12
24
  skipPackageJson: options.skipPackageJson,
25
+ addPlugin: options.addPlugin,
13
26
  }));
14
27
  const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
28
+ const hasTsConfig = tree.exists((0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json'));
29
+ const offsetFromProjectRoot = (0, devkit_1.offsetFromRoot)(projectConfig.root);
15
30
  (0, devkit_1.generateFiles)(tree, path.join(__dirname, 'files'), projectConfig.root, {
16
- offsetFromRoot: (0, devkit_1.offsetFromRoot)(projectConfig.root),
31
+ offsetFromRoot: offsetFromProjectRoot,
17
32
  projectRoot: projectConfig.root,
18
33
  webServerCommand: options.webServerCommand ?? null,
19
34
  webServerAddress: options.webServerAddress ?? null,
20
35
  ...options,
21
36
  });
22
- addE2eTarget(tree, options);
23
- setupE2ETargetDefaults(tree);
37
+ if (!hasTsConfig) {
38
+ tree.write(`${projectConfig.root}/tsconfig.json`, JSON.stringify({
39
+ extends: (0, js_1.getRelativePathToRootTsConfig)(tree, projectConfig.root),
40
+ compilerOptions: {
41
+ allowJs: true,
42
+ outDir: `${offsetFromProjectRoot}dist/out-tsc`,
43
+ module: 'commonjs',
44
+ sourceMap: false,
45
+ },
46
+ include: [
47
+ '**/*.ts',
48
+ '**/*.js',
49
+ 'playwright.config.ts',
50
+ 'src/**/*.spec.ts',
51
+ 'src/**/*.spec.js',
52
+ 'src/**/*.test.ts',
53
+ 'src/**/*.test.js',
54
+ 'src/**/*.d.ts',
55
+ ],
56
+ }, null, 2));
57
+ }
58
+ const hasPlugin = (0, devkit_1.readNxJson)(tree).plugins?.some((p) => typeof p === 'string'
59
+ ? p === '@nx/playwright/plugin'
60
+ : p.plugin === '@nx/playwright/plugin');
61
+ if (!hasPlugin) {
62
+ addE2eTarget(tree, options);
63
+ setupE2ETargetDefaults(tree);
64
+ }
24
65
  tasks.push(await (0, add_linter_1.addLinterToPlaywrightProject)(tree, {
25
66
  project: options.project,
26
67
  linter: options.linter,
@@ -29,16 +70,54 @@ async function configurationGenerator(tree, options) {
29
70
  directory: options.directory,
30
71
  setParserOptionsProject: options.setParserOptionsProject,
31
72
  rootProject: options.rootProject ?? projectConfig.root === '.',
73
+ addPlugin: options.addPlugin,
32
74
  }));
33
75
  if (options.js) {
34
- (0, devkit_1.toJS)(tree);
76
+ const { ModuleKind } = (0, devkit_1.ensurePackage)('typescript', versions_1.typescriptVersion);
77
+ (0, devkit_1.toJS)(tree, { extension: '.cjs', module: ModuleKind.CommonJS });
78
+ }
79
+ recommendVsCodeExtensions(tree);
80
+ if (!options.skipPackageJson) {
81
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
82
+ // required since used in playwright config
83
+ '@nx/devkit': versions_2.nxVersion,
84
+ }));
85
+ }
86
+ if (!options.skipInstall) {
87
+ tasks.push(getBrowsersInstallTask());
35
88
  }
36
89
  if (!options.skipFormat) {
37
90
  await (0, devkit_1.formatFiles)(tree);
38
91
  }
39
92
  return (0, devkit_1.runTasksInSerial)(...tasks);
40
93
  }
41
- exports.configurationGenerator = configurationGenerator;
94
+ exports.configurationGeneratorInternal = configurationGeneratorInternal;
95
+ function getBrowsersInstallTask() {
96
+ return () => {
97
+ devkit_1.output.log({
98
+ title: 'Ensuring Playwright is installed.',
99
+ bodyLines: ['use --skipInstall to skip installation.'],
100
+ });
101
+ const pmc = (0, devkit_1.getPackageManagerCommand)();
102
+ (0, child_process_1.execSync)(`${pmc.exec} playwright install`, { cwd: devkit_1.workspaceRoot });
103
+ };
104
+ }
105
+ function recommendVsCodeExtensions(tree) {
106
+ if (tree.exists('.vscode/extensions.json')) {
107
+ (0, devkit_1.updateJson)(tree, '.vscode/extensions.json', (json) => {
108
+ json.recommendations ??= [];
109
+ const recs = new Set(json.recommendations);
110
+ recs.add('ms-playwright.playwright');
111
+ json.recommendations = Array.from(recs);
112
+ return json;
113
+ });
114
+ }
115
+ else {
116
+ (0, devkit_1.writeJson)(tree, '.vscode/extensions.json', {
117
+ recommendations: ['ms-playwright.playwright'],
118
+ });
119
+ }
120
+ }
42
121
  function setupE2ETargetDefaults(tree) {
43
122
  const nxJson = (0, devkit_1.readNxJson)(tree);
44
123
  if (!nxJson.namedInputs) {
@@ -48,6 +127,7 @@ function setupE2ETargetDefaults(tree) {
48
127
  nxJson.targetDefaults ??= {};
49
128
  const productionFileSet = !!nxJson.namedInputs?.production;
50
129
  nxJson.targetDefaults.e2e ??= {};
130
+ nxJson.targetDefaults.e2e.cache ??= true;
51
131
  nxJson.targetDefaults.e2e.inputs ??= [
52
132
  'default',
53
133
  productionFileSet ? '^production' : '^default',
@@ -65,7 +145,7 @@ Rename or remove the existing e2e target.`);
65
145
  executor: '@nx/playwright:playwright',
66
146
  outputs: [`{workspaceRoot}/dist/.playwright/${projectConfig.root}`],
67
147
  options: {
68
- config: `${projectConfig.root}/playwright.config.${options.js ? 'js' : 'ts'}`,
148
+ config: `${projectConfig.root}/playwright.config.${options.js ? 'cjs' : 'ts'}`,
69
149
  },
70
150
  };
71
151
  (0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
@@ -1,4 +1,4 @@
1
- import { defineConfig } from '@playwright/test';
1
+ import { defineConfig, devices } from '@playwright/test';
2
2
  import { nxE2EPreset } from '@nx/playwright/preset';
3
3
  <% if(!webServerCommand || !webServerAddress) { %>// eslint-disable-next-line @typescript-eslint/no-unused-vars <% } %>
4
4
  import { workspaceRoot } from '@nx/devkit';
@@ -29,10 +29,47 @@ export default defineConfig({
29
29
  url: '<%= webServerAddress %>',
30
30
  reuseExistingServer: !process.env.CI,
31
31
  cwd: workspaceRoot
32
- },<% } else {%>// webServer: {
32
+ },<% } else {%>
33
+ // webServer: {
33
34
  // command: 'npm run start',
34
35
  // url: 'http://127.0.0.1:3000',
35
36
  // reuseExistingServer: !process.env.CI,
36
37
  // cwd: workspaceRoot,
37
38
  // },<% } %>
39
+ projects: [
40
+ {
41
+ name: "chromium",
42
+ use: { ...devices["Desktop Chrome"] },
43
+ },
44
+
45
+ {
46
+ name: "firefox",
47
+ use: { ...devices["Desktop Firefox"] },
48
+ },
49
+
50
+ {
51
+ name: "webkit",
52
+ use: { ...devices["Desktop Safari"] },
53
+ },
54
+
55
+ // Uncomment for mobile browsers support
56
+ /* {
57
+ name: 'Mobile Chrome',
58
+ use: { ...devices['Pixel 5'] },
59
+ },
60
+ {
61
+ name: 'Mobile Safari',
62
+ use: { ...devices['iPhone 12'] },
63
+ }, */
64
+
65
+ // Uncomment for branded browsers
66
+ /* {
67
+ name: 'Microsoft Edge',
68
+ use: { ...devices['Desktop Edge'], channel: 'msedge' },
69
+ },
70
+ {
71
+ name: 'Google Chrome',
72
+ use: { ...devices['Desktop Chrome'], channel: 'chrome' },
73
+ } */
74
+ ],
38
75
  });
@@ -9,6 +9,7 @@ export interface ConfigurationGeneratorSchema {
9
9
  js: boolean; // default is false
10
10
  skipFormat: boolean;
11
11
  skipPackageJson: boolean;
12
+ skipInstall?: boolean;
12
13
  linter: Linter;
13
14
  setParserOptionsProject: boolean; // default is false
14
15
  /**
@@ -22,4 +23,5 @@ export interface ConfigurationGeneratorSchema {
22
23
  **/
23
24
  webServerAddress?: string;
24
25
  rootProject?: boolean;
26
+ addPlugin?: boolean;
25
27
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "$id": "NxPlaywrightConfiguration",
4
4
  "description": "Add a Playwright configuration.",
5
5
  "title": "Add a Playwright configuration",
@@ -62,6 +62,11 @@
62
62
  "default": false,
63
63
  "hidden": true,
64
64
  "x-priority": "internal"
65
+ },
66
+ "skipInstall": {
67
+ "type": "boolean",
68
+ "description": "Skip running `playwright install`. This is to ensure that playwright browsers are installed.",
69
+ "default": false
65
70
  }
66
71
  },
67
72
  "required": ["project"]
@@ -1,4 +1,5 @@
1
1
  import { GeneratorCallback, Tree } from '@nx/devkit';
2
2
  import { InitGeneratorSchema } from './schema';
3
3
  export declare function initGenerator(tree: Tree, options: InitGeneratorSchema): Promise<GeneratorCallback>;
4
+ export declare function initGeneratorInternal(tree: Tree, options: InitGeneratorSchema): Promise<GeneratorCallback>;
4
5
  export default initGenerator;
@@ -1,47 +1,51 @@
1
1
  "use strict";
2
2
  Object.defineProperty(exports, "__esModule", { value: true });
3
- exports.initGenerator = void 0;
3
+ exports.initGeneratorInternal = exports.initGenerator = void 0;
4
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");
5
7
  const versions_1 = require("../../utils/versions");
6
- const child_process_1 = require("child_process");
7
- async function initGenerator(tree, options) {
8
+ function initGenerator(tree, options) {
9
+ return initGeneratorInternal(tree, { addPlugin: false, ...options });
10
+ }
11
+ exports.initGenerator = initGenerator;
12
+ async function initGeneratorInternal(tree, options) {
8
13
  const tasks = [];
14
+ const nxJson = (0, devkit_1.readNxJson)(tree);
15
+ const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
16
+ nxJson.useInferencePlugins !== false;
17
+ options.addPlugin ??= addPluginDefault;
9
18
  if (!options.skipPackageJson) {
10
19
  tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
11
20
  '@nx/playwright': versions_1.nxVersion,
12
- // required since used in playwright config
13
- '@nx/devkit': versions_1.nxVersion,
14
21
  '@playwright/test': versions_1.playwrightVersion,
15
- }));
22
+ }, undefined, options.keepExistingVersions));
16
23
  }
17
- if (!options.skipFormat) {
18
- await (0, devkit_1.formatFiles)(tree);
24
+ if (options.addPlugin) {
25
+ addPlugin(tree);
19
26
  }
20
- if (tree.exists('.vscode/extensions.json')) {
21
- (0, devkit_1.updateJson)(tree, '.vscode/extensions.json', (json) => {
22
- json.recommendations ??= [];
23
- const recs = new Set(json.recommendations);
24
- recs.add('ms-playwright.playwright');
25
- json.recommendations = Array.from(recs);
26
- return json;
27
- });
27
+ if (options.updatePackageScripts) {
28
+ await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
28
29
  }
29
- else {
30
- tree.write('.vscode/extensions.json', JSON.stringify({
31
- recommendations: ['ms-playwright.playwright'],
32
- }, null, 2));
30
+ if (!options.skipFormat) {
31
+ await (0, devkit_1.formatFiles)(tree);
33
32
  }
34
- if (!options.skipInstall) {
35
- tasks.push(() => {
36
- devkit_1.output.log({
37
- title: 'Ensuring Playwright is installed.',
38
- bodyLines: ['use --skipInstall to skip installation.'],
39
- });
40
- const pmc = (0, devkit_1.getPackageManagerCommand)();
41
- (0, child_process_1.execSync)(`${pmc.exec} playwright install`, { cwd: devkit_1.workspaceRoot });
33
+ return (0, devkit_1.runTasksInSerial)(...tasks);
34
+ }
35
+ exports.initGeneratorInternal = initGeneratorInternal;
36
+ function addPlugin(tree) {
37
+ const nxJson = (0, devkit_1.readNxJson)(tree);
38
+ nxJson.plugins ??= [];
39
+ if (!nxJson.plugins.some((p) => typeof p === 'string'
40
+ ? p === '@nx/playwright/plugin'
41
+ : p.plugin === '@nx/playwright/plugin')) {
42
+ nxJson.plugins.push({
43
+ plugin: '@nx/playwright/plugin',
44
+ options: {
45
+ targetName: 'e2e',
46
+ },
42
47
  });
48
+ (0, devkit_1.updateNxJson)(tree, nxJson);
43
49
  }
44
- return (0, devkit_1.runTasksInSerial)(...tasks);
45
50
  }
46
- exports.initGenerator = initGenerator;
47
51
  exports.default = initGenerator;
@@ -1,5 +1,7 @@
1
1
  export interface InitGeneratorSchema {
2
- skipFormat: boolean;
3
- skipPackageJson: boolean;
4
- skipInstall?: boolean;
2
+ skipFormat?: boolean;
3
+ skipPackageJson?: boolean;
4
+ keepExistingVersions?: boolean;
5
+ updatePackageScripts?: boolean;
6
+ addPlugin?: boolean;
5
7
  }
@@ -1,5 +1,5 @@
1
1
  {
2
- "$schema": "http://json-schema.org/schema",
2
+ "$schema": "https://json-schema.org/schema",
3
3
  "$id": "NxPlaywrightInit",
4
4
  "title": "Playwright Init Generator",
5
5
  "description": "Initializes a Playwright project in the current workspace.",
@@ -17,9 +17,16 @@
17
17
  "description": "Do not add dependencies to `package.json`.",
18
18
  "x-priority": "internal"
19
19
  },
20
- "skipInstall": {
20
+ "keepExistingVersions": {
21
21
  "type": "boolean",
22
- "description": "Skip running `playwright install`. This is to ensure that playwright browsers are installed.",
22
+ "x-priority": "internal",
23
+ "description": "Keep existing dependencies versions",
24
+ "default": false
25
+ },
26
+ "updatePackageScripts": {
27
+ "type": "boolean",
28
+ "x-priority": "internal",
29
+ "description": "Update `package.json` scripts with inferred targets",
23
30
  "default": false
24
31
  }
25
32
  },
@@ -0,0 +1,2 @@
1
+ import { Tree } from '@nx/devkit';
2
+ export default function update(tree: Tree): Promise<void>;
@@ -0,0 +1,95 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const ts = require("typescript");
5
+ const tsquery_1 = require("@phenomnomnominal/tsquery");
6
+ async function update(tree) {
7
+ const projects = (0, devkit_1.getProjects)(tree);
8
+ projects.forEach((project) => {
9
+ // Check if the project contains playwright config
10
+ const configPath = (0, devkit_1.joinPathFragments)(project.root, 'playwright.config.ts');
11
+ if (tree.exists(configPath)) {
12
+ addProjectIfExists(tree, (0, devkit_1.joinPathFragments)(configPath));
13
+ }
14
+ });
15
+ }
16
+ exports.default = update;
17
+ function addProjectIfExists(tree, configFilePath) {
18
+ const configFileContent = tree.read(configFilePath, 'utf-8');
19
+ const sourceFile = tsquery_1.tsquery.ast(configFileContent);
20
+ const printer = ts.createPrinter();
21
+ const updatedStatements = updateOrCreateImportStatement(sourceFile, '@playwright/test', ['devices']);
22
+ const exportAssignment = tsquery_1.tsquery.query(sourceFile, 'ExportAssignment')[0];
23
+ if (!exportAssignment) {
24
+ // No export found in the file
25
+ return;
26
+ }
27
+ const exportAssignemntObject = exportAssignment.expression;
28
+ if (!(ts.isCallExpression(exportAssignemntObject) &&
29
+ exportAssignemntObject.getText(sourceFile).startsWith('defineConfig') &&
30
+ exportAssignemntObject.arguments.length > 0)) {
31
+ // Export is not a call expression with defineConfig ex. export default defineConfig({ ... })
32
+ return;
33
+ }
34
+ let firstArgument = exportAssignemntObject.arguments[0];
35
+ if (!ts.isObjectLiteralExpression(firstArgument)) {
36
+ // First argument is not an object literal ex. defineConfig('foo')
37
+ return;
38
+ }
39
+ const projectProperty = tsquery_1.tsquery.query(exportAssignemntObject, 'PropertyAssignment > Identifier[name="projects"]')[0];
40
+ if (projectProperty) {
41
+ // Projects property already exists in the config
42
+ return;
43
+ }
44
+ // Add projects property to the config
45
+ const projectsArray = ts.factory.createArrayLiteralExpression([
46
+ createProperty('chromium', 'Desktop Chrome'),
47
+ createProperty('firefox', 'Desktop Firefox'),
48
+ createProperty('webkit', 'Desktop Safari'),
49
+ ], true);
50
+ const newProjectsProperty = ts.factory.createPropertyAssignment('projects', projectsArray);
51
+ const newObj = ts.factory.createObjectLiteralExpression([
52
+ ...firstArgument.properties,
53
+ newProjectsProperty,
54
+ ]);
55
+ const newCallExpression = ts.factory.updateCallExpression(exportAssignemntObject, exportAssignemntObject.expression, exportAssignemntObject.typeArguments, [newObj]);
56
+ const newExportAssignment = ts.factory.updateExportAssignment(exportAssignment, exportAssignment.modifiers, newCallExpression);
57
+ const transformedStatements = updatedStatements.map((statement) => {
58
+ return statement === exportAssignment ? newExportAssignment : statement;
59
+ });
60
+ const transformedSourceFile = ts.factory.updateSourceFile(sourceFile, transformedStatements);
61
+ const updatedConfigFileContent = printer.printFile(transformedSourceFile);
62
+ tree.write(configFilePath, updatedConfigFileContent);
63
+ }
64
+ function createProperty(name, device) {
65
+ return ts.factory.createObjectLiteralExpression([
66
+ ts.factory.createPropertyAssignment('name', ts.factory.createStringLiteral(name)),
67
+ ts.factory.createPropertyAssignment('use', ts.factory.createObjectLiteralExpression([
68
+ ts.factory.createSpreadAssignment(ts.factory.createElementAccessExpression(ts.factory.createIdentifier('devices'), ts.factory.createStringLiteral(device))),
69
+ ])),
70
+ ]);
71
+ }
72
+ function updateOrCreateImportStatement(sourceFile, moduleName, importNames) {
73
+ let importDeclarationFound = false;
74
+ const newStatements = sourceFile.statements.map((statement) => {
75
+ if (ts.isImportDeclaration(statement) &&
76
+ statement.moduleSpecifier.getText(sourceFile) === `'${moduleName}'`) {
77
+ importDeclarationFound = true;
78
+ const existingSpecifiers = statement.importClause?.namedBindings &&
79
+ ts.isNamedImports(statement.importClause.namedBindings)
80
+ ? statement.importClause.namedBindings.elements.map((e) => e.name.text)
81
+ : [];
82
+ // Merge with new import names, avoiding duplicates
83
+ const mergedImportNames = Array.from(new Set([...existingSpecifiers, ...importNames]));
84
+ // Create new import specifiers
85
+ const importSpecifiers = mergedImportNames.map((name) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(name)));
86
+ return ts.factory.updateImportDeclaration(statement, statement.modifiers, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(importSpecifiers)), statement.moduleSpecifier, undefined);
87
+ }
88
+ return statement;
89
+ });
90
+ if (!importDeclarationFound) {
91
+ const importDeclaration = ts.factory.createImportDeclaration(undefined, ts.factory.createImportClause(false, undefined, ts.factory.createNamedImports(importNames.map((name) => ts.factory.createImportSpecifier(false, undefined, ts.factory.createIdentifier(name))))), ts.factory.createStringLiteral(moduleName));
92
+ newStatements.push(importDeclaration);
93
+ }
94
+ return newStatements;
95
+ }
@@ -0,0 +1,2 @@
1
+ import { type 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
+ (0, executor_options_utils_1.forEachExecutorOptions)(tree, '@nx/playwright:playwright', (options, projectName, targetName, configurationName) => {
7
+ if (options?.['baseUrl']) {
8
+ const project = (0, devkit_1.readProjectConfiguration)(tree, projectName);
9
+ if (configurationName) {
10
+ delete project.targets[targetName].configurations[configurationName]['baseUrl'];
11
+ }
12
+ else {
13
+ delete project.targets[targetName].options['baseUrl'];
14
+ }
15
+ (0, devkit_1.updateProjectConfiguration)(tree, projectName, project);
16
+ }
17
+ });
18
+ const nxJson = (0, devkit_1.readNxJson)(tree);
19
+ for (const [targetNameOrExecutor, target] of Object.entries(nxJson.targetDefaults)) {
20
+ if (targetNameOrExecutor === '@nx/playwright:playwright' ||
21
+ (target.executor && target.executor === '@nx/playwright:playwright')) {
22
+ let updated = false;
23
+ if (target.options?.['baseUrl']) {
24
+ delete nxJson.targetDefaults[targetNameOrExecutor].options['baseUrl'];
25
+ updated = true;
26
+ }
27
+ if (target.configurations) {
28
+ for (const [configurationName, configuration] of Object.entries(target.configurations)) {
29
+ if (configuration['baseUrl']) {
30
+ delete nxJson.targetDefaults[targetNameOrExecutor].configurations[configurationName]['baseUrl'];
31
+ updated = true;
32
+ }
33
+ }
34
+ }
35
+ if (updated) {
36
+ (0, devkit_1.updateNxJson)(tree, nxJson);
37
+ }
38
+ }
39
+ }
40
+ await (0, devkit_1.formatFiles)(tree);
41
+ }
42
+ exports.default = default_1;
@@ -0,0 +1,7 @@
1
+ import { CreateDependencies, CreateNodes } from '@nx/devkit';
2
+ export interface PlaywrightPluginOptions {
3
+ targetName?: string;
4
+ ciTargetName?: string;
5
+ }
6
+ export declare const createDependencies: CreateDependencies;
7
+ export declare const createNodes: CreateNodes<PlaywrightPluginOptions>;
@@ -0,0 +1,205 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.createNodes = exports.createDependencies = void 0;
4
+ const fs_1 = require("fs");
5
+ const path_1 = require("path");
6
+ const devkit_1 = require("@nx/devkit");
7
+ const get_named_inputs_1 = require("@nx/devkit/src/utils/get-named-inputs");
8
+ const calculate_hash_for_create_nodes_1 = require("@nx/devkit/src/utils/calculate-hash-for-create-nodes");
9
+ const workspace_context_1 = require("nx/src/utils/workspace-context");
10
+ const minimatch_1 = require("minimatch");
11
+ const cache_directory_1 = require("nx/src/utils/cache-directory");
12
+ const js_1 = require("@nx/js");
13
+ const config_utils_1 = require("@nx/devkit/src/utils/config-utils");
14
+ const cachePath = (0, path_1.join)(cache_directory_1.projectGraphCacheDirectory, 'playwright.hash');
15
+ const targetsCache = (0, fs_1.existsSync)(cachePath) ? readTargetsCache() : {};
16
+ const calculatedTargets = {};
17
+ function readTargetsCache() {
18
+ return (0, devkit_1.readJsonFile)(cachePath);
19
+ }
20
+ function writeTargetsToCache(targets) {
21
+ (0, devkit_1.writeJsonFile)(cachePath, targets);
22
+ }
23
+ const createDependencies = () => {
24
+ writeTargetsToCache(calculatedTargets);
25
+ return [];
26
+ };
27
+ exports.createDependencies = createDependencies;
28
+ exports.createNodes = [
29
+ '**/playwright.config.{js,ts,cjs,cts,mjs,mts}',
30
+ async (configFilePath, options, context) => {
31
+ const projectRoot = (0, path_1.dirname)(configFilePath);
32
+ // Do not create a project if package.json and project.json isn't there.
33
+ const siblingFiles = (0, fs_1.readdirSync)((0, path_1.join)(context.workspaceRoot, projectRoot));
34
+ if (!siblingFiles.includes('package.json') &&
35
+ !siblingFiles.includes('project.json')) {
36
+ return {};
37
+ }
38
+ const normalizedOptions = normalizeOptions(options);
39
+ const hash = (0, calculate_hash_for_create_nodes_1.calculateHashForCreateNodes)(projectRoot, options, context, [
40
+ (0, js_1.getLockFileName)((0, devkit_1.detectPackageManager)(context.workspaceRoot)),
41
+ ]);
42
+ const targets = targetsCache[hash] ??
43
+ (await buildPlaywrightTargets(configFilePath, projectRoot, normalizedOptions, context));
44
+ calculatedTargets[hash] = targets;
45
+ return {
46
+ projects: {
47
+ [projectRoot]: {
48
+ root: projectRoot,
49
+ targets,
50
+ },
51
+ },
52
+ };
53
+ },
54
+ ];
55
+ async function buildPlaywrightTargets(configFilePath, projectRoot, options, context) {
56
+ // Playwright forbids importing the `@playwright/test` module twice. This would affect running the tests,
57
+ // but we're just reading the config so let's delete the variable they are using to detect this.
58
+ // See: https://github.com/microsoft/playwright/pull/11218/files
59
+ delete process['__pw_initiator__'];
60
+ const playwrightConfig = await (0, config_utils_1.loadConfigFile)((0, path_1.join)(context.workspaceRoot, configFilePath));
61
+ const namedInputs = (0, get_named_inputs_1.getNamedInputs)(projectRoot, context);
62
+ const targets = {};
63
+ const baseTargetConfig = {
64
+ command: 'playwright test',
65
+ options: {
66
+ cwd: '{projectRoot}',
67
+ },
68
+ };
69
+ targets[options.targetName] = {
70
+ ...baseTargetConfig,
71
+ cache: true,
72
+ inputs: 'production' in namedInputs
73
+ ? ['default', '^production']
74
+ : ['default', '^default'],
75
+ outputs: getOutputs(projectRoot, playwrightConfig),
76
+ };
77
+ if (options.ciTargetName) {
78
+ const ciBaseTargetConfig = {
79
+ ...baseTargetConfig,
80
+ cache: true,
81
+ inputs: 'production' in namedInputs
82
+ ? ['default', '^production']
83
+ : ['default', '^default'],
84
+ outputs: getOutputs(projectRoot, playwrightConfig),
85
+ };
86
+ const testDir = playwrightConfig.testDir
87
+ ? (0, devkit_1.joinPathFragments)(projectRoot, playwrightConfig.testDir)
88
+ : projectRoot;
89
+ // Playwright defaults to the following pattern.
90
+ playwrightConfig.testMatch ??= '**/*.@(spec|test).?(c|m)[jt]s?(x)';
91
+ const dependsOn = [];
92
+ forEachTestFile((testFile) => {
93
+ const relativeToProjectRoot = (0, devkit_1.normalizePath)((0, path_1.relative)(projectRoot, testFile));
94
+ const targetName = `${options.ciTargetName}--${relativeToProjectRoot}`;
95
+ targets[targetName] = {
96
+ ...ciBaseTargetConfig,
97
+ command: `${baseTargetConfig.command} ${relativeToProjectRoot}`,
98
+ };
99
+ dependsOn.push({
100
+ target: targetName,
101
+ projects: 'self',
102
+ params: 'forward',
103
+ });
104
+ }, {
105
+ context,
106
+ path: testDir,
107
+ config: playwrightConfig,
108
+ });
109
+ targets[options.ciTargetName] ??= {};
110
+ targets[options.ciTargetName] = {
111
+ executor: 'nx:noop',
112
+ cache: ciBaseTargetConfig.cache,
113
+ inputs: ciBaseTargetConfig.inputs,
114
+ outputs: ciBaseTargetConfig.outputs,
115
+ dependsOn,
116
+ };
117
+ }
118
+ return targets;
119
+ }
120
+ async function forEachTestFile(cb, opts) {
121
+ const files = (0, workspace_context_1.getFilesInDirectoryUsingContext)(opts.context.workspaceRoot, opts.path);
122
+ const matcher = createMatcher(opts.config.testMatch);
123
+ const ignoredMatcher = opts.config.testIgnore
124
+ ? createMatcher(opts.config.testIgnore)
125
+ : () => false;
126
+ for (const file of files) {
127
+ if (matcher(file) && !ignoredMatcher(file)) {
128
+ cb(file);
129
+ }
130
+ }
131
+ }
132
+ function createMatcher(pattern) {
133
+ if (Array.isArray(pattern)) {
134
+ const matchers = pattern.map((p) => createMatcher(p));
135
+ return (path) => matchers.some((m) => m(path));
136
+ }
137
+ else if (pattern instanceof RegExp) {
138
+ return (path) => pattern.test(path);
139
+ }
140
+ else {
141
+ return (path) => {
142
+ try {
143
+ return (0, minimatch_1.minimatch)(path, pattern);
144
+ }
145
+ catch (e) {
146
+ throw new Error(`Error matching ${path} with ${pattern}: ${e.message}`);
147
+ }
148
+ };
149
+ }
150
+ }
151
+ function getOutputs(projectRoot, playwrightConfig) {
152
+ function getOutput(path) {
153
+ if (path.startsWith('..')) {
154
+ return (0, path_1.join)('{workspaceRoot}', (0, path_1.join)(projectRoot, path));
155
+ }
156
+ else {
157
+ return (0, path_1.join)('{projectRoot}', path);
158
+ }
159
+ }
160
+ const outputs = [];
161
+ const { reporter, outputDir } = playwrightConfig;
162
+ if (reporter) {
163
+ const DEFAULT_REPORTER_OUTPUT = getOutput('playwright-report');
164
+ if (reporter === 'html' || reporter === 'json') {
165
+ // Reporter is a string, so it uses the default output directory.
166
+ outputs.push(DEFAULT_REPORTER_OUTPUT);
167
+ }
168
+ else if (Array.isArray(reporter)) {
169
+ for (const r of reporter) {
170
+ const [, opts] = r;
171
+ // There are a few different ways to specify an output file or directory
172
+ // depending on the reporter. This is a best effort to find the output.
173
+ if (!opts) {
174
+ outputs.push(DEFAULT_REPORTER_OUTPUT);
175
+ }
176
+ else if (opts.outputFile) {
177
+ outputs.push(getOutput(opts.outputFile));
178
+ }
179
+ else if (opts.outputDir) {
180
+ outputs.push(getOutput(opts.outputDir));
181
+ }
182
+ else if (opts.outputFolder) {
183
+ outputs.push(getOutput(opts.outputFolder));
184
+ }
185
+ else {
186
+ outputs.push(DEFAULT_REPORTER_OUTPUT);
187
+ }
188
+ }
189
+ }
190
+ }
191
+ if (outputDir) {
192
+ outputs.push(getOutput(outputDir));
193
+ }
194
+ else {
195
+ outputs.push(getOutput('./test-results'));
196
+ }
197
+ return outputs;
198
+ }
199
+ function normalizeOptions(options) {
200
+ return {
201
+ ...options,
202
+ targetName: options.targetName ?? 'e2e',
203
+ ciTargetName: options.ciTargetName ?? 'e2e-ci',
204
+ };
205
+ }
@@ -11,5 +11,6 @@ export interface PlaywrightLinterOptions {
11
11
  * Directory from the project root, where the playwright files will be located.
12
12
  **/
13
13
  directory: string;
14
+ addPlugin?: boolean;
14
15
  }
15
16
  export declare function addLinterToPlaywrightProject(tree: Tree, options: PlaywrightLinterOptions): Promise<GeneratorCallback>;
@@ -19,12 +19,10 @@ async function addLinterToPlaywrightProject(tree, options) {
19
19
  linter: options.linter,
20
20
  skipFormat: true,
21
21
  tsConfigPaths: [(0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json')],
22
- eslintFilePatterns: [
23
- `${projectConfig.root}/**/*.${options.js ? 'js' : '{js,ts}'}`,
24
- ],
25
22
  setParserOptionsProject: options.setParserOptionsProject,
26
23
  skipPackageJson: options.skipPackageJson,
27
24
  rootProject: options.rootProject,
25
+ addPlugin: options.addPlugin,
28
26
  }));
29
27
  }
30
28
  if (!options.linter || options.linter !== eslint_1.Linter.EsLint) {
@@ -4,16 +4,6 @@ export interface NxPlaywrightOptions {
4
4
  * @default './src'
5
5
  **/
6
6
  testDir?: string;
7
- /**
8
- * Include Mobile Chome and Mobile Safari browsers in test projects
9
- * @default false
10
- **/
11
- includeMobileBrowsers?: boolean;
12
- /**
13
- * Include Microsoft Edge and Google Chrome browsers in test projects
14
- * @default false
15
- **/
16
- includeBrandedBrowsers?: boolean;
17
7
  }
18
8
  /**
19
9
  * nx E2E Preset for Playwright
@@ -25,6 +15,7 @@ export interface NxPlaywrightOptions {
25
15
  * - chromium
26
16
  * - firefox
27
17
  * - webkit
18
+ * These are generated by default.
28
19
  *
29
20
  * you can easily extend this within your playwright config via spreading the preset
30
21
  * @example
@@ -15,6 +15,7 @@ const test_1 = require("@playwright/test");
15
15
  * - chromium
16
16
  * - firefox
17
17
  * - webkit
18
+ * These are generated by default.
18
19
  *
19
20
  * you can easily extend this within your playwright config via spreading the preset
20
21
  * @example
@@ -34,44 +35,6 @@ function nxE2EPreset(pathToConfig, options) {
34
35
  const offset = (0, node_path_1.relative)(normalizedPath, devkit_1.workspaceRoot);
35
36
  const testResultOuputDir = (0, node_path_1.join)(offset, 'dist', '.playwright', projectPath, 'test-output');
36
37
  const reporterOutputDir = (0, node_path_1.join)(offset, 'dist', '.playwright', projectPath, 'playwright-report');
37
- const projects = [
38
- {
39
- name: 'chromium',
40
- use: { ...test_1.devices['Desktop Chrome'] },
41
- },
42
- {
43
- name: 'firefox',
44
- use: { ...test_1.devices['Desktop Firefox'] },
45
- },
46
- {
47
- name: 'webkit',
48
- use: { ...test_1.devices['Desktop Safari'] },
49
- },
50
- ];
51
- if (options?.includeMobileBrowsers) {
52
- projects.push(...[
53
- {
54
- name: 'Mobile Chrome',
55
- use: { ...test_1.devices['Pixel 5'] },
56
- },
57
- {
58
- name: 'Mobile Safari',
59
- use: { ...test_1.devices['iPhone 12'] },
60
- },
61
- ]);
62
- }
63
- if (options?.includeBrandedBrowsers) {
64
- projects.push(...[
65
- {
66
- name: 'Microsoft Edge',
67
- use: { ...test_1.devices['Desktop Edge'], channel: 'msedge' },
68
- },
69
- {
70
- name: 'Google Chrome',
71
- use: { ...test_1.devices['Desktop Chrome'], channel: 'chrome' },
72
- },
73
- ]);
74
- }
75
38
  return (0, test_1.defineConfig)({
76
39
  testDir: options?.testDir ?? './src',
77
40
  outputDir: testResultOuputDir,
@@ -92,7 +55,6 @@ function nxE2EPreset(pathToConfig, options) {
92
55
  },
93
56
  ],
94
57
  ],
95
- projects,
96
58
  });
97
59
  }
98
60
  exports.nxE2EPreset = nxE2EPreset;