diff --git a/.eslintrc.js b/.eslintrc.js index a81369b61c5f1..fd7e9183781ea 100644 --- a/.eslintrc.js +++ b/.eslintrc.js @@ -294,7 +294,7 @@ module.exports = { 'packages/e2e-test-utils-playwright/**/*.[tj]s', ], extends: [ - 'plugin:eslint-plugin-playwright/playwright-test', + 'plugin:@wordpress/eslint-plugin/test-playwright', 'plugin:@typescript-eslint/base', ], parserOptions: { @@ -308,7 +308,6 @@ module.exports = { rules: { '@wordpress/no-global-active-element': 'off', '@wordpress/no-global-get-selection': 'off', - 'playwright/no-page-pause': 'error', 'no-restricted-syntax': [ 'error', { diff --git a/package-lock.json b/package-lock.json index cabb3c8c18155..f5d327696992b 100644 --- a/package-lock.json +++ b/package-lock.json @@ -182,7 +182,6 @@ "eslint-plugin-import": "2.25.2", "eslint-plugin-jest": "27.2.1", "eslint-plugin-jest-dom": "5.0.2", - "eslint-plugin-playwright": "0.8.0", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "5.7.2", @@ -5670,18 +5669,6 @@ "fsevents": "2.3.2" } }, - "node_modules/@playwright/test/node_modules/playwright-core": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.0.tgz", - "integrity": "sha512-Z9Ij17X5Z3bjpp6XKujGBp9Gv4eViESac9aDmwgQFUEJBW0K80T21m/Z+XJQlu4cNsvPygw33b6V1Va6Bda5zQ==", - "dev": true, - "bin": { - "playwright": "cli.js" - }, - "engines": { - "node": ">=14" - } - }, "node_modules/@pmmmwh/react-refresh-webpack-plugin": { "version": "0.5.2", "resolved": "https://registry.npmjs.org/@pmmmwh/react-refresh-webpack-plugin/-/react-refresh-webpack-plugin-0.5.2.tgz", @@ -28815,13 +28802,13 @@ "dev": true }, "node_modules/eslint-plugin-playwright": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.8.0.tgz", - "integrity": "sha512-9uJH25m6H3jwU5O7bHD5M8cLx46L72EnIUe3dZqTox6M+WzOFzeUWaDJHHCdLGXZ8XlAU4mbCZnP7uhjKepfRA==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.15.3.tgz", + "integrity": "sha512-LQMW5y0DLK5Fnpya7JR1oAYL2/7Y9wDiYw6VZqlKqcRGSgjbVKNqxraphk7ra1U3Bb5EK444xMgUlQPbMg2M1g==", "dev": true, "peerDependencies": { "eslint": ">=7", - "eslint-plugin-jest": ">=24" + "eslint-plugin-jest": ">=25" }, "peerDependenciesMeta": { "eslint-plugin-jest": { @@ -44185,6 +44172,18 @@ "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", "dev": true }, + "node_modules/playwright-core": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.0.tgz", + "integrity": "sha512-Z9Ij17X5Z3bjpp6XKujGBp9Gv4eViESac9aDmwgQFUEJBW0K80T21m/Z+XJQlu4cNsvPygw33b6V1Va6Bda5zQ==", + "dev": true, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=14" + } + }, "node_modules/please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -55338,6 +55337,7 @@ "eslint-plugin-jest": "^27.2.1", "eslint-plugin-jsdoc": "^46.4.6", "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-playwright": "^0.15.3", "eslint-plugin-prettier": "^3.3.0", "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.3.0", @@ -56083,6 +56083,7 @@ "@wordpress/babel-preset-default": "file:../babel-preset-default", "@wordpress/browserslist-config": "file:../browserslist-config", "@wordpress/dependency-extraction-webpack-plugin": "file:../dependency-extraction-webpack-plugin", + "@wordpress/e2e-test-utils-playwright": "file:../e2e-test-utils-playwright", "@wordpress/eslint-plugin": "file:../eslint-plugin", "@wordpress/jest-preset-default": "file:../jest-preset-default", "@wordpress/npm-package-json-lint-config": "file:../npm-package-json-lint-config", @@ -56116,6 +56117,7 @@ "minimist": "^1.2.0", "npm-package-json-lint": "^6.4.0", "npm-packlist": "^3.0.0", + "playwright-core": "1.32.0", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", "prettier": "npm:wp-prettier@2.8.5", @@ -56142,6 +56144,7 @@ "npm": ">=6.14.4" }, "peerDependencies": { + "@playwright/test": "^1.32.0", "react": "^18.0.0", "react-dom": "^18.0.0" } @@ -60191,14 +60194,6 @@ "@types/node": "*", "fsevents": "2.3.2", "playwright-core": "1.32.0" - }, - "dependencies": { - "playwright-core": { - "version": "1.32.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.0.tgz", - "integrity": "sha512-Z9Ij17X5Z3bjpp6XKujGBp9Gv4eViESac9aDmwgQFUEJBW0K80T21m/Z+XJQlu4cNsvPygw33b6V1Va6Bda5zQ==", - "dev": true - } } }, "@pmmmwh/react-refresh-webpack-plugin": { @@ -67852,6 +67847,7 @@ "eslint-plugin-jest": "^27.2.1", "eslint-plugin-jsdoc": "^46.4.6", "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-playwright": "^0.15.3", "eslint-plugin-prettier": "^3.3.0", "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.3.0", @@ -68284,6 +68280,7 @@ "@wordpress/babel-preset-default": "file:../babel-preset-default", "@wordpress/browserslist-config": "file:../browserslist-config", "@wordpress/dependency-extraction-webpack-plugin": "file:../dependency-extraction-webpack-plugin", + "@wordpress/e2e-test-utils-playwright": "file:../e2e-test-utils-playwright", "@wordpress/eslint-plugin": "file:../eslint-plugin", "@wordpress/jest-preset-default": "file:../jest-preset-default", "@wordpress/npm-package-json-lint-config": "file:../npm-package-json-lint-config", @@ -68317,6 +68314,7 @@ "minimist": "^1.2.0", "npm-package-json-lint": "^6.4.0", "npm-packlist": "^3.0.0", + "playwright-core": "1.32.0", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", "prettier": "npm:wp-prettier@2.8.5", @@ -80583,9 +80581,9 @@ } }, "eslint-plugin-playwright": { - "version": "0.8.0", - "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.8.0.tgz", - "integrity": "sha512-9uJH25m6H3jwU5O7bHD5M8cLx46L72EnIUe3dZqTox6M+WzOFzeUWaDJHHCdLGXZ8XlAU4mbCZnP7uhjKepfRA==", + "version": "0.15.3", + "resolved": "https://registry.npmjs.org/eslint-plugin-playwright/-/eslint-plugin-playwright-0.15.3.tgz", + "integrity": "sha512-LQMW5y0DLK5Fnpya7JR1oAYL2/7Y9wDiYw6VZqlKqcRGSgjbVKNqxraphk7ra1U3Bb5EK444xMgUlQPbMg2M1g==", "dev": true }, "eslint-plugin-prettier": { @@ -92182,6 +92180,12 @@ "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", "dev": true }, + "playwright-core": { + "version": "1.32.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.32.0.tgz", + "integrity": "sha512-Z9Ij17X5Z3bjpp6XKujGBp9Gv4eViESac9aDmwgQFUEJBW0K80T21m/Z+XJQlu4cNsvPygw33b6V1Va6Bda5zQ==", + "dev": true + }, "please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", diff --git a/package.json b/package.json index d8640a128c10f..9fc475fe70dcc 100644 --- a/package.json +++ b/package.json @@ -194,7 +194,6 @@ "eslint-plugin-import": "2.25.2", "eslint-plugin-jest": "27.2.1", "eslint-plugin-jest-dom": "5.0.2", - "eslint-plugin-playwright": "0.8.0", "eslint-plugin-ssr-friendly": "1.0.6", "eslint-plugin-storybook": "0.6.13", "eslint-plugin-testing-library": "5.7.2", @@ -314,7 +313,7 @@ "test:create-block": "bash ./bin/test-create-block.sh", "test:e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", "test:e2e:debug": "wp-scripts --inspect-brk test-e2e --runInBand --no-cache --verbose --config packages/e2e-tests/jest.config.js --puppeteer-devtools", - "test:e2e:playwright": "playwright test --config test/e2e/playwright.config.ts", + "test:e2e:playwright": "wp-scripts test-playwright --config test/e2e/playwright.config.ts", "test:e2e:storybook": "playwright test --config test/storybook-playwright/playwright.config.ts", "test:e2e:watch": "npm run test:e2e -- --watch", "test:native": "cross-env NODE_ENV=test jest --config test/native/jest.config.js", @@ -323,8 +322,8 @@ "test:native:perf": "cross-env TEST_RUNNER_ARGS='--runInBand --config test/native/jest.config.js --testMatch \"**/performance/*.native.[jt]s?(x)\"' reassure", "test:native:perf:baseline": "cross-env TEST_RUNNER_ARGS='--runInBand --config test/native/jest.config.js --testMatch \"**/performance/*.native.[jt]s?(x)\"' reassure --baseline", "test:native:update": "npm run test:native -- --updateSnapshot", - "test:performance": "playwright test --config test/performance/playwright.config.ts", - "test:performance:debug": "playwright test --config test/performance/playwright.config.ts --debug", + "test:performance": "wp-scripts test-playwright --config test/performance/playwright.config.ts", + "test:performance:debug": "wp-scripts test-playwright --config test/performance/playwright.config.ts --debug", "test:php": "npm-run-all lint:php test:unit:php", "test:php:watch": "wp-env run --env-cwd='wp-content/plugins/gutenberg' tests-cli composer run-script test:watch", "test:unit": "wp-scripts test-unit-js --config test/unit/jest.config.js", diff --git a/packages/eslint-plugin/CHANGELOG.md b/packages/eslint-plugin/CHANGELOG.md index d8d39769a279b..05276fb340bb3 100644 --- a/packages/eslint-plugin/CHANGELOG.md +++ b/packages/eslint-plugin/CHANGELOG.md @@ -2,6 +2,10 @@ ## Unreleased +### Enhancement + +- Added a new `test-playwright` ruleset using [`eslint-plugin-playwright`](https://www.npmjs.com/package/eslint-plugin-playwright). + ## 15.1.0 (2023-08-31) ## 15.0.0 (2023-08-16) diff --git a/packages/eslint-plugin/README.md b/packages/eslint-plugin/README.md index cbc297d6b99e5..1619778add661 100644 --- a/packages/eslint-plugin/README.md +++ b/packages/eslint-plugin/README.md @@ -53,6 +53,7 @@ Alternatively, you can opt-in to only the more granular rulesets offered by the - `react` – rules for React components. - `test-e2e` – rules for end-to-end tests written in Puppeteer. - `test-unit`– rules for unit tests written in Jest. +- `test-playwright` – rules for end-to-end tests written in Playwright. For example, if your project does not use React, you could consider extending including only the ESNext rules in your project using the following `extends` definition: diff --git a/packages/eslint-plugin/configs/test-playwright.js b/packages/eslint-plugin/configs/test-playwright.js new file mode 100644 index 0000000000000..c3c72be05c1e9 --- /dev/null +++ b/packages/eslint-plugin/configs/test-playwright.js @@ -0,0 +1,3 @@ +module.exports = { + extends: [ 'plugin:playwright/recommended' ], +}; diff --git a/packages/eslint-plugin/package.json b/packages/eslint-plugin/package.json index 9fada24d1782d..d546f19e0b64f 100644 --- a/packages/eslint-plugin/package.json +++ b/packages/eslint-plugin/package.json @@ -42,6 +42,7 @@ "eslint-plugin-jest": "^27.2.1", "eslint-plugin-jsdoc": "^46.4.6", "eslint-plugin-jsx-a11y": "^6.5.1", + "eslint-plugin-playwright": "^0.15.3", "eslint-plugin-prettier": "^3.3.0", "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.3.0", diff --git a/packages/scripts/CHANGELOG.md b/packages/scripts/CHANGELOG.md index b7dce7e73cf58..1e11550a8f07c 100644 --- a/packages/scripts/CHANGELOG.md +++ b/packages/scripts/CHANGELOG.md @@ -2,13 +2,17 @@ ## Unreleased +### Enhancement + +- Added support for `test-playwright` script ([#53108](https://github.com/WordPress/gutenberg/pull/53108)). + ## 26.12.0 (2023-08-31) ## 26.11.0 (2023-08-16) ### Enhancement -- Updated `npm-package-json-lint` peer dependency to require v6.0.0 [#53636](https://github.com/WordPress/gutenberg/pull/53636) +- Updated `npm-package-json-lint` peer dependency to require v6.0.0 [#53636](https://github.com/WordPress/gutenberg/pull/53636). - The bundled `@svgr/webpack` dependency has been updated from requiring ^6.2.1 to requiring ^8.0.1 ([#53630](https://github.com/WordPress/gutenberg/pull/53630)). - The bundled `cssnano` dependency has been updated from requiring ^5.07 to requiring ^6.0.1 ([#53630](https://github.com/WordPress/gutenberg/pull/53630)). diff --git a/packages/scripts/README.md b/packages/scripts/README.md index d34dab634a2b4..8e80d806b17e7 100644 --- a/packages/scripts/README.md +++ b/packages/scripts/README.md @@ -491,6 +491,47 @@ Should there be any situation where you want to provide your own Jest config, yo - there is a file called `jest-unit.config.js`, `jest-unit.config.json`, `jest.config.js`, or `jest.config.json` in the top-level directory of your package (at the same level than your `package.json`). - a `jest` object can be provided in the `package.json` file with the test configuration. +### `test-plyawright` + +Launches the Playwright End-To-End (E2E) test runner. Similar to Puppeteer, it provides a high-level API to control a headless browser. + +Refer to the [Getting Started guide](https://playwright.dev/docs/writing-tests) to learn how to write tests. + +_Example:_ + +```json +{ + "scripts": { + "test:playwright": "wp-scripts test-playwright", + "test:playwright:help": "wp-scripts test-playwright --help", + "test:playwright:debug": "wp-scripts test-playwright --debug" + } +} +``` + +This is how you execute those scripts using the presented setup: + +- `npm run test:playwright` - runs all tests. +- `npm run test:playwright:help` - prints all available options to configure the test runner. +- `npm run test:playwright:debug` - runs all tests interactively with the Playwright inspector. +- `npm run test:playwright FILE_NAME` - runs a specific test file. +- `npm run test:playwright -- --watch` - runs all tests interactively with watch mode and enhanced debugging. + +By default, Playwright looks for JavaScript or TypeScript files with `.test` or `.spec` suffix in the project root-level `/specs` folder, for example `/specs/login-screen.wrong-credentials.spec.ts`. + +This script automatically detects the best config to start Playwright, but sometimes you may need to specify custom options. +To do so, you can add a file called `playwright.config.ts` or `playwright.config.js` in the top-level directory of your package (at the same level as your `package.json`). + +#### Failed Test Artifacts + +When tests fail, snapshots will be taken of the page and stored in the `artifacts/` directory at the root of your project. These snapshots may help debug failed tests during development or when running tests in a CI environment. + +The `artifacts/` directory can be customized by setting the `WP_ARTIFACTS_PATH` environment variable to the relative path of the desired directory within your project's root. For example: to change the default directory from `artifacts/` to `my/custom/artifacts`, you could use `WP_ARTIFACTS_PATH=my/custom/artifacts npm run test:playwright`. + +#### Advanced information + +You are able to use all of Playwright's [CLI options](https://playwright.dev/docs/test-cli#reference). You can also run `./node_modules/.bin/wp-scripts test-playwright --help` or `npm run test:playwright:help` (as mentioned above) to view all the available options. Learn more in the [Advanced Usage](#advanced-usage) section. + ## Passing Node.js options `wp-scripts` supports the full array of [Node.js CLI options](https://nodejs.org/api/cli.html). They can be passed after the `wp-scripts` command and before the script name. diff --git a/packages/scripts/config/playwright.config.ts b/packages/scripts/config/playwright.config.ts new file mode 100644 index 0000000000000..16ee210bdfb86 --- /dev/null +++ b/packages/scripts/config/playwright.config.ts @@ -0,0 +1,63 @@ +/** + * External dependencies + */ +const path = require( 'path' ); +const { fileURLToPath } = require( 'url' ); +const { defineConfig, devices } = require( '@playwright/test' ); + +process.env.WP_ARTIFACTS_PATH ??= path.join( process.cwd(), 'artifacts' ); +process.env.STORAGE_STATE_PATH ??= path.join( + process.env.WP_ARTIFACTS_PATH, + 'storage-states/admin.json' +); + +const config = defineConfig( { + reporter: process.env.CI ? [ [ 'github' ] ] : [ [ 'list' ] ], + forbidOnly: !! process.env.CI, + // fullyParallel: false, + workers: 1, + retries: process.env.CI ? 2 : 0, + timeout: parseInt( process.env.TIMEOUT || '', 10 ) || 100_000, // Defaults to 100 seconds. + // Don't report slow test "files", as we will be running our tests in serial. + reportSlowTests: null, + testDir: './specs', + outputDir: path.join( process.env.WP_ARTIFACTS_PATH, 'test-results' ), + snapshotPathTemplate: + '{testDir}/{testFileDir}/__snapshots__/{arg}-{projectName}{ext}', + globalSetup: fileURLToPath( + new URL( './playwright/global-setup.ts', 'file:' + __filename ).href + ), + use: { + baseURL: process.env.WP_BASE_URL || 'http://localhost:8889', + headless: true, + viewport: { + width: 960, + height: 700, + }, + ignoreHTTPSErrors: true, + locale: 'en-US', + contextOptions: { + reducedMotion: 'reduce', + strictSelectors: true, + }, + storageState: process.env.STORAGE_STATE_PATH, + actionTimeout: 10_000, // 10 seconds. + trace: 'retain-on-failure', + screenshot: 'only-on-failure', + video: 'on-first-retry', + }, + webServer: { + command: 'npm run wp-env start', + port: 8889, + timeout: 120_000, // 120 seconds. + reuseExistingServer: true, + }, + projects: [ + { + name: 'chromium', + use: { ...devices[ 'Desktop Chrome' ] }, + }, + ], +} ); + +export default config; diff --git a/packages/scripts/config/playwright/global-setup.ts b/packages/scripts/config/playwright/global-setup.ts new file mode 100644 index 0000000000000..10f2822fdfe1a --- /dev/null +++ b/packages/scripts/config/playwright/global-setup.ts @@ -0,0 +1,31 @@ +/** + * External dependencies + */ +import { request } from '@playwright/test'; +import type { FullConfig } from '@playwright/test'; + +/** + * WordPress dependencies + */ +import { RequestUtils } from '@wordpress/e2e-test-utils-playwright'; + +async function globalSetup( config: FullConfig ) { + const { storageState, baseURL } = config.projects[ 0 ].use; + const storageStatePath = + typeof storageState === 'string' ? storageState : undefined; + + const requestContext = await request.newContext( { + baseURL, + } ); + + const requestUtils = new RequestUtils( requestContext, { + storageStatePath, + } ); + + // Authenticate and save the storageState to disk. + await requestUtils.setupRest(); + + await requestContext.dispose(); +} + +export default globalSetup; diff --git a/packages/scripts/package.json b/packages/scripts/package.json index faad42de3585a..12ca7854da191 100644 --- a/packages/scripts/package.json +++ b/packages/scripts/package.json @@ -38,6 +38,7 @@ "@wordpress/babel-preset-default": "file:../babel-preset-default", "@wordpress/browserslist-config": "file:../browserslist-config", "@wordpress/dependency-extraction-webpack-plugin": "file:../dependency-extraction-webpack-plugin", + "@wordpress/e2e-test-utils-playwright": "file:../e2e-test-utils-playwright", "@wordpress/eslint-plugin": "file:../eslint-plugin", "@wordpress/jest-preset-default": "file:../jest-preset-default", "@wordpress/npm-package-json-lint-config": "file:../npm-package-json-lint-config", @@ -71,6 +72,7 @@ "minimist": "^1.2.0", "npm-package-json-lint": "^6.4.0", "npm-packlist": "^3.0.0", + "playwright-core": "1.32.0", "postcss": "^8.4.5", "postcss-loader": "^6.2.1", "prettier": "npm:wp-prettier@2.8.5", @@ -90,6 +92,7 @@ "webpack-dev-server": "^4.4.0" }, "peerDependencies": { + "@playwright/test": "^1.32.0", "react": "^18.0.0", "react-dom": "^18.0.0" }, diff --git a/packages/scripts/scripts/test-playwright.js b/packages/scripts/scripts/test-playwright.js new file mode 100644 index 0000000000000..4c10fb6f62114 --- /dev/null +++ b/packages/scripts/scripts/test-playwright.js @@ -0,0 +1,70 @@ +// Do this as the first thing so that any code reading it knows the right env. +process.env.BABEL_ENV = 'test'; +process.env.NODE_ENV = 'test'; + +// Makes the script crash on unhandled rejections instead of silently +// ignoring them. In the future, promise rejections that are not handled will +// terminate the Node.js process with a non-zero exit code. +process.on( 'unhandledRejection', ( err ) => { + throw err; +} ); + +/** + * External dependencies + */ +const { resolve } = require( 'node:path' ); +const { sync: spawn } = require( 'cross-spawn' ); + +/** + * Internal dependencies + */ +const { + fromConfigRoot, + hasProjectFile, + hasArgInCLI, + getArgsFromCLI, +} = require( '../utils' ); + +const result = spawn( + 'node', + [ require.resolve( 'playwright-core/cli' ), 'install' ], + { + stdio: 'inherit', + } +); + +if ( result.status > 0 ) { + process.exit( result.status ); +} + +const config = + ! hasArgInCLI( '--config' ) && + ! hasProjectFile( 'playwright.config.ts' ) && + ! hasProjectFile( 'playwright.config.js' ) + ? [ '--config', fromConfigRoot( 'playwright.config.ts' ) ] + : []; + +// Set the default artifacts path. +if ( ! process.env.WP_ARTIFACTS_PATH ) { + process.env.WP_ARTIFACTS_PATH = resolve( + process.env.GITHUB_WORKSPACE || process.cwd(), + 'artifacts' + ); +} + +const testResult = spawn( + 'npx', + [ + require.resolve( '@playwright/test/cli' ), + 'test', + ...config, + ...getArgsFromCLI(), + ], + { + stdio: 'inherit', + } +); + +if ( testResult.status > 0 ) { + process.exit( testResult.status ); +} diff --git a/test/e2e/playwright.config.ts b/test/e2e/playwright.config.ts index e1724a61d6126..742ca54f4f2ac 100644 --- a/test/e2e/playwright.config.ts +++ b/test/e2e/playwright.config.ts @@ -2,56 +2,23 @@ * External dependencies */ import os from 'os'; -import path from 'path'; import { fileURLToPath } from 'url'; import { defineConfig, devices } from '@playwright/test'; -const STORAGE_STATE_PATH = - process.env.STORAGE_STATE_PATH || - path.join( process.cwd(), 'artifacts/storage-states/admin.json' ); +/** + * WordPress dependencies + */ +const baseConfig = require( '@wordpress/scripts/config/playwright.config' ); const config = defineConfig( { + ...baseConfig.default, reporter: process.env.CI ? [ [ 'github' ], [ './config/flaky-tests-reporter.ts' ] ] : 'list', - forbidOnly: !! process.env.CI, workers: 1, - retries: process.env.CI ? 2 : 0, - timeout: parseInt( process.env.TIMEOUT || '', 10 ) || 100_000, // Defaults to 100 seconds. - // Don't report slow test "files", as we will be running our tests in serial. - reportSlowTests: null, - testDir: fileURLToPath( new URL( './specs', 'file:' + __filename ).href ), - outputDir: path.join( process.cwd(), 'artifacts/test-results' ), - snapshotPathTemplate: - '{testDir}/{testFileDir}/__snapshots__/{arg}-{projectName}{ext}', globalSetup: fileURLToPath( new URL( './config/global-setup.ts', 'file:' + __filename ).href ), - use: { - baseURL: process.env.WP_BASE_URL || 'http://localhost:8889', - headless: true, - viewport: { - width: 960, - height: 700, - }, - ignoreHTTPSErrors: true, - locale: 'en-US', - contextOptions: { - reducedMotion: 'reduce', - strictSelectors: true, - }, - storageState: STORAGE_STATE_PATH, - actionTimeout: 10_000, // 10 seconds. - trace: 'retain-on-failure', - screenshot: 'only-on-failure', - video: 'on-first-retry', - }, - webServer: { - command: 'npm run wp-env start', - port: 8889, - timeout: 120_000, // 120 seconds. - reuseExistingServer: true, - }, projects: [ { name: 'chromium', diff --git a/test/e2e/specs/editor/blocks/image.spec.js b/test/e2e/specs/editor/blocks/image.spec.js index c9d7bbe464428..887e96afe707e 100644 --- a/test/e2e/specs/editor/blocks/image.spec.js +++ b/test/e2e/specs/editor/blocks/image.spec.js @@ -459,9 +459,10 @@ test.describe( 'Image', () => { attributes: { url }, }, ] = blocks; - expect( - await imageBlock.getByRole( 'img' ).getAttribute( 'src' ) - ).toBe( url ); + await expect( imageBlock.getByRole( 'img' ) ).toHaveAttribute( + 'src', + url + ); expect( new URL( url ).host, 'should be updated to the media library' @@ -492,9 +493,10 @@ test.describe( 'Image', () => { }, ] = blocks; expect( url ).not.toBe( firstUrl ); - expect( - await imageBlock.getByRole( 'img' ).getAttribute( 'src' ) - ).toBe( url ); + await expect( imageBlock.getByRole( 'img' ) ).toHaveAttribute( + 'src', + url + ); expect( new URL( url ).host, 'should be updated to the media library' @@ -1182,7 +1184,7 @@ test.describe( 'Image - interactivity', () => { page.getByRole( 'combobox', { name: 'Animation', } ) - ).not.toBeVisible(); + ).toBeHidden(); } ); test( 'Animation selector should NOT appear if Behavior is Default', async ( { page, @@ -1215,7 +1217,7 @@ test.describe( 'Image - interactivity', () => { page.getByRole( 'combobox', { name: 'Animation', } ) - ).not.toBeVisible(); + ).toBeHidden(); } ); } ); diff --git a/test/e2e/specs/editor/plugins/nonce.spec.js b/test/e2e/specs/editor/plugins/nonce.spec.js index b2c249ac968b8..a05f3618b3641 100644 --- a/test/e2e/specs/editor/plugins/nonce.spec.js +++ b/test/e2e/specs/editor/plugins/nonce.spec.js @@ -16,6 +16,7 @@ test.describe( 'Nonce', () => { await admin.createNewPost(); await page.keyboard.press( 'Enter' ); // Wait until the network is idle. + // eslint-disable-next-line playwright/no-networkidle await page.waitForLoadState( 'networkidle' ); await page.keyboard.type( 'test' ); diff --git a/test/e2e/specs/editor/various/post-editor-template-mode.spec.js b/test/e2e/specs/editor/various/post-editor-template-mode.spec.js index a8e4d04df378e..5d63ff789e4ec 100644 --- a/test/e2e/specs/editor/various/post-editor-template-mode.spec.js +++ b/test/e2e/specs/editor/various/post-editor-template-mode.spec.js @@ -207,6 +207,7 @@ class PostEditorTemplateMode { // Without this, the editor will move focus to body while still typing. // And the save states will not be counted as dirty. // There is likely a bug in the code, waiting for the snackbar above should be enough. + // eslint-disable-next-line playwright/no-networkidle await this.page.waitForLoadState( 'networkidle' ); } diff --git a/test/performance/playwright.config.ts b/test/performance/playwright.config.ts index e17d3c7fc31ca..0918b79d3144d 100644 --- a/test/performance/playwright.config.ts +++ b/test/performance/playwright.config.ts @@ -3,63 +3,32 @@ */ import path from 'path'; import { fileURLToPath } from 'url'; -import { defineConfig, devices } from '@playwright/test'; +import { defineConfig } from '@playwright/test'; + +/** + * WordPress dependencies + */ +const baseConfig = require( '@wordpress/scripts/config/playwright.config' ); -process.env.WP_ARTIFACTS_PATH ??= path.join( process.cwd(), 'artifacts' ); -process.env.STORAGE_STATE_PATH ??= path.join( - process.env.WP_ARTIFACTS_PATH, - 'storage-states/admin.json' -); process.env.ASSETS_PATH = path.join( __dirname, 'assets' ); const config = defineConfig( { + ...baseConfig.default, reporter: process.env.CI ? './config/performance-reporter.ts' : [ [ 'list' ], [ './config/performance-reporter.ts' ] ], forbidOnly: !! process.env.CI, fullyParallel: false, - workers: 1, retries: 0, timeout: parseInt( process.env.TIMEOUT || '', 10 ) || 600_000, // Defaults to 10 minutes. reportSlowTests: null, - testDir: fileURLToPath( new URL( './specs', 'file:' + __filename ).href ), - outputDir: path.join( process.env.WP_ARTIFACTS_PATH, 'test-results' ), - snapshotPathTemplate: - '{testDir}/{testFileDir}/__snapshots__/{arg}-{projectName}{ext}', globalSetup: fileURLToPath( new URL( './config/global-setup.ts', 'file:' + __filename ).href ), use: { - baseURL: process.env.WP_BASE_URL || 'http://localhost:8889', - headless: true, - viewport: { - width: 960, - height: 700, - }, - ignoreHTTPSErrors: true, - locale: 'en-US', - contextOptions: { - reducedMotion: 'reduce', - strictSelectors: true, - }, - storageState: process.env.STORAGE_STATE_PATH, - actionTimeout: 10_000, // 10 seconds. - trace: 'retain-on-failure', - screenshot: 'only-on-failure', + ...baseConfig.default.use, video: 'off', }, - webServer: { - command: 'npm run wp-env start', - port: 8889, - timeout: 120_000, // 120 seconds. - reuseExistingServer: true, - }, - projects: [ - { - name: 'chromium', - use: { ...devices[ 'Desktop Chrome' ] }, - }, - ], } ); export default config; diff --git a/test/performance/specs/front-end-block-theme.spec.js b/test/performance/specs/front-end-block-theme.spec.js index 6ceedba9bd6d5..55845e49f9515 100644 --- a/test/performance/specs/front-end-block-theme.spec.js +++ b/test/performance/specs/front-end-block-theme.spec.js @@ -32,6 +32,7 @@ test.describe( 'Front End Performance', () => { i + 1 } of ${ rounds })`, async ( { page } ) => { // Go to the base URL. + // eslint-disable-next-line playwright/no-networkidle await page.goto( '/', { waitUntil: 'networkidle' } ); // Take the measurements. diff --git a/test/performance/specs/front-end-classic-theme.spec.js b/test/performance/specs/front-end-classic-theme.spec.js index 880da94a11c60..cbc058f4536d6 100644 --- a/test/performance/specs/front-end-classic-theme.spec.js +++ b/test/performance/specs/front-end-classic-theme.spec.js @@ -31,6 +31,7 @@ test.describe( 'Front End Performance', () => { page, } ) => { // Go to the base URL. + // eslint-disable-next-line playwright/no-networkidle await page.goto( '/', { waitUntil: 'networkidle' } ); // Take the measurements.