@nx/playwright 24.0.0-beta.2 → 24.0.0-beta.4
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/dist/index.d.ts +1 -1
- package/dist/index.js +1 -3
- package/dist/src/executors/playwright/{playwright.impl.d.ts → schema.d.ts} +0 -5
- package/dist/src/executors/playwright/schema.js +2 -0
- package/dist/src/executors/wait-for-webserver/wait-for-webserver.impl.js +10 -1
- package/dist/src/generators/configuration/configuration.js +1 -66
- package/dist/src/generators/configuration/files/playwright.config.mts.template +4 -3
- package/dist/src/generators/configuration/schema.d.ts +0 -2
- package/dist/src/generators/init/init.js +2 -8
- package/dist/src/generators/init/schema.d.ts +0 -1
- package/dist/src/migrations/update-24-0-0/disable-wait-for-server-ready.d.ts +4 -0
- package/dist/src/migrations/update-24-0-0/disable-wait-for-server-ready.js +35 -0
- package/dist/src/migrations/update-24-0-0/disable-wait-for-server-ready.md +40 -0
- package/dist/src/migrations/update-24-0-0/finish-inferred-conversion.md +12 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.d.ts +6 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.js +10 -0
- package/dist/src/migrations/update-24-0-0/remove-deprecated-executors.md +40 -0
- package/dist/src/plugins/plugin.d.ts +6 -0
- package/dist/src/plugins/plugin.js +14 -11
- package/dist/src/utils/add-linter.d.ts +0 -1
- package/dist/src/utils/add-linter.js +0 -1
- package/executors.json +0 -5
- package/migrations.json +13 -0
- package/package.json +5 -5
- package/dist/src/executors/playwright/playwright.impl.js +0 -83
- package/dist/src/executors/playwright/schema.json +0 -166
- package/dist/src/utils/deprecation.d.ts +0 -3
- package/dist/src/utils/deprecation.js +0 -16
package/dist/index.d.ts
CHANGED
|
@@ -1,3 +1,3 @@
|
|
|
1
|
-
export {
|
|
1
|
+
export type { PlaywrightExecutorSchema } from './src/executors/playwright/schema';
|
|
2
2
|
export { initGenerator } from './src/generators/init/init';
|
|
3
3
|
export { configurationGenerator } from './src/generators/configuration/configuration';
|
package/dist/index.js
CHANGED
|
@@ -1,8 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.configurationGenerator = exports.initGenerator =
|
|
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; } });
|
|
3
|
+
exports.configurationGenerator = exports.initGenerator = void 0;
|
|
6
4
|
var init_1 = require("./src/generators/init/init");
|
|
7
5
|
Object.defineProperty(exports, "initGenerator", { enumerable: true, get: function () { return init_1.initGenerator; } });
|
|
8
6
|
var configuration_1 = require("./src/generators/configuration/configuration");
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { ExecutorContext } from '@nx/devkit';
|
|
2
1
|
export interface PlaywrightExecutorSchema {
|
|
3
2
|
browser?: 'all' | 'chromium' | 'firefox' | 'webkit' | string;
|
|
4
3
|
config?: string;
|
|
@@ -33,7 +32,3 @@ export interface PlaywrightExecutorSchema {
|
|
|
33
32
|
skipInstall?: boolean;
|
|
34
33
|
cacheDir?: string;
|
|
35
34
|
}
|
|
36
|
-
export declare function playwrightExecutor(options: PlaywrightExecutorSchema, context: ExecutorContext): Promise<{
|
|
37
|
-
success: boolean;
|
|
38
|
-
}>;
|
|
39
|
-
export default playwrightExecutor;
|
|
@@ -21,7 +21,7 @@ const FALLBACK_RETRY_DELAY = 1_000;
|
|
|
21
21
|
// nothing, so it must not replace what the previous probe saw.
|
|
22
22
|
const NO_OBSERVATION = 'the deadline passed before the server responded';
|
|
23
23
|
async function waitForWebserverExecutor(options, context) {
|
|
24
|
-
const servers = options.servers ?? [];
|
|
24
|
+
const servers = withReadyUrl(options.servers ?? []);
|
|
25
25
|
if (servers.length === 0) {
|
|
26
26
|
devkit_1.logger.error('@nx/playwright:wait-for-webserver requires at least one server to wait for.');
|
|
27
27
|
return { success: false };
|
|
@@ -49,6 +49,15 @@ async function waitForWebserverExecutor(options, context) {
|
|
|
49
49
|
}
|
|
50
50
|
}
|
|
51
51
|
exports.default = waitForWebserverExecutor;
|
|
52
|
+
// The address the server task reported when it signaled readiness. It names no
|
|
53
|
+
// server, so it only moves the url of a gate waiting for exactly one.
|
|
54
|
+
function withReadyUrl(servers) {
|
|
55
|
+
const readyUrl = process.env.NX_READY_URL;
|
|
56
|
+
if (!readyUrl || servers.length !== 1 || servers[0].port != null) {
|
|
57
|
+
return servers;
|
|
58
|
+
}
|
|
59
|
+
return [{ ...servers[0], url: (0, devkit_1.getReadyUrl)(servers[0].url) }];
|
|
60
|
+
}
|
|
52
61
|
// A malformed URL, an out-of-range port and a proxy that cannot be used are all
|
|
53
62
|
// inputs that can never become valid, so they are rejected up front instead of
|
|
54
63
|
// being retried until the timeout and reported as a slow server. An unusable
|
|
@@ -7,7 +7,6 @@ const internal_1 = require("@nx/devkit/internal");
|
|
|
7
7
|
const devkit_1 = require("@nx/devkit");
|
|
8
8
|
const js_1 = require("@nx/js");
|
|
9
9
|
const internal_2 = require("@nx/js/internal");
|
|
10
|
-
const deprecation_1 = require("../../utils/deprecation");
|
|
11
10
|
const child_process_1 = require("child_process");
|
|
12
11
|
const path = tslib_1.__importStar(require("path"));
|
|
13
12
|
const add_linter_1 = require("../../utils/add-linter");
|
|
@@ -16,7 +15,7 @@ const versions_1 = require("../../utils/versions");
|
|
|
16
15
|
const init_1 = require("../init/init");
|
|
17
16
|
const internal_3 = require("@nx/eslint/internal");
|
|
18
17
|
function configurationGenerator(tree, options) {
|
|
19
|
-
return configurationGeneratorInternal(tree,
|
|
18
|
+
return configurationGeneratorInternal(tree, options);
|
|
20
19
|
}
|
|
21
20
|
async function configurationGeneratorInternal(tree, rawOptions) {
|
|
22
21
|
(0, assert_supported_playwright_version_1.assertSupportedPlaywrightVersion)(tree);
|
|
@@ -25,7 +24,6 @@ async function configurationGeneratorInternal(tree, rawOptions) {
|
|
|
25
24
|
tasks.push(await (0, init_1.initGenerator)(tree, {
|
|
26
25
|
skipFormat: true,
|
|
27
26
|
skipPackageJson: options.skipPackageJson,
|
|
28
|
-
addPlugin: options.addPlugin,
|
|
29
27
|
}));
|
|
30
28
|
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
31
29
|
const offsetFromProjectRoot = (0, devkit_1.offsetFromRoot)(projectConfig.root);
|
|
@@ -135,14 +133,6 @@ async function configurationGeneratorInternal(tree, rawOptions) {
|
|
|
135
133
|
}
|
|
136
134
|
ignoreTestOutput(tree, options);
|
|
137
135
|
}
|
|
138
|
-
const hasPlugin = (0, devkit_1.readNxJson)(tree).plugins?.some((p) => typeof p === 'string'
|
|
139
|
-
? p === '@nx/playwright/plugin'
|
|
140
|
-
: p.plugin === '@nx/playwright/plugin');
|
|
141
|
-
if (!hasPlugin) {
|
|
142
|
-
(0, deprecation_1.warnPlaywrightExecutorGenerating)();
|
|
143
|
-
addE2eTarget(tree, options);
|
|
144
|
-
setupE2ETargetDefaults(tree);
|
|
145
|
-
}
|
|
146
136
|
tasks.push(await (0, add_linter_1.addLinterToPlaywrightProject)(tree, {
|
|
147
137
|
project: options.project,
|
|
148
138
|
linter: options.linter,
|
|
@@ -151,7 +141,6 @@ async function configurationGeneratorInternal(tree, rawOptions) {
|
|
|
151
141
|
directory: options.directory,
|
|
152
142
|
enableTypedLinting: (0, internal_3.isTypedLintingEnabled)(options),
|
|
153
143
|
rootProject: options.rootProject ?? projectConfig.root === '.',
|
|
154
|
-
addPlugin: options.addPlugin,
|
|
155
144
|
}));
|
|
156
145
|
if (options.js) {
|
|
157
146
|
const { ModuleKind } = (0, internal_2.ensureTypescript)();
|
|
@@ -179,10 +168,6 @@ async function configurationGeneratorInternal(tree, rawOptions) {
|
|
|
179
168
|
return (0, devkit_1.runTasksInSerial)(...tasks);
|
|
180
169
|
}
|
|
181
170
|
async function normalizeOptions(tree, options) {
|
|
182
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
183
|
-
const addPlugin = options.addPlugin ??
|
|
184
|
-
(process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
185
|
-
nxJson.useInferencePlugins !== false);
|
|
186
171
|
const linter = await (0, internal_2.normalizeLinterOption)(tree, options.linter);
|
|
187
172
|
if (!options.webServerCommand || !options.webServerAddress) {
|
|
188
173
|
const { webServerCommand, webServerAddress } = await promptForMissingServeData(options.project);
|
|
@@ -191,7 +176,6 @@ async function normalizeOptions(tree, options) {
|
|
|
191
176
|
}
|
|
192
177
|
return {
|
|
193
178
|
...options,
|
|
194
|
-
addPlugin,
|
|
195
179
|
linter,
|
|
196
180
|
directory: options.directory ?? 'e2e',
|
|
197
181
|
};
|
|
@@ -248,55 +232,6 @@ function recommendVsCodeExtensions(tree) {
|
|
|
248
232
|
});
|
|
249
233
|
}
|
|
250
234
|
}
|
|
251
|
-
function setupE2ETargetDefaults(tree) {
|
|
252
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
253
|
-
if (!nxJson.namedInputs) {
|
|
254
|
-
return;
|
|
255
|
-
}
|
|
256
|
-
// E2e targets depend on all their project's sources + production sources of dependencies
|
|
257
|
-
const productionFileSet = !!nxJson.namedInputs?.production;
|
|
258
|
-
// Either a `target: 'e2e'` default or a default keyed on the executor
|
|
259
|
-
// we're about to scaffold will apply to the new target — consider both
|
|
260
|
-
// before deciding to add cache/inputs. Target-keyed wins when both are
|
|
261
|
-
// present.
|
|
262
|
-
const existingForTarget = (0, internal_1.findTargetDefault)(nxJson.targetDefaults, {
|
|
263
|
-
target: 'e2e',
|
|
264
|
-
});
|
|
265
|
-
const existingForExecutor = (0, internal_1.findTargetDefault)(nxJson.targetDefaults, {
|
|
266
|
-
executor: '@nx/playwright:playwright',
|
|
267
|
-
});
|
|
268
|
-
const existingCache = existingForTarget?.cache ?? existingForExecutor?.cache;
|
|
269
|
-
const existingInputs = existingForTarget?.inputs ?? existingForExecutor?.inputs;
|
|
270
|
-
const patch = {};
|
|
271
|
-
if (existingCache === undefined) {
|
|
272
|
-
patch.cache = true;
|
|
273
|
-
}
|
|
274
|
-
if (existingInputs === undefined) {
|
|
275
|
-
patch.inputs = ['default', productionFileSet ? '^production' : '^default'];
|
|
276
|
-
}
|
|
277
|
-
if (Object.keys(patch).length > 0) {
|
|
278
|
-
(0, internal_1.upsertTargetDefault)(tree, nxJson, { target: 'e2e', ...patch });
|
|
279
|
-
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
280
|
-
}
|
|
281
|
-
}
|
|
282
|
-
function addE2eTarget(tree, options) {
|
|
283
|
-
const projectConfig = (0, devkit_1.readProjectConfiguration)(tree, options.project);
|
|
284
|
-
if (projectConfig?.targets?.e2e) {
|
|
285
|
-
throw new Error(`Project ${options.project} already has an e2e target.
|
|
286
|
-
Rename or remove the existing e2e target.`);
|
|
287
|
-
}
|
|
288
|
-
projectConfig.targets ??= {};
|
|
289
|
-
projectConfig.targets.e2e = {
|
|
290
|
-
executor: '@nx/playwright:playwright',
|
|
291
|
-
outputs: [`{workspaceRoot}/dist/.playwright/${projectConfig.root}`],
|
|
292
|
-
options: {
|
|
293
|
-
// Generator emits `playwright.config.mts` (`.mjs` for `--js`) so the
|
|
294
|
-
// legacy executor's `--config` flag must point at the same extension.
|
|
295
|
-
config: `${projectConfig.root}/playwright.config.${options.js ? 'mjs' : 'mts'}`,
|
|
296
|
-
},
|
|
297
|
-
};
|
|
298
|
-
(0, devkit_1.updateProjectConfiguration)(tree, options.project, projectConfig);
|
|
299
|
-
}
|
|
300
235
|
function ignoreTestOutput(tree, options) {
|
|
301
236
|
// Make sure playwright outputs are not linted.
|
|
302
237
|
if (options.linter === 'eslint') {
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
import { defineConfig, devices } from '@playwright/test';
|
|
2
2
|
import { nxE2EPreset } from '@nx/playwright/preset';
|
|
3
|
-
<% if (webServerCommand && webServerAddress) { %>import { workspaceRoot } from '@nx/devkit';<% } %>
|
|
3
|
+
<% if (webServerCommand && webServerAddress) { %>import { getReadyUrl, workspaceRoot } from '@nx/devkit';<% } %>
|
|
4
4
|
|
|
5
5
|
// For CI, you may want to set BASE_URL to the deployed application.
|
|
6
|
-
|
|
6
|
+
<% if (webServerCommand && webServerAddress) { %>// getReadyUrl moves the address to the port the dev server task reported.
|
|
7
|
+
const baseURL = process.env['BASE_URL'] || getReadyUrl('<%= webServerAddress %>');<% } else { %>const baseURL = process.env['BASE_URL'] || '<% if(webServerAddress) {%><%= webServerAddress %><% } else {%>http://localhost:3000<% } %>';<% } %>
|
|
7
8
|
|
|
8
9
|
/**
|
|
9
10
|
* Read environment variables from file.
|
|
@@ -32,7 +33,7 @@ export default defineConfig({
|
|
|
32
33
|
/* Run your local dev server before starting the tests */<% if(webServerCommand && webServerAddress) {%>
|
|
33
34
|
webServer: {
|
|
34
35
|
command: '<%= webServerCommand %>',
|
|
35
|
-
url: '<%= webServerAddress %>',
|
|
36
|
+
url: getReadyUrl('<%= webServerAddress %>'),
|
|
36
37
|
reuseExistingServer: true,
|
|
37
38
|
cwd: workspaceRoot
|
|
38
39
|
},<% } else {%>
|
|
@@ -27,11 +27,9 @@ export interface ConfigurationGeneratorSchema {
|
|
|
27
27
|
**/
|
|
28
28
|
webServerAddress?: string;
|
|
29
29
|
rootProject?: boolean;
|
|
30
|
-
addPlugin?: boolean;
|
|
31
30
|
}
|
|
32
31
|
|
|
33
32
|
export interface NormalizedGeneratorOptions extends ConfigurationGeneratorSchema {
|
|
34
|
-
addPlugin: boolean;
|
|
35
33
|
directory: string;
|
|
36
34
|
linter: LinterType;
|
|
37
35
|
}
|
|
@@ -8,24 +8,18 @@ const plugin_1 = require("../../plugins/plugin");
|
|
|
8
8
|
const assert_supported_playwright_version_1 = require("../../utils/assert-supported-playwright-version");
|
|
9
9
|
const versions_1 = require("../../utils/versions");
|
|
10
10
|
function initGenerator(tree, options) {
|
|
11
|
-
return initGeneratorInternal(tree,
|
|
11
|
+
return initGeneratorInternal(tree, options);
|
|
12
12
|
}
|
|
13
13
|
async function initGeneratorInternal(tree, options) {
|
|
14
14
|
(0, assert_supported_playwright_version_1.assertSupportedPlaywrightVersion)(tree);
|
|
15
15
|
const tasks = [];
|
|
16
|
-
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
17
|
-
const addPluginDefault = process.env.NX_ADD_PLUGINS !== 'false' &&
|
|
18
|
-
nxJson.useInferencePlugins !== false;
|
|
19
|
-
options.addPlugin ??= addPluginDefault;
|
|
20
16
|
if (!options.skipPackageJson) {
|
|
21
17
|
tasks.push((0, devkit_1.addDependenciesToPackageJson)(tree, {}, {
|
|
22
18
|
'@nx/playwright': versions_1.nxVersion,
|
|
23
19
|
'@playwright/test': versions_1.playwrightVersion,
|
|
24
20
|
}, undefined, options.keepExistingVersions ?? true));
|
|
25
21
|
}
|
|
26
|
-
|
|
27
|
-
await (0, internal_1.addPlugin)(tree, await (0, devkit_1.createProjectGraphAsync)(), '@nx/playwright/plugin', plugin_1.createNodesV2, { targetName: ['e2e', 'playwright:e2e', 'playwright-e2e'] }, options.updatePackageScripts);
|
|
28
|
-
}
|
|
22
|
+
await (0, internal_1.addPlugin)(tree, await (0, devkit_1.createProjectGraphAsync)(), '@nx/playwright/plugin', plugin_1.createNodesV2, { targetName: ['e2e', 'playwright:e2e', 'playwright-e2e'] }, options.updatePackageScripts);
|
|
29
23
|
if (!options.skipFormat) {
|
|
30
24
|
await (0, devkit_1.formatFiles)(tree);
|
|
31
25
|
}
|
|
@@ -0,0 +1,35 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = update;
|
|
4
|
+
const devkit_1 = require("@nx/devkit");
|
|
5
|
+
const pluginName = '@nx/playwright/plugin';
|
|
6
|
+
async function update(tree) {
|
|
7
|
+
const nxJson = (0, devkit_1.readNxJson)(tree);
|
|
8
|
+
if (!nxJson?.plugins) {
|
|
9
|
+
return { skipAgentic: true };
|
|
10
|
+
}
|
|
11
|
+
let changed = false;
|
|
12
|
+
nxJson.plugins = nxJson.plugins.map((plugin) => {
|
|
13
|
+
if (typeof plugin === 'string') {
|
|
14
|
+
if (plugin !== pluginName) {
|
|
15
|
+
return plugin;
|
|
16
|
+
}
|
|
17
|
+
changed = true;
|
|
18
|
+
return { plugin, options: { waitForServerReady: false } };
|
|
19
|
+
}
|
|
20
|
+
if (plugin.plugin !== pluginName) {
|
|
21
|
+
return plugin;
|
|
22
|
+
}
|
|
23
|
+
const options = (plugin.options ?? {});
|
|
24
|
+
if (options.waitForServerReady !== undefined) {
|
|
25
|
+
return plugin;
|
|
26
|
+
}
|
|
27
|
+
changed = true;
|
|
28
|
+
return { ...plugin, options: { ...options, waitForServerReady: false } };
|
|
29
|
+
});
|
|
30
|
+
if (!changed) {
|
|
31
|
+
return { skipAgentic: true };
|
|
32
|
+
}
|
|
33
|
+
(0, devkit_1.updateNxJson)(tree, nxJson);
|
|
34
|
+
await (0, devkit_1.formatFiles)(tree);
|
|
35
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#### Keep Playwright e2e tasks from waiting for the dev server to be ready
|
|
2
|
+
|
|
3
|
+
`@nx/playwright/plugin` has a new `waitForServerReady` option, on by default. With it on, the inferred e2e tasks wait for the dev server task's `readyWhen` and get the address it reported in `NX_READY_URL`. Before, they only waited for the dev server task to start.
|
|
4
|
+
|
|
5
|
+
This migration sets `waitForServerReady: false` on every `@nx/playwright/plugin` entry in `nx.json`, so existing workspaces keep the old behavior. Entries that already set the option stay as they are. To opt in, remove the option or set it to `true`.
|
|
6
|
+
|
|
7
|
+
#### Sample code changes
|
|
8
|
+
|
|
9
|
+
##### Before
|
|
10
|
+
|
|
11
|
+
```json title="nx.json"
|
|
12
|
+
{
|
|
13
|
+
"plugins": [
|
|
14
|
+
"@nx/playwright/plugin",
|
|
15
|
+
{
|
|
16
|
+
"plugin": "@nx/playwright/plugin",
|
|
17
|
+
"include": ["apps/admin-e2e/**"],
|
|
18
|
+
"options": { "targetName": "e2e" }
|
|
19
|
+
}
|
|
20
|
+
]
|
|
21
|
+
}
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
##### After
|
|
25
|
+
|
|
26
|
+
```json title="nx.json"
|
|
27
|
+
{
|
|
28
|
+
"plugins": [
|
|
29
|
+
{
|
|
30
|
+
"plugin": "@nx/playwright/plugin",
|
|
31
|
+
"options": { "waitForServerReady": false }
|
|
32
|
+
},
|
|
33
|
+
{
|
|
34
|
+
"plugin": "@nx/playwright/plugin",
|
|
35
|
+
"include": ["apps/admin-e2e/**"],
|
|
36
|
+
"options": { "targetName": "e2e", "waitForServerReady": false }
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
# Replace removed @nx/playwright executors with inferred tasks
|
|
2
|
+
|
|
3
|
+
Nx 24 removed `@nx/playwright:playwright` (including old `@nrwl` aliases).
|
|
4
|
+
|
|
5
|
+
Before changing anything, check for leftover work: a project target, a package.json target or a `targetDefaults` entry still uses a removed executor, or the advisory context reports a conversion error. If none applies, make no changes and stop. Treat each advisory-context item as pending work.
|
|
6
|
+
|
|
7
|
+
1. Inspect all affected projects and workspace defaults. Repair config-loading errors first. Do not restore executor registrations or install older Nx packages.
|
|
8
|
+
2. Preserve Playwright config, browser projects, CI sharding and webServer orchestration.
|
|
9
|
+
3. Register `@nx/playwright/plugin` with options/includes that preserve custom target names and mixed inferred/explicit projects. Replace remaining removed-executor targets, including those in package.json and filtered targetDefaults. Transfer their behavior before removing obsolete defaults. Preserve configurations, dependencies, cache inputs/outputs and environment behavior. Do not silently delete unsupported options or unrelated targets. Migrate old @nrwl aliases too.
|
|
10
|
+
4. Run project graph creation with the daemon and graph cache disabled (`NX_DAEMON=false NX_CACHE_PROJECT_GRAPH=false`), using the workspace package manager. Inspect resolved project targets and verify each migrated entrypoint exists and is inferred (a thin alias to an inferred target is acceptable). Resolve graph errors before completing this migration, even if task validation was skipped. Configs must load for subsequent migrations.
|
|
11
|
+
5. By default run relevant real builds/tests with task cache disabled, including alternate configurations. Honor an existing preference to skip expensive task validation; otherwise offer that option when validation is slow. Skipping expensive tasks never skips conversion or the graph check. Report each skipped task as unverified. Never weaken assertions or change application behavior to make checks pass.
|
|
12
|
+
6. Report converted projects, graph validation, task results and any skipped checks. Unconverted targets or a broken graph mean the migration is incomplete. Investigate task failures and distinguish missing environment prerequisites from conversion regressions; do not claim a working workspace with unresolved regressions.
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.default = update;
|
|
4
|
+
const internal_1 = require("@nx/devkit/internal");
|
|
5
|
+
function update(tree) {
|
|
6
|
+
return (0, internal_1.migrateRemovedExecutors)(tree, ['@nx/playwright:playwright', '@nrwl/playwright:playwright'], async (tree, options) => {
|
|
7
|
+
const { convertToInferred } = require('../../generators/convert-to-inferred/convert-to-inferred');
|
|
8
|
+
return convertToInferred(tree, options);
|
|
9
|
+
});
|
|
10
|
+
}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
#### Convert `@nx/playwright:playwright` targets to inferred tasks
|
|
2
|
+
|
|
3
|
+
Nx 24 removes the `@nx/playwright:playwright` executor and its `@nrwl/playwright:playwright` alias. The migration registers `@nx/playwright/plugin` in `nx.json` and converts the targets that use those executors to inferred tasks. Options the plugin does not infer stay on the target. A target with nothing left to override is removed from project configuration. When several projects share the same remaining options, those options move to a `targetDefaults` entry scoped to the plugin. `targetDefaults` entries keyed by a removed executor are removed once no target uses that executor.
|
|
4
|
+
|
|
5
|
+
The migration lists the targets the converter cannot convert safely. In agentic runs, an AI prompt finishes them and validates the project graph.
|
|
6
|
+
|
|
7
|
+
#### Sample code changes
|
|
8
|
+
|
|
9
|
+
##### Before
|
|
10
|
+
|
|
11
|
+
```json title="myapp-e2e/project.json"
|
|
12
|
+
{
|
|
13
|
+
"name": "myapp-e2e",
|
|
14
|
+
"targets": {
|
|
15
|
+
"e2e": {
|
|
16
|
+
"executor": "@nx/playwright:playwright",
|
|
17
|
+
"outputs": ["{workspaceRoot}/dist/.playwright/myapp-e2e"],
|
|
18
|
+
"options": {
|
|
19
|
+
"config": "myapp-e2e/playwright.config.ts"
|
|
20
|
+
}
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
```
|
|
25
|
+
|
|
26
|
+
##### After
|
|
27
|
+
|
|
28
|
+
```json title="nx.json"
|
|
29
|
+
{
|
|
30
|
+
"plugins": [
|
|
31
|
+
{
|
|
32
|
+
"plugin": "@nx/playwright/plugin",
|
|
33
|
+
"options": {
|
|
34
|
+
"ciTargetName": "e2e-ci",
|
|
35
|
+
"targetName": "e2e"
|
|
36
|
+
}
|
|
37
|
+
}
|
|
38
|
+
]
|
|
39
|
+
}
|
|
40
|
+
```
|
|
@@ -16,6 +16,12 @@ export interface PlaywrightPluginOptions {
|
|
|
16
16
|
* true.
|
|
17
17
|
*/
|
|
18
18
|
waitForWebServer?: boolean;
|
|
19
|
+
/**
|
|
20
|
+
* Whether the inferred dependencies on the web server tasks wait for those
|
|
21
|
+
* tasks' `readyWhen` (`waitFor: 'ready'`) rather than for them to start.
|
|
22
|
+
* Defaults to true.
|
|
23
|
+
*/
|
|
24
|
+
waitForServerReady?: boolean;
|
|
19
25
|
}
|
|
20
26
|
export declare const createNodes: CreateNodes<PlaywrightPluginOptions>;
|
|
21
27
|
export declare const createNodesV2: CreateNodes<PlaywrightPluginOptions>;
|
|
@@ -205,7 +205,7 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
|
|
|
205
205
|
},
|
|
206
206
|
},
|
|
207
207
|
};
|
|
208
|
-
applyChainDependsOn(baseTargetConfig, e2eChain, e2eReadyTargetName);
|
|
208
|
+
applyChainDependsOn(baseTargetConfig, e2eChain, e2eReadyTargetName, options.waitForServerReady);
|
|
209
209
|
targets[options.targetName] = {
|
|
210
210
|
...baseTargetConfig,
|
|
211
211
|
cache: true,
|
|
@@ -219,10 +219,10 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
|
|
|
219
219
|
outputs: getTargetOutputs(testOutput, reporterOutputs, context.workspaceRoot, projectRoot),
|
|
220
220
|
};
|
|
221
221
|
if (e2eReadyTargetName) {
|
|
222
|
-
targets[e2eReadyTargetName] = buildWaitForWebserverTarget(e2eChain, options.webServerTimeout);
|
|
222
|
+
targets[e2eReadyTargetName] = buildWaitForWebserverTarget(e2eChain, options.webServerTimeout, options.waitForServerReady);
|
|
223
223
|
}
|
|
224
224
|
if (ciReadyTargetName && ciReadyTargetName !== e2eReadyTargetName) {
|
|
225
|
-
targets[ciReadyTargetName] = buildWaitForWebserverTarget(ciChain, options.webServerTimeout);
|
|
225
|
+
targets[ciReadyTargetName] = buildWaitForWebserverTarget(ciChain, options.webServerTimeout, options.waitForServerReady);
|
|
226
226
|
}
|
|
227
227
|
if (options.ciTargetName) {
|
|
228
228
|
// ensure the blob reporter output is the directory containing the blob
|
|
@@ -245,7 +245,7 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
|
|
|
245
245
|
// Unconditionally: the chains can differ in ways the shared-gate check
|
|
246
246
|
// deliberately ignores (an extra uncovered server flips parallelism), and
|
|
247
247
|
// re-deriving is a no-op when they match.
|
|
248
|
-
applyChainDependsOn(ciBaseTargetConfig, ciChain, ciReadyTargetName);
|
|
248
|
+
applyChainDependsOn(ciBaseTargetConfig, ciChain, ciReadyTargetName, options.waitForServerReady);
|
|
249
249
|
const groupName = 'E2E (CI)';
|
|
250
250
|
metadata = { targetGroups: { [groupName]: [] } };
|
|
251
251
|
const ciTargetGroup = metadata.targetGroups[groupName];
|
|
@@ -279,7 +279,7 @@ async function buildPlaywrightTargets(configFilePath, projectRoot, options, cont
|
|
|
279
279
|
const targetName = `${options.ciTargetName}--${relativeSpecFilePath}`;
|
|
280
280
|
ciTargetGroup.push(targetName);
|
|
281
281
|
targets[targetName] = {
|
|
282
|
-
...(0, internal_1.applyTestFileDirectives)(ciBaseTargetConfig, context.workspaceRoot, testFile,
|
|
282
|
+
...(0, internal_1.applyTestFileDirectives)(ciBaseTargetConfig, context.workspaceRoot, testFile, { ignoreServerInputs: true }),
|
|
283
283
|
options: {
|
|
284
284
|
...ciBaseTargetConfig.options,
|
|
285
285
|
env: getAtomizedTaskEnvVars(reporterOutputs, outputSubfolder),
|
|
@@ -401,6 +401,7 @@ function normalizeOptions(options) {
|
|
|
401
401
|
ciTargetName,
|
|
402
402
|
mergeReportsTargetName: `${ciTargetName}--merge-reports`,
|
|
403
403
|
waitForWebServer: options?.waitForWebServer ?? true,
|
|
404
|
+
waitForServerReady: options?.waitForServerReady !== false,
|
|
404
405
|
};
|
|
405
406
|
}
|
|
406
407
|
function getTestOutput(playwrightConfig) {
|
|
@@ -546,7 +547,7 @@ function sameChain(a, b) {
|
|
|
546
547
|
return (JSON.stringify(a.commandTasks) === JSON.stringify(b.commandTasks) &&
|
|
547
548
|
JSON.stringify(a.readinessServers) === JSON.stringify(b.readinessServers));
|
|
548
549
|
}
|
|
549
|
-
function buildWaitForWebserverTarget(chain, webServerTimeout) {
|
|
550
|
+
function buildWaitForWebserverTarget(chain, webServerTimeout, waitForServerReady) {
|
|
550
551
|
return {
|
|
551
552
|
executor: '@nx/playwright:wait-for-webserver',
|
|
552
553
|
cache: false,
|
|
@@ -554,7 +555,7 @@ function buildWaitForWebserverTarget(chain, webServerTimeout) {
|
|
|
554
555
|
servers: chain.readinessServers,
|
|
555
556
|
...(webServerTimeout != null ? { timeout: webServerTimeout } : {}),
|
|
556
557
|
},
|
|
557
|
-
dependsOn: getDependsOn(chain.commandTasks),
|
|
558
|
+
dependsOn: getDependsOn(chain.commandTasks, waitForServerReady),
|
|
558
559
|
metadata: {
|
|
559
560
|
technologies: ['playwright'],
|
|
560
561
|
description: 'Waits for the E2E web server(s) to be ready before the Playwright test tasks run.',
|
|
@@ -693,11 +694,12 @@ function chainRequiresSerialization(chain) {
|
|
|
693
694
|
// was inferred). Set together with parallelism so a config that inherits one
|
|
694
695
|
// state (the atomized CI base copies the e2e config) cannot end up carrying
|
|
695
696
|
// both.
|
|
696
|
-
function applyChainDependsOn(targetConfig, chain, readyTargetName) {
|
|
697
|
+
function applyChainDependsOn(targetConfig, chain, readyTargetName, waitForServerReady) {
|
|
697
698
|
if (chain.commandTasks.length) {
|
|
699
|
+
const serverDependsOn = getDependsOn(chain.commandTasks, waitForServerReady);
|
|
698
700
|
targetConfig.dependsOn = readyTargetName
|
|
699
|
-
? [...
|
|
700
|
-
:
|
|
701
|
+
? [...serverDependsOn, { target: readyTargetName }]
|
|
702
|
+
: serverDependsOn;
|
|
701
703
|
}
|
|
702
704
|
else {
|
|
703
705
|
delete targetConfig.dependsOn;
|
|
@@ -709,7 +711,7 @@ function applyChainDependsOn(targetConfig, chain, readyTargetName) {
|
|
|
709
711
|
delete targetConfig.parallelism;
|
|
710
712
|
}
|
|
711
713
|
}
|
|
712
|
-
function getDependsOn(tasks) {
|
|
714
|
+
function getDependsOn(tasks, waitForServerReady) {
|
|
713
715
|
const projectsPerTask = new Map();
|
|
714
716
|
for (const { project, target } of tasks) {
|
|
715
717
|
if (!projectsPerTask.has(target)) {
|
|
@@ -720,6 +722,7 @@ function getDependsOn(tasks) {
|
|
|
720
722
|
return Array.from(projectsPerTask.entries()).map(([target, projects]) => ({
|
|
721
723
|
projects,
|
|
722
724
|
target,
|
|
725
|
+
...(waitForServerReady ? { waitFor: 'ready' } : {}),
|
|
723
726
|
}));
|
|
724
727
|
}
|
|
725
728
|
function normalizeOutput(path, workspaceRoot, projectRoot) {
|
|
@@ -15,6 +15,5 @@ export interface PlaywrightLinterOptions {
|
|
|
15
15
|
* Directory from the project root, where the playwright files will be located.
|
|
16
16
|
**/
|
|
17
17
|
directory: string;
|
|
18
|
-
addPlugin?: boolean;
|
|
19
18
|
}
|
|
20
19
|
export declare function addLinterToPlaywrightProject(tree: Tree, options: PlaywrightLinterOptions): Promise<GeneratorCallback>;
|
|
@@ -23,7 +23,6 @@ async function addLinterToPlaywrightProject(tree, options) {
|
|
|
23
23
|
enableTypedLinting,
|
|
24
24
|
skipPackageJson: options.skipPackageJson,
|
|
25
25
|
rootProject: options.rootProject,
|
|
26
|
-
addPlugin: options.addPlugin,
|
|
27
26
|
}));
|
|
28
27
|
}
|
|
29
28
|
// Everything below configures ESLint — predefined configs, `extends`, ignore
|
package/executors.json
CHANGED
|
@@ -1,10 +1,5 @@
|
|
|
1
1
|
{
|
|
2
2
|
"executors": {
|
|
3
|
-
"playwright": {
|
|
4
|
-
"implementation": "./dist/src/executors/playwright/playwright.impl",
|
|
5
|
-
"schema": "./dist/src/executors/playwright/schema.json",
|
|
6
|
-
"description": "Run Playwright tests."
|
|
7
|
-
},
|
|
8
3
|
"merge-reports": {
|
|
9
4
|
"implementation": "./dist/src/executors/merge-reports/merge-reports.impl",
|
|
10
5
|
"schema": "./dist/src/executors/merge-reports/schema.json",
|
package/migrations.json
CHANGED
|
@@ -5,6 +5,19 @@
|
|
|
5
5
|
"description": "Rename imports of `createNodesV2` from `@nx/playwright/plugin` to the canonical `createNodes` export.",
|
|
6
6
|
"implementation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes",
|
|
7
7
|
"documentation": "./dist/src/migrations/update-23-0-0/migrate-create-nodes-v2-to-create-nodes.md"
|
|
8
|
+
},
|
|
9
|
+
"remove-deprecated-executors": {
|
|
10
|
+
"version": "24.0.0-beta.3",
|
|
11
|
+
"description": "Converts targets using the removed `@nx/playwright` executors to inferred tasks; an AI prompt finishes the targets the converter cannot convert safely and validates the project graph.",
|
|
12
|
+
"implementation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors",
|
|
13
|
+
"prompt": "./dist/src/migrations/update-24-0-0/finish-inferred-conversion.md",
|
|
14
|
+
"documentation": "./dist/src/migrations/update-24-0-0/remove-deprecated-executors.md"
|
|
15
|
+
},
|
|
16
|
+
"update-24-0-0-disable-wait-for-server-ready": {
|
|
17
|
+
"version": "24.0.0-beta.4",
|
|
18
|
+
"description": "Sets `waitForServerReady: false` on `@nx/playwright/plugin` entries in `nx.json` so existing Playwright e2e tasks keep starting without waiting for the dev server to report it is ready.",
|
|
19
|
+
"implementation": "./dist/src/migrations/update-24-0-0/disable-wait-for-server-ready",
|
|
20
|
+
"documentation": "./dist/src/migrations/update-24-0-0/disable-wait-for-server-ready.md"
|
|
8
21
|
}
|
|
9
22
|
}
|
|
10
23
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@nx/playwright",
|
|
3
|
-
"version": "24.0.0-beta.
|
|
3
|
+
"version": "24.0.0-beta.4",
|
|
4
4
|
"private": false,
|
|
5
5
|
"type": "commonjs",
|
|
6
6
|
"files": [
|
|
@@ -75,16 +75,16 @@
|
|
|
75
75
|
"supportsOptionalMigrations": true
|
|
76
76
|
},
|
|
77
77
|
"dependencies": {
|
|
78
|
-
"@nx/devkit": "24.0.0-beta.
|
|
79
|
-
"@nx/eslint": "24.0.0-beta.
|
|
80
|
-
"@nx/js": "24.0.0-beta.
|
|
78
|
+
"@nx/devkit": "24.0.0-beta.4",
|
|
79
|
+
"@nx/eslint": "24.0.0-beta.4",
|
|
80
|
+
"@nx/js": "24.0.0-beta.4",
|
|
81
81
|
"https-proxy-agent": "^7.0.6",
|
|
82
82
|
"minimatch": "10.2.5",
|
|
83
83
|
"semver": "^7.6.3",
|
|
84
84
|
"tslib": "^2.3.0"
|
|
85
85
|
},
|
|
86
86
|
"devDependencies": {
|
|
87
|
-
"nx": "24.0.0-beta.
|
|
87
|
+
"nx": "24.0.0-beta.4"
|
|
88
88
|
},
|
|
89
89
|
"peerDependencies": {
|
|
90
90
|
"@playwright/test": "^1.36.0"
|
|
@@ -1,83 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.playwrightExecutor = playwrightExecutor;
|
|
4
|
-
const devkit_1 = require("@nx/devkit");
|
|
5
|
-
const child_process_1 = require("child_process");
|
|
6
|
-
const deprecation_1 = require("../../utils/deprecation");
|
|
7
|
-
async function playwrightExecutor(options, context) {
|
|
8
|
-
(0, deprecation_1.warnPlaywrightExecutorDeprecation)();
|
|
9
|
-
const projectRoot = context.projectGraph?.nodes?.[context?.projectName]?.data?.root;
|
|
10
|
-
if (!projectRoot) {
|
|
11
|
-
throw new Error(`Unable to find the Project Root for ${context.projectName}. Is it set in the project.json?`);
|
|
12
|
-
}
|
|
13
|
-
if (!options.skipInstall) {
|
|
14
|
-
devkit_1.output.log({
|
|
15
|
-
title: 'Ensuring Playwright is installed.',
|
|
16
|
-
bodyLines: ['use --skipInstall to skip installation.'],
|
|
17
|
-
});
|
|
18
|
-
const pmc = (0, devkit_1.getPackageManagerCommand)();
|
|
19
|
-
(0, child_process_1.execSync)(`${pmc.exec} playwright install`, {
|
|
20
|
-
cwd: devkit_1.workspaceRoot,
|
|
21
|
-
stdio: 'inherit',
|
|
22
|
-
windowsHide: true,
|
|
23
|
-
});
|
|
24
|
-
}
|
|
25
|
-
const args = createArgs(options);
|
|
26
|
-
const env = options.cacheDir
|
|
27
|
-
? { ...process.env, PWTEST_CACHE_DIR: options.cacheDir }
|
|
28
|
-
: undefined;
|
|
29
|
-
const p = runPlaywright(args, context.root, env);
|
|
30
|
-
p.stdout.on('data', (message) => {
|
|
31
|
-
process.stdout.write(message);
|
|
32
|
-
});
|
|
33
|
-
p.stderr.on('data', (message) => {
|
|
34
|
-
process.stderr.write(message);
|
|
35
|
-
});
|
|
36
|
-
return new Promise((resolve) => {
|
|
37
|
-
p.on('close', (code) => {
|
|
38
|
-
resolve({ success: code === 0 });
|
|
39
|
-
});
|
|
40
|
-
});
|
|
41
|
-
}
|
|
42
|
-
function createArgs(opts, exclude = ['skipInstall', 'cacheDir']) {
|
|
43
|
-
const args = [];
|
|
44
|
-
const { testFiles, ...rest } = opts;
|
|
45
|
-
if (testFiles) {
|
|
46
|
-
args.push(...testFiles);
|
|
47
|
-
}
|
|
48
|
-
for (const key in rest) {
|
|
49
|
-
if (exclude.includes(key))
|
|
50
|
-
continue;
|
|
51
|
-
const value = opts[key];
|
|
52
|
-
// NOTE: playwright doesn't accept pascalCase args, only kebab-case
|
|
53
|
-
const arg = (0, devkit_1.names)(key).fileName;
|
|
54
|
-
if (Array.isArray(value)) {
|
|
55
|
-
args.push(...value.map((v) => `--${arg}=${v.trim()}`));
|
|
56
|
-
}
|
|
57
|
-
else if (typeof value === 'boolean') {
|
|
58
|
-
// NOTE: playwright don't accept --arg=false, instead just don't pass the arg.
|
|
59
|
-
if (value) {
|
|
60
|
-
args.push(`--${arg}`);
|
|
61
|
-
}
|
|
62
|
-
}
|
|
63
|
-
else {
|
|
64
|
-
args.push(`--${arg}=${value}`);
|
|
65
|
-
}
|
|
66
|
-
}
|
|
67
|
-
return args;
|
|
68
|
-
}
|
|
69
|
-
function runPlaywright(args, cwd, env) {
|
|
70
|
-
try {
|
|
71
|
-
const cli = require.resolve('@playwright/test/cli');
|
|
72
|
-
return (0, child_process_1.fork)(cli, ['test', ...args], {
|
|
73
|
-
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
|
|
74
|
-
cwd,
|
|
75
|
-
...(env ? { env } : {}),
|
|
76
|
-
});
|
|
77
|
-
}
|
|
78
|
-
catch (e) {
|
|
79
|
-
console.error(e);
|
|
80
|
-
throw new Error('Unable to run playwright. Is @playwright/test installed?');
|
|
81
|
-
}
|
|
82
|
-
}
|
|
83
|
-
exports.default = playwrightExecutor;
|
|
@@ -1,166 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"$schema": "https://json-schema.org/schema",
|
|
3
|
-
"version": 2,
|
|
4
|
-
"title": "Playwright executor",
|
|
5
|
-
"description": "Run Playwright tests.",
|
|
6
|
-
"x-deprecated": "The `@nx/playwright:playwright` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/playwright:convert-to-inferred` to migrate to the `@nx/playwright/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.",
|
|
7
|
-
"type": "object",
|
|
8
|
-
"properties": {
|
|
9
|
-
"browser": {
|
|
10
|
-
"type": "string",
|
|
11
|
-
"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'",
|
|
12
|
-
"x-priority": "important"
|
|
13
|
-
},
|
|
14
|
-
"config": {
|
|
15
|
-
"type": "string",
|
|
16
|
-
"description": "Configuration file, or a test directory with optional",
|
|
17
|
-
"x-completion-type": "file",
|
|
18
|
-
"x-completion-glob": "playwright?(*)@(.js|.cjs|.mjs|.ts|.cts|.mtx)",
|
|
19
|
-
"x-priority": "important"
|
|
20
|
-
},
|
|
21
|
-
"debug": {
|
|
22
|
-
"type": "boolean",
|
|
23
|
-
"description": "Run tests with Playwright Inspector. Shortcut for 'PWDEBUG=1' environment variable and '--timeout=0',--max-failures=1 --headed --workers=1' options"
|
|
24
|
-
},
|
|
25
|
-
"lastFailed": {
|
|
26
|
-
"type": "boolean",
|
|
27
|
-
"description": "Run only the tests that failed in the last run"
|
|
28
|
-
},
|
|
29
|
-
"forbidOnly": {
|
|
30
|
-
"type": "boolean",
|
|
31
|
-
"description": "Fail if test.only is called"
|
|
32
|
-
},
|
|
33
|
-
"fullyParallel": {
|
|
34
|
-
"type": "boolean",
|
|
35
|
-
"description": "Run all tests in parallel"
|
|
36
|
-
},
|
|
37
|
-
"grep": {
|
|
38
|
-
"alias": "g",
|
|
39
|
-
"type": "string",
|
|
40
|
-
"description": "Only run tests matching this regular expression"
|
|
41
|
-
},
|
|
42
|
-
"globalTimeout": {
|
|
43
|
-
"type": "number",
|
|
44
|
-
"description": "Maximum time this test suite can run in milliseconds"
|
|
45
|
-
},
|
|
46
|
-
"grepInvert": {
|
|
47
|
-
"alias": "gv",
|
|
48
|
-
"type": "string",
|
|
49
|
-
"description": "Only run tests that do not match this regular expression"
|
|
50
|
-
},
|
|
51
|
-
"testFiles": {
|
|
52
|
-
"alias": "t",
|
|
53
|
-
"type": "array",
|
|
54
|
-
"description": "Test files to run",
|
|
55
|
-
"items": {
|
|
56
|
-
"type": "string"
|
|
57
|
-
}
|
|
58
|
-
},
|
|
59
|
-
"headed": {
|
|
60
|
-
"type": "boolean",
|
|
61
|
-
"description": "Run tests in headed browsers",
|
|
62
|
-
"x-priority": "important"
|
|
63
|
-
},
|
|
64
|
-
"ignoreSnapshots": {
|
|
65
|
-
"type": "boolean",
|
|
66
|
-
"description": "Ignore screenshot and snapshot expectations"
|
|
67
|
-
},
|
|
68
|
-
"workers": {
|
|
69
|
-
"alias": "j",
|
|
70
|
-
"oneOf": [{ "type": "number" }, { "type": "string" }],
|
|
71
|
-
"description": "Number of concurrent workers or percentage of logical CPU cores, use 1 to run in a single worker"
|
|
72
|
-
},
|
|
73
|
-
"list": {
|
|
74
|
-
"type": "boolean",
|
|
75
|
-
"description": "Collect all the tests and report them, but do not run"
|
|
76
|
-
},
|
|
77
|
-
"maxFailures": {
|
|
78
|
-
"alias": "x",
|
|
79
|
-
"oneOf": [{ "type": "number" }, { "type": "boolean" }],
|
|
80
|
-
"description": "Stop after the first N failures"
|
|
81
|
-
},
|
|
82
|
-
"noDeps": {
|
|
83
|
-
"type": "boolean",
|
|
84
|
-
"description": "Do not run project dependencies"
|
|
85
|
-
},
|
|
86
|
-
"output": {
|
|
87
|
-
"type": "string",
|
|
88
|
-
"description": "Folder for output artifacts"
|
|
89
|
-
},
|
|
90
|
-
"passWithNoTests": {
|
|
91
|
-
"type": "boolean",
|
|
92
|
-
"description": "Makes test run succeed even if no tests were found",
|
|
93
|
-
"default": true
|
|
94
|
-
},
|
|
95
|
-
"project": {
|
|
96
|
-
"description": "Only run tests from the specified list of projects",
|
|
97
|
-
"type": "array",
|
|
98
|
-
"items": {
|
|
99
|
-
"type": "string"
|
|
100
|
-
}
|
|
101
|
-
},
|
|
102
|
-
"quiet": {
|
|
103
|
-
"alias": "q",
|
|
104
|
-
"type": "boolean",
|
|
105
|
-
"description": "Suppress stdio"
|
|
106
|
-
},
|
|
107
|
-
"repeatEach": {
|
|
108
|
-
"type": "number",
|
|
109
|
-
"description": "Run each test N times"
|
|
110
|
-
},
|
|
111
|
-
"reporter": {
|
|
112
|
-
"type": "string",
|
|
113
|
-
"description": "Common Reporter values to use, comma-separated, 'list', 'line', 'dot', 'json', 'junit', 'null', 'github', 'html', 'blob'. To configure reporter options, use the playwright configuration."
|
|
114
|
-
},
|
|
115
|
-
"retries": {
|
|
116
|
-
"type": "number",
|
|
117
|
-
"description": "Maximum retry count for flaky tests, zero for no retries"
|
|
118
|
-
},
|
|
119
|
-
"shard": {
|
|
120
|
-
"type": "string",
|
|
121
|
-
"description": "Shard tests and execute only the selected shard, specify in the form 'current/all', 1-based, for example '3/5'"
|
|
122
|
-
},
|
|
123
|
-
"timeout": {
|
|
124
|
-
"type": "number",
|
|
125
|
-
"description": "Specify test timeout threshold in milliseconds, zero for unlimited"
|
|
126
|
-
},
|
|
127
|
-
"trace": {
|
|
128
|
-
"type": "string",
|
|
129
|
-
"enum": [
|
|
130
|
-
"on",
|
|
131
|
-
"off",
|
|
132
|
-
"on-first-retry",
|
|
133
|
-
"on-all-retries",
|
|
134
|
-
"retain-on-failure"
|
|
135
|
-
],
|
|
136
|
-
"description": "Force tracing mode, can be 'on', 'off', 'on-first-retry', 'on-all-retries', 'retain-on-failure'"
|
|
137
|
-
},
|
|
138
|
-
"updateSnapshots": {
|
|
139
|
-
"alias": "u",
|
|
140
|
-
"type": "boolean",
|
|
141
|
-
"description": "Update snapshots with actual results. Snapshots will be created if missing."
|
|
142
|
-
},
|
|
143
|
-
"ui": {
|
|
144
|
-
"type": "boolean",
|
|
145
|
-
"description": "Run tests in interactive UI mode"
|
|
146
|
-
},
|
|
147
|
-
"uiHost": {
|
|
148
|
-
"type": "string",
|
|
149
|
-
"description": "Host to serve UI on; specifying this option opens UI in a browser tab"
|
|
150
|
-
},
|
|
151
|
-
"uiPort": {
|
|
152
|
-
"type": "number",
|
|
153
|
-
"description": "Port to serve UI on, 0 for any free port; specifying this option opens UI in a browser tab"
|
|
154
|
-
},
|
|
155
|
-
"skipInstall": {
|
|
156
|
-
"type": "boolean",
|
|
157
|
-
"description": "Skip running playwright install before running playwright tests. This is to ensure that playwright browsers are installed before running tests.",
|
|
158
|
-
"default": false
|
|
159
|
-
},
|
|
160
|
-
"cacheDir": {
|
|
161
|
-
"type": "string",
|
|
162
|
-
"description": "Directory for Playwright internal cache (browser binaries, etc.). Sets the PWTEST_CACHE_DIR environment variable."
|
|
163
|
-
}
|
|
164
|
-
},
|
|
165
|
-
"required": []
|
|
166
|
-
}
|
|
@@ -1,3 +0,0 @@
|
|
|
1
|
-
export declare const PLAYWRIGHT_EXECUTOR_DEPRECATION_MESSAGE = "The `@nx/playwright:playwright` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/playwright:convert-to-inferred` to migrate to the `@nx/playwright/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.";
|
|
2
|
-
export declare function warnPlaywrightExecutorDeprecation(): void;
|
|
3
|
-
export declare function warnPlaywrightExecutorGenerating(): void;
|
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
"use strict";
|
|
2
|
-
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
-
exports.PLAYWRIGHT_EXECUTOR_DEPRECATION_MESSAGE = void 0;
|
|
4
|
-
exports.warnPlaywrightExecutorDeprecation = warnPlaywrightExecutorDeprecation;
|
|
5
|
-
exports.warnPlaywrightExecutorGenerating = warnPlaywrightExecutorGenerating;
|
|
6
|
-
const devkit_1 = require("@nx/devkit");
|
|
7
|
-
// TODO(v24): Remove the @nx/playwright:playwright executor. The inferred
|
|
8
|
-
// plugin (@nx/playwright/plugin) and the convert-to-inferred generator stay
|
|
9
|
-
// supported.
|
|
10
|
-
exports.PLAYWRIGHT_EXECUTOR_DEPRECATION_MESSAGE = 'The `@nx/playwright:playwright` executor is deprecated and will be removed in Nx v24. Run `nx g @nx/playwright:convert-to-inferred` to migrate to the `@nx/playwright/plugin` inferred targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.';
|
|
11
|
-
function warnPlaywrightExecutorDeprecation() {
|
|
12
|
-
devkit_1.logger.warn(exports.PLAYWRIGHT_EXECUTOR_DEPRECATION_MESSAGE);
|
|
13
|
-
}
|
|
14
|
-
function warnPlaywrightExecutorGenerating() {
|
|
15
|
-
devkit_1.logger.warn('Generating a target that uses the deprecated `@nx/playwright:playwright` executor. The executor will be removed in Nx v24. Run `nx g @nx/playwright:convert-to-inferred` next to migrate this target to the `@nx/playwright/plugin` inferred plugin and prevent future generators from emitting executor targets. See https://nx.dev/docs/guides/tasks--caching/convert-to-inferred for details.');
|
|
16
|
-
}
|