diff --git a/BREAKING_CHANGES.md b/BREAKING_CHANGES.md index 3fff279b855..d75bb2f83a3 100644 --- a/BREAKING_CHANGES.md +++ b/BREAKING_CHANGES.md @@ -557,3 +557,10 @@ When running Jest directly, previously most of Jest had to be manually configure - ] } ``` + +# Stencil v3.0.0 [Unreleased] + +Stencil v3.0.0 is in development at this time and has not been released. The list below is not final and is subject to +change. Further details on each of these items will be included prior to the release. + +- [fix(testing): puppeteer v10 support #2934](https://github.com/ionic-team/stencil/pull/2934) \ No newline at end of file diff --git a/package-lock.json b/package-lock.json index b3abbeea569..a42717c6479 100644 --- a/package-lock.json +++ b/package-lock.json @@ -6,7 +6,7 @@ "packages": { "": { "name": "@stencil/core", - "version": "2.6.0-0", + "version": "2.6.0", "license": "MIT", "bin": { "stencil": "bin/stencil" @@ -33,7 +33,6 @@ "@types/pixelmatch": "^4.0.0", "@types/pngjs": "^3.4.2", "@types/prompts": "^2.0.9", - "@types/puppeteer": "^5.4.3", "@types/semver": "^7.3.4", "@types/sizzle": "^2.3.2", "@types/webpack": "^4.41.26", @@ -69,7 +68,7 @@ "postcss": "^8.2.8", "prettier": "^2.2.1", "prompts": "2.4.0", - "puppeteer": "~5.5.0", + "puppeteer": "~10.0.0", "rollup": "2.42.3", "semiver": "^1.1.0", "semver": "7.3.4", @@ -1332,15 +1331,6 @@ "@types/node": "*" } }, - "node_modules/@types/puppeteer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.3.tgz", - "integrity": "sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==", - "dev": true, - "dependencies": { - "@types/node": "*" - } - }, "node_modules/@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -1709,10 +1699,13 @@ "dev": true }, "node_modules/agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", + "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, + "dependencies": { + "debug": "4" + }, "engines": { "node": ">= 6.0.0" } @@ -3880,9 +3873,9 @@ } }, "node_modules/devtools-protocol": { - "version": "0.0.818844", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz", - "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==", + "version": "0.0.883894", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.883894.tgz", + "integrity": "sha512-33idhm54QJzf3Q7QofMgCvIVSd2o9H3kQPWaKT/fhoZh+digc+WSiMhbkeG3iN79WY4Hwr9G05NpbhEVrsOYAg==", "dev": true }, "node_modules/diff-sequences": { @@ -5779,16 +5772,16 @@ "dev": true }, "node_modules/https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "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, "dependencies": { - "agent-base": "5", + "agent-base": "6", "debug": "4" }, "engines": { - "node": ">= 6.0.0" + "node": ">= 6" } }, "node_modules/human-signals": { @@ -8195,12 +8188,6 @@ "mkdirp": "bin/cmd.js" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", @@ -9153,9 +9140,9 @@ "dev": true }, "node_modules/progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", + "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", "dev": true, "engines": { "node": ">=0.4.0" @@ -9259,29 +9246,50 @@ } }, "node_modules/puppeteer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.5.0.tgz", - "integrity": "sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-10.0.0.tgz", + "integrity": "sha512-AxHvCb9IWmmP3gMW+epxdj92Gglii+6Z4sb+W+zc2hTTu10HF0yg6hGXot5O74uYkVqG3lfDRLfnRpi6WOwi5A==", "dev": true, "hasInstallScript": true, "dependencies": { - "debug": "^4.1.0", - "devtools-protocol": "0.0.818844", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.6.1", - "pkg-dir": "^4.2.0", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^3.0.2", - "tar-fs": "^2.0.0", - "unbzip2-stream": "^1.3.3", - "ws": "^7.2.3" + "debug": "4.3.1", + "devtools-protocol": "0.0.883894", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "node-fetch": "2.6.1", + "pkg-dir": "4.2.0", + "progress": "2.0.1", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.0.0", + "unbzip2-stream": "1.3.3", + "ws": "7.4.6" }, "engines": { "node": ">=10.18.1" } }, + "node_modules/puppeteer/node_modules/ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "engines": { + "node": ">=8.3.0" + }, + "peerDependencies": { + "bufferutil": "^4.0.1", + "utf-8-validate": "^5.0.2" + }, + "peerDependenciesMeta": { + "bufferutil": { + "optional": true + }, + "utf-8-validate": { + "optional": true + } + } + }, "node_modules/q": { "version": "1.5.1", "resolved": "https://registry.npmjs.org/q/-/q-1.5.1.tgz", @@ -11168,15 +11176,15 @@ } }, "node_modules/tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", + "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", "dev": true, "dependencies": { "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", + "mkdirp": "^0.5.1", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^2.0.0" } }, "node_modules/tar-stream": { @@ -11624,9 +11632,9 @@ } }, "node_modules/unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", + "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", "dev": true, "dependencies": { "buffer": "^5.2.1", @@ -13758,15 +13766,6 @@ "@types/node": "*" } }, - "@types/puppeteer": { - "version": "5.4.3", - "resolved": "https://registry.npmjs.org/@types/puppeteer/-/puppeteer-5.4.3.tgz", - "integrity": "sha512-3nE8YgR9DIsgttLW+eJf6mnXxq8Ge+27m5SU3knWmrlfl6+KOG0Bf9f7Ua7K+C4BnaTMAh3/UpySqdAYvrsvjg==", - "dev": true, - "requires": { - "@types/node": "*" - } - }, "@types/resolve": { "version": "1.17.1", "resolved": "https://registry.npmjs.org/@types/resolve/-/resolve-1.17.1.tgz", @@ -14121,10 +14120,13 @@ "dev": true }, "agent-base": { - "version": "5.1.1", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-5.1.1.tgz", - "integrity": "sha512-TMeqbNl2fMW0nMjTEPOwe3J/PRFP4vqeoNuQMG0HlMrtm5QxKqdvAkZ1pRBQ/ulIyDD5Yq0nJ7YbdD8ey0TO3g==", - "dev": true + "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" + } }, "ajv": { "version": "6.12.6", @@ -15863,9 +15865,9 @@ "dev": true }, "devtools-protocol": { - "version": "0.0.818844", - "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.818844.tgz", - "integrity": "sha512-AD1hi7iVJ8OD0aMLQU5VK0XH9LDlA1+BcPIgrAxPfaibx2DbWucuyOhc4oyQCbnvDDO68nN6/LcKfqTP343Jjg==", + "version": "0.0.883894", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.883894.tgz", + "integrity": "sha512-33idhm54QJzf3Q7QofMgCvIVSd2o9H3kQPWaKT/fhoZh+digc+WSiMhbkeG3iN79WY4Hwr9G05NpbhEVrsOYAg==", "dev": true }, "diff-sequences": { @@ -17400,12 +17402,12 @@ "dev": true }, "https-proxy-agent": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-4.0.0.tgz", - "integrity": "sha512-zoDhWrkR3of1l9QAL8/scJZyLu8j/gBkcwcaQOZh7Gyh/+uJQzGVETdgT30akuwkpL8HTRfssqI3BZuV18teDg==", + "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": "5", + "agent-base": "6", "debug": "4" } }, @@ -19314,12 +19316,6 @@ "minimist": "^1.2.5" } }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "modify-values": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/modify-values/-/modify-values-1.0.1.tgz", @@ -20084,9 +20080,9 @@ "dev": true }, "progress": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.3.tgz", - "integrity": "sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==", + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/progress/-/progress-2.0.1.tgz", + "integrity": "sha512-OE+a6vzqazc+K6LxJrX5UPyKFvGnL5CYmq2jFGNIBWHpc4QyE49/YOumcrpQFJpfejmvRtbJzgO1zPmMCqlbBg==", "dev": true }, "promise-inflight": { @@ -20185,23 +20181,32 @@ "dev": true }, "puppeteer": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-5.5.0.tgz", - "integrity": "sha512-OM8ZvTXAhfgFA7wBIIGlPQzvyEETzDjeRa4mZRCRHxYL+GNH5WAuYUQdja3rpWZvkX/JKqmuVgbsxDNsDFjMEg==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/puppeteer/-/puppeteer-10.0.0.tgz", + "integrity": "sha512-AxHvCb9IWmmP3gMW+epxdj92Gglii+6Z4sb+W+zc2hTTu10HF0yg6hGXot5O74uYkVqG3lfDRLfnRpi6WOwi5A==", "dev": true, "requires": { - "debug": "^4.1.0", - "devtools-protocol": "0.0.818844", - "extract-zip": "^2.0.0", - "https-proxy-agent": "^4.0.0", - "node-fetch": "^2.6.1", - "pkg-dir": "^4.2.0", - "progress": "^2.0.1", - "proxy-from-env": "^1.0.0", - "rimraf": "^3.0.2", - "tar-fs": "^2.0.0", - "unbzip2-stream": "^1.3.3", - "ws": "^7.2.3" + "debug": "4.3.1", + "devtools-protocol": "0.0.883894", + "extract-zip": "2.0.1", + "https-proxy-agent": "5.0.0", + "node-fetch": "2.6.1", + "pkg-dir": "4.2.0", + "progress": "2.0.1", + "proxy-from-env": "1.1.0", + "rimraf": "3.0.2", + "tar-fs": "2.0.0", + "unbzip2-stream": "1.3.3", + "ws": "7.4.6" + }, + "dependencies": { + "ws": { + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", + "dev": true, + "requires": {} + } } }, "q": { @@ -21731,15 +21736,15 @@ "dev": true }, "tar-fs": { - "version": "2.1.1", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.1.1.tgz", - "integrity": "sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==", + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-2.0.0.tgz", + "integrity": "sha512-vaY0obB6Om/fso8a8vakQBzwholQ7v5+uy+tF3Ozvxv1KNezmVQAiWtcNmMHFSFPqL3dJA8ha6gdtFbfX9mcxA==", "dev": true, "requires": { "chownr": "^1.1.1", - "mkdirp-classic": "^0.5.2", + "mkdirp": "^0.5.1", "pump": "^3.0.0", - "tar-stream": "^2.1.4" + "tar-stream": "^2.0.0" } }, "tar-stream": { @@ -22082,9 +22087,9 @@ "optional": true }, "unbzip2-stream": { - "version": "1.4.3", - "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.4.3.tgz", - "integrity": "sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==", + "version": "1.3.3", + "resolved": "https://registry.npmjs.org/unbzip2-stream/-/unbzip2-stream-1.3.3.tgz", + "integrity": "sha512-fUlAF7U9Ah1Q6EieQ4x4zLNejrRvDWUYmxXUpN3uziFYCHapjWFaCAnreY9bGgxzaMCFAPPpYNng57CypwJVhg==", "dev": true, "requires": { "buffer": "^5.2.1", diff --git a/package.json b/package.json index f9326d1d1bc..2378c21dcf0 100644 --- a/package.json +++ b/package.json @@ -71,7 +71,6 @@ "@types/pixelmatch": "^4.0.0", "@types/pngjs": "^3.4.2", "@types/prompts": "^2.0.9", - "@types/puppeteer": "^5.4.3", "@types/semver": "^7.3.4", "@types/sizzle": "^2.3.2", "@types/webpack": "^4.41.26", @@ -107,7 +106,7 @@ "postcss": "^8.2.8", "prettier": "^2.2.1", "prompts": "2.4.0", - "puppeteer": "~5.5.0", + "puppeteer": "~10.0.0", "rollup": "2.42.3", "semiver": "^1.1.0", "semver": "7.3.4", diff --git a/src/cli/task-test.ts b/src/cli/task-test.ts index 2ef8dde1147..0df7365cf5d 100644 --- a/src/cli/task-test.ts +++ b/src/cli/task-test.ts @@ -24,7 +24,7 @@ export const taskTest = async (config: Config) => { // puppeteer modules installed and if browserExecutablePath is provided don't download Chromium use only puppeteer-core instead const puppeteer = config.testing.browserExecutablePath ? 'puppeteer-core' : 'puppeteer'; - ensureModuleIds.push('@types/puppeteer', puppeteer); + ensureModuleIds.push(puppeteer); if (testingRunOpts.screenshot) { // ensure we've got pixelmatch for screenshots diff --git a/src/declarations/stencil-public-compiler.ts b/src/declarations/stencil-public-compiler.ts index b74faeb63d6..9c2f9fcc932 100644 --- a/src/declarations/stencil-public-compiler.ts +++ b/src/declarations/stencil-public-compiler.ts @@ -1674,7 +1674,7 @@ export interface TestingConfig extends JestConfig { export interface EmulateConfig { /** * Predefined device descriptor name, such as "iPhone X" or "Nexus 10". - * For a complete list please see: https://github.com/GoogleChrome/puppeteer/blob/master/DeviceDescriptors.js + * For a complete list please see: https://github.com/puppeteer/puppeteer/blob/main/src/common/DeviceDescriptors.ts */ device?: string; diff --git a/src/sys/node/node-sys.ts b/src/sys/node/node-sys.ts index b0a3013902a..99fabf53256 100644 --- a/src/sys/node/node-sys.ts +++ b/src/sys/node/node-sys.ts @@ -563,11 +563,10 @@ export function createNodeSys(c: { process?: any } = {}) { sys.lazyRequire = new NodeLazyRequire(nodeResolve, { // [minimumVersion, recommendedVersion] '@types/jest': ['24.9.1', '26.0.21'], - '@types/puppeteer': ['1.19.0', '5.4.3'], 'jest': ['24.9.0', '26.6.3'], 'jest-cli': ['24.9.0', '26.6.3'], 'pixelmatch': ['4.0.2', '4.0.2'], - 'puppeteer': ['1.19.0', '5.5.0'], + 'puppeteer': ['1.19.0', '10.0.0'], 'puppeteer-core': ['1.19.0', '5.2.1'], 'workbox-build': ['4.3.1', '4.3.1'], }); diff --git a/src/testing/puppeteer/puppeteer-browser.ts b/src/testing/puppeteer/puppeteer-browser.ts index b362ec2e510..997e9112199 100644 --- a/src/testing/puppeteer/puppeteer-browser.ts +++ b/src/testing/puppeteer/puppeteer-browser.ts @@ -35,27 +35,32 @@ export async function startPuppeteerBrowser(config: Config) { config.logger.debug(`puppeteer slowMo: ${config.testing.browserSlowMo}`); } - const launchOpts: puppeteer.LaunchOptions = { + // connection options will be used regardless whether a new browser instance is created or we attach to a + // pre-existing instance + const connectOpts: puppeteer.ConnectOptions = { ignoreHTTPSErrors: true, - args: config.testing.browserArgs, - headless: config.testing.browserHeadless, - devtools: config.testing.browserDevtools, slowMo: config.testing.browserSlowMo, }; - if (config.testing.browserExecutablePath) { - launchOpts.executablePath = config.testing.browserExecutablePath; + let browser: puppeteer.Browser; + if (config.testing.browserWSEndpoint) { + browser = await puppeteer.connect({ + browserWSEndpoint: config.testing.browserWSEndpoint, + ...connectOpts + }); + } else { + const launchOpts: puppeteer.BrowserLaunchArgumentOptions & puppeteer.LaunchOptions & puppeteer.ConnectOptions = { + args: config.testing.browserArgs, + headless: config.testing.browserHeadless, + devtools: config.testing.browserDevtools, + ...connectOpts, + }; + if (config.testing.browserExecutablePath) { + launchOpts.executablePath = config.testing.browserExecutablePath; + } + browser = await puppeteer.launch({ ...launchOpts }); } - const browser = await (config.testing.browserWSEndpoint - ? puppeteer.connect({ - ...launchOpts, - browserWSEndpoint: config.testing.browserWSEndpoint, - }) - : puppeteer.launch({ - ...launchOpts, - })); - env.__STENCIL_BROWSER_WS_ENDPOINT__ = browser.wsEndpoint(); config.logger.debug(`puppeteer browser wsEndpoint: ${env.__STENCIL_BROWSER_WS_ENDPOINT__}`); diff --git a/src/testing/puppeteer/puppeteer-declarations.ts b/src/testing/puppeteer/puppeteer-declarations.ts index bbc411c7a79..a899e6e3fe8 100644 --- a/src/testing/puppeteer/puppeteer-declarations.ts +++ b/src/testing/puppeteer/puppeteer-declarations.ts @@ -1,14 +1,49 @@ import type { EventInitDict, EventSpy, ScreenshotDiff, ScreenshotOptions } from '@stencil/core/internal'; import type { ClickOptions, - NavigationOptions, + HTTPResponse as PuppeteerHTTPResponse, Page, - PageCloseOptions, ScreenshotOptions as PuppeteerScreenshotOptions, - Response, + WaitForOptions, } from 'puppeteer'; -export interface NewE2EPageOptions extends NavigationOptions { +/** + * This type helps with declaration merging as a part of Stencil's migration from Puppeteer v5.4.3 to v10.0.0. In + * v5.4.3, `HttpResponse` was an interface whereas v10.0.0 declares it as a class. It is redeclared here to help teams + * migrate to a newer minor version of Stencil without requiring a Puppeteer upgrade/major version of Stencil. This type + * should be removed as a part of the Stencil 3.0 release. + */ +export type HTTPResponse = PuppeteerHTTPResponse; + +/** + * These types help with declaration merging as a part of Stencil's migration from Puppeteer v5.4.3 to v10.0.0. In + * v10.0.0, `WaitForOptions` is a renamed version of `NavigationOptions` from v5.4.3, who has had its type hierarchy + * flattened. + * + * See {@link https://github.com/DefinitelyTyped/DefinitelyTyped/blob/8290e943f6b398acf39ee1b2e486824144e15bc8/types/puppeteer/index.d.ts#L605-L622} + * for the v5.4.3 types. + * + * These types are redeclared here to help teams migrate to a newer minor version of Stencil without requiring a + * Puppeteer upgrade/major version of Stencil. These type additions should be removed as a part of the Stencil 3.0 + * release. + */ +declare module "puppeteer" { + type LifeCycleEvent = 'load' | 'domcontentloaded' | 'networkidle0' | 'networkidle2'; + interface WaitForOptions { + timeout?: number; + waitUntil?: LifeCycleEvent | LifeCycleEvent[]; + } +} + +/** + * This type was once exported by Puppeteer, but has since moved to an object literal in (Puppeteer’s) native types. + * Re-create it here as a named type to use across multiple Stencil-related testing files. + */ +export type PageCloseOptions = { + runBeforeUnload?: boolean; +} + +export interface NewE2EPageOptions extends WaitForOptions { url?: string; html?: string; failOnConsoleError?: boolean; @@ -127,7 +162,7 @@ export interface E2EPage extends PuppeteerPage { * a localhost address. A shortcut to `page.goto(url)` is to set the `url` option * when creating a new page, such as `const page = await newE2EPage({ url })`. */ - goTo(url: string, options?: NavigationOptions): Promise; + goTo(url: string, options?: WaitForOptions): Promise; /** * Instead of testing a url directly, html content can be mocked using @@ -135,7 +170,7 @@ export interface E2EPage extends PuppeteerPage { * the `html` option when creating a new page, such as * `const page = await newE2EPage({ html })`. */ - setContent(html: string, options?: NavigationOptions): Promise; + setContent(html: string, options?: WaitForOptions): Promise; /** * Used to test if an event was, or was not dispatched. This method @@ -169,7 +204,7 @@ export interface E2EPageInternal extends E2EPage { _e2eElements: E2EElementInternal[]; _e2eEvents: Map; _e2eEventIds: number; - _e2eGoto(url: string, options?: Partial): Promise; + _e2eGoto(url: string, options?: Partial): Promise; _e2eClose(options?: PageCloseOptions): Promise; screenshot(options?: PuppeteerScreenshotOptions): Promise; } @@ -456,7 +491,7 @@ export interface E2EElement { export interface E2EElementInternal extends E2EElement { e2eDispose(): Promise; - e2eRunActions(): Promise; + e2eRunActions(): Promise; e2eSync(): Promise; } diff --git a/src/testing/puppeteer/puppeteer-element.ts b/src/testing/puppeteer/puppeteer-element.ts index 22d3809bd7a..a55135a230e 100644 --- a/src/testing/puppeteer/puppeteer-element.ts +++ b/src/testing/puppeteer/puppeteer-element.ts @@ -147,7 +147,7 @@ export class E2EElement extends MockHTMLElement implements pd.E2EElementInternal return this._elmHandle.isIntersectingViewport(); } - async press(key: string, options?: { text?: string; delay?: number }) { + async press(key: puppeteer.KeyInput, options?: { text?: string; delay?: number }) { await this._elmHandle.press(key, options); await this._page.waitForChanges(); } @@ -401,7 +401,7 @@ export class E2EElement extends MockHTMLElement implements pd.E2EElementInternal const executionContext = this._elmHandle.executionContext(); - const rtn = await executionContext.evaluate( + const rtn = await executionContext.evaluate( (elm: HTMLElement, queuedActions: ElementAction[]) => { // BROWSER CONTEXT // cannot use async/await in here cuz typescript transpiles it in the node context diff --git a/src/testing/puppeteer/puppeteer-emulate.ts b/src/testing/puppeteer/puppeteer-emulate.ts index efb4f26542d..5c8427c361f 100644 --- a/src/testing/puppeteer/puppeteer-emulate.ts +++ b/src/testing/puppeteer/puppeteer-emulate.ts @@ -18,7 +18,8 @@ export function setScreenshotEmulateData(userEmulateConfig: EmulateConfig, env: try { const deviceDescriptors = require(env.__STENCIL_PUPPETEER_MODULE__ + '/DeviceDescriptors'); - const puppeteerEmulateOpts = deviceDescriptors[userEmulateConfig.device] as puppeteer.EmulateOptions; + const puppeteerEmulateOpts = + deviceDescriptors[userEmulateConfig.device] as { userAgent: string, viewport: puppeteer.Viewport }; if (!puppeteerEmulateOpts) { console.error(`invalid emulate device: ${userEmulateConfig.device}`); return; diff --git a/src/testing/puppeteer/puppeteer-page.ts b/src/testing/puppeteer/puppeteer-page.ts index cdb715e576f..bb9f8a35a86 100644 --- a/src/testing/puppeteer/puppeteer-page.ts +++ b/src/testing/puppeteer/puppeteer-page.ts @@ -4,16 +4,16 @@ import type { E2EPageInternal, FindSelector, NewE2EPageOptions, + PageCloseOptions, PageDiagnostic, } from './puppeteer-declarations'; + import type { ConsoleMessage, ConsoleMessageLocation, - EmulateOptions, JSHandle, - NavigationOptions, Page, - PageCloseOptions, + WaitForOptions, } from 'puppeteer'; import { find, findAll } from './puppeteer-element'; import { initPageEvents, waitForEvent } from './puppeteer-events'; @@ -175,7 +175,7 @@ export async function newE2EPage(opts: NewE2EPageOptions = {}): Promise return page; } -async function e2eGoTo(page: E2EPageInternal, url: string, options: NavigationOptions = {}) { +async function e2eGoTo(page: E2EPageInternal, url: string, options: WaitForOptions = {}) { if (page.isClosed()) { throw new Error('e2eGoTo unavailable: page already closed'); } @@ -209,7 +209,7 @@ async function e2eGoTo(page: E2EPageInternal, url: string, options: NavigationOp return rsp; } -async function e2eSetContent(page: E2EPageInternal, html: string, options: NavigationOptions = {}) { +async function e2eSetContent(page: E2EPageInternal, html: string, options: WaitForOptions = {}) { if (page.isClosed()) { throw new Error('e2eSetContent unavailable: page already closed'); } @@ -272,7 +272,7 @@ async function e2eSetContent(page: E2EPageInternal, html: string, options: Navig return rsp; } -async function waitForStencil(page: E2EPage, options: NavigationOptions) { +async function waitForStencil(page: E2EPage, options: WaitForOptions) { try { const timeout = typeof options.timeout === 'number' ? options.timeout : 4750; await page.waitForFunction('window.stencilAppLoaded', { timeout }); @@ -293,7 +293,7 @@ async function setPageEmulate(page: Page) { const screenshotEmulate = JSON.parse(emulateJsonContent) as EmulateConfig; - const emulateOptions: EmulateOptions = { + const emulateOptions = { viewport: screenshotEmulate.viewport, userAgent: screenshotEmulate.userAgent, };