diff --git a/package-lock.json b/package-lock.json index 5b4d99f9..37b25abf 100644 --- a/package-lock.json +++ b/package-lock.json @@ -10,13 +10,13 @@ "license": "ISC", "dependencies": { "accounting": "^0.4.1", - "classnames": "^2.2.6", + "classnames": "^2.3.1", "dom-scroll-into-view": "^1.2.1", "flystyles": "^2.21.0", "focus-trap-react": "^6.0.0", "fuse.js": "^3.2.1", "moment": "^2.22.2", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "react-focus-lock": "^2.2.1" }, "devDependencies": { @@ -26,10 +26,10 @@ "@babel/preset-env": "^7.9.0", "@babel/preset-react": "^7.9.4", "@flywire/prettier-config": "^1.1.0", - "@testing-library/dom": "^8.11.3", - "@testing-library/jest-dom": "^5.16.2", + "@testing-library/dom": "^8.12.0", + "@testing-library/jest-dom": "^5.16.3", "@testing-library/react": "^12.1.4", - "@testing-library/user-event": "^13.5.0", + "@testing-library/user-event": "^14.0.0", "@wojtekmaj/enzyme-adapter-react-17": "^0.6.3", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "^8.2.3", @@ -107,9 +107,9 @@ } }, "node_modules/@babel/core": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.7.tgz", - "integrity": "sha512-djHlEfFHnSnTAcPb7dATbiM5HxGOP98+3JLBZtjRb5I7RXrw7kFRoG2dXM8cm3H+o11A8IFH/uprmJpwFynRNQ==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", + "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", "dev": true, "dependencies": { "@ampproject/remapping": "^2.1.0", @@ -117,8 +117,8 @@ "@babel/generator": "^7.17.7", "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.7", - "@babel/parser": "^7.17.7", + "@babel/helpers": "^7.17.8", + "@babel/parser": "^7.17.8", "@babel/template": "^7.16.7", "@babel/traverse": "^7.17.3", "@babel/types": "^7.17.0", @@ -289,9 +289,9 @@ } }, "node_modules/@babel/core/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -1259,9 +1259,9 @@ } }, "node_modules/@babel/helper-module-transforms/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -1907,9 +1907,9 @@ } }, "node_modules/@babel/helpers": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.7.tgz", - "integrity": "sha512-TKsj9NkjJfTBxM7Phfy7kv6yYc4ZcOo+AaWGqQOKTPDOmcGkIFb5xNA746eKisQkm4yavUYh4InYM9S+VnO01w==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", + "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", "dev": true, "dependencies": { "@babel/template": "^7.16.7", @@ -2073,9 +2073,9 @@ } }, "node_modules/@babel/helpers/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -2172,9 +2172,9 @@ } }, "node_modules/@babel/parser": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.7.tgz", - "integrity": "sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", + "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", "dev": true, "bin": { "parser": "bin/babel-parser.js" @@ -3484,13 +3484,14 @@ } }, "node_modules/@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "dependencies": { "camelcase": "^5.3.1", "find-up": "^4.1.0", + "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" }, @@ -3525,9 +3526,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "dependencies": { "argparse": "^1.0.7", @@ -3550,9 +3551,9 @@ } }, "node_modules/@istanbuljs/load-nyc-config/node_modules/p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "dependencies": { "p-try": "^2.0.0" @@ -3595,9 +3596,9 @@ } }, "node_modules/@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true, "engines": { "node": ">=8" @@ -4297,9 +4298,9 @@ } }, "node_modules/@testing-library/dom": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.3.tgz", - "integrity": "sha512-9LId28I+lx70wUiZjLvi1DB/WT2zGOxUh46glrSNMaWVx849kKAluezVzZrXJfTKKoQTmEOutLes/bHg4Bj3aA==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.12.0.tgz", + "integrity": "sha512-rBrJk5WjI02X1edtiUcZhgyhgBhiut96r5Jp8J5qktKdcvLcZpKDW8i2hkGMMItxrghjXuQ5AM6aE0imnFawaw==", "dev": true, "dependencies": { "@babel/code-frame": "^7.10.4", @@ -4483,9 +4484,9 @@ } }, "node_modules/@testing-library/jest-dom": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz", - "integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==", + "version": "5.16.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz", + "integrity": "sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA==", "dev": true, "dependencies": { "@babel/runtime": "^7.9.2", @@ -4627,15 +4628,12 @@ } }, "node_modules/@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.0.tgz", + "integrity": "sha512-hZhjNrle/DMi1ziHwHy8LS0fYJtf+cID7fuG5+4h+Bk83xQaRDQT/DlqfL4hJYw3mxW6KTIxoODrhGnhqJebdQ==", "dev": true, - "dependencies": { - "@babel/runtime": "^7.12.5" - }, "engines": { - "node": ">=10", + "node": ">=12", "npm": ">=6" }, "peerDependencies": { @@ -4658,9 +4656,9 @@ "dev": true }, "node_modules/@types/babel__core": { - "version": "7.1.18", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", - "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -4671,40 +4669,44 @@ } }, "node_modules/@types/babel__core/node_modules/@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "dependencies": { "@babel/types": "^7.0.0" } }, "node_modules/@types/babel__generator/node_modules/@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "dependencies": { "@babel/parser": "^7.1.0", @@ -4712,34 +4714,38 @@ } }, "node_modules/@types/babel__template/node_modules/@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@types/babel__traverse": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.9.tgz", - "integrity": "sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "dependencies": { "@babel/types": "^7.3.0" } }, "node_modules/@types/babel__traverse/node_modules/@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "dependencies": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" + }, + "engines": { + "node": ">=6.9.0" } }, "node_modules/@types/color-name": { @@ -4810,9 +4816,9 @@ "dev": true }, "node_modules/@types/react": { - "version": "17.0.40", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz", - "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==", + "version": "17.0.43", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.43.tgz", + "integrity": "sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==", "dev": true, "dependencies": { "@types/prop-types": "*", @@ -4821,9 +4827,9 @@ } }, "node_modules/@types/react-dom": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz", - "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==", + "version": "17.0.14", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz", + "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==", "dev": true, "dependencies": { "@types/react": "*" @@ -5260,9 +5266,9 @@ } }, "node_modules/agent-base/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -5528,9 +5534,6 @@ }, "engines": { "node": ">= 0.4" - }, - "funding": { - "url": "https://github.com/sponsors/ljharb" } }, "node_modules/asn1.js": { @@ -6705,14 +6708,20 @@ "dev": true }, "node_modules/caniuse-lite": { - "version": "1.0.30001317", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001317.tgz", - "integrity": "sha512-xIZLh8gBm4dqNX0gkzrBeyI86J2eCjWzYAs40q88smG844YIrN4tVQl/RhquHvKEKImWWFIVh1Lxe5n1G/N+GQ==", + "version": "1.0.30001322", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001322.tgz", + "integrity": "sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==", "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/browserslist" - } + "funding": [ + { + "type": "opencollective", + "url": "https://opencollective.com/browserslist" + }, + { + "type": "tidelift", + "url": "https://tidelift.com/funding/github/npm/caniuse-lite" + } + ] }, "node_modules/chalk": { "version": "1.1.3", @@ -6927,9 +6936,9 @@ } }, "node_modules/classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, "node_modules/cli-cursor": { "version": "2.1.0", @@ -8102,9 +8111,9 @@ "dev": true }, "node_modules/electron-to-chromium": { - "version": "1.4.86", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.86.tgz", - "integrity": "sha512-EVTZ+igi8x63pK4bPuA95PXIs2b2Cowi3WQwI9f9qManLiZJOD1Lash1J3W4TvvcUCcIR4o/rgi9o8UicXSO+w==", + "version": "1.4.100", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.100.tgz", + "integrity": "sha512-pNrSE2naf8fizl6/Uxq8UbKb8hU9EiYW4OzCYswosXoLV5NTMOUVKECNzDaHiUubsPq/kAckOzZd7zd8S8CHVw==", "dev": true }, "node_modules/elliptic": { @@ -10101,6 +10110,15 @@ "url": "https://github.com/sponsors/ljharb" } }, + "node_modules/get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true, + "engines": { + "node": ">=8.0.0" + } + }, "node_modules/get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", @@ -10532,9 +10550,9 @@ } }, "node_modules/http-proxy-agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -10643,9 +10661,9 @@ } }, "node_modules/https-proxy-agent/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -11760,9 +11778,9 @@ } }, "node_modules/istanbul-lib-source-maps/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -12726,8 +12744,7 @@ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "has-flag": "^3.0.0" }, "engines": { "node": ">=10" @@ -13281,6 +13298,10 @@ "resolved": "https://registry.npmjs.org/jest-regex-util/-/jest-regex-util-27.5.1.tgz", "integrity": "sha512-4bfKq2zie+x16okqDXjXn9ql2B0dScQu+vcwe4TvFVhkVyuWLqpZrZtXxLLWoXYgn0E87I6r6GRYHF7wFZBUvg==", "dev": true, + "dependencies": { + "@types/node": "*", + "graceful-fs": "^4.2.9" + }, "engines": { "node": "^10.13.0 || ^12.13.0 || ^14.15.0 || >=15.0.0" } @@ -13329,10 +13350,7 @@ "color-convert": "^2.0.1" }, "engines": { - "node": ">=8" - }, - "funding": { - "url": "https://github.com/chalk/ansi-styles?sponsor=1" + "node": ">=6.9.0" } }, "node_modules/jest-resolve/node_modules/chalk": { @@ -13341,8 +13359,9 @@ "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" + "@babel/helper-get-function-arity": "^7.16.7", + "@babel/template": "^7.16.7", + "@babel/types": "^7.16.7" }, "engines": { "node": ">=10" @@ -13357,10 +13376,10 @@ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "@babel/types": "^7.16.7" }, "engines": { - "node": ">=7.0.0" + "node": ">=6.9.0" } }, "node_modules/jest-resolve/node_modules/has-flag": { @@ -13368,8 +13387,11 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "dependencies": { + "@babel/types": "^7.16.7" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, "node_modules/jest-resolve/node_modules/supports-color": { @@ -13378,10 +13400,10 @@ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "color-convert": "^1.9.0" }, "engines": { - "node": ">=8" + "node": ">=4" } }, "node_modules/jest-runner": { @@ -13436,10 +13458,6 @@ "resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.2.tgz", "integrity": "sha512-oKnbhFyRIXpUuez8iBMmyEa4nbj4IOQyuhc/wy9kY7/WVPcwIO9VA668Pu8RkO7+0G76SLROeyw9CpQ061i4mA==", "dev": true, - "dependencies": { - "ansi-styles": "^4.1.0", - "supports-color": "^7.1.0" - }, "engines": { "node": ">=10" }, @@ -13453,10 +13471,10 @@ "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", "dev": true, "dependencies": { - "color-name": "~1.1.4" + "has-flag": "^3.0.0" }, "engines": { - "node": ">=7.0.0" + "node": ">=4" } }, "node_modules/jest-runner/node_modules/has-flag": { @@ -13464,8 +13482,13 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz", "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true, + "dependencies": { + "@babel/code-frame": "^7.16.7", + "@babel/parser": "^7.16.7", + "@babel/types": "^7.16.7" + }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, "node_modules/jest-runner/node_modules/supports-color": { @@ -13474,10 +13497,19 @@ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "@babel/code-frame": "^7.16.7", + "@babel/generator": "^7.17.3", + "@babel/helper-environment-visitor": "^7.16.7", + "@babel/helper-function-name": "^7.16.7", + "@babel/helper-hoist-variables": "^7.16.7", + "@babel/helper-split-export-declaration": "^7.16.7", + "@babel/parser": "^7.17.3", + "@babel/types": "^7.17.0", + "debug": "^4.1.0", + "globals": "^11.1.0" }, "engines": { - "node": ">=8" + "node": ">=6.9.0" } }, "node_modules/jest-runtime": { @@ -13707,7 +13739,7 @@ "integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==", "dev": true, "dependencies": { - "has-flag": "^4.0.0" + "ms": "2.1.2" }, "engines": { "node": ">=8" @@ -13796,8 +13828,10 @@ "jsesc": "^2.5.1", "source-map": "^0.5.0" }, - "engines": { - "node": ">=6.9.0" + "peerDependenciesMeta": { + "supports-color": { + "optional": true + } } }, "node_modules/jest-snapshot/node_modules/@babel/helper-function-name": { @@ -13849,7 +13883,7 @@ "js-tokens": "^4.0.0" }, "engines": { - "node": ">=6.9.0" + "node": ">=8" } }, "node_modules/jest-snapshot/node_modules/@babel/highlight/node_modules/ansi-styles": { @@ -13870,9 +13904,7 @@ "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" + "yallist": "^4.0.0" }, "engines": { "node": ">=4" @@ -13898,8 +13930,14 @@ "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", "integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=", "dev": true, + "dependencies": { + "lru-cache": "^6.0.0" + }, + "bin": { + "semver": "bin/semver.js" + }, "engines": { - "node": ">=4" + "node": ">=10" } }, "node_modules/jest-snapshot/node_modules/@babel/highlight/node_modules/supports-color": { @@ -13908,10 +13946,10 @@ "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", "dev": true, "dependencies": { - "has-flag": "^3.0.0" + "has-flag": "^4.0.0" }, "engines": { - "node": ">=4" + "node": ">=8" } }, "node_modules/jest-snapshot/node_modules/@babel/template": { @@ -14006,9 +14044,9 @@ } }, "node_modules/jest-snapshot/node_modules/debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "dependencies": { "ms": "2.1.2" @@ -15263,12 +15301,12 @@ } }, "node_modules/makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "dependencies": { - "tmpl": "1.0.x" + "tmpl": "1.0.5" } }, "node_modules/mamacro": { @@ -15518,13 +15556,13 @@ } }, "node_modules/micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "dependencies": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "engines": { "node": ">=8.6" @@ -17430,13 +17468,13 @@ } }, "node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "dependencies": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "react-is": "^16.13.1" } }, "node_modules/prop-types/node_modules/loose-envify": { @@ -17731,31 +17769,10 @@ "react": "^16.8.0" } }, - "node_modules/react-focus-lock/node_modules/loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "dependencies": { - "js-tokens": "^3.0.0 || ^4.0.0" - }, - "bin": { - "loose-envify": "cli.js" - } - }, - "node_modules/react-focus-lock/node_modules/prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "dependencies": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - }, "node_modules/react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "node_modules/react-router": { "version": "4.3.1", @@ -18895,6 +18912,9 @@ "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-2.0.0.tgz", "integrity": "sha512-UpzcLCXolUWcNu5HtVMHYdXJjArjsF9C0aNnquZYY4uW/Vu0miy5YoWvbV345HauVvcAUnpRuhMMcqTcGOY2+w==", "dev": true, + "dependencies": { + "escape-string-regexp": "^2.0.0" + }, "engines": { "node": ">=8" } @@ -19529,9 +19549,9 @@ } }, "node_modules/tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "node_modules/to-arraybuffer": { @@ -20201,12 +20221,12 @@ } }, "node_modules/walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "dependencies": { - "makeerror": "1.0.x" + "makeerror": "1.0.12" } }, "node_modules/warning": { @@ -21116,9 +21136,9 @@ "dev": true }, "@babel/core": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.7.tgz", - "integrity": "sha512-djHlEfFHnSnTAcPb7dATbiM5HxGOP98+3JLBZtjRb5I7RXrw7kFRoG2dXM8cm3H+o11A8IFH/uprmJpwFynRNQ==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/core/-/core-7.17.8.tgz", + "integrity": "sha512-OdQDV/7cRBtJHLSOBqqbYNkOcydOgnX59TZx4puf41fzcVtN3e/4yqY8lMQsK+5X2lJtAdmA+6OHqsj1hBJ4IQ==", "dev": true, "requires": { "@ampproject/remapping": "^2.1.0", @@ -21126,8 +21146,8 @@ "@babel/generator": "^7.17.7", "@babel/helper-compilation-targets": "^7.17.7", "@babel/helper-module-transforms": "^7.17.7", - "@babel/helpers": "^7.17.7", - "@babel/parser": "^7.17.7", + "@babel/helpers": "^7.17.8", + "@babel/parser": "^7.17.8", "@babel/template": "^7.16.7", "@babel/traverse": "^7.17.3", "@babel/types": "^7.17.0", @@ -21258,9 +21278,9 @@ } }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -21744,6 +21764,27 @@ } } }, + "@babel/helper-environment-visitor": { + "version": "7.16.7", + "resolved": "https://registry.npmjs.org/@babel/helper-environment-visitor/-/helper-environment-visitor-7.16.7.tgz", + "integrity": "sha512-SLLb0AAn6PkUeAfKJCCOl9e1R53pQlGAfc4y4XuMRZfqeMYLE0dM1LMhqbGAlGQY0lfw5/ohoYWAe9V1yibRag==", + "dev": true, + "requires": { + "@babel/types": "^7.16.7" + }, + "dependencies": { + "@babel/types": { + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.16.7", + "to-fast-properties": "^2.0.0" + } + } + } + }, "@babel/helper-explode-assignable-expression": { "version": "7.8.3", "resolved": "https://registry.npmjs.org/@babel/helper-explode-assignable-expression/-/helper-explode-assignable-expression-7.8.3.tgz", @@ -22126,9 +22167,9 @@ } }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -22730,9 +22771,9 @@ } }, "@babel/helpers": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.7.tgz", - "integrity": "sha512-TKsj9NkjJfTBxM7Phfy7kv6yYc4ZcOo+AaWGqQOKTPDOmcGkIFb5xNA746eKisQkm4yavUYh4InYM9S+VnO01w==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/helpers/-/helpers-7.17.8.tgz", + "integrity": "sha512-QcL86FGxpfSJwGtAvv4iG93UL6bmqBdmoVY0CMCU2g+oD2ezQse3PT5Pa+jiD6LJndBQi0EDlpzOWNlLuhz5gw==", "dev": true, "requires": { "@babel/template": "^7.16.7", @@ -22860,9 +22901,9 @@ } }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -22940,9 +22981,9 @@ } }, "@babel/parser": { - "version": "7.17.7", - "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.7.tgz", - "integrity": "sha512-bm3AQf45vR4gKggRfvJdYJ0gFLoCbsPxiFLSH6hTVYABptNHY6l9NrhnucVjQ/X+SPtLANT9lc0fFhikj+VBRA==", + "version": "7.17.8", + "resolved": "https://registry.npmjs.org/@babel/parser/-/parser-7.17.8.tgz", + "integrity": "sha512-BoHhDJrJXqcg+ZL16Xv39H9n+AqJ4pcDrQBGZN+wHxIysrLZ3/ECwCBUch/1zUNhnsXULcONU3Ei5Hmkfk6kiQ==", "dev": true }, "@babel/plugin-proposal-async-generator-functions": { @@ -24019,13 +24060,14 @@ "requires": {} }, "@istanbuljs/load-nyc-config": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.0.0.tgz", - "integrity": "sha512-ZR0rq/f/E4f4XcgnDvtMWXCUJpi8eO0rssVhmztsZqLIEFA9UUP9zmpE0VxlM+kv/E1ul2I876Fwil2ayptDVg==", + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", + "integrity": "sha512-VjeHSlIzpv/NyD3N0YuHfXOPDIixcA1q2ZV98wsMqcYlPmv2n3Yb2lYP9XMElnaFVXg5A7YLTeLu6V84uQDjmQ==", "dev": true, "requires": { "camelcase": "^5.3.1", "find-up": "^4.1.0", + "get-package-type": "^0.1.0", "js-yaml": "^3.13.1", "resolve-from": "^5.0.0" }, @@ -24047,9 +24089,9 @@ } }, "js-yaml": { - "version": "3.13.1", - "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz", - "integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==", + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", "dev": true, "requires": { "argparse": "^1.0.7", @@ -24066,9 +24108,9 @@ } }, "p-limit": { - "version": "2.2.2", - "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.2.2.tgz", - "integrity": "sha512-WGR+xHecKTr7EbUEhyLSh5Dube9JtdiG78ufaeLxTgpudf/20KqyMioIUZJAezlTIi6evxuoUs9YXc11cU+yzQ==", + "version": "2.3.0", + "resolved": "https://registry.npmjs.org/p-limit/-/p-limit-2.3.0.tgz", + "integrity": "sha512-//88mFWSJx8lxCzwdAABTJL2MyWB12+eIY7MDL2SqLmAkeKU9qxRvWuSyTjm3FUmpBEMuFfckAIqEaVGUDxb6w==", "dev": true, "requires": { "p-try": "^2.0.0" @@ -24098,9 +24140,9 @@ } }, "@istanbuljs/schema": { - "version": "0.1.2", - "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.2.tgz", - "integrity": "sha512-tsAQNx32a8CoFhjhijUIhI4kccIAgmGhy8LZMZgGfmXcpMbPRUqn5LWmgRttILi6yeGmBJd2xsPkFMs0PzgPCw==", + "version": "0.1.3", + "resolved": "https://registry.npmjs.org/@istanbuljs/schema/-/schema-0.1.3.tgz", + "integrity": "sha512-ZXRY4jNvVgSVQ8DL3LTcakaAtXwTVUxE81hslsyD2AtoXW/wVob10HkOJ1X/pAlcI7D+2YoZKg5do8G/w6RYgA==", "dev": true }, "@jest/console": { @@ -24619,9 +24661,9 @@ } }, "@testing-library/dom": { - "version": "8.11.3", - "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.11.3.tgz", - "integrity": "sha512-9LId28I+lx70wUiZjLvi1DB/WT2zGOxUh46glrSNMaWVx849kKAluezVzZrXJfTKKoQTmEOutLes/bHg4Bj3aA==", + "version": "8.12.0", + "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.12.0.tgz", + "integrity": "sha512-rBrJk5WjI02X1edtiUcZhgyhgBhiut96r5Jp8J5qktKdcvLcZpKDW8i2hkGMMItxrghjXuQ5AM6aE0imnFawaw==", "dev": true, "requires": { "@babel/code-frame": "^7.10.4", @@ -24764,9 +24806,9 @@ } }, "@testing-library/jest-dom": { - "version": "5.16.2", - "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.2.tgz", - "integrity": "sha512-6ewxs1MXWwsBFZXIk4nKKskWANelkdUehchEOokHsN8X7c2eKXGw+77aRV63UU8f/DTSVUPLaGxdrj4lN7D/ug==", + "version": "5.16.3", + "resolved": "https://registry.npmjs.org/@testing-library/jest-dom/-/jest-dom-5.16.3.tgz", + "integrity": "sha512-u5DfKj4wfSt6akfndfu1eG06jsdyA/IUrlX2n3pyq5UXgXMhXY+NJb8eNK/7pqPWAhCKsCGWDdDO0zKMKAYkEA==", "dev": true, "requires": { "@babel/runtime": "^7.9.2", @@ -24868,13 +24910,11 @@ } }, "@testing-library/user-event": { - "version": "13.5.0", - "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-13.5.0.tgz", - "integrity": "sha512-5Kwtbo3Y/NowpkbRuSepbyMFkZmHgD+vPzYB/RJ4oxt5Gj/avFFBYjhw27cqSVPVw/3a67NK1PbiIr9k4Gwmdg==", + "version": "14.0.0", + "resolved": "https://registry.npmjs.org/@testing-library/user-event/-/user-event-14.0.0.tgz", + "integrity": "sha512-hZhjNrle/DMi1ziHwHy8LS0fYJtf+cID7fuG5+4h+Bk83xQaRDQT/DlqfL4hJYw3mxW6KTIxoODrhGnhqJebdQ==", "dev": true, - "requires": { - "@babel/runtime": "^7.12.5" - } + "requires": {} }, "@tootallnate/once": { "version": "1.1.2", @@ -24889,9 +24929,9 @@ "dev": true }, "@types/babel__core": { - "version": "7.1.18", - "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.18.tgz", - "integrity": "sha512-S7unDjm/C7z2A2R9NzfKCK1I+BAALDtxEmsJBwlB3EzNfb929ykjL++1CK9LO++EIp2fQrC8O+BwjKvz6UeDyQ==", + "version": "7.1.19", + "resolved": "https://registry.npmjs.org/@types/babel__core/-/babel__core-7.1.19.tgz", + "integrity": "sha512-WEOTgRsbYkvA/KCsDwVEGkd7WAr1e3g31VHQ8zy5gul/V1qKullU/BU5I68X5v7V3GnB9eotmom4v5a5gjxorw==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -24902,44 +24942,42 @@ }, "dependencies": { "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } } } }, "@types/babel__generator": { - "version": "7.6.1", - "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.1.tgz", - "integrity": "sha512-bBKm+2VPJcMRVwNhxKu8W+5/zT7pwNEqeokFOmbvVSqGzFneNxYcEBro9Ac7/N9tlsaPYnZLK8J1LWKkMsLAew==", + "version": "7.6.4", + "resolved": "https://registry.npmjs.org/@types/babel__generator/-/babel__generator-7.6.4.tgz", + "integrity": "sha512-tFkciB9j2K755yrTALxD44McOrk+gfpIpvC3sxHjRawj6PfnQxrse4Clq5y/Rq+G3mrBurMax/lG8Qn2t9mSsg==", "dev": true, "requires": { "@babel/types": "^7.0.0" }, "dependencies": { "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } } } }, "@types/babel__template": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.0.2.tgz", - "integrity": "sha512-/K6zCpeW7Imzgab2bLkLEbz0+1JlFSrUMdw7KoIIu+IUdu51GWaBZpd3y1VXGVXzynvGa4DaIaxNZHiON3GXUg==", + "version": "7.4.1", + "resolved": "https://registry.npmjs.org/@types/babel__template/-/babel__template-7.4.1.tgz", + "integrity": "sha512-azBFKemX6kMg5Io+/rdGT0dkGreboUVR0Cdm3fz9QJWpaQGJRQXl7C+6hOTCZcMll7KFyEQpgbYI2lHdsS4U7g==", "dev": true, "requires": { "@babel/parser": "^7.1.0", @@ -24947,35 +24985,33 @@ }, "dependencies": { "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } } } }, "@types/babel__traverse": { - "version": "7.0.9", - "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.0.9.tgz", - "integrity": "sha512-jEFQ8L1tuvPjOI8lnpaf73oCJe+aoxL6ygqSy6c8LcW98zaC+4mzWuQIRCEvKeCOu+lbqdXcg4Uqmm1S8AP1tw==", + "version": "7.14.2", + "resolved": "https://registry.npmjs.org/@types/babel__traverse/-/babel__traverse-7.14.2.tgz", + "integrity": "sha512-K2waXdXBi2302XUdcHcR1jCeU0LL4TD9HRs/gk0N2Xvrht+G/BfJa4QObBQZfhMdxiCpV3COl5Nfq4uKTeTnJA==", "dev": true, "requires": { "@babel/types": "^7.3.0" }, "dependencies": { "@babel/types": { - "version": "7.9.0", - "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.9.0.tgz", - "integrity": "sha512-BS9JKfXkzzJl8RluW4JGknzpiUV7ZrvTayM6yfqLTVBEnFtyowVIOu6rqxRd5cVO6yGoWf4T8u8dgK9oB+GCng==", + "version": "7.17.0", + "resolved": "https://registry.npmjs.org/@babel/types/-/types-7.17.0.tgz", + "integrity": "sha512-TmKSNO4D5rzhL5bjWFcVHHLETzfQ/AmbKpKPOSjlP0WoHZ6L911fgoOKY4Alp/emzG4cHJdyN49zpgkbXFEHHw==", "dev": true, "requires": { - "@babel/helper-validator-identifier": "^7.9.0", - "lodash": "^4.17.13", + "@babel/helper-validator-identifier": "^7.16.7", "to-fast-properties": "^2.0.0" } } @@ -25049,9 +25085,9 @@ "dev": true }, "@types/react": { - "version": "17.0.40", - "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.40.tgz", - "integrity": "sha512-UrXhD/JyLH+W70nNSufXqMZNuUD2cXHu6UjCllC6pmOQgBX4SGXOH8fjRka0O0Ee0HrFxapDD8Bwn81Kmiz6jQ==", + "version": "17.0.43", + "resolved": "https://registry.npmjs.org/@types/react/-/react-17.0.43.tgz", + "integrity": "sha512-8Q+LNpdxf057brvPu1lMtC5Vn7J119xrP1aq4qiaefNioQUYANF/CYeK4NsKorSZyUGJ66g0IM+4bbjwx45o2A==", "dev": true, "requires": { "@types/prop-types": "*", @@ -25060,9 +25096,9 @@ } }, "@types/react-dom": { - "version": "17.0.13", - "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.13.tgz", - "integrity": "sha512-wEP+B8hzvy6ORDv1QBhcQia4j6ea4SFIBttHYpXKPFZRviBvknq0FRh3VrIxeXUmsPkwuXVZrVGG7KUVONmXCQ==", + "version": "17.0.14", + "resolved": "https://registry.npmjs.org/@types/react-dom/-/react-dom-17.0.14.tgz", + "integrity": "sha512-H03xwEP1oXmSfl3iobtmQ/2dHF5aBHr8aUMwyGZya6OW45G+xtdzmq6HkncefiBt5JU8DVyaWl/nWZbjZCnzAQ==", "dev": true, "requires": { "@types/react": "*" @@ -25481,9 +25517,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -25688,7 +25724,8 @@ "requires": { "call-bind": "^1.0.2", "define-properties": "^1.1.3", - "es-abstract": "^1.19.0" + "es-abstract": "^1.15.0", + "function-bind": "^1.1.1" } }, "asn1.js": { @@ -26652,9 +26689,9 @@ "dev": true }, "caniuse-lite": { - "version": "1.0.30001317", - "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001317.tgz", - "integrity": "sha512-xIZLh8gBm4dqNX0gkzrBeyI86J2eCjWzYAs40q88smG844YIrN4tVQl/RhquHvKEKImWWFIVh1Lxe5n1G/N+GQ==", + "version": "1.0.30001322", + "resolved": "https://registry.npmjs.org/caniuse-lite/-/caniuse-lite-1.0.30001322.tgz", + "integrity": "sha512-neRmrmIrCGuMnxGSoh+x7zYtQFFgnSY2jaomjU56sCkTA6JINqQrxutF459JpWcWRajvoyn95sOXq4Pqrnyjew==", "dev": true }, "chalk": { @@ -26835,9 +26872,9 @@ } }, "classnames": { - "version": "2.2.6", - "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.2.6.tgz", - "integrity": "sha512-JR/iSQOSt+LQIWwrwEzJ9uk0xfN3mTVYMwt1Ir5mUcSN6pU+V4zQFFaJsclJbPuAUQH+yfWef6tm7l1quW3C8Q==" + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/classnames/-/classnames-2.3.1.tgz", + "integrity": "sha512-OlQdbZ7gLfGarSqxesMesDa5uz7KFbID8Kpq/SxIoNGDqY8lSYs0D+hhtBXhcdB3rcbXArFr7vlHheLk1voeNA==" }, "cli-cursor": { "version": "2.1.0", @@ -27834,9 +27871,9 @@ "dev": true }, "electron-to-chromium": { - "version": "1.4.86", - "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.86.tgz", - "integrity": "sha512-EVTZ+igi8x63pK4bPuA95PXIs2b2Cowi3WQwI9f9qManLiZJOD1Lash1J3W4TvvcUCcIR4o/rgi9o8UicXSO+w==", + "version": "1.4.100", + "resolved": "https://registry.npmjs.org/electron-to-chromium/-/electron-to-chromium-1.4.100.tgz", + "integrity": "sha512-pNrSE2naf8fizl6/Uxq8UbKb8hU9EiYW4OzCYswosXoLV5NTMOUVKECNzDaHiUubsPq/kAckOzZd7zd8S8CHVw==", "dev": true }, "elliptic": { @@ -29422,6 +29459,12 @@ "has-symbols": "^1.0.1" } }, + "get-package-type": { + "version": "0.1.0", + "resolved": "https://registry.npmjs.org/get-package-type/-/get-package-type-0.1.0.tgz", + "integrity": "sha512-pjzuKtY64GYfWizNAJ0fr9VqttZkNiK2iS430LtIHzjBEr6bX8Am2zm4sW4Ro5wjWW5cAlRL1qAMTcXbjNAO2Q==", + "dev": true + }, "get-stdin": { "version": "6.0.0", "resolved": "https://registry.npmjs.org/get-stdin/-/get-stdin-6.0.0.tgz", @@ -29775,9 +29818,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -29864,9 +29907,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -30699,9 +30742,9 @@ }, "dependencies": { "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -32437,9 +32480,9 @@ } }, "debug": { - "version": "4.3.3", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.3.tgz", - "integrity": "sha512-/zxw5+vh1Tfv+4Qn7a5nsbcJKPaSvCDhojn6FEl9vupwK2VCSDtEiEtqr8DFtzYFOdz63LBkxec7DYuc2jon6Q==", + "version": "4.3.4", + "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.4.tgz", + "integrity": "sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==", "dev": true, "requires": { "ms": "2.1.2" @@ -33296,12 +33339,12 @@ } }, "makeerror": { - "version": "1.0.11", - "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.11.tgz", - "integrity": "sha1-4BpckQnyr3lmDk6LlYd5AYT1qWw=", + "version": "1.0.12", + "resolved": "https://registry.npmjs.org/makeerror/-/makeerror-1.0.12.tgz", + "integrity": "sha512-JmqCvUhmt43madlpFzG4BQzG2Z3m6tvQDNKdClZnO3VbIudJYmxsT0FNJMeiB2+JTSlTQTSbU8QdesVmwJcmLg==", "dev": true, "requires": { - "tmpl": "1.0.x" + "tmpl": "1.0.5" } }, "mamacro": { @@ -33502,13 +33545,13 @@ "dev": true }, "micromatch": { - "version": "4.0.4", - "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.4.tgz", - "integrity": "sha512-pRmzw/XUcwXGpD9aI9q/0XOwLNygjETJ8y0ao0wdqprrzDa4YnxLcz7fQRZr8voh8V10kGhABbNcHVk5wHgWwg==", + "version": "4.0.5", + "resolved": "https://registry.npmjs.org/micromatch/-/micromatch-4.0.5.tgz", + "integrity": "sha512-DMy+ERcEW2q8Z2Po+WNXuw3c5YaUSFjAO5GsJqfEl7UjvtIuFKO6ZrKvcItdy98dwFI2N1tg3zNIdKaQT+aNdA==", "dev": true, "requires": { - "braces": "^3.0.1", - "picomatch": "^2.2.3" + "braces": "^3.0.2", + "picomatch": "^2.3.1" }, "dependencies": { "braces": { @@ -35089,13 +35132,13 @@ } }, "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", + "version": "15.8.1", + "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.8.1.tgz", + "integrity": "sha512-oj87CgZICdulUohogVAR7AjlC0327U4el4L6eAvOqCeudMDVU0NThNaV+b9Df4dXgSP1gXMTnPdhfe/2qDH5cg==", "requires": { "loose-envify": "^1.4.0", "object-assign": "^4.1.1", - "react-is": "^16.8.1" + "react-is": "^16.13.1" }, "dependencies": { "loose-envify": { @@ -35342,32 +35385,12 @@ "react-clientside-effect": "^1.2.2", "use-callback-ref": "^1.2.1", "use-sidecar": "^1.0.1" - }, - "dependencies": { - "loose-envify": { - "version": "1.4.0", - "resolved": "https://registry.npmjs.org/loose-envify/-/loose-envify-1.4.0.tgz", - "integrity": "sha512-lyuxPGr/Wfhrlem2CL/UcnUc1zcqKAImBDzukY7Y5F/yQiNdko6+fRLevlw1HgMySw7f611UIY408EtxRSoK3Q==", - "requires": { - "js-tokens": "^3.0.0 || ^4.0.0" - } - }, - "prop-types": { - "version": "15.7.2", - "resolved": "https://registry.npmjs.org/prop-types/-/prop-types-15.7.2.tgz", - "integrity": "sha512-8QQikdH7//R2vurIJSutZ1smHYTcLpRWEOlHnzcWHmBYrOGUysKwSsrC89BCiFj3CbrfJ/nXFdJepOVrY1GCHQ==", - "requires": { - "loose-envify": "^1.4.0", - "object-assign": "^4.1.1", - "react-is": "^16.8.1" - } - } } }, "react-is": { - "version": "16.12.0", - "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.12.0.tgz", - "integrity": "sha512-rPCkf/mWBtKc97aLL9/txD8DZdemK0vkA3JMLShjlJB3Pj3s+lpf1KaBzMfQrAmhMQB0n1cU/SUGgKKBCe837Q==" + "version": "16.13.1", + "resolved": "https://registry.npmjs.org/react-is/-/react-is-16.13.1.tgz", + "integrity": "sha512-24e6ynE2H+OKt4kqsOvNd8kBpV65zoxbA4BVsEOB3ARVWQki/DHzaUoC5KuON/BiccDaCCTZBuOcfZs70kR8bQ==" }, "react-router": { "version": "4.3.1", @@ -36846,9 +36869,9 @@ } }, "tmpl": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.4.tgz", - "integrity": "sha1-I2QN17QtAEM5ERQIIOXPRA5SHdE=", + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/tmpl/-/tmpl-1.0.5.tgz", + "integrity": "sha512-3f0uOEAQwIqGuWW2MVzYg8fV/QNnc/IpuJNG837rLuczAaLVHslWHZQj4IGiEl5Hs3kkbhwL9Ab7Hrsmuj+Smw==", "dev": true }, "to-arraybuffer": { @@ -37393,12 +37416,12 @@ } }, "walker": { - "version": "1.0.7", - "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.7.tgz", - "integrity": "sha1-L3+bj9ENZ3JisYqITijRlhjgKPs=", + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/walker/-/walker-1.0.8.tgz", + "integrity": "sha512-ts/8E8l5b7kY0vlWLewOkDXMmPdLcVV4GmOQLyxuSswIJsweeFZtAsMF7k1Nszz+TYBQrlYRmzOnr398y1JemQ==", "dev": true, "requires": { - "makeerror": "1.0.x" + "makeerror": "1.0.12" } }, "warning": { diff --git a/package.json b/package.json index 585737a5..3ddf8e98 100644 --- a/package.json +++ b/package.json @@ -30,13 +30,13 @@ "homepage": "https://github.com/peertransfer/flycomponents#readme", "dependencies": { "accounting": "^0.4.1", - "classnames": "^2.2.6", + "classnames": "^2.3.1", "dom-scroll-into-view": "^1.2.1", "flystyles": "^2.21.0", "focus-trap-react": "^6.0.0", "fuse.js": "^3.2.1", "moment": "^2.22.2", - "prop-types": "^15.7.2", + "prop-types": "^15.8.1", "react-focus-lock": "^2.2.1" }, "peerDependencies": { @@ -50,10 +50,10 @@ "@babel/preset-env": "^7.9.0", "@babel/preset-react": "^7.9.4", "@flywire/prettier-config": "^1.1.0", - "@testing-library/dom": "^8.11.3", - "@testing-library/jest-dom": "^5.16.2", + "@testing-library/dom": "^8.12.0", + "@testing-library/jest-dom": "^5.16.3", "@testing-library/react": "^12.1.4", - "@testing-library/user-event": "^13.5.0", + "@testing-library/user-event": "^14.0.0", "@wojtekmaj/enzyme-adapter-react-17": "^0.6.3", "babel-core": "^7.0.0-bridge.0", "babel-eslint": "^8.2.3", diff --git a/src/CardForm/CVVInput/CVVInput.test.js b/src/CardForm/CVVInput/CVVInput.test.js index e909956d..4e2d8760 100644 --- a/src/CardForm/CVVInput/CVVInput.test.js +++ b/src/CardForm/CVVInput/CVVInput.test.js @@ -1,49 +1,51 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { fireEvent, render, screen } from '@testing-library/react'; import CVVInput from './CVVInput'; -import TextInput from '../TextInput'; -import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; describe('CVVInput', () => { + userEvent.setup(); + describe('renders', () => { test('a TextInput with all the passed props', () => { - const props = { name: 'a_name', propA: 'propA', propB: 'propB' }; - const wrapper = shallow(); + const props = { name: 'a_name', prop_a: 'propA', prop_b: 'propB' }; + const { getByRole } = render(); - const textInput = wrapper.find(TextInput); + const input = getByRole('textbox'); - expect(textInput.props()).toEqual(expect.objectContaining(props)); + expect(input).toHaveAttribute('name', 'a_name'); + expect(input).toHaveAttribute('prop_a', 'propA'); + expect(input).toHaveAttribute('prop_b', 'propB'); }); test('a TextInput with the provided className', () => { const props = { name: 'a_name', className: 'a_className' }; - const wrapper = shallow(); - - const textInput = wrapper.find(TextInput); + const { container } = render(); - expect(textInput.hasClass('a_className')).toEqual(true); + expect(container.firstChild.classList.contains('a_className')).toBe(true); }); test('a span with the question logo', () => { const props = { name: 'a_name' }; - const wrapper = shallow(); + const { container } = render(); - expect(wrapper.find('#cvvInput-Label-Tooltip')).toHaveLength(1); + expect( + container.firstChild.children[2].className.includes( + 'cvvInput-Label-Tooltip' + ) + ).toBe(true); }); test('a span with the provided message', () => { const cvvTooltip = 'a_cvvTooltip'; const props = { name: 'a_name', cvvTooltip }; - const wrapper = shallow(); + render(); - expect(wrapper.find('#cvvInput-Label-Tooltip').text()).toEqual( - cvvTooltip - ); + expect(screen.queryByText(cvvTooltip)).toBeInTheDocument(); }); }); - it('handles on focus events with its name', () => { + it('handles on focus events with its name', async () => { const onFocus = jest.fn(); const props = { label: 'CVV', @@ -54,18 +56,18 @@ describe('CVVInput', () => { render(); - userEvent.tab(); + await userEvent.tab(); expect(onFocus).toHaveBeenCalledWith('cvv_field_name'); }); describe('format', () => { - test('when no format prop given defaults to 3/4 digits only', () => { + test('when no format prop given defaults to 3/4 digits only', async () => { const props = { label: 'CVV', name: 'cvv_field_name' }; render(); const input = screen.getByRole('textbox', { name: 'CVV' }); - userEvent.type( + await userEvent.type( input, 'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ/.,> { expect(input).toHaveValue(''); }); - test('when format prop given set the format of the input ', () => { + test('when format prop given set the format of the input ', async () => { const props = { label: 'CVV', name: 'cvv_field_name', @@ -82,7 +84,7 @@ describe('CVVInput', () => { render(); const input = screen.getByRole('textbox', { name: 'CVV' }); - userEvent.type(input, 'abcde'); + await userEvent.type(input, 'abcde'); expect(input).toHaveValue('abcde'); }); @@ -90,16 +92,22 @@ describe('CVVInput', () => { describe('tooltip', () => { test('shows the tooltip while the input is focused', () => { - const wrapper = shallow(); - const textInput = wrapper.find(TextInput); - - wrapper.find('#cvvInput-Label-Tooltip').hasClass('opacity-0'); - - textInput.simulate('focus'); - wrapper.find('#cvvInput-Label-Tooltip').hasClass('opacity-1'); - - textInput.simulate('blur'); - wrapper.find('#cvvInput-Label-Tooltip').hasClass('opacity-0'); + const { container, getByRole } = render(); + const input = getByRole('textbox'); + + expect( + container.firstChild.children[2].className.includes('opacity-0') + ).toBe(true); + + fireEvent.focus(input); + expect( + container.firstChild.children[2].className.includes('opacity-1') + ).toBe(true); + + fireEvent.blur(input); + expect( + container.firstChild.children[2].className.includes('opacity-0') + ).toBe(true); }); }); }); diff --git a/src/CardForm/CardForm.test.js b/src/CardForm/CardForm.test.js index bd19f387..6b32065e 100644 --- a/src/CardForm/CardForm.test.js +++ b/src/CardForm/CardForm.test.js @@ -1,86 +1,84 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { screen, fireEvent, render } from '@testing-library/react'; import CardForm from './CardForm'; -import Button from '../Button'; describe('CardForm', () => { test('renders a form', () => { - const wrapper = shallow(); + const { getByText } = render(); - expect(wrapper.find('form')).toHaveLength(1); + expect(getByText('Submit')).toBeInTheDocument(); }); test('renders a compressed form', () => { - const wrapper = shallow(); + const { container } = render(); - expect(wrapper.find('form')).toHaveLength(1); - expect(wrapper.find('.CardForm-Input--Compressed')).toHaveLength(5); + expect( + container.getElementsByClassName('CardForm--Compressed').length + ).toBe(1); }); test('renders the passed children', () => { - const ChildrenComponent = () =>
; + const ChildrenComponent = () =>
; - const wrapper = shallow( + const { getByTestId } = render( ); - expect(wrapper.find(ChildrenComponent)).toHaveLength(1); + expect(getByTestId('children_component_id')).toBeInTheDocument(); }); describe('onFocus', () => { const inputs = [ - ['name'], - ['surname'], - ['cardNumber'], - ['expiryDate'], - ['cvv'] + ["Cardholder's name"], + ["Cardholder's surname"], + ['Card number'], + ['Expiry date (MM/YY)'], + ['CVV'] ]; - test.each(inputs)('removes the field errors from %s', name => { - const wrapper = shallow(); - const input = wrapper.find(`[name="${name}"]`); - input.simulate('blur', name, ''); + test.each(inputs)('removes the field errors from %s', label => { + const { getByLabelText } = render(); - input.simulate('focus', name); + const input = getByLabelText(label); + fireEvent.change(input, { target: { value: '' } }); + input.blur(); + input.focus(); - expect(wrapper.find(`[name="${name}"]`).prop('error')).toBeUndefined(); + const errorMessage = screen.queryByText('error'); + expect(errorMessage).toBeNull(); }); }); describe('validations', () => { /* eslint-disable */ describe.each` - fieldName | fieldValue | error - ${'name'} | ${'a_name'} | ${'invalid_name'} - ${'surname'} | ${'a_surname'} | ${'invalid_surname'} - ${'cardNumber'} | ${'4111111111111111'} | ${'invalid_card_number'} - ${'expiryDate'} | ${'12/99'} | ${'invalid_expiry_date'} - ${'cvv'} | ${'555'} | ${'invalid_cvv'} - `('$fieldName is required', ({ fieldName, fieldValue, error }) => { + fieldName | fieldLabel | fieldValue | error + ${'name'} | ${"Cardholder's name"} | ${'a_name'} | ${'invalid_name'} + ${'surname'} | ${"Cardholder's surname"} | ${'a_surname'} | ${'invalid_surname'} + ${'cardNumber'} | ${'Card number'} | ${'4111111111111111'} | ${'invalid_card_number'} + ${'expiryDate'} | ${'Expiry date (MM/YY)'} | ${'12/99'} | ${'invalid_expiry_date'} + ${'cvv'} | ${'CVV'} | ${'555'} | ${'invalid_cvv'} + `('$fieldName is required', ({ fieldName, fieldLabel, fieldValue, error }) => { const errors = { [fieldName]: error }; test('has an error when is empty', () => { - const wrapper = shallow(); + const { getByText, getByLabelText } = render(); - blurField(wrapper, fieldName, ''); + blurField(getByLabelText, fieldLabel, ''); - expect(wrapper.find(`[name="${fieldName}"]`).prop('error')).toEqual( - error - ); + expect(getByText(error)).toBeInTheDocument(); }); test('has no error when is not empty', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); - blurField(wrapper, fieldName, fieldValue); + blurField(getByLabelText, fieldLabel, fieldValue); - expect( - wrapper.find(`[name="${fieldName}"]`).prop('error') - ).toBeUndefined(); + expect(screen.queryByText(error)).toBeNull(); }); }); @@ -101,33 +99,28 @@ describe('CardForm', () => { }); test('has no error if is a valid future date', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); - blurField(wrapper, 'expiryDate', '12/30'); + blurField(getByLabelText, 'Expiry date (MM/YY)', '12/30'); + + expect(screen.queryByText('invalid_expiry_date')).toBeNull(); - expect( - wrapper.find(`[name="expiryDate"]`).prop('error') - ).toBeUndefined(); }); test('has error if is an invalid date', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); - blurField(wrapper, 'expiryDate', '12/'); + blurField(getByLabelText, 'Expiry date (MM/YY)', '12/'); - expect(wrapper.find(`[name="expiryDate"]`).prop('error')).toEqual( - 'invalid_expiry_date' - ); + expect(screen.queryByText('invalid_expiry_date')).toBeInTheDocument(); }); test('has error if is a past date', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); - blurField(wrapper, 'expiryDate', '12/12'); + blurField(getByLabelText, 'Expiry date (MM/YY)', '12/12'); - expect(wrapper.find(`[name="expiryDate"]`).prop('error')).toEqual( - 'invalid_expiry_date' - ); + expect(screen.queryByText('invalid_expiry_date')).toBeInTheDocument(); }); }); @@ -142,33 +135,27 @@ describe('CardForm', () => { const validAMEXCardNumber = '373968333653142'; test('has no error if is a valid accepted card', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); - blurField(wrapper, 'cardNumber', validVisaCardNumber); + blurField(getByLabelText, 'Card number', validVisaCardNumber); - expect( - wrapper.find(`[name="cardNumber"]`).prop('error') - ).toBeUndefined(); + expect(screen.queryByText('invalid_card_number')).not.toBeInTheDocument(); }); test('has error if has an invalid value', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); - blurField(wrapper, 'cardNumber', invalidCardNumber); + blurField(getByLabelText, 'Card number', invalidCardNumber); - expect(wrapper.find(`[name="cardNumber"]`).prop('error')).toBe( - 'invalid_card_number' - ); + expect(screen.queryByText('invalid_card_number')).toBeInTheDocument(); }); test('has error if has an unnacepted card type', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); - blurField(wrapper, 'cardNumber', validAMEXCardNumber); + blurField(getByLabelText, 'Card number', validAMEXCardNumber); - expect(wrapper.find(`[name="cardNumber"]`).prop('error')).toBe( - 'invalid_card_type' - ); + expect(screen.queryByText('invalid_card_type')).toBeInTheDocument(); }); }); @@ -177,38 +164,36 @@ describe('CardForm', () => { describe('when there is no card number', () => { test('has no error when the cvv is invalid', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); const invalidCvv = 1; - blurField(wrapper, 'cvv', invalidCvv); + blurField(getByLabelText, 'CVV', invalidCvv); - expect(wrapper.find(`[name="cvv"]`).prop('error')).toBeUndefined(); + expect(screen.queryByText('invalid_cvv')).not.toBeInTheDocument(); }); }); describe('when there is a card number', () => { test('has no error when the cvv is valid', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); const validCvv = 111; const validCardNumber = '4111111111111111'; - fillField(wrapper, 'cardNumber', validCardNumber); + fillField(getByLabelText, 'Card number', validCardNumber); - blurField(wrapper, 'cvv', validCvv); + blurField(getByLabelText, 'CVV', validCvv); - expect(wrapper.find(`[name="cvv"]`).prop('error')).toBeUndefined(); + expect(screen.queryByText('invalid_cvv')).not.toBeInTheDocument(); }); test('has error when the cvv is invalid', () => { - const wrapper = shallow(); + const { getByLabelText } = render(); const invalidCvv = 11; const validCardNumber = '4111111111111111'; - fillField(wrapper, 'cardNumber', validCardNumber); - blurField(wrapper, 'cvv', invalidCvv); + fillField(getByLabelText, 'Card number', validCardNumber); + blurField(getByLabelText, 'CVV', invalidCvv); - expect(wrapper.find(`[name="cvv"]`).prop('error')).toBe( - 'invalid_cvv' - ); + expect(screen.queryByText('invalid_cvv')).toBeInTheDocument(); }); }); }); @@ -220,24 +205,22 @@ describe('CardForm', () => { const onSubmit = jest.fn(); const formValues = { - name: 'a_name', - surname: 'a_surname', - cardNumber: '4111111111111111', + name: 'aname', + surname: 'asurname', + cardNumber: '4111-1111-1111-1111', expiryDate: '12/23', cvv: '555', cardType: 'VISA' }; - const wrapper = shallow( - - ); - fillField(wrapper, 'name', formValues.name); - fillField(wrapper, 'surname', formValues.surname); - fillField(wrapper, 'cardNumber', formValues.cardNumber); - fillField(wrapper, 'expiryDate', formValues.expiryDate); - fillField(wrapper, 'cvv', formValues.cvv); - - const form = wrapper.find('form'); - form.simulate('submit', { preventDefault: () => {} }); + + const { getByLabelText } = render(); + fillField(getByLabelText, "Cardholder's name", formValues.name); + fillField(getByLabelText, "Cardholder's surname", formValues.surname); + fillField(getByLabelText, 'Card number', formValues.cardNumber); + fillField(getByLabelText, 'Expiry date (MM/YY)', formValues.expiryDate); + fillField(getByLabelText, 'CVV', formValues.cvv); + + submitForm(); expect(onValidate).toHaveBeenCalledTimes(1); expect(onSubmit).toHaveBeenCalledWith(formValues); @@ -252,16 +235,13 @@ describe('CardForm', () => { expiryDate: '12/23', cvv: '555' }; - const wrapper = shallow( - - ); - fillField(wrapper, 'name', formValues.name); - fillField(wrapper, 'surname', formValues.surname); - fillField(wrapper, 'expiryDate', formValues.expiryDate); - fillField(wrapper, 'cvv', formValues.cvv); + const { getByLabelText } = render(); + fillField(getByLabelText, "Cardholder's name", formValues.name); + fillField(getByLabelText, "Cardholder's surname", formValues.surname); + fillField(getByLabelText, 'Expiry date (MM/YY)', formValues.expiryDate); + fillField(getByLabelText, 'CVV', formValues.cvv); - const form = wrapper.find('form'); - form.simulate('submit', { preventDefault: () => {} }); + submitForm(); expect(onValidate).toHaveBeenCalledTimes(1); expect(onSubmit).not.toHaveBeenCalled(); @@ -270,30 +250,30 @@ describe('CardForm', () => { describe('onSubmit', () => { test('renders a submit button', () => { - const wrapper = shallow(); + render(); - expect(wrapper.find(Button)).toHaveLength(1); + const submitButton = screen.getAllByRole("button"); + expect(submitButton).toHaveLength(1); }); test('executes onSubmit callback with form values when clicking on submit button', () => { const onSubmit = jest.fn(); const formValues = { - name: 'a_name', - surname: 'a_surname', - cardNumber: '4111111111111111', + name: 'a name', + surname: 'a surname', + cardNumber: '4111-1111-1111-1111', expiryDate: '12/23', cvv: '555', cardType: 'VISA' }; - const wrapper = shallow(); - fillField(wrapper, 'name', formValues.name); - fillField(wrapper, 'surname', formValues.surname); - fillField(wrapper, 'cardNumber', formValues.cardNumber); - fillField(wrapper, 'expiryDate', formValues.expiryDate); - fillField(wrapper, 'cvv', formValues.cvv); + const { getByLabelText } = render(); + fillField(getByLabelText, "Cardholder's name", formValues.name); + fillField(getByLabelText, "Cardholder's surname", formValues.surname); + fillField(getByLabelText, 'Card number', formValues.cardNumber); + fillField(getByLabelText, 'Expiry date (MM/YY)', formValues.expiryDate); + fillField(getByLabelText, 'CVV', formValues.cvv); - const form = wrapper.find('form'); - form.simulate('submit', { preventDefault: () => {} }); + submitForm(); expect(onSubmit).toHaveBeenCalledWith(formValues); }); @@ -306,14 +286,13 @@ describe('CardForm', () => { expiryDate: '12/23', cvv: '555' }; - const wrapper = shallow(); - fillField(wrapper, 'name', formValues.name); - fillField(wrapper, 'surname', formValues.surname); - fillField(wrapper, 'expiryDate', formValues.expiryDate); - fillField(wrapper, 'cvv', formValues.cvv); + const { getByLabelText } = render(); + fillField(getByLabelText, "Cardholder's name", formValues.name); + fillField(getByLabelText, "Cardholder's surname", formValues.surname); + fillField(getByLabelText, 'Expiry date (MM/YY)', formValues.expiryDate); + fillField(getByLabelText, 'CVV', formValues.cvv); - const form = wrapper.find('form'); - form.simulate('submit', { preventDefault: () => {} }); + submitForm(); expect(onSubmit).not.toHaveBeenCalled(); }); @@ -327,15 +306,14 @@ describe('CardForm', () => { expiryDate: '12/23', cvv: '55' }; - const wrapper = shallow(); - fillField(wrapper, 'name', formValues.name); - fillField(wrapper, 'surname', formValues.surname); - fillField(wrapper, 'cardNumber', formValues.cardNumber); - fillField(wrapper, 'expiryDate', formValues.expiryDate); - fillField(wrapper, 'cvv', formValues.cvv); + const { getByLabelText } = render(); + fillField(getByLabelText, "Cardholder's name", formValues.name); + fillField(getByLabelText, "Cardholder's surname", formValues.surname); + fillField(getByLabelText, 'Card number', formValues.cardNumber); + fillField(getByLabelText, 'Expiry date (MM/YY)', formValues.expiryDate); + fillField(getByLabelText, 'CVV', formValues.cvv); - const form = wrapper.find('form'); - form.simulate('submit', { preventDefault: () => {} }); + submitForm(); expect(onSubmit).not.toHaveBeenCalled(); }); @@ -343,24 +321,26 @@ describe('CardForm', () => { describe('onCancel', () => { test('does not render a cancel button if onCancel is not provided', () => { - const wrapper = shallow(); + render(); - expect(wrapper.find('Button [type="button"]')).toHaveLength(0); + const buttons = screen.queryAllByText('Cancel'); + expect(buttons).toHaveLength(0); }); test('renders a cancel button if onCancel is provided', () => { const onCancel = () => {}; - const wrapper = shallow(); + render(); - expect(wrapper.find('Button[type="button"]')).toHaveLength(1); + const buttons = screen.queryAllByText('Cancel'); + expect(buttons).toHaveLength(1); }); test('calls onCancel when clicking on cancel button', () => { const onCancel = jest.fn(); - const wrapper = shallow(); + render(); - const cancelButton = wrapper.find('Button[type="button"]'); - cancelButton.simulate('click'); + const cancelButton = screen.getByText('Cancel'); + cancelButton.click(); expect(onCancel).toHaveBeenCalled(); }); @@ -369,11 +349,12 @@ describe('CardForm', () => { describe('onChange', () => { test('executes onChange callback when changing any form value', () => { const onChange = jest.fn(); - const fieldName = 'name'; - const fieldValue = 'a_name'; - const wrapper = shallow(); + const fieldLabel = "Cardholder's name"; + const fieldName = "name"; + const fieldValue = 'a name'; + const { getByLabelText } = render(); - fillField(wrapper, fieldName, fieldValue); + fillField(getByLabelText, fieldLabel, fieldValue); expect(onChange).toHaveBeenCalledWith(fieldName, fieldValue); }); @@ -382,42 +363,42 @@ describe('CardForm', () => { describe('card number format', () => { test('format allows up to 19 digits if accepted card types include UnionPay', () => { const acceptedCards = ['VISA', 'MC', 'UNIONPAY']; - const expectedFormat = { - pattern: '....-....-....-....-...', - shouldAddSeparatorBeforeTyping: false, - allowedCharacters: /[0-9]*/g - } + const numberWithSymbolsAndExtraDigits = '1111B2222a3333$4444#555/6666'; + + const { getByLabelText } = render(); - const wrapper = shallow(); + fillField(getByLabelText, 'Card number', numberWithSymbolsAndExtraDigits); - expect(wrapper.find(`[name="cardNumber"]`).prop('format')).toEqual(expectedFormat); + expect(getByLabelText('Card number').value).toEqual('1111-2222-3333-4444-555'); }); test('format allows up to 16 digits if accepted cards do not include UnionPay', () => { const acceptedCards = ['VISA', 'MC']; - const expectedFormat = { - pattern: '....-....-....-....', - shouldAddSeparatorBeforeTyping: true, - allowedCharacters: /[0-9]*/g - } + const numberWithSymbolsAndExtraDigits = '1111B2222a3333$4444#555/6666'; - const wrapper = shallow(); + const { getByLabelText } = render(); - expect(wrapper.find(`[name="cardNumber"]`).prop('format')).toEqual(expectedFormat); + fillField(getByLabelText, 'Card number', numberWithSymbolsAndExtraDigits); + + expect(getByLabelText('Card number').value).toEqual('1111-2222-3333-4444'); }); test('updates card number format if acceptedCards prop changes', () => { - const acceptedCards = ['VISA', 'MC']; - const expectedFormat = { - pattern: '....-....-....-....-...', - shouldAddSeparatorBeforeTyping: false, - allowedCharacters: /[0-9]*/g - } + const acceptedCards = ['VISA', 'MC', 'UNIONPAY']; + const numberWithSymbolsAndExtraDigits = '1111B2222a3333$4444#555/6666'; + + const { getByLabelText, rerender } = render(); + + fillField(getByLabelText, 'Card number', numberWithSymbolsAndExtraDigits); - const wrapper = shallow(); - wrapper.setProps({ acceptedCards: ['VISA', 'UNIONPAY']}); + expect(getByLabelText('Card number').value).toEqual('1111-2222-3333-4444-555'); - expect(wrapper.find(`[name="cardNumber"]`).prop('format')).toEqual(expectedFormat); + const updatedCcceptedCards = ['VISA', 'MC']; + rerender() + + fillField(getByLabelText, 'Card number', numberWithSymbolsAndExtraDigits); + + expect(getByLabelText('Card number').value).toEqual('1111-2222-3333-4444'); }); }); @@ -425,45 +406,49 @@ describe('CardForm', () => { test('does not render optional fields', () => { const optionalFields = ['expiryDate', 'cvv']; - const wrapper = shallow(); + render(); - expect(wrapper.find(`[name="expiryDate"]`)).toHaveLength(0); - expect(wrapper.find(`[name="cvv"]`)).toHaveLength(0); + expect(screen.queryAllByLabelText('Expiry date (MM/YY)')).toHaveLength(0); + expect(screen.queryAllByLabelText('CVV')).toHaveLength(0); }); test('does not validate optinal fields on submit', () => { const optionalFields = ['expiryDate', 'cvv']; const onSubmit = jest.fn(); - const props = { onSubmit, optionalFields} + const props = { onSubmit, optionalFields }; const expectedSubmittedValues = { - name: 'a_name', - surname: 'a_surname', - cardNumber:'4111111111111111', + name: 'a name', + surname: 'a surname', + cardNumber: '4111-1111-1111-1111', cardType: 'VISA' }; - const wrapper = shallow(); + const { getByLabelText } = render(); - fillField(wrapper, 'name', 'a_name'); - fillField(wrapper, 'surname', 'a_surname'); - fillField(wrapper, 'cardNumber', '4111111111111111'); + fillField(getByLabelText, "Cardholder's name", 'a name'); + fillField(getByLabelText, "Cardholder's surname", 'a surname'); + fillField(getByLabelText, 'Card number', '4111-1111-1111-1111'); - const form = wrapper.find('form'); - form.simulate('submit', { preventDefault: () => {} }); + submitForm(); expect(onSubmit).toHaveBeenCalledWith(expectedSubmittedValues); }); }); }); -const fillField = (wrapper, name, value) => { - wrapper - .find(`[name="${name}"]`) - .simulate('change', name, value); +const fillField = (getByLabelText, label, value) => { + const input = getByLabelText(label); + fireEvent.change(input, { target: { value: value } }); }; -const blurField = (wrapper, name, value) => { - wrapper - .find(`[name="${name}"]`) - .simulate('blur', name, value); +const submitForm = () => { + const submitButton = screen.getByRole("button"); + submitButton.click(); +} + +const blurField = (getByLabelText, label, value) => { + const input = getByLabelText(label); + fireEvent.change(input, { target: { value: value } }); + input.blur(); + submitForm(); }; diff --git a/src/CardForm/CardNumberInput/CardNumberInput.test.js b/src/CardForm/CardNumberInput/CardNumberInput.test.js index b6bb1406..c6387f55 100644 --- a/src/CardForm/CardNumberInput/CardNumberInput.test.js +++ b/src/CardForm/CardNumberInput/CardNumberInput.test.js @@ -1,42 +1,44 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { fireEvent, render, screen } from '@testing-library/react'; import CardNumberInput from './CardNumberInput'; -import TextInput from '../TextInput'; -import { render, screen } from '@testing-library/react'; import userEvent from '@testing-library/user-event'; describe('CardNumberInput', () => { + userEvent.setup(); + describe('renders', () => { test('a TextInput with all the passed props', () => { - const props = { name: 'a_name', propA: 'propA', propB: 'propB' }; - const wrapper = shallow(); + const props = { name: 'a_name', prop_a: 'propA', prop_b: 'propB' }; + const { getByRole } = render(); - const textInput = wrapper.find(TextInput); + const input = getByRole('textbox'); - expect(textInput.props()).toEqual(expect.objectContaining(props)); + expect(input).toHaveAttribute('name', 'a_name'); + expect(input).toHaveAttribute('prop_a', 'propA'); + expect(input).toHaveAttribute('prop_b', 'propB'); }); test('a TextInput witht the provided className', () => { const props = { name: 'a_name', className: 'a_className' }; - const wrapper = shallow(); + const { container } = render(); - expect(wrapper.find(TextInput).hasClass('a_className')).toEqual(true); + expect(container.firstChild.classList.contains('a_className')).toBe(true); }); }); describe('when no format prop is passed', () => { - it('defaults to ....-....-....-.... only allowing numbers', () => { + it('defaults to ....-....-....-.... only allowing numbers', async () => { render(); const cardInput = screen.getByRole('textbox', { name: /Card input/i }); - userEvent.type(cardInput, '1111-vvvv-aaaa-bbbb'); + await userEvent.type(cardInput, '1111-vvvv-aaaa-bbbb'); expect(cardInput).toHaveValue('1111-'); }); }); describe('when format prop is passed', () => { - it('adapts to it', () => { + it('adapts to it', async () => { const format = { pattern: '...', allowedCharacters: /[0-9]*/g @@ -46,22 +48,23 @@ describe('CardNumberInput', () => { ); const cardInput = screen.getByRole('textbox', { name: /Card input/i }); - userEvent.type(cardInput, '111'); + await userEvent.type(cardInput, '111'); expect(cardInput).toHaveValue('111'); }); }); describe('onChange', () => { - test('calls the passed onChange callback when on change', () => { + test('calls the passed onChange callback when on change', async () => { const onChange = jest.fn(); const name = 'a_name'; - const value = 'a_value'; - const wrapper = shallow( + const value = '123'; + const { getByRole } = render( ); - wrapper.simulate('change', name, value); + const input = getByRole('textbox'); + fireEvent.change(input, { target: { value: value } }); expect(onChange).toHaveBeenCalledWith(name, value); }); @@ -77,12 +80,14 @@ describe('CardNumberInput', () => { 'to identify the card type %s', (cardType, cardNumber) => { const name = 'a_name'; - const wrapper = shallow(); + const { container, getByRole } = render( + + ); - const textInput = wrapper.find(TextInput); - textInput.simulate('change', name, cardNumber); + const input = getByRole('textbox'); + fireEvent.change(input, { target: { value: cardNumber } }); - expect(wrapper.find(TextInput).hasClass(cardType)).toEqual(true); + expect(container.firstChild.classList.contains(cardType)).toBe(true); } ); @@ -91,15 +96,15 @@ describe('CardNumberInput', () => { const cardNumber = '4111111111111111'; const cardType = 'visa'; const className = 'a_className'; - const wrapper = shallow( + const { container, getByRole } = render( ); - const textInput = wrapper.find(TextInput); - textInput.simulate('change', name, cardNumber); + const input = getByRole('textbox'); + fireEvent.change(input, { target: { value: cardNumber } }); - expect(wrapper.find(TextInput).hasClass(className)).toEqual(true); - expect(wrapper.find(TextInput).hasClass(cardType)).toEqual(true); + expect(container.firstChild.classList.contains(className)).toBe(true); + expect(container.firstChild.classList.contains(cardType)).toBe(true); }); test('cleans className when value is invalid', () => { @@ -107,13 +112,15 @@ describe('CardNumberInput', () => { const validCardNumber = '4111111111111111'; const cardType = 'visa'; const invalidCardNumber = '4'; - const wrapper = shallow(); + const { container, getByRole } = render( + + ); - const textInput = wrapper.find(TextInput); - textInput.simulate('change', name, validCardNumber); - textInput.simulate('change', name, invalidCardNumber); + const input = getByRole('textbox'); + fireEvent.change(input, { target: { value: validCardNumber } }); + fireEvent.change(input, { target: { value: invalidCardNumber } }); - expect(wrapper.find(TextInput).hasClass(cardType)).not.toEqual(true); + expect(container.firstChild.classList.contains(cardType)).toBe(false); }); }); }); diff --git a/src/CardForm/TextInput/TextInput.test.js b/src/CardForm/TextInput/TextInput.test.js index 21d1e99b..31a145dd 100644 --- a/src/CardForm/TextInput/TextInput.test.js +++ b/src/CardForm/TextInput/TextInput.test.js @@ -1,261 +1,105 @@ import React from 'react'; -import { shallow } from 'enzyme'; +import { fireEvent, render } from '@testing-library/react'; +import userEvent from '@testing-library/user-event'; import TextInput from './TextInput'; describe('TextInput', () => { - class TextInputComponent { - constructor(ownProps) { - const defaultProps = { name: 'name' }; - const props = { ...defaultProps, ...ownProps }; - - this.component = shallow(); - this.mockRefs(); - } - - input() { - return this.component.find('input'); - } - - simulateBlur(name, value) { - this.simulate('blur', { - target: { name, value } - }); - } - - simulateChange(name, value) { - this.simulate('change', { - target: { name, value } - }); - } - - simulate(eventName, event) { - this.input().simulate(eventName, event); - } - - mockRefs(mock = () => {}) { - this.component.instance().inputRef.current = { - setSelectionRange: mock - }; - } - } + const defaultProps = { + name: 'a_name', + 'data-testid': 'a_test_id' + }; test('renders an input text', () => { - const component = new TextInputComponent(); + const { getByTestId } = render(); - expect(component.input()).toHaveLength(1); - expect(component.input().prop('type')).toEqual('text'); + expect(getByTestId(defaultProps['data-testid'])).toBeInTheDocument(); + expect(getByTestId(defaultProps['data-testid'])).toHaveProperty( + 'type', + 'text' + ); }); test('renders an input field with the provided className', () => { - const className = 'a_className'; - const component = new TextInputComponent({ className }).component; + const props = { name: 'a_name', className: 'a_className' }; + const { container } = render(); - expect(component.hasClass('a_className')).toEqual(true); + expect(container.firstChild.classList.contains('a_className')).toBe(true); }); test('renders the provided children', () => { - const ChildrenComponent = () =>
; - const wrapper = shallow( + const ChildrenComponent = () =>
; + const { getAllByTestId } = render( ); - expect(wrapper.find(ChildrenComponent)).toHaveLength(1); + expect(getAllByTestId('child')).toHaveLength(1); }); - describe('componentDidUpdate', () => { - test('sets the input caret position with the position in the state when it is focused', () => { - const wrapper = new TextInputComponent(); - const setSelectionRange = jest.fn(); - Object.defineProperty(wrapper.component.instance(), 'isFocused', { - get: () => true - }); - wrapper.mockRefs(setSelectionRange); + test('handles on change events in input', () => { + const onChange = jest.fn(); + const props = { ...defaultProps, onChange }; - wrapper.component.setState({ caretPosition: 2 }); + const { getByTestId } = render(); - expect(setSelectionRange).toHaveBeenCalledWith(2, 2); + fireEvent.change(getByTestId(defaultProps['data-testid']), { + target: { name: 'name', value: 'Dolores' } }); - test('does not set the input caret position when it is not focused', () => { - const wrapper = new TextInputComponent(); - Object.defineProperty(wrapper.component.instance(), 'isFocused', { - get: () => false - }); - const setSelectionRange = jest.fn(); - wrapper.mockRefs(setSelectionRange); - - wrapper.component.setState({ caretPosition: 2 }); - - expect(setSelectionRange).not.toHaveBeenCalled(); - }); + expect(onChange).toBeCalledWith('name', 'Dolores'); }); - describe('onChange', () => { - test('handles on change events in input', () => { - const onChange = jest.fn(); - const props = { onChange }; - - const component = new TextInputComponent(props); + test('handles on blur events in input', () => { + const onBlur = jest.fn(); + const props = { ...defaultProps, onBlur }; - component.simulateChange('name', 'Dolores'); + const { getByTestId } = render(); - expect(onChange).toBeCalledWith('name', 'Dolores'); + fireEvent.blur(getByTestId(defaultProps['data-testid']), { + target: { name: 'name' } }); - describe('when format is not provided', () => { - test('saves in the state the value and caret position', () => { - const value = 'a_value'; - const caretPosition = 2; - const name = 'a_name'; - const event = { - target: { name, value, selectionStart: caretPosition } - }; - const wrapper = new TextInputComponent(); - - const input = wrapper.input(); - input.simulate('change', event); - - const { - value: stateValue, - caretPosition: stateCaretPosition - } = wrapper.component.state(); - expect(stateValue).toEqual(value); - expect(stateCaretPosition).toEqual(caretPosition); - }); - - test('calls onChange callback with name and value', () => { - const onChange = jest.fn(); - const value = 'a_value'; - const name = 'a_name'; - const event = { target: { name, value } }; - const wrapper = new TextInputComponent({ name, onChange }); - - const input = wrapper.input(); - input.simulate('change', event); + expect(onBlur).toBeCalled(); + }); - expect(onChange).toHaveBeenCalledWith(name, value); - }); + describe('when format is provided', () => { + const onChange = jest.fn(); + userEvent.setup(); + const format = { + pattern: '..-../..', + shouldAddSeparatorBeforeTyping: true, + allowedCharacters: /\d/g + }; + const name = 'a_name'; + + test('formats the input value on change if format is provided', () => { + const value = '123456'; + const formattedValue = '12-34/56'; + const event = { target: { value } }; + + const props = { ...defaultProps, name, onChange, format }; + const { getByTestId } = render(); + + fireEvent.input(getByTestId(defaultProps['data-testid']), event); + + expect(getByTestId(defaultProps['data-testid']).value).toEqual( + formattedValue + ); }); - describe('when format is provided', () => { + test('calls onChange callback with name and formatted value', () => { + const value = '123456'; const onChange = jest.fn(); - const format = { - pattern: '..-../..', - shouldAddSeparatorBeforeTyping: true, - allowedCharacters: /\d/g - }; - - test('formats the input value on change if format is provnameed', () => { - const value = '123456'; - const formattedValue = '12-34/56'; - const event = { target: { value } }; - const name = 'a_name'; - const wrapper = new TextInputComponent({ name, onChange, format }); - - let input = wrapper.input(); - input.simulate('change', event); - - input = wrapper.input(); - expect(input.prop('value')).toEqual(formattedValue); - }); - - test('calls onChange callback with name and formatted value', () => { - const value = '123456'; - const name = 'a_name'; - const onChange = jest.fn(); - const formattedValue = '12-34/56'; - const event = { target: { name, value } }; - const wrapper = new TextInputComponent({ name, onChange, format }); - - const input = wrapper.input(); - input.simulate('change', event); - - expect(onChange).toHaveBeenCalledWith(name, formattedValue); - }); - - describe('sets input caret position', () => { - test('does not modifies the caret position if no format changes have been applied', () => { - const value = '1'; - const caretPosition = 1; - const event = { target: { value, selectionStart: caretPosition } }; - const name = 'a_name'; - const wrapper = new TextInputComponent({ name, format }); - - const input = wrapper.input(); - input.simulate('change', event); - - const { - caretPosition: stateCaretPosition - } = wrapper.component.state(); - - expect(stateCaretPosition).toEqual(caretPosition); - }); - - test('increases the caret position if a separator is added by the formatting', () => { - const value = '12'; - const caretPosition = 2; - const event = { target: { value, selectionStart: caretPosition } }; - const name = 'a_name'; - const wrapper = new TextInputComponent({ name, format }); - - const input = wrapper.input(); - input.simulate('change', event); - - const { - caretPosition: stateCaretPosition - } = wrapper.component.state(); - - expect(stateCaretPosition).toBeGreaterThan(caretPosition); - }); - - test('does not increases the caret position by formatting if user is deleting', () => { - const value = '12-'; - const caretPosition = 2; - const event = { target: { value, selectionStart: caretPosition } }; - const name = 'a_name'; - const wrapper = new TextInputComponent({ name, format }); - - wrapper.component.setState({ value: '12-' }); - const input = wrapper.input(); - input.simulate('change', event); - - const { - caretPosition: stateCaretPosition - } = wrapper.component.state(); - - expect(stateCaretPosition).toEqual(caretPosition); - }); - }); - }); - }); - - test('handles on blur events in input', () => { - const onBlur = jest.fn(); - const component = new TextInputComponent({ onBlur }); - - component.simulateBlur('name', 'a_value'); - - expect(onBlur).toBeCalledWith('name', 'a_value'); - }); - - test('renders an input with type password', () => { - const type = 'password'; - const component = new TextInputComponent({ type }); - - expect(component.input().prop('type')).toEqual('password'); - }); + const formattedValue = '12-34/56'; + const event = { target: { name, value } }; - describe('onFocus', () => { - test('calls the onFocus callback when on focus', () => { - const name = 'a_name'; - const onFocus = jest.fn(); - const component = new TextInputComponent({ name, onFocus }); + const props = { ...defaultProps, name, onChange, format }; + const { getByTestId } = render(); - component.simulate('focus'); + fireEvent.input(getByTestId(defaultProps['data-testid']), event); - expect(onFocus).toHaveBeenCalledWith(name); + expect(onChange).toHaveBeenCalledWith(name, formattedValue); }); }); });