From 76f6be040efb1127f32bc24f4f6c4501ad42ba45 Mon Sep 17 00:00:00 2001 From: Nathan Arthur Date: Tue, 16 Jul 2024 10:55:22 -0400 Subject: [PATCH] use pixelteer for snapshot testing --- package.json | 3 +- pnpm-lock.yaml | 327 +++++++++++++++++++-------------- scripts/puppeteer.spec.ts | 73 -------- scripts/puppeteer.ts | 152 ++++----------- src/lib/test/createReport.ts | 79 -------- src/lib/test/readScreenshot.ts | 7 - src/lib/test/resizeImage.ts | 23 --- src/lib/test/saveScreenshot.ts | 26 --- vitest.setup.ts | 7 - 9 files changed, 224 insertions(+), 473 deletions(-) delete mode 100644 scripts/puppeteer.spec.ts delete mode 100644 src/lib/test/createReport.ts delete mode 100644 src/lib/test/readScreenshot.ts delete mode 100644 src/lib/test/resizeImage.ts delete mode 100644 src/lib/test/saveScreenshot.ts diff --git a/package.json b/package.json index 02ca6d4..099fc97 100644 --- a/package.json +++ b/package.json @@ -67,9 +67,10 @@ "diffable-html": "^5.0.0", "eslint": "^8.49.0", "pixelmatch": "^5.3.0", + "pixelteer": "github:narthur/pixelteer", "pngjs": "^7.0.0", "prettier": "3.0.3", - "puppeteer": "^21.3.8", + "puppeteer": "22.6.5", "typescript": "^5.2.2", "vite": "^4.4.9", "vitest": "^2.0.3" diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index c90fb61..0cf4970 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -132,6 +132,9 @@ importers: pixelmatch: specifier: ^5.3.0 version: 5.3.0 + pixelteer: + specifier: github:narthur/pixelteer + version: https://codeload.github.com/narthur/pixelteer/tar.gz/4f4e26f9abb2981a1dad3e0f5b8b078835c9ceb3(puppeteer@22.6.5(typescript@5.2.2)) pngjs: specifier: ^7.0.0 version: 7.0.0 @@ -139,8 +142,8 @@ importers: specifier: 3.0.3 version: 3.0.3 puppeteer: - specifier: ^21.3.8 - version: 21.3.8(typescript@5.2.2) + specifier: 22.6.5 + version: 22.6.5(typescript@5.2.2) typescript: specifier: ^5.2.2 version: 5.2.2 @@ -197,10 +200,6 @@ packages: resolution: {integrity: sha512-A+0c7k/Xy293xx6odsYZuXiaHO0PL+bnDoXOc47sGDF5ffIKdKQGRPFl2NMlCF4L0NqN4Ynbgnaip+pPF0s7pQ==} engines: {node: '>=18.14.1'} - '@babel/code-frame@7.22.13': - resolution: {integrity: sha512-XktuhWlJ5g+3TJXc5upd9Ks1HutSArik6jf2eAjYFyIOf4ej3RN+184cZbzDvbPnuTJIUhPKKJE3cIsYTiAT3w==} - engines: {node: '>=6.9.0'} - '@babel/code-frame@7.23.5': resolution: {integrity: sha512-CgH3s1a96LipHCmSUmYFPwY7MNx8C3avkq7i4Wl3cfa662ldtUe4VM1TPXX70pfmrlWTb6jLqTYrZyT2ZTJBgA==} engines: {node: '>=6.9.0'} @@ -275,10 +274,6 @@ packages: resolution: {integrity: sha512-ulDZdc0Aj5uLc5nETsa7EPx2L7rM0YJM8r7ck7U73AXi7qOV44IHHRAYZHY6iU1rr3C5N4NtTmMRUJP6kwCWeA==} engines: {node: '>=6.9.0'} - '@babel/highlight@7.22.20': - resolution: {integrity: sha512-dkdMCN3py0+ksCgYmGG8jKeGA/8Tk+gJwSYYlFGxG5lmhfKNoAy004YpLxpS1W2J8m/EK2Ew+yOs9pVRwO89mg==} - engines: {node: '>=6.9.0'} - '@babel/highlight@7.23.4': resolution: {integrity: sha512-acGdbYSfp2WheJoJm/EBBBLh/ID8KDc64ISZ9DYtBmC8/Q204PZJLHyzeB5qMzJ5trcOkybd78M4x2KWsUq++A==} engines: {node: '>=6.9.0'} @@ -952,9 +947,9 @@ packages: '@polka/url@1.0.0-next.23': resolution: {integrity: sha512-C16M+IYz0rgRhWZdCmK+h58JMv8vijAA61gmz2rspCSwKwzBebpdcsiUmwrtJRdphuY30i6BSLEOP8ppbNLyLg==} - '@puppeteer/browsers@1.7.1': - resolution: {integrity: sha512-nIb8SOBgDEMFY2iS2MdnUZOg2ikcYchRrBoF+wtdjieRFKR2uGRipHY/oFLo+2N6anDualyClPzGywTHRGrLfw==} - engines: {node: '>=16.3.0'} + '@puppeteer/browsers@2.2.2': + resolution: {integrity: sha512-hZ/JhxPIceWaGSEzUZp83/8M49CoxlkuThfTR7t4AoCu5+ZvJ3vktLm60Otww2TXeROB5igiZ8D9oPQh6ckBVg==} + engines: {node: '>=18'} hasBin: true '@rollup/rollup-android-arm-eabi@4.12.1': @@ -1395,6 +1390,21 @@ packages: balanced-match@1.0.2: resolution: {integrity: sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==} + bare-events@2.4.2: + resolution: {integrity: sha512-qMKFd2qG/36aA4GwvKq8MxnPgCQAmBWmSyLWsJcbn8v03wvIPQ/hG1Ms8bPzndZxMDoHpxez5VOS+gC9Yi24/Q==} + + bare-fs@2.3.1: + resolution: {integrity: sha512-W/Hfxc/6VehXlsgFtbB5B4xFcsCl+pAh30cYhoFyXErf6oGrwjh8SwiPAdHgpmWonKuYpZgGywN0SXt7dgsADA==} + + bare-os@2.4.0: + resolution: {integrity: sha512-v8DTT08AS/G0F9xrhyLtepoo9EJBJ85FRSMbu1pQUlAf6A8T0tEEQGMVObWeqpjhSPXsE0VGlluFBJu2fdoTNg==} + + bare-path@2.1.3: + resolution: {integrity: sha512-lh/eITfU8hrj9Ru5quUp0Io1kJWIk1bTjzo7JH1P5dWmQ2EL4hFUlfI8FonAhSlgIfhn63p84CDY/x+PisgcXA==} + + bare-stream@2.1.3: + resolution: {integrity: sha512-tiDAH9H/kP+tvNO5sczyn9ZAA7utrSMobyDchsnyyXBuUe2FSQWbxhtuHB8jwpHYYevVo2UJpcmvvjrbHboUUQ==} + base-64@1.0.0: resolution: {integrity: sha512-kwDPIFCGx0NZHog36dj+tHiwP4QMzsZ3AgMViUBKI0+V5n4U0ufTCUMhnQ04diaRI8EX/QcPfql7zlhZ7j4zgg==} @@ -1515,8 +1525,8 @@ packages: resolution: {integrity: sha512-bIomtDF5KGpdogkLd9VspvFzk9KfpyyGlS8YFVZl7TGPBHL5snIOnxeshwVgPteQ9b4Eydl+pVbIyE1DcvCWgQ==} engines: {node: '>=10'} - chromium-bidi@0.4.31: - resolution: {integrity: sha512-OtvEg2JMRQrHsmLx4FV3u1Hf9waYxB5PmL+yM0HkFpc9H2x3TMbUqS+GP2/fC4399hzOO+EQF8uVU43By9ILag==} + chromium-bidi@0.5.17: + resolution: {integrity: sha512-BqOuIWUgTPj8ayuBFJUYCCuwIcwjBsb3/614P7tt1bEPJ4i1M0kCdIl0Wi9xhtswBXnfO2bTpTMkHD71H8rJMg==} peerDependencies: devtools-protocol: '*' @@ -1603,8 +1613,8 @@ packages: core-js@3.32.2: resolution: {integrity: sha512-pxXSw1mYZPDGvTQqEc5vgIb83jGQKFGYWY76z4a7weZXUolw3G+OvpZqSRcfYOoOVUQJYEPsWeQK8pKEnUtWxQ==} - cosmiconfig@8.3.6: - resolution: {integrity: sha512-kcZ6+W5QzcJ3P1Mt+83OUv/oHFqZHIx8DuxG6eZ5RGMERoLqp4BuGjhHLYGK+Kf5XVkQvqBSmAy/nGWN3qDgEA==} + cosmiconfig@9.0.0: + resolution: {integrity: sha512-itvL5h8RETACmOTFc4UfIyB2RfEHi71Ax6E/PivVxq9NseKbOWpeyHEOIbmAw1rs8Ak0VursQNww7lf7YtUwzg==} engines: {node: '>=14'} peerDependencies: typescript: '>=4.9.5' @@ -1612,9 +1622,6 @@ packages: typescript: optional: true - cross-fetch@4.0.0: - resolution: {integrity: sha512-e4a5N8lVvuLgAWgnCrLr2PP0YyDOTHa9H/Rj54dirp61qXnNq46m82bRhNqIA5VccJtWBvPTFRV3TtvHUKPB1g==} - cross-spawn@7.0.3: resolution: {integrity: sha512-iRDPJKUPVEND7dHPO8rkbOnPpyDygcDFtWjpeWNCgy8WP2rXcxXL8TskReQl6OrB2G7+UJrags1q15Fudc7G6w==} engines: {node: '>= 8'} @@ -1719,8 +1726,8 @@ packages: devlop@1.1.0: resolution: {integrity: sha512-RWmIqhcFf1lRYBvNmr7qTNuyCt/7/ns2jbpp1+PalgE/rDQcBT0fioSMUpJ93irlUhC5hrg4cYqe6U+0ImW0rA==} - devtools-protocol@0.0.1179426: - resolution: {integrity: sha512-KKC7IGwdOr7u9kTGgjUvGTov/z1s2H7oHi3zKCdR9eSDyCPia5CBi4aRhtp7d8uR7l0GS5UTDw3TjKGu5CqINg==} + devtools-protocol@0.0.1262051: + resolution: {integrity: sha512-YJe4CT5SA8on3Spa+UDtNhEqtuV6Epwz3OZ4HQVLhlRccpZ9/PAYk0/cy/oKxFKRrZPBUPyxympQci4yWNWZ9g==} diff-sequences@29.6.3: resolution: {integrity: sha512-EjePK1srD3P08o2j4f0ExnylqRs5B9tJjcp9t1krH2qRi8CCdsYfwe9JgSLurFBWwq4uOlipzfk5fHNvwFKr8Q==} @@ -1812,6 +1819,10 @@ packages: resolution: {integrity: sha512-V0hjH4dGPh9Ao5p0MoRY6BVqtwCjhz6vI5LT8AJ55H+4g9/4vbHx1I54fS0XuclLhDHArPQCiMjDxjaL8fPxhw==} engines: {node: '>=0.12'} + env-paths@2.2.1: + resolution: {integrity: sha512-+h1lkLKhZMTYjog1VEpJNG7NZJWcuc2DDk/qsqSTRRCOXiLjeQ1d1/udrUGhqMxUgAlwKNZ0cf2uqan5GLuS2A==} + engines: {node: '>=6'} + error-ex@1.3.2: resolution: {integrity: sha512-7dFHNmqeFSEt2ZBsCriorKnn3Z2pj+fd9kmI6QoWw4//DL+icEBfc0U7qJCisqrTsKTjw4fNFy2pW9OqStD84g==} @@ -2048,6 +2059,9 @@ packages: get-tsconfig@4.7.2: resolution: {integrity: sha512-wuMsz4leaj5hbGgg4IvDU0bqJagpftG5l5cXIAvo8uZrqn0NJqwtfupTN00VnkQJPcIRrxYrm1Ue24btpCha2A==} + get-tsconfig@4.7.5: + resolution: {integrity: sha512-ZCuZCnlqNzjb4QprAzXKdpp/gh6KTxSJuw3IBsPnV/7fV4NxC9ckB+vPTt8w7fJA0TaSD7c55BR47JD6MEDyDw==} + get-uri@6.0.2: resolution: {integrity: sha512-5KLucCJobh8vBY1K07EFV4+cPZH3mrV9YeAruUseCQKHB58SGjjT2l9/eA9LD082IiuMjSlFJEcdJ27TXvbZNw==} engines: {node: '>= 14'} @@ -2157,12 +2171,12 @@ packages: http-cache-semantics@4.1.1: resolution: {integrity: sha512-er295DKPVsV82j5kw1Gjt+ADA/XYHsajl82cGNQG2eyoPkvgUhX+nDIyelzhIWbbsXP39EHcI6l5tYs2FYqYXQ==} - http-proxy-agent@7.0.0: - resolution: {integrity: sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==} + http-proxy-agent@7.0.2: + resolution: {integrity: sha512-T1gkAiYYDWYx3V5Bmyu7HcfcvL7mUrTWiM6yOfa3PIphViJ/gFPbvidQ+veqSOHci/PxBcDabeUNCzpOODJZig==} engines: {node: '>= 14'} - https-proxy-agent@7.0.2: - resolution: {integrity: sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==} + https-proxy-agent@7.0.5: + resolution: {integrity: sha512-1e4Wqeblerz+tMKPIq2EMGiiWW1dIjZOksyHWSUm1rmuvw/how9hBHZ38lAGj5ID4Ik6EdkOw7NmWPy6LAwalw==} engines: {node: '>= 14'} human-signals@5.0.0: @@ -2679,15 +2693,6 @@ packages: encoding: optional: true - node-fetch@2.7.0: - resolution: {integrity: sha512-c4FRfUm/dbcWZ7U+1Wq0AwCyFL+3nt2bEw05wfxSz+DWpWsitgmSgYmy2dQdWyKC1694ELPqMs/YzUSNozLt8A==} - engines: {node: 4.x || >=6.0.0} - peerDependencies: - encoding: ^0.1.0 - peerDependenciesMeta: - encoding: - optional: true - node-releases@2.0.14: resolution: {integrity: sha512-y10wOWt8yZpqXmOgRo77WaHEmhYQYGNA6y421PKsKYWEK8aW+cqAphborZDhqfyKrbZEN92CN1X2KbafY2s7Yw==} @@ -2850,6 +2855,12 @@ packages: resolution: {integrity: sha512-o8mkY4E/+LNUf6LzX96ht6k6CEDi65k9G2rjMtBe9Oo+VPKSvl+0GKHuH/AlG+GA5LPG/i5hrekkxUc3s2HU+Q==} hasBin: true + pixelteer@https://codeload.github.com/narthur/pixelteer/tar.gz/4f4e26f9abb2981a1dad3e0f5b8b078835c9ceb3: + resolution: {tarball: https://codeload.github.com/narthur/pixelteer/tar.gz/4f4e26f9abb2981a1dad3e0f5b8b078835c9ceb3} + version: 1.0.0 + peerDependencies: + puppeteer: ^22.6.5 + pkg-dir@4.2.0: resolution: {integrity: sha512-HRDzbaKjC+AOWVXxAU/x54COGeIv9eb+6CkDSQoNTt4XyWoIJvuPsXizxu/Fr23EiekbtZwmh1IcIG/l/a10GQ==} engines: {node: '>=8'} @@ -2919,8 +2930,8 @@ packages: property-information@6.3.0: resolution: {integrity: sha512-gVNZ74nqhRMiIUYWGQdosYetaKc83x8oT41a0LlV3AAFCAZwCpg4vmGkq8t34+cUhp3cnM4XDiU/7xlgK7HGrg==} - proxy-agent@6.3.1: - resolution: {integrity: sha512-Rb5RVBy1iyqOtNl15Cw/llpeLH8bsb37gM1FUfKQ+Wck6xHlbAhWGUFiTRHtkjqGTA5pSHz6+0hrPW/oECihPQ==} + proxy-agent@6.4.0: + resolution: {integrity: sha512-u0piLU+nCOHMgGjRbimiXmA9kM/L9EHh3zL81xCdp7m+Y2pHIsnmbdDoEDoAz5geaonNR6q6+yOPQs6n4T6sBQ==} engines: {node: '>= 14'} proxy-from-env@1.1.0: @@ -2933,13 +2944,14 @@ packages: resolution: {integrity: sha512-rRV+zQD8tVFys26lAGR9WUuS4iUAngJScM+ZRSKtvl5tKeZ2t5bvdNFdNHBW9FWR4guGHlgmsZ1G7BSm2wTbuA==} engines: {node: '>=6'} - puppeteer-core@21.3.8: - resolution: {integrity: sha512-yv12E/+zZ7Lei5tJB4sUkSrsuqKibuYpYxLGbmtLUjjYIqGE5HKz9OUI2I/RFHEvF+pHi2bTbv5bWydeCGJ6Mw==} - engines: {node: '>=16.3.0'} + puppeteer-core@22.6.5: + resolution: {integrity: sha512-s0/5XkAWe0/dWISiljdrybjwDCHhgN31Nu/wznOZPKeikgcJtZtbvPKBz0t802XWqfSQnQDt3L6xiAE5JLlfuw==} + engines: {node: '>=18'} - puppeteer@21.3.8: - resolution: {integrity: sha512-4OrInVIAtDgcznENUV4Du4gYSZhRmbCkckvOoPstXrUH4JsQ3atSegY+9f/tOKCDB2qh7sXaszDcFEn+RymY0g==} - engines: {node: '>=16.3.0'} + puppeteer@22.6.5: + resolution: {integrity: sha512-YuoRKGj3MxHhUwrey7vmNvU4odGdUdNsj1ee8pfcqQlLWIXfMOXZCAXh8xdzpZESHH3tCGWp2xmPZE8E6iUEWg==} + engines: {node: '>=18'} + hasBin: true queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -3212,8 +3224,8 @@ packages: resolution: {integrity: sha512-xhV7w8S+bUwlPTb4bAOUQhv8/cSS5offJuX8GQGq32ONF0ZtDWKfkdomM3HMRA+LhX6um/FZ0COqlwsjD53LeQ==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} - streamx@2.15.1: - resolution: {integrity: sha512-fQMzy2O/Q47rgwErk/eGeLu/roaFWV0jVsogDmrszM9uIw8L5OA+t+V93MgYlufNptfjmYR1tOMWhei/Eh7TQA==} + streamx@2.18.0: + resolution: {integrity: sha512-LLUC1TWdjVdn1weXGcSxyTR3T4+acB6tVGXT95y0nGbca4t4o/ng1wKAGTljm9VicuCVLvRlqFYXYy5GwgM7sQ==} string-width@4.2.3: resolution: {integrity: sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==} @@ -3290,8 +3302,8 @@ packages: tar-fs@2.1.1: resolution: {integrity: sha512-V0r2Y9scmbDRLCNex/+hYzvp/zyYjvFbHPNgVTKfQvVrb6guiE/fxP+XblDNR011utopbkex2nM4dHNV6GDsng==} - tar-fs@3.0.4: - resolution: {integrity: sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==} + tar-fs@3.0.5: + resolution: {integrity: sha512-JOgGAmZyMgbqpLwct7ZV8VzkEB6pxXFBVErLtb+XCOqzc6w1xiWKI9GVd6bwk68EX7eJ4DWmfXVmq8K2ziZTGg==} tar-stream@2.2.0: resolution: {integrity: sha512-ujeqbceABgwMZxEJnk2HDY2DlnUZ+9oEcb1KzTVfYHio0UE6dG71n60d8D2I4qNvleWrrXpmjpt7vZeF1LnMZQ==} @@ -3304,6 +3316,9 @@ packages: resolution: {integrity: sha512-/Wo7DcT0u5HUV486xg675HtjNd3BXZ6xDbzsCUZPt5iw8bTQ63bP0Raut3mvro9u+CUyq7YQd8Cx55fsZXxqLQ==} engines: {node: '>=10'} + text-decoder@1.1.1: + resolution: {integrity: sha512-8zll7REEv4GDD3x4/0pW+ppIxSNs7H1J10IKFZsuOMscumCdM2a+toDGLPA3T+1+fLBql4zbt5z83GEQGGV5VA==} + text-table@0.2.0: resolution: {integrity: sha512-N+8UisAXDGk8PFXP4HAzVR9nbfmVJ3zYLAWiTIoqC5v5isinhr+r5uaO8+7r3BMfuNIufIsA7RdpVgacC2cSpw==} @@ -3377,6 +3392,11 @@ packages: resolution: {integrity: sha512-rjmRpTu3as/5fjNq/kOkOtihgLxuIz6pbKdj9xwP4J5jOLkBxw/rjN5ANw+KyrrOXV5uB7HC8+SrrSJxT65y+A==} hasBin: true + tsx@4.16.2: + resolution: {integrity: sha512-C1uWweJDgdtX2x600HjaFaucXTilT7tgUZHbOE4+ypskZ1OP8CRCSDkCxG6Vya9EwaFIVagWwpaVAn5wzypaqQ==} + engines: {node: '>=18.0.0'} + hasBin: true + tunnel-agent@0.6.0: resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} @@ -3397,6 +3417,11 @@ packages: engines: {node: '>=14.17'} hasBin: true + typescript@5.5.3: + resolution: {integrity: sha512-/hreyEujaB0w76zKo6717l3L0o/qEUtRgdvUBvlkhoWeOVMjMuHNHk0BRBzikzuGDqNmPQbg5ifMEqsHLiIUcQ==} + engines: {node: '>=14.17'} + hasBin: true + unbzip2-stream@1.4.3: resolution: {integrity: sha512-mlExGW4w71ebDJviH16lQLtZS32VKqsSfk80GCfUlwT/4/hNRFsoscrF/c++9xinkMzECL1uL9DDwXqFWkruPg==} @@ -3464,8 +3489,8 @@ packages: uri-js@4.4.1: resolution: {integrity: sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==} - urlpattern-polyfill@9.0.0: - resolution: {integrity: sha512-WHN8KDQblxd32odxeIgo83rdVDE2bvdkb86it7bMhYZwWKJz0+O0RK/eZiHYnM+zgt/U7hAHOlCQGfjjvSkw2g==} + urlpattern-polyfill@10.0.0: + resolution: {integrity: sha512-H/A06tKD7sS1O1X2SshBVeA5FLycRpjqiBeqGKmBwBDBy28EnRjORxTNe269KSSr5un5qyWi1iL61wLxpd+ZOg==} util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} @@ -3669,8 +3694,8 @@ packages: wrappy@1.0.2: resolution: {integrity: sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==} - ws@8.14.2: - resolution: {integrity: sha512-wEBG1ftX4jcglPxgFCMJmZ2PLtSbJ2Peg6TmpJFTbe9GZYOQCDPdMYu/Tm0/bGZkw8paZnJY45J4K2PZrLYq8g==} + ws@8.16.0: + resolution: {integrity: sha512-HS0c//TP7Ina87TfiPUz1rQzMhHrl/SG2guqRcTOIUYD2q8uhUdNHZYJUaQ8aTGPzCh+c6oawMKW35nFl1dxyQ==} engines: {node: '>=10.0.0'} peerDependencies: bufferutil: ^4.0.1 @@ -3695,10 +3720,6 @@ packages: resolution: {integrity: sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==} engines: {node: '>=12'} - yargs@17.7.1: - resolution: {integrity: sha512-cwiTb08Xuv5fqF4AovYacTFNxk62th7LKJ6BL9IGUpTJrWoU7/7WdQGTP2SjKf1dUNBGzDd28p/Yfs/GI6JrLw==} - engines: {node: '>=12'} - yargs@17.7.2: resolution: {integrity: sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==} engines: {node: '>=12'} @@ -3786,7 +3807,7 @@ snapshots: '@astrojs/telemetry@3.0.4': dependencies: ci-info: 3.8.0 - debug: 4.3.4 + debug: 4.3.5 dlv: 1.1.3 dset: 3.1.3 is-docker: 3.0.0 @@ -3795,11 +3816,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/code-frame@7.22.13': - dependencies: - '@babel/highlight': 7.22.20 - chalk: 2.4.2 - '@babel/code-frame@7.23.5': dependencies: '@babel/highlight': 7.23.4 @@ -3820,7 +3836,7 @@ snapshots: '@babel/traverse': 7.24.0 '@babel/types': 7.24.0 convert-source-map: 2.0.0 - debug: 4.3.4 + debug: 4.3.5 gensync: 1.0.0-beta.2 json5: 2.2.3 semver: 6.3.1 @@ -3894,12 +3910,6 @@ snapshots: transitivePeerDependencies: - supports-color - '@babel/highlight@7.22.20': - dependencies: - '@babel/helper-validator-identifier': 7.22.20 - chalk: 2.4.2 - js-tokens: 4.0.0 - '@babel/highlight@7.23.4': dependencies: '@babel/helper-validator-identifier': 7.22.20 @@ -3950,7 +3960,7 @@ snapshots: '@babel/helper-split-export-declaration': 7.22.6 '@babel/parser': 7.24.0 '@babel/types': 7.24.0 - debug: 4.3.4 + debug: 4.3.5 globals: 11.12.0 transitivePeerDependencies: - supports-color @@ -4343,7 +4353,7 @@ snapshots: '@npmcli/fs@1.1.1': dependencies: '@gar/promisify': 1.1.3 - semver: 7.5.4 + semver: 7.6.0 '@npmcli/move-file@1.1.2': dependencies: @@ -4352,15 +4362,16 @@ snapshots: '@polka/url@1.0.0-next.23': {} - '@puppeteer/browsers@1.7.1': + '@puppeteer/browsers@2.2.2': dependencies: debug: 4.3.4 extract-zip: 2.0.1 progress: 2.0.3 - proxy-agent: 6.3.1 - tar-fs: 3.0.4 + proxy-agent: 6.4.0 + semver: 7.6.0 + tar-fs: 3.0.5 unbzip2-stream: 1.4.3 - yargs: 17.7.1 + yargs: 17.7.2 transitivePeerDependencies: - supports-color @@ -4560,7 +4571,7 @@ snapshots: '@types/yauzl@2.10.1': dependencies: - '@types/node': 20.6.2 + '@types/node': 20.14.10 optional: true '@typescript-eslint/eslint-plugin@6.7.0(@typescript-eslint/parser@6.7.0(eslint@8.49.0)(typescript@5.2.2))(eslint@8.49.0)(typescript@5.2.2)': @@ -4710,7 +4721,7 @@ snapshots: agent-base@7.1.0: dependencies: - debug: 4.3.4 + debug: 4.3.5 transitivePeerDependencies: - supports-color @@ -4864,6 +4875,29 @@ snapshots: balanced-match@1.0.2: {} + bare-events@2.4.2: + optional: true + + bare-fs@2.3.1: + dependencies: + bare-events: 2.4.2 + bare-path: 2.1.3 + bare-stream: 2.1.3 + optional: true + + bare-os@2.4.0: + optional: true + + bare-path@2.1.3: + dependencies: + bare-os: 2.4.0 + optional: true + + bare-stream@2.1.3: + dependencies: + streamx: 2.18.0 + optional: true + base-64@1.0.0: {} base64-js@1.5.1: {} @@ -5026,11 +5060,12 @@ snapshots: chownr@2.0.0: {} - chromium-bidi@0.4.31(devtools-protocol@0.0.1179426): + chromium-bidi@0.5.17(devtools-protocol@0.0.1262051): dependencies: - devtools-protocol: 0.0.1179426 + devtools-protocol: 0.0.1262051 mitt: 3.0.1 - urlpattern-polyfill: 9.0.0 + urlpattern-polyfill: 10.0.0 + zod: 3.22.4 ci-info@3.8.0: {} @@ -5106,21 +5141,15 @@ snapshots: core-js@3.32.2: {} - cosmiconfig@8.3.6(typescript@5.2.2): + cosmiconfig@9.0.0(typescript@5.2.2): dependencies: + env-paths: 2.2.1 import-fresh: 3.3.0 js-yaml: 4.1.0 parse-json: 5.2.0 - path-type: 4.0.0 optionalDependencies: typescript: 5.2.2 - cross-fetch@4.0.0: - dependencies: - node-fetch: 2.7.0 - transitivePeerDependencies: - - encoding - cross-spawn@7.0.3: dependencies: path-key: 3.1.1 @@ -5202,7 +5231,7 @@ snapshots: dependencies: dequal: 2.0.3 - devtools-protocol@0.0.1179426: {} + devtools-protocol@0.0.1262051: {} diff-sequences@29.6.3: {} @@ -5284,6 +5313,8 @@ snapshots: entities@4.5.0: {} + env-paths@2.2.1: {} + error-ex@1.3.2: dependencies: is-arrayish: 0.2.1 @@ -5493,7 +5524,7 @@ snapshots: extract-zip@2.0.1: dependencies: - debug: 4.3.4 + debug: 4.3.5 get-stream: 5.2.0 yauzl: 2.10.0 optionalDependencies: @@ -5628,11 +5659,15 @@ snapshots: dependencies: resolve-pkg-maps: 1.0.0 + get-tsconfig@4.7.5: + dependencies: + resolve-pkg-maps: 1.0.0 + get-uri@6.0.2: dependencies: basic-ftp: 5.0.3 data-uri-to-buffer: 6.0.1 - debug: 4.3.4 + debug: 4.3.5 fs-extra: 8.1.0 transitivePeerDependencies: - supports-color @@ -5819,17 +5854,17 @@ snapshots: http-cache-semantics@4.1.1: {} - http-proxy-agent@7.0.0: + http-proxy-agent@7.0.2: dependencies: agent-base: 7.1.0 - debug: 4.3.4 + debug: 4.3.5 transitivePeerDependencies: - supports-color - https-proxy-agent@7.0.2: + https-proxy-agent@7.0.5: dependencies: agent-base: 7.1.0 - debug: 4.3.4 + debug: 4.3.5 transitivePeerDependencies: - supports-color @@ -6329,7 +6364,7 @@ snapshots: micromark@4.0.0: dependencies: '@types/debug': 4.1.8 - debug: 4.3.4 + debug: 4.3.5 decode-named-character-reference: 1.0.2 devlop: 1.1.0 micromark-core-commonmark: 2.0.0 @@ -6400,7 +6435,8 @@ snapshots: mitt@3.0.1: {} - mkdirp-classic@0.5.3: {} + mkdirp-classic@0.5.3: + optional: true mkdirp@1.0.4: {} @@ -6425,7 +6461,7 @@ snapshots: node-abi@3.47.0: dependencies: - semver: 7.5.4 + semver: 7.6.0 optional: true node-addon-api@6.1.0: @@ -6444,10 +6480,6 @@ snapshots: dependencies: whatwg-url: 5.0.0 - node-fetch@2.7.0: - dependencies: - whatwg-url: 5.0.0 - node-releases@2.0.14: {} normalize-path@3.0.0: {} @@ -6534,10 +6566,10 @@ snapshots: dependencies: '@tootallnate/quickjs-emscripten': 0.23.0 agent-base: 7.1.0 - debug: 4.3.4 + debug: 4.3.5 get-uri: 6.0.2 - http-proxy-agent: 7.0.0 - https-proxy-agent: 7.0.2 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 pac-resolver: 7.0.0 socks-proxy-agent: 8.0.2 transitivePeerDependencies: @@ -6555,7 +6587,7 @@ snapshots: parse-json@5.2.0: dependencies: - '@babel/code-frame': 7.22.13 + '@babel/code-frame': 7.23.5 error-ex: 1.3.2 json-parse-even-better-errors: 2.3.1 lines-and-columns: 1.2.4 @@ -6613,6 +6645,15 @@ snapshots: dependencies: pngjs: 6.0.0 + pixelteer@https://codeload.github.com/narthur/pixelteer/tar.gz/4f4e26f9abb2981a1dad3e0f5b8b078835c9ceb3(puppeteer@22.6.5(typescript@5.2.2)): + dependencies: + pixelmatch: 5.3.0 + pngjs: 7.0.0 + puppeteer: 22.6.5(typescript@5.2.2) + sharp: 0.33.3 + tsx: 4.16.2 + typescript: 5.5.3 + pkg-dir@4.2.0: dependencies: find-up: 4.1.0 @@ -6685,12 +6726,12 @@ snapshots: property-information@6.3.0: {} - proxy-agent@6.3.1: + proxy-agent@6.4.0: dependencies: agent-base: 7.1.0 - debug: 4.3.4 - http-proxy-agent: 7.0.0 - https-proxy-agent: 7.0.2 + debug: 4.3.5 + http-proxy-agent: 7.0.2 + https-proxy-agent: 7.0.5 lru-cache: 7.18.3 pac-proxy-agent: 7.0.1 proxy-from-env: 1.1.0 @@ -6707,28 +6748,26 @@ snapshots: punycode@2.3.0: {} - puppeteer-core@21.3.8: + puppeteer-core@22.6.5: dependencies: - '@puppeteer/browsers': 1.7.1 - chromium-bidi: 0.4.31(devtools-protocol@0.0.1179426) - cross-fetch: 4.0.0 + '@puppeteer/browsers': 2.2.2 + chromium-bidi: 0.5.17(devtools-protocol@0.0.1262051) debug: 4.3.4 - devtools-protocol: 0.0.1179426 - ws: 8.14.2 + devtools-protocol: 0.0.1262051 + ws: 8.16.0 transitivePeerDependencies: - bufferutil - - encoding - supports-color - utf-8-validate - puppeteer@21.3.8(typescript@5.2.2): + puppeteer@22.6.5(typescript@5.2.2): dependencies: - '@puppeteer/browsers': 1.7.1 - cosmiconfig: 8.3.6(typescript@5.2.2) - puppeteer-core: 21.3.8 + '@puppeteer/browsers': 2.2.2 + cosmiconfig: 9.0.0(typescript@5.2.2) + devtools-protocol: 0.0.1262051 + puppeteer-core: 22.6.5 transitivePeerDependencies: - bufferutil - - encoding - supports-color - typescript - utf-8-validate @@ -6984,9 +7023,9 @@ snapshots: detect-libc: 2.0.2 node-addon-api: 6.1.0 prebuild-install: 7.1.1 - semver: 7.5.4 + semver: 7.6.0 simple-get: 4.0.1 - tar-fs: 3.0.4 + tar-fs: 3.0.5 tunnel-agent: 0.6.0 optional: true @@ -7074,7 +7113,7 @@ snapshots: socks-proxy-agent@8.0.2: dependencies: agent-base: 7.1.0 - debug: 4.3.4 + debug: 4.3.5 socks: 2.7.1 transitivePeerDependencies: - supports-color @@ -7113,10 +7152,13 @@ snapshots: dependencies: bl: 5.1.0 - streamx@2.15.1: + streamx@2.18.0: dependencies: fast-fifo: 1.3.2 queue-tick: 1.0.1 + text-decoder: 1.1.1 + optionalDependencies: + bare-events: 2.4.2 string-width@4.2.3: dependencies: @@ -7196,11 +7238,13 @@ snapshots: tar-stream: 2.2.0 optional: true - tar-fs@3.0.4: + tar-fs@3.0.5: dependencies: - mkdirp-classic: 0.5.3 pump: 3.0.0 tar-stream: 3.1.6 + optionalDependencies: + bare-fs: 2.3.1 + bare-path: 2.1.3 tar-stream@2.2.0: dependencies: @@ -7215,7 +7259,7 @@ snapshots: dependencies: b4a: 1.6.4 fast-fifo: 1.3.2 - streamx: 2.15.1 + streamx: 2.18.0 tar@6.2.0: dependencies: @@ -7226,6 +7270,10 @@ snapshots: mkdirp: 1.0.4 yallist: 4.0.0 + text-decoder@1.1.1: + dependencies: + b4a: 1.6.4 + text-table@0.2.0: {} throttles@1.0.1: {} @@ -7274,6 +7322,13 @@ snapshots: optionalDependencies: fsevents: 2.3.3 + tsx@4.16.2: + dependencies: + esbuild: 0.21.5 + get-tsconfig: 4.7.5 + optionalDependencies: + fsevents: 2.3.3 + tunnel-agent@0.6.0: dependencies: safe-buffer: 5.2.1 @@ -7289,6 +7344,8 @@ snapshots: typescript@5.2.2: {} + typescript@5.5.3: {} + unbzip2-stream@1.4.3: dependencies: buffer: 5.7.1 @@ -7390,7 +7447,7 @@ snapshots: dependencies: punycode: 2.3.0 - urlpattern-polyfill@9.0.0: {} + urlpattern-polyfill@10.0.0: {} util-deprecate@1.0.2: {} @@ -7564,7 +7621,7 @@ snapshots: wrappy@1.0.2: {} - ws@8.14.2: {} + ws@8.16.0: {} y18n@5.0.8: {} @@ -7574,16 +7631,6 @@ snapshots: yargs-parser@21.1.1: {} - yargs@17.7.1: - dependencies: - cliui: 8.0.1 - escalade: 3.1.1 - get-caller-file: 2.0.5 - require-directory: 2.1.1 - string-width: 4.2.3 - y18n: 5.0.8 - yargs-parser: 21.1.1 - yargs@17.7.2: dependencies: cliui: 8.0.1 diff --git a/scripts/puppeteer.spec.ts b/scripts/puppeteer.spec.ts deleted file mode 100644 index ce6fb4c..0000000 --- a/scripts/puppeteer.spec.ts +++ /dev/null @@ -1,73 +0,0 @@ -import pixelmatch from "pixelmatch"; -import { describe, it, expect, beforeEach, vi } from "vitest"; -import { run } from "./puppeteer.js"; -import getSitemap from "../src/lib/test/getSitemap.js"; -import readScreenshot from "../src/lib/test/readScreenshot.js"; -import resizeImage from "../src/lib/test/resizeImage.js"; -import fs from "fs"; -import createReport from "../src/lib/test/createReport.js"; - -describe("puppeteer", () => { - beforeEach(() => { - vi.mocked(getSitemap).mockResolvedValue(["https://blog.beeminder.com"]); - - vi.mocked(readScreenshot) - .mockReturnValueOnce({ - metadata: () => ({ - width: 1, - height: 1, - }), - toBuffer: () => Buffer.from(""), - } as any) - .mockReturnValueOnce({ - metadata: () => ({ - width: 100, - height: 100, - }), - toBuffer: () => Buffer.from(""), - } as any); - - vi.mocked(fs.readdirSync).mockReturnValue([]); - }); - - it("uses max width and max height", async () => { - await run(); - - expect(pixelmatch).toBeCalledWith( - undefined, - undefined, - undefined, - 100, - 100, - expect.anything(), - ); - }); - - it("resizes images", async () => { - await run(); - - expect(resizeImage).toBeCalledTimes(2); - }); - - it("does not run if shots is not empty", async () => { - vi.mocked(fs.readdirSync).mockReturnValue(["foo" as any]); - - await run(); - - expect(resizeImage).toBeCalledTimes(0); - }); - - it("runs if shots is not empty and force arg provided", async () => { - vi.mocked(fs.readdirSync).mockReturnValue(["foo" as any]); - - await run(["--force"]); - - expect(resizeImage).toBeCalledTimes(2); - }); - - it("creates report", async () => { - await run(); - - expect(createReport).toBeCalled(); - }); -}); diff --git a/scripts/puppeteer.ts b/scripts/puppeteer.ts index 43389f3..606cfdc 100644 --- a/scripts/puppeteer.ts +++ b/scripts/puppeteer.ts @@ -1,125 +1,43 @@ -// usage: -// pnpm tsx ./scripts/puppeteer.ts -// pnpm puppeteer - -import fs from "fs"; import { preview } from "astro"; -import pixelmatch from "pixelmatch"; -import { PNG } from "pngjs"; -import takeScreenshot from "../src/lib/test/saveScreenshot"; import getSitemap from "../src/lib/test/getSitemap"; -import readScreenshot from "../src/lib/test/readScreenshot"; -import resizeImage from "../src/lib/test/resizeImage"; -import puppeteer, { Browser } from "puppeteer"; -import createReport from "../src/lib/test/createReport"; import url from "url"; +import { compareUrls, createReport } from "pixelteer"; const port = 4321; const base = `https://blog.beeminder.com`; const compare = `http://localhost:${port}`; const outPath = new URL("../shots/", import.meta.url); - -function makeOutPath(url: string, suffix: string): URL { - const p = new URL(url).pathname.replaceAll("/", "_"); - return new URL(`./${p}.${suffix}.png`, outPath); -} - -async function snap( - browser: Browser, - url: string, - suffix: string, -): Promise { - const p = makeOutPath(url, suffix); - - await takeScreenshot({ - browser, - url, - path: p, - }); - - return p; -} - -async function handleUrl(browser: Browser, url: string) { - const pathname = new URL(url).pathname; - console.time(pathname); - - const path1 = await snap(browser, `${url}?snap`, "base"); - const path2 = await snap( - browser, - `${url.replace(base, compare)}?snap`, - "compare", - ); - const img1 = readScreenshot(path1); - const img2 = readScreenshot(path2); - const meta1 = await img1.metadata(); - const meta2 = await img2.metadata(); - - if (!meta1.width || !meta1.height || !meta2.width || !meta2.height) { - throw new Error("Missing image size data"); - } - - const width = Math.max(meta1.width, meta2.width); - const height = Math.max(meta1.height, meta2.height); - const resized1 = await resizeImage({ image: img1, width, height }); - const resized2 = await resizeImage({ image: img2, width, height }); - const diff = new PNG({ width, height }); - - const c = pixelmatch(resized1, resized2, diff.data, width, height, { - threshold: 0.1, - }); - - fs.writeFileSync(makeOutPath(url, "diff"), PNG.sync.write(diff)); - - console.timeEnd(pathname); - console.log(c); -} - -async function takeScreenshots() { - const root = new URL("..", import.meta.url); - const server = await preview({ - root: url.fileURLToPath(root), - server: { - port, - }, - }); - const browser = await puppeteer.launch({ - headless: "new", - }); - const urls = await getSitemap(); - console.log(urls); - - console.time("Capturing screenshots"); - for (const url of urls) { - await handleUrl(browser, url); - } - console.timeEnd("Capturing screenshots"); - - await browser.close(); - await server.stop(); -} - -export async function run(argv: string[] = []) { - if (!fs.existsSync(outPath)) { - fs.mkdirSync(outPath); - } - - const isEmpty = fs.readdirSync(outPath).length === 0; - const isForced = argv.includes("--force"); - - if (isEmpty || isForced) { - await takeScreenshots(); - } else { - console.log( - "Skipping screenshots because shots is not empty. Use --force to override.", - ); - } - - createReport(); -} -const a = new URL(import.meta.url).pathname; -const b = new URL(`file://${process.argv[1]}`).pathname; -if (a === b) { - console.log("Running puppeteer script"); - await run(process.argv); -} +const root = new URL("..", import.meta.url); + +const server = await preview({ + root: url.fileURLToPath(root), + server: { + port, + }, +}); + +const urls = await getSitemap(); +const paths = urls.map((url) => new URL(url).pathname); + +await compareUrls({ + baseUrl1: base, + baseUrl2: compare, + paths, + outDir: url.fileURLToPath(outPath), + force: process.argv.includes("--force"), + onSuccess: (data) => { + console.log(data); + }, + onError: (error) => { + console.error(error); + }, +}); + +createReport({ + baseUrl1: base, + baseUrl2: compare, + shotsDir: url.fileURLToPath(outPath), + outDir: url.fileURLToPath(root), +}); + +await server.stop(); diff --git a/src/lib/test/createReport.ts b/src/lib/test/createReport.ts deleted file mode 100644 index 69cfd6c..0000000 --- a/src/lib/test/createReport.ts +++ /dev/null @@ -1,79 +0,0 @@ -import fs from "fs"; - -export default function createReport() { - const shotsDir = new URL("../../../shots/", import.meta.url); - const files = fs.readdirSync(shotsDir); - const sets = files.reduce( - (acc, file) => { - const key = file.split(".")[0]; - if (!key) return acc; - const value = acc[key] || []; - value.push(file); - acc[key] = value; - return acc; - }, - {} as Record, - ); - const panes = Object.entries(sets).map(([key, value]) => { - const p = key.replaceAll("_", "/"); - return ` -
-
-

