From b3a22f1706409c05b896ff499686b6e3fea85134 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Wed, 30 Oct 2019 05:24:39 -0400 Subject: [PATCH 01/14] Add integration tests for buttons with Jest --- .eslintrc.json | 2 +- package.json | 2 + src/content/index.test.js | 60 +++++++++++ yarn.lock | 203 +++++++++++++++++++++++++++++++++++--- 4 files changed, 255 insertions(+), 12 deletions(-) create mode 100644 src/content/index.test.js diff --git a/.eslintrc.json b/.eslintrc.json index 06f41caa..3d38823a 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -55,7 +55,7 @@ { "files": ["src/**/*"], "plugins": ["react-hooks"], - "extends": ["plugin:react/recommended"], + "extends": ["plugin:react/recommended", "plugin:jest-dom/recommended"], "env": { "browser": true, "node": false diff --git a/package.json b/package.json index 421e31d5..25a32cf7 100644 --- a/package.json +++ b/package.json @@ -27,9 +27,11 @@ "@babel/plugin-transform-modules-commonjs": "7.7.0", "@babel/preset-react": "7.7.0", "@ffflorian/jszip-cli": "3.0.2", + "@testing-library/jest-dom": "4.2.0", "babel-loader": "8.0.6", "eslint": "6.6.0", "eslint-config-prettier": "6.5.0", + "eslint-plugin-jest-dom": "1.1.3", "eslint-plugin-prettier": "3.1.1", "eslint-plugin-react": "7.16.0", "eslint-plugin-react-hooks": "2.2.0", diff --git a/src/content/index.test.js b/src/content/index.test.js new file mode 100644 index 00000000..92a4ece4 --- /dev/null +++ b/src/content/index.test.js @@ -0,0 +1,60 @@ +import "@testing-library/jest-dom/extend-expect"; +import GitHub from "./github"; +import StackOverflow from "./stackOverflow"; +import Storage from "./storage"; + +window.chrome = { + runtime: {}, + storage: { + onChanged: { + addListener() {} + }, + sync: { + get(callback) { + setTimeout(() => callback({})); + } + } + } +}; + +window.MutationObserver = class { + constructor() {} + observe() {} +}; + +describe("Prettier format button injection", () => { + function createStorage() { + const storage = new Storage(); + return storage.init(); + } + + function expectToHavePrettierButton() { + expect(document.querySelector(".prettier-btn")).toHaveTextContent( + "Prettier" + ); + } + + beforeEach(() => (document.body.innerHTML = "")); + + test("GitHub", async () => { + // Basis: https://github.com/prettier/prettier-chrome-extension/issues/new + const button = document.createElement("button"); + button.innerText = "Comment"; + document.body.appendChild(button); + // Hack around JSDOM's lack of offsetHeight support to fix isElementVisible + Object.defineProperty(document.body, "offsetHeight", { value: 1 }); + + new GitHub(await createStorage()); + expectToHavePrettierButton(); + }); + + test("Stack Overflow", async () => { + // Basis: https://stackoverflow.com/questions/51875054 + const button = document.createElement("div"); + button.className = "wmd-button-row"; + document.body.appendChild(button); + + new StackOverflow(await createStorage()); + expectToHavePrettierButton(); + }); +}); diff --git a/yarn.lock b/yarn.lock index caf2a451..572ab98f 100644 --- a/yarn.lock +++ b/yarn.lock @@ -9,7 +9,7 @@ dependencies: "@babel/highlight" "^7.0.0" -"@babel/core@7.7.2", "@babel/core@^7.1.0": +"@babel/core@7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.7.2.tgz#ea5b99693bcfc058116f42fa1dd54da412b29d91" integrity sha512-eeD7VEZKfhK1KUXGiyPFettgF3m513f8FoBSWiQ1xTvl1RAopLs42Wp9+Ze911I6H0N9lNqJMDgoZT7gHsipeQ== @@ -29,7 +29,37 @@ semver "^5.4.1" source-map "^0.5.0" -"@babel/generator@^7.4.0", "@babel/generator@^7.7.2": +"@babel/core@^7.1.0": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@babel/core/-/core-7.6.4.tgz#6ebd9fe00925f6c3e177bb726a188b5f578088ff" + integrity sha512-Rm0HGw101GY8FTzpWSyRbki/jzq+/PkNQJ+nSulrdY6gFGOsNseCqD6KHRYe2E+EdzuBdr2pxCp6s4Uk6eJ+XQ== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.6.4" + "@babel/helpers" "^7.6.2" + "@babel/parser" "^7.6.4" + "@babel/template" "^7.6.0" + "@babel/traverse" "^7.6.3" + "@babel/types" "^7.6.3" + convert-source-map "^1.1.0" + debug "^4.1.0" + json5 "^2.1.0" + lodash "^4.17.13" + resolve "^1.3.2" + semver "^5.4.1" + source-map "^0.5.0" + +"@babel/generator@^7.4.0", "@babel/generator@^7.6.3", "@babel/generator@^7.6.4": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.6.4.tgz#a4f8437287bf9671b07f483b76e3bb731bc97671" + integrity sha512-jsBuXkFoZxk0yWLyGI9llT9oiQ2FeTASmRFE32U+aaDTfoE92t78eroO7PTpU/OrYq38hlcDM6vbfLDaOLy+7w== + dependencies: + "@babel/types" "^7.6.3" + jsesc "^2.5.1" + lodash "^4.17.13" + source-map "^0.5.0" + +"@babel/generator@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/generator/-/generator-7.7.2.tgz#2f4852d04131a5e17ea4f6645488b5da66ebf3af" integrity sha512-WthSArvAjYLz4TcbKOi88me+KmDJdKSlfwwN8CnUYn9jBkzhq0ZEPuBfkAWIvjJ3AdEV1Cf/+eSQTnp3IDJKlQ== @@ -47,6 +77,15 @@ "@babel/types" "^7.7.0" esutils "^2.0.0" +"@babel/helper-function-name@^7.1.0": + version "7.1.0" + resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.1.0.tgz#a0ceb01685f73355d4360c1247f582bfafc8ff53" + integrity sha512-A95XEoCpb3TO+KZzJ4S/5uW5fNe26DjBGqf1o9ucyLyCmi1dXq/B3c8iaWTfBk3VvetUxl16e8tIrd5teOCfGw== + dependencies: + "@babel/helper-get-function-arity" "^7.0.0" + "@babel/template" "^7.1.0" + "@babel/types" "^7.0.0" + "@babel/helper-function-name@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/helper-function-name/-/helper-function-name-7.7.0.tgz#44a5ad151cfff8ed2599c91682dda2ec2c8430a3" @@ -56,6 +95,13 @@ "@babel/template" "^7.7.0" "@babel/types" "^7.7.0" +"@babel/helper-get-function-arity@^7.0.0": + version "7.0.0" + resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.0.0.tgz#83572d4320e2a4657263734113c42868b64e49c3" + integrity sha512-r2DbJeg4svYvt3HOS74U4eWKsUAMRH01Z1ds1zx8KNTPtpTL5JAsdFv8BNyOpVqdFhHkkRDIg5B4AsxmkjAlmQ== + dependencies: + "@babel/types" "^7.0.0" + "@babel/helper-get-function-arity@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/helper-get-function-arity/-/helper-get-function-arity-7.7.0.tgz#c604886bc97287a1d1398092bc666bc3d7d7aa2d" @@ -95,6 +141,13 @@ "@babel/template" "^7.7.0" "@babel/types" "^7.7.0" +"@babel/helper-split-export-declaration@^7.4.4": + version "7.4.4" + resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.4.4.tgz#ff94894a340be78f53f06af038b205c49d993677" + integrity sha512-Ro/XkzLf3JFITkW6b+hNxzZ1n5OQ80NvIUdmHspih1XAhtN3vPTuUFT4eQnela+2MaZ5ulH+iyP513KJrxbN7Q== + dependencies: + "@babel/types" "^7.4.4" + "@babel/helper-split-export-declaration@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/helper-split-export-declaration/-/helper-split-export-declaration-7.7.0.tgz#1365e74ea6c614deeb56ebffabd71006a0eb2300" @@ -102,6 +155,15 @@ dependencies: "@babel/types" "^7.7.0" +"@babel/helpers@^7.6.2": + version "7.6.2" + resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.6.2.tgz#681ffe489ea4dcc55f23ce469e58e59c1c045153" + integrity sha512-3/bAUL8zZxYs1cdX2ilEE0WobqbCmKWr/889lf2SS0PpDcpEIY8pb1CCyz0pEcX3pEb+MCbks1jIokz2xLtGTA== + dependencies: + "@babel/template" "^7.6.0" + "@babel/traverse" "^7.6.2" + "@babel/types" "^7.6.0" + "@babel/helpers@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/helpers/-/helpers-7.7.0.tgz#359bb5ac3b4726f7c1fde0ec75f64b3f4275d60b" @@ -120,7 +182,12 @@ esutils "^2.0.2" js-tokens "^4.0.0" -"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.7.0", "@babel/parser@^7.7.2": +"@babel/parser@^7.1.0", "@babel/parser@^7.4.3", "@babel/parser@^7.6.0", "@babel/parser@^7.6.3", "@babel/parser@^7.6.4": + version "7.6.4" + resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.6.4.tgz#cb9b36a7482110282d5cb6dd424ec9262b473d81" + integrity sha512-D8RHPW5qd0Vbyo3qb+YjO5nvUVRTXFLQ/FsDxJU2Nqz4uB5EnUN0ZQSEYpvTIbRuttig1XbHWU5oMeQwQSAA+A== + +"@babel/parser@^7.7.0", "@babel/parser@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/parser/-/parser-7.7.2.tgz#ea8334dc77416bfd9473eb470fd00d8245b3943b" integrity sha512-DDaR5e0g4ZTb9aP7cpSZLkACEBdoLGwJDWgHtBhrGX7Q1RjhdoMOfexICj5cqTAtpowjGQWfcvfnQG7G2kAB5w== @@ -192,7 +259,23 @@ "@babel/plugin-transform-react-jsx-self" "^7.0.0" "@babel/plugin-transform-react-jsx-source" "^7.0.0" -"@babel/template@^7.4.0", "@babel/template@^7.7.0": +"@babel/runtime@^7.5.1": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.6.3.tgz#935122c74c73d2240cafd32ddb5fc2a6cd35cf1f" + integrity sha512-kq6anf9JGjW8Nt5rYfEuGRaEAaH1mkv3Bbu6rYvLOpPh/RusSJXuKPEAoZ7L7gybZkchE8+NV5g9vKF4AGAtsA== + dependencies: + regenerator-runtime "^0.13.2" + +"@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.6.0": + version "7.6.0" + resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" + integrity sha512-5AEH2EXD8euCk446b7edmgFdub/qfH1SN6Nii3+fyXP807QRx9Q73A2N5hNwRRslC2H9sNzaFhsPubkS4L8oNQ== + dependencies: + "@babel/code-frame" "^7.0.0" + "@babel/parser" "^7.6.0" + "@babel/types" "^7.6.0" + +"@babel/template@^7.7.0": version "7.7.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.7.0.tgz#4fadc1b8e734d97f56de39c77de76f2562e597d0" integrity sha512-OKcwSYOW1mhWbnTBgQY5lvg1Fxg+VyfQGjcBduZFljfc044J5iDlnDSfhQ867O17XHiSCxYHUxHg2b7ryitbUQ== @@ -201,7 +284,22 @@ "@babel/parser" "^7.7.0" "@babel/types" "^7.7.0" -"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": +"@babel/traverse@^7.1.0", "@babel/traverse@^7.4.3", "@babel/traverse@^7.6.2", "@babel/traverse@^7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.6.3.tgz#66d7dba146b086703c0fb10dd588b7364cec47f9" + integrity sha512-unn7P4LGsijIxaAJo/wpoU11zN+2IaClkQAxcJWBNCMS6cmVh802IyLHNkAjQ0iYnRS3nnxk5O3fuXW28IMxTw== + dependencies: + "@babel/code-frame" "^7.5.5" + "@babel/generator" "^7.6.3" + "@babel/helper-function-name" "^7.1.0" + "@babel/helper-split-export-declaration" "^7.4.4" + "@babel/parser" "^7.6.3" + "@babel/types" "^7.6.3" + debug "^4.1.0" + globals "^11.1.0" + lodash "^4.17.13" + +"@babel/traverse@^7.7.0", "@babel/traverse@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/traverse/-/traverse-7.7.2.tgz#ef0a65e07a2f3c550967366b3d9b62a2dcbeae09" integrity sha512-TM01cXib2+rgIZrGJOLaHV/iZUAxf4A0dt5auY6KNZ+cm6aschuJGqKJM3ROTt3raPUdIDk9siAufIFEleRwtw== @@ -216,7 +314,16 @@ globals "^11.1.0" lodash "^4.17.13" -"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.7.0", "@babel/types@^7.7.2": +"@babel/types@^7.0.0", "@babel/types@^7.3.0", "@babel/types@^7.4.0", "@babel/types@^7.4.4", "@babel/types@^7.6.0", "@babel/types@^7.6.3": + version "7.6.3" + resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.6.3.tgz#3f07d96f854f98e2fbd45c64b0cb942d11e8ba09" + integrity sha512-CqbcpTxMcpuQTMhjI37ZHVgjBkysg5icREQIEZ0eG1yCNwg3oy+5AaLiOKmjsCj6nqOsa6Hf0ObjRVwokb7srA== + dependencies: + esutils "^2.0.2" + lodash "^4.17.13" + to-fast-properties "^2.0.0" + +"@babel/types@^7.7.0", "@babel/types@^7.7.2": version "7.7.2" resolved "https://registry.yarnpkg.com/@babel/types/-/types-7.7.2.tgz#550b82e5571dcd174af576e23f0adba7ffc683f7" integrity sha512-YTf6PXoh3+eZgRCBzzP25Bugd2ngmpQVrk7kXX0i5N9BO7TFBtIgZYs7WtxtOGs8e6A4ZI7ECkbBCEHeXocvOA== @@ -421,6 +528,21 @@ dependencies: any-observable "^0.3.0" +"@testing-library/jest-dom@4.2.0": + version "4.2.0" + resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-4.2.0.tgz#32f8df3a78511b347d39374ea89dc8e0a1c2fb69" + integrity sha512-H61OmRhGPWLrj9emyISx0qjp8jvC9RWyRniuLAq75Ny5XfPiOvWfnY3Wm2Tf0HXusX+PG40I94Gw792IAtSKKg== + dependencies: + "@babel/runtime" "^7.5.1" + chalk "^2.4.1" + css "^2.2.3" + css.escape "^1.5.1" + jest-diff "^24.0.0" + jest-matcher-utils "^24.0.0" + lodash "^4.17.11" + pretty-format "^24.0.0" + redent "^3.0.0" + "@types/babel__core@^7.1.0": version "7.1.3" resolved "https://registry.yarnpkg.com/@types/babel__core/-/babel__core-7.1.3.tgz#e441ea7df63cd080dfcd02ab199e6d16a735fc30" @@ -1552,7 +1674,14 @@ constants-browserify@^1.0.0: resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" integrity sha1-wguW2MYXdIqvHBYCF2DNJ/y4y3U= -convert-source-map@^1.4.0, convert-source-map@^1.7.0: +convert-source-map@^1.1.0, convert-source-map@^1.4.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.6.0.tgz#51b537a8c43e0f04dec1993bffcdd504e758ac20" + integrity sha512-eFu7XigvxdZ1ETfbgPBohgyQ/Z++C0eEhTor0qRwBw9unw+L0/6V8wkSuGgzdThkiS5lSpdptOQPD8Ak40a+7A== + dependencies: + safe-buffer "~5.1.1" + +convert-source-map@^1.7.0: version "1.7.0" resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.7.0.tgz#17a2cb882d7f77d3490585e2ce6c524424a3a442" integrity sha512-4FJkXzKXEDB1snCFZlLP4gpC3JILicCpGbzG9f9G7tGqGCzETQ2hWPrcinA9oU4wtf2biUaEH5065UnMeR33oA== @@ -1698,6 +1827,21 @@ crypto-random-string@^1.0.0: resolved "https://registry.yarnpkg.com/crypto-random-string/-/crypto-random-string-1.0.0.tgz#a230f64f568310e1498009940790ec99545bca7e" integrity sha1-ojD2T1aDEOFJgAmUB5DsmVRbyn4= +css.escape@^1.5.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/css.escape/-/css.escape-1.5.1.tgz#42e27d4fa04ae32f931a4b4d4191fa9cddee97cb" + integrity sha1-QuJ9T6BK4y+TGktNQZH6nN3ul8s= + +css@^2.2.3: + version "2.2.4" + resolved "https://registry.yarnpkg.com/css/-/css-2.2.4.tgz#c646755c73971f2bba6a601e2cf2fd71b1298929" + integrity sha512-oUnjmWpy0niI3x/mPL8dVEI1l7MnG3+HHyRPHf+YFSbK+svOhXpmSOcDURUh2aOCgl2grzrOPt1nHLuCVFULLw== + dependencies: + inherits "^2.0.3" + source-map "^0.6.1" + source-map-resolve "^0.5.2" + urix "^0.1.0" + cssom@0.3.x, "cssom@>= 0.3.2 < 0.4.0": version "0.3.8" resolved "https://registry.yarnpkg.com/cssom/-/cssom-0.3.8.tgz#9f1276f5b2b463f2114d3f2c75250af8c1a36f4a" @@ -2138,6 +2282,13 @@ eslint-config-prettier@6.5.0: dependencies: get-stdin "^6.0.0" +eslint-plugin-jest-dom@1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-1.1.3.tgz#36ba066de1671433b5d5c2ab90eda8f8e47f0a2b" + integrity sha512-fhwdRaZRU0nsqxzKI13fm1cHYTU+5FLgJRn27mcKAC16ajGoefMimHrXPdweX/ht8susO7Q+z4DzY+wKuYQjFg== + dependencies: + requireindex "~1.2.0" + eslint-plugin-prettier@3.1.1: version "3.1.1" resolved "https://registry.yarnpkg.com/eslint-plugin-prettier/-/eslint-plugin-prettier-3.1.1.tgz#507b8562410d02a03f0ddc949c616f877852f2ba" @@ -3640,7 +3791,7 @@ jest-config@^24.9.0: pretty-format "^24.9.0" realpath-native "^1.1.0" -jest-diff@^24.9.0: +jest-diff@^24.0.0, jest-diff@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-diff/-/jest-diff-24.9.0.tgz#931b7d0d5778a1baf7452cb816e325e3724055da" integrity sha512-qMfrTs8AdJE2iqrTp0hzh7kTd2PQWrsFyj9tORoKmu32xjPjeE4NyjVRDz8ybYwqS2ik8N4hsIpiVTyFeo2lBQ== @@ -3745,7 +3896,7 @@ jest-leak-detector@^24.9.0: jest-get-type "^24.9.0" pretty-format "^24.9.0" -jest-matcher-utils@^24.9.0: +jest-matcher-utils@^24.0.0, jest-matcher-utils@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/jest-matcher-utils/-/jest-matcher-utils-24.9.0.tgz#f5b3661d5e628dffe6dd65251dfdae0e87c3a073" integrity sha512-OZz2IXsu6eaiMAwe67c1T+5tUAtQyQx27/EMEkbFAGiw52tB9em+uGbzpcgYVpA8wl0hlxKPZxrly4CXU/GjHA== @@ -4502,6 +4653,11 @@ mimic-fn@^2.0.0, mimic-fn@^2.1.0: resolved "https://registry.yarnpkg.com/mimic-fn/-/mimic-fn-2.1.0.tgz#7ed2c2ccccaf84d3ffcb7a69b57711fc2083401b" integrity sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg== +min-indent@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/min-indent/-/min-indent-1.0.0.tgz#cfc45c37e9ec0d8f0a0ec3dd4ef7f7c3abe39256" + integrity sha1-z8RcN+nsDY8KDsPdTvf3w6vjklY= + minimalistic-assert@^1.0.0, minimalistic-assert@^1.0.1: version "1.0.1" resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.1.tgz#2e194de044626d4a10e7f7fbc00ce73e83e4d5c7" @@ -5335,7 +5491,7 @@ pretty-bytes@^1.0.2: get-stdin "^4.0.1" meow "^3.1.0" -pretty-format@^24.9.0: +pretty-format@^24.0.0, pretty-format@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== @@ -5633,6 +5789,19 @@ redent@^1.0.0: indent-string "^2.1.0" strip-indent "^1.0.1" +redent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/redent/-/redent-3.0.0.tgz#e557b7998316bb53c9f1f56fa626352c6963059f" + integrity sha512-6tDA8g98We0zd0GvVeMT9arEOnTw9qM03L9cJXaCjrip1OO764RDBLBfrB4cwzNGDj5OA5ioymC9GkizgWJDUg== + dependencies: + indent-string "^4.0.0" + strip-indent "^3.0.0" + +regenerator-runtime@^0.13.2: + version "0.13.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.13.3.tgz#7cf6a77d8f5c6f60eb73c5fc1955b2ceb01e6bf5" + integrity sha512-naKIZz2GQ8JWh///G7L3X6LaQUAMp2lvb1rvwwsURe/VXwD6VMfr+/1NuNw3ag8v2kY1aQ/go5SNn79O9JU7yw== + regex-not@^1.0.0, regex-not@^1.0.2: version "1.0.2" resolved "https://registry.yarnpkg.com/regex-not/-/regex-not-1.0.2.tgz#1f4ece27e00b0b65e0247a6810e6a85d83a5752c" @@ -5735,6 +5904,11 @@ require-main-filename@^2.0.0: resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-2.0.0.tgz#d0b329ecc7cc0f61649f62215be69af54aa8989b" integrity sha512-NKN5kMDylKuldxYLSUfrbo5Tuzh4hd+2E8NPPX02mZtn1VuREQToYe/ZdlJy+J3uCpfaiGF05e7B8W0iXbQHmg== +requireindex@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/requireindex/-/requireindex-1.2.0.tgz#3463cdb22ee151902635aa6c9535d4de9c2ef1ef" + integrity sha512-L9jEkOi3ASd9PYit2cwRfyppc9NoABujTP8/5gFcbERmo5jUoAKovIC3fsF17pkTnGsrByysqX+Kxd2OTNI1ww== + resolve-cwd@^2.0.0: version "2.0.0" resolved "https://registry.yarnpkg.com/resolve-cwd/-/resolve-cwd-2.0.0.tgz#00a9f7387556e27038eae232caa372a6a59b665a" @@ -6107,7 +6281,7 @@ source-list-map@^2.0.0: resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-2.0.1.tgz#3993bd873bfc48479cca9ea3a547835c7c154b34" integrity sha512-qnQ7gVMxGNxsiL4lEuJwe/To8UnK7fAnmbGEEH8RpLouuKbeEm0lhbQVFIrNSuB+G7tVrAlVsZgETT5nljf+Iw== -source-map-resolve@^0.5.0: +source-map-resolve@^0.5.0, source-map-resolve@^0.5.2: version "0.5.2" resolved "https://registry.yarnpkg.com/source-map-resolve/-/source-map-resolve-0.5.2.tgz#72e2cc34095543e43b2c62b2c4c10d4a9054f259" integrity sha512-MjqsvNwyz1s0k81Goz/9vRBe9SZdB09Bdw+/zYyO+3CuPk6fouTaxscHkgtE8jKvf01kVfl8riHzERQ/kefaSA== @@ -6406,6 +6580,13 @@ strip-indent@^1.0.1: dependencies: get-stdin "^4.0.1" +strip-indent@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/strip-indent/-/strip-indent-3.0.0.tgz#c32e1cee940b6b3432c771bc2c54bcce73cd3001" + integrity sha512-laJTa3Jb+VQpaC6DseHhF7dXVqHTfJPCRDaEbid/drOhgitgYku/letMUqOXFoWV0zIIUbjpdH2t+tYj4bQMRQ== + dependencies: + min-indent "^1.0.0" + strip-json-comments@^3.0.1: version "3.0.1" resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-3.0.1.tgz#85713975a91fb87bf1b305cca77395e40d2a64a7" From 62747233b1c9f9096650f8804587e9b33e80e191 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Sun, 3 Nov 2019 01:00:58 -0400 Subject: [PATCH 02/14] Separate test files slightly --- src/content/github.test.js | 14 ++++++++ src/content/index.test.js | 60 ------------------------------- src/content/stackOverflow.test.js | 12 +++++++ src/content/testUtils.js | 30 ++++++++++++++++ 4 files changed, 56 insertions(+), 60 deletions(-) create mode 100644 src/content/github.test.js delete mode 100644 src/content/index.test.js create mode 100644 src/content/stackOverflow.test.js create mode 100644 src/content/testUtils.js diff --git a/src/content/github.test.js b/src/content/github.test.js new file mode 100644 index 00000000..1ecf12e7 --- /dev/null +++ b/src/content/github.test.js @@ -0,0 +1,14 @@ +import { createStorage, expectToHavePrettierButton } from "./testUtils"; +import GitHub from "./github"; + +test("GitHub", async () => { + // Basis: https://github.com/prettier/prettier-chrome-extension/issues/new + const button = document.createElement("button"); + button.innerText = "Comment"; + document.body.appendChild(button); + // Hack around JSDOM's lack of offsetHeight support to fix isElementVisible + Object.defineProperty(document.body, "offsetHeight", { value: 1 }); + + new GitHub(await createStorage()); + expectToHavePrettierButton(); +}); diff --git a/src/content/index.test.js b/src/content/index.test.js deleted file mode 100644 index 92a4ece4..00000000 --- a/src/content/index.test.js +++ /dev/null @@ -1,60 +0,0 @@ -import "@testing-library/jest-dom/extend-expect"; -import GitHub from "./github"; -import StackOverflow from "./stackOverflow"; -import Storage from "./storage"; - -window.chrome = { - runtime: {}, - storage: { - onChanged: { - addListener() {} - }, - sync: { - get(callback) { - setTimeout(() => callback({})); - } - } - } -}; - -window.MutationObserver = class { - constructor() {} - observe() {} -}; - -describe("Prettier format button injection", () => { - function createStorage() { - const storage = new Storage(); - return storage.init(); - } - - function expectToHavePrettierButton() { - expect(document.querySelector(".prettier-btn")).toHaveTextContent( - "Prettier" - ); - } - - beforeEach(() => (document.body.innerHTML = "")); - - test("GitHub", async () => { - // Basis: https://github.com/prettier/prettier-chrome-extension/issues/new - const button = document.createElement("button"); - button.innerText = "Comment"; - document.body.appendChild(button); - // Hack around JSDOM's lack of offsetHeight support to fix isElementVisible - Object.defineProperty(document.body, "offsetHeight", { value: 1 }); - - new GitHub(await createStorage()); - expectToHavePrettierButton(); - }); - - test("Stack Overflow", async () => { - // Basis: https://stackoverflow.com/questions/51875054 - const button = document.createElement("div"); - button.className = "wmd-button-row"; - document.body.appendChild(button); - - new StackOverflow(await createStorage()); - expectToHavePrettierButton(); - }); -}); diff --git a/src/content/stackOverflow.test.js b/src/content/stackOverflow.test.js new file mode 100644 index 00000000..1b666396 --- /dev/null +++ b/src/content/stackOverflow.test.js @@ -0,0 +1,12 @@ +import { createStorage, expectToHavePrettierButton } from "./testUtils"; +import StackOverflow from "./stackOverflow"; + +test("Stack Overflow", async () => { + // Basis: https://stackoverflow.com/questions/51875054 + const button = document.createElement("div"); + button.className = "wmd-button-row"; + document.body.appendChild(button); + + new StackOverflow(await createStorage()); + expectToHavePrettierButton(); +}); diff --git a/src/content/testUtils.js b/src/content/testUtils.js new file mode 100644 index 00000000..07660275 --- /dev/null +++ b/src/content/testUtils.js @@ -0,0 +1,30 @@ +import "@testing-library/jest-dom/extend-expect"; +import Storage from "./storage"; + +window.chrome = { + runtime: {}, + storage: { + onChanged: { + addListener() {} + }, + sync: { + get(callback) { + setTimeout(() => callback({})); + } + } + } +}; + +window.MutationObserver = class { + constructor() {} + observe() {} +}; + +export function createStorage() { + const storage = new Storage(); + return storage.init(); +} + +export function expectToHavePrettierButton() { + expect(document.querySelector(".prettier-btn")).toHaveTextContent("Prettier"); +} From 6f6b0de864fff90011bcad0957d6ce09639c312c Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Sun, 17 Nov 2019 09:02:58 -0500 Subject: [PATCH 03/14] Update extension API mock for polyfill --- src/__mocks__/webextension-polyfill.js | 13 +++++++++++++ src/content/testUtils.js | 14 -------------- 2 files changed, 13 insertions(+), 14 deletions(-) create mode 100644 src/__mocks__/webextension-polyfill.js diff --git a/src/__mocks__/webextension-polyfill.js b/src/__mocks__/webextension-polyfill.js new file mode 100644 index 00000000..7b65340f --- /dev/null +++ b/src/__mocks__/webextension-polyfill.js @@ -0,0 +1,13 @@ +export default { + runtime: {}, + storage: { + onChanged: { + addListener() {} + }, + sync: { + get() { + return new Promise(resolve => setTimeout(() => resolve({}))); + } + } + } +}; diff --git a/src/content/testUtils.js b/src/content/testUtils.js index 07660275..80c02d47 100644 --- a/src/content/testUtils.js +++ b/src/content/testUtils.js @@ -1,20 +1,6 @@ import "@testing-library/jest-dom/extend-expect"; import Storage from "./storage"; -window.chrome = { - runtime: {}, - storage: { - onChanged: { - addListener() {} - }, - sync: { - get(callback) { - setTimeout(() => callback({})); - } - } - } -}; - window.MutationObserver = class { constructor() {} observe() {} From 20cbbd27d4ef3d3c2cd2bde75a733e54b1d42e50 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Wed, 20 Nov 2019 08:35:38 -0500 Subject: [PATCH 04/14] Simplify browser.storage.sync.get mock --- src/__mocks__/webextension-polyfill.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/__mocks__/webextension-polyfill.js b/src/__mocks__/webextension-polyfill.js index 7b65340f..4629eeea 100644 --- a/src/__mocks__/webextension-polyfill.js +++ b/src/__mocks__/webextension-polyfill.js @@ -6,7 +6,7 @@ export default { }, sync: { get() { - return new Promise(resolve => setTimeout(() => resolve({}))); + return Promise.resolve({}); } } } From fd282479a617a36b67126dca23f3e47c0e01b375 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Wed, 20 Nov 2019 10:17:33 -0500 Subject: [PATCH 05/14] Upgrade eslint-plugin-jest-dom for new rule --- package.json | 2 +- src/content/.eslintrc.json | 5 ++++- yarn.lock | 8 ++++---- 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/package.json b/package.json index 53226c02..2b2bbac2 100644 --- a/package.json +++ b/package.json @@ -32,7 +32,7 @@ "copy-webpack-plugin": "5.0.5", "eslint": "6.6.0", "eslint-config-prettier": "6.5.0", - "eslint-plugin-jest-dom": "1.1.3", + "eslint-plugin-jest-dom": "1.2.1", "eslint-plugin-prettier": "3.1.1", "eslint-plugin-react": "7.16.0", "eslint-plugin-react-hooks": "2.3.0", diff --git a/src/content/.eslintrc.json b/src/content/.eslintrc.json index 443de2fa..c54890a0 100644 --- a/src/content/.eslintrc.json +++ b/src/content/.eslintrc.json @@ -2,7 +2,10 @@ "overrides": [ { "files": "*test*.js", - "extends": ["plugin:jest-dom/recommended"] + "extends": ["plugin:jest-dom/recommended"], + "rules": { + "jest-dom/prefer-to-have-attribute": "error" + } } ] } diff --git a/yarn.lock b/yarn.lock index 766b0193..be3577c8 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2275,10 +2275,10 @@ eslint-config-prettier@6.5.0: dependencies: get-stdin "^6.0.0" -eslint-plugin-jest-dom@1.1.3: - version "1.1.3" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-1.1.3.tgz#36ba066de1671433b5d5c2ab90eda8f8e47f0a2b" - integrity sha512-fhwdRaZRU0nsqxzKI13fm1cHYTU+5FLgJRn27mcKAC16ajGoefMimHrXPdweX/ht8susO7Q+z4DzY+wKuYQjFg== +eslint-plugin-jest-dom@1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-1.2.1.tgz#de48e13a900d37613288e3e30a32edb5157895c1" + integrity sha512-rCKs6+JVA/312pB1rbcD7HEr3LbgTZRw3uSrg0Si8J8PCgrbBwJ/6heuyUE2OWntQT/8/aJgWijBmvG2q9uJrA== dependencies: requireindex "~1.2.0" From 5c3373c6ac20e01ba01100ac5be3741dd261da95 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Wed, 20 Nov 2019 20:00:21 -0500 Subject: [PATCH 06/14] Emulate a matching GitHub pathname to fix tests --- src/content/github.test.js | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/src/content/github.test.js b/src/content/github.test.js index 1ecf12e7..525e321c 100644 --- a/src/content/github.test.js +++ b/src/content/github.test.js @@ -8,6 +8,10 @@ test("GitHub", async () => { document.body.appendChild(button); // Hack around JSDOM's lack of offsetHeight support to fix isElementVisible Object.defineProperty(document.body, "offsetHeight", { value: 1 }); + // Emulate a matching GitHub pathname + Object.defineProperty(window, "location", { + value: { pathname: "/prettier/prettier-chrome-extension/issues/new" } + }); new GitHub(await createStorage()); expectToHavePrettierButton(); From 68299699b5b7d782be0a46cdff601ea03e781582 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Wed, 20 Nov 2019 20:40:49 -0500 Subject: [PATCH 07/14] Collect and ignore test coverage --- .gitignore | 1 + .prettierignore | 1 + package.json | 3 +++ 3 files changed, 5 insertions(+) diff --git a/.gitignore b/.gitignore index 10e081f3..3eaa7bf1 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ node_modules extension extension.zip +coverage diff --git a/.prettierignore b/.prettierignore index af66bf58..3fbe9d36 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,2 @@ extension +coverage diff --git a/package.json b/package.json index 41b7e9f9..ceb23ec8 100644 --- a/package.json +++ b/package.json @@ -58,5 +58,8 @@ "hooks": { "pre-commit": "lint-staged" } + }, + "jest": { + "collectCoverage": true } } From 3ac5a36cddf026dd51a7d814944233a461074a4f Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Thu, 21 Nov 2019 10:38:15 -0500 Subject: [PATCH 08/14] Add more tests with DOM testing library --- package.json | 2 + src/__mocks__/webextension-polyfill.js | 23 ++++++++-- src/content/.eslintrc.json | 5 ++- src/content/button.test.js | 16 +++++++ src/content/domUtils.test.js | 20 +++++++++ src/content/extension.test.js | 8 ++++ src/content/github.test.js | 5 ++- src/content/stackOverflow.test.js | 5 ++- src/content/storage.test.js | 12 ++++++ src/content/testUtils.js | 4 -- yarn.lock | 58 +++++++++++++++++++++++++- 11 files changed, 143 insertions(+), 15 deletions(-) create mode 100644 src/content/button.test.js create mode 100644 src/content/domUtils.test.js create mode 100644 src/content/extension.test.js create mode 100644 src/content/storage.test.js diff --git a/package.json b/package.json index ceb23ec8..0a100240 100644 --- a/package.json +++ b/package.json @@ -27,6 +27,7 @@ "@babel/plugin-transform-modules-commonjs": "7.7.0", "@babel/preset-react": "7.7.0", "@ffflorian/jszip-cli": "3.0.2", + "@testing-library/dom": "6.10.1", "@testing-library/jest-dom": "4.2.0", "babel-loader": "8.0.6", "copy-webpack-plugin": "5.0.5", @@ -36,6 +37,7 @@ "eslint-plugin-prettier": "3.1.1", "eslint-plugin-react": "7.16.0", "eslint-plugin-react-hooks": "2.3.0", + "eslint-plugin-testing-library": "1.3.2", "husky": "3.1.0", "jest": "24.9.0", "lint-staged": "9.4.3", diff --git a/src/__mocks__/webextension-polyfill.js b/src/__mocks__/webextension-polyfill.js index 4629eeea..1335b009 100644 --- a/src/__mocks__/webextension-polyfill.js +++ b/src/__mocks__/webextension-polyfill.js @@ -1,12 +1,27 @@ +const listeners = []; +let storageItems = {}; + +function callListeners() { + for (const listener of listeners) { + listener(); + } +} + export default { - runtime: {}, storage: { onChanged: { - addListener() {} + addListener(listener) { + listeners.push(listener); + } }, sync: { - get() { - return Promise.resolve({}); + async get() { + return storageItems; + }, + async set(newItems) { + await Promise.resolve(); + storageItems = { ...storageItems, ...newItems }; + callListeners(); } } } diff --git a/src/content/.eslintrc.json b/src/content/.eslintrc.json index c54890a0..e3049806 100644 --- a/src/content/.eslintrc.json +++ b/src/content/.eslintrc.json @@ -2,7 +2,10 @@ "overrides": [ { "files": "*test*.js", - "extends": ["plugin:jest-dom/recommended"], + "extends": [ + "plugin:jest-dom/recommended", + "plugin:testing-library/recommended" + ], "rules": { "jest-dom/prefer-to-have-attribute": "error" } diff --git a/src/content/button.test.js b/src/content/button.test.js new file mode 100644 index 00000000..48924b89 --- /dev/null +++ b/src/content/button.test.js @@ -0,0 +1,16 @@ +import "./testUtils"; +import renderButton from "./button"; + +test("renderButton", () => { + const button = renderButton(document.body, { + classes: ["btn2"], + style: { color: "blue" } + }); + + expect(button).toBeInstanceOf(HTMLButtonElement); + expect(button).toHaveTextContent("Prettier"); + expect(button).toHaveAttribute("type", "button"); + expect(button).toHaveClass("btn", "btn2"); + expect(button).toHaveStyle("color: blue;"); + expect(button).toBeInTheDocument(); +}); diff --git a/src/content/domUtils.test.js b/src/content/domUtils.test.js new file mode 100644 index 00000000..58c60b6e --- /dev/null +++ b/src/content/domUtils.test.js @@ -0,0 +1,20 @@ +import { findWithClass, isElementVisible } from "./domUtils"; +import renderButton from "./button"; + +test("findWithClass", () => { + // Basis: https://github.com/prettier/prettier-chrome-extension/issues/new + const textarea = document.createElement("textarea"); + textarea.className = "comment-form-textarea"; + document.body.appendChild(textarea); + const prettierButton = renderButton(document.body); + + expect(findWithClass(prettierButton, "comment-form-textarea")).toBe(textarea); +}); + +test("isElementVisible", () => { + const element = document.createElement("div"); + expect(isElementVisible(element)).toBeFalsy(); + + Object.defineProperty(element, "offsetHeight", { value: 1 }); + expect(isElementVisible(element)).toBeTruthy(); +}); diff --git a/src/content/extension.test.js b/src/content/extension.test.js new file mode 100644 index 00000000..f43dabe4 --- /dev/null +++ b/src/content/extension.test.js @@ -0,0 +1,8 @@ +import "./testUtils"; +import Extension from "./Extension"; +import { queryByText } from "@testing-library/dom"; + +test("Extension", async () => { + await new Extension().init(); + expect(queryByText(document, "Prettier")).not.toBeInTheDocument(); +}); diff --git a/src/content/github.test.js b/src/content/github.test.js index 525e321c..fed0de51 100644 --- a/src/content/github.test.js +++ b/src/content/github.test.js @@ -1,5 +1,6 @@ -import { createStorage, expectToHavePrettierButton } from "./testUtils"; import GitHub from "./github"; +import { createStorage } from "./testUtils"; +import { getByText } from "@testing-library/dom"; test("GitHub", async () => { // Basis: https://github.com/prettier/prettier-chrome-extension/issues/new @@ -14,5 +15,5 @@ test("GitHub", async () => { }); new GitHub(await createStorage()); - expectToHavePrettierButton(); + getByText(document, "Prettier"); }); diff --git a/src/content/stackOverflow.test.js b/src/content/stackOverflow.test.js index 1b666396..7d39b9c4 100644 --- a/src/content/stackOverflow.test.js +++ b/src/content/stackOverflow.test.js @@ -1,5 +1,6 @@ -import { createStorage, expectToHavePrettierButton } from "./testUtils"; import StackOverflow from "./stackOverflow"; +import { createStorage } from "./testUtils"; +import { getByText } from "@testing-library/dom"; test("Stack Overflow", async () => { // Basis: https://stackoverflow.com/questions/51875054 @@ -8,5 +9,5 @@ test("Stack Overflow", async () => { document.body.appendChild(button); new StackOverflow(await createStorage()); - expectToHavePrettierButton(); + getByText(document, "Prettier"); }); diff --git a/src/content/storage.test.js b/src/content/storage.test.js new file mode 100644 index 00000000..3493bab1 --- /dev/null +++ b/src/content/storage.test.js @@ -0,0 +1,12 @@ +import Storage from "./storage"; +import browser from "webextension-polyfill"; + +test("Storage", async () => { + const storage = new Storage(); + expect(storage.get()).toEqual({}); + + await storage.init(); + await browser.storage.sync.set({ valid: true }); + expect(storage.get("valid")).toBeTruthy(); + expect(storage.get("invalid")).toBeNull(); +}); diff --git a/src/content/testUtils.js b/src/content/testUtils.js index 80c02d47..0df81ef8 100644 --- a/src/content/testUtils.js +++ b/src/content/testUtils.js @@ -10,7 +10,3 @@ export function createStorage() { const storage = new Storage(); return storage.init(); } - -export function expectToHavePrettierButton() { - expect(document.querySelector(".prettier-btn")).toHaveTextContent("Prettier"); -} diff --git a/yarn.lock b/yarn.lock index ef1c863f..67c80e23 100644 --- a/yarn.lock +++ b/yarn.lock @@ -266,6 +266,13 @@ dependencies: regenerator-runtime "^0.13.2" +"@babel/runtime@^7.6.2": + version "7.7.2" + resolved "https://registry.yarnpkg.com/@babel/runtime/-/runtime-7.7.2.tgz#111a78002a5c25fc8e3361bedc9529c696b85a6a" + integrity sha512-JONRbXbTXc9WQE2mAZd1p0Z3DZ/6vaQIkgYMSTP3KjRCyd7rCZCcfhCyX+YjwcKxcZ82UrxbRD358bpExNgrjw== + dependencies: + regenerator-runtime "^0.13.2" + "@babel/template@^7.1.0", "@babel/template@^7.4.0", "@babel/template@^7.6.0": version "7.6.0" resolved "https://registry.yarnpkg.com/@babel/template/-/template-7.6.0.tgz#7f0159c7f5012230dad64cca42ec9bdb5c9536e6" @@ -528,6 +535,23 @@ dependencies: any-observable "^0.3.0" +"@sheerun/mutationobserver-shim@^0.3.2": + version "0.3.2" + resolved "https://registry.yarnpkg.com/@sheerun/mutationobserver-shim/-/mutationobserver-shim-0.3.2.tgz#8013f2af54a2b7d735f71560ff360d3a8176a87b" + integrity sha512-vTCdPp/T/Q3oSqwHmZ5Kpa9oI7iLtGl3RQaA/NyLHikvcrPxACkkKVr/XzkSPJWXHRhKGzVvb0urJsbMlRxi1Q== + +"@testing-library/dom@6.10.1": + version "6.10.1" + resolved "https://registry.yarnpkg.com/@testing-library/dom/-/dom-6.10.1.tgz#da5bf5065d3f9e484aef4cc495f4e1a5bea6df2e" + integrity sha512-5BPKxaO+zSJDUbVZBRNf9KrmDkm/EcjjaHSg3F9+031VZyPACKXlwLBjVzZxheunT9m72DoIq7WvyE457/Xweg== + dependencies: + "@babel/runtime" "^7.6.2" + "@sheerun/mutationobserver-shim" "^0.3.2" + "@types/testing-library__dom" "^6.0.0" + aria-query "3.0.0" + pretty-format "^24.9.0" + wait-for-expect "^3.0.0" + "@testing-library/jest-dom@4.2.0": version "4.2.0" resolved "https://registry.yarnpkg.com/@testing-library/jest-dom/-/jest-dom-4.2.0.tgz#32f8df3a78511b347d39374ea89dc8e0a1c2fb69" @@ -635,6 +659,13 @@ resolved "https://registry.yarnpkg.com/@types/stack-utils/-/stack-utils-1.0.1.tgz#0a851d3bd96498fa25c33ab7278ed3bd65f06c3e" integrity sha512-l42BggppR6zLmpfU6fq9HEa2oGPEI8yrSPL3GITjfRInppYFahObbIQOQK3UGxEnyQpltZLaPe75046NOZQikw== +"@types/testing-library__dom@^6.0.0": + version "6.10.0" + resolved "https://registry.yarnpkg.com/@types/testing-library__dom/-/testing-library__dom-6.10.0.tgz#590d76e3875a7c536dc744eb530cbf51b6483404" + integrity sha512-mL/GMlyQxiZplbUuFNwA0vAI3k3uJNSf6slr5AVve9TXmfLfyefNT0uHHnxwdYuPMxYD5gI/+dgAvc/5opW9JQ== + dependencies: + pretty-format "^24.3.0" + "@types/yargs-parser@*": version "13.1.0" resolved "https://registry.yarnpkg.com/@types/yargs-parser/-/yargs-parser-13.1.0.tgz#c563aa192f39350a1d18da36c5a8da382bbd8228" @@ -963,6 +994,14 @@ argparse@^1.0.7: dependencies: sprintf-js "~1.0.2" +aria-query@3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/aria-query/-/aria-query-3.0.0.tgz#65b3fcc1ca1155a8c9ae64d6eee297f15d5133cc" + integrity sha1-ZbP8wcoRVajJrmTW7uKX8V1RM8w= + dependencies: + ast-types-flow "0.0.7" + commander "^2.11.0" + arr-diff@^4.0.0: version "4.0.0" resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-4.0.0.tgz#d6461074febfec71e7e15235761a329a5dc7c520" @@ -1052,6 +1091,11 @@ assign-symbols@^1.0.0: resolved "https://registry.yarnpkg.com/assign-symbols/-/assign-symbols-1.0.0.tgz#59667f41fadd4f20ccbc2bb96b8d4f7f78ec0367" integrity sha1-WWZ/QfrdTyDMvCu5a41Pf3jsA2c= +ast-types-flow@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ast-types-flow/-/ast-types-flow-0.0.7.tgz#f70b735c6bca1a5c9c22d982c3e39e7feba3bdad" + integrity sha1-9wtzXGvKGlycItmCw+Oef+ujva0= + astral-regex@^1.0.0: version "1.0.0" resolved "https://registry.yarnpkg.com/astral-regex/-/astral-regex-1.0.0.tgz#6c8c3fb827dd43ee3918f27b82782ab7658a6fd9" @@ -1615,7 +1659,7 @@ commander@3.0.2: resolved "https://registry.yarnpkg.com/commander/-/commander-3.0.2.tgz#6837c3fb677ad9933d1cfba42dd14d5117d6b39e" integrity sha512-Gar0ASD4BDyKC4hl4DwHqDrmvjoxWKZigVnAbn5H1owvm4CxCPdb0HQDehwNYMJpla5+M2tPmPARzhtYuwpHow== -commander@^2.20.0, commander@~2.20.3: +commander@^2.11.0, commander@^2.20.0, commander@~2.20.3: version "2.20.3" resolved "https://registry.yarnpkg.com/commander/-/commander-2.20.3.tgz#fd485e84c03eb4881c20722ba48035e8531aeb33" integrity sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ== @@ -2309,6 +2353,11 @@ eslint-plugin-react@7.16.0: prop-types "^15.7.2" resolve "^1.12.0" +eslint-plugin-testing-library@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/eslint-plugin-testing-library/-/eslint-plugin-testing-library-1.3.2.tgz#1aab27c166c6c6e1a98e578fb38f7e143a850b99" + integrity sha512-ZrJGex7YbaymUvSxgMJp1MmqqJo0OvElcd3XImtIHBbzPPnBhvExl+s+//yYlP8QO+jZCvyHGx/4rGGsKU2UTw== + eslint-scope@^4.0.3: version "4.0.3" resolved "https://registry.yarnpkg.com/eslint-scope/-/eslint-scope-4.0.3.tgz#ca03833310f6889a3264781aa82e63eb9cfe7848" @@ -5479,7 +5528,7 @@ pretty-bytes@^1.0.2: get-stdin "^4.0.1" meow "^3.1.0" -pretty-format@^24.0.0, pretty-format@^24.9.0: +pretty-format@^24.0.0, pretty-format@^24.3.0, pretty-format@^24.9.0: version "24.9.0" resolved "https://registry.yarnpkg.com/pretty-format/-/pretty-format-24.9.0.tgz#12fac31b37019a4eea3c11aa9a959eb7628aa7c9" integrity sha512-00ZMZUiHaJrNfk33guavqgvfJS30sLYf0f8+Srklv0AMPodGGHcoHgksZ3OThYnIvOd+8yMCn0YiEOogjlgsnA== @@ -7054,6 +7103,11 @@ w3c-hr-time@^1.0.1: dependencies: browser-process-hrtime "^0.1.2" +wait-for-expect@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/wait-for-expect/-/wait-for-expect-3.0.1.tgz#ec204a76b0038f17711e575720aaf28505ac7185" + integrity sha512-3Ha7lu+zshEG/CeHdcpmQsZnnZpPj/UsG3DuKO8FskjuDbkx3jE3845H+CuwZjA2YWYDfKMU2KhnCaXMLd3wVw== + walker@^1.0.7, walker@~1.0.5: version "1.0.7" resolved "https://registry.yarnpkg.com/walker/-/walker-1.0.7.tgz#2f7f9b8fd10d677262b18a884e28d19618e028fb" From 3a88388ab04f9735e3ec998b2e38d29c318d96c4 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Thu, 21 Nov 2019 11:16:48 -0500 Subject: [PATCH 09/14] Fix case sensitive import --- src/content/extension.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/content/extension.test.js b/src/content/extension.test.js index f43dabe4..cc8b8642 100644 --- a/src/content/extension.test.js +++ b/src/content/extension.test.js @@ -1,5 +1,5 @@ import "./testUtils"; -import Extension from "./Extension"; +import Extension from "./extension"; import { queryByText } from "@testing-library/dom"; test("Extension", async () => { From 4c3067a4512a2647e41f58573684d553af654e30 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Thu, 21 Nov 2019 19:56:54 -0500 Subject: [PATCH 10/14] Test all renderButton use cases --- src/content/button.test.js | 32 +++++++++++++++++++++++--------- 1 file changed, 23 insertions(+), 9 deletions(-) diff --git a/src/content/button.test.js b/src/content/button.test.js index 48924b89..20e1b6d6 100644 --- a/src/content/button.test.js +++ b/src/content/button.test.js @@ -1,16 +1,30 @@ import "./testUtils"; import renderButton from "./button"; -test("renderButton", () => { - const button = renderButton(document.body, { +const buttonRef = {}; +const element = document.createElement("div"); + +beforeEach(() => (document.body.innerHTML = "")); + +test.each([ + [{}, [element, buttonRef]], + [{ append: false }, [buttonRef, element]], + [{ refNode: element }, [buttonRef, element]] +])("renderButton with %p", (positionOptions, expectedOrder) => { + document.body.appendChild(element); + buttonRef.current = renderButton(document.body, { classes: ["btn2"], - style: { color: "blue" } + style: { color: "blue" }, + ...positionOptions }); - expect(button).toBeInstanceOf(HTMLButtonElement); - expect(button).toHaveTextContent("Prettier"); - expect(button).toHaveAttribute("type", "button"); - expect(button).toHaveClass("btn", "btn2"); - expect(button).toHaveStyle("color: blue;"); - expect(button).toBeInTheDocument(); + expect(Array.from(document.body.childNodes)).toEqual( + expectedOrder.map(thing => thing.current || thing) + ); + expect(buttonRef.current).toBeInstanceOf(HTMLButtonElement); + expect(buttonRef.current).toHaveTextContent("Prettier"); + expect(buttonRef.current).toHaveAttribute("type", "button"); + expect(buttonRef.current).toHaveClass("btn", "btn2"); + expect(buttonRef.current).toHaveStyle("color: blue;"); + expect(buttonRef.current).toBeInTheDocument(); }); From a46c30da32f862cd4b3932a3e38a733c6f68b57a Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Thu, 21 Nov 2019 22:07:53 -0500 Subject: [PATCH 11/14] Test formatting for GitHub and Stack Overflow --- src/content/github.test.js | 8 +++++--- src/content/stackOverflow.test.js | 8 +++++--- src/content/testUtils.js | 14 ++++++++++++-- 3 files changed, 22 insertions(+), 8 deletions(-) diff --git a/src/content/github.test.js b/src/content/github.test.js index fed0de51..946ba95c 100644 --- a/src/content/github.test.js +++ b/src/content/github.test.js @@ -1,12 +1,14 @@ +import { createStorage, expectToFormat } from "./testUtils"; import GitHub from "./github"; -import { createStorage } from "./testUtils"; -import { getByText } from "@testing-library/dom"; test("GitHub", async () => { // Basis: https://github.com/prettier/prettier-chrome-extension/issues/new const button = document.createElement("button"); button.innerText = "Comment"; document.body.appendChild(button); + const textarea = document.createElement("textarea"); + textarea.className = "comment-form-textarea"; + document.body.appendChild(textarea); // Hack around JSDOM's lack of offsetHeight support to fix isElementVisible Object.defineProperty(document.body, "offsetHeight", { value: 1 }); // Emulate a matching GitHub pathname @@ -15,5 +17,5 @@ test("GitHub", async () => { }); new GitHub(await createStorage()); - getByText(document, "Prettier"); + expectToFormat(textarea); }); diff --git a/src/content/stackOverflow.test.js b/src/content/stackOverflow.test.js index 7d39b9c4..36623579 100644 --- a/src/content/stackOverflow.test.js +++ b/src/content/stackOverflow.test.js @@ -1,13 +1,15 @@ +import { createStorage, expectToFormat } from "./testUtils"; import StackOverflow from "./stackOverflow"; -import { createStorage } from "./testUtils"; -import { getByText } from "@testing-library/dom"; test("Stack Overflow", async () => { // Basis: https://stackoverflow.com/questions/51875054 const button = document.createElement("div"); button.className = "wmd-button-row"; document.body.appendChild(button); + const textarea = document.createElement("textarea"); + textarea.className = "wmd-input"; + document.body.appendChild(textarea); new StackOverflow(await createStorage()); - getByText(document, "Prettier"); + expectToFormat(textarea); }); diff --git a/src/content/testUtils.js b/src/content/testUtils.js index 0df81ef8..aeb1babd 100644 --- a/src/content/testUtils.js +++ b/src/content/testUtils.js @@ -1,4 +1,5 @@ import "@testing-library/jest-dom/extend-expect"; +import { fireEvent, getByText } from "@testing-library/dom"; import Storage from "./storage"; window.MutationObserver = class { @@ -6,7 +7,16 @@ window.MutationObserver = class { observe() {} }; -export function createStorage() { +export async function createStorage() { const storage = new Storage(); - return storage.init(); + await storage.init(); + return storage; +} + +export function expectToFormat(textarea) { + fireEvent.change(textarea, { + target: { value: "```js\nconst variable=value\n```" } + }); + fireEvent.click(getByText(document, "Prettier")); + expect(textarea).toHaveValue("```js\nconst variable = value;\n```\n"); } From f78ff1148dc620f4c8abf48a9832540c229d9c64 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Thu, 21 Nov 2019 22:08:36 -0500 Subject: [PATCH 12/14] Restore findWithClass coverage --- src/content/domUtils.test.js | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/content/domUtils.test.js b/src/content/domUtils.test.js index 58c60b6e..c0f76625 100644 --- a/src/content/domUtils.test.js +++ b/src/content/domUtils.test.js @@ -2,12 +2,13 @@ import { findWithClass, isElementVisible } from "./domUtils"; import renderButton from "./button"; test("findWithClass", () => { + const prettierButton = renderButton(document.body); + expect(findWithClass(prettierButton, "comment-form-textarea")).toBeNull(); + // Basis: https://github.com/prettier/prettier-chrome-extension/issues/new const textarea = document.createElement("textarea"); textarea.className = "comment-form-textarea"; document.body.appendChild(textarea); - const prettierButton = renderButton(document.body); - expect(findWithClass(prettierButton, "comment-form-textarea")).toBe(textarea); }); From 80e8f2d4fb775aec5bf68843d289891cae30ff60 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Mon, 9 Dec 2019 18:54:23 -0500 Subject: [PATCH 13/14] Upgrade eslint-plugin-jest-dom --- package.json | 2 +- src/content/.eslintrc.json | 5 +---- yarn.lock | 8 ++++---- 3 files changed, 6 insertions(+), 9 deletions(-) diff --git a/package.json b/package.json index 0a100240..94fb4e94 100644 --- a/package.json +++ b/package.json @@ -33,7 +33,7 @@ "copy-webpack-plugin": "5.0.5", "eslint": "6.6.0", "eslint-config-prettier": "6.5.0", - "eslint-plugin-jest-dom": "1.2.1", + "eslint-plugin-jest-dom": "1.3.0", "eslint-plugin-prettier": "3.1.1", "eslint-plugin-react": "7.16.0", "eslint-plugin-react-hooks": "2.3.0", diff --git a/src/content/.eslintrc.json b/src/content/.eslintrc.json index e3049806..58faf3eb 100644 --- a/src/content/.eslintrc.json +++ b/src/content/.eslintrc.json @@ -5,10 +5,7 @@ "extends": [ "plugin:jest-dom/recommended", "plugin:testing-library/recommended" - ], - "rules": { - "jest-dom/prefer-to-have-attribute": "error" - } + ] } ] } diff --git a/yarn.lock b/yarn.lock index 67c80e23..2e2e48c5 100644 --- a/yarn.lock +++ b/yarn.lock @@ -2319,10 +2319,10 @@ eslint-config-prettier@6.5.0: dependencies: get-stdin "^6.0.0" -eslint-plugin-jest-dom@1.2.1: - version "1.2.1" - resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-1.2.1.tgz#de48e13a900d37613288e3e30a32edb5157895c1" - integrity sha512-rCKs6+JVA/312pB1rbcD7HEr3LbgTZRw3uSrg0Si8J8PCgrbBwJ/6heuyUE2OWntQT/8/aJgWijBmvG2q9uJrA== +eslint-plugin-jest-dom@1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/eslint-plugin-jest-dom/-/eslint-plugin-jest-dom-1.3.0.tgz#8cff5077af4647d29fa04838b4ef4f7d805b782d" + integrity sha512-e1V5Z4xDz0z62Yy4A3nlMU3HzGlHCWiCekXMpe6zfEmElmeEpPYRa35Ehzn9Mn9IGKa6T11SXyRH1KMnFMcZlg== dependencies: requireindex "~1.2.0" From 2aff8df642a89f7b113d21a7a2c80fbae43a4ea9 Mon Sep 17 00:00:00 2001 From: Nick McCurdy Date: Sat, 29 Aug 2020 19:08:14 -0400 Subject: [PATCH 14/14] Format with Prettier --- src/__mocks__/webextension-polyfill.js | 8 ++++---- src/content/button.test.js | 6 +++--- src/content/github.test.js | 2 +- src/content/testUtils.js | 2 +- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/src/__mocks__/webextension-polyfill.js b/src/__mocks__/webextension-polyfill.js index 1335b009..f762214e 100644 --- a/src/__mocks__/webextension-polyfill.js +++ b/src/__mocks__/webextension-polyfill.js @@ -12,7 +12,7 @@ export default { onChanged: { addListener(listener) { listeners.push(listener); - } + }, }, sync: { async get() { @@ -22,7 +22,7 @@ export default { await Promise.resolve(); storageItems = { ...storageItems, ...newItems }; callListeners(); - } - } - } + }, + }, + }, }; diff --git a/src/content/button.test.js b/src/content/button.test.js index 20e1b6d6..00c5bfd0 100644 --- a/src/content/button.test.js +++ b/src/content/button.test.js @@ -9,17 +9,17 @@ beforeEach(() => (document.body.innerHTML = "")); test.each([ [{}, [element, buttonRef]], [{ append: false }, [buttonRef, element]], - [{ refNode: element }, [buttonRef, element]] + [{ refNode: element }, [buttonRef, element]], ])("renderButton with %p", (positionOptions, expectedOrder) => { document.body.appendChild(element); buttonRef.current = renderButton(document.body, { classes: ["btn2"], style: { color: "blue" }, - ...positionOptions + ...positionOptions, }); expect(Array.from(document.body.childNodes)).toEqual( - expectedOrder.map(thing => thing.current || thing) + expectedOrder.map((thing) => thing.current || thing) ); expect(buttonRef.current).toBeInstanceOf(HTMLButtonElement); expect(buttonRef.current).toHaveTextContent("Prettier"); diff --git a/src/content/github.test.js b/src/content/github.test.js index 946ba95c..63a23e43 100644 --- a/src/content/github.test.js +++ b/src/content/github.test.js @@ -13,7 +13,7 @@ test("GitHub", async () => { Object.defineProperty(document.body, "offsetHeight", { value: 1 }); // Emulate a matching GitHub pathname Object.defineProperty(window, "location", { - value: { pathname: "/prettier/prettier-chrome-extension/issues/new" } + value: { pathname: "/prettier/prettier-chrome-extension/issues/new" }, }); new GitHub(await createStorage()); diff --git a/src/content/testUtils.js b/src/content/testUtils.js index aeb1babd..e7375f38 100644 --- a/src/content/testUtils.js +++ b/src/content/testUtils.js @@ -15,7 +15,7 @@ export async function createStorage() { export function expectToFormat(textarea) { fireEvent.change(textarea, { - target: { value: "```js\nconst variable=value\n```" } + target: { value: "```js\nconst variable=value\n```" }, }); fireEvent.click(getByText(document, "Prettier")); expect(textarea).toHaveValue("```js\nconst variable = value;\n```\n");