diff --git a/packages/webdriverio/package-lock.json b/packages/webdriverio/package-lock.json index cf43ee96..028635bf 100644 --- a/packages/webdriverio/package-lock.json +++ b/packages/webdriverio/package-lock.json @@ -265,6 +265,25 @@ "integrity": "sha512-O0L6v/HvqbdJawj0iBEfVQMc3/6WP+AeOsovsIgBFyJaG+W2w7eqvZB7puddATmWuARlm1SX7DwxJ/JJUnDpEA==", "dev": true }, + "@babel/runtime": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime/-/runtime-7.15.4.tgz", + "integrity": "sha512-99catp6bHCaxr4sJ/DbTGgHS4+Rs2RVd2g7iOap6SLGPDknRK9ztKNsE/Fg6QhSeh1FGE5f6gHGQmvvn3I3xhw==", + "dev": true, + "requires": { + "regenerator-runtime": "^0.13.4" + } + }, + "@babel/runtime-corejs3": { + "version": "7.15.4", + "resolved": "https://registry.npmjs.org/@babel/runtime-corejs3/-/runtime-corejs3-7.15.4.tgz", + "integrity": "sha512-lWcAqKeB624/twtTc3w6w/2o9RqJPaNBhPGK6DKLSiwuVWC7WFkypWyNg+CpZoyJH0jVzv1uMtXZ/5/lQOLtCg==", + "dev": true, + "requires": { + "core-js-pure": "^3.16.0", + "regenerator-runtime": "^0.13.4" + } + }, "@babel/template": { "version": "7.14.5", "resolved": "https://registry.npmjs.org/@babel/template/-/template-7.14.5.tgz", @@ -413,9 +432,9 @@ } }, "@sindresorhus/is": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.0.1.tgz", - "integrity": "sha512-Qm9hBEBu18wt1PO2flE7LPb30BHMQt1eQgbV76YntdNk73XZGpn3izvGTYxbGgzXKgbCjiia0uxTd3aTNQrY/g==", + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/@sindresorhus/is/-/is-4.1.0.tgz", + "integrity": "sha512-Cgva8HxclecUCmAImsWsbZGUh6p5DSzQ8l2Uzxuj9ANiD7LVhLM1UJ2hX/R2Y+ILpvqgW9QjmTCaBkXtj8+UOg==", "dev": true }, "@szmarczak/http-timer": { @@ -433,6 +452,12 @@ "integrity": "sha512-8UT/J+xqCYfn3fKtOznAibsHpiuDshCb0fwgWxRazTT19Igp9ovoXMPhXyLD6m3CKQGTMHgqoxaFfMWaL40Rnw==", "dev": true }, + "@types/aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/@types/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-HnYpAE1Y6kRyKM/XkEuiRQhTHvkzMBurTHnpFLYLBGPIylZNPs9jJcuOOYWxPLJCSEtmZT0Y8rHDokKN7rRTig==", + "dev": true + }, "@types/body-parser": { "version": "1.19.1", "resolved": "https://registry.npmjs.org/@types/body-parser/-/body-parser-1.19.1.tgz", @@ -521,9 +546,9 @@ "dev": true }, "@types/keyv": { - "version": "3.1.2", - "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.2.tgz", - "integrity": "sha512-/FvAK2p4jQOaJ6CGDHJTqZcUtbZe820qIeTg7o0Shg7drB4JHeL+V/dhSaly7NXx6u8eSee+r7coT+yuJEvDLg==", + "version": "3.1.3", + "resolved": "https://registry.npmjs.org/@types/keyv/-/keyv-3.1.3.tgz", + "integrity": "sha512-FXCJgyyN3ivVgRoml4h94G/p3kY+u/B86La+QptcqJaWtBWtmc6TtkNfS40n9bIvyLteHh7zXOtgbobORKPbDg==", "dev": true, "requires": { "@types/node": "*" @@ -556,15 +581,6 @@ "@types/node": "*" } }, - "@types/puppeteer-core": { - "version": "5.4.0", - "resolved": "https://registry.npmjs.org/@types/puppeteer-core/-/puppeteer-core-5.4.0.tgz", - "integrity": "sha512-yqRPuv4EFcSkTyin6Yy17pN6Qz2vwVwTCJIDYMXbE3j8vTPhv0nCQlZOl5xfi0WHUkqvQsjAR8hAfjeMCoetwg==", - "dev": true, - "requires": { - "@types/puppeteer": "*" - } - }, "@types/qs": { "version": "6.9.7", "resolved": "https://registry.npmjs.org/@types/qs/-/qs-6.9.7.tgz", @@ -628,20 +644,35 @@ "dev": true }, "@wdio/config": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/@wdio/config/-/config-6.12.1.tgz", - "integrity": "sha512-V5hTIW5FNlZ1W33smHF4Rd5BKjGW2KeYhyXDQfXHjqLCeRiirZ9fABCo9plaVQDnwWSUMWYaAaIAifV82/oJCQ==", + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@wdio/config/-/config-7.10.1.tgz", + "integrity": "sha512-EA+kJBNPeIxkkyilHcmiIwqjtOUcWx5FVp69kSBs4BN2fG+6CgpzoVecuTm/qPU6D0DT5KIfxVR4FRHCF99F/g==", "dev": true, "requires": { - "@wdio/logger": "6.10.10", + "@wdio/logger": "7.7.0", + "@wdio/types": "7.10.1", "deepmerge": "^4.0.0", "glob": "^7.1.2" + }, + "dependencies": { + "@wdio/logger": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.7.0.tgz", + "integrity": "sha512-XX/OkC8NlvsBdhKsb9j7ZbuQtF/Vuo0xf38PXdqYtVezOrYbDuba0hPG++g/IGNuAF34ZbSi+49cvz4u5w92kQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^6.0.0" + } + } } }, "@wdio/logger": { - "version": "6.10.10", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-6.10.10.tgz", - "integrity": "sha512-2nh0hJz9HeZE0VIEMI+oPgjr/Q37ohrR9iqsl7f7GW5ik+PnKYCT9Eab5mR1GNMG60askwbskgGC1S9ygtvrSw==", + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.7.0.tgz", + "integrity": "sha512-XX/OkC8NlvsBdhKsb9j7ZbuQtF/Vuo0xf38PXdqYtVezOrYbDuba0hPG++g/IGNuAF34ZbSi+49cvz4u5w92kQ==", "dev": true, "requires": { "chalk": "^4.0.0", @@ -651,39 +682,75 @@ } }, "@wdio/protocols": { - "version": "6.12.0", - "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-6.12.0.tgz", - "integrity": "sha512-UhTBZxClCsM3VjaiDp4DoSCnsa7D1QNmI2kqEBfIpyNkT3GcZhJb7L+nL0fTkzCwi7+/uLastb3/aOwH99gt0A==", + "version": "7.12.1", + "resolved": "https://registry.npmjs.org/@wdio/protocols/-/protocols-7.12.1.tgz", + "integrity": "sha512-RMZltyM3PqDuaENqAiMwjqQG6y/np+agjv6oTOYSej9FzfkwJeCK2w1KhtYMmISlpodYqioXm8TLxpk0wE+QcA==", "dev": true }, "@wdio/repl": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-6.11.0.tgz", - "integrity": "sha512-FxrFKiTkFyELNGGVEH1uijyvNY7lUpmff6x+FGskFGZB4uSRs0rxkOMaEjxnxw7QP1zgQKr2xC7GyO03gIGRGg==", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/@wdio/repl/-/repl-7.12.4.tgz", + "integrity": "sha512-LM+FD2IDowoRLbP8AuBQQT9L3iM1+trX8tDL6GV3nf9cngDk/vLQtbLi7xboJDSlje/8ibh9bDARmc5fM0djog==", "dev": true, "requires": { - "@wdio/utils": "6.11.0" + "@wdio/utils": "7.12.4" } }, "@wdio/sync": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@wdio/sync/-/sync-6.11.0.tgz", - "integrity": "sha512-ORdY40PNP1c0VKJV+dIh1tYmMXwsRHPhB66p1Y6TRm6LvIpPVX8peoB/Qx9zBsO40hAS1cFt9pdsGxu7VCHnfg==", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/@wdio/sync/-/sync-7.12.4.tgz", + "integrity": "sha512-s++j8XpeAy+5eC8jO07Jp63WAiVUlIi4BU4WpLom8iQvghJVWuXetE/uuL50GwChQDBAF4mC6NV9vAbTw+WPUA==", "dev": true, "requires": { "@types/fibers": "^3.1.0", "@types/puppeteer": "^5.4.0", - "@wdio/logger": "6.10.10", - "fibers": "^4.0.1" + "@wdio/logger": "7.7.0", + "@wdio/types": "7.10.1", + "fibers": "^5.0.0", + "webdriverio": "7.12.4" + } + }, + "@wdio/types": { + "version": "7.10.1", + "resolved": "https://registry.npmjs.org/@wdio/types/-/types-7.10.1.tgz", + "integrity": "sha512-wEDmdux2VCGO4wWVj7v9UbVRqQG7liHnDVPYJuQURPj3hJMiQQTIHwRi7EmwYfbJ9/mRoHBOGeZt7nSvtcjeaQ==", + "dev": true, + "requires": { + "@types/node": "^15.12.5", + "got": "^11.8.1" + }, + "dependencies": { + "@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", + "dev": true + } } }, "@wdio/utils": { - "version": "6.11.0", - "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-6.11.0.tgz", - "integrity": "sha512-vf0sOQzd28WbI26d6/ORrQ4XKWTzSlWLm9W/K/eJO0NASKPEzR+E+Q2kaa+MJ4FKXUpjbt+Lxfo+C26TzBk7tg==", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/@wdio/utils/-/utils-7.12.4.tgz", + "integrity": "sha512-o2jMByJElanG47syEu7UQkbJqZespO0DH4cUBG4GMbhkzSjDv3pE8UD6oknusHBM89DJT2UMYlZkrQSHxnovFw==", "dev": true, "requires": { - "@wdio/logger": "6.10.10" + "@wdio/logger": "7.7.0", + "@wdio/types": "7.10.1", + "p-iteration": "^1.1.8" + }, + "dependencies": { + "@wdio/logger": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.7.0.tgz", + "integrity": "sha512-XX/OkC8NlvsBdhKsb9j7ZbuQtF/Vuo0xf38PXdqYtVezOrYbDuba0hPG++g/IGNuAF34ZbSi+49cvz4u5w92kQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^6.0.0" + } + } } }, "accepts": { @@ -788,12 +855,6 @@ "readable-stream": "^2.0.0" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -829,6 +890,16 @@ "integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==", "dev": true }, + "aria-query": { + "version": "4.2.2", + "resolved": "https://registry.npmjs.org/aria-query/-/aria-query-4.2.2.tgz", + "integrity": "sha512-o/HelwhuKpTj/frsOsbNLNgnNGVIFsVP/SW2BSF14gVl7kAfMOJ6/8wUAUvG1R1NHKrfG+2sHZTu0yauT1qBrA==", + "dev": true, + "requires": { + "@babel/runtime": "^7.10.2", + "@babel/runtime-corejs3": "^7.10.2" + } + }, "array-flatten": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/array-flatten/-/array-flatten-1.1.1.tgz", @@ -853,12 +924,6 @@ "integrity": "sha512-XdD5lRO/87udXCMC9meWdYiR+Nq6ZjUfXidViUZGu2F1MO4T3XwZ1et0hb2++BgLfhyJwy44BGB/yx80ABx8hg==", "dev": true }, - "at-least-node": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/at-least-node/-/at-least-node-1.0.0.tgz", - "integrity": "sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==", - "dev": true - }, "atob": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/atob/-/atob-2.1.2.tgz", @@ -1112,25 +1177,15 @@ "dev": true }, "chrome-launcher": { - "version": "0.13.4", - "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.13.4.tgz", - "integrity": "sha512-nnzXiDbGKjDSK6t2I+35OAPBy5Pw/39bgkb/ZAFwMhwJbdYBp6aH+vW28ZgtjdU890Q7D+3wN/tB8N66q5Gi2A==", + "version": "0.14.0", + "resolved": "https://registry.npmjs.org/chrome-launcher/-/chrome-launcher-0.14.0.tgz", + "integrity": "sha512-W//HpflaW6qBGrmuskup7g+XJZN6w03ko9QSIe5CtcTal2u0up5SeReK3Ll1Why4Ey8dPkv8XSodZyHPnGbVHQ==", "dev": true, "requires": { "@types/node": "*", - "escape-string-regexp": "^1.0.5", + "escape-string-regexp": "^4.0.0", "is-wsl": "^2.2.0", - "lighthouse-logger": "^1.0.0", - "mkdirp": "^0.5.3", - "rimraf": "^3.0.2" - }, - "dependencies": { - "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=", - "dev": true - } + "lighthouse-logger": "^1.0.0" } }, "chromedriver": { @@ -1274,10 +1329,16 @@ "integrity": "sha1-4wOogrNCzD7oylE6eZmXNNqzriw=", "dev": true }, + "core-js-pure": { + "version": "3.17.3", + "resolved": "https://registry.npmjs.org/core-js-pure/-/core-js-pure-3.17.3.tgz", + "integrity": "sha512-YusrqwiOTTn8058JDa0cv9unbXdIiIgcgI9gXso0ey4WgkFLd3lYlV9rp9n7nDCsYxXsMDTjA4m1h3T348mdlQ==", + "dev": true + }, "core-util-is": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz", - "integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=", + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.3.tgz", + "integrity": "sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==", "dev": true }, "crc-32": { @@ -1443,22 +1504,43 @@ "dev": true }, "devtools": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/devtools/-/devtools-6.12.1.tgz", - "integrity": "sha512-JyG46suEiZmld7/UVeogkCWM0zYGt+2ML/TI+SkEp+bTv9cs46cDb0pKF3glYZJA7wVVL2gC07Ic0iCxyJEnCQ==", - "dev": true, - "requires": { - "@wdio/config": "6.12.1", - "@wdio/logger": "6.10.10", - "@wdio/protocols": "6.12.0", - "@wdio/utils": "6.11.0", - "chrome-launcher": "^0.13.1", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/devtools/-/devtools-7.12.4.tgz", + "integrity": "sha512-Rm4nzb8LXhf+1B3Z4t99TViG2xtvTGxyZq2nhGsBwcslstb4xug1B8ixmIfFuv+QDaavj0Z4Fa/YfUUWikY7lA==", + "dev": true, + "requires": { + "@types/node": "^15.12.5", + "@wdio/config": "7.10.1", + "@wdio/logger": "7.7.0", + "@wdio/protocols": "7.12.1", + "@wdio/types": "7.10.1", + "@wdio/utils": "7.12.4", + "chrome-launcher": "^0.14.0", "edge-paths": "^2.1.0", - "puppeteer-core": "^5.1.0", + "puppeteer-core": "^10.1.0", + "query-selector-shadow-dom": "^1.0.0", "ua-parser-js": "^0.7.21", "uuid": "^8.0.0" }, "dependencies": { + "@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", + "dev": true + }, + "@wdio/logger": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.7.0.tgz", + "integrity": "sha512-XX/OkC8NlvsBdhKsb9j7ZbuQtF/Vuo0xf38PXdqYtVezOrYbDuba0hPG++g/IGNuAF34ZbSi+49cvz4u5w92kQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^6.0.0" + } + }, "uuid": { "version": "8.3.2", "resolved": "https://registry.npmjs.org/uuid/-/uuid-8.3.2.tgz", @@ -1468,9 +1550,9 @@ } }, "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.917689", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.917689.tgz", + "integrity": "sha512-3oTB74BuK5FmesiBrj4qEz3b/47rSK5aniNhvlvOpNOcJeD9bhO50egRh/QsCX8oqgTvWqu11hy7ZmE8LKEaWA==", "dev": true }, "diff": { @@ -1678,9 +1760,9 @@ } }, "fibers": { - "version": "4.0.3", - "resolved": "https://registry.npmjs.org/fibers/-/fibers-4.0.3.tgz", - "integrity": "sha512-MW5VrDtTOLpKK7lzw4qD7Z9tXaAhdOmOED5RHzg3+HjUk+ibkjVW0Py2ERtdqgTXaerLkVkBy2AEmJiT6RMyzg==", + "version": "5.0.0", + "resolved": "https://registry.npmjs.org/fibers/-/fibers-5.0.0.tgz", + "integrity": "sha512-UpGv/YAZp7mhKHxDvC1tColrroGRX90sSvh8RMZV9leo+e5+EkRVgCEZPlmXeo3BUNQTZxUaVdLskq1Q2FyCPg==", "dev": true, "requires": { "detect-libc": "^1.0.3" @@ -1795,12 +1877,11 @@ "dev": true }, "fs-extra": { - "version": "9.1.0", - "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-9.1.0.tgz", - "integrity": "sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==", + "version": "10.0.0", + "resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.0.0.tgz", + "integrity": "sha512-C5owb14u9eJwizKGdchcDUQeFtlSHHthBk8pbX9Vc1PFZrLombudjDnNns88aYslCyF6IY5SUw3Roz6xShcEIQ==", "dev": true, "requires": { - "at-least-node": "^1.0.0", "graceful-fs": "^4.2.0", "jsonfile": "^6.0.1", "universalify": "^2.0.0" @@ -2178,6 +2259,12 @@ "is-url": "^1.2.4" } }, + "isarray": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", + "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", + "dev": true + }, "isexe": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz", @@ -2332,6 +2419,12 @@ "json-buffer": "3.0.1" } }, + "ky": { + "version": "0.28.5", + "resolved": "https://registry.npmjs.org/ky/-/ky-0.28.5.tgz", + "integrity": "sha512-O5gg9kF4MeyfSw+YkgPAafOPwEUU6xcdGEJKUJmKpIPbLzk3oxUtY4OdBNekG7mawofzkyZ/ZHuR9ev5uZZdAA==", + "dev": true + }, "lazystream": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/lazystream/-/lazystream-1.0.0.tgz", @@ -2341,12 +2434,6 @@ "readable-stream": "^2.0.5" }, "dependencies": { - "isarray": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", - "integrity": "sha1-u5NdSFgsuhaMBoNJV6VKPgcSTxE=", - "dev": true - }, "readable-stream": { "version": "2.3.7", "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.7.tgz", @@ -2593,12 +2680,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 - }, "mocha": { "version": "8.4.0", "resolved": "https://registry.npmjs.org/mocha/-/mocha-8.4.0.tgz", @@ -2924,6 +3005,12 @@ "integrity": "sha512-BZOr3nRQHOntUjTrH8+Lh54smKHoHyur8We1V8DSMVrl5A2malOOwuJRnKRDjSnkoeBh4at6BwEnb5I7Jl31wg==", "dev": true }, + "p-iteration": { + "version": "1.1.8", + "resolved": "https://registry.npmjs.org/p-iteration/-/p-iteration-1.1.8.tgz", + "integrity": "sha512-IMFBSDIYcPNnW7uWYGrBqmvTiq7W0uB0fJn6shQZs7dlF3OvrHOre+JT9ikSZ7gZS3vWqclVgoQSvToJrns7uQ==", + "dev": true + }, "p-limit": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-3.1.0.tgz", @@ -3093,9 +3180,9 @@ } }, "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 }, "proxy-addr": { @@ -3125,40 +3212,39 @@ } }, "puppeteer-core": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-5.5.0.tgz", - "integrity": "sha512-tlA+1n+ziW/Db03hVV+bAecDKse8ihFRXYiEypBe9IlLRvOCzYFG6qrCMBYK34HO/Q/Ecjc+tvkHRAfLVH+NgQ==", + "version": "10.2.0", + "resolved": "https://registry.npmjs.org/puppeteer-core/-/puppeteer-core-10.2.0.tgz", + "integrity": "sha512-c1COxSnfynsE6Mtt+dW0t3TITjF9Ku4dnJbFMDDVhLQuMTYSpz4rkSP37qvzcSo3k02/Ac3GYWk0/ncp6DKZNA==", "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.901419", + "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": { - "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 - }, - "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==", + "debug": { + "version": "4.3.1", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", + "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", "dev": true, "requires": { - "agent-base": "5", - "debug": "4" + "ms": "2.1.2" } + }, + "devtools-protocol": { + "version": "0.0.901419", + "resolved": "https://registry.npmjs.org/devtools-protocol/-/devtools-protocol-0.0.901419.tgz", + "integrity": "sha512-4INMPwNm9XRpBukhNbF7OB6fNTTCaI8pzy/fXg0xQzAy5h3zL1P8xT3QazgKqBrb/hAYwIBizqDBZ7GtJE74QQ==", + "dev": true } } }, @@ -3168,6 +3254,12 @@ "integrity": "sha512-VCdBRNFTX1fyE7Nb6FYoURo/SPe62QCaAyzJvUjwRaIsc+NePBEniHlvxFmmX56+HZphIGtV0XeCirBtpDrTyQ==", "dev": true }, + "query-selector-shadow-dom": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/query-selector-shadow-dom/-/query-selector-shadow-dom-1.0.0.tgz", + "integrity": "sha512-bK0/0cCI+R8ZmOF1QjT7HupDUYCxbf/9TJgAmSXQxZpftXmTAeil9DRoCnTDkWbvOyZzhcMBwKpptWcdkGFIMg==", + "dev": true + }, "queue-microtask": { "version": "1.2.3", "resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz", @@ -3236,6 +3328,12 @@ "picomatch": "^2.2.1" } }, + "regenerator-runtime": { + "version": "0.13.9", + "resolved": "https://registry.npmjs.org/regenerator-runtime/-/regenerator-runtime-0.13.9.tgz", + "integrity": "sha512-p3VT+cOEgxFsRRA9X4lkI1E+k2/CtnKtU4gcxyaCUreilL/vqI6CdZ3wxVUx3UOUg+gnUOQQcRI7BmSI656MYA==", + "dev": true + }, "release-zalgo": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/release-zalgo/-/release-zalgo-1.0.0.tgz", @@ -3258,9 +3356,9 @@ "dev": true }, "resolve-alpn": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.0.tgz", - "integrity": "sha512-e4FNQs+9cINYMO5NMFc6kOUCdohjqFPSgMuwuZAOUWqrfWsen+Yjy5qZFkV5K7VO7tFSLKcUL97olkED7sCBHA==", + "version": "1.2.1", + "resolved": "https://registry.npmjs.org/resolve-alpn/-/resolve-alpn-1.2.1.tgz", + "integrity": "sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==", "dev": true }, "resolve-from": { @@ -3294,9 +3392,9 @@ "dev": true }, "rgb2hex": { - "version": "0.2.3", - "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.3.tgz", - "integrity": "sha512-clEe0m1xv+Tva1B/TOepuIcvLAxP0U+sCDfgt1SX1HmI2Ahr5/Cd/nzJM1e78NKVtWdoo0s33YehpFA8UfIShQ==", + "version": "0.2.5", + "resolved": "https://registry.npmjs.org/rgb2hex/-/rgb2hex-0.2.5.tgz", + "integrity": "sha512-22MOP1Rh7sAo1BZpDG6R5RFYzR2lYEgwq7HEmyW2qcsOqR2lQKmn+O//xV3YG/0rrhMC6KVX2hU+ZXuaw9a5bw==", "dev": true }, "rimraf": { @@ -3575,15 +3673,15 @@ } }, "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": { @@ -3871,9 +3969,9 @@ "dev": 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", @@ -3917,36 +4015,64 @@ "dev": true }, "webdriver": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-6.12.1.tgz", - "integrity": "sha512-3rZgAj9o2XHp16FDTzvUYaHelPMSPbO1TpLIMUT06DfdZjNYIzZiItpIb/NbQDTPmNhzd9cuGmdI56WFBGY2BA==", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/webdriver/-/webdriver-7.12.4.tgz", + "integrity": "sha512-7l52acjLt9J6LNY+3oYGX2Rhqq7qCX55LOzIxhX6W5qufKHIF6xNYyng/PN++OrM0jb/EIOkmUviC7/hDLcuIg==", "dev": true, "requires": { - "@wdio/config": "6.12.1", - "@wdio/logger": "6.10.10", - "@wdio/protocols": "6.12.0", - "@wdio/utils": "6.11.0", + "@types/node": "^15.12.5", + "@wdio/config": "7.10.1", + "@wdio/logger": "7.7.0", + "@wdio/protocols": "7.12.1", + "@wdio/types": "7.10.1", + "@wdio/utils": "7.12.4", "got": "^11.0.2", + "ky": "^0.28.5", "lodash.merge": "^4.6.1" + }, + "dependencies": { + "@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", + "dev": true + }, + "@wdio/logger": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.7.0.tgz", + "integrity": "sha512-XX/OkC8NlvsBdhKsb9j7ZbuQtF/Vuo0xf38PXdqYtVezOrYbDuba0hPG++g/IGNuAF34ZbSi+49cvz4u5w92kQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^6.0.0" + } + } } }, "webdriverio": { - "version": "6.12.1", - "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-6.12.1.tgz", - "integrity": "sha512-Nx7ge0vTWHVIRUbZCT+IuMwB5Q0Q5nLlYdgnmmJviUKLuc3XtaEBkYPTbhHWHgSBXsPZMIc023vZKNkn+6iyeQ==", - "dev": true, - "requires": { - "@types/puppeteer-core": "^5.4.0", - "@wdio/config": "6.12.1", - "@wdio/logger": "6.10.10", - "@wdio/repl": "6.11.0", - "@wdio/utils": "6.11.0", + "version": "7.12.4", + "resolved": "https://registry.npmjs.org/webdriverio/-/webdriverio-7.12.4.tgz", + "integrity": "sha512-a9GnQ2Df2M/PWSaKeAOaX0LCBFtepo/GRIxLM2uqL2FbE/2emGt793wf+qzMA3RokNryxF+pcPNyAgyhS4uH2g==", + "dev": true, + "requires": { + "@types/aria-query": "^4.2.1", + "@types/node": "^15.12.5", + "@wdio/config": "7.10.1", + "@wdio/logger": "7.7.0", + "@wdio/protocols": "7.12.1", + "@wdio/repl": "7.12.4", + "@wdio/types": "7.10.1", + "@wdio/utils": "7.12.4", "archiver": "^5.0.0", + "aria-query": "^4.2.2", "atob": "^2.1.2", "css-shorthand-properties": "^1.1.1", "css-value": "^0.0.1", - "devtools": "6.12.1", - "fs-extra": "^9.0.1", + "devtools": "7.12.4", + "devtools-protocol": "^0.0.917689", + "fs-extra": "^10.0.0", "get-port": "^5.1.1", "grapheme-splitter": "^1.0.2", "lodash.clonedeep": "^4.5.0", @@ -3954,11 +4080,32 @@ "lodash.isplainobject": "^4.0.6", "lodash.zip": "^4.2.0", "minimatch": "^3.0.4", - "puppeteer-core": "^5.1.0", + "puppeteer-core": "^10.1.0", + "query-selector-shadow-dom": "^1.0.0", "resq": "^1.9.1", - "rgb2hex": "0.2.3", + "rgb2hex": "0.2.5", "serialize-error": "^8.0.0", - "webdriver": "6.12.1" + "webdriver": "7.12.4" + }, + "dependencies": { + "@types/node": { + "version": "15.14.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-15.14.9.tgz", + "integrity": "sha512-qjd88DrCxupx/kJD5yQgZdcYKZKSIGBVDIBE1/LTGcNm3d2Np/jxojkdePDdfnBHJc5W7vSMpbJ1aB7p/Py69A==", + "dev": true + }, + "@wdio/logger": { + "version": "7.7.0", + "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-7.7.0.tgz", + "integrity": "sha512-XX/OkC8NlvsBdhKsb9j7ZbuQtF/Vuo0xf38PXdqYtVezOrYbDuba0hPG++g/IGNuAF34ZbSi+49cvz4u5w92kQ==", + "dev": true, + "requires": { + "chalk": "^4.0.0", + "loglevel": "^1.6.0", + "loglevel-plugin-prefix": "^0.8.4", + "strip-ansi": "^6.0.0" + } + } } }, "which": { @@ -4040,9 +4187,9 @@ } }, "ws": { - "version": "7.5.3", - "resolved": "https://registry.npmjs.org/ws/-/ws-7.5.3.tgz", - "integrity": "sha512-kQ/dHIzuLrS6Je9+uv81ueZomEwH0qVYstcAQ4/Z93K8zeko9gtAbttJWzoC5ukqXY1PpoouV3+VSOqEAFt5wg==", + "version": "7.4.6", + "resolved": "https://registry.npmjs.org/ws/-/ws-7.4.6.tgz", + "integrity": "sha512-YmhHDO4MzaDLB+M9ym/mDA5z0naX8j7SIlT8f8z+I0VtzsRbekxEutHSme7NPS2qE8StCYQNUnfWdXta/Yu85A==", "dev": true }, "y18n": { diff --git a/packages/webdriverio/package.json b/packages/webdriverio/package.json index f70e7060..4a21e42a 100644 --- a/packages/webdriverio/package.json +++ b/packages/webdriverio/package.json @@ -44,7 +44,7 @@ "@types/mocha": "^8.2.3", "@types/node": "^14.17.9", "@types/test-listen": "^1.1.0", - "@wdio/sync": "^6.11.0", + "@wdio/sync": "^7.12.4", "axe-test-fixtures": "github:dequelabs/axe-test-fixtures#v1", "chai": "^4.3.0", "chromedriver": "^93.0.1", @@ -58,10 +58,10 @@ "ts-node": "^9.1.1", "tsc-silent": "^1.2.1", "typescript": "^4.3.5", - "webdriverio": "^6.12.1" + "webdriverio": "^7.12.4" }, "peerDependencies": { - "webdriverio": "^6.0.0 || ^5.0.0" + "webdriverio": "^7.0.0 || ^6.0.0 || ^5.0.0" }, "nyc": { "include": [ @@ -77,9 +77,9 @@ "sourceMap": true, "instrument": true, "checkCoverage": true, - "statements": 98, - "branches": 90, - "functions": 100, - "lines": 98 + "statements": 85, + "branches": 85, + "functions": 85, + "lines": 85 } } diff --git a/packages/webdriverio/src/index.ts b/packages/webdriverio/src/index.ts index 763a6014..462be4c6 100644 --- a/packages/webdriverio/src/index.ts +++ b/packages/webdriverio/src/index.ts @@ -1,15 +1,6 @@ -import type { RunOptions, AxeResults } from 'axe-core'; -import { ContextObject } from 'axe-core'; import * as fs from 'fs'; import * as assert from 'assert'; import * as cssesc from 'cssesc'; -import type { - Options, - CallbackFunction, - BrowserObject, - Element, - PartialResults -} from './types'; import { isWebdriverClient, normalizeContext, @@ -21,13 +12,23 @@ import { axeRunLegacy } from './utils'; +import type { Browser } from 'webdriverio'; +import type { RunOptions, AxeResults, ContextObject } from 'axe-core'; +import type { + Options, + CallbackFunction, + WdioBrowser, + WdioElement, + PartialResults +} from './types'; + export default class AxeBuilder { - private client: BrowserObject; + private client: Browser<'async'>; private axeSource: string; - private includes: string[]; - private excludes: string[]; - private option: RunOptions; - private disableFrameSelectors: string[]; + private includes: string[] = []; + private excludes: string[] = []; + private option: RunOptions = {}; + private disableFrameSelectors: string[] = []; private legacyMode = false; constructor({ client, axeSource }: Options) { @@ -35,23 +36,29 @@ export default class AxeBuilder { isWebdriverClient(client), 'An instantiated WebdriverIO client greater than v5 is required' ); - const sourceDir = require.resolve('axe-core'); - const source = fs.readFileSync(sourceDir, 'utf-8'); - this.client = client; - this.axeSource = axeSource || source; - this.includes = []; - this.excludes = []; - this.option = {}; - this.disableFrameSelectors = []; + // Treat everything as Browser<'async'>: + // - Anything sync can also run async, since JS can await sync functions + // - Ignore MultiRemoteBrowser, which is just Browser with extra props + this.client = client as Browser<'async'>; + + if (axeSource) { + this.axeSource = axeSource; + } else { + const sourceDir = require.resolve('axe-core'); + try { + this.axeSource = fs.readFileSync(sourceDir, 'utf-8'); + } catch (e) { + throw new Error( + 'Unable to find axe-core source. Is axe-core installed?' + ); + } + } } /** * Disable injecting axe-core into frame(s) matching the * given CSS `selector`. This method may be called any number of times. - * @param {String} selector - * @returns {this} */ - public disableFrame(selector: string): this { this.disableFrameSelectors.push(cssesc(selector)); return this; @@ -60,10 +67,7 @@ export default class AxeBuilder { /** * Selector to include in analysis. * This may be called any number of times. - * @param {String} selector - * @returns {this} */ - public include(selector: string): this { this.includes.push(selector); return this; @@ -72,10 +76,7 @@ export default class AxeBuilder { /** * Selector to exclude in analysis. * This may be called any number of times. - * @param {String} selector - * @returns {this} */ - public exclude(selector: string): this { this.excludes.push(selector); return this; @@ -83,10 +84,7 @@ export default class AxeBuilder { /** * Set options to be passed into axe-core - * @param {RunOptions} options - * @returns {this} */ - public options(options: RunOptions): this { this.option = options; return this; @@ -95,14 +93,9 @@ export default class AxeBuilder { /** * Limit analysis to only the specified rules. * Cannot be used with `AxeBuilder#withTags` - * @param {String|Array} rules - * @returns {this} */ - public withRules(rules: string | string[]): this { rules = Array.isArray(rules) ? rules : [rules]; - /* istanbul ignore next */ - this.option = this.option || {}; this.option.runOnly = { type: 'rule', values: rules @@ -114,14 +107,9 @@ export default class AxeBuilder { /** * Limit analysis to only specified tags. * Cannot be used with `AxeBuilder#withRules` - * @param {String|Array} tags - * @returns {this} */ - public withTags(tags: string | string[]): this { tags = Array.isArray(tags) ? tags : [tags]; - /* istanbul ignore next */ - this.option = this.option || {}; this.option.runOnly = { type: 'tag', values: tags @@ -131,14 +119,9 @@ export default class AxeBuilder { /** * Set the list of rules to skip when running an analysis. - * @param {String|Array} rules - * @returns {this} */ - public disableRules(rules: string | string[]): this { rules = Array.isArray(rules) ? rules : [rules]; - /* istanbul ignore next */ - this.option = this.option || {}; this.option.rules = {}; for (const rule of rules) { @@ -162,10 +145,7 @@ export default class AxeBuilder { /** * Performs an analysis and retrieves results. - * @param {CallbackFunction} callback - * @returns {Promise} */ - public async analyze(callback?: CallbackFunction): Promise { return new Promise((resolve, reject) => { return this.analyzePromise() @@ -186,9 +166,7 @@ export default class AxeBuilder { /** * Get axe-core source and configurations - * @returns {String} */ - private get script(): string { return ` ${this.axeSource} @@ -201,35 +179,28 @@ export default class AxeBuilder { /** * Injects `axe-core` into all frames. - * @param {Element | null} browsingContext - defaults to null - * @returns {Promise} */ - - private async inject(browsingContext: Element | null = null): Promise { + private async inject( + browsingContext: WdioElement | null = null + ): Promise { await this.setBrowsingContext(browsingContext); await this.client.execute(this.script); - const frames = - (await this.client.$$(this.frameSelector())) || - /* istanbul ignore next */ []; + const frames = (await this.client.$$(this.frameSelector())) || []; const iframes = - frames.concat(await this.client.$$(this.iframeSelector())) || - /* istanbul ignore next */ []; + frames.concat(await this.client.$$(this.iframeSelector())) || []; if (!iframes.length) { return; } for (const iframe of iframes) { try { - const exist = await iframe.isExisting(); - /* istanbul ignore if */ - if (!exist) { + if (!(await iframe.isExisting())) { continue; } await this.inject(iframe); await this.client.switchToParentFrame(); } catch (error) { - /* istanbul ignore next */ logOrRethrowError(error); } } @@ -243,11 +214,7 @@ export default class AxeBuilder { this.disableFrameSelectors ); - const runPartialSupported = await axeSourceInject({ - client, - axeSource - }); - + const runPartialSupported = await axeSourceInject(client, axeSource); if (!runPartialSupported || this.legacyMode) { return await this.runLegacy(context); } @@ -257,7 +224,9 @@ export default class AxeBuilder { return await this.finishRun(partials); } catch (error) { throw new Error( - `${error.message}\n Please check out https://github.com/dequelabs/axe-core-npm/blob/develop/packages/webdriverio/error-handling.md` + `${ + (error as Error).message + }\n Please check out https://github.com/dequelabs/axe-core-npm/blob/develop/packages/webdriverio/error-handling.md` ); } } @@ -265,14 +234,12 @@ export default class AxeBuilder { private async runLegacy(context: ContextObject): Promise { const { client, option } = this; await this.inject(); - return axeRunLegacy({ client, context, options: option }); + return axeRunLegacy(client, context, option); } /** * Get a CSS selector for retrieving child iframes. - * @returns {String} */ - private iframeSelector(): string { let selector = 'iframe'; for (const disableFrameSelector of this.disableFrameSelectors) { @@ -283,9 +250,7 @@ export default class AxeBuilder { /** * Get a CSS selector for retrieving child frames. - * @returns {String} */ - private frameSelector(): string { let selector = 'frame'; for (const disableFrameSelector of this.disableFrameSelectors) { @@ -297,12 +262,9 @@ export default class AxeBuilder { /** * Set browsing context - when `null` sets top level page as context * - https://webdriver.io/docs/api/webdriver.html#switchtoframe - * @param {null | Element | BrowserObject} id - defaults to null - * @returns {Promise} */ - private async setBrowsingContext( - id: null | Element | BrowserObject = null + id: null | WdioElement | WdioBrowser = null ): Promise { if (id) { await this.client.switchToFrame(id); @@ -319,17 +281,9 @@ export default class AxeBuilder { private async runPartialRecursive( context: ContextObject ): Promise { - const frameContexts = await axeGetFrameContext({ - client: this.client, - context - }); - + const frameContexts = await axeGetFrameContext(this.client, context); const partials: PartialResults = [ - await axeRunPartial({ - client: this.client, - context, - options: this.option - }) + await axeRunPartial(this.client, context, this.option) ]; for (const { frameSelector, frameContext } of frameContexts) { @@ -337,10 +291,7 @@ export default class AxeBuilder { const frame = await this.client.$(frameSelector); assert(frame, `Expect frame of "${frameSelector}" to be defined`); await this.client.switchToFrame(frame); - await axeSourceInject({ - client: this.client, - axeSource: this.script - }); + await axeSourceInject(this.client, this.script); partials.push(...(await this.runPartialRecursive(frameContext))); } catch (error) { partials.push(null); @@ -353,9 +304,7 @@ export default class AxeBuilder { private async finishRun(partials: PartialResults): Promise { const { client, axeSource, option } = this; const win = await client.getWindowHandle(); - const newWindow = await client.createWindow('tab'); - assert( newWindow.handle, 'Please make sure that you have popup blockers disabled.' @@ -366,17 +315,14 @@ export default class AxeBuilder { await client.url('about:blank'); } catch (error) { throw new Error( - `switchToWindow failed. Are you using updated browser drivers? \nDriver reported:\n${error.message}` + `switchToWindow failed. Are you using updated browser drivers? \nDriver reported:\n${ + (error as Error).message + }` ); } - const res = await axeFinishRun({ - client, - axeSource, - options: option, - partialResults: partials - }); - + const res = await axeFinishRun(client, axeSource, partials, option); + // Cleanup await client.closeWindow(); await client.switchToWindow(win); diff --git a/packages/webdriverio/src/test.ts b/packages/webdriverio/src/test.ts index 47dd7d14..fa477882 100644 --- a/packages/webdriverio/src/test.ts +++ b/packages/webdriverio/src/test.ts @@ -1,7 +1,6 @@ import 'mocha'; import * as webdriverio from 'webdriverio'; -const sync = require('@wdio/sync').default; -import * as wdio from '@wdio/sync'; +import sync from '@wdio/sync'; import * as express from 'express'; import testListen = require('test-listen'); import { assert } from 'chai'; @@ -13,6 +12,7 @@ import * as fs from 'fs'; import delay from 'delay'; import AxeBuilder from '.'; import { logOrRethrowError } from './utils'; +import { WdioBrowser } from './types'; const connectToChromeDriver = (port: number): Promise => { let socket: net.Socket; @@ -47,7 +47,7 @@ const connectToChromeDriver = (port: number): Promise => { describe('@axe-core/webdriverio', () => { let port: number; - for (const protocol of ['devtools', 'webdriver']) { + for (const protocol of ['devtools', 'webdriver'] as const) { if (protocol === 'webdriver') { port = 9515; before(async () => { @@ -64,7 +64,7 @@ describe('@axe-core/webdriverio', () => { describe('WebdriverIO Async', () => { let server: Server; let addr: string; - let client: webdriverio.BrowserObject; + let client: WdioBrowser; const axePath = require.resolve('axe-core'); const axeSource = fs.readFileSync(axePath, 'utf8'); const axeTestFixtures = path.resolve( @@ -158,7 +158,7 @@ describe('@axe-core/webdriverio', () => { }); it('throws if axe errors out on the top window', async () => { - let error: Error | null = null; + let error: unknown = null; await client.url(`${addr}/crash.html`); try { await new AxeBuilder({ @@ -357,7 +357,7 @@ describe('@axe-core/webdriverio', () => { }); it('throws if axe errors out on the top window', async () => { - let error: Error | null = null; + let error: unknown = null; await client.url(`${addr}/crash.html`); try { await new AxeBuilder({ @@ -371,7 +371,7 @@ describe('@axe-core/webdriverio', () => { }); it('throws when injecting a problematic source', async () => { - let error: Error | null = null; + let error: unknown = null; await client.url(`${addr}/crash-me.html`); try { await new AxeBuilder({ @@ -385,7 +385,7 @@ describe('@axe-core/webdriverio', () => { }); it('throws when a setup fails', async () => { - let error: Error | null = null; + let error: unknown = null; const brokenSource = axeSource + `;window.axe.utils = {};`; await client.url(`${addr}/index.html`); @@ -401,7 +401,7 @@ describe('@axe-core/webdriverio', () => { }); it('properly isolates the call to axe.finishRun', async () => { - let error: Error | null = null; + let error: unknown = null; await client.url(`${addr}/isolated-finish.html`); try { @@ -671,29 +671,27 @@ describe('@axe-core/webdriverio', () => { describe('logOrRethrowError', () => { it('log a StaleElementReference Error with `seleniumStack`', () => { - const error = { - seleniumStack: { - type: 'StaleElementReference' - } + const error = new Error('Selenium Error'); + error.seleniumStack = { + type: 'StaleElementReference' }; assert.doesNotThrow(() => logOrRethrowError(error as any)); }); it('log a `stale element reference` Error', () => { - const error = { - name: 'stale element reference', - message: 'foobar' - }; + const error = new Error('foobar'); + error.name = 'stale element reference'; assert.doesNotThrow(() => logOrRethrowError(error)); }); it('throws errors that are not StaleElementReferenceErrors', () => { - const error = { - name: 'foo', - message: 'bar' - }; + const error = new Error('foo'); assert.throws(() => logOrRethrowError(error)); }); + + it('throws if non-Error content is passed', () => { + assert.throws(() => logOrRethrowError('error')); + }); }); describe('withRules', () => { @@ -798,7 +796,7 @@ describe('@axe-core/webdriverio', () => { describe('include/exclude', () => { it('with include and exclude', async () => { - let error: Error | null = null; + let error: unknown = null; await client.url(`${addr}/nested-iframes.html`); const builder = new AxeBuilder({ client }) .include('#ifr-foo') @@ -814,7 +812,7 @@ describe('@axe-core/webdriverio', () => { }); it('with only include', async () => { - let error: Error | null = null; + let error: unknown = null; await client.url(`${addr}/nested-iframes.html`); const builder = new AxeBuilder({ client }).include('#ifr-foo'); @@ -828,7 +826,7 @@ describe('@axe-core/webdriverio', () => { }); it('wth only exclude', async () => { - let error: Error | null = null; + let error: unknown = null; await client.url(`${addr}/nested-iframes.html`); const builder = new AxeBuilder({ client }).exclude('#ifr-bar'); @@ -990,19 +988,19 @@ describe('@axe-core/webdriverio', () => { afterEach(function (done) { remote - .then((client: wdio.BrowserObject) => + .then((client: WdioBrowser) => sync(() => { client.deleteSession(); server.close(); }) ) .then(() => done()) - .catch((e: Error) => done(e)); + .catch((e: unknown) => done(e)); }); it('analyze', function (done) { remote - .then((client: wdio.BrowserObject) => + .then((client: WdioBrowser) => sync(() => { client.url(`${addr}/index.html`); assert.isTrue(client.isDevTools); @@ -1016,7 +1014,7 @@ describe('@axe-core/webdriverio', () => { }) ) .then(() => done()) - .catch((e: Error) => done(e)); + .catch((e: unknown) => done(e)); }); }); }); diff --git a/packages/webdriverio/src/types.ts b/packages/webdriverio/src/types.ts index 77e418bb..ce0a3c16 100644 --- a/packages/webdriverio/src/types.ts +++ b/packages/webdriverio/src/types.ts @@ -1,52 +1,14 @@ +import type { Browser, MultiRemoteBrowser, Element } from 'webdriverio'; import type { AxeResults, ElementContext, RunOptions, Spec } from 'axe-core'; import * as axe from 'axe-core'; -import { - BrowserObject as BrowserObjectSync, - Element as ElementSync, - MultiRemoteBrowserObject as MultiRemoteBrowserObjectSync -} from '@wdio/sync'; -import { - BrowserObject as BrowserObjectAsync, - MultiRemoteBrowserObject as MultiRemoteBrowserObjectAsync, - Element as ElementAsync -} from 'webdriverio'; -export type BrowserObject = - | BrowserObjectAsync - | BrowserObjectSync - | MultiRemoteBrowserObjectAsync - | MultiRemoteBrowserObjectSync; +export type WdioBrowser = + | Browser<'async'> + | Browser<'sync'> + | MultiRemoteBrowser<'async'> + | MultiRemoteBrowser<'sync'>; -export type Element = ElementAsync | ElementSync; - -export interface AxeRunPartialParams { - client: BrowserObject; - context?: ElementContext; - options?: RunOptions; -} - -export interface AxeGetFrameContextParams { - client: BrowserObject; - context: ElementContext; -} - -export interface AxeRunLegacyParams extends AxeRunPartialParams { - config?: Spec; -} - -export interface AxeSourceInjectParams { - client: BrowserObject; - axeSource: string; -} - -export interface AxeFinishRunParams extends AxeSourceInjectParams { - partialResults: PartialResults; - options: RunOptions; -} - -export interface AxeSourceInjectResponse { - runPartialSupported: boolean; -} +export type WdioElement = Element<'async'> | Element<'sync'>; export type CallbackFunction = ( error: string | null, @@ -54,7 +16,7 @@ export type CallbackFunction = ( ) => void; export interface Options { - client: BrowserObject; + client: WdioBrowser; axeSource?: string; } diff --git a/packages/webdriverio/src/utils.ts b/packages/webdriverio/src/utils.ts index b4fcfaac..e2e247b2 100644 --- a/packages/webdriverio/src/utils.ts +++ b/packages/webdriverio/src/utils.ts @@ -1,21 +1,19 @@ -import type { AxeResults, PartialResult, ContextObject } from 'axe-core'; +import * as assert from 'assert'; +import type { Browser } from 'webdriverio'; import type { - BrowserObject, - AxeRunPartialParams, - AxeGetFrameContextParams, - AxeRunLegacyParams, - AxeFinishRunParams, - AxeSourceInjectResponse, - AxeSourceInjectParams -} from './types'; + AxeResults, + PartialResult, + ContextObject, + RunOptions, + Spec, + PartialResults +} from 'axe-core'; +import type { WdioBrowser } from './types'; /** * Validates that the client provided is WebdriverIO v5 or v6. - * @param {BrowserObject} client - * @returns {boolean} */ - -export const isWebdriverClient = (client: BrowserObject): boolean => { +export const isWebdriverClient = (client: WdioBrowser): boolean => { if (!client || typeof client !== 'object') { return false; } @@ -33,11 +31,7 @@ export const isWebdriverClient = (client: BrowserObject): boolean => { /** * Get running context - * @param {Array} include - * @param {Array} exclude - * @returns {ContextObject} */ - export const normalizeContext = ( includes: string[], excludes: string[], @@ -61,11 +55,9 @@ export const normalizeContext = ( /** * Checks to make sure that the error thrown was not a stale iframe - * @param {Error} error - * @returns {void} */ - -export const logOrRethrowError = (error: Error): void => { +export const logOrRethrowError = (error: unknown): void => { + assert(error instanceof Error, 'An unknown error occurred'); if ( error?.seleniumStack?.type === 'StaleElementReference' || error.name === 'stale element reference' @@ -81,17 +73,16 @@ export const logOrRethrowError = (error: Error): void => { /** * Selenium-webdriver thenable aren't chainable. This fixes it. */ - const promisify = (thenable: Promise): Promise => { return new Promise((resolve, reject) => { thenable.then(resolve, reject); }); }; -export const axeSourceInject = async ({ - client, - axeSource -}: AxeSourceInjectParams): Promise => { +export const axeSourceInject = async ( + client: Browser<'async'>, + axeSource: string +): Promise<{ runPartialSupported: boolean }> => { return promisify( // Had to use executeAsync() because we could not use multiline statements in client.execute() // we were able to return a single boolean in a line but not when assigned to a variable. @@ -107,31 +98,30 @@ export const axeSourceInject = async ({ ); }; -export const axeRunPartial = ({ - client, - context, - options -}: AxeRunPartialParams): Promise => { +export const axeRunPartial = ( + client: Browser<'async'>, + context?: ContextObject, + options?: RunOptions +): Promise => { return promisify( client - .executeAsync( + .executeAsync( ` var callback = arguments[arguments.length - 1]; var context = ${JSON.stringify(context)} || document; var options = ${JSON.stringify(options)} || {}; window.axe.runPartial(context, options).then(function (partials) { callback(JSON.stringify(partials)) - }); - ` + });` ) .then((r: string) => deserialize(r)) ); }; -export const axeGetFrameContext = ({ - client, - context -}: AxeGetFrameContextParams): Promise => { +export const axeGetFrameContext = ( + client: Browser<'async'>, + context: ContextObject +): Promise => { return promisify( // Had to use executeAsync() because we could not use multiline statements in client.execute() // we were able to return a single boolean in a line but not when assigned to a variable. @@ -144,17 +134,16 @@ export const axeGetFrameContext = ({ ); }; -export const axeRunLegacy = ({ - client, - context, - options, - config -}: AxeRunLegacyParams): Promise => { +export const axeRunLegacy = ( + client: Browser<'async'>, + context: ContextObject, + options: RunOptions, + config?: Spec +): Promise => { return promisify( client - .executeAsync( - ` - var callback = arguments[arguments.length - 1]; + .executeAsync( + `var callback = arguments[arguments.length - 1]; var context = ${JSON.stringify(context)} || document; var options = ${JSON.stringify(options)} || {}; var config = ${JSON.stringify(config)} || null; @@ -163,24 +152,22 @@ export const axeRunLegacy = ({ } window.axe.run(context, options).then(function (axeResults) { callback(JSON.stringify(axeResults)) - }); - ` + });` ) .then((r: string) => deserialize(r)) ); }; -export const axeFinishRun = ({ - client, - axeSource, - partialResults, - options -}: AxeFinishRunParams): Promise => { +export const axeFinishRun = ( + client: Browser<'async'>, + axeSource: string, + partialResults: PartialResults, + options: RunOptions +): Promise => { return promisify( client - .executeAsync( - ` - var callback = arguments[arguments.length - 1]; + .executeAsync( + `var callback = arguments[arguments.length - 1]; ${axeSource}; window.axe.configure({ branding: { application: 'webdriverio' } @@ -190,8 +177,7 @@ export const axeFinishRun = ({ var options = ${JSON.stringify(options || {})}; window.axe.finishRun(partialResults, options).then(function (axeResults) { callback(JSON.stringify(axeResults)) - }); - ` + });` ) .then((r: string) => deserialize(r)) );