${p}

-

- base | - compare -

-
-
- ${value - .map( - (file) => - ``, - ) - .join("\n")} -
-
- `; - }); - - const html = ` - - - - - - ${panes.join("\n")} - - - `; - - // const reportPath = path.join(shotsDir.pathname, "..", "report.html"); - const reportPath = new URL("../report.html", shotsDir); - - fs.writeFileSync(reportPath, html); - - console.log(`Report written to ${reportPath}`); -} diff --git a/src/lib/test/readScreenshot.ts b/src/lib/test/readScreenshot.ts deleted file mode 100644 index 7517771..0000000 --- a/src/lib/test/readScreenshot.ts +++ /dev/null @@ -1,7 +0,0 @@ -import fs from "fs"; -import type { Sharp } from "sharp"; -import sharp from "sharp"; - -export default function readScreenshot(path: URL): Sharp { - return sharp(fs.readFileSync(path)); -} diff --git a/src/lib/test/resizeImage.ts b/src/lib/test/resizeImage.ts deleted file mode 100644 index 9036932..0000000 --- a/src/lib/test/resizeImage.ts +++ /dev/null @@ -1,23 +0,0 @@ -import { type Sharp } from "sharp"; - -type Options = { - image: Sharp; - width: number; - height: number; -}; - -export default function resizeImage({ - image, - width, - height, -}: Options): Promise { - return image - .resize({ - width, - height, - fit: "contain", - position: "left top", - }) - .raw() - .toBuffer(); -} diff --git a/src/lib/test/saveScreenshot.ts b/src/lib/test/saveScreenshot.ts deleted file mode 100644 index 2d22005..0000000 --- a/src/lib/test/saveScreenshot.ts +++ /dev/null @@ -1,26 +0,0 @@ -import { Browser } from "puppeteer"; -import _url from "url"; - -type Options = { - url: string; - path: URL; - browser: Browser; -}; - -export default async function takeScreenshot({ - browser, - url, - path, -}: Options): Promise { - const page = await browser.newPage(); - - await page.setViewport({ width: 1920, height: 1080 }); - await page.goto(url, { waitUntil: "networkidle0" }); - - await page.screenshot({ - path: _url.fileURLToPath(path), - fullPage: true, - }); - - await page.close(); -} diff --git a/vitest.setup.ts b/vitest.setup.ts index 00dac51..ab485ac 100644 --- a/vitest.setup.ts +++ b/vitest.setup.ts @@ -4,7 +4,6 @@ import fetchPost from "./src/lib/fetchPost"; import { __reset } from "./src/lib/memoize"; import ether from "./src/lib/test/ether"; import getSitemap from "./src/lib/test/getSitemap"; -import readScreenshot from "./src/lib/test/readScreenshot"; vi.mock("./src/lib/fetchPost"); vi.mock("./src/lib/readSources"); @@ -48,12 +47,6 @@ beforeEach(() => { vi.mocked(fetchPost).mockResolvedValue(ether()); vi.mocked(getSitemap).mockResolvedValue([]); - vi.mocked(readScreenshot).mockReturnValue({ - metadata: () => ({ - width: 100, - height: 100, - }), - } as any); vi.stubGlobal("console", { ...console,