@nx/playwright 17.0.4 → 17.0.6
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/LICENSE +1 -1
- package/README.md +4 -9
- package/executors.json +1 -1
- package/generators.json +2 -2
- package/index.d.ts +1 -1
- package/index.js +2 -2
- package/package.json +4 -11
- package/src/executors/playwright/{playwright.impl.d.ts → playwright.d.ts} +1 -2
- package/src/executors/playwright/{playwright.impl.js → playwright.js} +2 -6
- package/src/executors/playwright/schema.json +2 -10
- package/src/generators/configuration/configuration.d.ts +0 -1
- package/src/generators/configuration/configuration.js +10 -90
- package/src/generators/configuration/files/playwright.config.ts.template +2 -39
- package/src/generators/configuration/schema.d.ts +0 -2
- package/src/generators/configuration/schema.json +1 -6
- package/src/generators/init/init.d.ts +0 -1
- package/src/generators/init/init.js +30 -34
- package/src/generators/init/schema.d.ts +3 -5
- package/src/generators/init/schema.json +3 -10
- package/src/utils/add-linter.d.ts +0 -1
- package/src/utils/add-linter.js +3 -1
- package/src/utils/preset.d.ts +10 -1
- package/src/utils/preset.js +39 -1
- package/migrations.json +0 -16
- package/plugin.d.ts +0 -1
- package/plugin.js +0 -6
- package/src/migrations/update-17-3-1/add-project-to-config.d.ts +0 -2
- package/src/migrations/update-17-3-1/add-project-to-config.js +0 -95
- package/src/migrations/update-18-1-0/remove-baseUrl-from-project-json.d.ts +0 -2
- package/src/migrations/update-18-1-0/remove-baseUrl-from-project-json.js +0 -42
- package/src/plugins/plugin.d.ts +0 -7
- package/src/plugins/plugin.js +0 -205
package/LICENSE
CHANGED
package/README.md
CHANGED
|
@@ -1,9 +1,4 @@
|
|
|
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>
|
|
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>
|
|
7
2
|
|
|
8
3
|
<div style="text-align: center;">
|
|
9
4
|
|
|
@@ -20,9 +15,9 @@
|
|
|
20
15
|
|
|
21
16
|
<hr>
|
|
22
17
|
|
|
23
|
-
# Nx: Smart
|
|
18
|
+
# Nx: Smart, Fast and Extensible Build System
|
|
24
19
|
|
|
25
|
-
Nx is a build system with
|
|
20
|
+
Nx is a next generation build system with first class monorepo support and powerful integrations.
|
|
26
21
|
|
|
27
22
|
## Getting Started
|
|
28
23
|
|
|
@@ -62,5 +57,5 @@ npx nx@latest init
|
|
|
62
57
|
- [Blog Posts About Nx](https://blog.nrwl.io/nx/home)
|
|
63
58
|
|
|
64
59
|
<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"
|
|
65
|
-
width="100%" alt="Nx - Smart
|
|
60
|
+
width="100%" alt="Nx - Smart, Fast and Extensible Build System"></a></p>
|
|
66
61
|
|
package/executors.json
CHANGED
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",
|
|
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",
|
|
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';
|
|
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
|
|
5
|
-
Object.defineProperty(exports, "playwrightExecutor", { enumerable: true, get: function () { return
|
|
4
|
+
var playwright_1 = require("./src/executors/playwright/playwright");
|
|
5
|
+
Object.defineProperty(exports, "playwrightExecutor", { enumerable: true, get: function () { return playwright_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");
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/playwright",
|
|
3
|
-
"version": "
|
|
3
|
+
"version": "v17.0.6",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"homepage": "https://nx.dev",
|
|
6
6
|
"private": false,
|
|
@@ -32,12 +32,9 @@
|
|
|
32
32
|
"directory": "packages/playwright"
|
|
33
33
|
},
|
|
34
34
|
"dependencies": {
|
|
35
|
-
"@
|
|
36
|
-
"@nx/
|
|
37
|
-
"
|
|
38
|
-
"@nx/js": "17.0.4",
|
|
39
|
-
"tslib": "^2.3.0",
|
|
40
|
-
"minimatch": "9.0.3"
|
|
35
|
+
"@nx/devkit": "v17.0.6",
|
|
36
|
+
"@nx/eslint": "v17.0.6",
|
|
37
|
+
"tslib": "^2.3.0"
|
|
41
38
|
},
|
|
42
39
|
"peerDependencies": {
|
|
43
40
|
"@playwright/test": "^1.36.0"
|
|
@@ -57,10 +54,6 @@
|
|
|
57
54
|
"./generators/*/schema.json": "./src/generators/*/schema.json",
|
|
58
55
|
"./executors.json": "./executors.json",
|
|
59
56
|
"./executors/*/schema.json": "./src/executors/*/schema.json",
|
|
60
|
-
"./plugin": "./plugin.js",
|
|
61
57
|
"./preset": "./src/utils/preset.js"
|
|
62
|
-
},
|
|
63
|
-
"nx-migrations": {
|
|
64
|
-
"migrations": "./migrations.json"
|
|
65
58
|
}
|
|
66
59
|
}
|
|
@@ -8,7 +8,6 @@ export interface PlaywrightExecutorSchema {
|
|
|
8
8
|
grep?: string;
|
|
9
9
|
globalTimeout?: number;
|
|
10
10
|
grepInvert?: string;
|
|
11
|
-
testFiles?: string[];
|
|
12
11
|
headed?: boolean;
|
|
13
12
|
ignoreSnapshots?: boolean;
|
|
14
13
|
workers?: string;
|
|
@@ -28,7 +27,7 @@ export interface PlaywrightExecutorSchema {
|
|
|
28
27
|
updateSnapshots?: boolean;
|
|
29
28
|
ui?: boolean;
|
|
30
29
|
uiHost?: string;
|
|
31
|
-
uiPort?:
|
|
30
|
+
uiPort?: string;
|
|
32
31
|
skipInstall?: boolean;
|
|
33
32
|
}
|
|
34
33
|
export declare function playwrightExecutor(options: PlaywrightExecutorSchema, context: ExecutorContext): Promise<{
|
|
@@ -36,18 +36,14 @@ async function playwrightExecutor(options, context) {
|
|
|
36
36
|
exports.playwrightExecutor = playwrightExecutor;
|
|
37
37
|
function createArgs(opts, exclude = ['skipInstall']) {
|
|
38
38
|
const args = [];
|
|
39
|
-
const
|
|
40
|
-
if (testFiles) {
|
|
41
|
-
args.push(...testFiles);
|
|
42
|
-
}
|
|
43
|
-
for (const key in rest) {
|
|
39
|
+
for (const key in opts) {
|
|
44
40
|
if (exclude.includes(key))
|
|
45
41
|
continue;
|
|
46
42
|
const value = opts[key];
|
|
47
43
|
// NOTE: playwright doesn't accept pascalCase args, only kebab-case
|
|
48
44
|
const arg = (0, devkit_1.names)(key).fileName;
|
|
49
45
|
if (Array.isArray(value)) {
|
|
50
|
-
args.push(
|
|
46
|
+
args.push(`--${arg}=${value.map((v) => v.trim()).join(',')}`);
|
|
51
47
|
}
|
|
52
48
|
else if (typeof value === 'boolean') {
|
|
53
49
|
// NOTE: playwright don't accept --arg=false, instead just don't pass the arg.
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
3
|
"version": 2,
|
|
4
4
|
"title": "Playwright executor",
|
|
5
5
|
"description": "Run Playwright tests.",
|
|
@@ -43,14 +43,6 @@
|
|
|
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
|
-
},
|
|
54
46
|
"headed": {
|
|
55
47
|
"type": "boolean",
|
|
56
48
|
"description": "Run tests in headed browsers",
|
|
@@ -155,7 +147,7 @@
|
|
|
155
147
|
"description": "Host to serve UI on; specifying this option opens UI in a browser tab"
|
|
156
148
|
},
|
|
157
149
|
"uiPort": {
|
|
158
|
-
"type": "
|
|
150
|
+
"type": "string",
|
|
159
151
|
"description": "Port to serve UI on, 0 for any free port; specifying this option opens UI in a browser tab"
|
|
160
152
|
},
|
|
161
153
|
"skipInstall": {
|
|
@@ -1,5 +1,4 @@
|
|
|
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>;
|
|
5
4
|
export default configurationGenerator;
|
|
@@ -1,67 +1,26 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
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");
|
|
8
5
|
const path = require("path");
|
|
9
|
-
const add_linter_1 = require("../../utils/add-linter");
|
|
10
|
-
const versions_2 = require("../../utils/versions");
|
|
11
6
|
const init_1 = require("../init/init");
|
|
12
|
-
|
|
13
|
-
|
|
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;
|
|
7
|
+
const add_linter_1 = require("../../utils/add-linter");
|
|
8
|
+
async function configurationGenerator(tree, options) {
|
|
21
9
|
const tasks = [];
|
|
22
|
-
tasks.push(await (0, init_1.
|
|
10
|
+
tasks.push(await (0, init_1.default)(tree, {
|
|
23
11
|
skipFormat: true,
|
|
24
12
|
skipPackageJson: options.skipPackageJson,
|
|
25
|
-
addPlugin: options.addPlugin,
|
|
26
13
|
}));
|
|
27
14
|
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);
|
|
30
15
|
(0, devkit_1.generateFiles)(tree, path.join(__dirname, 'files'), projectConfig.root, {
|
|
31
|
-
offsetFromRoot:
|
|
16
|
+
offsetFromRoot: (0, devkit_1.offsetFromRoot)(projectConfig.root),
|
|
32
17
|
projectRoot: projectConfig.root,
|
|
33
18
|
webServerCommand: options.webServerCommand ?? null,
|
|
34
19
|
webServerAddress: options.webServerAddress ?? null,
|
|
35
20
|
...options,
|
|
36
21
|
});
|
|
37
|
-
|
|
38
|
-
|
|
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
|
-
}
|
|
22
|
+
addE2eTarget(tree, options);
|
|
23
|
+
setupE2ETargetDefaults(tree);
|
|
65
24
|
tasks.push(await (0, add_linter_1.addLinterToPlaywrightProject)(tree, {
|
|
66
25
|
project: options.project,
|
|
67
26
|
linter: options.linter,
|
|
@@ -70,54 +29,16 @@ async function configurationGeneratorInternal(tree, options) {
|
|
|
70
29
|
directory: options.directory,
|
|
71
30
|
setParserOptionsProject: options.setParserOptionsProject,
|
|
72
31
|
rootProject: options.rootProject ?? projectConfig.root === '.',
|
|
73
|
-
addPlugin: options.addPlugin,
|
|
74
32
|
}));
|
|
75
33
|
if (options.js) {
|
|
76
|
-
|
|
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());
|
|
34
|
+
(0, devkit_1.toJS)(tree);
|
|
88
35
|
}
|
|
89
36
|
if (!options.skipFormat) {
|
|
90
37
|
await (0, devkit_1.formatFiles)(tree);
|
|
91
38
|
}
|
|
92
39
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
93
40
|
}
|
|
94
|
-
exports.
|
|
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
|
-
}
|
|
41
|
+
exports.configurationGenerator = configurationGenerator;
|
|
121
42
|
function setupE2ETargetDefaults(tree) {
|
|
122
43
|
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
123
44
|
if (!nxJson.namedInputs) {
|
|
@@ -127,7 +48,6 @@ function setupE2ETargetDefaults(tree) {
|
|
|
127
48
|
nxJson.targetDefaults ??= {};
|
|
128
49
|
const productionFileSet = !!nxJson.namedInputs?.production;
|
|
129
50
|
nxJson.targetDefaults.e2e ??= {};
|
|
130
|
-
nxJson.targetDefaults.e2e.cache ??= true;
|
|
131
51
|
nxJson.targetDefaults.e2e.inputs ??= [
|
|
132
52
|
'default',
|
|
133
53
|
productionFileSet ? '^production' : '^default',
|
|
@@ -145,7 +65,7 @@ Rename or remove the existing e2e target.`);
|
|
|
145
65
|
executor: '@nx/playwright:playwright',
|
|
146
66
|
outputs: [`{workspaceRoot}/dist/.playwright/${projectConfig.root}`],
|
|
147
67
|
options: {
|
|
148
|
-
config: `${projectConfig.root}/playwright.config.${options.js ? '
|
|
68
|
+
config: `${projectConfig.root}/playwright.config.${options.js ? 'js' : 'ts'}`,
|
|
149
69
|
},
|
|
150
70
|
};
|
|
151
71
|
(0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { defineConfig
|
|
1
|
+
import { defineConfig } 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,47 +29,10 @@ export default defineConfig({
|
|
|
29
29
|
url: '<%= webServerAddress %>',
|
|
30
30
|
reuseExistingServer: !process.env.CI,
|
|
31
31
|
cwd: workspaceRoot
|
|
32
|
-
},<% } else {
|
|
33
|
-
// webServer: {
|
|
32
|
+
},<% } else {%>// webServer: {
|
|
34
33
|
// command: 'npm run start',
|
|
35
34
|
// url: 'http://127.0.0.1:3000',
|
|
36
35
|
// reuseExistingServer: !process.env.CI,
|
|
37
36
|
// cwd: workspaceRoot,
|
|
38
37
|
// },<% } %>
|
|
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
|
-
],
|
|
75
38
|
});
|
|
@@ -9,7 +9,6 @@ export interface ConfigurationGeneratorSchema {
|
|
|
9
9
|
js: boolean; // default is false
|
|
10
10
|
skipFormat: boolean;
|
|
11
11
|
skipPackageJson: boolean;
|
|
12
|
-
skipInstall?: boolean;
|
|
13
12
|
linter: Linter;
|
|
14
13
|
setParserOptionsProject: boolean; // default is false
|
|
15
14
|
/**
|
|
@@ -23,5 +22,4 @@ export interface ConfigurationGeneratorSchema {
|
|
|
23
22
|
**/
|
|
24
23
|
webServerAddress?: string;
|
|
25
24
|
rootProject?: boolean;
|
|
26
|
-
addPlugin?: boolean;
|
|
27
25
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "http://json-schema.org/schema",
|
|
3
3
|
"$id": "NxPlaywrightConfiguration",
|
|
4
4
|
"description": "Add a Playwright configuration.",
|
|
5
5
|
"title": "Add a Playwright configuration",
|
|
@@ -62,11 +62,6 @@
|
|
|
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
|
|
70
65
|
}
|
|
71
66
|
},
|
|
72
67
|
"required": ["project"]
|
|
@@ -1,5 +1,4 @@
|
|
|
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>;
|
|
5
4
|
export default initGenerator;
|
|
@@ -1,51 +1,47 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.
|
|
3
|
+
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");
|
|
7
5
|
const versions_1 = require("../../utils/versions");
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
exports.initGenerator = initGenerator;
|
|
12
|
-
async function initGeneratorInternal(tree, options) {
|
|
6
|
+
const child_process_1 = require("child_process");
|
|
7
|
+
async function initGenerator(tree, options) {
|
|
13
8
|
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;
|
|
18
9
|
if (!options.skipPackageJson) {
|
|
19
10
|
tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
20
11
|
'@nx/playwright': versions_1.nxVersion,
|
|
12
|
+
// required since used in playwright config
|
|
13
|
+
'@nx/devkit': versions_1.nxVersion,
|
|
21
14
|
'@playwright/test': versions_1.playwrightVersion,
|
|
22
|
-
}
|
|
23
|
-
}
|
|
24
|
-
if (options.addPlugin) {
|
|
25
|
-
addPlugin(tree);
|
|
26
|
-
}
|
|
27
|
-
if (options.updatePackageScripts) {
|
|
28
|
-
await (0, update_package_scripts_1.updatePackageScripts)(tree, plugin_1.createNodes);
|
|
15
|
+
}));
|
|
29
16
|
}
|
|
30
17
|
if (!options.skipFormat) {
|
|
31
18
|
await (0, devkit_1.formatFiles)(tree);
|
|
32
19
|
}
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
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
|
-
},
|
|
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;
|
|
47
27
|
});
|
|
48
|
-
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
49
28
|
}
|
|
29
|
+
else {
|
|
30
|
+
tree.write('.vscode/extensions.json', JSON.stringify({
|
|
31
|
+
recommendations: ['ms-playwright.playwright'],
|
|
32
|
+
}, null, 2));
|
|
33
|
+
}
|
|
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 });
|
|
42
|
+
});
|
|
43
|
+
}
|
|
44
|
+
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
50
45
|
}
|
|
46
|
+
exports.initGenerator = initGenerator;
|
|
51
47
|
exports.default = initGenerator;
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
export interface InitGeneratorSchema {
|
|
2
|
-
skipFormat
|
|
3
|
-
skipPackageJson
|
|
4
|
-
|
|
5
|
-
updatePackageScripts?: boolean;
|
|
6
|
-
addPlugin?: boolean;
|
|
2
|
+
skipFormat: boolean;
|
|
3
|
+
skipPackageJson: boolean;
|
|
4
|
+
skipInstall?: boolean;
|
|
7
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
{
|
|
2
|
-
"$schema": "
|
|
2
|
+
"$schema": "http://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,16 +17,9 @@
|
|
|
17
17
|
"description": "Do not add dependencies to `package.json`.",
|
|
18
18
|
"x-priority": "internal"
|
|
19
19
|
},
|
|
20
|
-
"
|
|
20
|
+
"skipInstall": {
|
|
21
21
|
"type": "boolean",
|
|
22
|
-
"
|
|
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",
|
|
22
|
+
"description": "Skip running `playwright install`. This is to ensure that playwright browsers are installed.",
|
|
30
23
|
"default": false
|
|
31
24
|
}
|
|
32
25
|
},
|
|
@@ -11,6 +11,5 @@ 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;
|
|
15
14
|
}
|
|
16
15
|
export declare function addLinterToPlaywrightProject(tree: Tree, options: PlaywrightLinterOptions): Promise<GeneratorCallback>;
|
package/src/utils/add-linter.js
CHANGED
|
@@ -19,10 +19,12 @@ 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
|
+
],
|
|
22
25
|
setParserOptionsProject: options.setParserOptionsProject,
|
|
23
26
|
skipPackageJson: options.skipPackageJson,
|
|
24
27
|
rootProject: options.rootProject,
|
|
25
|
-
addPlugin: options.addPlugin,
|
|
26
28
|
}));
|
|
27
29
|
}
|
|
28
30
|
if (!options.linter || options.linter !== eslint_1.Linter.EsLint) {
|
package/src/utils/preset.d.ts
CHANGED
|
@@ -4,6 +4,16 @@ 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;
|
|
7
17
|
}
|
|
8
18
|
/**
|
|
9
19
|
* nx E2E Preset for Playwright
|
|
@@ -15,7 +25,6 @@ export interface NxPlaywrightOptions {
|
|
|
15
25
|
* - chromium
|
|
16
26
|
* - firefox
|
|
17
27
|
* - webkit
|
|
18
|
-
* These are generated by default.
|
|
19
28
|
*
|
|
20
29
|
* you can easily extend this within your playwright config via spreading the preset
|
|
21
30
|
* @example
|
package/src/utils/preset.js
CHANGED
|
@@ -15,7 +15,6 @@ const test_1 = require("@playwright/test");
|
|
|
15
15
|
* - chromium
|
|
16
16
|
* - firefox
|
|
17
17
|
* - webkit
|
|
18
|
-
* These are generated by default.
|
|
19
18
|
*
|
|
20
19
|
* you can easily extend this within your playwright config via spreading the preset
|
|
21
20
|
* @example
|
|
@@ -35,6 +34,44 @@ function nxE2EPreset(pathToConfig, options) {
|
|
|
35
34
|
const offset = (0, node_path_1.relative)(normalizedPath, devkit_1.workspaceRoot);
|
|
36
35
|
const testResultOuputDir = (0, node_path_1.join)(offset, 'dist', '.playwright', projectPath, 'test-output');
|
|
37
36
|
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
|
+
}
|
|
38
75
|
return (0, test_1.defineConfig)({
|
|
39
76
|
testDir: options?.testDir ?? './src',
|
|
40
77
|
outputDir: testResultOuputDir,
|
|
@@ -55,6 +92,7 @@ function nxE2EPreset(pathToConfig, options) {
|
|
|
55
92
|
},
|
|
56
93
|
],
|
|
57
94
|
],
|
|
95
|
+
projects,
|
|
58
96
|
});
|
|
59
97
|
}
|
|
60
98
|
exports.nxE2EPreset = nxE2EPreset;
|
package/migrations.json
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
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/plugin.d.ts
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
export { createNodes, PlaywrightPluginOptions, createDependencies, } from './src/plugins/plugin';
|
package/plugin.js
DELETED
|
@@ -1,6 +0,0 @@
|
|
|
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; } });
|
|
@@ -1,95 +0,0 @@
|
|
|
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
|
-
}
|
|
@@ -1,42 +0,0 @@
|
|
|
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;
|
package/src/plugins/plugin.d.ts
DELETED
|
@@ -1,7 +0,0 @@
|
|
|
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>;
|
package/src/plugins/plugin.js
DELETED
|
@@ -1,205 +0,0 @@
|
|
|
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
|
-
}
|