From bfaf528e61fd82c9106e3c5060921fb79d97156a Mon Sep 17 00:00:00 2001 From: Liam DeBeasi Date: Mon, 15 Apr 2024 13:46:17 -0400 Subject: [PATCH] docs(test): clarify docker usage for windows (#29274) Team members on Windows were having trouble running tests inside of Docker. Given that headed tests must use WSL, I think it makes sense to have Windows devs use WSL for any E2E tests run inside of Docker. That way they aren't switching back and forth between shells. This PR clarifies the Docker docs that instruct devs on how to use WSL. --- core/package-lock.json | 715 ++++++++++++++---- core/package.json | 8 +- core/scripts/docker.mjs | 56 ++ .../playwright/docs/assets/vscode-wsl.png | Bin 0 -> 10451 bytes docs/core/testing/usage-instructions.md | 26 +- 5 files changed, 654 insertions(+), 151 deletions(-) create mode 100644 core/scripts/docker.mjs create mode 100644 core/src/utils/test/playwright/docs/assets/vscode-wsl.png diff --git a/core/package-lock.json b/core/package-lock.json index 5cf8ee048a..7699286ae7 100644 --- a/core/package-lock.json +++ b/core/package-lock.json @@ -32,12 +32,13 @@ "@types/node": "^14.6.0", "@typescript-eslint/eslint-plugin": "^6.7.2", "@typescript-eslint/parser": "^6.7.2", + "chalk": "^5.3.0", "clean-css-cli": "^5.6.1", "domino": "^2.1.6", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-custom-rules": "file:custom-rules", - "execa": "^5.0.0", + "execa": "^8.0.1", "fs-extra": "^9.0.1", "jest": "^29.7.0", "jest-cli": "^29.7.0", @@ -371,6 +372,32 @@ "node": ">=6.9.0" } }, + "node_modules/@babel/highlight/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/@babel/highlight/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/@babel/parser": { "version": "7.23.0", "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.23.0.tgz", @@ -2920,18 +2947,6 @@ "url": "https://github.com/sponsors/sindresorhus" } }, - "node_modules/boxen/node_modules/chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, "node_modules/boxen/node_modules/string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -3128,17 +3143,15 @@ ] }, "node_modules/chalk": { - "version": "2.4.2", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", - "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", "dev": true, - "dependencies": { - "ansi-styles": "^3.2.1", - "escape-string-regexp": "^1.0.5", - "supports-color": "^5.3.0" - }, "engines": { - "node": ">=4" + "node": "^12.17.0 || ^14.13 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/chalk/chalk?sponsor=1" } }, "node_modules/chalk-template": { @@ -3205,18 +3218,6 @@ "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", "dev": true }, - "node_modules/chalk/node_modules/supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "dependencies": { - "has-flag": "^3.0.0" - }, - "engines": { - "node": ">=4" - } - }, "node_modules/char-regex": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/char-regex/-/char-regex-1.0.2.tgz", @@ -3363,6 +3364,107 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/clipboardy/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/clipboardy/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/clipboardy/node_modules/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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/clipboardy/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/clipboardy/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/clipboardy/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/cliui": { "version": "8.0.1", "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", @@ -3467,7 +3569,7 @@ "node_modules/color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "node_modules/colorette": { @@ -3949,7 +4051,7 @@ "node_modules/escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true, "engines": { "node": ">=0.8.0" @@ -4567,38 +4669,38 @@ } }, "node_modules/execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "dependencies": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "engines": { - "node": ">=10" + "node": ">=16.17" }, "funding": { "url": "https://github.com/sindresorhus/execa?sponsor=1" } }, - "node_modules/execa/node_modules/get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "node_modules/execa/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true, "engines": { - "node": ">=10" + "node": ">=14" }, "funding": { - "url": "https://github.com/sponsors/sindresorhus" + "url": "https://github.com/sponsors/isaacs" } }, "node_modules/execall": { @@ -4882,6 +4984,18 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true, + "engines": { + "node": ">=16" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -5132,12 +5246,12 @@ } }, "node_modules/human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true, "engines": { - "node": ">=10.17.0" + "node": ">=16.17.0" } }, "node_modules/ignore": { @@ -5569,12 +5683,15 @@ } }, "node_modules/is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/is-string": { @@ -5793,6 +5910,98 @@ "node": "^14.15.0 || ^16.10.0 || >=18.0.0" } }, + "node_modules/jest-changed-files/node_modules/execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sindresorhus/execa?sponsor=1" + } + }, + "node_modules/jest-changed-files/node_modules/get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/node_modules/human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true, + "engines": { + "node": ">=10.17.0" + } + }, + "node_modules/jest-changed-files/node_modules/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, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/jest-changed-files/node_modules/mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true, + "engines": { + "node": ">=6" + } + }, + "node_modules/jest-changed-files/node_modules/npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "dependencies": { + "path-key": "^3.0.0" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/jest-changed-files/node_modules/onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "dependencies": { + "mimic-fn": "^2.1.0" + }, + "engines": { + "node": ">=6" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, "node_modules/jest-changed-files/node_modules/p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -5808,6 +6017,15 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/jest-changed-files/node_modules/strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true, + "engines": { + "node": ">=6" + } + }, "node_modules/jest-circus": { "version": "29.7.0", "resolved": "https://registry.npmjs.org/jest-circus/-/jest-circus-29.7.0.tgz", @@ -7586,12 +7804,15 @@ } }, "node_modules/mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/min-indent": { @@ -7705,15 +7926,30 @@ "dev": true }, "node_modules/npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "dependencies": { - "path-key": "^3.0.0" + "path-key": "^4.0.0" }, "engines": { - "node": ">=8" + "node": "^12.20.0 || ^14.13.1 || >=16.0.0" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" + } + }, + "node_modules/npm-run-path/node_modules/path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/num2fraction": { @@ -7794,15 +8030,15 @@ } }, "node_modules/onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "dependencies": { - "mimic-fn": "^2.1.0" + "mimic-fn": "^4.0.0" }, "engines": { - "node": ">=6" + "node": ">=12" }, "funding": { "url": "https://github.com/sponsors/sindresorhus" @@ -8145,6 +8381,32 @@ "integrity": "sha512-97DXOFbQJhk71ne5/Mt6cOu6yxsSfM0QGQyl0L25Gca4yGWEGJaig7l7gbCX623VqTBNGLRLaVUCnNkcedlRSQ==", "dev": true }, + "node_modules/postcss/node_modules/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, + "dependencies": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + }, + "engines": { + "node": ">=4" + } + }, + "node_modules/postcss/node_modules/chalk/node_modules/supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "dependencies": { + "has-flag": "^3.0.0" + }, + "engines": { + "node": ">=4" + } + }, "node_modules/postcss/node_modules/supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -8976,12 +9238,15 @@ } }, "node_modules/strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true, "engines": { - "node": ">=6" + "node": ">=12" + }, + "funding": { + "url": "https://github.com/sponsors/sindresorhus" } }, "node_modules/strip-indent": { @@ -10224,6 +10489,28 @@ "@babel/helper-validator-identifier": "^7.16.7", "chalk": "^2.0.0", "js-tokens": "^4.0.0" + }, + "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" + } + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } } }, "@babel/parser": { @@ -12041,12 +12328,6 @@ "integrity": "sha512-JToIvOmz6nhGsUhAYScbo2d6Py5wojjNfoxoc2mEVLUdJ70gJK2gnd+ABY1Tc3sVMyK7QDPtN0T/XdlCQWITyQ==", "dev": true }, - "chalk": { - "version": "5.0.1", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.0.1.tgz", - "integrity": "sha512-Fo07WOYGqMfCWHOzSXOt2CxDbC6skS/jO9ynEcmpANMoPrD+W1r1K6Vx7iNm+AQmETU1Xr2t+n8nzkV9t6xh3w==", - "dev": true - }, "string-width": { "version": "5.1.2", "resolved": "https://registry.npmjs.org/string-width/-/string-width-5.1.2.tgz", @@ -12174,26 +12455,10 @@ "dev": true }, "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" - }, - "dependencies": { - "supports-color": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", - "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", - "dev": true, - "requires": { - "has-flag": "^3.0.0" - } - } - } + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", + "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", + "dev": true }, "chalk-template": { "version": "0.4.0", @@ -12328,6 +12593,73 @@ "arch": "^2.2.0", "execa": "^5.1.1", "is-wsl": "^2.2.0" + }, + "dependencies": { + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "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 + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true + } } }, "cliui": { @@ -12411,7 +12743,7 @@ "color-name": { "version": "1.1.3", "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", - "integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", "dev": true }, "colorette": { @@ -12792,7 +13124,7 @@ "escape-string-regexp": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", - "integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", "dev": true }, "eslint": { @@ -13248,26 +13580,26 @@ "dev": true }, "execa": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", - "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-8.0.1.tgz", + "integrity": "sha512-VyhnebXciFV2DESc+p6B+y0LjSm0krU4OgJN44qFAhBY0TJ+1V61tYD2+wHusZ6F9n5K+vl8k0sTy7PEfV4qpg==", "dev": true, "requires": { "cross-spawn": "^7.0.3", - "get-stream": "^6.0.0", - "human-signals": "^2.1.0", - "is-stream": "^2.0.0", + "get-stream": "^8.0.1", + "human-signals": "^5.0.0", + "is-stream": "^3.0.0", "merge-stream": "^2.0.0", - "npm-run-path": "^4.0.1", - "onetime": "^5.1.2", - "signal-exit": "^3.0.3", - "strip-final-newline": "^2.0.0" + "npm-run-path": "^5.1.0", + "onetime": "^6.0.0", + "signal-exit": "^4.1.0", + "strip-final-newline": "^3.0.0" }, "dependencies": { - "get-stream": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", - "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", "dev": true } } @@ -13502,6 +13834,12 @@ "integrity": "sha512-sY22aA6xchAzprjyqmSEQv4UbAAzRN0L2dQB0NlN5acTTK9Don6nhoc3eAbUnpZiCANAMfd/+40kVdKfFygohg==", "dev": true }, + "get-stream": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-8.0.1.tgz", + "integrity": "sha512-VaUJspBffn/LMCJVoMvSAdmscJyS1auj5Zulnn5UoYcY531UWmdwhRWkcGKnGU93m5HSXP9LP2usOryrBtQowA==", + "dev": true + }, "get-symbol-description": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/get-symbol-description/-/get-symbol-description-1.0.0.tgz", @@ -13688,9 +14026,9 @@ } }, "human-signals": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", - "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-5.0.0.tgz", + "integrity": "sha512-AXcZb6vzzrFAUE61HnN4mpLqd/cSIwNQjtNWR0euPm6y0iqx3G4gOXaIDdtdDwZmhwe82LA6+zinmW4UBWVePQ==", "dev": true }, "ignore": { @@ -13973,9 +14311,9 @@ "dev": true }, "is-stream": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.0.tgz", - "integrity": "sha512-XCoy+WlUr7d1+Z8GgSuXmpuUFC9fOhRXglJMx+dwLKTkL44Cjd4W1Z5P+BQZpr+cR93aGP4S/s7Ftw6Nd/kiEw==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-stream/-/is-stream-3.0.0.tgz", + "integrity": "sha512-LnQR4bZ9IADDRSkvpqMGvt/tEJWclzklNgSw48V5EAaAeDd6qGvN8ei6k5p0tvxSR171VmGyHuTiAOfxAbr8kA==", "dev": true }, "is-string": { @@ -14128,6 +14466,65 @@ "p-limit": "^3.1.0" }, "dependencies": { + "execa": { + "version": "5.1.1", + "resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz", + "integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.3", + "get-stream": "^6.0.0", + "human-signals": "^2.1.0", + "is-stream": "^2.0.0", + "merge-stream": "^2.0.0", + "npm-run-path": "^4.0.1", + "onetime": "^5.1.2", + "signal-exit": "^3.0.3", + "strip-final-newline": "^2.0.0" + } + }, + "get-stream": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz", + "integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==", + "dev": true + }, + "human-signals": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz", + "integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==", + "dev": true + }, + "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 + }, + "mimic-fn": { + "version": "2.1.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", + "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "dev": true + }, + "npm-run-path": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", + "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "dev": true, + "requires": { + "path-key": "^3.0.0" + } + }, + "onetime": { + "version": "5.1.2", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", + "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "dev": true, + "requires": { + "mimic-fn": "^2.1.0" + } + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -14136,6 +14533,12 @@ "requires": { "yocto-queue": "^0.1.0" } + }, + "strip-final-newline": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", + "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "dev": true } } }, @@ -15456,9 +15859,9 @@ } }, "mimic-fn": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz", - "integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==", + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-4.0.0.tgz", + "integrity": "sha512-vqiC06CuhBTUdZH+RYl8sFrL096vA45Ok5ISO6sE/Mr1jRbGH4Csnhi8f3wKVl7x8mO4Au7Ir9D3Oyv1VYMFJw==", "dev": true }, "min-indent": { @@ -15554,12 +15957,20 @@ "dev": true }, "npm-run-path": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz", - "integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==", + "version": "5.3.0", + "resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-5.3.0.tgz", + "integrity": "sha512-ppwTtiJZq0O/ai0z7yfudtBpWIoxM8yE6nHi1X47eFR2EWORqfbu6CnPlNsjeN683eT0qG6H/Pyf9fCcvjnnnQ==", "dev": true, "requires": { - "path-key": "^3.0.0" + "path-key": "^4.0.0" + }, + "dependencies": { + "path-key": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/path-key/-/path-key-4.0.0.tgz", + "integrity": "sha512-haREypq7xkM7ErfgIyA0z+Bj4AGKlMSdlQE2jvJo6huWD1EdkKYV+G/T4nq0YEF2vgTT8kqMFKo1uHn950r4SQ==", + "dev": true + } } }, "num2fraction": { @@ -15619,12 +16030,12 @@ } }, "onetime": { - "version": "5.1.2", - "resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz", - "integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==", + "version": "6.0.0", + "resolved": "https://registry.npmjs.org/onetime/-/onetime-6.0.0.tgz", + "integrity": "sha512-1FlR+gjXK7X+AsAHso35MnyN5KqGwJRi/31ft6x0M194ht7S+rWAvd7PHss9xSKMzE0asv1pyIHaJYq+BbacAQ==", "dev": true, "requires": { - "mimic-fn": "^2.1.0" + "mimic-fn": "^4.0.0" } }, "p-limit": { @@ -15782,6 +16193,28 @@ "supports-color": "^6.1.0" }, "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" + }, + "dependencies": { + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + } + } + }, "supports-color": { "version": "6.1.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-6.1.0.tgz", @@ -16481,9 +16914,9 @@ "dev": true }, "strip-final-newline": { - "version": "2.0.0", - "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz", - "integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==", + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-3.0.0.tgz", + "integrity": "sha512-dOESqjYr96iWYylGObzd39EuNTa5VJxyvVAEm5Jnh7KGo75V43Hk1odPQkNDyXNmUR6k+gEiDVXnjB8HJ3crXw==", "dev": true }, "strip-indent": { diff --git a/core/package.json b/core/package.json index db357ca4d8..980492bd8c 100644 --- a/core/package.json +++ b/core/package.json @@ -54,12 +54,13 @@ "@types/node": "^14.6.0", "@typescript-eslint/eslint-plugin": "^6.7.2", "@typescript-eslint/parser": "^6.7.2", + "chalk": "^5.3.0", "clean-css-cli": "^5.6.1", "domino": "^2.1.6", "eslint": "^7.32.0", "eslint-config-prettier": "^8.5.0", "eslint-plugin-custom-rules": "file:custom-rules", - "execa": "^5.0.0", + "execa": "^8.0.1", "fs-extra": "^9.0.1", "jest": "^29.7.0", "jest-cli": "^29.7.0", @@ -96,10 +97,9 @@ "test.treeshake": "node scripts/treeshaking.js dist/index.js", "validate": "npm run lint && npm run test && npm run build && npm run test.treeshake", "docker.build": "docker build -t ionic-playwright .", - "test.e2e.docker": "npm run docker.build && docker run -it --rm -e DISPLAY=$(cat docker-display.txt) -v $(cat docker-display-volume.txt) --ipc=host --mount=type=bind,source=./,target=/ionic ionic-playwright npm run test.e2e --", + "test.e2e.docker": "npm run docker.build && node ./scripts/docker.mjs", "test.e2e.docker.update-snapshots": "npm run test.e2e.docker -- --update-snapshots", - "test.e2e.docker.ci": "npm run docker.build && docker run -e CI='true' --rm --ipc=host --mount=type=bind,source=./,target=/ionic ionic-playwright npm run test.e2e --", - "test.report": "npx playwright show-report" + "test.e2e.docker.ci": "npm run docker.build && CI=true node ./scripts/docker.mjs" }, "author": "Ionic Team", "license": "MIT", diff --git a/core/scripts/docker.mjs b/core/scripts/docker.mjs new file mode 100644 index 0000000000..f723305459 --- /dev/null +++ b/core/scripts/docker.mjs @@ -0,0 +1,56 @@ +import { execa } from 'execa'; +import * as fs from 'fs'; +import { resolve } from 'path'; +import chalk from 'chalk'; + +const removeNewline = (string) => { + return string.replace(/(\r\n|\n|\r)/gm, ""); +} + +const readConfigFile = (file) => { + if (fs.existsSync(file)) { + return fs.readFileSync(file, { encoding: 'utf-8' }); + } + + return ''; +} + +// These files are optional, so we don't want to error if they don't exist +const display = removeNewline(readConfigFile('docker-display.txt')); +const displayVolume = removeNewline(readConfigFile('docker-display-volume.txt')); + +// Using --mount requires an absolute path which is what this gives us. +const pwd = resolve('./'); + +/** + * -it will let the user gracefully kill the process using Ctrl+C (or equivalent) + * -e DISPLAY and -v handle configuration for headed mode + * --ipc=host is recommended when using Chromium to avoid out of memory crashes: https://playwright.dev/docs/ci#docker + * --init is recommended to avoid zombie processes: https://playwright.dev/docs/ci#docker + * --mount allow us to mount the local Ionic project inside of the Docker container so devs do not need to re-build the project in Docker. + */ +const args = ['run', '--rm', '--init', `-e DISPLAY=${display}`, `-v ${displayVolume}`, '--ipc=host', `--mount=type=bind,source=${pwd},target=/ionic`, 'ionic-playwright', 'npm run test.e2e --', ...process.argv.slice(2)]; + +// Set the CI env variable so Playwright uses the CI config +if (process.env.CI) { + args.splice(1, 0, '-e CI=true'); +/** + * Otherwise, we should let the session be interactive locally. This will + * not work on CI which is why we do not apply it there. + */ +} else { + args.splice(1, 0, '-it'); +} + +/** + * While these config files are optional to run the tests, they are required to run + * the tests in headed mode. Add a warning if dev tries to run headed tests without + * the correct config files. + */ +const requestHeaded = process.argv.find(arg => arg.includes('headed')); +const hasHeadedConfigFiles = display && displayVolume; +if (requestHeaded && !hasHeadedConfigFiles) { + console.warn(chalk.yellow.bold('\n⚠️ You are running tests in headed mode, but one or more of your headed config files was not found.\nPlease ensure that both docker-display.txt and docker-display-volume.txt have been created in the correct location.\n')); +} + +execa('docker', args, { shell: true, stdio: 'inherit' }); diff --git a/core/src/utils/test/playwright/docs/assets/vscode-wsl.png b/core/src/utils/test/playwright/docs/assets/vscode-wsl.png new file mode 100644 index 0000000000000000000000000000000000000000..fa9e7590f5bae83aa499a9dd74ebe01836e68c12 GIT binary patch literal 10451 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 + ### Configuring Docker for Headed Tests (Optional) Additional software is needed to run headed tests inside of Docker. The Docker-specific test commands such as `npm run test.e2e.docker` are configured to use this additional software, but it is up to the developer to ensure that the software is installed and running. @@ -56,14 +71,13 @@ macOS uses [XQuartz](https://www.xquartz.org) to use XServer on macOS. #### Windows -Windows has a native XServer called [WSLg](https://github.com/microsoft/wslg#readme) that is included as part of the [Windows Subsystem for Linux (WSL)](https://apps.microsoft.com/store/detail/9P9TQF7MRM4R?hl=en-us&gl=US). If you are running Docker Desktop on Windows 10 or 11 you likely already have both WSL and WSLg installed. The following steps show how to verify the WSL and WSLg are installed as well as how to configure your environment for headed tests in Docker. +Windows has a native XServer called [WSLg](https://github.com/microsoft/wslg#readme) that is included as part of the [Windows Subsystem for Linux (WSL)](https://learn.microsoft.com/en-us/windows/wsl/about). See [Docker and Windows Development](#docker-and-windows-development) for information on how to ensure both WSL and WSLg are installed. Once completed, follow the steps below to configure headed tests to use XServer. -If either of the below verification checks fail, then developers should [download the latest version of WSL](https://apps.microsoft.com/store/detail/9P9TQF7MRM4R?hl=en-us&gl=US). +> [!NOTE] +> The following steps should be done in WSL, not PowerShell. Running the commands in PowerShell may result in extra hidden characters being added. -1. To verify WSL is installed, launch "WSL" from the start menu. If "WSL" does not show up in the start menu then you do not have WSL installed. -2. With WSL open, verify that WSLg is installed: `ls -a -w 1 /mnt/wslg`. If the command fails with `No such file or directory` then your system is either missing WSL or running an old version. -3. In the `core` directory run `echo :0 > docker-display.txt`. This information is used to set the `DISPLAY` environment variable which tells Playwright how to render a headed UI from the Docker container. -4. In the `core` directory run `echo /tmp/.X11-unix:/tmp/.X11-unix > docker-display-volume.txt`. This information is used to make XServer available inside of the Docker container. +1. In the `core` directory run `echo :0 > docker-display.txt`. This information is used to set the `DISPLAY` environment variable which tells Playwright how to render a headed UI from the Docker container. +2. In the `core` directory run `echo /tmp/.X11-unix:/tmp/.X11-unix > docker-display-volume.txt`. This information is used to make XServer available inside of the Docker container. ## Running Tests