@nx/playwright 16.7.0-beta.1

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/CHANGELOG.md ADDED
@@ -0,0 +1,8 @@
1
+ # Change Log
2
+
3
+ All notable changes to this project will be documented in this file.
4
+ See [Conventional Commits](https://conventionalcommits.org) for commit guidelines.
5
+
6
+
7
+
8
+ **Note:** Version bump only for package @nx/playwright
package/LICENSE ADDED
@@ -0,0 +1,22 @@
1
+ (The MIT License)
2
+
3
+ Copyright (c) 2017-2023 Narwhal Technologies Inc.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining
6
+ a copy of this software and associated documentation files (the
7
+ 'Software'), to deal in the Software without restriction, including
8
+ without limitation the rights to use, copy, modify, merge, publish,
9
+ distribute, sublicense, and/or sell copies of the Software, and to
10
+ permit persons to whom the Software is furnished to do so, subject to
11
+ the following conditions:
12
+
13
+ The above copyright notice and this permission notice shall be
14
+ included in all copies or substantial portions of the Software.
15
+
16
+ THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND,
17
+ EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18
+ MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
19
+ IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
20
+ CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
21
+ TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
22
+ SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,61 @@
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>
2
+
3
+ <div style="text-align: center;">
4
+
5
+ [![CircleCI](https://circleci.com/gh/nrwl/nx.svg?style=svg)](https://circleci.com/gh/nrwl/nx)
6
+ [![License](https://img.shields.io/npm/l/@nx/workspace.svg?style=flat-square)]()
7
+ [![NPM Version](https://badge.fury.io/js/%40nrwl%2Fworkspace.svg)](https://www.npmjs.com/@nx/workspace)
8
+ [![Semantic Release](https://img.shields.io/badge/%20%20%F0%9F%93%A6%F0%9F%9A%80-semantic--release-e10079.svg?style=flat-square)]()
9
+ [![Commitizen friendly](https://img.shields.io/badge/commitizen-friendly-brightgreen.svg)](http://commitizen.github.io/cz-cli/)
10
+ [![Join the chat at https://gitter.im/nrwl-nx/community](https://badges.gitter.im/nrwl-nx/community.svg)](https://gitter.im/nrwl-nx/community?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
11
+ [![Join us @nx/community on slack](https://img.shields.io/badge/slack-%40nrwl%2Fcommunity-brightgreen)](https://join.slack.com/t/nrwlcommunity/shared_invite/enQtNzU5MTE4OTQwOTk0LTgxY2E0ZWYzMWE0YzA5ZDA2MWM1NDVhNmI2ZWMyYmZhNWJiODk3MjkxZjY3MzU5ZjRmM2NmNWU1OTgyZmE4Mzc)
12
+
13
+ </div>
14
+
15
+
16
+ <hr>
17
+
18
+ # Nx: Smart, Fast and Extensible Build System
19
+
20
+ Nx is a next generation build system with first class monorepo support and powerful integrations.
21
+
22
+ ## Getting Started
23
+
24
+ ### Creating an Nx Workspace
25
+
26
+ **Using `npx`**
27
+
28
+ ```bash
29
+ npx create-nx-workspace
30
+ ```
31
+
32
+ **Using `npm init`**
33
+
34
+ ```bash
35
+ npm init nx-workspace
36
+ ```
37
+
38
+ **Using `yarn create`**
39
+
40
+ ```bash
41
+ yarn create nx-workspace
42
+ ```
43
+
44
+ ### Adding Nx to an Existing Repository
45
+
46
+ Run:
47
+
48
+ ```bash
49
+ npx nx@latest init
50
+ ```
51
+
52
+ ## Documentation & Resources
53
+
54
+ - [Nx.Dev: Documentation, Guides, Tutorials](https://nx.dev)
55
+ - [Intro to Nx](https://nx.dev/getting-started/intro)
56
+ - [Official Nx YouTube Channel](https://www.youtube.com/@NxDevtools)
57
+ - [Blog Posts About Nx](https://blog.nrwl.io/nx/home)
58
+
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"
60
+ width="100%" alt="Nx - Smart, Fast and Extensible Build System"></a></p>
61
+
package/executors.json ADDED
@@ -0,0 +1,16 @@
1
+ {
2
+ "builders": {
3
+ "playwright": {
4
+ "implementation": "./src/executors/playwright/compat",
5
+ "schema": "./src/executors/playwright/schema.json",
6
+ "description": "Run Playwright tests."
7
+ }
8
+ },
9
+ "executors": {
10
+ "playwright": {
11
+ "implementation": "./src/executors/playwright/playwright",
12
+ "schema": "./src/executors/playwright/schema.json",
13
+ "description": "Run Playwright tests."
14
+ }
15
+ }
16
+ }
@@ -0,0 +1,28 @@
1
+ {
2
+ "name": "Nx Playwright",
3
+ "version": "0.1",
4
+ "schematics": {
5
+ "configuration": {
6
+ "factory": "./src/generators/configuration/configuration#configurationSchematic",
7
+ "schema": "./src/generators/configuration/schema.json",
8
+ "description": "Add Nx Playwright configuration to your project"
9
+ },
10
+ "init": {
11
+ "factory": "./src/generators/init/init#initSchematic",
12
+ "schema": "./src/generators/init/schema.json",
13
+ "description": "Initializes a Playwright project in the current workspace"
14
+ }
15
+ },
16
+ "generators": {
17
+ "configuration": {
18
+ "factory": "./src/generators/configuration/configuration",
19
+ "schema": "./src/generators/configuration/schema.json",
20
+ "description": "Add Nx Playwright configuration to your project"
21
+ },
22
+ "init": {
23
+ "factory": "./src/generators/init/init",
24
+ "schema": "./src/generators/init/schema.json",
25
+ "description": "Initializes a Playwright project in the current workspace"
26
+ }
27
+ }
28
+ }
package/index.d.ts ADDED
@@ -0,0 +1,3 @@
1
+ export { playwrightExecutor, PlaywrightExecutorSchema, } from './src/executors/playwright/playwright';
2
+ export { initGenerator } from './src/generators/init/init';
3
+ export { configurationGenerator } from './src/generators/configuration/configuration';
package/index.js ADDED
@@ -0,0 +1,9 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
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; } });
6
+ var init_1 = require("./src/generators/init/init");
7
+ Object.defineProperty(exports, "initGenerator", { enumerable: true, get: function () { return init_1.initGenerator; } });
8
+ var configuration_1 = require("./src/generators/configuration/configuration");
9
+ Object.defineProperty(exports, "configurationGenerator", { enumerable: true, get: function () { return configuration_1.configurationGenerator; } });
package/package.json ADDED
@@ -0,0 +1,61 @@
1
+ {
2
+ "name": "@nx/playwright",
3
+ "version": "16.7.0-beta.1",
4
+ "type": "commonjs",
5
+ "homepage": "https://nx.dev",
6
+ "private": false,
7
+ "publishConfig": {
8
+ "access": "public"
9
+ },
10
+ "description": "The Nx Plugin for Playwright contains executors and generators allowing your workspace to use the powerful Playwright integration testing capabilities.",
11
+ "keywords": [
12
+ "Monorepo",
13
+ "Angular",
14
+ "React",
15
+ "Web",
16
+ "Node",
17
+ "Nest",
18
+ "Jest",
19
+ "Playwright",
20
+ "CLI"
21
+ ],
22
+ "main": "./index.js",
23
+ "typings": "./index.d.ts",
24
+ "author": "Victor Savkin",
25
+ "license": "MIT",
26
+ "bugs": {
27
+ "url": "https://github.com/nrwl/nx/issues"
28
+ },
29
+ "repository": {
30
+ "type": "git",
31
+ "url": "https://github.com/nrwl/nx.git",
32
+ "directory": "packages/playwright"
33
+ },
34
+ "dependencies": {
35
+ "@nx/devkit": "16.7.0-beta.1",
36
+ "@nx/linter": "16.7.0-beta.1",
37
+ "tslib": "^2.3.0"
38
+ },
39
+ "peerDependencies": {
40
+ "@playwright/test": "^1.36.0"
41
+ },
42
+ "peerDependenciesMeta": {
43
+ "@playwright/test": {
44
+ "optional": true
45
+ }
46
+ },
47
+ "executors": "./executors.json",
48
+ "generators": "./generators.json",
49
+ "exports": {
50
+ ".": "./index.js",
51
+ "./package.json": "./package.json",
52
+ "./migrations.json": "./migrations.json",
53
+ "./generators.json": "./generators.json",
54
+ "./generators/*/schema.json": "./src/generators/*/schema.json",
55
+ "./executors.json": "./executors.json",
56
+ "./executors/*/schema.json": "./src/executors/*/schema.json",
57
+ "./preset": "./src/utils/preset.js"
58
+ },
59
+ "types": "./index.d.ts",
60
+ "gitHead": "50a145bb64edcf76985184a9a83d1449dcd4f3d9"
61
+ }
package/preset.d.ts ADDED
@@ -0,0 +1 @@
1
+ export * from './src/utils/preset';
package/preset.js ADDED
@@ -0,0 +1,4 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const tslib_1 = require("tslib");
4
+ tslib_1.__exportStar(require("./src/utils/preset"), exports);
@@ -0,0 +1,2 @@
1
+ declare const _default: any;
2
+ export default _default;
@@ -0,0 +1,5 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ const devkit_1 = require("@nx/devkit");
4
+ const playwright_1 = require("./playwright");
5
+ exports.default = (0, devkit_1.convertNxExecutor)(playwright_1.playwrightExecutor);
@@ -0,0 +1,36 @@
1
+ import { ExecutorContext } from '@nx/devkit';
2
+ export interface PlaywrightExecutorSchema {
3
+ browser?: 'all' | 'chromium' | 'firefox' | 'webkit' | string;
4
+ config?: string;
5
+ debug?: boolean;
6
+ forbidOnly?: boolean;
7
+ fullyParallel?: boolean;
8
+ grep?: string;
9
+ globalTimeout?: number;
10
+ grepInvert?: string;
11
+ headed?: boolean;
12
+ ignoreSnapshots?: boolean;
13
+ workers?: string;
14
+ list?: boolean;
15
+ maxFailures?: number | boolean;
16
+ noDeps?: boolean;
17
+ output?: string;
18
+ passWithNoTests?: boolean;
19
+ project?: string[];
20
+ quiet?: boolean;
21
+ repeatEach?: number;
22
+ reporter?: 'list' | 'line' | 'dot' | 'json' | 'junit' | 'null' | 'github' | 'html' | 'blob';
23
+ retries?: number;
24
+ shard?: string;
25
+ timeout?: number;
26
+ trace?: 'on' | 'off' | 'on-first-retry' | 'on-all-retries' | 'retain-on-failure';
27
+ updateSnapshots?: boolean;
28
+ ui?: boolean;
29
+ uiHost?: string;
30
+ uiPort?: string;
31
+ skipInstall?: boolean;
32
+ }
33
+ export declare function playwrightExecutor(options: PlaywrightExecutorSchema, context: ExecutorContext): Promise<{
34
+ success: boolean;
35
+ }>;
36
+ export default playwrightExecutor;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.playwrightExecutor = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const child_process_1 = require("child_process");
6
+ const devkit_1 = require("@nx/devkit");
7
+ function playwrightExecutor(options, context) {
8
+ var _a, _b, _c, _d;
9
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
+ const projectRoot = (_d = (_c = (_b = (_a = context.projectGraph) === null || _a === void 0 ? void 0 : _a.nodes) === null || _b === void 0 ? void 0 : _b[context === null || context === void 0 ? void 0 : context.projectName]) === null || _c === void 0 ? void 0 : _c.data) === null || _d === void 0 ? void 0 : _d.root;
11
+ if (!projectRoot) {
12
+ throw new Error(`Unable to find the Project Root for ${context.projectName}. Is it set in the project.json?`);
13
+ }
14
+ if (!options.skipInstall) {
15
+ devkit_1.output.log({
16
+ title: 'Ensuring Playwright is installed.',
17
+ bodyLines: ['use --skipInstall to skip installation.'],
18
+ });
19
+ const pmc = (0, devkit_1.getPackageManagerCommand)();
20
+ (0, child_process_1.execSync)(`${pmc.exec} playwright install`, { cwd: devkit_1.workspaceRoot });
21
+ }
22
+ const args = createArgs(options);
23
+ const p = runPlaywright(args, context.root);
24
+ return new Promise((resolve) => {
25
+ p.on('close', (code) => {
26
+ resolve({ success: code === 0 });
27
+ });
28
+ });
29
+ });
30
+ }
31
+ exports.playwrightExecutor = playwrightExecutor;
32
+ function createArgs(opts) {
33
+ const args = [];
34
+ for (const key in opts) {
35
+ const value = opts[key];
36
+ // NOTE: playwright doesn't accept pascalCase args, only kebab-case
37
+ const arg = (0, devkit_1.names)(key).fileName;
38
+ if (Array.isArray(value)) {
39
+ args.push(`--${arg}=${value.map((v) => v.trim()).join(',')}`);
40
+ }
41
+ else if (typeof value === 'boolean') {
42
+ // NOTE: playwright don't accept --arg=false, instead just don't pass the arg.
43
+ if (value) {
44
+ args.push(`--${arg}`);
45
+ }
46
+ }
47
+ else {
48
+ args.push(`--${arg}=${value}`);
49
+ }
50
+ }
51
+ return args;
52
+ }
53
+ function runPlaywright(args, cwd) {
54
+ try {
55
+ const cli = require.resolve('@playwright/test/cli');
56
+ return (0, child_process_1.fork)(cli, ['test', ...args], {
57
+ stdio: 'inherit',
58
+ cwd,
59
+ });
60
+ }
61
+ catch (e) {
62
+ console.error(e);
63
+ throw new Error('Unable to run playwright. Is @playwright/test installed?');
64
+ }
65
+ }
66
+ exports.default = playwrightExecutor;
@@ -0,0 +1,160 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "version": 2,
4
+ "title": "Playwright executor",
5
+ "description": "Run Playwright tests.",
6
+ "type": "object",
7
+ "properties": {
8
+ "browser": {
9
+ "type": "string",
10
+ "description": "Browser to use for tests, one of 'all', 'chromium', 'firefox' or 'webkit'. If a playwright config is provided/discovered then the browserName value is expected from the configured 'projects'",
11
+ "x-priority": "important"
12
+ },
13
+ "config": {
14
+ "type": "string",
15
+ "description": "Configuration file, or a test directory with optional",
16
+ "x-completion-type": "file",
17
+ "x-completion-glob": "playwright?(*)@(.js|.cjs|.mjs|.ts|.cts|.mtx)",
18
+ "x-priority": "important"
19
+ },
20
+ "debug": {
21
+ "type": "boolean",
22
+ "description": "Run tests with Playwright Inspector. Shortcut for 'PWDEBUG=1' environment variable and '--timeout=0',--max-failures=1 --headed --workers=1' options"
23
+ },
24
+ "forbidOnly": {
25
+ "type": "boolean",
26
+ "description": "Fail if test.only is called"
27
+ },
28
+ "fullyParallel": {
29
+ "type": "boolean",
30
+ "description": "Run all tests in parallel"
31
+ },
32
+ "grep": {
33
+ "alias": "g",
34
+ "type": "string",
35
+ "description": "Only run tests matching this regular expression"
36
+ },
37
+ "globalTimeout": {
38
+ "type": "number",
39
+ "description": "Maximum time this test suite can run in milliseconds"
40
+ },
41
+ "grepInvert": {
42
+ "alias": "gv",
43
+ "type": "string",
44
+ "description": "Only run tests that do not match this regular expression"
45
+ },
46
+ "headed": {
47
+ "type": "boolean",
48
+ "description": "Run tests in headed browsers",
49
+ "x-priority": "important"
50
+ },
51
+ "ignoreSnapshots": {
52
+ "type": "boolean",
53
+ "description": "Ignore screenshot and snapshot expectations"
54
+ },
55
+ "workers": {
56
+ "alias": "j",
57
+ "type": "string",
58
+ "description": "Number of concurrent workers or percentage of logical CPU cores, use 1 to run in a single worker"
59
+ },
60
+ "list": {
61
+ "type": "boolean",
62
+ "description": "Collect all the tests and report them, but do not run"
63
+ },
64
+ "maxFailures": {
65
+ "alias": "x",
66
+ "oneOf": [{ "type": "number" }, { "type": "boolean" }],
67
+ "description": "Stop after the first N failures"
68
+ },
69
+ "noDeps": {
70
+ "type": "boolean",
71
+ "description": "Do not run project dependencies"
72
+ },
73
+ "output": {
74
+ "type": "string",
75
+ "description": "Folder for output artifacts"
76
+ },
77
+ "passWithNoTests": {
78
+ "type": "boolean",
79
+ "description": "Makes test run succeed even if no tests were found",
80
+ "default": true
81
+ },
82
+ "project": {
83
+ "description": "Only run tests from the specified list of projects",
84
+ "type": "array",
85
+ "items": {
86
+ "type": "string"
87
+ }
88
+ },
89
+ "quiet": {
90
+ "alias": "q",
91
+ "type": "boolean",
92
+ "description": "Suppress stdio"
93
+ },
94
+ "repeatEach": {
95
+ "type": "number",
96
+ "description": "Run each test N times"
97
+ },
98
+ "reporter": {
99
+ "type": "string",
100
+ "enum": [
101
+ "list",
102
+ "line",
103
+ "dot",
104
+ "json",
105
+ "junit",
106
+ "null",
107
+ "github",
108
+ "html",
109
+ "blob"
110
+ ],
111
+ "description": "Reporter to use, comma-separated, can be 'list', 'line', 'dot', 'json', 'junit', 'null', 'github', 'html', 'blob'. To configure reporter options, use the playwright configuration."
112
+ },
113
+ "retries": {
114
+ "type": "number",
115
+ "description": "Maximum retry count for flaky tests, zero for no retries"
116
+ },
117
+ "shard": {
118
+ "type": "string",
119
+ "description": "Shard tests and execute only the selected shard, specify in the form 'current/all', 1-based, for example '3/5'"
120
+ },
121
+ "timeout": {
122
+ "type": "number",
123
+ "description": "Specify test timeout threshold in milliseconds, zero for unlimited"
124
+ },
125
+ "trace": {
126
+ "type": "string",
127
+ "enum": [
128
+ "on",
129
+ "off",
130
+ "on-first-retry",
131
+ "on-all-retries",
132
+ "retain-on-failure"
133
+ ],
134
+ "description": "Force tracing mode, can be 'on', 'off', 'on-first-retry', 'on-all-retries', 'retain-on-failure'"
135
+ },
136
+ "updateSnapshots": {
137
+ "alias": "u",
138
+ "type": "boolean",
139
+ "description": "Update snapshots with actual results. Snapshots will be created if missing."
140
+ },
141
+ "ui": {
142
+ "type": "boolean",
143
+ "description": "Run tests in interactive UI mode"
144
+ },
145
+ "uiHost": {
146
+ "type": "string",
147
+ "description": "Host to serve UI on; specifying this option opens UI in a browser tab"
148
+ },
149
+ "uiPort": {
150
+ "type": "string",
151
+ "description": "Port to serve UI on, 0 for any free port; specifying this option opens UI in a browser tab"
152
+ },
153
+ "skipInstall": {
154
+ "type": "boolean",
155
+ "description": "Skip running playwright install before running playwright tests. This is to ensure that playwright browsers are installed before running tests.",
156
+ "default": false
157
+ }
158
+ },
159
+ "required": []
160
+ }
@@ -0,0 +1,5 @@
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
+ import { ConfigurationGeneratorSchema } from './schema';
3
+ export declare function configurationGenerator(tree: Tree, options: ConfigurationGeneratorSchema): Promise<GeneratorCallback>;
4
+ export default configurationGenerator;
5
+ export declare const configurationSchematic: (generatorOptions: ConfigurationGeneratorSchema) => (tree: any, context: any) => Promise<any>;
@@ -0,0 +1,75 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.configurationSchematic = exports.configurationGenerator = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const path = require("path");
7
+ const init_1 = require("../init/init");
8
+ const add_linter_1 = require("../../utils/add-linter");
9
+ function configurationGenerator(tree, options) {
10
+ var _a, _b;
11
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
12
+ const tasks = [];
13
+ tasks.push(yield (0, init_1.default)(tree, {
14
+ skipFormat: true,
15
+ skipPackageJson: options.skipPackageJson,
16
+ }));
17
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
18
+ (0, devkit_1.generateFiles)(tree, path.join(__dirname, 'files'), projectConfig.root, Object.assign({ offsetFromRoot: (0, devkit_1.offsetFromRoot)(projectConfig.root), projectRoot: projectConfig.root, webServerCommand: (_a = options.webServerCommand) !== null && _a !== void 0 ? _a : null, webServerAddress: (_b = options.webServerAddress) !== null && _b !== void 0 ? _b : null }, options));
19
+ addE2eTarget(tree, options);
20
+ setupE2ETargetDefaults(tree);
21
+ tasks.push(yield (0, add_linter_1.addLinterToPlaywrightProject)(tree, {
22
+ project: options.project,
23
+ linter: options.linter,
24
+ skipPackageJson: options.skipPackageJson,
25
+ js: options.js,
26
+ directory: options.directory,
27
+ setParserOptionsProject: options.setParserOptionsProject,
28
+ rootProject: projectConfig.root === '.',
29
+ }));
30
+ if (options.js) {
31
+ (0, devkit_1.toJS)(tree);
32
+ }
33
+ if (!options.skipFormat) {
34
+ yield (0, devkit_1.formatFiles)(tree);
35
+ }
36
+ return (0, devkit_1.runTasksInSerial)(...tasks);
37
+ });
38
+ }
39
+ exports.configurationGenerator = configurationGenerator;
40
+ function setupE2ETargetDefaults(tree) {
41
+ var _a, _b, _c, _d;
42
+ var _e, _f;
43
+ const nxJson = (0, devkit_1.readNxJson)(tree);
44
+ if (!nxJson.namedInputs) {
45
+ return;
46
+ }
47
+ // E2e targets depend on all their project's sources + production sources of dependencies
48
+ (_a = nxJson.targetDefaults) !== null && _a !== void 0 ? _a : (nxJson.targetDefaults = {});
49
+ const productionFileSet = !!((_b = nxJson.namedInputs) === null || _b === void 0 ? void 0 : _b.production);
50
+ (_c = (_e = nxJson.targetDefaults).e2e) !== null && _c !== void 0 ? _c : (_e.e2e = {});
51
+ (_d = (_f = nxJson.targetDefaults.e2e).inputs) !== null && _d !== void 0 ? _d : (_f.inputs = [
52
+ 'default',
53
+ productionFileSet ? '^production' : '^default',
54
+ ]);
55
+ (0, devkit_1.updateNxJson)(tree, nxJson);
56
+ }
57
+ function addE2eTarget(tree, options) {
58
+ var _a, _b;
59
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
60
+ if ((_a = projectConfig === null || projectConfig === void 0 ? void 0 : projectConfig.targets) === null || _a === void 0 ? void 0 : _a.e2e) {
61
+ throw new Error(`Project ${options.project} already has an e2e target.
62
+ Rename or remove the existing e2e target.`);
63
+ }
64
+ (_b = projectConfig.targets) !== null && _b !== void 0 ? _b : (projectConfig.targets = {});
65
+ projectConfig.targets.e2e = {
66
+ executor: '@nx/playwright:playwright',
67
+ outputs: [`dist/.playwright/${projectConfig.root}`],
68
+ options: {
69
+ config: `${projectConfig.root}/playwright.config.${options.js ? 'js' : 'ts'}`,
70
+ },
71
+ };
72
+ (0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
73
+ }
74
+ exports.default = configurationGenerator;
75
+ exports.configurationSchematic = (0, devkit_1.convertNxGenerator)(configurationGenerator);
@@ -0,0 +1,8 @@
1
+ import { test, expect } from '@playwright/test';
2
+
3
+ test('has title', async ({ page }) => {
4
+ await page.goto('/');
5
+
6
+ // Expect a title "to contain" a substring.
7
+ await expect(page).toHaveTitle(/Welcome/);
8
+ });
@@ -0,0 +1,38 @@
1
+ import { defineConfig } from '@playwright/test';
2
+ import { nxE2EPreset } from '@nx/playwright/preset';
3
+ <% if(!webServerCommand || !webServerAddress) { %>// eslint-disable-next-line @typescript-eslint/no-unused-vars <% } %>
4
+ import { workspaceRoot } from '@nx/devkit';
5
+
6
+ // For CI, you may want to set BASE_URL to the deployed application.
7
+ const baseURL = process.env['BASE_URL'] || '<% if(webServerAddress) {%><%= webServerAddress %><% } else {%>http://localhost:3000<% } %>';
8
+
9
+ /**
10
+ * Read environment variables from file.
11
+ * https://github.com/motdotla/dotenv
12
+ */
13
+ // require('dotenv').config();
14
+
15
+ /**
16
+ * See https://playwright.dev/docs/test-configuration.
17
+ */
18
+ export default defineConfig({
19
+ ...nxE2EPreset(__filename, { testDir: './<>' }),
20
+ /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */
21
+ use: {
22
+ baseURL,
23
+ /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */
24
+ trace: 'on-first-retry',
25
+ },
26
+ /* Run your local dev server before starting the tests */<% if(webServerCommand && webServerAddress) {%>
27
+ webServer: {
28
+ command: '<%= webServerCommand %>',
29
+ url: '<%= webServerAddress %>',
30
+ reuseExistingServer: !process.env.CI,
31
+ cwd: workspaceRoot
32
+ },<% } else {%>// webServer: {
33
+ // command: 'npm run start',
34
+ // url: 'http://127.0.0.1:3000',
35
+ // reuseExistingServer: !process.env.CI,
36
+ // cwd: workspaceRoot,
37
+ // },<% } %>
38
+ });
@@ -0,0 +1,21 @@
1
+ import type { Linter } from '@nx/linter';
2
+
3
+ export interface ConfigurationGeneratorSchema {
4
+ project: string;
5
+ directory: string;
6
+ js: boolean; // default is false
7
+ skipFormat: boolean;
8
+ skipPackageJson: boolean;
9
+ linter: Linter;
10
+ setParserOptionsProject: boolean; // default is false
11
+ /**
12
+ * command to give playwright to run the web server
13
+ * @example: "npx nx serve my-fe-app"
14
+ **/
15
+ webServerCommand?: string;
16
+ /**
17
+ * address
18
+ * @example: "http://localhost:4200"
19
+ **/
20
+ webServerAddress?: string;
21
+ }
@@ -0,0 +1,61 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "NxPlaywrightConfiguration",
4
+ "description": "Add a Playwright configuration.",
5
+ "title": "Add a Playwright configuration",
6
+ "type": "object",
7
+ "properties": {
8
+ "project": {
9
+ "type": "string",
10
+ "description": "The project to add a Playwright configuration to",
11
+ "$default": {
12
+ "$source": "projectName"
13
+ },
14
+ "x-priority": "important",
15
+ "x-prompt": "What is the name of the project to set up Playwright for?"
16
+ },
17
+ "directory": {
18
+ "type": "string",
19
+ "description": "A directory where the project is placed relative from the project root",
20
+ "x-priority": "important",
21
+ "default": "playwright"
22
+ },
23
+ "js": {
24
+ "type": "boolean",
25
+ "description": "Generate JavaScript files rather than TypeScript files.",
26
+ "default": false
27
+ },
28
+ "webServerCommand": {
29
+ "type": "string",
30
+ "description": "The command to start the web server."
31
+ },
32
+ "webServerAddress": {
33
+ "type": "string",
34
+ "description": "The address of the web server."
35
+ },
36
+ "linter": {
37
+ "description": "The tool to use for running lint checks.",
38
+ "type": "string",
39
+ "enum": ["eslint", "none"],
40
+ "default": "eslint"
41
+ },
42
+ "setParserOptionsProject": {
43
+ "type": "boolean",
44
+ "description": "Whether or not to configure the ESLint `parserOptions.project` option. We do not do this by default for lint performance reasons.",
45
+ "default": false
46
+ },
47
+ "skipFormat": {
48
+ "description": "Skip formatting files.",
49
+ "type": "boolean",
50
+ "default": false,
51
+ "x-priority": "internal"
52
+ },
53
+ "skipPackageJson": {
54
+ "type": "boolean",
55
+ "default": false,
56
+ "description": "Do not add dependencies to `package.json`.",
57
+ "x-priority": "internal"
58
+ }
59
+ },
60
+ "required": ["project"]
61
+ }
@@ -0,0 +1,5 @@
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
+ import { InitGeneratorSchema } from './schema';
3
+ export declare function initGenerator(tree: Tree, options: InitGeneratorSchema): Promise<GeneratorCallback>;
4
+ export default initGenerator;
5
+ export declare const initSchematic: (generatorOptions: InitGeneratorSchema) => (tree: any, context: any) => Promise<any>;
@@ -0,0 +1,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.initSchematic = exports.initGenerator = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const versions_1 = require("../../utils/versions");
7
+ const child_process_1 = require("child_process");
8
+ function initGenerator(tree, options) {
9
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
10
+ const tasks = [];
11
+ if (!options.skipPackageJson) {
12
+ tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
13
+ '@nx/playwright': versions_1.nxVersion,
14
+ '@playwright/test': versions_1.playwrightVersion,
15
+ }));
16
+ }
17
+ if (!options.skipFormat) {
18
+ yield (0, devkit_1.formatFiles)(tree);
19
+ }
20
+ if (tree.exists('.vscode/extensions.json')) {
21
+ (0, devkit_1.updateJson)(tree, '.vscode/extensions.json', (json) => {
22
+ var _a;
23
+ (_a = json.recommendations) !== null && _a !== void 0 ? _a : (json.recommendations = []);
24
+ const recs = new Set(json.recommendations);
25
+ recs.add('ms-playwright.playwright');
26
+ json.recommendations = Array.from(recs);
27
+ return json;
28
+ });
29
+ }
30
+ else {
31
+ tree.write('.vscode/extensions.json', JSON.stringify({
32
+ recommendations: ['ms-playwright.playwright'],
33
+ }, null, 2));
34
+ }
35
+ if (!options.skipInstall) {
36
+ tasks.push(() => {
37
+ devkit_1.output.log({
38
+ title: 'Ensuring Playwright is installed.',
39
+ bodyLines: ['use --skipInstall to skip installation.'],
40
+ });
41
+ const pmc = (0, devkit_1.getPackageManagerCommand)();
42
+ (0, child_process_1.execSync)(`${pmc.exec} playwright install`, { cwd: devkit_1.workspaceRoot });
43
+ });
44
+ }
45
+ return (0, devkit_1.runTasksInSerial)(...tasks);
46
+ });
47
+ }
48
+ exports.initGenerator = initGenerator;
49
+ exports.default = initGenerator;
50
+ exports.initSchematic = (0, devkit_1.convertNxGenerator)(initGenerator);
@@ -0,0 +1,5 @@
1
+ export interface InitGeneratorSchema {
2
+ skipFormat: boolean;
3
+ skipPackageJson: boolean;
4
+ skipInstall?: boolean;
5
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "$schema": "http://json-schema.org/schema",
3
+ "$id": "NxPlaywrightInit",
4
+ "title": "Playwright Init Generator",
5
+ "description": "Initializes a Playwright project in the current workspace.",
6
+ "type": "object",
7
+ "properties": {
8
+ "skipFormat": {
9
+ "description": "Skip formatting files.",
10
+ "type": "boolean",
11
+ "default": false,
12
+ "x-priority": "internal"
13
+ },
14
+ "skipPackageJson": {
15
+ "type": "boolean",
16
+ "default": false,
17
+ "description": "Do not add dependencies to `package.json`.",
18
+ "x-priority": "internal"
19
+ },
20
+ "skipInstall": {
21
+ "type": "boolean",
22
+ "description": "Skip running `playwright install`. This is to ensure that playwright browsers are installed.",
23
+ "default": false
24
+ }
25
+ },
26
+ "required": []
27
+ }
@@ -0,0 +1,15 @@
1
+ import { GeneratorCallback, Tree } from '@nx/devkit';
2
+ import { Linter } from '@nx/linter';
3
+ export interface PlaywrightLinterOptions {
4
+ project: string;
5
+ linter: Linter;
6
+ setParserOptionsProject: boolean;
7
+ skipPackageJson: boolean;
8
+ rootProject: boolean;
9
+ js?: boolean;
10
+ /**
11
+ * Directory from the project root, where the playwright files will be located.
12
+ **/
13
+ directory: string;
14
+ }
15
+ export declare function addLinterToPlaywrightProject(tree: Tree, options: PlaywrightLinterOptions): Promise<GeneratorCallback>;
@@ -0,0 +1,66 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.addLinterToPlaywrightProject = void 0;
4
+ const tslib_1 = require("tslib");
5
+ const devkit_1 = require("@nx/devkit");
6
+ const linter_1 = require("@nx/linter");
7
+ const global_eslint_config_1 = require("@nx/linter/src/generators/init/global-eslint-config");
8
+ const versions_1 = require("./versions");
9
+ function addLinterToPlaywrightProject(tree, options) {
10
+ return tslib_1.__awaiter(this, void 0, void 0, function* () {
11
+ if (options.linter === linter_1.Linter.None) {
12
+ return () => { };
13
+ }
14
+ const tasks = [];
15
+ const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
16
+ if (!tree.exists((0, devkit_1.joinPathFragments)(projectConfig.root, '.eslintrc.json'))) {
17
+ tasks.push(yield (0, linter_1.lintProjectGenerator)(tree, {
18
+ project: options.project,
19
+ linter: options.linter,
20
+ skipFormat: true,
21
+ tsConfigPaths: [(0, devkit_1.joinPathFragments)(projectConfig.root, 'tsconfig.json')],
22
+ eslintFilePatterns: [
23
+ `${projectConfig.root}/**/*.${options.js ? 'js' : '{js,ts}'}`,
24
+ ],
25
+ setParserOptionsProject: options.setParserOptionsProject,
26
+ skipPackageJson: options.skipPackageJson,
27
+ rootProject: options.rootProject,
28
+ }));
29
+ }
30
+ if (!options.linter || options.linter !== linter_1.Linter.EsLint) {
31
+ return (0, devkit_1.runTasksInSerial)(...tasks);
32
+ }
33
+ tasks.push(!options.skipPackageJson
34
+ ? (0, devkit_1.addDependenciesToPackageJson)(tree, {}, { 'eslint-plugin-playwright': versions_1.eslintPluginPlaywrightVersion })
35
+ : () => { });
36
+ (0, devkit_1.updateJson)(tree, (0, devkit_1.joinPathFragments)(projectConfig.root, '.eslintrc.json'), (json) => {
37
+ var _a;
38
+ if (options.rootProject) {
39
+ json.plugins = ['@nx'];
40
+ json.extends = ['plugin:playwright/recommended'];
41
+ }
42
+ else {
43
+ json.extends = ['plugin:playwright/recommended', ...json.extends];
44
+ }
45
+ (_a = json.overrides) !== null && _a !== void 0 ? _a : (json.overrides = []);
46
+ const globals = options.rootProject ? [global_eslint_config_1.globalJavaScriptOverrides] : [];
47
+ const override = {
48
+ files: ['*.ts', '*.tsx', '*.js', '*.jsx'],
49
+ parserOptions: !options.setParserOptionsProject
50
+ ? undefined
51
+ : {
52
+ project: `${projectConfig.root}/tsconfig.*?.json`,
53
+ },
54
+ rules: {},
55
+ };
56
+ const palywrightFiles = [
57
+ Object.assign(Object.assign({}, override), { files: [`${options.directory}/**/*.{ts,js,tsx,jsx}`] }),
58
+ ];
59
+ json.overrides.push(...globals);
60
+ json.overrides.push(...palywrightFiles);
61
+ return json;
62
+ });
63
+ return (0, devkit_1.runTasksInSerial)(...tasks);
64
+ });
65
+ }
66
+ exports.addLinterToPlaywrightProject = addLinterToPlaywrightProject;
@@ -0,0 +1,39 @@
1
+ export interface NxPlaywrightOptions {
2
+ /**
3
+ * The directory where the e2e tests are located.
4
+ * @default './src'
5
+ **/
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
+ }
18
+ /**
19
+ * nx E2E Preset for Playwright
20
+ * @description
21
+ * this preset contains the base configuration
22
+ * for your e2e tests that nx recommends.
23
+ * By default html reporter is configured
24
+ * along with the following browsers:
25
+ * - chromium
26
+ * - firefox
27
+ * - webkit
28
+ *
29
+ * you can easily extend this within your playwright config via spreading the preset
30
+ * @example
31
+ * export default defineConfig({
32
+ * ...nxE2EPreset(__filename, options)
33
+ * // add your own config here
34
+ * })
35
+ *
36
+ * @param pathToConfig will be used to construct the output paths for reporters and test results
37
+ * @param options optional configuration options
38
+ */
39
+ export declare function nxE2EPreset(pathToConfig: string, options?: NxPlaywrightOptions): import("@playwright/test").PlaywrightTestConfig<{}, {}>;
@@ -0,0 +1,99 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.nxE2EPreset = void 0;
4
+ const devkit_1 = require("@nx/devkit");
5
+ const node_fs_1 = require("node:fs");
6
+ const node_path_1 = require("node:path");
7
+ const test_1 = require("@playwright/test");
8
+ /**
9
+ * nx E2E Preset for Playwright
10
+ * @description
11
+ * this preset contains the base configuration
12
+ * for your e2e tests that nx recommends.
13
+ * By default html reporter is configured
14
+ * along with the following browsers:
15
+ * - chromium
16
+ * - firefox
17
+ * - webkit
18
+ *
19
+ * you can easily extend this within your playwright config via spreading the preset
20
+ * @example
21
+ * export default defineConfig({
22
+ * ...nxE2EPreset(__filename, options)
23
+ * // add your own config here
24
+ * })
25
+ *
26
+ * @param pathToConfig will be used to construct the output paths for reporters and test results
27
+ * @param options optional configuration options
28
+ */
29
+ function nxE2EPreset(pathToConfig, options) {
30
+ var _a;
31
+ const normalizedPath = (0, node_fs_1.lstatSync)(pathToConfig).isDirectory()
32
+ ? pathToConfig
33
+ : (0, node_path_1.dirname)(pathToConfig);
34
+ const projectPath = (0, node_path_1.relative)(devkit_1.workspaceRoot, normalizedPath);
35
+ const offset = (0, node_path_1.relative)(normalizedPath, devkit_1.workspaceRoot);
36
+ const testResultOuputDir = (0, node_path_1.join)(offset, 'dist', '.playwright', projectPath, 'test-output');
37
+ const reporterOutputDir = (0, node_path_1.join)(offset, 'dist', '.playwright', projectPath, 'playwright-report');
38
+ const projects = [
39
+ {
40
+ name: 'chromium',
41
+ use: Object.assign({}, test_1.devices['Desktop Chrome']),
42
+ },
43
+ {
44
+ name: 'firefox',
45
+ use: Object.assign({}, test_1.devices['Desktop Firefox']),
46
+ },
47
+ {
48
+ name: 'webkit',
49
+ use: Object.assign({}, test_1.devices['Desktop Safari']),
50
+ },
51
+ ];
52
+ if (options === null || options === void 0 ? void 0 : options.includeMobileBrowsers) {
53
+ projects.push(...[
54
+ {
55
+ name: 'Mobile Chrome',
56
+ use: Object.assign({}, test_1.devices['Pixel 5']),
57
+ },
58
+ {
59
+ name: 'Mobile Safari',
60
+ use: Object.assign({}, test_1.devices['iPhone 12']),
61
+ },
62
+ ]);
63
+ }
64
+ if (options === null || options === void 0 ? void 0 : options.includeBrandedBrowsers) {
65
+ projects.push(...[
66
+ {
67
+ name: 'Microsoft Edge',
68
+ use: Object.assign(Object.assign({}, test_1.devices['Desktop Edge']), { channel: 'msedge' }),
69
+ },
70
+ {
71
+ name: 'Google Chrome',
72
+ use: Object.assign(Object.assign({}, test_1.devices['Desktop Chrome']), { channel: 'chrome' }),
73
+ },
74
+ ]);
75
+ }
76
+ return (0, test_1.defineConfig)({
77
+ testDir: (_a = options.testDir) !== null && _a !== void 0 ? _a : './src',
78
+ outputDir: testResultOuputDir,
79
+ /* Run tests in files in parallel */
80
+ fullyParallel: true,
81
+ /* Fail the build on CI if you accidentally left test.only in the source code. */
82
+ forbidOnly: !!process.env.CI,
83
+ /* Retry on CI only */
84
+ retries: process.env.CI ? 2 : 0,
85
+ /* Opt out of parallel tests on CI. */
86
+ workers: process.env.CI ? 1 : undefined,
87
+ /* Reporter to use. See https://playwright.dev/docs/test-reporters */
88
+ reporter: [
89
+ [
90
+ 'html',
91
+ {
92
+ outputFolder: reporterOutputDir,
93
+ },
94
+ ],
95
+ ],
96
+ projects,
97
+ });
98
+ }
99
+ exports.nxE2EPreset = nxE2EPreset;
@@ -0,0 +1,3 @@
1
+ export declare const nxVersion: any;
2
+ export declare const playwrightVersion = "^1.36.0";
3
+ export declare const eslintPluginPlaywrightVersion = "^0.15.3";
@@ -0,0 +1,6 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.eslintPluginPlaywrightVersion = exports.playwrightVersion = exports.nxVersion = void 0;
4
+ exports.nxVersion = require('../../package.json').version;
5
+ exports.playwrightVersion = '^1.36.0';
6
+ exports.eslintPluginPlaywrightVersion = '^0.15.3';