From c933d8c633234c24bf2b9ba6fc20925920b7fa90 Mon Sep 17 00:00:00 2001 From: Riad Benguella Date: Wed, 17 Jun 2020 14:45:55 +0100 Subject: [PATCH 01/44] Try running our e2e tests using playwright Update playwright packages --- jest-playwright.config.js | 3 + package-lock.json | 1022 +++++++++++++++++ package.json | 4 + packages/e2e-test-utils/package.json | 6 +- .../src/mocks/set-up-response-mocking.js | 6 +- .../src/set-browser-viewport.js | 2 +- packages/e2e-tests/config/setup-playwright.js | 190 +++ packages/e2e-tests/jest.playwright.config.js | 16 + .../e2e-tests/playwright/specs/hello.test.js | 5 + .../editor/various/change-detection.test.js | 13 +- 10 files changed, 1249 insertions(+), 18 deletions(-) create mode 100644 jest-playwright.config.js create mode 100644 packages/e2e-tests/config/setup-playwright.js create mode 100644 packages/e2e-tests/jest.playwright.config.js create mode 100644 packages/e2e-tests/playwright/specs/hello.test.js diff --git a/jest-playwright.config.js b/jest-playwright.config.js new file mode 100644 index 00000000000000..af8abe6888497d --- /dev/null +++ b/jest-playwright.config.js @@ -0,0 +1,3 @@ +module.exports = { + launchBrowserApp: {}, +}; diff --git a/package-lock.json b/package-lock.json index 297e1c5bcb8923..906f2a1b6ab807 100644 --- a/package-lock.json +++ b/package-lock.json @@ -16881,6 +16881,15 @@ "@types/unist": "*" } }, + "@types/wait-on": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/@types/wait-on/-/wait-on-5.3.1.tgz", + "integrity": "sha512-2FFOKCF/YydrMUaqg+fkk49qf0e5rDgwt6aQsMzFQzbS419h2gNOXyiwp/o2yYy27bi/C1z+HgfncryjGzlvgQ==", + "dev": true, + "requires": { + "@types/node": "*" + } + }, "@types/webpack": { "version": "4.41.16", "resolved": "https://registry.npmjs.org/@types/webpack/-/webpack-4.41.16.tgz", @@ -19962,6 +19971,15 @@ "resolved": "https://registry.npmjs.org/appdirsjs/-/appdirsjs-1.2.4.tgz", "integrity": "sha512-WO5StDORR6JF/xYnXk/Fm0yu+iULaV5ULKuUw0Tu+jbgiTlSquaWBCgbpnsHLMXldf+fM3Gxn5p7vjond7He6w==" }, + "append-transform": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/append-transform/-/append-transform-2.0.0.tgz", + "integrity": "sha512-7yeyCEurROLQJFv5Xj4lEGTy0borxepjFv1g22oAdqFu//SrAlDl1O1Nxx15SH1RoliUml6p8dwJW9jvZughhg==", + "dev": true, + "requires": { + "default-require-extensions": "^3.0.0" + } + }, "appium": { "version": "1.20.2", "resolved": "https://registry.npmjs.org/appium/-/appium-1.20.2.tgz", @@ -27338,6 +27356,12 @@ } } }, + "archy": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/archy/-/archy-1.0.0.tgz", + "integrity": "sha1-+cjBN1fMHde8N5rHeyxipcKGjEA=", + "dev": true + }, "are-we-there-yet": { "version": "1.1.5", "resolved": "https://registry.npmjs.org/are-we-there-yet/-/are-we-there-yet-1.1.5.tgz", @@ -29864,6 +29888,32 @@ } } }, + "caching-transform": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/caching-transform/-/caching-transform-4.0.0.tgz", + "integrity": "sha512-kpqOvwXnjjN44D89K5ccQC+RUrsy7jB/XLlRrx0D7/2HNcTPqzsb6XgYoErwko6QsV184CA2YgS1fxDiiDZMWA==", + "dev": true, + "requires": { + "hasha": "^5.0.0", + "make-dir": "^3.0.0", + "package-hash": "^4.0.0", + "write-file-atomic": "^3.0.0" + }, + "dependencies": { + "write-file-atomic": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/write-file-atomic/-/write-file-atomic-3.0.3.tgz", + "integrity": "sha512-AvHcyZ5JnSfq3ioSyjrBkH9yW4m7Ayk8/9My/DD9onKeu/94fwrMocemO2QAJFAlnnDN+ZDS+ZjAR5ua1/PV/Q==", + "dev": true, + "requires": { + "imurmurhash": "^0.1.4", + "is-typedarray": "^1.0.0", + "signal-exit": "^3.0.2", + "typedarray-to-buffer": "^3.1.5" + } + } + } + }, "call-bind": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/call-bind/-/call-bind-1.0.0.tgz", @@ -32711,6 +32761,23 @@ "integrity": "sha512-FJ3UgI4gIl+PHZm53knsuSFpE+nESMr7M4v9QcgB7S63Kj/6WqMiFQJpBBYz1Pt+66bZpP3Q7Lye0Oo9MPKEdg==", "dev": true }, + "default-require-extensions": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/default-require-extensions/-/default-require-extensions-3.0.0.tgz", + "integrity": "sha512-ek6DpXq/SCpvjhpFsLFRVtIxJCRw6fUR42lYMVZuUMK7n8eMz4Uh5clckdBjEpLhn/gEBZo7hDJnJcwdKLKQjg==", + "dev": true, + "requires": { + "strip-bom": "^4.0.0" + }, + "dependencies": { + "strip-bom": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", + "integrity": "sha512-3xurFv5tEgii33Zi8Jtp55wEIILR9eh34FAW00PZf+JnSsTmV/ioewSgQl97JHvgjoRGwPShsWm+IdrxB35d0w==", + "dev": true + } + } + }, "defaults": { "version": "1.0.3", "resolved": "https://registry.npmjs.org/defaults/-/defaults-1.0.3.tgz", @@ -34054,6 +34121,12 @@ "integrity": "sha512-FYpuxEjMeDvU4rulKqFdukQyZSTpzhg4ScQHrAosrlVpR6GFyaw14f74yn2+4BugniIS0Frpg7TvwZocU4ZMTw==", "dev": true }, + "es6-error": { + "version": "4.1.1", + "resolved": "https://registry.npmjs.org/es6-error/-/es6-error-4.1.1.tgz", + "integrity": "sha512-Um/+FxMr9CISWh0bi5Zv0iOD+4cFh5qLeks1qhAopKVAJw3drgKbKySikp7wGhDL0HPeaja0P5ULZrxLkniUVg==", + "dev": true + }, "es6-promise": { "version": "4.2.8", "resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz", @@ -35835,6 +35908,12 @@ } } }, + "expect-playwright": { + "version": "0.7.2", + "resolved": "https://registry.npmjs.org/expect-playwright/-/expect-playwright-0.7.2.tgz", + "integrity": "sha512-5o9si+8SUi68QVI0CRVv8tvTjZinpJWRSfQ3GP6v0DvlK55lDgFvD79r6A/NU+EUawrBc62qP30MxzOUnXNJZQ==", + "dev": true + }, "expect-puppeteer": { "version": "4.4.0", "resolved": "https://registry.npmjs.org/expect-puppeteer/-/expect-puppeteer-4.4.0.tgz", @@ -36958,6 +37037,12 @@ "readable-stream": "^2.0.0" } }, + "fromentries": { + "version": "1.3.2", + "resolved": "https://registry.npmjs.org/fromentries/-/fromentries-1.3.2.tgz", + "integrity": "sha512-cHEpEQHUg0f8XdtZCc2ZAhrHzKzT0MrFUTcvx+hfxYu7rGMDc5SKoXFh+n4YigxsHXRzc6OrCshdR1bWH6HHyg==", + "dev": true + }, "fs-constants": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/fs-constants/-/fs-constants-1.0.0.tgz", @@ -37346,6 +37431,12 @@ "integrity": "sha512-CIJYJC4GGF06TakLg8z4GQKvDsx9EMspVxOYih7LerEL/WosUnFIww45CGfxfeKHqlg3twgUrYRT1O3WQqjGCg==", "dev": true }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, "get-pkg-repo": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/get-pkg-repo/-/get-pkg-repo-1.4.0.tgz", @@ -38277,6 +38368,30 @@ "minimalistic-assert": "^1.0.1" } }, + "hasha": { + "version": "5.2.2", + "resolved": "https://registry.npmjs.org/hasha/-/hasha-5.2.2.tgz", + "integrity": "sha512-Hrp5vIK/xr5SkeN2onO32H0MgNZ0f17HRNH39WfL0SYUNOTZ5Lz1TJ8Pajo/87dYGEFlLMm7mIc/k/s6Bvz9HQ==", + "dev": true, + "requires": { + "is-stream": "^2.0.0", + "type-fest": "^0.8.0" + }, + "dependencies": { + "is-stream": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz", + "integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==", + "dev": true + }, + "type-fest": { + "version": "0.8.1", + "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.8.1.tgz", + "integrity": "sha512-4dbzIzqvjtgiM5rw1k5rEHtBANKmdudhGyBEajN01fEyhaAIhsoKNy6y7+IN93IfpFtwY9iqi7kD+xwKhQsNJA==", + "dev": true + } + } + }, "hast-to-hyperscript": { "version": "9.0.1", "resolved": "https://registry.npmjs.org/hast-to-hyperscript/-/hast-to-hyperscript-9.0.1.tgz", @@ -39947,6 +40062,15 @@ "integrity": "sha512-UiUIqxMgRDET6eR+o5HbfRYP1l0hqkWOs7vNxC/mggutCMUIhWMm8gAHb8tHlyfD3/l6rlgNA5cKdDzEAf6hEg==", "dev": true }, + "istanbul-lib-hook": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/istanbul-lib-hook/-/istanbul-lib-hook-3.0.0.tgz", + "integrity": "sha512-Pt/uge1Q9s+5VAZ+pCo16TYMWPBIl+oaNIjgLQxcX0itS6ueeaA+pEfThZpH8WxhFgCiEb8sAJY6MdUKgiIWaQ==", + "dev": true, + "requires": { + "append-transform": "^2.0.0" + } + }, "istanbul-lib-instrument": { "version": "4.0.1", "resolved": "https://registry.npmjs.org/istanbul-lib-instrument/-/istanbul-lib-instrument-4.0.1.tgz", @@ -39970,6 +40094,70 @@ } } }, + "istanbul-lib-processinfo": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/istanbul-lib-processinfo/-/istanbul-lib-processinfo-2.0.2.tgz", + "integrity": "sha512-kOwpa7z9hme+IBPZMzQ5vdQj8srYgAtaRqeI48NGmAQ+/5yKiHLV0QbYqQpxsdEF0+w14SoB8YbnHKcXE2KnYw==", + "dev": true, + "requires": { + "archy": "^1.0.0", + "cross-spawn": "^7.0.0", + "istanbul-lib-coverage": "^3.0.0-alpha.1", + "make-dir": "^3.0.0", + "p-map": "^3.0.0", + "rimraf": "^3.0.0", + "uuid": "^3.3.3" + }, + "dependencies": { + "cross-spawn": { + "version": "7.0.3", + "resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.3.tgz", + "integrity": "sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==", + "dev": true, + "requires": { + "path-key": "^3.1.0", + "shebang-command": "^2.0.0", + "which": "^2.0.1" + } + }, + "path-key": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz", + "integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==", + "dev": true + }, + "shebang-command": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz", + "integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==", + "dev": true, + "requires": { + "shebang-regex": "^3.0.0" + } + }, + "shebang-regex": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz", + "integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==", + "dev": true + }, + "uuid": { + "version": "3.4.0", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-3.4.0.tgz", + "integrity": "sha512-HjSDRw6gZE5JMggctHBcjVak08+KEVhSIiDzFnT9S9aegmp85S/bReBVTb4QTFaRNptJ9kuYaNhnbNEOkbKb/A==", + "dev": true + }, + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "istanbul-lib-report": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/istanbul-lib-report/-/istanbul-lib-report-3.0.0.tgz", @@ -42482,12 +42670,289 @@ } } }, + "jest-playwright-preset": { + "version": "1.7.0", + "resolved": "https://registry.npmjs.org/jest-playwright-preset/-/jest-playwright-preset-1.7.0.tgz", + "integrity": "sha512-G25Nik+By0SNniMDdkouDL/yA1LdqjzsXNSVU4xnRX1typjXRmzRE0aSgqxas2sRi8cwG3M1ioHdkLLsp6sang==", + "dev": true, + "requires": { + "expect-playwright": "^0.7.0", + "jest-process-manager": "^0.3.1", + "nyc": "^15.1.0", + "playwright-core": ">=1.2.0", + "rimraf": "^3.0.2", + "uuid": "^8.3.2" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "playwright-core": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.14.0.tgz", + "integrity": "sha512-n6NdknezSfRgB6LkLwcrbm5orRQZSpbd8LZmlc4YrIXV0VEvJr5tzP3xlHXpiFBfTr3yoFuagldI3T7bD/8H3w==", + "dev": true, + "requires": { + "commander": "^6.1.0", + "debug": "^4.1.1", + "extract-zip": "^2.0.1", + "https-proxy-agent": "^5.0.0", + "jpeg-js": "^0.4.2", + "mime": "^2.4.6", + "pngjs": "^5.0.0", + "progress": "^2.0.3", + "proper-lockfile": "^4.1.1", + "proxy-from-env": "^1.1.0", + "rimraf": "^3.0.2", + "stack-utils": "^2.0.3", + "ws": "^7.4.6", + "yazl": "^2.5.1" + } + }, + "uuid": { + "version": "8.3.2", + "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", + "integrity": "sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==", + "dev": true + }, + "ws": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } + }, "jest-pnp-resolver": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/jest-pnp-resolver/-/jest-pnp-resolver-1.2.2.tgz", "integrity": "sha512-olV41bKSMm8BdnuMsewT4jqlZ8+3TCARAXjZGT9jcoSnrfUnRCqnMoF9XEeoWjbzObpqF9dRhHQj0Xb9QdF6/w==", "dev": true }, + "jest-process-manager": { + "version": "0.3.1", + "resolved": "https://registry.npmjs.org/jest-process-manager/-/jest-process-manager-0.3.1.tgz", + "integrity": "sha512-x9W54UgZ7IkzUHgXtnI1x4GKOVjxtwW0CA/7yGbTHtT/YhENO0Lic2yfVyC/gekn7OIEMcQmy0L1r9WLQABfqw==", + "dev": true, + "requires": { + "@types/wait-on": "^5.2.0", + "chalk": "^4.1.0", + "cwd": "^0.10.0", + "exit": "^0.1.2", + "find-process": "^1.4.4", + "prompts": "^2.4.1", + "signal-exit": "^3.0.3", + "spawnd": "^5.0.0", + "tree-kill": "^1.2.2", + "wait-on": "^5.3.0" + }, + "dependencies": { + "commander": { + "version": "5.1.0", + "resolved": "https://registry.npmjs.org/commander/-/commander-5.1.0.tgz", + "integrity": "sha512-P0CysNDQ7rtVw4QIQtm+MRxV66vKFSvlsQvGYXZWR3qFU0jlMKHZZZgw8e+8DSah4UDKMqnknRDQz+xuQXQ/Zg==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "find-process": { + "version": "1.4.4", + "resolved": "https://registry.npmjs.org/find-process/-/find-process-1.4.4.tgz", + "integrity": "sha512-rRSuT1LE4b+BFK588D2V8/VG9liW0Ark1XJgroxZXI0LtwmQJOb490DvDYvbm+Hek9ETFzTutGfJ90gumITPhQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "commander": "^5.1.0", + "debug": "^4.1.1" + } + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "prompts": { + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/prompts/-/prompts-2.4.1.tgz", + "integrity": "sha512-EQyfIuO2hPDsX1L/blblV+H7I0knhgAd82cVneCwcdND9B8AuCDuRcBH6yIcG4dFzlOUqbazQqwGjx5xmsNLuQ==", + "dev": true, + "requires": { + "kleur": "^3.0.3", + "sisteransi": "^1.0.5" + } + }, + "rxjs": { + "version": "6.6.7", + "resolved": "https://registry.npmjs.org/rxjs/-/rxjs-6.6.7.tgz", + "integrity": "sha512-hTdwr+7yYNIT5n4AMYp85KA6yw2Va0FLa3Rguvbpa4W3I5xynaBZo41cM3XM+4Q6fRMj3sBYIR1VAmZMXYJvRQ==", + "dev": true, + "requires": { + "tslib": "^1.9.0" + } + }, + "signal-exit": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.3.tgz", + "integrity": "sha512-VUJ49FC8U1OxwZLxIbTTrDvLnf/6TDgxZcK8wxR8zs13xpx7xbG60ndBlhNrFi2EMuFRoeDoJO7wthSLq42EjA==", + "dev": true + }, + "sisteransi": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/sisteransi/-/sisteransi-1.0.5.tgz", + "integrity": "sha512-bLGGlR1QxBcynn2d5YmDX4MGjlZvy2MRBDRNHLJ8VI6l6+9FUiyTFNJ0IveOSP0bcXgVDPRcfGqA0pjaqUpfVg==", + "dev": true + }, + "spawnd": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-5.0.0.tgz", + "integrity": "sha512-28+AJr82moMVWolQvlAIv3JcYDkjkFTEmfDc503wxrF5l2rQ3dFz6DpbXp3kD4zmgGGldfM4xM4v1sFj/ZaIOA==", + "dev": true, + "requires": { + "exit": "^0.1.2", + "signal-exit": "^3.0.3", + "tree-kill": "^1.2.2", + "wait-port": "^0.2.9" + } + }, + "tree-kill": { + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", + "integrity": "sha512-L0Orpi8qGpRG//Nd+H90vFB+3iHnue1zSSGmNOOCh1GLJ7rUKVwV2HvijphGQS2UmhUZewS9VgvxYIdgr+fG1A==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "wait-on": { + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/wait-on/-/wait-on-5.3.0.tgz", + "integrity": "sha512-DwrHrnTK+/0QFaB9a8Ol5Lna3k7WvUR4jzSKmz0YaPBpuN2sACyiPVKVfj6ejnjcajAcvn3wlbTyMIn9AZouOg==", + "dev": true, + "requires": { + "axios": "^0.21.1", + "joi": "^17.3.0", + "lodash": "^4.17.21", + "minimist": "^1.2.5", + "rxjs": "^6.6.3" + } + }, + "wait-port": { + "version": "0.2.9", + "resolved": "https://registry.npmjs.org/wait-port/-/wait-port-0.2.9.tgz", + "integrity": "sha512-hQ/cVKsNqGZ/UbZB/oakOGFqic00YAMM5/PEj3Bt4vKarv2jWIWzDbqlwT94qMs/exAQAsvMOq99sZblV92zxQ==", + "dev": true, + "requires": { + "chalk": "^2.4.2", + "commander": "^3.0.2", + "debug": "^4.1.1" + }, + "dependencies": { + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "commander": { + "version": "3.0.2", + "resolved": "https://registry.npmjs.org/commander/-/commander-3.0.2.tgz", + "integrity": "sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow==", + "dev": true + } + } + } + } + }, "jest-regex-util": { "version": "26.0.0", "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-26.0.0.tgz", @@ -44490,6 +44955,12 @@ } } }, + "jpeg-js": { + "version": "0.4.3", + "resolved": "https://registry.npmjs.org/jpeg-js/-/jpeg-js-0.4.3.tgz", + "integrity": "sha512-ru1HWKek8octvUHFHvE5ZzQ1yAsJmIvRdGWvSoKV52XKyuyYA437QWDttXT8eZXDSbuMpHlLzPDZUPd6idIz+Q==", + "dev": true + }, "js-string-escape": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/js-string-escape/-/js-string-escape-1.0.1.tgz", @@ -48443,6 +48914,15 @@ "resolved": "https://registry.npmjs.org/node-modules-regexp/-/node-modules-regexp-1.0.0.tgz", "integrity": "sha1-jZ2+KJZKSsVxLpExZCEHxx6Q7EA=" }, + "node-preload": { + "version": "0.2.1", + "resolved": "https://registry.npmjs.org/node-preload/-/node-preload-0.2.1.tgz", + "integrity": "sha512-RM5oyBy45cLEoHqCeh+MNuFAxO0vTFBLskvQbOKnEE7YTTSN4tbN8QWDIPQ6L+WvKsB/qLEGpYe2ZZ9d4W9OIQ==", + "dev": true, + "requires": { + "process-on-spawn": "^1.0.0" + } + }, "node-releases": { "version": "1.1.71", "resolved": "https://registry.npmjs.org/node-releases/-/node-releases-1.1.71.tgz", @@ -49226,6 +49706,231 @@ "integrity": "sha512-h2AatdwYH+JHiZpv7pt/gSX1XoRGb7L/qSIeuqA6GwYoF9w1vP1cw42TO0aI2pNyshRK5893hNSl+1//vHK7hQ==", "dev": true }, + "nyc": { + "version": "15.1.0", + "resolved": "https://registry.npmjs.org/nyc/-/nyc-15.1.0.tgz", + "integrity": "sha512-jMW04n9SxKdKi1ZMGhvUTHBN0EICCRkHemEoE5jm6mTYcqcdas0ATzgUgejlQUHMvpnOZqGB5Xxsv9KxJW1j8A==", + "dev": true, + "requires": { + "@istanbuljs/load-nyc-config": "^1.0.0", + "@istanbuljs/schema": "^0.1.2", + "caching-transform": "^4.0.0", + "convert-source-map": "^1.7.0", + "decamelize": "^1.2.0", + "find-cache-dir": "^3.2.0", + "find-up": "^4.1.0", + "foreground-child": "^2.0.0", + "get-package-type": "^0.1.0", + "glob": "^7.1.6", + "istanbul-lib-coverage": "^3.0.0", + "istanbul-lib-hook": "^3.0.0", + "istanbul-lib-instrument": "^4.0.0", + "istanbul-lib-processinfo": "^2.0.2", + "istanbul-lib-report": "^3.0.0", + "istanbul-lib-source-maps": "^4.0.0", + "istanbul-reports": "^3.0.2", + "make-dir": "^3.0.0", + "node-preload": "^0.2.1", + "p-map": "^3.0.0", + "process-on-spawn": "^1.0.0", + "resolve-from": "^5.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "spawn-wrap": "^2.0.0", + "test-exclude": "^6.0.0", + "yargs": "^15.0.2" + }, + "dependencies": { + "ansi-regex": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-5.0.0.tgz", + "integrity": "sha512-bY6fj56OUQ0hU1KjFNDQuJFezqKdrAyFdIevADiqrWHwSlbmBNMHp5ak2f40Pm8JTFyM2mqxkG6ngkHO11f/lg==", + "dev": true + }, + "camelcase": { + "version": "5.3.1", + "resolved": "https://registry.npmjs.org/camelcase/-/camelcase-5.3.1.tgz", + "integrity": "sha512-L28STB170nwWS63UjtlEOE3dldQApaJXZkOI1uMFfzf3rRuPegHaHesyee+YxQ+W6SvRDQV6UrdOdRiR153wJg==", + "dev": true + }, + "convert-source-map": { + "version": "1.8.0", + "resolved": "https://registry.npmjs.org/convert-source-map/-/convert-source-map-1.8.0.tgz", + "integrity": "sha512-+OQdjP49zViI/6i7nIJpA8rAl4sV/JdPfU9nZs3VqOwGIgizICvuN2ru6fMd+4llL0tar18UYJXfZ/TWtmhUjA==", + "dev": true, + "requires": { + "safe-buffer": "~5.1.1" + } + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "find-cache-dir": { + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/find-cache-dir/-/find-cache-dir-3.3.1.tgz", + "integrity": "sha512-t2GDMt3oGC/v+BMwzmllWDuJF/xcDtE5j/fCGbqDD7OLuJkj0cfh1YSA5VKPvwMeLFLNDBkwOKZ2X85jGLVftQ==", + "dev": true, + "requires": { + "commondir": "^1.0.1", + "make-dir": "^3.0.2", + "pkg-dir": "^4.1.0" + }, + "dependencies": { + "make-dir": { + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/make-dir/-/make-dir-3.1.0.tgz", + "integrity": "sha512-g3FeP20LNwhALb/6Cz6Dd4F2ngze0jz7tbzrD2wAV+o9FeNHe4rL+yK2md0J/fiSf1sa1ADhXqi5+oVwOM/eGw==", + "dev": true, + "requires": { + "semver": "^6.0.0" + } + } + } + }, + "find-up": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/find-up/-/find-up-4.1.0.tgz", + "integrity": "sha512-PpOwAdQ/YlXQ2vj8a3h8IipDuYRi3wceVQQGYWxNINccq40Anw7BlsEXCMbt1Zt+OLA6Fq9suIpIWD0OsnISlw==", + "dev": true, + "requires": { + "locate-path": "^5.0.0", + "path-exists": "^4.0.0" + } + }, + "glob": { + "version": "7.1.7", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.1.7.tgz", + "integrity": "sha512-OvD9ENzPLbegENnYP5UUfJIirTg4+XwMWGaQfQTY0JenxNvvIKP3U3/tAQSPIu/lHxXYSZmpXlUHeqAIdKzBLQ==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.0.4", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "locate-path": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/locate-path/-/locate-path-5.0.0.tgz", + "integrity": "sha512-t7hw9pI+WvuwNJXwk5zVHpyhIqzg2qTlklJOf0mVxGSbe3Fp2VieZcduNYjaLDoy6p9uGpQEGWG87WpMKlNq8g==", + "dev": true, + "requires": { + "p-locate": "^4.1.0" + } + }, + "p-limit": { + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", + "dev": true, + "requires": { + "p-try": "^2.0.0" + } + }, + "p-locate": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/p-locate/-/p-locate-4.1.0.tgz", + "integrity": "sha512-R79ZZ/0wAxKGu3oYMlz8jy/kbhsNrS7SKZ7PxEHBgJ5+F2mtFW2fK2cOtBh1cHYkQsbzFV7I+EoRKe6Yt0oK7A==", + "dev": true, + "requires": { + "p-limit": "^2.2.0" + } + }, + "p-try": { + "version": "2.2.0", + "resolved": "https://registry.npmjs.org/p-try/-/p-try-2.2.0.tgz", + "integrity": "sha512-R4nPAVTAU0B9D35/Gk3uJf/7XYbQcyohSKdvAxIRSNghFl4e71hVoGnBNQz9cWaXxO2I10KTC+3jMdvvoKw6dQ==", + "dev": true + }, + "path-exists": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-exists/-/path-exists-4.0.0.tgz", + "integrity": "sha512-ak9Qy5Q7jYb2Wwcey5Fpvg2KoAc/ZIhLSLOSBmRmygPsGwkVVt0fZa0qrtMz+m6tJTAHfZQ8FnmB4MG4LWy7/w==", + "dev": true + }, + "pkg-dir": { + "version": "4.2.0", + "resolved": "https://registry.npmjs.org/pkg-dir/-/pkg-dir-4.2.0.tgz", + "integrity": "sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==", + "dev": true, + "requires": { + "find-up": "^4.0.0" + } + }, + "resolve-from": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/resolve-from/-/resolve-from-5.0.0.tgz", + "integrity": "sha512-qYg9KP24dD5qka9J47d0aVky0N+b4fTU89LN9iDnjB5waksiC49rvMB0PrUJQGoTmH50XPiqOvAjDfaijGxYZw==", + "dev": true + }, + "semver": { + "version": "6.3.0", + "resolved": "https://registry.npmjs.org/semver/-/semver-6.3.0.tgz", + "integrity": "sha512-b39TBaTSfV6yBrapU89p5fKekE2m/NwnDocOVruQFS1/veMgdzuPcnOM34M6CwxW8jH/lxEa5rBoDeUwu5HHTw==", + "dev": true + }, + "string-width": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.2.tgz", + "integrity": "sha512-XBJbT3N4JhVumXE0eoLU9DCjcaF92KLNqTmFCnG1pf8duUxFGwtP6AD6nkjw9a3IdiRtL3E2w3JDiE/xi3vOeA==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.0" + } + }, + "strip-ansi": { + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.0.tgz", + "integrity": "sha512-AuvKTrTfQNYNIctbR1K/YGTR1756GycPsg7b9bdV9Duqur4gv6aKqHXah67Z8ImS7WEz5QVcOtlfW2rZEugt6w==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.0" + } + }, + "yargs": { + "version": "15.4.1", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-15.4.1.tgz", + "integrity": "sha512-aePbxDmcYW++PaqBsJ+HYUFwCdv4LVvdnhBy78E57PIor8/OVvhMrADFFEDh8DHDFRv/O9i3lPhsENjO7QX0+A==", + "dev": true, + "requires": { + "cliui": "^6.0.0", + "decamelize": "^1.2.0", + "find-up": "^4.1.0", + "get-caller-file": "^2.0.1", + "require-directory": "^2.1.1", + "require-main-filename": "^2.0.0", + "set-blocking": "^2.0.0", + "string-width": "^4.2.0", + "which-module": "^2.0.0", + "y18n": "^4.0.0", + "yargs-parser": "^18.1.2" + } + }, + "yargs-parser": { + "version": "18.1.3", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-18.1.3.tgz", + "integrity": "sha512-o50j0JeToy/4K6OZcaQmW6lyXXKhq7csREXcDwk2omFPJEwUNOVtJKvmDr9EI1fAJZUyZcRF7kxGBWmRXudrCQ==", + "dev": true, + "requires": { + "camelcase": "^5.0.0", + "decamelize": "^1.2.0" + } + } + } + }, "oauth-sign": { "version": "0.9.0", "resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz", @@ -49956,6 +50661,26 @@ "p-reduce": "^1.0.0" } }, + "package-hash": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/package-hash/-/package-hash-4.0.0.tgz", + "integrity": "sha512-whdkPIooSu/bASggZ96BWVvZTRMOFxnyUG5PnTSGKoJE2gd5mbVNmR2Nj20QFzxYYgAXpoqC+AiXzl+UMRh7zQ==", + "dev": true, + "requires": { + "graceful-fs": "^4.1.15", + "hasha": "^5.0.0", + "lodash.flattendeep": "^4.4.0", + "release-zalgo": "^1.0.0" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + } + } + }, "pako": { "version": "1.0.8", "resolved": "https://registry.npmjs.org/pako/-/pako-1.0.8.tgz", @@ -50381,6 +51106,220 @@ "integrity": "sha512-TuvHS8AOIZNAlE77WUDiR4rySV/VMptyMfcfeoMgs4P8apaZM3JrnbzBiixKUv+XR6i+BXrQh8WAnjaSPFO65Q==", "dev": true }, + "playwright": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.14.0.tgz", + "integrity": "sha512-aR5oZ1iVsjQkGfYCjgYAmyMAVu0MQ0i8MgdnfdqDu9EVLfbnpuuFmTv/Rb7/Yjno1kOrDUP9+RyNC+zfG3wozA==", + "dev": true, + "requires": { + "commander": "^6.1.0", + "debug": "^4.1.1", + "extract-zip": "^2.0.1", + "https-proxy-agent": "^5.0.0", + "jpeg-js": "^0.4.2", + "mime": "^2.4.6", + "pngjs": "^5.0.0", + "progress": "^2.0.3", + "proper-lockfile": "^4.1.1", + "proxy-from-env": "^1.1.0", + "rimraf": "^3.0.2", + "stack-utils": "^2.0.3", + "ws": "^7.4.6", + "yazl": "^2.5.1" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "ws": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } + }, + "playwright-chromium": { + "version": "1.14.0", + "resolved": "https://registry.npmjs.org/playwright-chromium/-/playwright-chromium-1.14.0.tgz", + "integrity": "sha512-qWQN9VTPhvEZdRpn1564EOtiNU+hRHhogKg1heBX9VsfGy6WHytR9XPFJjD4M6fhNAV1WKM2McVPYIbi1EOYww==", + "dev": true, + "requires": { + "commander": "^6.1.0", + "debug": "^4.1.1", + "extract-zip": "^2.0.1", + "https-proxy-agent": "^5.0.0", + "jpeg-js": "^0.4.2", + "mime": "^2.4.6", + "pngjs": "^5.0.0", + "progress": "^2.0.3", + "proper-lockfile": "^4.1.1", + "proxy-from-env": "^1.1.0", + "rimraf": "^3.0.2", + "stack-utils": "^2.0.3", + "ws": "^7.4.6", + "yazl": "^2.5.1" + }, + "dependencies": { + "agent-base": { + "version": "6.0.2", + "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-6.0.2.tgz", + "integrity": "sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==", + "dev": true, + "requires": { + "debug": "4" + } + }, + "commander": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/commander/-/commander-6.2.1.tgz", + "integrity": "sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==", + "dev": true + }, + "debug": { + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.2.tgz", + "integrity": "sha512-mOp8wKcvj7XxC78zLgw/ZA+6TSgkoE2C/ienthhRD298T7UNwAg9diBpLRxC0mOezLl4B0xV7M0cCO6P/O0Xhw==", + "dev": true, + "requires": { + "ms": "2.1.2" + } + }, + "extract-zip": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/extract-zip/-/extract-zip-2.0.1.tgz", + "integrity": "sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==", + "dev": true, + "requires": { + "@types/yauzl": "^2.9.1", + "debug": "^4.1.1", + "get-stream": "^5.1.0", + "yauzl": "^2.10.0" + } + }, + "fd-slicer": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/fd-slicer/-/fd-slicer-1.1.0.tgz", + "integrity": "sha1-JcfInLH5B3+IkbvmHY85Dq4lbx4=", + "dev": true, + "requires": { + "pend": "~1.2.0" + } + }, + "https-proxy-agent": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-5.0.0.tgz", + "integrity": "sha512-EkYm5BcKUGiduxzSt3Eppko+PiNWNEpa4ySk9vTC6wDsQJW9rHSa+UhGNJoRYp7bz6Ht1eaRIa6QaJqO5rCFbA==", + "dev": true, + "requires": { + "agent-base": "6", + "debug": "4" + } + }, + "mime": { + "version": "2.5.2", + "resolved": "https://registry.npmjs.org/mime/-/mime-2.5.2.tgz", + "integrity": "sha512-tqkh47FzKeCPD2PUiPB6pkbMzsCasjxAfC62/Wap5qrUWcb+sFasXUC5I3gYM5iBM8v/Qpn4UK0x+j0iHyFPDg==", + "dev": true + }, + "ms": { + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", + "integrity": "sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==", + "dev": true + }, + "ws": { + "version": "7.5.3", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", + "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "dev": true + }, + "yauzl": { + "version": "2.10.0", + "resolved": "https://registry.npmjs.org/yauzl/-/yauzl-2.10.0.tgz", + "integrity": "sha1-x+sXyT4RLLEIb6bY5R+wZnt5pfk=", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3", + "fd-slicer": "~1.1.0" + } + } + } + }, "please-upgrade-node": { "version": "3.2.0", "resolved": "https://registry.npmjs.org/please-upgrade-node/-/please-upgrade-node-3.2.0.tgz", @@ -50416,6 +51355,12 @@ "irregular-plurals": "^3.2.0" } }, + "pngjs": { + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/pngjs/-/pngjs-5.0.0.tgz", + "integrity": "sha512-40QW5YalBNfQo5yRYmiw7Yz6TKKVr3h6970B2YE+3fQpsWcrbj1PzJgxeJ19DRQjhMbKPIuMY8rFaXc8moolVw==", + "dev": true + }, "pnp-webpack-plugin": { "version": "1.6.4", "resolved": "https://registry.npmjs.org/pnp-webpack-plugin/-/pnp-webpack-plugin-1.6.4.tgz", @@ -51761,6 +52706,15 @@ "resolved": "https://registry.npmjs.org/process-nextick-args/-/process-nextick-args-2.0.0.tgz", "integrity": "sha512-MtEC1TqN0EU5nephaJ4rAtThHtC86dNN9qCuEhtshvpVBkAW5ZO7BASN9REnF9eoXGcRub+pFuKEpOHE+HbEMw==" }, + "process-on-spawn": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/process-on-spawn/-/process-on-spawn-1.0.0.tgz", + "integrity": "sha512-1WsPDsUSMmZH5LeMLegqkPDrsGgsWwk1Exipy2hvB0o/F0ASzbpIctSCcZIK1ykJvtTJULEH+20WOFjMvGnCTg==", + "dev": true, + "requires": { + "fromentries": "^1.2.0" + } + }, "progress": { "version": "2.0.3", "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", @@ -52165,6 +53119,31 @@ "integrity": "sha512-vGrhOavPSTz4QVNuBNdcNXePNdNMaO1xj9yBeH1ScQPjk/rhg9sSlCXPhMkFuaNNW/syTvYqsnbIJxMBfRbbag==", "dev": true }, + "proper-lockfile": { + "version": "4.1.2", + "resolved": "https://registry.npmjs.org/proper-lockfile/-/proper-lockfile-4.1.2.tgz", + "integrity": "sha512-TjNPblN4BwAWMXU8s9AEz4JmQxnD1NNL7bNOY/AKUzyamc379FWASUhc/K1pL2noVb+XmZKLL68cjzLsiOAMaA==", + "dev": true, + "requires": { + "graceful-fs": "^4.2.4", + "retry": "^0.12.0", + "signal-exit": "^3.0.2" + }, + "dependencies": { + "graceful-fs": { + "version": "4.2.8", + "resolved": "https://registry.npmjs.org/graceful-fs/-/graceful-fs-4.2.8.tgz", + "integrity": "sha512-qkIilPUYcNhJpd33n0GBXTB1MMPp14TxEsEs0pTrsSVucApsYzW5V+Q8Qxhik6KU3evy+qkAAowTByymK0avdg==", + "dev": true + }, + "retry": { + "version": "0.12.0", + "resolved": "https://registry.npmjs.org/retry/-/retry-0.12.0.tgz", + "integrity": "sha1-G0KmJmoh8HQh0bC1S33BZ7AcATs=", + "dev": true + } + } + }, "property-information": { "version": "5.6.0", "resolved": "https://registry.npmjs.org/property-information/-/property-information-5.6.0.tgz", @@ -54621,6 +55600,15 @@ "integrity": "sha1-VNvzd+UUQKypCkzSdGANP/LYiKk=", "dev": true }, + "release-zalgo": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", + "integrity": "sha1-CXALflB0Mpc5Mw5TXFqQ+2eFFzA=", + "dev": true, + "requires": { + "es6-error": "^4.0.1" + } + }, "remark": { "version": "10.0.1", "resolved": "https://registry.npmjs.org/remark/-/remark-10.0.1.tgz", @@ -56733,6 +57721,31 @@ "integrity": "sha1-YvXpRmmBwbeW3Fkpk34RycaSG9A=", "dev": true }, + "spawn-wrap": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/spawn-wrap/-/spawn-wrap-2.0.0.tgz", + "integrity": "sha512-EeajNjfN9zMnULLwhZZQU3GWBoFNkbngTUPfaawT4RkMiviTxcX0qfhVbGey39mfctfDHkWtuecgQ8NJcyQWHg==", + "dev": true, + "requires": { + "foreground-child": "^2.0.0", + "is-windows": "^1.0.2", + "make-dir": "^3.0.0", + "rimraf": "^3.0.0", + "signal-exit": "^3.0.2", + "which": "^2.0.1" + }, + "dependencies": { + "which": { + "version": "2.0.2", + "resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz", + "integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==", + "dev": true, + "requires": { + "isexe": "^2.0.0" + } + } + } + }, "spawnd": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/spawnd/-/spawnd-5.0.0.tgz", @@ -62228,6 +63241,15 @@ "fd-slicer": "~1.0.1" } }, + "yazl": { + "version": "2.5.1", + "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", + "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", + "dev": true, + "requires": { + "buffer-crc32": "~0.2.3" + } + }, "yocto-queue": { "version": "0.1.0", "resolved": "https://registry.npmjs.org/yocto-queue/-/yocto-queue-0.1.0.tgz", diff --git a/package.json b/package.json index d170ee49c809b6..3a2c4b902623e9 100644 --- a/package.json +++ b/package.json @@ -175,6 +175,7 @@ "jest": "26.6.3", "jest-junit": "11.0.0", "jest-message-util": "27.0.6", + "jest-playwright-preset": "1.7.0", "jest-serializer-enzyme": "1.0.0", "jest-watch-typeahead": "0.6.1", "jsdom": "16.4.0", @@ -188,6 +189,8 @@ "nock": "12.0.3", "node-watch": "0.7.0", "patch-package": "6.2.2", + "playwright": "1.14.0", + "playwright-chromium": "1.14.0", "postcss": "8.2.15", "postcss-loader": "6.1.1", "prettier": "npm:wp-prettier@2.2.1-beta-1", @@ -261,6 +264,7 @@ "test": "npm run lint && npm run test-unit", "test:create-block": "./bin/test-create-block.sh", "test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", + "test-pl": "jest --config packages/e2e-tests/jest.playwright.config.js", "test-e2e:debug": "wp-scripts --inspect-brk test-e2e --config packages/e2e-tests/jest.config.js --puppeteer-devtools", "test-e2e:watch": "npm run test-e2e -- --watch", "test-performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js", diff --git a/packages/e2e-test-utils/package.json b/packages/e2e-test-utils/package.json index b8c8664651b1c3..d1faccc5f6ef39 100644 --- a/packages/e2e-test-utils/package.json +++ b/packages/e2e-test-utils/package.json @@ -23,11 +23,9 @@ "node": ">=12" }, "files": [ - "build", - "build-module" + "src" ], - "main": "build/index.js", - "module": "build-module/index.js", + "main": "src/index.js", "dependencies": { "@babel/runtime": "^7.13.10", "@wordpress/api-fetch": "file:../api-fetch", diff --git a/packages/e2e-test-utils/src/mocks/set-up-response-mocking.js b/packages/e2e-test-utils/src/mocks/set-up-response-mocking.js index b2ba2d31db0ac7..61687429215588 100644 --- a/packages/e2e-test-utils/src/mocks/set-up-response-mocking.js +++ b/packages/e2e-test-utils/src/mocks/set-up-response-mocking.js @@ -39,8 +39,8 @@ export async function setUpResponseMocking( mocks ) { // We only want to set up the request interception once, or else we get a crash // when we try to process the same request twice. interceptionInitialized = true; - await page.setRequestInterception( true ); - page.on( 'request', async ( request ) => { + await page.route( '**/*', async ( route ) => { + const request = route.request(); for ( let i = 0; i < requestMocks.length; i++ ) { const mock = requestMocks[ i ]; if ( mock.match( request ) ) { @@ -48,7 +48,7 @@ export async function setUpResponseMocking( mocks ) { return; } } - request.continue(); + route.continue(); } ); } // Overwrite with the passed in mocks, so we can change the mocks mid-test to test diff --git a/packages/e2e-test-utils/src/set-browser-viewport.js b/packages/e2e-test-utils/src/set-browser-viewport.js index 3408dfe03903eb..8fc99200f2ad7a 100644 --- a/packages/e2e-test-utils/src/set-browser-viewport.js +++ b/packages/e2e-test-utils/src/set-browser-viewport.js @@ -48,6 +48,6 @@ export async function setBrowserViewport( viewport ) { ? PREDEFINED_DIMENSIONS[ viewport ] : viewport; - await page.setViewport( dimensions ); + await page.setViewportSize( dimensions ); await waitForWindowDimensions( dimensions.width, dimensions.height ); } diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js new file mode 100644 index 00000000000000..630716ae1c5b86 --- /dev/null +++ b/packages/e2e-tests/config/setup-playwright.js @@ -0,0 +1,190 @@ +/** + * External dependencies + */ +import { get } from 'lodash'; + +/** + * WordPress dependencies + */ +import { + //clearLocalStorage, + activatePlugin, + enablePageDialogAccept, + isOfflineMode, + setBrowserViewport, + switchUserToAdmin, + switchUserToTest, + visitAdminPage, +} from '@wordpress/e2e-test-utils'; +import { addQueryArgs } from '@wordpress/url'; + +// The Jest timeout is increased because these tests are a bit slow +jest.setTimeout( 100000 ); + +/** + * Set of console logging types observed to protect against unexpected yet + * handled (i.e. not catastrophic) errors or warnings. Each key corresponds + * to the Puppeteer ConsoleMessage type, its value the corresponding function + * on the console global object. + * + * @type {Object} + */ +const OBSERVED_CONSOLE_MESSAGE_TYPES = { + warning: 'warn', + error: 'error', +}; + +async function setupBrowser() { + //await clearLocalStorage(); + await setBrowserViewport( 'large' ); +} + +/** + * Adds a page event handler to emit uncaught exception to process if one of + * the observed console logging types is encountered. + */ +function observeConsoleLogging() { + page.on( 'console', ( message ) => { + const type = message.type(); + if ( ! OBSERVED_CONSOLE_MESSAGE_TYPES.hasOwnProperty( type ) ) { + return; + } + + let text = message.text(); + + // An exception is made for _blanket_ deprecation warnings: Those + // which log regardless of whether a deprecated feature is in use. + if ( text.includes( 'This is a global warning' ) ) { + return; + } + + // A chrome advisory warning about SameSite cookies is informational + // about future changes, tracked separately for improvement in core. + // + // See: https://core.trac.wordpress.org/ticket/37000 + // See: https://www.chromestatus.com/feature/5088147346030592 + // See: https://www.chromestatus.com/feature/5633521622188032 + if ( + text.includes( 'A cookie associated with a cross-site resource' ) + ) { + return; + } + + // Viewing posts on the front end can result in this error, which + // has nothing to do with Gutenberg. + if ( text.includes( 'net::ERR_UNKNOWN_URL_SCHEME' ) ) { + return; + } + + // Network errors are ignored only if we are intentionally testing + // offline mode. + if ( + text.includes( 'net::ERR_INTERNET_DISCONNECTED' ) && + isOfflineMode() + ) { + return; + } + + // As of WordPress 5.3.2 in Chrome 79, navigating to the block editor + // (Posts > Add New) will display a console warning about + // non - unique IDs. + // See: https://core.trac.wordpress.org/ticket/23165 + if ( text.includes( 'elements with non-unique id #_wpnonce' ) ) { + return; + } + + // As of WordPress 5.3.2 in Chrome 79, navigating to the block editor + // (Posts > Add New) will display a console warning about + // non - unique IDs. + // See: https://core.trac.wordpress.org/ticket/23165 + if ( text.includes( 'elements with non-unique id #_wpnonce' ) ) { + return; + } + + const logFunction = OBSERVED_CONSOLE_MESSAGE_TYPES[ type ]; + + // As of Puppeteer 1.6.1, `message.text()` wrongly returns an object of + // type JSHandle for error logging, instead of the expected string. + // + // See: https://github.com/GoogleChrome/puppeteer/issues/3397 + // + // The recommendation there to asynchronously resolve the error value + // upon a console event may be prone to a race condition with the test + // completion, leaving a possibility of an error not being surfaced + // correctly. Instead, the logic here synchronously inspects the + // internal object shape of the JSHandle to find the error text. If it + // cannot be found, the default text value is used instead. + text = get( + message.args(), + [ 0, '_remoteObject', 'description' ], + text + ); + + // Disable reason: We intentionally bubble up the console message + // which, unless the test explicitly anticipates the logging via + // @wordpress/jest-console matchers, will cause the intended test + // failure. + + // eslint-disable-next-line no-console + console[ logFunction ]( text ); + } ); +} + +/** + * Navigates to the post listing screen and bulk-trashes any posts which exist. + * + * @param {string} postType - String slug for type of post to trash. + * + * @return {Promise} Promise resolving once posts have been trashed. + */ +export async function trashExistingPosts( postType = 'post' ) { + await switchUserToAdmin(); + // Visit `/wp-admin/edit.php` so we can see a list of posts and delete them. + const query = addQueryArgs( '', { + post_type: postType, + } ).slice( 1 ); + await visitAdminPage( 'edit.php', query ); + + // If this selector doesn't exist there are no posts for us to delete. + const bulkSelector = await page.$( '#bulk-action-selector-top' ); + if ( ! bulkSelector ) { + return; + } + + // Select all posts. + await page.waitForSelector( '[id^=cb-select-all-]' ); + await page.click( '[id^=cb-select-all-]' ); + // Select the "bulk actions" > "trash" option. + await page.select( '#bulk-action-selector-top', 'trash' ); + // Submit the form to send all draft/scheduled/published posts to the trash. + await page.click( '#doaction' ); + await page.waitForXPath( + '//*[contains(@class, "updated notice")]/p[contains(text(), "moved to the Trash.")]' + ); + await switchUserToTest(); +} + +// Before every test suite run, delete all content created by the test. This ensures +// other posts/comments/etc. aren't dirtying tests and tests don't depend on +// each other's side-effects. +beforeAll( async () => { + const originalWaitForSelector = page.waitForSelector; + page.$x = page.$$; + page.select = page.selectOption; + page.waitForXPath = ( selector, options ) => { + return originalWaitForSelector.call( + page, + 'xpath=' + selector, + options + ); + }; + page.waitFor = page.waitForTimeout; + page.waitForSelector = ( selector, options ) => { + return originalWaitForSelector.call( page, 'css=' + selector, options ); + }; + await setupBrowser(); + await enablePageDialogAccept(); + await observeConsoleLogging(); + await trashExistingPosts(); + await activatePlugin( 'gutenberg-test-plugin-disables-the-css-animations' ); +} ); diff --git a/packages/e2e-tests/jest.playwright.config.js b/packages/e2e-tests/jest.playwright.config.js new file mode 100644 index 00000000000000..8eacdfa7a7daf8 --- /dev/null +++ b/packages/e2e-tests/jest.playwright.config.js @@ -0,0 +1,16 @@ +module.exports = { + preset: 'jest-playwright-preset', + testMatch: [ '**/specs/**/*.[jt]s', '**/?(*.)spec.[jt]s' ], + testPathIgnorePatterns: [ '/node_modules/', '/wordpress/' ], + reporters: + 'TRAVIS' in process.env && 'CI' in process.env + ? [ + '@wordpress/jest-preset-default/scripts/travis-fold-passes-reporter.js', + ] + : undefined, + setupFiles: [ '/config/gutenberg-phase.js' ], + setupFilesAfterEnv: [ + '/config/setup-playwright.js', + '@wordpress/jest-console', + ], +}; diff --git a/packages/e2e-tests/playwright/specs/hello.test.js b/packages/e2e-tests/playwright/specs/hello.test.js new file mode 100644 index 00000000000000..a0239518181fdb --- /dev/null +++ b/packages/e2e-tests/playwright/specs/hello.test.js @@ -0,0 +1,5 @@ +describe( 'hello', () => { + it( 'world', async () => { + expect( true ).toBe( true ); + } ); +} ); diff --git a/packages/e2e-tests/specs/editor/various/change-detection.test.js b/packages/e2e-tests/specs/editor/various/change-detection.test.js index d3694734d2db5e..77fd9fd5aeb33f 100644 --- a/packages/e2e-tests/specs/editor/various/change-detection.test.js +++ b/packages/e2e-tests/specs/editor/various/change-detection.test.js @@ -54,16 +54,9 @@ describe( 'Change detection', () => { } async function interceptSave() { - await page.setRequestInterception( true ); - - handleInterceptedRequest = ( interceptedRequest ) => { - if ( interceptedRequest.url().includes( '/wp/v2/posts' ) ) { - hadInterceptedSave = true; - } else { - interceptedRequest.continue(); - } - }; - page.on( 'request', handleInterceptedRequest ); + await page.route( '*/v2/posts', ( route ) => { + route.abort(); + } ); } async function releaseSaveIntercept() { From 1aa63461cdd4efc0db3b763d82c23921c03764d1 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 4 Aug 2021 16:54:57 +0200 Subject: [PATCH 02/44] Migrate to Playwright API --- packages/e2e-test-utils/src/drag-and-resize.js | 2 +- .../e2e-test-utils/src/press-key-with-modifier.js | 9 ++++----- packages/e2e-test-utils/src/wp-data-select.js | 10 ++++------ packages/e2e-tests/config/setup-playwright.js | 13 ++----------- .../e2e-tests/specs/editor/blocks/classic.test.js | 2 +- .../e2e-tests/specs/editor/blocks/gallery.test.js | 2 +- .../e2e-tests/specs/editor/blocks/image.test.js | 2 +- .../specs/editor/plugins/image-size.test.js | 2 +- .../editor/various/manage-reusable-blocks.test.js | 2 +- 9 files changed, 16 insertions(+), 28 deletions(-) diff --git a/packages/e2e-test-utils/src/drag-and-resize.js b/packages/e2e-test-utils/src/drag-and-resize.js index aa8a23cd8d4344..f895e6581268b5 100644 --- a/packages/e2e-test-utils/src/drag-and-resize.js +++ b/packages/e2e-test-utils/src/drag-and-resize.js @@ -9,7 +9,7 @@ * @return {Promise} Promise resolving when drag completes. */ export async function dragAndResize( element, delta ) { - const elementPoint = await element.clickablePoint(); + const elementPoint = await element.boundingBox(); await page.mouse.move( elementPoint.x, elementPoint.y ); await page.mouse.down(); await page.mouse.move( elementPoint.x + delta.x, elementPoint.y + delta.y ); diff --git a/packages/e2e-test-utils/src/press-key-with-modifier.js b/packages/e2e-test-utils/src/press-key-with-modifier.js index 24eb4c3c86e487..1fbe73d1434289 100644 --- a/packages/e2e-test-utils/src/press-key-with-modifier.js +++ b/packages/e2e-test-utils/src/press-key-with-modifier.js @@ -91,13 +91,12 @@ async function emulateSelectAll() { */ export async function setClipboardData( { plainText = '', html = '' } ) { await page.evaluate( - ( _plainText, _html ) => { + ( args ) => { window._clipboardData = new DataTransfer(); - window._clipboardData.setData( 'text/plain', _plainText ); - window._clipboardData.setData( 'text/html', _html ); + window._clipboardData.setData( 'text/plain', args.plainText ); + window._clipboardData.setData( 'text/html', args.html ); }, - plainText, - html + { plainText, html } ); } diff --git a/packages/e2e-test-utils/src/wp-data-select.js b/packages/e2e-test-utils/src/wp-data-select.js index 65e382730292c2..7512782e9becdc 100644 --- a/packages/e2e-test-utils/src/wp-data-select.js +++ b/packages/e2e-test-utils/src/wp-data-select.js @@ -20,13 +20,11 @@ */ export async function wpDataSelect( store, selector, ...parameters ) { return page.evaluate( - ( _store, _selector, ..._parameters ) => { + ( args ) => { return window.wp.data - .select( _store ) - [ _selector ]( ..._parameters ); + .select( args.store ) + [ args.selector ]( ...args.parameters ); }, - store, - selector, - ...parameters + { store, selector, parameters } ); } diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js index 630716ae1c5b86..7d708b38f93d38 100644 --- a/packages/e2e-tests/config/setup-playwright.js +++ b/packages/e2e-tests/config/setup-playwright.js @@ -168,20 +168,11 @@ export async function trashExistingPosts( postType = 'post' ) { // other posts/comments/etc. aren't dirtying tests and tests don't depend on // each other's side-effects. beforeAll( async () => { - const originalWaitForSelector = page.waitForSelector; page.$x = page.$$; page.select = page.selectOption; - page.waitForXPath = ( selector, options ) => { - return originalWaitForSelector.call( - page, - 'xpath=' + selector, - options - ); - }; + page.waitForXPath = page.waitForSelector; page.waitFor = page.waitForTimeout; - page.waitForSelector = ( selector, options ) => { - return originalWaitForSelector.call( page, 'css=' + selector, options ); - }; + page.cookies = () => page.context().cookies(); await setupBrowser(); await enablePageDialogAccept(); await observeConsoleLogging(); diff --git a/packages/e2e-tests/specs/editor/blocks/classic.test.js b/packages/e2e-tests/specs/editor/blocks/classic.test.js index d48cd0b826784d..76d58b2932e073 100644 --- a/packages/e2e-tests/specs/editor/blocks/classic.test.js +++ b/packages/e2e-tests/specs/editor/blocks/classic.test.js @@ -64,7 +64,7 @@ describe( 'Classic', () => { const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); - await inputElement.uploadFile( tmpFileName ); + await inputElement.setInputFiles( tmpFileName ); // Wait for upload. await page.waitForSelector( diff --git a/packages/e2e-tests/specs/editor/blocks/gallery.test.js b/packages/e2e-tests/specs/editor/blocks/gallery.test.js index e44e7ddf17b5e1..33e03db6492224 100644 --- a/packages/e2e-tests/specs/editor/blocks/gallery.test.js +++ b/packages/e2e-tests/specs/editor/blocks/gallery.test.js @@ -30,7 +30,7 @@ async function upload( selector ) { const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); - await inputElement.uploadFile( tmpFileName ); + await inputElement.setInputFiles( tmpFileName ); await page.waitForSelector( `.wp-block-gallery img[src$="${ filename }.png"]` ); diff --git a/packages/e2e-tests/specs/editor/blocks/image.test.js b/packages/e2e-tests/specs/editor/blocks/image.test.js index 3aed0fcb3310e3..df1c7eec6d07d0 100644 --- a/packages/e2e-tests/specs/editor/blocks/image.test.js +++ b/packages/e2e-tests/specs/editor/blocks/image.test.js @@ -34,7 +34,7 @@ async function upload( selector ) { const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.png' ); fs.copyFileSync( testImagePath, tmpFileName ); - await inputElement.uploadFile( tmpFileName ); + await inputElement.setInputFiles( tmpFileName ); return filename; } diff --git a/packages/e2e-tests/specs/editor/plugins/image-size.test.js b/packages/e2e-tests/specs/editor/plugins/image-size.test.js index a92ae630465506..8123506efc5a8f 100644 --- a/packages/e2e-tests/specs/editor/plugins/image-size.test.js +++ b/packages/e2e-tests/specs/editor/plugins/image-size.test.js @@ -46,7 +46,7 @@ describe( 'changing image size', () => { const filename = uuid(); const tmpFileName = path.join( os.tmpdir(), filename + '.jpg' ); fs.copyFileSync( testImagePath, tmpFileName ); - await inputElement.uploadFile( tmpFileName ); + await inputElement.setInputFiles( tmpFileName ); // Wait for upload to finish. await page.waitForSelector( diff --git a/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js b/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js index be20ca9e6d52d6..dd682f02e157f3 100644 --- a/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js +++ b/packages/e2e-tests/specs/editor/various/manage-reusable-blocks.test.js @@ -45,7 +45,7 @@ describe( 'Managing reusable blocks', () => { 'greeting-reusable-block.json' ); const input = await page.$( '.list-reusable-blocks-import-form input' ); - await input.uploadFile( testReusableBlockFile ); + await input.setInputFiles( testReusableBlockFile ); // Submit the form const button = await page.$( From f65086da1c6978309f280f2cd02ad113c89da793 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 15:46:52 +0200 Subject: [PATCH 03/44] Update jest.playwright.config.js - Use jest-circus runner - Specify only a subset of tests to run (editor/blocks) - Add some handy env options - Remove obsolete jest-playwright.config.js --- jest-playwright.config.js | 3 --- packages/e2e-tests/jest.playwright.config.js | 13 ++++++++++++- 2 files changed, 12 insertions(+), 4 deletions(-) delete mode 100644 jest-playwright.config.js diff --git a/jest-playwright.config.js b/jest-playwright.config.js deleted file mode 100644 index af8abe6888497d..00000000000000 --- a/jest-playwright.config.js +++ /dev/null @@ -1,3 +0,0 @@ -module.exports = { - launchBrowserApp: {}, -}; diff --git a/packages/e2e-tests/jest.playwright.config.js b/packages/e2e-tests/jest.playwright.config.js index 8eacdfa7a7daf8..57e7b280c3ba58 100644 --- a/packages/e2e-tests/jest.playwright.config.js +++ b/packages/e2e-tests/jest.playwright.config.js @@ -1,7 +1,8 @@ module.exports = { preset: 'jest-playwright-preset', - testMatch: [ '**/specs/**/*.[jt]s', '**/?(*.)spec.[jt]s' ], + testMatch: [ '**/specs/editor/blocks/**/*.js' ], testPathIgnorePatterns: [ '/node_modules/', '/wordpress/' ], + testRunner: 'jest-circus/runner', reporters: 'TRAVIS' in process.env && 'CI' in process.env ? [ @@ -13,4 +14,14 @@ module.exports = { '/config/setup-playwright.js', '@wordpress/jest-console', ], + testEnvironmentOptions: { + 'jest-playwright': { + launchOptions: { + // devtools: true, + // headless: false, // use PWDEBUG=1 for headfull run with debugger window + // slowMo: 100, + args: [ '--enable-blink-features=ComputedAccessibilityInfo' ], + }, + }, + }, }; From acca37d1da7f1282e7643c723f094032e746e686 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 15:48:05 +0200 Subject: [PATCH 04/44] Add --runInBand for serial running --- package.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/package.json b/package.json index 3a2c4b902623e9..0e28dfc41c21b8 100644 --- a/package.json +++ b/package.json @@ -264,7 +264,7 @@ "test": "npm run lint && npm run test-unit", "test:create-block": "./bin/test-create-block.sh", "test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", - "test-pl": "jest --config packages/e2e-tests/jest.playwright.config.js", + "test-pl": "jest --config packages/e2e-tests/jest.playwright.config.js --runInBand", "test-e2e:debug": "wp-scripts --inspect-brk test-e2e --config packages/e2e-tests/jest.config.js --puppeteer-devtools", "test-e2e:watch": "npm run test-e2e -- --watch", "test-performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js", From 998a8120a6ae867559def2bf4edc504a7d943b57 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 15:53:02 +0200 Subject: [PATCH 05/44] Update playwright setup - Activate twentytwenty theme - DISABLE the plugin for disabling CSS animations. We shouldn't need it anymore thanks to the auto-waiting functionality. --- packages/e2e-tests/config/setup-playwright.js | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js index 7d708b38f93d38..49316c18cb5fd4 100644 --- a/packages/e2e-tests/config/setup-playwright.js +++ b/packages/e2e-tests/config/setup-playwright.js @@ -7,8 +7,8 @@ import { get } from 'lodash'; * WordPress dependencies */ import { - //clearLocalStorage, - activatePlugin, + activateTheme, + deactivatePlugin, enablePageDialogAccept, isOfflineMode, setBrowserViewport, @@ -177,5 +177,9 @@ beforeAll( async () => { await enablePageDialogAccept(); await observeConsoleLogging(); await trashExistingPosts(); - await activatePlugin( 'gutenberg-test-plugin-disables-the-css-animations' ); + await activateTheme( 'twentytwenty' ); + + await deactivatePlugin( + 'gutenberg-test-plugin-disables-the-css-animations' + ); } ); From 415e94d39e144dc4710ddf70b045e46bdbfd01b9 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:07:52 +0200 Subject: [PATCH 06/44] Refactor saveDraft util --- packages/e2e-test-utils/src/save-draft.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/e2e-test-utils/src/save-draft.js b/packages/e2e-test-utils/src/save-draft.js index 8660910837026e..11f610b380dd91 100644 --- a/packages/e2e-test-utils/src/save-draft.js +++ b/packages/e2e-test-utils/src/save-draft.js @@ -5,7 +5,6 @@ * @return {Promise} Promise resolving when draft save is complete. */ export async function saveDraft() { - await page.waitForSelector( '.editor-post-save-draft' ); await page.click( '.editor-post-save-draft' ); - return page.waitForSelector( '.editor-post-saved-state.is-saved' ); + return await page.waitForSelector( '.editor-post-saved-state.is-saved' ); } From c4bfa475baaf6319ec95a2a6b6bf4098d04a38de Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:08:52 +0200 Subject: [PATCH 07/44] Simplify "moved to trash" selector --- packages/e2e-tests/config/setup-playwright.js | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js index 49316c18cb5fd4..76343f1923a4f9 100644 --- a/packages/e2e-tests/config/setup-playwright.js +++ b/packages/e2e-tests/config/setup-playwright.js @@ -158,9 +158,7 @@ export async function trashExistingPosts( postType = 'post' ) { await page.select( '#bulk-action-selector-top', 'trash' ); // Submit the form to send all draft/scheduled/published posts to the trash. await page.click( '#doaction' ); - await page.waitForXPath( - '//*[contains(@class, "updated notice")]/p[contains(text(), "moved to the Trash.")]' - ); + await page.waitForSelector( 'text=/moved to the trash/i' ); await switchUserToTest(); } From 4c43789eec0142990f147dc2edaaa1bd5e59bbc5 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:11:24 +0200 Subject: [PATCH 08/44] Classic block: skip cache-based test I'm skipping this for now because setCacheEnabled is not available in Playwright as the cache is disabled by default because of separate browser context. It's worth noting though that Puppeteer's setCacheEnabled is for network cache, not disk. --- packages/e2e-tests/specs/editor/blocks/classic.test.js | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/classic.test.js b/packages/e2e-tests/specs/editor/blocks/classic.test.js index 76d58b2932e073..93bf2305c9ada2 100644 --- a/packages/e2e-tests/specs/editor/blocks/classic.test.js +++ b/packages/e2e-tests/specs/editor/blocks/classic.test.js @@ -101,7 +101,12 @@ describe( 'Classic', () => { expect( await getEditedPostContent() ).toMatch( /\\s*
\\s*` @@ -359,6 +356,7 @@ describe( 'Image', () => { await pressKeyWithModifier( 'primary', 'z' ); // Expect an empty image block (placeholder) rather than one with a // broken temporary URL. + await page.waitForSelector( 'text=/Upload an image file/' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); } ); From d95ca24bd00521610dc77930558c152dc03a45f5 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:18:33 +0200 Subject: [PATCH 15/44] List block test: demo refactor --- .../specs/editor/blocks/list.test.js | 32 ++++++++++++++----- 1 file changed, 24 insertions(+), 8 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/list.test.js b/packages/e2e-tests/specs/editor/blocks/list.test.js index b75f79bb7af532..cac8781fb3eb32 100644 --- a/packages/e2e-tests/specs/editor/blocks/list.test.js +++ b/packages/e2e-tests/specs/editor/blocks/list.test.js @@ -36,6 +36,7 @@ describe( 'List', () => { await page.keyboard.type( 'test' ); await pressKeyTimes( 'ArrowLeft', 4 ); await page.keyboard.type( '* ' ); + await page.waitForSelector( 'ul[aria-label="Block: List"]' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); @@ -51,52 +52,67 @@ describe( 'List', () => { it( 'can undo asterisk transform', async () => { await clickBlockAppender(); await page.keyboard.type( '1. ' ); + await page.waitForSelector( 'ol[aria-label="Block: List"]' ); await pressKeyWithModifier( 'primary', 'z' ); + await page.waitForSelector( 'p:text-is("1. ")' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); it( 'should undo asterisk transform with backspace', async () => { await clickBlockAppender(); - await page.keyboard.type( '* ' ); + // A delay is needed here because the UI doesn't keep up and the whole + // content gets removed instead being reverted to "* ". + await page.keyboard.type( '* ', { delay: 100 } ); + await page.waitForSelector( 'ul[aria-label="Block: List"]' ); + // Adding delay to the Backspace will not have any effect because the + // undo action happens on keydown, not keyup (delay is between those events). await page.keyboard.press( 'Backspace' ); + await page.waitForSelector( 'p:text-is("* ")' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); it( 'should undo asterisk transform with backspace after selection changes', async () => { await clickBlockAppender(); - await page.keyboard.type( '* ' ); + await page.keyboard.type( '* ', { delay: 100 } ); + await page.waitForSelector( 'ul[aria-label="Block: List"]' ); await page.evaluate( () => new Promise( window.requestIdleCallback ) ); await page.keyboard.press( 'Backspace' ); + await page.waitForSelector( 'p:text-is("* ")' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); it( 'should undo asterisk transform with backspace setting isTyping state', async () => { await clickBlockAppender(); - await page.keyboard.type( '* ' ); + await page.keyboard.type( '* ', { delay: 100 } ); + await page.waitForSelector( 'ul[aria-label="Block: List"]' ); await showBlockToolbar(); await page.keyboard.press( 'Backspace' ); + await page.waitForSelector( 'p:text-is("* ")' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); it( 'should undo asterisk transform with backspace after selection changes without requestIdleCallback', async () => { await clickBlockAppender(); await page.evaluate( () => delete window.requestIdleCallback ); - await page.keyboard.type( '* ' ); - await new Promise( ( resolve ) => setTimeout( resolve, 100 ) ); + await page.keyboard.type( '* ', { delay: 100 } ); + await page.waitForSelector( 'ul[aria-label="Block: List"]' ); await page.keyboard.press( 'Backspace' ); + await page.waitForSelector( 'p:text-is("* ")' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); it( 'should undo asterisk transform with escape', async () => { await clickBlockAppender(); - await page.keyboard.type( '* ' ); + await page.keyboard.type( '* ', { delay: 100 } ); + await page.waitForSelector( 'ul[aria-label="Block: List"]' ); await page.keyboard.press( 'Escape' ); + await page.waitForSelector( 'p:text-is("* ")' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); @@ -126,8 +142,8 @@ describe( 'List', () => { // Create a list with the slash block shortcut. await clickBlockAppender(); await page.keyboard.type( '/list' ); - await page.waitForXPath( - `//*[contains(@class, "components-autocomplete__result") and contains(@class, "is-selected") and contains(text(), 'List')]` + await page.waitForSelector( + 'button[aria-selected="true"]:text("List")' ); await page.keyboard.press( 'Enter' ); await page.keyboard.type( 'Iā€™m a list' ); From 26f8ae850a29b63a486f6fa2dbb626507804b997 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:18:53 +0200 Subject: [PATCH 16/44] Missing block test: demo refactor --- packages/e2e-tests/specs/editor/blocks/missing.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/missing.test.js b/packages/e2e-tests/specs/editor/blocks/missing.test.js index 4c74cdab9c336f..1f92ddf9ced0d2 100644 --- a/packages/e2e-tests/specs/editor/blocks/missing.test.js +++ b/packages/e2e-tests/specs/editor/blocks/missing.test.js @@ -25,7 +25,7 @@ describe( 'missing block', () => { expect( hasAlert ).toBe( false ); } ); - it( 'hould strip potentially malicious script tags', async () => { + it( 'should strip potentially malicious script tags', async () => { let hasAlert = false; page.on( 'dialog', () => { From 37a49fc3e2befc49abf6a13037d3f56bbadbf457 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:19:15 +0200 Subject: [PATCH 17/44] Post Title block test: demo refactor --- .../specs/editor/blocks/post-title.test.js | 19 +++++++------------ 1 file changed, 7 insertions(+), 12 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/post-title.test.js b/packages/e2e-tests/specs/editor/blocks/post-title.test.js index 621e6815cfba84..8004054d6417bf 100644 --- a/packages/e2e-tests/specs/editor/blocks/post-title.test.js +++ b/packages/e2e-tests/specs/editor/blocks/post-title.test.js @@ -13,23 +13,18 @@ describe( 'Post Title block', () => { } ); it( 'Can edit the post title', async () => { - // Create a block with some text that will trigger a list creation. await insertBlock( 'Post Title' ); - const editablePostTitleSelector = - '.wp-block-post-title[contenteditable="true"]'; - await page.waitForSelector( editablePostTitleSelector ); - await page.focus( editablePostTitleSelector ); - // Create a second list item. - await page.keyboard.type( 'Just tweaking the post title' ); + const titleText = 'Just tweaking the post title'; + + await page.click( '[aria-label="Block: Post Title"]' ); + await page.keyboard.type( titleText ); await saveDraft(); await page.reload(); - await page.waitForSelector( '.edit-post-layout' ); - const title = await page.$eval( - '.editor-post-title__input', - ( element ) => element.textContent + + await page.waitForSelector( + `.editor-post-title >> text="${ titleText }"` ); - expect( title ).toEqual( 'Just tweaking the post title' ); } ); } ); From 4a063aa1d70f2134956b9632f11329e640d050ef Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:20:00 +0200 Subject: [PATCH 18/44] Query block test: demo refactor --- .../specs/editor/blocks/query.test.js | 22 ++++++++----------- 1 file changed, 9 insertions(+), 13 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/query.test.js b/packages/e2e-tests/specs/editor/blocks/query.test.js index 769abbf76bee37..3a7f4c1375a4ca 100644 --- a/packages/e2e-tests/specs/editor/blocks/query.test.js +++ b/packages/e2e-tests/specs/editor/blocks/query.test.js @@ -11,7 +11,7 @@ import { } from '@wordpress/e2e-test-utils'; const createDemoPosts = async () => { - await createNewPost( { postType: 'post', title: `Post 1` } ); + await createNewPost( { postType: 'post', title: 'Post 1' } ); await publishPost(); }; @@ -44,21 +44,19 @@ describe( 'Query block', () => { await page.waitForSelector( 'li.pattern-slide.active-slide[aria-label="Query Test 1"]' ); - const nextPatternButton = await page.waitForSelector( + await page.click( '.block-editor-block-pattern-setup__navigation button[aria-label="Next pattern"]' ); - await nextPatternButton.click(); await page.waitForSelector( 'li.pattern-slide.active-slide[aria-label="Query Test 2"]' ); // Choose the selected pattern. - const chooseButton = await page.waitForXPath( - '//div[contains(@class, "block-editor-block-pattern-setup__actions")]//button[text()="Choose"]' + await page.click( + '.block-editor-block-pattern-setup__actions button:text("Choose")' ); - chooseButton.click(); // Wait for pattern setup to go away. await page.waitForSelector( '.block-editor-block-pattern-setup', { - hidden: true, + state: 'hidden', } ); /** * We can't use `getEditedPostContent` easily for now because @@ -75,18 +73,16 @@ describe( 'Query block', () => { '.block-editor-block-pattern-setup__display-controls' ); // Click the Grid view button. - const gridViewButton = await page.waitForSelector( + await page.click( '.block-editor-block-pattern-setup__display-controls button[aria-label="Grid view"]' ); - await gridViewButton.click(); // Wait for patterns to be loaded and click the wanted pattern. - const gridPattern = await page.waitForXPath( - '//div[@class="block-editor-block-pattern-setup-list__item-title" and contains(text(), "Query Test 2")]' + await page.click( + '.block-editor-block-pattern-setup-list__item-title:text("Query Test 2")' ); - await gridPattern.click(); // Wait for pattern setup to go away. await page.waitForSelector( '.block-editor-block-pattern-setup', { - hidden: true, + state: 'hidden', } ); /** * We can't use `getEditedPostContent` easily for now because From f6824d0bd4c0f757378a21487aa2df8d99a444a9 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:20:14 +0200 Subject: [PATCH 19/44] Quote block test: demo refactor --- packages/e2e-tests/specs/editor/blocks/quote.test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/quote.test.js b/packages/e2e-tests/specs/editor/blocks/quote.test.js index da4efefb38de13..e02952ae11d538 100644 --- a/packages/e2e-tests/specs/editor/blocks/quote.test.js +++ b/packages/e2e-tests/specs/editor/blocks/quote.test.js @@ -41,8 +41,8 @@ describe( 'Quote', () => { // Create a list with the slash block shortcut. await clickBlockAppender(); await page.keyboard.type( '/quote' ); - await page.waitForXPath( - `//*[contains(@class, "components-autocomplete__result") and contains(@class, "is-selected") and contains(text(), 'Quote')]` + await page.waitForSelector( + 'button[aria-selected="true"]:text("Quote")' ); await page.keyboard.press( 'Enter' ); await page.keyboard.type( 'Iā€™m a quote' ); From 4d8daa72aea6d0ebf4a79a7cfdfba8229988715f Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:20:38 +0200 Subject: [PATCH 20/44] Site Title block test: demo refactor --- .../specs/editor/blocks/site-title.test.js | 33 +++++-------------- 1 file changed, 9 insertions(+), 24 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/site-title.test.js b/packages/e2e-tests/specs/editor/blocks/site-title.test.js index 60aefe5637b3aa..78ac7c3d9bab69 100644 --- a/packages/e2e-tests/specs/editor/blocks/site-title.test.js +++ b/packages/e2e-tests/specs/editor/blocks/site-title.test.js @@ -29,34 +29,22 @@ async function setOption( setting, value ) { await switchUserToAdmin(); await visitAdminPage( 'options-general.php' ); - await page.focus( `#${ setting }` ); - await pressKeyWithModifier( 'primary', 'a' ); - await page.type( `#${ setting }`, value ); + await page.fill( `#${ setting }`, value ); await Promise.all( [ page.click( '#submit' ), - page.waitForNavigation( { waitUntil: 'networkidle0' } ), + page.waitForNavigation( { waitUntil: 'networkidle' } ), ] ); await switchUserToTest(); } const saveEntities = async () => { - const savePostSelector = '.editor-post-publish-button__button'; - const savePanelSelector = '.entities-saved-states__panel'; - const entitiesSaveSelector = '.editor-entities-saved-states__save-button'; - const publishPanelSelector = '.editor-post-publish-panel'; - const closePanelButtonSelector = - '.editor-post-publish-panel__header-cancel-button button'; - - await page.click( savePostSelector ); - await page.waitForSelector( savePanelSelector ); - await page.click( entitiesSaveSelector ); - await page.waitForSelector( publishPanelSelector ); - await page.waitForSelector( - '.editor-post-publish-panel__header-cancel-button button:not([disabled])' - ); - await page.click( closePanelButtonSelector ); + await page.click( 'button:text-is("Publish")' ); + await Promise.all( [ + page.waitForResponse( /settings/ ), + page.click( 'button:text-is("Save")' ), + ] ); }; describe( 'Site Title block', () => { @@ -75,12 +63,9 @@ describe( 'Site Title block', () => { it( 'Can edit the site title as admin', async () => { await createNewPost(); await insertBlock( 'Site Title' ); - const editableSiteTitleSelector = - '[aria-label="Block: Site Title"] a[contenteditable="true"]'; - await page.waitForSelector( editableSiteTitleSelector ); - await page.focus( editableSiteTitleSelector ); - await pressKeyWithModifier( 'primary', 'a' ); + await page.click( '[aria-label="Site title text"]' ); + await pressKeyWithModifier( 'primary', 'a' ); await page.keyboard.type( 'New Site Title' ); await saveEntities(); From b95bec88f2328cfbba9569d81b8ea53dfd99ee26 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:20:56 +0200 Subject: [PATCH 21/44] Spacer block test: demo refactor --- .../e2e-tests/specs/editor/blocks/spacer.test.js | 15 ++++++--------- 1 file changed, 6 insertions(+), 9 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/spacer.test.js b/packages/e2e-tests/specs/editor/blocks/spacer.test.js index 258fc59a6d1eed..44ed92e8a6238d 100644 --- a/packages/e2e-tests/specs/editor/blocks/spacer.test.js +++ b/packages/e2e-tests/specs/editor/blocks/spacer.test.js @@ -17,8 +17,8 @@ describe( 'Spacer', () => { // Create a spacer with the slash block shortcut. await clickBlockAppender(); await page.keyboard.type( '/spacer' ); - await page.waitForXPath( - `//*[contains(@class, "components-autocomplete__result") and contains(@class, "is-selected") and contains(text(), 'Spacer')]` + await page.waitForSelector( + 'button[aria-selected="true"]:text-is("Spacer")' ); await page.keyboard.press( 'Enter' ); @@ -29,20 +29,17 @@ describe( 'Spacer', () => { // Create a spacer with the slash block shortcut. await clickBlockAppender(); await page.keyboard.type( '/spacer' ); - await page.waitForXPath( - `//*[contains(@class, "components-autocomplete__result") and contains(@class, "is-selected") and contains(text(), 'Spacer')]` + await page.waitForSelector( + 'button[aria-selected="true"]:text-is("Spacer")' ); await page.keyboard.press( 'Enter' ); - const resizableHandle = await page.$( + const resizableHandle = await page.waitForSelector( '.block-library-spacer__resize-container .components-resizable-box__handle' ); await dragAndResize( resizableHandle, { x: 0, y: 50 } ); expect( await getEditedPostContent() ).toMatchSnapshot(); - const selectedSpacer = await page.$( - '[data-type="core/spacer"].is-selected' - ); - expect( selectedSpacer ).not.toBe( null ); + await page.waitForSelector( '[data-type="core/spacer"].is-selected' ); } ); } ); From cba116d7db75e9f4678586b1e3dc44b83f0d56f3 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:25:54 +0200 Subject: [PATCH 22/44] Rich Text test: demo refactor --- .../specs/editor/various/rich-text.test.js | 96 +++++++++++++------ 1 file changed, 68 insertions(+), 28 deletions(-) diff --git a/packages/e2e-tests/specs/editor/various/rich-text.test.js b/packages/e2e-tests/specs/editor/various/rich-text.test.js index f5113e8b1d16a4..7853220eac9aad 100644 --- a/packages/e2e-tests/specs/editor/various/rich-text.test.js +++ b/packages/e2e-tests/specs/editor/various/rich-text.test.js @@ -265,10 +265,33 @@ describe( 'RichText', () => { await page.keyboard.press( 'Home' ); await page.keyboard.type( '-' ); - await page.keyboard.press( 'End' ); + await page.keyboard.press( 'End' ); // Scrolls the page down + + // Wait for the scroll to finish and hit End again + // const paragraph = await page.waitForSelector( + // '[aria-label="Paragraph block"]' + // ); + // await paragraph.waitForElementState( 'stable' ); + // await page.keyboard.press( 'End' ); + await page.keyboard.type( '+' ); expect( await getEditedPostContent() ).toMatchSnapshot(); + /** + * - Snapshot - 1 + * + Received + 1 + * + * + * -

-12+

+ * +

-+12

+ * + * + * This one's correct to be failing because the first End key press scrolls the page to the end + * and only the second one (after the scroll finished) will move the cursor to the EOL. This can + * be confirmed by testing manually, and TBH I'm not sure why Puppeteer is behaving differently + * here, but I have a hunch that it has something to do with how it resizes the browser to match + * the given viewport. + */ } ); it( 'should update internal selection after fresh focus', async () => { @@ -382,43 +405,42 @@ describe( 'RichText', () => { // Add text and select to color. await page.keyboard.type( '1' ); await pressKeyWithModifier( 'primary', 'a' ); + + // Open the color menu. await clickBlockToolbarButton( 'More' ); + await page.click( 'button:text-is( "Highlight" )' ); - const button = await page.waitForXPath( - `//button[text()='Highlight']` - ); - // Clicks may fail if the button is out of view. Assure it is before click. - await button.evaluate( ( element ) => element.scrollIntoView() ); - await button.click(); - - // Tab to the "Text" tab. - await page.keyboard.press( 'Tab' ); - // Tab to black. - await page.keyboard.press( 'Tab' ); - // Select color other than black. - await page.keyboard.press( 'Tab' ); - await page.keyboard.press( 'Enter' ); + // Apply the "Pale pink" color. + await page.click( 'button[ aria-label="Color: Pale pink" ]' ); + // Make sure the colored text is visible + const coloredTextSelector = '.has-pale-pink-color:text-is( "1" )'; + await page.waitForSelector( coloredTextSelector, { state: 'visible' } ); expect( await getEditedPostContent() ).toMatchSnapshot(); // Dismiss color picker popover - await page.keyboard.press( 'Escape' ); + await page.keyboard.press( 'Escape', { delay: 100 } ); // Navigate to the block. - await page.keyboard.press( 'Tab' ); + await page.keyboard.press( 'Tab', { delay: 100 } ); // Copy the colored text. await pressKeyWithModifier( 'primary', 'c' ); // Collapsed the selection to the end. - await page.keyboard.press( 'ArrowRight' ); + await page.keyboard.press( 'ArrowRight', { delay: 100 } ); // Create a new paragraph. - await page.keyboard.press( 'Enter' ); + await page.keyboard.press( 'Enter', { delay: 100 } ); // Paste the colored text. await pressKeyWithModifier( 'primary', 'v' ); + // Make sure the pasted/second colored text is visible + await page.waitForSelector( + `:nth-match( ${ coloredTextSelector }, 2 )`, + { state: 'visible' } + ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); @@ -430,30 +452,47 @@ describe( 'RichText', () => { await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.type( '1' ); - // Expect '1šŸ“'. + // Expect the text to be typed correctly. + await page.waitForSelector( '1šŸ“', { state: 'visible' } ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); it( 'should show/hide toolbar when entering/exiting format', async () => { const blockToolbarSelector = '.block-editor-block-toolbar'; await clickBlockAppender(); + await page.keyboard.type( '1' ); - expect( await page.$( blockToolbarSelector ) ).toBe( null ); + await page.waitForSelector( blockToolbarSelector, { state: 'hidden' } ); + await pressKeyWithModifier( 'primary', 'b' ); - expect( await page.$( blockToolbarSelector ) ).not.toBe( null ); + await page.waitForSelector( blockToolbarSelector, { + state: 'visible', + } ); + await page.keyboard.type( '2' ); - expect( await page.$( blockToolbarSelector ) ).not.toBe( null ); + await page.waitForSelector( blockToolbarSelector, { + state: 'visible', + } ); + await pressKeyWithModifier( 'primary', 'b' ); - expect( await page.$( blockToolbarSelector ) ).toBe( null ); + await page.waitForSelector( blockToolbarSelector, { state: 'hidden' } ); + await page.keyboard.type( '3' ); await page.keyboard.press( 'ArrowLeft' ); - expect( await page.$( blockToolbarSelector ) ).toBe( null ); + await page.waitForSelector( blockToolbarSelector, { state: 'hidden' } ); + await page.keyboard.press( 'ArrowLeft' ); - expect( await page.$( blockToolbarSelector ) ).not.toBe( null ); + await page.waitForSelector( blockToolbarSelector, { + state: 'visible', + } ); + await page.keyboard.press( 'ArrowLeft' ); - expect( await page.$( blockToolbarSelector ) ).not.toBe( null ); + await page.waitForSelector( blockToolbarSelector, { + state: 'visible', + } ); + await page.keyboard.press( 'ArrowLeft' ); - expect( await page.$( blockToolbarSelector ) ).toBe( null ); + await page.waitForSelector( blockToolbarSelector, { state: 'hidden' } ); } ); it( 'should run input rules after composition end', async () => { @@ -472,6 +511,7 @@ describe( 'RichText', () => { ); } ); + await page.waitForSelector( 'code:text-is( "a" )' ); expect( await getEditedPostContent() ).toMatchSnapshot(); } ); From 953a8675460b3dc3d7b288c96d031e3830c8c884 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 17:55:12 +0200 Subject: [PATCH 23/44] Columns block test: demo refactor --- packages/e2e-tests/specs/editor/blocks/columns.test.js | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/columns.test.js b/packages/e2e-tests/specs/editor/blocks/columns.test.js index da30710f5c43c0..2a7dcd745f1331 100644 --- a/packages/e2e-tests/specs/editor/blocks/columns.test.js +++ b/packages/e2e-tests/specs/editor/blocks/columns.test.js @@ -19,13 +19,11 @@ describe( 'Columns', () => { await closeGlobalBlockInserter(); await page.click( '[aria-label="Two columns; equal split"]' ); await page.click( '.edit-post-header-toolbar__list-view-toggle' ); - const columnBlockMenuItem = ( - await page.$x( - '//button[contains(concat(" ", @class, " "), " block-editor-list-view-block-select-button ")][text()="Column"]' - ) - )[ 0 ]; - await columnBlockMenuItem.click(); + await page.click( + '.block-editor-list-view-block-select-button:text-is("Column")' + ); await openGlobalBlockInserter(); + expect( await getAllBlockInserterItemTitles() ).toHaveLength( 1 ); } ); } ); From b957a100def94b8b70c2995064a647e7d0c37ebf Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 18:26:24 +0200 Subject: [PATCH 24/44] Cover block test: demo refactor --- .../e2e-tests/specs/editor/blocks/cover.test.js | 17 +++++------------ 1 file changed, 5 insertions(+), 12 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/cover.test.js b/packages/e2e-tests/specs/editor/blocks/cover.test.js index cd737f77a3702f..ac7b44751b0c6e 100644 --- a/packages/e2e-tests/specs/editor/blocks/cover.test.js +++ b/packages/e2e-tests/specs/editor/blocks/cover.test.js @@ -29,16 +29,12 @@ describe( 'Cover', () => { '.block-editor-list-view-block__contents-container button' ); - const heightInput = ( - await page.$x( - '//div[./label[contains(text(),"Minimum height of cover")]]//input' - ) - )[ 0 ]; + const heightInput = await page.waitForSelector( + 'input:below(:text("Minimum height of cover"))' + ); // Verify the height of the cover is not defined - expect( - await page.evaluate( ( { value } ) => value, heightInput ) - ).toBeFalsy(); + expect( await heightInput.getAttribute( 'value' ) ).toBeFalsy(); const resizeButton = await page.$( '.components-resizable-box__handle-bottom' @@ -81,10 +77,7 @@ describe( 'Cover', () => { // Verify the height of the cover has changed. expect( - await page.evaluate( - ( { value } ) => Number.parseInt( value ), - heightInput - ) + Number.parseInt( await heightInput.getAttribute( 'value' ) ) ).toBeGreaterThan( 100 ); } ); } ); From 0c99d348cc3d79a778a75dd780e2c1d3b54e78d8 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Mon, 16 Aug 2021 18:28:51 +0200 Subject: [PATCH 25/44] See if the CI catches --- .github/workflows/end2end-test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/end2end-test.yml b/.github/workflows/end2end-test.yml index 618d10f7db2b93..f8698b2d55b9d1 100644 --- a/.github/workflows/end2end-test.yml +++ b/.github/workflows/end2end-test.yml @@ -46,8 +46,8 @@ jobs: - name: Running the tests run: | - $( npm bin )/wp-scripts test-e2e --config=./packages/e2e-tests/jest.config.js --listTests > ~/.jest-e2e-tests - $( npm bin )/wp-scripts test-e2e --config=./packages/e2e-tests/jest.config.js --cacheDirectory="$HOME/.jest-cache" --runTestsByPath $( awk 'NR % 4 == ${{ matrix.part }} - 1' < ~/.jest-e2e-tests ) + $( npm bin )/wp-scripts test-e2e --config=./packages/e2e-tests/jest.playwright.config.js --listTests > ~/.jest-e2e-tests + $( npm bin )/wp-scripts test-e2e --config=./packages/e2e-tests/jest.playwright.config.js --cacheDirectory="$HOME/.jest-cache" --runTestsByPath $( awk 'NR % 4 == ${{ matrix.part }} - 1' < ~/.jest-e2e-tests ) - name: Archive debug artifacts (screenshots, HTML snapshots) uses: actions/upload-artifact@e448a9b857ee2131e752b06002bf0e093c65e571 # v2.2.2 From 8ccbd3daf592537084f7e0b308a5f4f0e8b7dfdb Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Tue, 17 Aug 2021 15:37:01 +0200 Subject: [PATCH 26/44] Use test-e2e script for running the specs locally --- package.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/package.json b/package.json index 0e28dfc41c21b8..1184541c67f797 100644 --- a/package.json +++ b/package.json @@ -263,8 +263,7 @@ "publish:latest": "lerna publish", "test": "npm run lint && npm run test-unit", "test:create-block": "./bin/test-create-block.sh", - "test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.config.js", - "test-pl": "jest --config packages/e2e-tests/jest.playwright.config.js --runInBand", + "test-e2e": "wp-scripts test-e2e --config packages/e2e-tests/jest.playwright.config.js", "test-e2e:debug": "wp-scripts --inspect-brk test-e2e --config packages/e2e-tests/jest.config.js --puppeteer-devtools", "test-e2e:watch": "npm run test-e2e -- --watch", "test-performance": "wp-scripts test-e2e --config packages/e2e-tests/jest.performance.config.js", From 6cc0bbf2d32cfd03bc2afba1dfe3f5763867865f Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 18 Aug 2021 16:22:35 +0200 Subject: [PATCH 27/44] Refactor insertBlock utility - Type in directly when searching for block. - Wait for the block to be stable when focused as the layout shifts when the Inserter closes. - Remove unnecessary waitForInserterCloseAndContentFocus call because Playwright's auto-waiting does that automagically. --- packages/e2e-test-utils/src/inserter.js | 35 ++++++++++--------------- 1 file changed, 14 insertions(+), 21 deletions(-) diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index 1bcce329f07dff..cb8f40887d5d5f 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -62,17 +62,17 @@ export async function toggleGlobalBlockInserter() { * Moves focus to the selected block. */ async function focusSelectedBlock() { - // Ideally there shouuld be a UI way to do this. (Focus the selected block) - await page.evaluate( () => { - wp.data - .dispatch( 'core/block-editor' ) - .selectBlock( - wp.data - .select( 'core/block-editor' ) - .getSelectedBlockClientId(), - 0 - ); - } ); + // Do a waitForFunction and wait until block is really focused + const blockId = await page.evaluate( () => + wp.data.select( 'core/block-editor' ).getSelectedBlockClientId() + ); + const blockElement = await page.waitForSelector( + `[data-block="${ blockId }"]` + ); + await page.evaluate( ( id ) => { + wp.data.dispatch( 'core/block-editor' ).selectBlock( id, 0 ); + }, blockId ); + await blockElement.waitForElementState( 'stable' ); } /** @@ -94,10 +94,8 @@ async function waitForInserterCloseAndContentFocus() { */ export async function searchForBlock( searchTerm ) { await openGlobalBlockInserter(); - await page.waitForSelector( INSERTER_SEARCH_SELECTOR ); - await page.focus( INSERTER_SEARCH_SELECTOR ); - await pressKeyWithModifier( 'primary', 'a' ); - await page.keyboard.type( searchTerm ); + await page.fill( INSERTER_SEARCH_SELECTOR, '' ); + await page.type( INSERTER_SEARCH_SELECTOR, searchTerm ); } /** @@ -152,13 +150,8 @@ export async function searchForReusableBlock( searchTerm ) { */ export async function insertBlock( searchTerm ) { await searchForBlock( searchTerm ); - const insertButton = await page.waitForXPath( - `//button//span[contains(text(), '${ searchTerm }')]` - ); - await insertButton.click(); + await page.click( `button :text("${ searchTerm }")` ); await focusSelectedBlock(); - // We should wait until the inserter closes and the focus moves to the content. - await waitForInserterCloseAndContentFocus(); } /** From 51787bffe625fca7fd77fe9bac8ac41abbe0386a Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 18 Aug 2021 16:24:40 +0200 Subject: [PATCH 28/44] Refactor clickBlockToolbarButton util - Remove explicit `waits` and remove the unnecessary scrollIntoView call (all thanks to auto-waiting) --- .../src/click-block-toolbar-button.js | 14 +++++--------- 1 file changed, 5 insertions(+), 9 deletions(-) diff --git a/packages/e2e-test-utils/src/click-block-toolbar-button.js b/packages/e2e-test-utils/src/click-block-toolbar-button.js index e73888f0681385..f7032d982c46a0 100644 --- a/packages/e2e-test-utils/src/click-block-toolbar-button.js +++ b/packages/e2e-test-utils/src/click-block-toolbar-button.js @@ -11,21 +11,17 @@ import { showBlockToolbar } from './show-block-toolbar'; */ export async function clickBlockToolbarButton( label, type = 'ariaLabel' ) { await showBlockToolbar(); - const BLOCK_TOOLBAR_SELECTOR = 'block-editor-block-toolbar'; - let button; + const BLOCK_TOOLBAR_SELECTOR = '.block-editor-block-toolbar'; if ( type === 'ariaLabel' ) { - button = await page.waitForSelector( - `.${ BLOCK_TOOLBAR_SELECTOR } button[aria-label="${ label }"]` + return await page.click( + `${ BLOCK_TOOLBAR_SELECTOR } button[aria-label="${ label }"]` ); } if ( type === 'content' ) { - button = await page.waitForXPath( - `//*[contains(concat(' ', normalize-space(@class), ' '), ' ${ BLOCK_TOOLBAR_SELECTOR } ')]//button[contains(text(), '${ label }')]` + return await page.click( + `${ BLOCK_TOOLBAR_SELECTOR } button :text("${ label }")` ); } - - await button.evaluate( ( element ) => element.scrollIntoView() ); - await button.click(); } From 355c8079eb585a5e6dfc32e78f31712bb3850fd1 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 18 Aug 2021 16:25:33 +0200 Subject: [PATCH 29/44] Refactor clickMenuItem util Doesn't really seem like we need it anymore? --- packages/e2e-test-utils/src/click-menu-item.js | 12 +----------- 1 file changed, 1 insertion(+), 11 deletions(-) diff --git a/packages/e2e-test-utils/src/click-menu-item.js b/packages/e2e-test-utils/src/click-menu-item.js index e4a29eacf39e60..ee506b07424549 100644 --- a/packages/e2e-test-utils/src/click-menu-item.js +++ b/packages/e2e-test-utils/src/click-menu-item.js @@ -1,18 +1,8 @@ -/** - * External dependencies - */ -import { first } from 'lodash'; - /** * Searches for an item in the menu with the text provided and clicks it. * * @param {string} label The label to search the menu item for. */ export async function clickMenuItem( label ) { - const elementToClick = first( - await page.$x( - `//div[@role="menu"]//span[contains(concat(" ", @class, " "), " components-menu-item__item ")][contains(text(), "${ label }")]` - ) - ); - await elementToClick.click(); + await page.click( `button :text("${ label }")` ); } From 36146d0c9fd8f049ef338b1d1d5a05690ac76dc2 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 18 Aug 2021 16:44:34 +0200 Subject: [PATCH 30/44] Fix accidental selector nesting --- packages/e2e-test-utils/src/click-block-toolbar-button.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-test-utils/src/click-block-toolbar-button.js b/packages/e2e-test-utils/src/click-block-toolbar-button.js index f7032d982c46a0..e25cec2f69ac0c 100644 --- a/packages/e2e-test-utils/src/click-block-toolbar-button.js +++ b/packages/e2e-test-utils/src/click-block-toolbar-button.js @@ -21,7 +21,7 @@ export async function clickBlockToolbarButton( label, type = 'ariaLabel' ) { if ( type === 'content' ) { return await page.click( - `${ BLOCK_TOOLBAR_SELECTOR } button :text("${ label }")` + `${ BLOCK_TOOLBAR_SELECTOR } button:text("${ label }")` ); } } From 2cba1a87991aea229daf53737e34d928cf171ee2 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 25 Aug 2021 13:25:12 +0200 Subject: [PATCH 31/44] Remove hello.test.js --- packages/e2e-tests/playwright/specs/hello.test.js | 5 ----- 1 file changed, 5 deletions(-) delete mode 100644 packages/e2e-tests/playwright/specs/hello.test.js diff --git a/packages/e2e-tests/playwright/specs/hello.test.js b/packages/e2e-tests/playwright/specs/hello.test.js deleted file mode 100644 index a0239518181fdb..00000000000000 --- a/packages/e2e-tests/playwright/specs/hello.test.js +++ /dev/null @@ -1,5 +0,0 @@ -describe( 'hello', () => { - it( 'world', async () => { - expect( true ).toBe( true ); - } ); -} ); From d20e558a17036dd42c50827f2a65ee0549f101d9 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 25 Aug 2021 13:29:27 +0200 Subject: [PATCH 32/44] Remove obsolete waitForSelector --- packages/e2e-tests/config/setup-playwright.js | 1 - 1 file changed, 1 deletion(-) diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js index 76343f1923a4f9..a91b7865caa95d 100644 --- a/packages/e2e-tests/config/setup-playwright.js +++ b/packages/e2e-tests/config/setup-playwright.js @@ -152,7 +152,6 @@ export async function trashExistingPosts( postType = 'post' ) { } // Select all posts. - await page.waitForSelector( '[id^=cb-select-all-]' ); await page.click( '[id^=cb-select-all-]' ); // Select the "bulk actions" > "trash" option. await page.select( '#bulk-action-selector-top', 'trash' ); From 913de3e6ab7b55aa84a618d5337aceb1b7fca38d Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 25 Aug 2021 13:45:26 +0200 Subject: [PATCH 33/44] Update confusing parts copypasted from Puppeteer setup --- packages/e2e-tests/config/setup-playwright.js | 124 +----------------- 1 file changed, 7 insertions(+), 117 deletions(-) diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js index a91b7865caa95d..6553e23498afda 100644 --- a/packages/e2e-tests/config/setup-playwright.js +++ b/packages/e2e-tests/config/setup-playwright.js @@ -1,8 +1,3 @@ -/** - * External dependencies - */ -import { get } from 'lodash'; - /** * WordPress dependencies */ @@ -10,7 +5,6 @@ import { activateTheme, deactivatePlugin, enablePageDialogAccept, - isOfflineMode, setBrowserViewport, switchUserToAdmin, switchUserToTest, @@ -18,118 +12,11 @@ import { } from '@wordpress/e2e-test-utils'; import { addQueryArgs } from '@wordpress/url'; -// The Jest timeout is increased because these tests are a bit slow -jest.setTimeout( 100000 ); - -/** - * Set of console logging types observed to protect against unexpected yet - * handled (i.e. not catastrophic) errors or warnings. Each key corresponds - * to the Puppeteer ConsoleMessage type, its value the corresponding function - * on the console global object. - * - * @type {Object} - */ -const OBSERVED_CONSOLE_MESSAGE_TYPES = { - warning: 'warn', - error: 'error', -}; - async function setupBrowser() { //await clearLocalStorage(); await setBrowserViewport( 'large' ); } -/** - * Adds a page event handler to emit uncaught exception to process if one of - * the observed console logging types is encountered. - */ -function observeConsoleLogging() { - page.on( 'console', ( message ) => { - const type = message.type(); - if ( ! OBSERVED_CONSOLE_MESSAGE_TYPES.hasOwnProperty( type ) ) { - return; - } - - let text = message.text(); - - // An exception is made for _blanket_ deprecation warnings: Those - // which log regardless of whether a deprecated feature is in use. - if ( text.includes( 'This is a global warning' ) ) { - return; - } - - // A chrome advisory warning about SameSite cookies is informational - // about future changes, tracked separately for improvement in core. - // - // See: https://core.trac.wordpress.org/ticket/37000 - // See: https://www.chromestatus.com/feature/5088147346030592 - // See: https://www.chromestatus.com/feature/5633521622188032 - if ( - text.includes( 'A cookie associated with a cross-site resource' ) - ) { - return; - } - - // Viewing posts on the front end can result in this error, which - // has nothing to do with Gutenberg. - if ( text.includes( 'net::ERR_UNKNOWN_URL_SCHEME' ) ) { - return; - } - - // Network errors are ignored only if we are intentionally testing - // offline mode. - if ( - text.includes( 'net::ERR_INTERNET_DISCONNECTED' ) && - isOfflineMode() - ) { - return; - } - - // As of WordPress 5.3.2 in Chrome 79, navigating to the block editor - // (Posts > Add New) will display a console warning about - // non - unique IDs. - // See: https://core.trac.wordpress.org/ticket/23165 - if ( text.includes( 'elements with non-unique id #_wpnonce' ) ) { - return; - } - - // As of WordPress 5.3.2 in Chrome 79, navigating to the block editor - // (Posts > Add New) will display a console warning about - // non - unique IDs. - // See: https://core.trac.wordpress.org/ticket/23165 - if ( text.includes( 'elements with non-unique id #_wpnonce' ) ) { - return; - } - - const logFunction = OBSERVED_CONSOLE_MESSAGE_TYPES[ type ]; - - // As of Puppeteer 1.6.1, `message.text()` wrongly returns an object of - // type JSHandle for error logging, instead of the expected string. - // - // See: https://github.com/GoogleChrome/puppeteer/issues/3397 - // - // The recommendation there to asynchronously resolve the error value - // upon a console event may be prone to a race condition with the test - // completion, leaving a possibility of an error not being surfaced - // correctly. Instead, the logic here synchronously inspects the - // internal object shape of the JSHandle to find the error text. If it - // cannot be found, the default text value is used instead. - text = get( - message.args(), - [ 0, '_remoteObject', 'description' ], - text - ); - - // Disable reason: We intentionally bubble up the console message - // which, unless the test explicitly anticipates the logging via - // @wordpress/jest-console matchers, will cause the intended test - // failure. - - // eslint-disable-next-line no-console - console[ logFunction ]( text ); - } ); -} - /** * Navigates to the post listing screen and bulk-trashes any posts which exist. * @@ -161,21 +48,24 @@ export async function trashExistingPosts( postType = 'post' ) { await switchUserToTest(); } -// Before every test suite run, delete all content created by the test. This ensures -// other posts/comments/etc. aren't dirtying tests and tests don't depend on -// each other's side-effects. beforeAll( async () => { + // Address Puppetteer vs Playwright API differences before running the tests page.$x = page.$$; page.select = page.selectOption; page.waitForXPath = page.waitForSelector; page.waitFor = page.waitForTimeout; page.cookies = () => page.context().cookies(); + + // Initialize the environment await setupBrowser(); await enablePageDialogAccept(); - await observeConsoleLogging(); await trashExistingPosts(); await activateTheme( 'twentytwenty' ); + // Deactivate the plugin that disables the CSS animations in case it's enabled + // (it is enabled for Puppeteer tests). We don't need to disable any + // animations anymore thanks to Playwright's automatic element stability + // check. await deactivatePlugin( 'gutenberg-test-plugin-disables-the-css-animations' ); From 61cec233e347206f230988194dd726d089752567 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 25 Aug 2021 13:53:28 +0200 Subject: [PATCH 34/44] Make devtools/headless/sloMo args usable --- packages/e2e-tests/jest.playwright.config.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/e2e-tests/jest.playwright.config.js b/packages/e2e-tests/jest.playwright.config.js index 57e7b280c3ba58..519933af748493 100644 --- a/packages/e2e-tests/jest.playwright.config.js +++ b/packages/e2e-tests/jest.playwright.config.js @@ -17,9 +17,9 @@ module.exports = { testEnvironmentOptions: { 'jest-playwright': { launchOptions: { - // devtools: true, - // headless: false, // use PWDEBUG=1 for headfull run with debugger window - // slowMo: 100, + devtools: process.env.PLAYWRIGHT_DEVTOOLS === 'true', + headless: process.env.PLAYWRIGHT_HEADLESS !== 'false', + slowMo: parseInt( process.env.PLAYWRIGHT_SLOWMO, 10 ) || 0, args: [ '--enable-blink-features=ComputedAccessibilityInfo' ], }, }, From 5da8b94bdc11fded6a1877d56c9d3801cd614503 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 25 Aug 2021 13:54:14 +0200 Subject: [PATCH 35/44] Remove obsolete visibility check --- packages/e2e-tests/specs/editor/blocks/image.test.js | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/image.test.js b/packages/e2e-tests/specs/editor/blocks/image.test.js index a2c8930e6aa0fa..d631aa47518e8c 100644 --- a/packages/e2e-tests/specs/editor/blocks/image.test.js +++ b/packages/e2e-tests/specs/editor/blocks/image.test.js @@ -41,8 +41,7 @@ async function upload( inputSelector ) { async function waitForImage( filename ) { const imageElement = await page.waitForSelector( - `.wp-block-image img[src$="${ filename }.png"]`, - { state: 'visible' } + `.wp-block-image img[src$="${ filename }.png"]` ); return imageElement; From 6c69a32904fbefb9b5f84dd466643353407027f0 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 25 Aug 2021 14:06:48 +0200 Subject: [PATCH 36/44] Remove unrelated note --- packages/e2e-test-utils/src/inserter.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index cb8f40887d5d5f..73feefbe3770ea 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -62,13 +62,13 @@ export async function toggleGlobalBlockInserter() { * Moves focus to the selected block. */ async function focusSelectedBlock() { - // Do a waitForFunction and wait until block is really focused const blockId = await page.evaluate( () => wp.data.select( 'core/block-editor' ).getSelectedBlockClientId() ); const blockElement = await page.waitForSelector( `[data-block="${ blockId }"]` ); + // Ideally there should be a UI way to do this. (Focus the selected block) await page.evaluate( ( id ) => { wp.data.dispatch( 'core/block-editor' ).selectBlock( id, 0 ); }, blockId ); From 193d26ca7aa77e5c6dcc20c9efa39eea8aaf96a5 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Wed, 25 Aug 2021 14:35:53 +0200 Subject: [PATCH 37/44] Restore the increased jest timeout (Removed accidentally) --- packages/e2e-tests/config/setup-playwright.js | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js index 6553e23498afda..d6664950b8d630 100644 --- a/packages/e2e-tests/config/setup-playwright.js +++ b/packages/e2e-tests/config/setup-playwright.js @@ -12,8 +12,10 @@ import { } from '@wordpress/e2e-test-utils'; import { addQueryArgs } from '@wordpress/url'; +// The Jest timeout is increased because these tests are a bit slow +jest.setTimeout( 100000 ); + async function setupBrowser() { - //await clearLocalStorage(); await setBrowserViewport( 'large' ); } From 8f29a9a49c24a128b63359e0e3016e53f330a93d Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Fri, 27 Aug 2021 15:18:40 +0200 Subject: [PATCH 38/44] Explicitly close the inserter before focusing block --- packages/e2e-test-utils/src/inserter.js | 1 + 1 file changed, 1 insertion(+) diff --git a/packages/e2e-test-utils/src/inserter.js b/packages/e2e-test-utils/src/inserter.js index 73feefbe3770ea..772b315121e031 100644 --- a/packages/e2e-test-utils/src/inserter.js +++ b/packages/e2e-test-utils/src/inserter.js @@ -151,6 +151,7 @@ export async function searchForReusableBlock( searchTerm ) { export async function insertBlock( searchTerm ) { await searchForBlock( searchTerm ); await page.click( `button :text("${ searchTerm }")` ); + await toggleGlobalBlockInserter(); await focusSelectedBlock(); } From 3dc4cea8498b6397388d9dce105a6a87842a4ea5 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Fri, 27 Aug 2021 15:19:19 +0200 Subject: [PATCH 39/44] Simplify transformBlockTo util --- .../e2e-test-utils/src/transform-block-to.js | 21 +++---------------- 1 file changed, 3 insertions(+), 18 deletions(-) diff --git a/packages/e2e-test-utils/src/transform-block-to.js b/packages/e2e-test-utils/src/transform-block-to.js index 4a6968c684904e..629a2326a596e3 100644 --- a/packages/e2e-test-utils/src/transform-block-to.js +++ b/packages/e2e-test-utils/src/transform-block-to.js @@ -11,25 +11,10 @@ import { showBlockToolbar } from './show-block-toolbar'; export async function transformBlockTo( name ) { await showBlockToolbar(); - const switcherToggle = await page.waitForSelector( - '.block-editor-block-switcher__toggle' + await page.click( '.block-editor-block-switcher__toggle' ); + await page.click( + `.block-editor-block-switcher__popover :text-is("${ name }")` ); - await switcherToggle.evaluate( ( element ) => element.scrollIntoView() ); - await page.waitForSelector( '.block-editor-block-switcher__toggle', { - visible: true, - } ); - await switcherToggle.click(); - await page.waitForSelector( '.block-editor-block-switcher__container', { - visible: true, - } ); - - // Find the block button option within the switcher popover. - const xpath = `//*[contains(@class, "block-editor-block-switcher__popover")]//button[.='${ name }']`; - const insertButton = await page.waitForXPath( xpath, { visible: true } ); - // Clicks may fail if the button is out of view. Assure it is before click. - await insertButton.evaluate( ( element ) => element.scrollIntoView() ); - await insertButton.click(); - // Wait for the transformed block to appear. const BLOCK_SELECTOR = '.block-editor-block-list__block'; const BLOCK_NAME_SELECTOR = `[data-title="${ name }"]`; From f6812eb9d8b15e60fe76caebf5bb0bd2c61c0f5e Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Fri, 27 Aug 2021 15:21:13 +0200 Subject: [PATCH 40/44] Bring focus back to image block to hide the caption toolbar It's standing in the way of the Replace button because the test image is really small. --- packages/e2e-tests/specs/editor/blocks/image.test.js | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/packages/e2e-tests/specs/editor/blocks/image.test.js b/packages/e2e-tests/specs/editor/blocks/image.test.js index d631aa47518e8c..44f617cf5c288f 100644 --- a/packages/e2e-tests/specs/editor/blocks/image.test.js +++ b/packages/e2e-tests/specs/editor/blocks/image.test.js @@ -97,6 +97,8 @@ describe( 'Image', () => { expect( await getEditedPostContent() ).toMatch( regex2 ); + // Focus back to the img element for the right context + await page.click( '[aria-label="Block: Image"] img' ); await clickButton( 'Replace' ); const filename2 = await upload( '.block-editor-media-replace-flow__options input[type="file"]' @@ -120,9 +122,13 @@ describe( 'Image', () => { await waitForImage( fileName ); await page.keyboard.type( '1' ); await page.keyboard.press( 'Enter' ); - // Make sure the

is created between keypresses - await page.waitForSelector( 'p[aria-label*="Empty block"]' ); + // Make sure the

is created between keypresses... + const paragraph = await page.waitForSelector( + 'p[aria-label*="Empty block"]' + ); await page.keyboard.press( 'Backspace' ); + // ...and make sure it's removed. + await paragraph.waitForElementState( 'hidden' ); await page.keyboard.type( '2' ); expect( @@ -334,6 +340,8 @@ describe( 'Image', () => { // Check if dimensions are changed. expect( await getEditedPostContent() ).toMatch( regexBefore ); + // Focus back to the img element for the right context + await page.click( '[aria-label="Block: Image"] img' ); // Replace uploaded image with an URL. await clickButton( 'Replace' ); await clickButton( 'Edit' ); From b6258f89f7dbdb5f6cbb61307fc82fa25c7963a6 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Fri, 27 Aug 2021 16:10:35 +0200 Subject: [PATCH 41/44] Update packages to see if it fixes the npm issues --- package-lock.json | 18 +++++++++--------- package.json | 4 ++-- 2 files changed, 11 insertions(+), 11 deletions(-) diff --git a/package-lock.json b/package-lock.json index 906f2a1b6ab807..4d30627cda8959 100644 --- a/package-lock.json +++ b/package-lock.json @@ -42752,9 +42752,9 @@ "dev": true }, "playwright-core": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.14.0.tgz", - "integrity": "sha512-n6NdknezSfRgB6LkLwcrbm5orRQZSpbd8LZmlc4YrIXV0VEvJr5tzP3xlHXpiFBfTr3yoFuagldI3T7bD/8H3w==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.14.1.tgz", + "integrity": "sha512-G4fO98T/DOTj3uabIlhkWrWzhXGXx8y8rVzBgR6DKPqEz8NfTxuQ3NFGWA1u+sfD1CtAXRxBisaUvlmnD2jRYw==", "dev": true, "requires": { "commander": "^6.1.0", @@ -51107,9 +51107,9 @@ "dev": true }, "playwright": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.14.0.tgz", - "integrity": "sha512-aR5oZ1iVsjQkGfYCjgYAmyMAVu0MQ0i8MgdnfdqDu9EVLfbnpuuFmTv/Rb7/Yjno1kOrDUP9+RyNC+zfG3wozA==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.14.1.tgz", + "integrity": "sha512-JYNjhwWcfsBkg0FMGLbFO9e58FVdmICE4k97/glIQV7cBULL7oxNjRQC7Ffe+Y70XVNnP0HSJLaA0W5SukyftQ==", "dev": true, "requires": { "commander": "^6.1.0", @@ -51214,9 +51214,9 @@ } }, "playwright-chromium": { - "version": "1.14.0", - "resolved": "https://registry.npmjs.org/playwright-chromium/-/playwright-chromium-1.14.0.tgz", - "integrity": "sha512-qWQN9VTPhvEZdRpn1564EOtiNU+hRHhogKg1heBX9VsfGy6WHytR9XPFJjD4M6fhNAV1WKM2McVPYIbi1EOYww==", + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/playwright-chromium/-/playwright-chromium-1.14.1.tgz", + "integrity": "sha512-gAHDcrBKrl1Az6TuzC4T013Nl+qKVZeblc2VkElHqEuNQHPKW7840cQBZavFz38xJshC993iClVc6Y+bLgF8FA==", "dev": true, "requires": { "commander": "^6.1.0", diff --git a/package.json b/package.json index 1184541c67f797..0a19c81d05d43a 100644 --- a/package.json +++ b/package.json @@ -189,8 +189,8 @@ "nock": "12.0.3", "node-watch": "0.7.0", "patch-package": "6.2.2", - "playwright": "1.14.0", - "playwright-chromium": "1.14.0", + "playwright": "1.14.1", + "playwright-chromium": "1.14.1", "postcss": "8.2.15", "postcss-loader": "6.1.1", "prettier": "npm:wp-prettier@2.2.1-beta-1", From 15eff8865016c39af15dfba7f678d18127c74e62 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Tue, 7 Sep 2021 16:38:38 +0200 Subject: [PATCH 42/44] Activate TwentyTwentyOne to align with trunk --- packages/e2e-tests/config/setup-playwright.js | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/packages/e2e-tests/config/setup-playwright.js b/packages/e2e-tests/config/setup-playwright.js index d6664950b8d630..9659febf6d8695 100644 --- a/packages/e2e-tests/config/setup-playwright.js +++ b/packages/e2e-tests/config/setup-playwright.js @@ -59,10 +59,10 @@ beforeAll( async () => { page.cookies = () => page.context().cookies(); // Initialize the environment - await setupBrowser(); - await enablePageDialogAccept(); + enablePageDialogAccept(); + await activateTheme( 'twentytwentyone' ); await trashExistingPosts(); - await activateTheme( 'twentytwenty' ); + await setupBrowser(); // Deactivate the plugin that disables the CSS animations in case it's enabled // (it is enabled for Puppeteer tests). We don't need to disable any From 8b9a5666f2ce465745b7e2422406d231f7041598 Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Tue, 7 Sep 2021 16:50:41 +0200 Subject: [PATCH 43/44] Restore `focus` call for the Classic block Addresses https://github.com/WordPress/gutenberg/pull/34089#discussion_r700745592 --- packages/e2e-tests/specs/editor/blocks/classic.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/classic.test.js b/packages/e2e-tests/specs/editor/blocks/classic.test.js index 38c50940f71c7e..290d81348aab66 100644 --- a/packages/e2e-tests/specs/editor/blocks/classic.test.js +++ b/packages/e2e-tests/specs/editor/blocks/classic.test.js @@ -27,7 +27,7 @@ describe( 'Classic', () => { await insertBlock( 'Classic' ); // Ensure there is focus. - await page.click( '.mce-content-body' ); + await page.focus( '.mce-content-body' ); await page.keyboard.type( 'test' ); // Move focus away. await pressKeyWithModifier( 'shift', 'Tab' ); From 3cdb35f284d0ad010c8112a8e76a7a5f37f4858c Mon Sep 17 00:00:00 2001 From: Bart Kalisz Date: Tue, 7 Sep 2021 16:54:39 +0200 Subject: [PATCH 44/44] Press ArrowLeft instead of Home key Addresses https://github.com/WordPress/gutenberg/pull/34089#discussion_r700751485 --- packages/e2e-tests/specs/editor/blocks/heading.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/packages/e2e-tests/specs/editor/blocks/heading.test.js b/packages/e2e-tests/specs/editor/blocks/heading.test.js index c250db18c9771c..e82600e7607d2d 100644 --- a/packages/e2e-tests/specs/editor/blocks/heading.test.js +++ b/packages/e2e-tests/specs/editor/blocks/heading.test.js @@ -29,7 +29,7 @@ describe( 'Heading', () => { it( 'can be created by prefixing existing content with number signs and a space', async () => { await clickBlockAppender(); await page.keyboard.type( '4' ); - await page.keyboard.press( 'Home' ); + await page.keyboard.press( 'ArrowLeft' ); await page.keyboard.type( '#### ' ); await page.waitForSelector( 'h4:text-is("4")' );