From 6471a2dfe84d4ccc2fe3bdae98f1bad72876deaa Mon Sep 17 00:00:00 2001 From: matstyler Date: Tue, 21 May 2024 11:39:45 +0200 Subject: [PATCH 01/11] feat: Cypress config files --- pnpm-lock.yaml | 644 +++++++++++++++++- .../ethereum-wallet-mock/cypress.config.ts | 16 + wallets/ethereum-wallet-mock/package.json | 1 + wallets/ethereum-wallet-mock/tsconfig.json | 3 +- wallets/metamask/cypress.config.ts | 16 + wallets/metamask/package.json | 1 + wallets/metamask/src/cypress/errors.ts | 4 + wallets/metamask/src/cypress/index.ts | 1 + wallets/metamask/src/cypress/initMetaMask.ts | 80 +++ .../metamask/src/cypress/installSynpress.ts | 52 ++ wallets/metamask/src/cypress/setupTasks.ts | 34 + .../metamask/test/wallet-setup/basic.setup.ts | 4 +- wallets/metamask/tsconfig.json | 3 +- 13 files changed, 836 insertions(+), 23 deletions(-) create mode 100644 wallets/ethereum-wallet-mock/cypress.config.ts create mode 100644 wallets/metamask/cypress.config.ts create mode 100644 wallets/metamask/src/cypress/errors.ts create mode 100644 wallets/metamask/src/cypress/index.ts create mode 100644 wallets/metamask/src/cypress/initMetaMask.ts create mode 100644 wallets/metamask/src/cypress/installSynpress.ts create mode 100644 wallets/metamask/src/cypress/setupTasks.ts diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index fb7ea137..340b65d3 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -249,6 +249,9 @@ importers: '@vitest/coverage-v8': specifier: 1.2.2 version: 1.2.2(vitest@1.2.2) + cypress: + specifier: 13.9.0 + version: 13.9.0 rimraf: specifier: 5.0.5 version: 5.0.5 @@ -292,6 +295,9 @@ importers: '@vitest/coverage-v8': specifier: 1.2.2 version: 1.2.2(vitest@1.2.2) + cypress: + specifier: 13.9.0 + version: 13.9.0 rimraf: specifier: 5.0.5 version: 5.0.5 @@ -802,6 +808,39 @@ packages: chalk: 4.1.2 dev: true + /@cypress/request@3.0.1: + resolution: {integrity: sha512-TWivJlJi8ZDx2wGOw1dbLuHJKUYX7bWySw377nlnGOW3hP9/MUKIsEdXT/YngWxVdgNCHRBmFlBipE+5/2ZZlQ==} + engines: {node: '>= 6'} + dependencies: + aws-sign2: 0.7.0 + aws4: 1.12.0 + caseless: 0.12.0 + combined-stream: 1.0.8 + extend: 3.0.2 + forever-agent: 0.6.1 + form-data: 2.3.3 + http-signature: 1.3.6 + is-typedarray: 1.0.0 + isstream: 0.1.2 + json-stringify-safe: 5.0.1 + mime-types: 2.1.35 + performance-now: 2.1.0 + qs: 6.10.4 + safe-buffer: 5.2.1 + tough-cookie: 4.1.4 + tunnel-agent: 0.6.0 + uuid: 8.3.2 + dev: true + + /@cypress/xvfb@1.2.4(supports-color@8.1.1): + resolution: {integrity: sha512-skbBzPggOVYCbnGgV+0dmBdW/s77ZkAOXIC1knS8NagwDjBrNC1LuXtQJeiN6l+m7lzmHtaoUw/ctJKdqkG57Q==} + dependencies: + debug: 3.2.7(supports-color@8.1.1) + lodash.once: 4.1.1 + transitivePeerDependencies: + - supports-color + dev: true + /@depay/solana-web3.js@1.26.0: resolution: {integrity: sha512-aAhDxfNGraE8VBwM5g/BhHnNCENlLSKDJ3yIh2EZd4mfmKM/4utv0cNUhTEytUAvvFoaMcOXXQ5U5sE1IMXFrQ==} dependencies: @@ -2392,6 +2431,14 @@ packages: resolution: {integrity: sha512-I8EUhyrgfLrcTkzV3TSsGyl1tSuPrEDzr0yd5m90UgNxQkyDXULk3b6MlQqTCpZpNtWe1K0hzclnZkTcLBe2UQ==} dev: true + /@types/sinonjs__fake-timers@8.1.1: + resolution: {integrity: sha512-0kSuKjAS0TrGLJ0M/+8MaFkGsQhZpB6pxOmvS3K8FYI72K//YmdfoW9X2qPsAKh1mkwxGD5zib9s1FIFed6E8g==} + dev: true + + /@types/sizzle@2.3.8: + resolution: {integrity: sha512-0vWLNK2D5MT9dg0iOo8GlKguPAU02QjmZitPEsXRuJXU/OGIOt9vT9Fc26wtYuavLxtO45v9PGleoL9Z0k1LHg==} + dev: true + /@types/statuses@2.0.5: resolution: {integrity: sha512-jmIUGWrAiwu3dZpxntxieC+1n/5c3mjrImkmOSQ2NC5uP6cYO4aAZDdSmRcI5C1oiTmqlZGHC+/NmJrKogbP5A==} dev: true @@ -2413,6 +2460,14 @@ packages: resolution: {integrity: sha512-ltIpx+kM7g/MLRZfkbL7EsCEjfzCcScLpkg37eXEtx5kmrAKBkTJwd1GIAjDSL8wTpM6Hzn5YO4pSb91BEwu1g==} dev: true + /@types/yauzl@2.10.3: + resolution: {integrity: sha512-oJoftv0LSuaDZE3Le4DbKX+KS9G36NzOeSap90UIK0yMA/NhKJhqlSGtNDORNRaIbQfzjXDrQa0ytJ6mNRGz/Q==} + requiresBuild: true + dependencies: + '@types/node': 20.11.17 + dev: true + optional: true + /@viem/anvil@0.0.7: resolution: {integrity: sha512-F+3ljCT1bEt8T4Fzm9gWpIgO3Dc7bzG1TtUtkStkJFMuummqZ8kvYc3UFMo5j3F51fSWZZvEkjs3+i7qf0AOqQ==} dependencies: @@ -2444,7 +2499,7 @@ packages: dependencies: '@ampproject/remapping': 2.3.0 '@bcoe/v8-coverage': 0.2.3 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 istanbul-lib-report: 3.0.1 istanbul-lib-source-maps: 4.0.1 @@ -2723,7 +2778,7 @@ packages: resolution: {integrity: sha512-RZNwNclF7+MS/8bDg70amg32dyeZGZxiDuQmZxKLAlQjr3jGyLx+4Kkk58UO7D2QdgFIQCovuSuZESne6RG6XQ==} engines: {node: '>= 6.0.0'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -2935,17 +2990,37 @@ packages: engines: {node: '>=0.10.0'} dev: true + /asn1@0.2.6: + resolution: {integrity: sha512-ix/FxPn0MDjeyJ7i/yoHGFt/EX6LyNbxSEhPPXODPL+KB0VPk86UYfL0lMdy+KCnv+fmvIzySwaK5COwqVbWTQ==} + dependencies: + safer-buffer: 2.1.2 + dev: true + + /assert-plus@1.0.0: + resolution: {integrity: sha512-NfJ4UzBCcQGLDlQq7nHxH+tv3kyZ0hHQqF5BO6J7tNJeP5do1llPr8dZ8zHonfhAu0PHAdMkSo+8o0wxg9lZWw==} + engines: {node: '>=0.8'} + dev: true + /assertion-error@1.1.0: resolution: {integrity: sha512-jgsaNduz+ndvGyFt3uSuWqvy4lCnIJiovtouQN5JZHOKCS2QuhEdbcQHFhVksz2N2U9hXJo8odG7ETyWlEeuDw==} dev: true + /astral-regex@2.0.0: + resolution: {integrity: sha512-Z7tMw1ytTXt5jqMcOP+OQteU1VuNK9Y02uuJtKQ1Sv69jXQKKg5cibLwGJow8yzZP+eAc18EmLGPal0bp36rvQ==} + engines: {node: '>=8'} + dev: true + /async@3.2.5: resolution: {integrity: sha512-baNZyqaaLhyLVKm/DlvdW051MSgO6b8eVfIezl9E5PqWxFgzLm/wQntEW4zOytVburDEr0JlALEpdOFwvErLsg==} dev: true /asynckit@0.4.0: resolution: {integrity: sha512-Oei9OH4tRh0YqU3GxhX79dM/mwVgvbZJaSNaRk+bshkj0S5cfHcgYakreBjrHwatXKbz+IoIdYLxrKim2MjW0Q==} - dev: false + + /at-least-node@1.0.0: + resolution: {integrity: sha512-+q/t7Ekv1EDY2l6Gda6LLiX14rU9TV20Wa3ofeQmwPFZbOMo9DXrLbOjFaaclkXKWidIaopwAObQDqwWtGUjqg==} + engines: {node: '>= 4.0.0'} + dev: true /available-typed-arrays@1.0.7: resolution: {integrity: sha512-wvUjBtSGN7+7SjNpq/9M2Tg350UZD3q62IFZLbRAR1bSMlCo1ZaeW+BJ+D090e4hIIZLBcTDWe4Mh4jvUDajzQ==} @@ -2954,6 +3029,14 @@ packages: possible-typed-array-names: 1.0.0 dev: true + /aws-sign2@0.7.0: + resolution: {integrity: sha512-08kcGqnYf/YmjoRhfxyu+CLxBjUtHLXLXX/vUfx9l2LYzG3c1m61nrpyFUZI6zeS+Li/wWMMidD9KgrqtGq3mA==} + dev: true + + /aws4@1.12.0: + resolution: {integrity: sha512-NmWvPnx0F1SfrQbYwOi7OeaNGokp9XhzNioJ/CSBs8Qa4vxug81mhJEAVZwxXuBmYB5KDRfMq/F3RR0BIU7sWg==} + dev: true + /axios@1.6.7: resolution: {integrity: sha512-/hDJGff6/c7u0hDkvkGxR/oy6CbCs8ziCsC7SqmhjfozqiJGc8Z11wrv9z9lYfY4K8l+H9TpjcMDX0xOZmx+RA==} dependencies: @@ -2981,6 +3064,16 @@ packages: resolution: {integrity: sha512-FuwxlW4H5kh37X/oW59pwTzzTKRzfrrQwhmyspRM7swOEZcHtDZSCt45U6oKgtuFE+WYPblePMVIPR4RZrh/hw==} dev: false + /base64-js@1.5.1: + resolution: {integrity: sha512-AKpaYlHn8t4SVbOHCy+b5+KKgvR4vrsD8vbvrbiQJps7fKDTkjkDry6ji0rUJjC0kzbNePLwzxq8iypo41qeWA==} + dev: true + + /bcrypt-pbkdf@1.0.2: + resolution: {integrity: sha512-qeFIXtP4MSoi6NLqO12WfqARWWuCKi2Rn/9hJLEmtB5yTNr9DqFWkJRCf2qShWzPeAMRnOgCrq0sg/KLv5ES9w==} + dependencies: + tweetnacl: 0.14.5 + dev: true + /bech32@1.1.4: resolution: {integrity: sha512-s0IrSOzLlbvX7yp4WBfPITzpAU8sqQcpsmwXDiKwrG4r491vwCO/XpejasRNl0piBMe/DvP4Tz0mIS/X1DPJBQ==} dev: false @@ -3008,10 +3101,18 @@ packages: chainsaw: 0.1.0 dev: false + /blob-util@2.0.2: + resolution: {integrity: sha512-T7JQa+zsXXEa6/8ZhHcQEW1UFfVM49Ts65uBkFL6fz2QmrElqmbajIDJvuA0tEhRe5eIjpV9ZF+0RfZR9voJFQ==} + dev: true + /bluebird@3.4.7: resolution: {integrity: sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==} dev: false + /bluebird@3.7.2: + resolution: {integrity: sha512-XpNj6GDQzdfW+r2Wnn7xiSAd7TM3jzkxGXBGTtWKuSXv1xUV+azxAm8jdWZN06QTQk+2N2XB9jRDkvbmQmcRtg==} + dev: true + /bn.js@4.12.0: resolution: {integrity: sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==} dev: false @@ -3094,6 +3195,13 @@ packages: engines: {node: '>=0.10'} dev: false + /buffer@5.7.1: + resolution: {integrity: sha512-EHcyIPBQ4BSGlvjB16k5KgAJ27CIsHY/2JBmCRReo48y9rQ3MaUzWX3KVlBa4U7MyX02HdVj0K7C3WaB3ju7FQ==} + dependencies: + base64-js: 1.5.1 + ieee754: 1.2.1 + dev: true + /buffers@0.1.1: resolution: {integrity: sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==} engines: {node: '>=0.2.0'} @@ -3179,6 +3287,11 @@ packages: responselike: 3.0.0 dev: true + /cachedir@2.4.0: + resolution: {integrity: sha512-9EtFOZR8g22CL7BWjJ9BUx1+A/djkofnyW3aOXZORNW2kxoUpx2h+uN2cOqwPmFhnpVmxg+KW2OjOSgChTEvsQ==} + engines: {node: '>=6'} + dev: true + /call-bind@1.0.7: resolution: {integrity: sha512-GHTSNSYICQ7scH7sZ+M2rFopRoLh8t2bLSW6BbgrtLsahOIB5iyAVJf9GjWK3cYTDaMj4XdBpM1cA6pIS0Kv2w==} engines: {node: '>= 0.4'} @@ -3209,6 +3322,10 @@ packages: engines: {node: '>=14.16'} dev: true + /caseless@0.12.0: + resolution: {integrity: sha512-4tYFyifaFfGacoiObjJegolkwSU4xQNGbVgUiNYVUxbQ2x2lUsFvY4hVgVzGiIe6WLOPqycWXA40l+PWsxthUw==} + dev: true + /chai@4.4.1: resolution: {integrity: sha512-13sOfMv2+DWduEU+/xbun3LScLoqN17nBeTLUsmDfKdoiC1fr0n9PU4guu4AhRcOVFk/sW8LyZWHuhWtQZiF+g==} engines: {node: '>=4'} @@ -3270,6 +3387,11 @@ packages: get-func-name: 2.0.2 dev: true + /check-more-types@2.24.0: + resolution: {integrity: sha512-Pj779qHxV2tuapviy1bSZNEL1maXr13bPYpsvSDB68HlYcYuhlDrmGd63i0JHMCLKzc7rUSNIrpdJlhVlNwrxA==} + engines: {node: '>= 0.8.0'} + dev: true + /chokidar@3.6.0: resolution: {integrity: sha512-7VT13fmjotKpGipCW9JEQAusEPE+Ei8nl6/g4FBAmIm0GOOLMua9NDDo/DWp0ZAxCr3cPq5ZpBqmPAQgDda2Pw==} engines: {node: '>= 8.10.0'} @@ -3304,6 +3426,13 @@ packages: engines: {node: '>=10'} dev: true + /cli-cursor@3.1.0: + resolution: {integrity: sha512-I/zHAwsKf9FqGoXM4WWRACob9+SNukZTd94DWF57E4toouRulbCxcUh6RKUEOQlYTHJnzkPMySvPNaaSLNfLZw==} + engines: {node: '>=8'} + dependencies: + restore-cursor: 3.1.0 + dev: true + /cli-cursor@4.0.0: resolution: {integrity: sha512-VGtlMu3x/4DOtIUwEkRezxUZ2lBacNJCHash0N0WeZDBS+7Ux1dm3XWAgWYxLJFMMdOeXMHXorshEFhbMSGelg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -3325,6 +3454,14 @@ packages: '@colors/colors': 1.5.0 dev: true + /cli-truncate@2.1.0: + resolution: {integrity: sha512-n8fOixwDD6b/ObinzTrp1ZKFzbgvKZvuz/TvejnLn1aQfC6r52XEx85FmuC+3HI+JM7coBRXUvNqEU2PHVrHpg==} + engines: {node: '>=8'} + dependencies: + slice-ansi: 3.0.0 + string-width: 4.2.3 + dev: true + /cli-truncate@4.0.0: resolution: {integrity: sha512-nPdaFdQ0h/GEigbPClz11D0v/ZJEwxmeVZGeMo3Z5StPtUTkA9o1lD6QwoirYiSDzbcwn2XcjwmCp68W1IS4TA==} engines: {node: '>=18'} @@ -3402,7 +3539,6 @@ packages: engines: {node: '>= 0.8'} dependencies: delayed-stream: 1.0.0 - dev: false /commander@10.0.1: resolution: {integrity: sha512-y4Mg2tXshplEbSGzx7amzPwKKOCGuoSRP/CjEdwwk0FOGlUbq6lKuoyDZTNZkmxHdJtp54hdfY/JUrdL7Xfdug==} @@ -3423,6 +3559,11 @@ packages: resolution: {integrity: sha512-NOKm8xhkzAjzFx8B2v5OAHT+u5pRQc2UCa2Vq9jYL/31o2wi9mxBA7LIFs3sV5VSC49z6pEhfbMULvShKj26WA==} engines: {node: '>= 6'} + /commander@6.2.1: + resolution: {integrity: sha512-U7VdrJFnJgo4xjrHpTzu0yrHPGImdsmD95ZlgYSEajAn2JKzDhDTPG9kBTefmObL2w/ngeZnilk+OV9CG3d7UA==} + engines: {node: '>= 6'} + dev: true + /commitlint-config-gitmoji@2.3.1: resolution: {integrity: sha512-T15ssbsyNc6szHlnGWo0/xvIA1mObqM70E9TwKNVTpksxhm+OdFht8hvDdKJAVi4nlZX5tcfTeILOi7SHBGH3w==} dependencies: @@ -3440,6 +3581,11 @@ packages: gitmojis: 3.14.0 dev: true + /common-tags@1.8.2: + resolution: {integrity: sha512-gk/Z852D2Wtb//0I+kRFNKKE9dIIVirjoqPoA1wJU+XePVXZfGeBpk45+A1rKO4Q43prqWBNY/MiIeRLbPWUaA==} + engines: {node: '>=4.0.0'} + dev: true + /compress-commons@5.0.3: resolution: {integrity: sha512-/UIcLWvwAQyVibgpQDPtfNM3SvqN7G9elAPAV7GM0L53EbNWwWiCsWtK8Fwed/APEbptPHXs5PuW+y8Bq8lFTA==} engines: {node: '>= 12.0.0'} @@ -3515,6 +3661,10 @@ packages: engines: {node: '>= 0.6'} dev: true + /core-util-is@1.0.2: + resolution: {integrity: sha512-3lqz5YjWTYnW6dlDa5TLaTCcShfar1e40rmcJVwCBJC6mWlFuj0eCHIElmG1g5kyuJ/GD+8Wn4FFCcz4gJPfaQ==} + dev: true + /core-util-is@1.0.3: resolution: {integrity: sha512-ZQBvi1DcpJ4GDqanjucZ2Hj3wEO5pZDS89BWbkcrvdxksJorwUDDZamX9ldFkp9aw2lmBDLgkObEA4DWNJ9FYQ==} @@ -3581,6 +3731,63 @@ packages: stream-transform: 2.1.3 dev: true + /cypress@13.9.0: + resolution: {integrity: sha512-atNjmYfHsvTuCaxTxLZr9xGoHz53LLui3266WWxXJHY7+N6OdwJdg/feEa3T+buez9dmUXHT1izCOklqG82uCQ==} + engines: {node: ^16.0.0 || ^18.0.0 || >=20.0.0} + hasBin: true + requiresBuild: true + dependencies: + '@cypress/request': 3.0.1 + '@cypress/xvfb': 1.2.4(supports-color@8.1.1) + '@types/sinonjs__fake-timers': 8.1.1 + '@types/sizzle': 2.3.8 + arch: 2.2.0 + blob-util: 2.0.2 + bluebird: 3.7.2 + buffer: 5.7.1 + cachedir: 2.4.0 + chalk: 4.1.2 + check-more-types: 2.24.0 + cli-cursor: 3.1.0 + cli-table3: 0.6.5 + commander: 6.2.1 + common-tags: 1.8.2 + dayjs: 1.11.11 + debug: 4.3.4(supports-color@8.1.1) + enquirer: 2.4.1 + eventemitter2: 6.4.7 + execa: 4.1.0 + executable: 4.1.1 + extract-zip: 2.0.1(supports-color@8.1.1) + figures: 3.2.0 + fs-extra: 9.1.0 + getos: 3.2.1 + is-ci: 3.0.1 + is-installed-globally: 0.4.0 + lazy-ass: 1.6.0 + listr2: 3.14.0(enquirer@2.4.1) + lodash: 4.17.21 + log-symbols: 4.1.0 + minimist: 1.2.8 + ospath: 1.2.2 + pretty-bytes: 5.6.0 + process: 0.11.10 + proxy-from-env: 1.0.0 + request-progress: 3.0.0 + semver: 7.6.2 + supports-color: 8.1.1 + tmp: 0.2.3 + untildify: 4.0.0 + yauzl: 2.10.0 + dev: true + + /dashdash@1.14.1: + resolution: {integrity: sha512-jRFi8UDGo6j+odZiEpjazZaWqEal3w/basFjQHQEwVtZJGDpxbH1MeYluwCS8Xq5wmLJooDlMgvVarmWfGM44g==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + dev: true + /data-view-buffer@1.0.1: resolution: {integrity: sha512-0lht7OugA5x3iJLOWFhWK/5ehONdprk0ISXqVFn/NFrDu+cuc8iADFrGQz5BnRK7LLU3JmkbXSxaqX+/mXYtUA==} engines: {node: '>= 0.4'} @@ -3608,6 +3815,10 @@ packages: is-data-view: 1.0.1 dev: true + /dayjs@1.11.11: + resolution: {integrity: sha512-okzr3f11N6WuqYtZSvm+F776mB41wRZMhKP+hc34YdW+KmtYYK9iqvHSwo2k9FEH3fhGXvOPV6yz2IcSrfRUDg==} + dev: true + /debug@2.6.9: resolution: {integrity: sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==} peerDependencies: @@ -3619,7 +3830,19 @@ packages: ms: 2.0.0 dev: true - /debug@4.3.4: + /debug@3.2.7(supports-color@8.1.1): + resolution: {integrity: sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==} + peerDependencies: + supports-color: '*' + peerDependenciesMeta: + supports-color: + optional: true + dependencies: + ms: 2.1.3 + supports-color: 8.1.1 + dev: true + + /debug@4.3.4(supports-color@8.1.1): resolution: {integrity: sha512-PRWFHuSU3eDtQJPvnNY7Jcket1j0t5OuOsFzPPzsekD52Zl8qUfFIPEiswXqIvHWGVHOgX+7G/vCNNhehwxfkQ==} engines: {node: '>=6.0'} peerDependencies: @@ -3629,6 +3852,7 @@ packages: optional: true dependencies: ms: 2.1.2 + supports-color: 8.1.1 /decamelize-keys@1.1.1: resolution: {integrity: sha512-WiPxgEirIV0/eIOMcnFBA3/IJZAZqKnwAwWyvvdi4lsr1WCN22nhdf/3db3DoZcUjTV2SqfzIwNyp6y2xs3nmg==} @@ -3694,7 +3918,6 @@ packages: /delayed-stream@1.0.0: resolution: {integrity: sha512-ZySD7Nf91aLB0RxL4KGrKHBXl7Eds1DAmEdcoVawXnLD7SDhpNgtuII2aAkg7a7QS41jxPSZ17p4VdGnMHk3MQ==} engines: {node: '>=0.4.0'} - dev: false /delegates@1.0.0: resolution: {integrity: sha512-bd2L678uiWATM6m5Z1VzNCErI3jiGzt6HGY8OVICs40JQq/HALfbyNJmp0UDakEY4pMMaN0Ly5om/B1VI/+xfQ==} @@ -3747,6 +3970,13 @@ packages: /eastasianwidth@0.2.0: resolution: {integrity: sha512-I88TYZWc9XiYHRQ4/3c5rjjfgkjhLyW2luGIheGERbNQ6OY7yTybanSpDXZa8y7VUP9YmDcYa+eyq4ca7iLqWA==} + /ecc-jsbn@0.1.2: + resolution: {integrity: sha512-eh9O+hwRHNbG4BLTjEl3nw044CkGm5X6LoaCf7LPp7UU8Qrt47JYNi6nPX8xjW97TKGKm1ouctg0QSpZe9qrnw==} + dependencies: + jsbn: 0.1.1 + safer-buffer: 2.1.2 + dev: true + /elliptic@6.5.4: resolution: {integrity: sha512-iLhC6ULemrljPZb+QutR5TQGB+pdW6KGD5RSegS+8sorOZT+rdQFbsQFJgvN3eRqNALqJer4oQ16YvJHlU8hzQ==} dependencies: @@ -3777,6 +4007,12 @@ packages: dev: true optional: true + /end-of-stream@1.4.4: + resolution: {integrity: sha512-+uw1inIHVPQoaVuHzRyXd21icM+cnt4CzD5rW+NC1wjOUSTOs+Te7FOv7AhN7vS9x/oIyhLP5PR1H+phQAHu5Q==} + dependencies: + once: 1.4.0 + dev: true + /enquirer@2.4.1: resolution: {integrity: sha512-rRqJg/6gd538VHvR3PSrdRBb/1Vy2YfzHqzvbhGIQpDRKIa4FgV/54b5Q1xYSxOOwKvjXweS26E0Q+nAMwp2pQ==} engines: {node: '>=8.6'} @@ -4061,6 +4297,10 @@ packages: - utf-8-validate dev: false + /eventemitter2@6.4.7: + resolution: {integrity: sha512-tYUSVOGeQPKt/eC1ABfhHy5Xd96N3oIijJvN3O9+TsC28T5V9yX9oEfEK5faP0EFSNVOG97qtAS68GBrQB2hDg==} + dev: true + /eventemitter3@4.0.7: resolution: {integrity: sha512-8guHBZCwKnFhYdHr2ysuRWErTwhoN2X8XELRlrRwpmfeY2jjuUN4taQMsULKUVo1K4DvZl+0pgfyoysHxvmvEw==} dev: false @@ -4069,6 +4309,21 @@ packages: resolution: {integrity: sha512-GWkBvjiSZK87ELrYOSESUYeVIc9mvLLf/nXalMOS5dYrgZq9o5OVkbZAVM06CVxYsCwH9BDZFPlQTlPA1j4ahA==} dev: true + /execa@4.1.0: + resolution: {integrity: sha512-j5W0//W7f8UxAn8hXVnwG8tLwdiUy4FJLcSupCg6maBYZDpyBvTApK7KyuI4bKj8KOh1r2YH+6ucuYtJv1bTZA==} + engines: {node: '>=10'} + dependencies: + cross-spawn: 7.0.3 + get-stream: 5.2.0 + human-signals: 1.1.1 + is-stream: 2.0.1 + merge-stream: 2.0.0 + npm-run-path: 4.0.1 + onetime: 5.1.2 + signal-exit: 3.0.7 + strip-final-newline: 2.0.0 + dev: true + /execa@5.1.1: resolution: {integrity: sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==} engines: {node: '>=10'} @@ -4113,10 +4368,21 @@ packages: strip-final-newline: 3.0.0 dev: true + /executable@4.1.1: + resolution: {integrity: sha512-8iA79xD3uAch729dUG8xaaBBFGaEa0wdD2VkYLFHwlqosEj/jT66AzcreRDSgV7ehnNLBW2WR5jIXwGKjVdTLg==} + engines: {node: '>=4'} + dependencies: + pify: 2.3.0 + dev: true + /exponential-backoff@3.1.1: resolution: {integrity: sha512-dX7e/LHVJ6W3DE1MHWi9S1EYzDESENfLrYohG2G++ovZrYOkm4Knwa0mc1cn84xJOR4KEU0WSchhLbd0UklbHw==} dev: true + /extend@3.0.2: + resolution: {integrity: sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==} + dev: true + /extendable-error@0.1.7: resolution: {integrity: sha512-UOiS2in6/Q0FK0R0q6UY9vYpQ21mr/Qn1KOnte7vsACuNJf514WvCCUHSRCPcgjPT2bAhNIJdlE6bVap1GKmeg==} dev: true @@ -4130,6 +4396,25 @@ packages: tmp: 0.0.33 dev: true + /extract-zip@2.0.1(supports-color@8.1.1): + resolution: {integrity: sha512-GDhU9ntwuKyGXdZBUgTIe+vXnWj0fppUEtMDL0+idd5Sta8TGpHssn/eusA9mrPr9qNDym6SxAYZjNvCn/9RBg==} + engines: {node: '>= 10.17.0'} + hasBin: true + dependencies: + debug: 4.3.4(supports-color@8.1.1) + get-stream: 5.2.0 + yauzl: 2.10.0 + optionalDependencies: + '@types/yauzl': 2.10.3 + transitivePeerDependencies: + - supports-color + dev: true + + /extsprintf@1.3.0: + resolution: {integrity: sha512-11Ndz7Nv+mvAC1j0ktTa7fAb0vLyGGX+rMHNBYQviQDGU0Hw7lhctJANqbPhu9nV9/izT/IntTgZ7Im/9LJs9g==} + engines: {'0': node >=0.6.0} + dev: true + /fast-deep-equal@3.1.3: resolution: {integrity: sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==} dev: true @@ -4167,6 +4452,19 @@ packages: dependencies: reusify: 1.0.4 + /fd-slicer@1.1.0: + resolution: {integrity: sha512-cE1qsB/VwyQozZ+q1dGxR8LBYNZeofhEdUNGSMbQD3Gw2lAzX9Zb3uIU6Ebc/Fmyjo9AWWfnn0AUCHqtevs/8g==} + dependencies: + pend: 1.2.0 + dev: true + + /figures@3.2.0: + resolution: {integrity: sha512-yaduQFRKLXYOGgEn6AZau90j3ggSOyiqXU0F9JZfeXYhNa+Jk4X+s45A2zg5jns87GAFa34BBm2kXw4XpNcbdg==} + engines: {node: '>=8'} + dependencies: + escape-string-regexp: 1.0.5 + dev: true + /fill-range@7.0.1: resolution: {integrity: sha512-qOo9F+dMUmC2Lcb4BbVvnKJxTPjCm+RRpe4gDuGrzkL7mEVl/djYSu2OdQ2Pa302N4oqkSg9ir6jaLWJ2USVpQ==} engines: {node: '>=8'} @@ -4225,11 +4523,24 @@ packages: cross-spawn: 7.0.3 signal-exit: 4.1.0 + /forever-agent@0.6.1: + resolution: {integrity: sha512-j0KLYPhm6zeac4lz3oJ3o65qvgQCcPubiyotZrXqEaG4hNagNYO8qdlUrX5vwqv9ohqeT/Z3j6+yW067yWWdUw==} + dev: true + /form-data-encoder@2.1.4: resolution: {integrity: sha512-yDYSgNMraqvnxiEXO4hi88+YZxaHC6QKzb5N84iRCTDeRO7ZALpir/lVmf/uXUhnwUr2O4HU8s/n6x+yNjQkHw==} engines: {node: '>= 14.17'} dev: true + /form-data@2.3.3: + resolution: {integrity: sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==} + engines: {node: '>= 0.12'} + dependencies: + asynckit: 0.4.0 + combined-stream: 1.0.8 + mime-types: 2.1.35 + dev: true + /form-data@4.0.0: resolution: {integrity: sha512-ETEklSGi5t0QMZuiXoA/Q6vcnxcLQP5vdugSpuAyi6SVGi2clPPp+xgEhuMaHC+zGgn31Kd235W35f7Hykkaww==} engines: {node: '>= 6'} @@ -4271,6 +4582,16 @@ packages: universalify: 0.1.2 dev: true + /fs-extra@9.1.0: + resolution: {integrity: sha512-hcg3ZmepS30/7BSFqRvoo3DOMQu7IjqxO5nCDt+zM9XWjb33Wg7ziNT+Qvqbuc3+gWpzO02JubVyk2G4Zvo1OQ==} + engines: {node: '>=10'} + dependencies: + at-least-node: 1.0.0 + graceful-fs: 4.2.11 + jsonfile: 6.1.0 + universalify: 2.0.1 + dev: true + /fs-minipass@2.1.0: resolution: {integrity: sha512-V/JgOLFCS+R6Vcq0slCuaeWEdNC3ouDlJMNIsacH2VtALiu9mV4LPrHc5cDl8k5aw6J8jwgWWpiTo5RYhmIzvg==} engines: {node: '>= 8'} @@ -4385,6 +4706,13 @@ packages: engines: {node: '>=12'} dev: true + /get-stream@5.2.0: + resolution: {integrity: sha512-nBF+F1rAZVCu/p7rjzgA+Yb4lfYXrpl7a6VmJrU8wF9I1CKvP/QwPNZHnOlwbTkY6dvtFIzFMSyQXbLoTQPRpA==} + engines: {node: '>=8'} + dependencies: + pump: 3.0.0 + dev: true + /get-stream@6.0.1: resolution: {integrity: sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==} engines: {node: '>=10'} @@ -4403,6 +4731,18 @@ packages: get-intrinsic: 1.2.4 dev: true + /getos@3.2.1: + resolution: {integrity: sha512-U56CfOK17OKgTVqozZjUKNdkfEv6jk5WISBJ8SHoagjE6L69zOwl3Z+O8myjY9MEW3i2HPWQBt/LTbCgcC973Q==} + dependencies: + async: 3.2.5 + dev: true + + /getpass@0.1.7: + resolution: {integrity: sha512-0fzj9JxOLfJ+XGLhR8ze3unN0KZCgZwiSSDz168VERjK8Wl8kVSdcu2kspd4s4wtAa1y/qrVRiAA0WclVsu0ng==} + dependencies: + assert-plus: 1.0.0 + dev: true + /git-hooks-list@3.1.0: resolution: {integrity: sha512-LF8VeHeR7v+wAbXqfgRlTSX/1BJR9Q1vEMR8JAz1cEg6GX07+zyj3sAdDvYjj/xnlIfVuGgj4qBei1K3hKH+PA==} dev: true @@ -4645,7 +4985,7 @@ packages: dependencies: '@tootallnate/once': 2.0.0 agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -4661,6 +5001,15 @@ packages: - debug dev: false + /http-signature@1.3.6: + resolution: {integrity: sha512-3adrsD6zqo4GsTqtO7FyrejHNv+NgiIfAfv68+jVlFmSr9OGy7zrxONceFRLKvnnZA5jbxQBX1u9PpB6Wi32Gw==} + engines: {node: '>=0.10'} + dependencies: + assert-plus: 1.0.0 + jsprim: 2.0.2 + sshpk: 1.18.0 + dev: true + /http2-wrapper@2.2.1: resolution: {integrity: sha512-V5nVw1PAOgfI3Lmeaj2Exmeg7fenjhRUgz1lPSezy1CuhPYbgQtbQj4jZfEAEMlaL+vupsvhjqCyjzob0yxsmQ==} engines: {node: '>=10.19.0'} @@ -4674,7 +5023,7 @@ packages: engines: {node: '>= 6'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) transitivePeerDependencies: - supports-color dev: true @@ -4683,6 +5032,11 @@ packages: resolution: {integrity: sha512-UNopramDEhHJD+VR+ehk8rOslwSfByxPIZyJRfV739NDhN5LF1fa1MqnzKm2lGTQRjNrjK19Q5fhkgIfjlVUKw==} dev: true + /human-signals@1.1.1: + resolution: {integrity: sha512-SEQu7vl8KjNL2eoGBLF3+wAjpsNfA9XMlXAYj/3EdaNfAlxKthD1xjEQfGOUhllCGGJVNY34bRr6lPINhNjyZw==} + engines: {node: '>=8.12.0'} + dev: true + /human-signals@2.1.0: resolution: {integrity: sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==} engines: {node: '>=10.17.0'} @@ -4730,6 +5084,10 @@ packages: dev: true optional: true + /ieee754@1.2.1: + resolution: {integrity: sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==} + dev: true + /ignore-walk@6.0.5: resolution: {integrity: sha512-VuuG0wCnjhnylG1ABXT3dAuIpTNDs/G8jlpmwXY03fXoXy/8ZK8/T+hMzt8L4WnrLCJgdybqgPagnF/f97cg3A==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -5013,6 +5371,11 @@ packages: resolution: {integrity: sha512-cyA56iCMHAh5CdzjJIa4aohJyeO1YbwLi3Jc35MmRU6poroFjIGZzUzupGiRPOjgHg9TLu43xbpwXk523fMxKA==} dev: true + /is-unicode-supported@0.1.0: + resolution: {integrity: sha512-knxG2q4UC3u8stRGyAVJCOdxFmv5DZiRcdlIaAQXAbSfJya+OhopNotLQrstBhququ4ZpuKbDc/8S6mgXgPFPw==} + engines: {node: '>=10'} + dev: true + /is-weakref@1.0.2: resolution: {integrity: sha512-qctsuLZmIQ0+vSSMfoVvyFe2+GSEvnmZ2ezTup1SBse9+twCCeial6EEi3Nc2KFcf6+qz2FBPnjXsk8xhKSaPQ==} dependencies: @@ -5054,6 +5417,10 @@ packages: ws: 8.13.0 dev: false + /isstream@0.1.2: + resolution: {integrity: sha512-Yljz7ffyPbrLpLngrMtZ7NduUgVvi6wG9RJ9IUcyCd59YQ911PBJphODUcbOVbqYfxe1wuYf/LJ8PauMRwsM/g==} + dev: true + /istanbul-lib-coverage@3.2.2: resolution: {integrity: sha512-O8dpsF+r0WV/8MNRKfnmrtCWhuKjxrq2w+jpzBL5UZKTi2LeVWnWOmWRxFlesJONmc+wLAGvKQZEOanko0LFTg==} engines: {node: '>=8'} @@ -5072,7 +5439,7 @@ packages: resolution: {integrity: sha512-n3s8EwkdFIJCG3BPKBYvskgXGoy88ARzvegkitk60NxRdwltLOTaH7CUiMRXvwYorl0Q712iEjcWB+fK/MrWVw==} engines: {node: '>=10'} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) istanbul-lib-coverage: 3.2.2 source-map: 0.6.1 transitivePeerDependencies: @@ -5126,6 +5493,10 @@ packages: argparse: 2.0.1 dev: true + /jsbn@0.1.1: + resolution: {integrity: sha512-UVU9dibq2JcFWxQPA6KCqj5O42VOmAY3zQUfEKxU0KpTGXwNoCjkX1e13eHNvw/xPynt6pU0rZ1htjWTNTSXsg==} + dev: true + /jsbn@1.1.0: resolution: {integrity: sha512-4bYVV3aAMtDTTu4+xsDYa6sy9GyJ69/amsu9sYF2zqjiEoZA5xJi3BrfX3uY+/IekIu7MwdObdbDWpoZdBv3/A==} dev: true @@ -5169,6 +5540,14 @@ packages: resolution: {integrity: sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==} dev: true + /json-schema@0.4.0: + resolution: {integrity: sha512-es94M3nTIfsEPisRafak+HDLfHXnKBhV3vU5eqPcS3flIWqcxJWgXHXiey3YrpaNsanY5ei1VoYEbOzijuq9BA==} + dev: true + + /json-stringify-safe@5.0.1: + resolution: {integrity: sha512-ZClg6AaYvamvYEE82d3Iyd3vSSIjQ+odgjaTzRuO3s7toCdFKczob2i0zCh7JE8kWn17yvAWhUVxvqGwUalsRA==} + dev: true + /json5@2.2.3: resolution: {integrity: sha512-XmOWe7eyHYH14cLdVPoyg+GOH3rYX++KpzrylJwSW98t3Nk+U8XOl8FWKOgwtzdb8lXGf6zYwDUzeHMWfxasyg==} engines: {node: '>=6'} @@ -5191,7 +5570,6 @@ packages: universalify: 2.0.1 optionalDependencies: graceful-fs: 4.2.11 - dev: false /jsonlines@0.1.1: resolution: {integrity: sha512-ekDrAGso79Cvf+dtm+mL8OBI2bmAOt3gssYs833De/C9NmIpWDWyUO4zPgB5x2/OhY366dkhgfPMYfwZF7yOZA==} @@ -5202,6 +5580,16 @@ packages: engines: {'0': node >= 0.2.0} dev: true + /jsprim@2.0.2: + resolution: {integrity: sha512-gqXddjPqQ6G40VdnI6T6yObEC+pDNvyP95wdQhkWkg7crHH3km5qP1FsOXEkzEQwnz6gz5qGTn1c2Y52wP3OyQ==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + extsprintf: 1.3.0 + json-schema: 0.4.0 + verror: 1.10.0 + dev: true + /keyv@4.5.4: resolution: {integrity: sha512-oxVHkHR/EJf2CNXnWxRLW6mg7JyCCUcG0DtEGmL2ctUo1PNTin1PUil+r/+4r5MpVgC/fn1kjsx7mjSujKqIpw==} dependencies: @@ -5225,6 +5613,11 @@ packages: package-json: 8.1.1 dev: true + /lazy-ass@1.6.0: + resolution: {integrity: sha512-cc8oEVoctTvsFZ/Oje/kGnHbpWHYBe8IAJe4C0QNc3t8uM/0Y8+erSz/7Y1ALuXTEZTMvxXwO6YbX1ey3ujiZw==} + engines: {node: '> 0.8'} + dev: true + /lazystream@1.0.1: resolution: {integrity: sha512-b94GiNHQNy6JNTrt5w6zNyffMrNkXZb3KTkCZJb2V1xaEGCk093vkZ2jk3tpaeP33/OiXC+WvK9AxUebnf5nbw==} engines: {node: '>= 0.6.3'} @@ -5251,7 +5644,7 @@ packages: dependencies: chalk: 5.3.0 commander: 11.1.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 lilconfig: 3.0.0 listr2: 8.0.1 @@ -5267,6 +5660,26 @@ packages: resolution: {integrity: sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==} dev: false + /listr2@3.14.0(enquirer@2.4.1): + resolution: {integrity: sha512-TyWI8G99GX9GjE54cJ+RrNMcIFBfwMPxc3XTFiAYGN4s10hWROGtOg7+O6u6LE3mNkyld7RSLE6nrKBvTfcs3g==} + engines: {node: '>=10.0.0'} + peerDependencies: + enquirer: '>= 2.3.0 < 3' + peerDependenciesMeta: + enquirer: + optional: true + dependencies: + cli-truncate: 2.1.0 + colorette: 2.0.20 + enquirer: 2.4.1 + log-update: 4.0.0 + p-map: 4.0.0 + rfdc: 1.3.1 + rxjs: 7.8.1 + through: 2.3.8 + wrap-ansi: 7.0.0 + dev: true + /listr2@8.0.1: resolution: {integrity: sha512-ovJXBXkKGfq+CwmKTjluEqFi3p4h8xvkxGQQAQan22YCgef4KZ1mKGjzfGh6PL6AW5Csw0QiQPNuQyH+6Xk3hA==} engines: {node: '>=18.0.0'} @@ -5323,6 +5736,10 @@ packages: resolution: {integrity: sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==} dev: true + /lodash.once@4.1.1: + resolution: {integrity: sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==} + dev: true + /lodash.sortby@4.7.0: resolution: {integrity: sha512-HDWXG8isMntAyRF5vZ7xKuEvOhT4AhlRt/3czTSjvGUxjYCBVRQY48ViDHyfYz9VIoBkW4TMGQNapx+l3RUwdA==} @@ -5334,6 +5751,24 @@ packages: resolution: {integrity: sha512-v2kDEe57lecTulaDIuNTPy3Ry4gLGJ6Z1O3vE1krgXZNrsQ+LFTGHVxVjcXPs17LhbZVGedAJv8XZ1tvj5FvSg==} dev: true + /log-symbols@4.1.0: + resolution: {integrity: sha512-8XPvpAA8uyhfteu8pIvQxpJZ7SYYdpUivZpGy6sFsBuKRY/7rQGavedeB8aK+Zkyq6upMFVL/9AW6vOYzfRyLg==} + engines: {node: '>=10'} + dependencies: + chalk: 4.1.2 + is-unicode-supported: 0.1.0 + dev: true + + /log-update@4.0.0: + resolution: {integrity: sha512-9fkkDevMefjg0mmzWFBW8YkFP91OrizzkW3diF7CpG+S2EYdy4+TVfGwz1zeF8x7hCx1ovSPTOE9Ngib74qqUg==} + engines: {node: '>=10'} + dependencies: + ansi-escapes: 4.3.2 + cli-cursor: 3.1.0 + slice-ansi: 4.0.0 + wrap-ansi: 6.2.0 + dev: true + /log-update@6.0.0: resolution: {integrity: sha512-niTvB4gqvtof056rRIrTZvjNYE4rCUzO6X/X+kYjd7WFxXeJ0NwEFnRxX6ehkvv3jTwrXnNdtAak5XYZuIyPFw==} engines: {node: '>=18'} @@ -6006,6 +6441,10 @@ packages: engines: {node: '>=0.10.0'} dev: true + /ospath@1.2.2: + resolution: {integrity: sha512-o6E5qJV5zkAbIDNhGSIlyOhScKXgQrSRMilfph0clDfM0nEnBOlKlH4sWDmG95BW/CvwNz0vmm7dJVtU2KlMiA==} + dev: true + /outdent@0.5.0: resolution: {integrity: sha512-/jHxFIzoMXdqPzTaCpFzAAWhpkSjZPF4Vsn6jAfNpmbH/ymsmd7Qc6VE9BGn0L6YMj6uwpQLxCECpus4ukKS9Q==} dev: true @@ -6184,10 +6623,18 @@ packages: resolution: {integrity: sha512-Dp6zGqpTdETdR63lehJYPeIOqpiNBNtc7BpWSLrOje7UaIsE5aY92r/AunQA7rsXvet3lrJ3JnZX29UPTKXyKQ==} dev: true + /pend@1.2.0: + resolution: {integrity: sha512-F3asv42UuXchdzt+xXqfW1OGlVBe+mxa2mqI0pg5yAHZPvFmY3Y6drSf/GQ1A86WgWEN9Kzh/WrgKa6iGcHXLg==} + dev: true + /perfect-debounce@1.0.0: resolution: {integrity: sha512-xCy9V055GLEqoFaHoC1SoLIaLmWctgCUaBaWxDZ7/Zx4CTyX7cJQLJOok/orfjZAh9kEYpjJa4d0KcJmCbctZA==} dev: true + /performance-now@2.1.0: + resolution: {integrity: sha512-7EAHlyLHI56VEIdK57uwHdHKIaAGbnXPiw0yWbarQZOKaKpvUIgW0jWRVLiatnM+XXlSwsanIBH/hzGMJulMow==} + dev: true + /picocolors@1.0.1: resolution: {integrity: sha512-anP1Z8qwhkbmu7MFP5iTt+wQKXgwzf7zTyGlcdzabySa9vd0Xt392U0rVmz9poOaBj0uHJKyyo9/upk0HrEQew==} dev: true @@ -6202,6 +6649,11 @@ packages: hasBin: true dev: true + /pify@2.3.0: + resolution: {integrity: sha512-udgsAY+fTnvv7kI7aaxbqwWNb0AHiB0qBO89PZKPkoTmGOgdbrHDKD+0B2X4uTfJ/FT1R09r9gTsjUjNJotuog==} + engines: {node: '>=0.10.0'} + dev: true + /pify@4.0.1: resolution: {integrity: sha512-uB80kBFb/tfd68bVleG9T5GGsGPjJrLAUpR5PZIrhBnIaRTQRjqdJSsIKkOP6OAIFbj7GOrcudc5pNjZ+geV2g==} engines: {node: '>=6'} @@ -6291,6 +6743,11 @@ packages: hasBin: true dev: true + /pretty-bytes@5.6.0: + resolution: {integrity: sha512-FFw039TmrBqFK8ma/7OL3sDz/VytdtJr044/QUJtH0wK9lb9jLq9tJyIxUwtQJHwar2BqtiA4iCWSwo9JLkzFg==} + engines: {node: '>=6'} + dev: true + /pretty-format@29.7.0: resolution: {integrity: sha512-Pdlw/oPxN+aXdmM9R00JVC9WVFoCLTKJvDVLgmJ+qAffBMxsV85l/Lu7sNx4zSzPyoL2euImuEwHhOXdEgNFZQ==} engines: {node: ^14.15.0 || ^16.10.0 || >=18.0.0} @@ -6308,6 +6765,11 @@ packages: /process-nextick-args@2.0.1: resolution: {integrity: sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==} + /process@0.11.10: + resolution: {integrity: sha512-cdGef/drWFoydD1JsMzuFf8100nZl+GT+yacc2bEced5f9Rjk4z+WtFUTBu9PhOi9j/jfmBPu0mMEY4wIdAF8A==} + engines: {node: '>= 0.6.0'} + dev: true + /progress@2.0.3: resolution: {integrity: sha512-7PiHtLll5LdnKIMw100I+8xJXR5gW2QwWYkT6iJva0bXitZKa/XMrSbdmg3r2Xnaidz9Qumd0VPaMrZlF9V9sA==} engines: {node: '>=0.4.0'} @@ -6341,6 +6803,10 @@ packages: resolution: {integrity: sha512-vtK/94akxsTMhe0/cbfpR+syPuszcuwhqVjJq26CuNDgFGj682oRBXOP5MJpv2r7JtE8MsiepGIqvvOTBwn2vA==} dev: true + /proxy-from-env@1.0.0: + resolution: {integrity: sha512-F2JHgJQ1iqwnHDcQjVBsq3n/uoaFL+iPW/eAeL7kVxy/2RrWaN4WroKjjvbsoRtv0ftelNyC01bjRhn/bhcf4A==} + dev: true + /proxy-from-env@1.1.0: resolution: {integrity: sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==} dev: false @@ -6349,6 +6815,17 @@ packages: resolution: {integrity: sha512-b/YwNhb8lk1Zz2+bXXpS/LK9OisiZZ1SNsSLxN1x2OXVEhW2Ckr/7mWE5vrC1ZTiJlD9g19jWszTmJsB+oEpFQ==} dev: true + /psl@1.9.0: + resolution: {integrity: sha512-E/ZsdU4HLs/68gYzgGTkMicWTLPdAftJLfJFlLUAAKZGkStNU72sZjT66SnMDVOfOWY/YAoiD7Jxa9iHvngcag==} + dev: true + + /pump@3.0.0: + resolution: {integrity: sha512-LwZy+p3SFs1Pytd/jYct4wpv49HiYCqd9Rlc5ZVdk0V+8Yzv6jR5Blk3TRmPL1ft69TxP0IMZGJ+WPFU2BFhww==} + dependencies: + end-of-stream: 1.4.4 + once: 1.4.0 + dev: true + /punycode@1.4.1: resolution: {integrity: sha512-jmYNElW7yvO7TV33CjSmvSiE2yco3bV2czu/OzDKdMNVZQWfxCblURLhf+47syQRBntjfLdd/H0egrzIG+oaFQ==} dev: true @@ -6364,6 +6841,17 @@ packages: escape-goat: 4.0.0 dev: true + /qs@6.10.4: + resolution: {integrity: sha512-OQiU+C+Ds5qiH91qh/mg0w+8nwQuLjM4F4M/PbmhDOoYehPh+Fb0bDjtR1sOvy7YKxvj28Y/M0PhP5uVX0kB+g==} + engines: {node: '>=0.6'} + dependencies: + side-channel: 1.0.6 + dev: true + + /querystringify@2.2.0: + resolution: {integrity: sha512-FIqgj2EUvTa7R50u0rGsyTftzjYmv/a3hO345bZNrqabNqjtgiDMgmo4mkUjd+nzU5oF3dClKqFIPUKybUyqoQ==} + dev: true + /queue-microtask@1.2.3: resolution: {integrity: sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==} @@ -6398,7 +6886,7 @@ packages: /rc-config-loader@4.1.3: resolution: {integrity: sha512-kD7FqML7l800i6pS6pvLyIE2ncbk9Du8Q0gp/4hMPhJU6ZxApkoLcGD8ZeqgiAlfwZ6BlETq6qqe+12DUL207w==} dependencies: - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) js-yaml: 4.1.0 json5: 2.2.3 require-from-string: 2.0.2 @@ -6554,6 +7042,12 @@ packages: engines: {node: '>=8'} dev: true + /request-progress@3.0.0: + resolution: {integrity: sha512-MnWzEHHaxHO2iWiQuHrUPBi/1WeBf5PkxQqNyNvLl9VAYSdXkP8tQ3pBSeCPD+yw0v0Aq1zosWLz0BdeXpWwZg==} + dependencies: + throttleit: 1.0.1 + dev: true + /require-directory@2.1.1: resolution: {integrity: sha512-fGxEI7+wsG9xrvdjsrlmL22OMTTiHRwAMroiEeMgq8gzoLC/PQr7RsRDSTLUg/bZAZtF+TVIkHc6/4RIKrui+Q==} engines: {node: '>=0.10.0'} @@ -6570,7 +7064,6 @@ packages: /requires-port@1.0.0: resolution: {integrity: sha512-KigOCHcocU3XODJxsu8i/j8T9tzT4adHiecwORRQ0ZZFcp7ahwXuRU1m+yuO90C5ZUyGeGfocHDI14M3L3yDAQ==} - dev: false /resolve-alpn@1.2.1: resolution: {integrity: sha512-0a1F4l73/ZFZOakJnQ3FvkJ2+gSTQWz/r2KE5OdDY0TxPm5h4GkqkWWfM47T7HsbnOtcJVEF4epCVy6u7Q3K+g==} @@ -6596,6 +7089,14 @@ packages: lowercase-keys: 3.0.0 dev: true + /restore-cursor@3.1.0: + resolution: {integrity: sha512-l+sSefzHpj5qimhFSE5a8nufZYAM3sBSVMAPtYkmC+4EH2anSGaEMXSD0izRQbu9nfyQ9y5JrVmp7E8oZrUjvA==} + engines: {node: '>=8'} + dependencies: + onetime: 5.1.2 + signal-exit: 3.0.7 + dev: true + /restore-cursor@4.0.0: resolution: {integrity: sha512-I9fPXU9geO9bHOt9pHHOhOkYerIMsmVaWB0rA2AI9ERh/+x/i7MV5HKBNrg+ljO5eoPVgCcnFuRjJ9uH6I/3eg==} engines: {node: ^12.20.0 || ^14.13.1 || >=16.0.0} @@ -6883,6 +7384,24 @@ packages: engines: {node: '>=12'} dev: true + /slice-ansi@3.0.0: + resolution: {integrity: sha512-pSyv7bSTC7ig9Dcgbw9AuRNUb5k5V6oDudjZoMBSr13qpLBG7tB+zgCkARjq7xIUgdz5P1Qe8u+rSGdouOOIyQ==} + engines: {node: '>=8'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + + /slice-ansi@4.0.0: + resolution: {integrity: sha512-qMCMfhY040cVHT43K9BFygqYbUPFZKHOg7K73mtTWJRb8pyP3fzf4Ixd5SzdEJQ6MRUg/WBnOLxghZtKKurENQ==} + engines: {node: '>=10'} + dependencies: + ansi-styles: 4.3.0 + astral-regex: 2.0.0 + is-fullwidth-code-point: 3.0.0 + dev: true + /slice-ansi@5.0.0: resolution: {integrity: sha512-FC+lgizVPfie0kkhqUScwRu1O/lF6NOgJmlCgK+/LYxDCTk8sGelYaHDhFcDN+Sn3Cv+3VSa4Byeo+IMCzpMgQ==} engines: {node: '>=12'} @@ -6922,7 +7441,7 @@ packages: engines: {node: '>= 10'} dependencies: agent-base: 6.0.2 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) socks: 2.8.3 transitivePeerDependencies: - supports-color @@ -7025,6 +7544,22 @@ packages: resolution: {integrity: sha512-Oo+0REFV59/rz3gfJNKQiBlwfHaSESl1pcGyABQsnnIfWOFt6JNj5gCog2U6MLZ//IGYD+nA8nI+mTShREReaA==} dev: true + /sshpk@1.18.0: + resolution: {integrity: sha512-2p2KJZTSqQ/I3+HX42EpYOa2l3f8Erv8MWKsy2I9uf4wA7yFIkXRffYdsx86y6z4vHtV8u7g+pPlr8/4ouAxsQ==} + engines: {node: '>=0.10.0'} + hasBin: true + dependencies: + asn1: 0.2.6 + assert-plus: 1.0.0 + bcrypt-pbkdf: 1.0.2 + dashdash: 1.14.1 + ecc-jsbn: 0.1.2 + getpass: 0.1.7 + jsbn: 0.1.1 + safer-buffer: 2.1.2 + tweetnacl: 0.14.5 + dev: true + /ssri@10.0.6: resolution: {integrity: sha512-MGrFH9Z4NP9Iyhqn16sDtBpRRNJ0Y2hNa6D65h736fVSaPCHr4DM4sWUNvVaSuC+0OBGhwsrydQwmgfg5LncqQ==} engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} @@ -7213,6 +7748,12 @@ packages: dependencies: has-flag: 4.0.0 + /supports-color@8.1.1: + resolution: {integrity: sha512-MpUEN2OodtUzxvKQl72cUF7RQ5EiHsGvSsVG0ia9c5RbWGL2CI4C7EpPS8UTBIplnlzZiNuV56w+FuNxy3ty2Q==} + engines: {node: '>=10'} + dependencies: + has-flag: 4.0.0 + /supports-preserve-symlinks-flag@1.0.0: resolution: {integrity: sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==} engines: {node: '>= 0.4'} @@ -7276,6 +7817,14 @@ packages: tslib: 2.6.2 dev: true + /throttleit@1.0.1: + resolution: {integrity: sha512-vDZpf9Chs9mAdfY046mcPt8fg5QSZr37hEH4TXYBnDF+izxgrbRGUAAaBvIk/fJm9aOFCGFd1EsNg5AZCbnQCQ==} + dev: true + + /through@2.3.8: + resolution: {integrity: sha512-w89qg7PI8wAdvX60bMDP+bFoD5Dvhm9oLheFp5O4a2QF0cSBGsBX4qZmadPMvVqlLJBBci+WqGGOAPvcDeNSVg==} + dev: true + /tinybench@2.8.0: resolution: {integrity: sha512-1/eK7zUnIklz4JUUlL+658n58XO2hHLQfSk1Zf2LKieUjxidN16eKFEoDEfjHc3ohofSSqK3X5yO6VGb6iW8Lw==} dev: true @@ -7308,6 +7857,11 @@ packages: os-tmpdir: 1.0.2 dev: true + /tmp@0.2.3: + resolution: {integrity: sha512-nZD7m9iCPC5g0pYmcaxogYKggSfLsdxl8of3Q/oIbqCqLLIO9IAF0GWjX1z9NZRHPiXv8Wex4yDCaZsgEw0Y8w==} + engines: {node: '>=14.14'} + dev: true + /to-fast-properties@2.0.0: resolution: {integrity: sha512-/OaKK0xYrs3DmxRYqL/yDc+FxFUVYhDlXMhRmv3z915w2HF1tnN1omB354j8VUGO/hbRzyD6Y3sA7v7GS/ceog==} engines: {node: '>=4'} @@ -7319,6 +7873,16 @@ packages: dependencies: is-number: 7.0.0 + /tough-cookie@4.1.4: + resolution: {integrity: sha512-Loo5UUvLD9ScZ6jh8beX1T6sO1w2/MpCRpEP7V280GKMVUQ0Jzar2U3UJPsrdbziLEMMhu3Ujnq//rhiFuIeag==} + engines: {node: '>=6'} + dependencies: + psl: 1.9.0 + punycode: 2.3.1 + universalify: 0.2.0 + url-parse: 1.5.10 + dev: true + /tr46@1.0.1: resolution: {integrity: sha512-dTpowEjclQ7Kgx5SdBkqRzVhERQXov8/l9Ft9dVM9fmg0W0KQSVaXX9T4i6twCPNtYiZM53lpSSUAwJbFPOHxA==} dependencies: @@ -7366,7 +7930,7 @@ packages: bundle-require: 4.1.0(esbuild@0.19.12) cac: 6.7.14 chokidar: 3.6.0 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) esbuild: 0.19.12 execa: 5.1.1 globby: 11.1.0 @@ -7401,12 +7965,18 @@ packages: engines: {node: ^14.17.0 || ^16.13.0 || >=18.0.0} dependencies: '@tufjs/models': 1.0.4 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) make-fetch-happen: 11.1.1 transitivePeerDependencies: - supports-color dev: true + /tunnel-agent@0.6.0: + resolution: {integrity: sha512-McnNiV1l8RYeY8tBgEpuodCC1mLUdbSN+CYBL7kJsJNInOP8UjDDEwdk6Mw60vdLLrr5NHKZhMAOSrR2NZuQ+w==} + dependencies: + safe-buffer: 5.2.1 + dev: true + /turbo-darwin-64@1.12.3: resolution: {integrity: sha512-dDglIaux+A4jOnB9CDH69sujmrnuLJLrKw1t3J+if6ySlFuxSwC++gDq9TVuOZo2+S7lFkGh+x5ytn3wp+jE8Q==} cpu: [x64] @@ -7467,6 +8037,10 @@ packages: turbo-windows-arm64: 1.12.3 dev: true + /tweetnacl@0.14.5: + resolution: {integrity: sha512-KXXFFdAbFXY4geFIwoyNK+f5Z1b7swfXABfL7HXCmoIWMKU3dmS26672A4EeQtDzLKy7SXmfBu51JolvEKwtGA==} + dev: true + /type-detect@4.0.8: resolution: {integrity: sha512-0fr/mIH1dlO+x7TlcMy+bIDqKPsw/70tVyeHW787goQjhmqaZe10uwLujubK9q9Lg6Fiho1KUKDYz0Z7k7g5/g==} engines: {node: '>=4'} @@ -7649,10 +8223,14 @@ packages: engines: {node: '>= 4.0.0'} dev: true + /universalify@0.2.0: + resolution: {integrity: sha512-CJ1QgKmNg3CwvAv/kOFmtnEN05f0D/cn9QntgNOQlQF9dgvVTHj3t+8JPdjqawCHk7V/KA+fbUqzZ9XWhcqPUg==} + engines: {node: '>= 4.0.0'} + dev: true + /universalify@2.0.1: resolution: {integrity: sha512-gptHNQghINnc/vTGIk0SOFGFNXw7JVrlRUtConJRlvaw6DuX0wO5Jeko9sWrMBhh+PsYAZ7oXAiOnf/UKogyiw==} engines: {node: '>= 10.0.0'} - dev: false /untildify@4.0.0: resolution: {integrity: sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==} @@ -7707,9 +8285,21 @@ packages: punycode: 2.3.1 dev: true + /url-parse@1.5.10: + resolution: {integrity: sha512-WypcfiRhfeUP9vvF0j6rw0J3hrWrw6iZv3+22h6iRMJ/8z1Tj6XfLP4DsUix5MhMPnXpiHDoKyoZ/bdCkwBCiQ==} + dependencies: + querystringify: 2.2.0 + requires-port: 1.0.0 + dev: true + /util-deprecate@1.0.2: resolution: {integrity: sha512-EPD5q1uXyFxJpCrLnCc1nHnq3gOa6DZBocAIiI2TaSCA7VCJ1UJDMagCzIkXNsUYfD1daK//LTEQ8xiIbrHtcw==} + /uuid@8.3.2: + resolution: {integrity: sha512-+NYs2QeMWy+GWFOEm9xnn6HCDp0l7QBD7ml8zLUmJ+93Q5NF0NocErnwkTkXVFNiX3/fpC6afS8Dhb/gz7R7eg==} + hasBin: true + dev: true + /v8-to-istanbul@9.2.0: resolution: {integrity: sha512-/EH/sDgxU2eGxajKdwLCDmQ4FWq+kpi3uCmBGpw1xJtnAxEjlD8j8PEiGWpCIMIs3ciNAgH0d3TTJiUkYzyZjA==} engines: {node: '>=10.12.0'} @@ -7736,6 +8326,15 @@ packages: engines: {node: '>= 0.8'} dev: true + /verror@1.10.0: + resolution: {integrity: sha512-ZZKSmDAEFOijERBLkmYfJ+vmk3w+7hOLYDNkRCuRuMJGEmqYNCNLyBBFwWKVMhfwaEF3WOd0Zlw86U/WC/+nYw==} + engines: {'0': node >=0.6.0} + dependencies: + assert-plus: 1.0.0 + core-util-is: 1.0.2 + extsprintf: 1.3.0 + dev: true + /viem@2.9.9(typescript@5.3.3): resolution: {integrity: sha512-SUIHBL6M5IIlqDCMEQwAAvHzeglaM4FEqM6bCI+srLXtFYmrpV4tWhnpobQRNwh4f7HIksmKLLZ+cytv8FfnJQ==} peerDependencies: @@ -7765,7 +8364,7 @@ packages: hasBin: true dependencies: cac: 6.7.14 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) pathe: 1.1.2 picocolors: 1.0.1 vite: 5.2.11(@types/node@20.11.17) @@ -7905,7 +8504,7 @@ packages: acorn-walk: 8.3.2 cac: 6.7.14 chai: 4.4.1 - debug: 4.3.4 + debug: 4.3.4(supports-color@8.1.1) execa: 8.0.1 local-pkg: 0.5.0 magic-string: 0.30.10 @@ -8220,6 +8819,13 @@ packages: yargs-parser: 21.1.1 dev: true + /yauzl@2.10.0: + resolution: {integrity: sha512-p4a9I6X6nu6IhoGmBqAcbJy1mlC4j27vEPZX9F4L4/vZT3Lyq1VkFHw/V/PUcB9Buo+DG3iHkT0x3Qya58zc3g==} + dependencies: + buffer-crc32: 0.2.13 + fd-slicer: 1.1.0 + dev: true + /yocto-queue@0.1.0: resolution: {integrity: sha512-rVksvsnNCdJ/ohGc6xgPwyN8eheCxsiLM8mxuE/t/mOVqJewPuO1miLpTHQiRgTKCLexL4MeAFVagts7HmNZ2Q==} engines: {node: '>=10'} diff --git a/wallets/ethereum-wallet-mock/cypress.config.ts b/wallets/ethereum-wallet-mock/cypress.config.ts new file mode 100644 index 00000000..bdaf5363 --- /dev/null +++ b/wallets/ethereum-wallet-mock/cypress.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "cypress"; +// import { installSynpress } from "./src/cypress"; + +export default defineConfig({ + chromeWebSecurity: false, + e2e: { + baseUrl: "http://localhost:9999", + supportFile: "src/cypress/support/e2e.{js,jsx,ts,tsx}", + specPattern: "test/**/*.cy.{js,jsx,ts,tsx}", + fixturesFolder: "src/cypress/fixtures", + testIsolation: false, + async setupNodeEvents(on, config) { + // return installSynpress(on, config); + }, + }, +}); diff --git a/wallets/ethereum-wallet-mock/package.json b/wallets/ethereum-wallet-mock/package.json index 43bafcb3..dfd7266e 100644 --- a/wallets/ethereum-wallet-mock/package.json +++ b/wallets/ethereum-wallet-mock/package.json @@ -34,6 +34,7 @@ "@synthetixio/synpress-tsconfig": "0.0.1-alpha.7", "@types/node": "20.11.17", "@vitest/coverage-v8": "1.2.2", + "cypress": "13.9.0", "rimraf": "5.0.5", "tsup": "8.0.2", "typescript": "5.3.3" diff --git a/wallets/ethereum-wallet-mock/tsconfig.json b/wallets/ethereum-wallet-mock/tsconfig.json index f36ef006..d33f5ffe 100644 --- a/wallets/ethereum-wallet-mock/tsconfig.json +++ b/wallets/ethereum-wallet-mock/tsconfig.json @@ -3,7 +3,8 @@ "extends": "./tsconfig.build.json", "compilerOptions": { "rootDir": ".", - "exactOptionalPropertyTypes": false // Allows for `undefined` in `playwright.config.ts` + "exactOptionalPropertyTypes": false, // Allows for `undefined` in `playwright.config.ts` + "types": ["cypress"] }, "include": ["src", "test"], "files": ["environment.d.ts", "playwright.config.ts", "vitest.config.ts"] diff --git a/wallets/metamask/cypress.config.ts b/wallets/metamask/cypress.config.ts new file mode 100644 index 00000000..22d8dd72 --- /dev/null +++ b/wallets/metamask/cypress.config.ts @@ -0,0 +1,16 @@ +import { defineConfig } from "cypress"; +import { installSynpress } from './src/cypress'; + +export default defineConfig({ + chromeWebSecurity: false, + e2e: { + baseUrl: "http://localhost:9999", + supportFile: "src/cypress/support/e2e.{js,jsx,ts,tsx}", + specPattern: "test/**/*.cy.{js,jsx,ts,tsx}", + fixturesFolder: "src/cypress/fixtures", + testIsolation: false, + async setupNodeEvents(on, config) { + return installSynpress(on, config); + }, + }, +}); diff --git a/wallets/metamask/package.json b/wallets/metamask/package.json index d9b2eed9..5e73532b 100644 --- a/wallets/metamask/package.json +++ b/wallets/metamask/package.json @@ -41,6 +41,7 @@ "@types/fs-extra": "11.0.4", "@types/node": "20.11.17", "@vitest/coverage-v8": "1.2.2", + "cypress": "13.9.0", "rimraf": "5.0.5", "tsup": "8.0.2", "typescript": "5.3.3", diff --git a/wallets/metamask/src/cypress/errors.ts b/wallets/metamask/src/cypress/errors.ts new file mode 100644 index 00000000..105c9eef --- /dev/null +++ b/wallets/metamask/src/cypress/errors.ts @@ -0,0 +1,4 @@ +export const NO_CONTEXT = + "No browser context found. Connect Playwright first - connectPlaywright()"; +export const NO_METAMASK_PAGE = "No MetaMask page found. Use getMetaMaskPage()"; +export const MISSING_INIT = "MetaMask not initialized. Use initMetaMask()"; diff --git a/wallets/metamask/src/cypress/index.ts b/wallets/metamask/src/cypress/index.ts new file mode 100644 index 00000000..3e141ea7 --- /dev/null +++ b/wallets/metamask/src/cypress/index.ts @@ -0,0 +1 @@ +export { default as installSynpress } from "./installSynpress" diff --git a/wallets/metamask/src/cypress/initMetaMask.ts b/wallets/metamask/src/cypress/initMetaMask.ts new file mode 100644 index 00000000..df753514 --- /dev/null +++ b/wallets/metamask/src/cypress/initMetaMask.ts @@ -0,0 +1,80 @@ +import { type BrowserContext, type Page, chromium } from '@playwright/test' +import { MISSING_INIT, NO_CONTEXT, NO_METAMASK_PAGE } from './errors' +import { getExtensionId } from '../fixture-actions' +import { MetaMask } from '../MetaMask' +import { PASSWORD, SEED_PHRASE } from '../../test/wallet-setup/basic.setup' + +let context: BrowserContext | undefined +let extensionId: string | undefined +let metamaskPage: Page | undefined +let metamask: MetaMask | undefined + +export async function getMetaMaskExtensionId() { + if (extensionId) return extensionId + + if (!context) { + console.error(NO_CONTEXT) + return + } + + extensionId = await getExtensionId(context, 'MetaMask') + return extensionId +} + +const isMetaMaskPage = (page: Page) => page.url().includes(`chrome-extension://${extensionId}`) + +const getMetaMaskPage = async () => { + await getMetaMaskExtensionId() + + if (!context) { + console.error(NO_CONTEXT) + return + } + + metamaskPage = context.pages().find(isMetaMaskPage) + return metamaskPage +} + +export async function connectPlaywrightToChrome(port: number) { + const debuggerDetails = await fetch(`http://127.0.0.1:${port}/json/version`) + + const debuggerDetailsConfig = (await debuggerDetails.json()) as { + webSocketDebuggerUrl: string + } + + const browser = await chromium.connectOverCDP(debuggerDetailsConfig.webSocketDebuggerUrl) + + context = browser.contexts()[0] + + return browser.isConnected() +} + +export async function initMetaMask(port: number) { + await connectPlaywrightToChrome(port) + + if (!context) { + console.error(NO_CONTEXT) + return + } + + await getMetaMaskPage() + + if (!metamaskPage) { + console.error(NO_METAMASK_PAGE) + return + } + + metamask = new MetaMask(context, metamaskPage, PASSWORD) + await metamask.importWallet(SEED_PHRASE) +} + +export function getMetaMask() { + if (!context || !metamaskPage || !metamask) { + console.error(MISSING_INIT) + return + } + + if (metamask) return metamask + + return new MetaMask(context, metamaskPage, PASSWORD) +} diff --git a/wallets/metamask/src/cypress/installSynpress.ts b/wallets/metamask/src/cypress/installSynpress.ts new file mode 100644 index 00000000..2e921f8d --- /dev/null +++ b/wallets/metamask/src/cypress/installSynpress.ts @@ -0,0 +1,52 @@ +import { prepareExtension } from '../fixture-actions' +import { initMetaMask } from './initMetaMask' +import setupTasks from './setupTasks' + +let port = 0 + +function ensureRdpPort(args: string[]) { + const existing = args.find((arg) => arg.slice(0, 23) === '--remote-debugging-port') + + if (existing) { + return Number(existing.split('=')[1]) + } + + const port = 40000 + Math.round(Math.random() * 25000) + + args.push(`--remote-debugging-port=${port}`) + + return port +} + +export default function installSynpress(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) { + const browsers = config.browsers.filter((b) => b.name === 'chrome') + if (browsers.length === 0) { + throw new Error('No Chrome browser found in the configuration') + } + + on('before:browser:launch', async (_, launchOptions) => { + // Enable debug mode to establish playwright connection + const args = Array.isArray(launchOptions) ? launchOptions : launchOptions.args + port = ensureRdpPort(args) + + // Preserved cache is not supported for Cypress - https://docs.cypress.io/guides/guides/launching-browsers#Cypress-Profile + // launchOptions.args.push('--user-data-dir=X') + + // Add MetaMask extension + const metamaskExtensionPath = await prepareExtension() + launchOptions.extensions.push(metamaskExtensionPath) + + return launchOptions + }) + + on('before:spec', async () => { + await initMetaMask(port) + }) + + setupTasks(on) + + return { + ...config, + browsers + } +} diff --git a/wallets/metamask/src/cypress/setupTasks.ts b/wallets/metamask/src/cypress/setupTasks.ts new file mode 100644 index 00000000..2595e007 --- /dev/null +++ b/wallets/metamask/src/cypress/setupTasks.ts @@ -0,0 +1,34 @@ +import { getMetaMask } from './initMetaMask'; + +export default function setupTasks(on: Cypress.PluginEvents) { + on("task", { + importWallet: async function (seedPhrase: string) { + const metamask = getMetaMask(); + if (metamask) { + await metamask.importWallet(seedPhrase); + } + return true; + }, + addNewAccount: async function (accountName: string) { + const metamask = getMetaMask(); + if (metamask) { + await metamask.addNewAccount(accountName); + } + return true; + }, + importWalletFromPrivateKey: async function (privateKey: string) { + const metamask = getMetaMask(); + if (metamask) { + await metamask.importWalletFromPrivateKey(privateKey); + } + return true; + }, + openSettings: async function () { + const metamask = getMetaMask(); + if (metamask) { + await metamask.openSettings(); + } + return true; + }, + }); +} diff --git a/wallets/metamask/test/wallet-setup/basic.setup.ts b/wallets/metamask/test/wallet-setup/basic.setup.ts index 82b61fbf..bd95e161 100644 --- a/wallets/metamask/test/wallet-setup/basic.setup.ts +++ b/wallets/metamask/test/wallet-setup/basic.setup.ts @@ -1,9 +1,9 @@ import { defineWalletSetup } from '@synthetixio/synpress-cache' import { MetaMask } from '../../src' -const SEED_PHRASE = 'test test test test test test test test test test test junk' +export const SEED_PHRASE = 'test test test test test test test test test test test junk' -const PASSWORD = 'Tester@1234' +export const PASSWORD = 'Tester@1234' export default defineWalletSetup(PASSWORD, async (context, walletPage) => { const metamask = new MetaMask(context, walletPage, PASSWORD) diff --git a/wallets/metamask/tsconfig.json b/wallets/metamask/tsconfig.json index d5e9e89c..15e94bcc 100644 --- a/wallets/metamask/tsconfig.json +++ b/wallets/metamask/tsconfig.json @@ -2,7 +2,8 @@ "extends": "./tsconfig.build.json", "compilerOptions": { "rootDir": ".", - "exactOptionalPropertyTypes": false // Allows for `undefined` in `playwright.config.ts` + "exactOptionalPropertyTypes": false, // Allows for `undefined` in `playwright.config.ts` + "types": ["cypress"], }, "include": [ "src", From 3f6c1fd9ab9f265051ca1cdd8e4e2f9bcc0d8908 Mon Sep 17 00:00:00 2001 From: matstyler Date: Wed, 22 May 2024 10:32:38 +0200 Subject: [PATCH 02/11] feat: cypress for mocked wallet - basics --- packages/core/src/cypress/ensureRdpPort.ts | 15 +++++ packages/core/src/cypress/index.ts | 0 .../ethereum-wallet-mock/cypress.config.ts | 6 +- wallets/ethereum-wallet-mock/package.json | 2 + .../ethereum-wallet-mock/playwright.config.ts | 2 +- .../src/cypress/errors.ts | 4 ++ .../ethereum-wallet-mock/src/cypress/index.ts | 1 + .../src/cypress/initEthereumWalletMock.ts | 65 +++++++++++++++++++ .../src/cypress/installSynpress.ts | 49 ++++++++++++++ .../src/cypress/setupTasks.ts | 34 ++++++++++ .../src/cypress/support/commands.ts | 50 ++++++++++++++ .../src/cypress/support/e2e.ts | 17 +++++ .../test/cypress/metamask/setupMetaMask.cy.ts | 11 ++++ .../{e2e => playwright}/addNewAccount.spec.ts | 0 .../importWalletFromPrivateKey.spec.ts | 0 .../metamask/addNewAccount.spec.ts | 0 .../importWalletFromPrivateKey.spec.ts | 0 .../metamask/mock/mockEthereum.spec.ts | 0 .../metamask/switchAccount.spec.ts | 0 .../metamask/switchNetwork.spec.ts | 0 .../mock/mockEthereum.spec.ts | 0 .../{e2e => playwright}/switchAccount.spec.ts | 0 .../{e2e => playwright}/switchNetwork.spec.ts | 0 23 files changed, 252 insertions(+), 4 deletions(-) create mode 100644 packages/core/src/cypress/ensureRdpPort.ts create mode 100644 packages/core/src/cypress/index.ts create mode 100644 wallets/ethereum-wallet-mock/src/cypress/errors.ts create mode 100644 wallets/ethereum-wallet-mock/src/cypress/index.ts create mode 100644 wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts create mode 100644 wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts create mode 100644 wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts create mode 100644 wallets/ethereum-wallet-mock/src/cypress/support/commands.ts create mode 100644 wallets/ethereum-wallet-mock/src/cypress/support/e2e.ts create mode 100644 wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/addNewAccount.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/importWalletFromPrivateKey.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/metamask/addNewAccount.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/metamask/importWalletFromPrivateKey.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/metamask/mock/mockEthereum.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/metamask/switchAccount.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/metamask/switchNetwork.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/mock/mockEthereum.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/switchAccount.spec.ts (100%) rename wallets/ethereum-wallet-mock/test/{e2e => playwright}/switchNetwork.spec.ts (100%) diff --git a/packages/core/src/cypress/ensureRdpPort.ts b/packages/core/src/cypress/ensureRdpPort.ts new file mode 100644 index 00000000..51248770 --- /dev/null +++ b/packages/core/src/cypress/ensureRdpPort.ts @@ -0,0 +1,15 @@ +export default function ensureRdpPort(args: string[]) { + const existing = args.find( + (arg) => arg.slice(0, 23) === "--remote-debugging-port" + ); + + if (existing) { + return Number(existing.split("=")[1]); + } + + const port = 40000 + Math.round(Math.random() * 25000); + + args.push(`--remote-debugging-port=${port}`); + + return port; +} diff --git a/packages/core/src/cypress/index.ts b/packages/core/src/cypress/index.ts new file mode 100644 index 00000000..e69de29b diff --git a/wallets/ethereum-wallet-mock/cypress.config.ts b/wallets/ethereum-wallet-mock/cypress.config.ts index bdaf5363..a676a23e 100644 --- a/wallets/ethereum-wallet-mock/cypress.config.ts +++ b/wallets/ethereum-wallet-mock/cypress.config.ts @@ -1,16 +1,16 @@ import { defineConfig } from "cypress"; -// import { installSynpress } from "./src/cypress"; +import { installSynpress } from "./src/cypress"; export default defineConfig({ chromeWebSecurity: false, e2e: { baseUrl: "http://localhost:9999", + specPattern: "test/cypress/**/*.cy.{js,jsx,ts,tsx}", supportFile: "src/cypress/support/e2e.{js,jsx,ts,tsx}", - specPattern: "test/**/*.cy.{js,jsx,ts,tsx}", fixturesFolder: "src/cypress/fixtures", testIsolation: false, async setupNodeEvents(on, config) { - // return installSynpress(on, config); + return installSynpress(on, config); }, }, }); diff --git a/wallets/ethereum-wallet-mock/package.json b/wallets/ethereum-wallet-mock/package.json index dfd7266e..5296f113 100644 --- a/wallets/ethereum-wallet-mock/package.json +++ b/wallets/ethereum-wallet-mock/package.json @@ -19,7 +19,9 @@ "build:types": "tsc --emitDeclarationOnly --project tsconfig.build.json", "clean": "rimraf dist types", "test:e2e:headful": "playwright test", + "test:e2e:headful:cypress": "cypress run --browser chrome --headed", "test:e2e:headless": "HEADLESS=true playwright test", + "test:e2e:headless:cypress": "cypress run --headless --browser chrome", "test:e2e:headless:ui": "HEADLESS=true playwright test --ui", "test:watch": "vitest watch", "types:check": "tsc --noEmit" diff --git a/wallets/ethereum-wallet-mock/playwright.config.ts b/wallets/ethereum-wallet-mock/playwright.config.ts index 0994ed0a..60e97f30 100644 --- a/wallets/ethereum-wallet-mock/playwright.config.ts +++ b/wallets/ethereum-wallet-mock/playwright.config.ts @@ -5,7 +5,7 @@ import { defineConfig, devices } from '@playwright/test' */ export default defineConfig({ // Look for test files in the "test/e2e" directory, relative to this configuration file. - testDir: './test/e2e', + testDir: './test/e2e/playwright', // We're increasing the timeout to 60 seconds to allow all traces to be recorded. // Sometimes it threw an error saying that traces were not recorded in the 30 seconds timeout limit. diff --git a/wallets/ethereum-wallet-mock/src/cypress/errors.ts b/wallets/ethereum-wallet-mock/src/cypress/errors.ts new file mode 100644 index 00000000..f9e1cab5 --- /dev/null +++ b/wallets/ethereum-wallet-mock/src/cypress/errors.ts @@ -0,0 +1,4 @@ +export const NO_CONTEXT = + "No browser context found. Connect Playwright first - connectPlaywright()"; +export const NO_PAGE = "No page found. Use getPage()"; +export const MISSING_INIT = "EthereumWalletMock not initialized. Use initEthereumWalletMock()"; diff --git a/wallets/ethereum-wallet-mock/src/cypress/index.ts b/wallets/ethereum-wallet-mock/src/cypress/index.ts new file mode 100644 index 00000000..3e141ea7 --- /dev/null +++ b/wallets/ethereum-wallet-mock/src/cypress/index.ts @@ -0,0 +1 @@ +export { default as installSynpress } from "./installSynpress" diff --git a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts new file mode 100644 index 00000000..d1283907 --- /dev/null +++ b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts @@ -0,0 +1,65 @@ +import { type BrowserContext, chromium, type Page } from "@playwright/test"; +import { MISSING_INIT, NO_CONTEXT, NO_PAGE } from "./errors"; +import { EthereumWalletMock } from "../EthereumWalletMock"; +import { SEED_PHRASE } from "../utils"; + +let context: BrowserContext | undefined; +let page: Page | undefined; +let ethereumWalletMock: EthereumWalletMock | undefined; + +const getPage = async () => { + if (!context) { + console.error(NO_CONTEXT); + return; + } + + page = await context.newPage(); + + return page; +}; + +export async function connectPlaywrightToChrome(port: number) { + const debuggerDetails = await fetch(`http://127.0.0.1:${port}/json/version`); + + const debuggerDetailsConfig = (await debuggerDetails.json()) as { + webSocketDebuggerUrl: string; + }; + + const browser = await chromium.connectOverCDP( + debuggerDetailsConfig.webSocketDebuggerUrl + ); + + context = browser.contexts()[0]; + + return browser.isConnected(); +} + +export async function initEthereumWalletMock(port: number) { + await connectPlaywrightToChrome(port); + + if (!context) { + console.error(NO_CONTEXT); + return; + } + + await getPage(); + + if (!page) { + console.error(NO_PAGE); + return; + } + + ethereumWalletMock = new EthereumWalletMock(page); + await ethereumWalletMock.importWallet(SEED_PHRASE); +} + +export function getEthereumWalletMock() { + if (!context || !page || !ethereumWalletMock) { + console.error(MISSING_INIT); + return; + } + + if (ethereumWalletMock) return ethereumWalletMock; + + return new EthereumWalletMock(page); +} diff --git a/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts b/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts new file mode 100644 index 00000000..814beaea --- /dev/null +++ b/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts @@ -0,0 +1,49 @@ +import { initEthereumWalletMock } from "./initEthereumWalletMock"; +import setupTasks from "./setupTasks"; + +let port = 0; + +function ensureRdpPort(args: string[]) { + const existing = args.find( + (arg) => arg.slice(0, 23) === "--remote-debugging-port" + ); + + if (existing) { + return Number(existing.split("=")[1]); + } + + const port = 40000 + Math.round(Math.random() * 25000); + + args.push(`--remote-debugging-port=${port}`); + + return port; +} + +export default function installSynpress( + on: Cypress.PluginEvents, + config: Cypress.PluginConfigOptions +) { + const browsers = config.browsers.filter((b) => b.name === "chrome"); + if (browsers.length === 0) { + throw new Error("No Chrome browser found in the configuration"); + } + + on("before:browser:launch", async (_, launchOptions) => { + // Enable debug mode to establish playwright connection + const args = Array.isArray(launchOptions) + ? launchOptions + : launchOptions.args; + port = ensureRdpPort(args); + }); + + on("before:spec", async () => { + await initEthereumWalletMock(port); + }); + + setupTasks(on); + + return { + ...config, + browsers, + }; +} diff --git a/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts b/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts new file mode 100644 index 00000000..ba7964d0 --- /dev/null +++ b/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts @@ -0,0 +1,34 @@ +import { getEthereumWalletMock } from './initEthereumWalletMock'; + +export default function setupTasks(on: Cypress.PluginEvents) { + on("task", { + importWallet: async function (seedPhrase: string) { + const ethereumWalletMock = getEthereumWalletMock(); + if (ethereumWalletMock) { + await ethereumWalletMock.importWallet(seedPhrase); + } + return true; + }, + addNewAccount: async function (accountName: string) { + const ethereumWalletMock = getEthereumWalletMock(); + if (ethereumWalletMock) { + await ethereumWalletMock.addNewAccount(accountName); + } + return true; + }, + importWalletFromPrivateKey: async function (privateKey: string) { + const ethereumWalletMock = getEthereumWalletMock(); + if (ethereumWalletMock) { + await ethereumWalletMock.importWalletFromPrivateKey(privateKey); + } + return true; + }, + openSettings: async function () { + const ethereumWalletMock = getEthereumWalletMock(); + if (ethereumWalletMock) { + await ethereumWalletMock.openSettings(); + } + return true; + }, + }); +} diff --git a/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts new file mode 100644 index 00000000..95e26a6c --- /dev/null +++ b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts @@ -0,0 +1,50 @@ +/// +// *********************************************** +// This example commands.ts shows you how to +// create various custom commands and overwrite +// existing commands. +// +// For more comprehensive examples of custom +// commands please read more here: +// https://on.cypress.io/custom-commands +// *********************************************** +// +// +// -- This is a parent command -- +// Cypress.Commands.add('login', (email, password) => { ... }) +// +// +// -- This is a child command -- +// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) +// +// +// -- This is a dual command -- +// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) +// +// +// -- This will overwrite an existing command -- +// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) +// +// import { MetaMask } from "../metamask"; +// import { PASSWORD } from "../constants"; + +declare global { + namespace Cypress { + interface Chainable { + importWallet(seedPhrase: string): Chainable; + addNewAccount(accountName: string): Chainable; + importWalletFromPrivateKey(privateKey: string): Chainable; + openSettings(): Chainable; + } + } +} +Cypress.Commands.add("importWallet", (seedPhrase) => + cy.task("importWallet", seedPhrase) +); +Cypress.Commands.add("addNewAccount", (accountName) => + cy.task("addNewAccount", accountName) +); +Cypress.Commands.add("importWalletFromPrivateKey", (privateKey) => + cy.task("importWalletFromPrivateKey", privateKey) +); +Cypress.Commands.add("openSettings", () => cy.task("openSettings")); diff --git a/wallets/ethereum-wallet-mock/src/cypress/support/e2e.ts b/wallets/ethereum-wallet-mock/src/cypress/support/e2e.ts new file mode 100644 index 00000000..c90b6b6d --- /dev/null +++ b/wallets/ethereum-wallet-mock/src/cypress/support/e2e.ts @@ -0,0 +1,17 @@ +// *********************************************************** +// This example support/e2e.ts is processed and +// loaded automatically before your test files. +// +// This is a great place to put global configuration and +// behavior that modifies Cypress. +// +// You can change the location of this file or turn off +// automatically serving support files with the +// 'supportFile' configuration option. +// +// You can read more here: +// https://on.cypress.io/configuration +// *********************************************************** + +// Import commands.js using ES2015 syntax: +import './commands' diff --git a/wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts b/wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts new file mode 100644 index 00000000..89252d8b --- /dev/null +++ b/wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts @@ -0,0 +1,11 @@ +it("should add new MetaMask account", () => { + cy.addNewAccount("Synpress with Cypress test"); + + cy.wait(10000); +}); + +it("should open MetaMask settings", () => { + cy.openSettings(); + + cy.wait(10000); +}); diff --git a/wallets/ethereum-wallet-mock/test/e2e/addNewAccount.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/addNewAccount.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/addNewAccount.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/addNewAccount.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/importWalletFromPrivateKey.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/importWalletFromPrivateKey.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/importWalletFromPrivateKey.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/importWalletFromPrivateKey.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/metamask/addNewAccount.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/metamask/addNewAccount.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/metamask/addNewAccount.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/metamask/addNewAccount.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/metamask/importWalletFromPrivateKey.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/metamask/importWalletFromPrivateKey.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/metamask/importWalletFromPrivateKey.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/metamask/importWalletFromPrivateKey.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/metamask/mock/mockEthereum.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/metamask/mock/mockEthereum.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/metamask/mock/mockEthereum.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/metamask/mock/mockEthereum.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/metamask/switchAccount.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/metamask/switchAccount.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/metamask/switchAccount.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/metamask/switchAccount.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/metamask/switchNetwork.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/metamask/switchNetwork.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/metamask/switchNetwork.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/metamask/switchNetwork.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/mock/mockEthereum.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/mock/mockEthereum.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/mock/mockEthereum.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/mock/mockEthereum.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/switchAccount.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/switchAccount.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/switchAccount.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/switchAccount.spec.ts diff --git a/wallets/ethereum-wallet-mock/test/e2e/switchNetwork.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/switchNetwork.spec.ts similarity index 100% rename from wallets/ethereum-wallet-mock/test/e2e/switchNetwork.spec.ts rename to wallets/ethereum-wallet-mock/test/playwright/switchNetwork.spec.ts From e5d18950fd89a35601e52825cc3aa8db644360e3 Mon Sep 17 00:00:00 2001 From: matstyler Date: Thu, 23 May 2024 17:28:56 +0200 Subject: [PATCH 03/11] feat: Cypress with mocked ethereum wallet --- packages/core/src/cypress/index.ts | 1 + packages/core/src/index.ts | 1 + .../ethereum-wallet-mock/cypress.config.ts | 20 ++--- .../src/cypress/errors.ts | 7 +- .../ethereum-wallet-mock/src/cypress/index.ts | 2 +- .../src/cypress/initEthereumWalletMock.ts | 81 +++++++++++-------- .../src/cypress/installSynpress.ts | 54 ++++--------- .../src/cypress/setupTasks.ts | 37 ++++----- .../src/cypress/support/commands.ts | 39 ++------- .../fixtures/ethereumWalletMockFixtures.ts | 7 +- .../src/utils/constants.ts | 6 ++ .../test/cypress/metamask/setupMetaMask.cy.ts | 14 ++-- wallets/ethereum-wallet-mock/tsconfig.json | 3 +- wallets/metamask/package.json | 1 - wallets/metamask/src/cypress/errors.ts | 4 - wallets/metamask/src/cypress/index.ts | 1 - wallets/metamask/src/cypress/initMetaMask.ts | 80 ------------------ .../metamask/src/cypress/installSynpress.ts | 52 ------------ wallets/metamask/src/cypress/setupTasks.ts | 34 -------- .../test/wallet-setup/basic.setup.d.ts | 9 +++ .../test/wallet-setup/basic.setup.d.ts.map | 1 + 21 files changed, 124 insertions(+), 330 deletions(-) delete mode 100644 wallets/metamask/src/cypress/errors.ts delete mode 100644 wallets/metamask/src/cypress/index.ts delete mode 100644 wallets/metamask/src/cypress/initMetaMask.ts delete mode 100644 wallets/metamask/src/cypress/installSynpress.ts delete mode 100644 wallets/metamask/src/cypress/setupTasks.ts create mode 100644 wallets/metamask/test/wallet-setup/basic.setup.d.ts create mode 100644 wallets/metamask/test/wallet-setup/basic.setup.d.ts.map diff --git a/packages/core/src/cypress/index.ts b/packages/core/src/cypress/index.ts index e69de29b..f88de010 100644 --- a/packages/core/src/cypress/index.ts +++ b/packages/core/src/cypress/index.ts @@ -0,0 +1 @@ +export { default as ensureRdpPort } from "./ensureRdpPort" diff --git a/packages/core/src/index.ts b/packages/core/src/index.ts index 33435f5c..49d444d3 100644 --- a/packages/core/src/index.ts +++ b/packages/core/src/index.ts @@ -1 +1,2 @@ export { default as testWithSynpress } from './testWithSynpress' +export * from './cypress' diff --git a/wallets/ethereum-wallet-mock/cypress.config.ts b/wallets/ethereum-wallet-mock/cypress.config.ts index a676a23e..e57319d6 100644 --- a/wallets/ethereum-wallet-mock/cypress.config.ts +++ b/wallets/ethereum-wallet-mock/cypress.config.ts @@ -1,16 +1,16 @@ -import { defineConfig } from "cypress"; -import { installSynpress } from "./src/cypress"; +import { defineConfig } from 'cypress' +import { installSynpress } from './src/cypress' export default defineConfig({ chromeWebSecurity: false, e2e: { - baseUrl: "http://localhost:9999", - specPattern: "test/cypress/**/*.cy.{js,jsx,ts,tsx}", - supportFile: "src/cypress/support/e2e.{js,jsx,ts,tsx}", - fixturesFolder: "src/cypress/fixtures", + baseUrl: 'http://localhost:9999', + specPattern: 'test/cypress/**/*.cy.{js,jsx,ts,tsx}', + supportFile: 'src/cypress/support/e2e.{js,jsx,ts,tsx}', + fixturesFolder: 'src/cypress/fixtures', testIsolation: false, async setupNodeEvents(on, config) { - return installSynpress(on, config); - }, - }, -}); + return installSynpress(on, config) + } + } +}) diff --git a/wallets/ethereum-wallet-mock/src/cypress/errors.ts b/wallets/ethereum-wallet-mock/src/cypress/errors.ts index f9e1cab5..fe094a48 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/errors.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/errors.ts @@ -1,4 +1,3 @@ -export const NO_CONTEXT = - "No browser context found. Connect Playwright first - connectPlaywright()"; -export const NO_PAGE = "No page found. Use getPage()"; -export const MISSING_INIT = "EthereumWalletMock not initialized. Use initEthereumWalletMock()"; +export const NO_CONTEXT = 'No browser context found. Connect Playwright first - connectPlaywright()' +export const NO_PAGE = 'No page found. Use getPage()' +export const MISSING_INIT = 'EthereumWalletMock not initialized. Use initEthereumWalletMock()' diff --git a/wallets/ethereum-wallet-mock/src/cypress/index.ts b/wallets/ethereum-wallet-mock/src/cypress/index.ts index 3e141ea7..c1cf1560 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/index.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/index.ts @@ -1 +1 @@ -export { default as installSynpress } from "./installSynpress" +export { default as installSynpress } from './installSynpress' diff --git a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts index d1283907..8cf53fca 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts @@ -1,65 +1,76 @@ -import { type BrowserContext, chromium, type Page } from "@playwright/test"; -import { MISSING_INIT, NO_CONTEXT, NO_PAGE } from "./errors"; -import { EthereumWalletMock } from "../EthereumWalletMock"; -import { SEED_PHRASE } from "../utils"; +import { type BrowserContext, chromium, type Page } from '@playwright/test' +import { MISSING_INIT, NO_CONTEXT, NO_PAGE } from './errors' +import { EthereumWalletMock } from '../EthereumWalletMock' +import { mockEthereum, SEED_PHRASE, web3MockPath } from '../utils' +import { readFileSync } from 'fs' -let context: BrowserContext | undefined; -let page: Page | undefined; -let ethereumWalletMock: EthereumWalletMock | undefined; +let context: BrowserContext | undefined +let cypressPage: Page | undefined +let ethereumWalletMock: EthereumWalletMock | undefined -const getPage = async () => { +let ethereumObjectLoaded = false + +const getCypressPage = async () => { if (!context) { - console.error(NO_CONTEXT); - return; + console.error(NO_CONTEXT) + return } - page = await context.newPage(); + cypressPage = context.pages()[0] - return page; -}; + return cypressPage +} export async function connectPlaywrightToChrome(port: number) { - const debuggerDetails = await fetch(`http://127.0.0.1:${port}/json/version`); + const debuggerDetails = await fetch(`http://127.0.0.1:${port}/json/version`) const debuggerDetailsConfig = (await debuggerDetails.json()) as { - webSocketDebuggerUrl: string; - }; + webSocketDebuggerUrl: string + } - const browser = await chromium.connectOverCDP( - debuggerDetailsConfig.webSocketDebuggerUrl - ); + const browser = await chromium.connectOverCDP(debuggerDetailsConfig.webSocketDebuggerUrl) - context = browser.contexts()[0]; + context = browser.contexts()[0] - return browser.isConnected(); + return browser.isConnected() } export async function initEthereumWalletMock(port: number) { - await connectPlaywrightToChrome(port); + await connectPlaywrightToChrome(port) if (!context) { - console.error(NO_CONTEXT); - return; + console.error(NO_CONTEXT) + return + } + + await getCypressPage() + + if (!cypressPage) { + console.error(NO_PAGE) + return } - await getPage(); + await context.addInitScript({ + content: `${readFileSync(web3MockPath, 'utf-8')}\n(${mockEthereum.toString()})();` + }) - if (!page) { - console.error(NO_PAGE); - return; + // As we want to refresh the page after mocking the ethereum object + if (!ethereumObjectLoaded) { + await cypressPage.reload() + ethereumObjectLoaded = true } - ethereumWalletMock = new EthereumWalletMock(page); - await ethereumWalletMock.importWallet(SEED_PHRASE); + ethereumWalletMock = new EthereumWalletMock(cypressPage) + await ethereumWalletMock.importWallet(SEED_PHRASE) } export function getEthereumWalletMock() { - if (!context || !page || !ethereumWalletMock) { - console.error(MISSING_INIT); - return; + if (!context || !cypressPage || !ethereumWalletMock) { + console.error(MISSING_INIT) + return } - if (ethereumWalletMock) return ethereumWalletMock; + if (ethereumWalletMock) return ethereumWalletMock - return new EthereumWalletMock(page); + return new EthereumWalletMock(cypressPage) } diff --git a/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts b/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts index 814beaea..bb562138 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts @@ -1,49 +1,29 @@ -import { initEthereumWalletMock } from "./initEthereumWalletMock"; -import setupTasks from "./setupTasks"; +import { initEthereumWalletMock } from './initEthereumWalletMock' +import setupTasks from './setupTasks' +import { ensureRdpPort } from '@synthetixio/synpress-core' -let port = 0; +let port: number -function ensureRdpPort(args: string[]) { - const existing = args.find( - (arg) => arg.slice(0, 23) === "--remote-debugging-port" - ); - - if (existing) { - return Number(existing.split("=")[1]); - } - - const port = 40000 + Math.round(Math.random() * 25000); - - args.push(`--remote-debugging-port=${port}`); - - return port; -} - -export default function installSynpress( - on: Cypress.PluginEvents, - config: Cypress.PluginConfigOptions -) { - const browsers = config.browsers.filter((b) => b.name === "chrome"); +export default function installSynpress(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) { + const browsers = config.browsers.filter((b) => b.name === 'chrome') if (browsers.length === 0) { - throw new Error("No Chrome browser found in the configuration"); + throw new Error('No Chrome browser found in the configuration') } - on("before:browser:launch", async (_, launchOptions) => { + on('before:browser:launch', async (_, launchOptions) => { // Enable debug mode to establish playwright connection - const args = Array.isArray(launchOptions) - ? launchOptions - : launchOptions.args; - port = ensureRdpPort(args); - }); + const args = Array.isArray(launchOptions) ? launchOptions : launchOptions.args + port = ensureRdpPort(args) + }) - on("before:spec", async () => { - await initEthereumWalletMock(port); - }); + on('before:spec', async () => { + await initEthereumWalletMock(port) + }) - setupTasks(on); + setupTasks(on) return { ...config, - browsers, - }; + browsers + } } diff --git a/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts b/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts index ba7964d0..6a801b90 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts @@ -1,34 +1,27 @@ -import { getEthereumWalletMock } from './initEthereumWalletMock'; +import { getEthereumWalletMock } from './initEthereumWalletMock' export default function setupTasks(on: Cypress.PluginEvents) { - on("task", { + on('task', { importWallet: async function (seedPhrase: string) { - const ethereumWalletMock = getEthereumWalletMock(); + const ethereumWalletMock = getEthereumWalletMock() if (ethereumWalletMock) { - await ethereumWalletMock.importWallet(seedPhrase); + await ethereumWalletMock.importWallet(seedPhrase) } - return true; + return true }, - addNewAccount: async function (accountName: string) { - const ethereumWalletMock = getEthereumWalletMock(); + addNewAccount: async function () { + const ethereumWalletMock = getEthereumWalletMock() if (ethereumWalletMock) { - await ethereumWalletMock.addNewAccount(accountName); + await ethereumWalletMock.addNewAccount() } - return true; + return true }, - importWalletFromPrivateKey: async function (privateKey: string) { - const ethereumWalletMock = getEthereumWalletMock(); + getAllAccounts: async function () { + const ethereumWalletMock = getEthereumWalletMock() if (ethereumWalletMock) { - await ethereumWalletMock.importWalletFromPrivateKey(privateKey); + return await ethereumWalletMock.getAllAccounts() } - return true; - }, - openSettings: async function () { - const ethereumWalletMock = getEthereumWalletMock(); - if (ethereumWalletMock) { - await ethereumWalletMock.openSettings(); - } - return true; - }, - }); + return [] + } + }) } diff --git a/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts index 95e26a6c..a2476a74 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts @@ -8,43 +8,16 @@ // commands please read more here: // https://on.cypress.io/custom-commands // *********************************************** -// -// -// -- This is a parent command -- -// Cypress.Commands.add('login', (email, password) => { ... }) -// -// -// -- This is a child command -- -// Cypress.Commands.add('drag', { prevSubject: 'element'}, (subject, options) => { ... }) -// -// -// -- This is a dual command -- -// Cypress.Commands.add('dismiss', { prevSubject: 'optional'}, (subject, options) => { ... }) -// -// -// -- This will overwrite an existing command -- -// Cypress.Commands.overwrite('visit', (originalFn, url, options) => { ... }) -// -// import { MetaMask } from "../metamask"; -// import { PASSWORD } from "../constants"; declare global { namespace Cypress { interface Chainable { - importWallet(seedPhrase: string): Chainable; - addNewAccount(accountName: string): Chainable; - importWalletFromPrivateKey(privateKey: string): Chainable; - openSettings(): Chainable; + importWallet(seedPhrase: string): Chainable + addNewAccount(): Chainable + getAllAccounts(): Chainable } } } -Cypress.Commands.add("importWallet", (seedPhrase) => - cy.task("importWallet", seedPhrase) -); -Cypress.Commands.add("addNewAccount", (accountName) => - cy.task("addNewAccount", accountName) -); -Cypress.Commands.add("importWalletFromPrivateKey", (privateKey) => - cy.task("importWalletFromPrivateKey", privateKey) -); -Cypress.Commands.add("openSettings", () => cy.task("openSettings")); +Cypress.Commands.add('importWallet', (seedPhrase) => cy.task('importWallet', seedPhrase)) +Cypress.Commands.add('addNewAccount', () => cy.task('addNewAccount')) +Cypress.Commands.add('getAllAccounts', () => cy.task('getAllAccounts')) diff --git a/wallets/ethereum-wallet-mock/src/fixtures/ethereumWalletMockFixtures.ts b/wallets/ethereum-wallet-mock/src/fixtures/ethereumWalletMockFixtures.ts index c69e9ca6..bb2b5385 100644 --- a/wallets/ethereum-wallet-mock/src/fixtures/ethereumWalletMockFixtures.ts +++ b/wallets/ethereum-wallet-mock/src/fixtures/ethereumWalletMockFixtures.ts @@ -1,16 +1,11 @@ import { readFileSync } from 'fs' -import { createRequire } from 'node:module' import { test as base } from '@playwright/test' import { EthereumWalletMock } from '../EthereumWalletMock' -import { SEED_PHRASE, mockEthereum } from '../utils' +import { SEED_PHRASE, mockEthereum, web3MockPath } from '../utils' export const ANVIL_CHAIN_ID = 31337 export const ANVIL_URL_URL = 'http://anvil:5000' -const require = createRequire(import.meta.url) -// Relative path to the web3-mock bundle -const web3MockPath = require.resolve('@depay/web3-mock/dist/umd/index.bundle.js') - type EthereumWalletMockFixtures = { ethereumWalletMock: EthereumWalletMock } diff --git a/wallets/ethereum-wallet-mock/src/utils/constants.ts b/wallets/ethereum-wallet-mock/src/utils/constants.ts index 9dfc79a8..8ec553d4 100644 --- a/wallets/ethereum-wallet-mock/src/utils/constants.ts +++ b/wallets/ethereum-wallet-mock/src/utils/constants.ts @@ -1,3 +1,6 @@ +import { createRequire } from 'node:module' +const require = createRequire(import.meta.url) + export const BLOCKCHAIN = 'ethereum' export const ACCOUNT_MOCK = '0xd73b04b0e696b0945283defa3eee453814758f1a' @@ -7,3 +10,6 @@ export const SEED_PHRASE = 'test test test test test test test test test test te export const PRIVATE_KEY = 'ea084c575a01e2bbefcca3db101eaeab1d8af15554640a510c73692db24d0a6a' export const OPTIMISM_NETWORK_ID = '0xa' + +// Relative path to the web3-mock bundle +export const web3MockPath = require.resolve('@depay/web3-mock/dist/umd/index.bundle.js') diff --git a/wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts b/wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts index 89252d8b..8938da0a 100644 --- a/wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts +++ b/wallets/ethereum-wallet-mock/test/cypress/metamask/setupMetaMask.cy.ts @@ -1,11 +1,7 @@ -it("should add new MetaMask account", () => { - cy.addNewAccount("Synpress with Cypress test"); +it('should add new MetaMask account', () => { + cy.getAllAccounts().should('have.length', 1) - cy.wait(10000); -}); + cy.addNewAccount() -it("should open MetaMask settings", () => { - cy.openSettings(); - - cy.wait(10000); -}); + cy.getAllAccounts().should('have.length', 2) +}) diff --git a/wallets/ethereum-wallet-mock/tsconfig.json b/wallets/ethereum-wallet-mock/tsconfig.json index d33f5ffe..91c6d73b 100644 --- a/wallets/ethereum-wallet-mock/tsconfig.json +++ b/wallets/ethereum-wallet-mock/tsconfig.json @@ -4,7 +4,8 @@ "compilerOptions": { "rootDir": ".", "exactOptionalPropertyTypes": false, // Allows for `undefined` in `playwright.config.ts` - "types": ["cypress"] + "types": ["cypress"], + "sourceMap": false }, "include": ["src", "test"], "files": ["environment.d.ts", "playwright.config.ts", "vitest.config.ts"] diff --git a/wallets/metamask/package.json b/wallets/metamask/package.json index 5e73532b..d9b2eed9 100644 --- a/wallets/metamask/package.json +++ b/wallets/metamask/package.json @@ -41,7 +41,6 @@ "@types/fs-extra": "11.0.4", "@types/node": "20.11.17", "@vitest/coverage-v8": "1.2.2", - "cypress": "13.9.0", "rimraf": "5.0.5", "tsup": "8.0.2", "typescript": "5.3.3", diff --git a/wallets/metamask/src/cypress/errors.ts b/wallets/metamask/src/cypress/errors.ts deleted file mode 100644 index 105c9eef..00000000 --- a/wallets/metamask/src/cypress/errors.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const NO_CONTEXT = - "No browser context found. Connect Playwright first - connectPlaywright()"; -export const NO_METAMASK_PAGE = "No MetaMask page found. Use getMetaMaskPage()"; -export const MISSING_INIT = "MetaMask not initialized. Use initMetaMask()"; diff --git a/wallets/metamask/src/cypress/index.ts b/wallets/metamask/src/cypress/index.ts deleted file mode 100644 index 3e141ea7..00000000 --- a/wallets/metamask/src/cypress/index.ts +++ /dev/null @@ -1 +0,0 @@ -export { default as installSynpress } from "./installSynpress" diff --git a/wallets/metamask/src/cypress/initMetaMask.ts b/wallets/metamask/src/cypress/initMetaMask.ts deleted file mode 100644 index df753514..00000000 --- a/wallets/metamask/src/cypress/initMetaMask.ts +++ /dev/null @@ -1,80 +0,0 @@ -import { type BrowserContext, type Page, chromium } from '@playwright/test' -import { MISSING_INIT, NO_CONTEXT, NO_METAMASK_PAGE } from './errors' -import { getExtensionId } from '../fixture-actions' -import { MetaMask } from '../MetaMask' -import { PASSWORD, SEED_PHRASE } from '../../test/wallet-setup/basic.setup' - -let context: BrowserContext | undefined -let extensionId: string | undefined -let metamaskPage: Page | undefined -let metamask: MetaMask | undefined - -export async function getMetaMaskExtensionId() { - if (extensionId) return extensionId - - if (!context) { - console.error(NO_CONTEXT) - return - } - - extensionId = await getExtensionId(context, 'MetaMask') - return extensionId -} - -const isMetaMaskPage = (page: Page) => page.url().includes(`chrome-extension://${extensionId}`) - -const getMetaMaskPage = async () => { - await getMetaMaskExtensionId() - - if (!context) { - console.error(NO_CONTEXT) - return - } - - metamaskPage = context.pages().find(isMetaMaskPage) - return metamaskPage -} - -export async function connectPlaywrightToChrome(port: number) { - const debuggerDetails = await fetch(`http://127.0.0.1:${port}/json/version`) - - const debuggerDetailsConfig = (await debuggerDetails.json()) as { - webSocketDebuggerUrl: string - } - - const browser = await chromium.connectOverCDP(debuggerDetailsConfig.webSocketDebuggerUrl) - - context = browser.contexts()[0] - - return browser.isConnected() -} - -export async function initMetaMask(port: number) { - await connectPlaywrightToChrome(port) - - if (!context) { - console.error(NO_CONTEXT) - return - } - - await getMetaMaskPage() - - if (!metamaskPage) { - console.error(NO_METAMASK_PAGE) - return - } - - metamask = new MetaMask(context, metamaskPage, PASSWORD) - await metamask.importWallet(SEED_PHRASE) -} - -export function getMetaMask() { - if (!context || !metamaskPage || !metamask) { - console.error(MISSING_INIT) - return - } - - if (metamask) return metamask - - return new MetaMask(context, metamaskPage, PASSWORD) -} diff --git a/wallets/metamask/src/cypress/installSynpress.ts b/wallets/metamask/src/cypress/installSynpress.ts deleted file mode 100644 index 2e921f8d..00000000 --- a/wallets/metamask/src/cypress/installSynpress.ts +++ /dev/null @@ -1,52 +0,0 @@ -import { prepareExtension } from '../fixture-actions' -import { initMetaMask } from './initMetaMask' -import setupTasks from './setupTasks' - -let port = 0 - -function ensureRdpPort(args: string[]) { - const existing = args.find((arg) => arg.slice(0, 23) === '--remote-debugging-port') - - if (existing) { - return Number(existing.split('=')[1]) - } - - const port = 40000 + Math.round(Math.random() * 25000) - - args.push(`--remote-debugging-port=${port}`) - - return port -} - -export default function installSynpress(on: Cypress.PluginEvents, config: Cypress.PluginConfigOptions) { - const browsers = config.browsers.filter((b) => b.name === 'chrome') - if (browsers.length === 0) { - throw new Error('No Chrome browser found in the configuration') - } - - on('before:browser:launch', async (_, launchOptions) => { - // Enable debug mode to establish playwright connection - const args = Array.isArray(launchOptions) ? launchOptions : launchOptions.args - port = ensureRdpPort(args) - - // Preserved cache is not supported for Cypress - https://docs.cypress.io/guides/guides/launching-browsers#Cypress-Profile - // launchOptions.args.push('--user-data-dir=X') - - // Add MetaMask extension - const metamaskExtensionPath = await prepareExtension() - launchOptions.extensions.push(metamaskExtensionPath) - - return launchOptions - }) - - on('before:spec', async () => { - await initMetaMask(port) - }) - - setupTasks(on) - - return { - ...config, - browsers - } -} diff --git a/wallets/metamask/src/cypress/setupTasks.ts b/wallets/metamask/src/cypress/setupTasks.ts deleted file mode 100644 index 2595e007..00000000 --- a/wallets/metamask/src/cypress/setupTasks.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { getMetaMask } from './initMetaMask'; - -export default function setupTasks(on: Cypress.PluginEvents) { - on("task", { - importWallet: async function (seedPhrase: string) { - const metamask = getMetaMask(); - if (metamask) { - await metamask.importWallet(seedPhrase); - } - return true; - }, - addNewAccount: async function (accountName: string) { - const metamask = getMetaMask(); - if (metamask) { - await metamask.addNewAccount(accountName); - } - return true; - }, - importWalletFromPrivateKey: async function (privateKey: string) { - const metamask = getMetaMask(); - if (metamask) { - await metamask.importWalletFromPrivateKey(privateKey); - } - return true; - }, - openSettings: async function () { - const metamask = getMetaMask(); - if (metamask) { - await metamask.openSettings(); - } - return true; - }, - }); -} diff --git a/wallets/metamask/test/wallet-setup/basic.setup.d.ts b/wallets/metamask/test/wallet-setup/basic.setup.d.ts new file mode 100644 index 00000000..97d7a02c --- /dev/null +++ b/wallets/metamask/test/wallet-setup/basic.setup.d.ts @@ -0,0 +1,9 @@ +export declare const SEED_PHRASE = "test test test test test test test test test test test junk"; +export declare const PASSWORD = "Tester@1234"; +declare const _default: { + hash: string; + fn: import("@synthetixio/synpress-cache").WalletSetupFunction; + walletPassword: string; +}; +export default _default; +//# sourceMappingURL=basic.setup.d.ts.map \ No newline at end of file diff --git a/wallets/metamask/test/wallet-setup/basic.setup.d.ts.map b/wallets/metamask/test/wallet-setup/basic.setup.d.ts.map new file mode 100644 index 00000000..d4aad874 --- /dev/null +++ b/wallets/metamask/test/wallet-setup/basic.setup.d.ts.map @@ -0,0 +1 @@ +{"version":3,"file":"basic.setup.d.ts","sourceRoot":"","sources":["basic.setup.ts"],"names":[],"mappings":"AAGA,eAAO,MAAM,WAAW,gEAAgE,CAAA;AAExF,eAAO,MAAM,QAAQ,gBAAgB,CAAA;;;;;;AAErC,wBAIE"} \ No newline at end of file From b4039a9a6c5c034ea9618e5aea1d8d0bc4c60029 Mon Sep 17 00:00:00 2001 From: matstyler Date: Thu, 23 May 2024 17:50:18 +0200 Subject: [PATCH 04/11] fix: dependencies --- pnpm-lock.yaml | 3 --- 1 file changed, 3 deletions(-) diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index 340b65d3..ade8d948 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -295,9 +295,6 @@ importers: '@vitest/coverage-v8': specifier: 1.2.2 version: 1.2.2(vitest@1.2.2) - cypress: - specifier: 13.9.0 - version: 13.9.0 rimraf: specifier: 5.0.5 version: 5.0.5 From 51811ed77394ff2a678b526a1de176199c49aa79 Mon Sep 17 00:00:00 2001 From: matstyler Date: Thu, 23 May 2024 18:26:31 +0200 Subject: [PATCH 05/11] fix: cleanup --- packages/core/src/cypress/ensureRdpPort.ts | 12 +++++------- packages/core/src/cypress/index.ts | 2 +- wallets/metamask/cypress.config.ts | 16 ---------------- .../metamask/test/wallet-setup/basic.setup.d.ts | 16 ++++++++-------- 4 files changed, 14 insertions(+), 32 deletions(-) delete mode 100644 wallets/metamask/cypress.config.ts diff --git a/packages/core/src/cypress/ensureRdpPort.ts b/packages/core/src/cypress/ensureRdpPort.ts index 51248770..bb7f0a6b 100644 --- a/packages/core/src/cypress/ensureRdpPort.ts +++ b/packages/core/src/cypress/ensureRdpPort.ts @@ -1,15 +1,13 @@ export default function ensureRdpPort(args: string[]) { - const existing = args.find( - (arg) => arg.slice(0, 23) === "--remote-debugging-port" - ); + const existing = args.find((arg) => arg.slice(0, 23) === '--remote-debugging-port') if (existing) { - return Number(existing.split("=")[1]); + return Number(existing.split('=')[1]) } - const port = 40000 + Math.round(Math.random() * 25000); + const port = 40000 + Math.round(Math.random() * 25000) - args.push(`--remote-debugging-port=${port}`); + args.push(`--remote-debugging-port=${port}`) - return port; + return port } diff --git a/packages/core/src/cypress/index.ts b/packages/core/src/cypress/index.ts index f88de010..3c8e8cf7 100644 --- a/packages/core/src/cypress/index.ts +++ b/packages/core/src/cypress/index.ts @@ -1 +1 @@ -export { default as ensureRdpPort } from "./ensureRdpPort" +export { default as ensureRdpPort } from './ensureRdpPort' diff --git a/wallets/metamask/cypress.config.ts b/wallets/metamask/cypress.config.ts deleted file mode 100644 index 22d8dd72..00000000 --- a/wallets/metamask/cypress.config.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { defineConfig } from "cypress"; -import { installSynpress } from './src/cypress'; - -export default defineConfig({ - chromeWebSecurity: false, - e2e: { - baseUrl: "http://localhost:9999", - supportFile: "src/cypress/support/e2e.{js,jsx,ts,tsx}", - specPattern: "test/**/*.cy.{js,jsx,ts,tsx}", - fixturesFolder: "src/cypress/fixtures", - testIsolation: false, - async setupNodeEvents(on, config) { - return installSynpress(on, config); - }, - }, -}); diff --git a/wallets/metamask/test/wallet-setup/basic.setup.d.ts b/wallets/metamask/test/wallet-setup/basic.setup.d.ts index 97d7a02c..1bc70ea7 100644 --- a/wallets/metamask/test/wallet-setup/basic.setup.d.ts +++ b/wallets/metamask/test/wallet-setup/basic.setup.d.ts @@ -1,9 +1,9 @@ -export declare const SEED_PHRASE = "test test test test test test test test test test test junk"; -export declare const PASSWORD = "Tester@1234"; +export declare const SEED_PHRASE = 'test test test test test test test test test test test junk' +export declare const PASSWORD = 'Tester@1234' declare const _default: { - hash: string; - fn: import("@synthetixio/synpress-cache").WalletSetupFunction; - walletPassword: string; -}; -export default _default; -//# sourceMappingURL=basic.setup.d.ts.map \ No newline at end of file + hash: string + fn: import('@synthetixio/synpress-cache').WalletSetupFunction + walletPassword: string +} +export default _default +//# sourceMappingURL=basic.setup.d.ts.map From 91ec0151c6aca1cb62ea59dc7d2faba478b751fc Mon Sep 17 00:00:00 2001 From: matstyler Date: Thu, 23 May 2024 18:31:48 +0200 Subject: [PATCH 06/11] fix: clean imports --- .../src/cypress/initEthereumWalletMock.ts | 5 +++-- wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts | 3 ++- 2 files changed, 5 insertions(+), 3 deletions(-) diff --git a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts index 8cf53fca..301c32a3 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts @@ -1,8 +1,9 @@ +import { readFileSync } from 'fs' import { type BrowserContext, chromium, type Page } from '@playwright/test' -import { MISSING_INIT, NO_CONTEXT, NO_PAGE } from './errors' + import { EthereumWalletMock } from '../EthereumWalletMock' import { mockEthereum, SEED_PHRASE, web3MockPath } from '../utils' -import { readFileSync } from 'fs' +import { MISSING_INIT, NO_CONTEXT, NO_PAGE } from './errors' let context: BrowserContext | undefined let cypressPage: Page | undefined diff --git a/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts b/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts index bb562138..71c6f884 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/installSynpress.ts @@ -1,6 +1,7 @@ +import { ensureRdpPort } from '@synthetixio/synpress-core' + import { initEthereumWalletMock } from './initEthereumWalletMock' import setupTasks from './setupTasks' -import { ensureRdpPort } from '@synthetixio/synpress-core' let port: number From a0aaa89d909977c57f0be6bb6b7dc8233271baba Mon Sep 17 00:00:00 2001 From: matstyler Date: Thu, 23 May 2024 18:33:42 +0200 Subject: [PATCH 07/11] fix: testing path --- wallets/ethereum-wallet-mock/playwright.config.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/wallets/ethereum-wallet-mock/playwright.config.ts b/wallets/ethereum-wallet-mock/playwright.config.ts index 60e97f30..a1c5c34e 100644 --- a/wallets/ethereum-wallet-mock/playwright.config.ts +++ b/wallets/ethereum-wallet-mock/playwright.config.ts @@ -5,7 +5,7 @@ import { defineConfig, devices } from '@playwright/test' */ export default defineConfig({ // Look for test files in the "test/e2e" directory, relative to this configuration file. - testDir: './test/e2e/playwright', + testDir: './test/playwright', // We're increasing the timeout to 60 seconds to allow all traces to be recorded. // Sometimes it threw an error saying that traces were not recorded in the 30 seconds timeout limit. From 1ce5226337ce2eb732bf7ae90b902c0a03667775 Mon Sep 17 00:00:00 2001 From: matstyler Date: Thu, 23 May 2024 18:35:47 +0200 Subject: [PATCH 08/11] fix --- .../src/cypress/initEthereumWalletMock.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts index 301c32a3..3eae9cb1 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts @@ -1,8 +1,8 @@ import { readFileSync } from 'fs' -import { type BrowserContext, chromium, type Page } from '@playwright/test' +import { type BrowserContext, type Page, chromium } from '@playwright/test' import { EthereumWalletMock } from '../EthereumWalletMock' -import { mockEthereum, SEED_PHRASE, web3MockPath } from '../utils' +import { SEED_PHRASE, mockEthereum, web3MockPath } from '../utils' import { MISSING_INIT, NO_CONTEXT, NO_PAGE } from './errors' let context: BrowserContext | undefined From 992a6a48e6b05ddabf8daa14109b0d592cef5d69 Mon Sep 17 00:00:00 2001 From: matstyler Date: Fri, 24 May 2024 16:09:20 +0200 Subject: [PATCH 09/11] :wrench: feat: EthereumWalletMock API covered by Cypress tasks --- .../src/cypress/support/commands.ts | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts index a2476a74..992070c3 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts @@ -9,15 +9,31 @@ // https://on.cypress.io/custom-commands // *********************************************** +import type { Network } from '../../network/Network'; +import type { WalletMock } from '../../EthereumWalletMock'; + declare global { namespace Cypress { interface Chainable { importWallet(seedPhrase: string): Chainable + importWalletFromPrivateKey(privateKey: `0x${string}`): Chainable addNewAccount(): Chainable - getAllAccounts(): Chainable + getAllAccounts(): Chainable> + switchAccount(accountAddress: string): Chainable + addNetwork(network: Network): Chainable + getAccountAddress(): Chainable<`0x${string}`> + switchNetwork(networkName: string): Chainable + connectToDapp(wallet?: WalletMock): Chainable } } } + Cypress.Commands.add('importWallet', (seedPhrase) => cy.task('importWallet', seedPhrase)) +Cypress.Commands.add('importWalletFromPrivateKey', (privateKey) => cy.task('importWalletFromPrivateKey', privateKey)) Cypress.Commands.add('addNewAccount', () => cy.task('addNewAccount')) Cypress.Commands.add('getAllAccounts', () => cy.task('getAllAccounts')) +Cypress.Commands.add('switchAccount', (accountAddress) => cy.task('switchAccount', accountAddress)) +Cypress.Commands.add('addNetwork', (network) => cy.task('addNetwork', network)) +Cypress.Commands.add('getAccountAddress', () => cy.task('getAccountAddress')) +Cypress.Commands.add('switchNetwork', (networkName) => cy.task('switchNetwork', networkName)) +Cypress.Commands.add('connectToDapp', (wallet) => cy.task('connectToDapp', wallet)) From eebc7cdf6b51559ae0c3674ef80a1431f1b09ca4 Mon Sep 17 00:00:00 2001 From: matstyler Date: Fri, 24 May 2024 16:11:34 +0200 Subject: [PATCH 10/11] fix: format --- wallets/ethereum-wallet-mock/src/cypress/support/commands.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts index 992070c3..88021a17 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/support/commands.ts @@ -9,8 +9,8 @@ // https://on.cypress.io/custom-commands // *********************************************** -import type { Network } from '../../network/Network'; -import type { WalletMock } from '../../EthereumWalletMock'; +import type { WalletMock } from '../../EthereumWalletMock' +import type { Network } from '../../network/Network' declare global { namespace Cypress { From 1d7035105ea1b6a208eb0a6364ebe83753dd349d Mon Sep 17 00:00:00 2001 From: matstyler Date: Sun, 26 May 2024 14:02:28 +0200 Subject: [PATCH 11/11] fix: format --- ...ould add new MetaMask account (failed).png | Bin 0 -> 39357 bytes .../src/EthereumWalletMock.ts | 17 ++++++- .../src/cypress/initEthereumWalletMock.ts | 2 +- .../src/cypress/setupTasks.ts | 38 +++++++++----- .../test/cypress/mock/mockEthereum.cy.ts | 48 ++++++++++++++++++ .../test/playwright/addNewAccount.spec.ts | 17 ------- .../importWalletFromPrivateKey.spec.ts | 12 ----- .../metamask/mock/mockEthereum.spec.ts | 42 --------------- .../test/playwright/switchAccount.spec.ts | 10 ---- .../test/playwright/switchNetwork.spec.ts | 34 ------------- 10 files changed, 89 insertions(+), 131 deletions(-) create mode 100644 wallets/ethereum-wallet-mock/cypress/screenshots/metamask/setupMetaMask.cy.ts/should add new MetaMask account (failed).png create mode 100644 wallets/ethereum-wallet-mock/test/cypress/mock/mockEthereum.cy.ts delete mode 100644 wallets/ethereum-wallet-mock/test/playwright/addNewAccount.spec.ts delete mode 100644 wallets/ethereum-wallet-mock/test/playwright/importWalletFromPrivateKey.spec.ts delete mode 100644 wallets/ethereum-wallet-mock/test/playwright/metamask/mock/mockEthereum.spec.ts delete mode 100644 wallets/ethereum-wallet-mock/test/playwright/switchAccount.spec.ts delete mode 100644 wallets/ethereum-wallet-mock/test/playwright/switchNetwork.spec.ts diff --git a/wallets/ethereum-wallet-mock/cypress/screenshots/metamask/setupMetaMask.cy.ts/should add new MetaMask account (failed).png b/wallets/ethereum-wallet-mock/cypress/screenshots/metamask/setupMetaMask.cy.ts/should add new MetaMask account (failed).png new file mode 100644 index 0000000000000000000000000000000000000000..ad858c0991e23031a95b4a4b6d80ef0df0d559ce GIT binary patch literal 39357 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%0A7sVJM_pz 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 Si{7!dbC--v&tnbjAN>#fI-bM; literal 0 HcmV?d00001 diff --git a/wallets/ethereum-wallet-mock/src/EthereumWalletMock.ts b/wallets/ethereum-wallet-mock/src/EthereumWalletMock.ts index 5e518c54..602c6e10 100644 --- a/wallets/ethereum-wallet-mock/src/EthereumWalletMock.ts +++ b/wallets/ethereum-wallet-mock/src/EthereumWalletMock.ts @@ -9,8 +9,9 @@ export class EthereumWalletMock { seedPhrase = '' wallet: WalletMock = 'metamask' - constructor(readonly page: Page) { + constructor(readonly page: Page, wallet: WalletMock = 'metamask') { this.page = page + this.wallet = wallet } /** @@ -21,14 +22,25 @@ export class EthereumWalletMock { importWallet(seedPhrase: string) { this.seedPhrase = seedPhrase + console.log(this.wallet) + return this.page.evaluate( ([blockchain, wallet, accounts]) => { + class WalletConnectStub {} + + let connector: WalletConnectStub | undefined + + if (wallet === 'walletconnect') { + connector = WalletConnectStub + } + return Web3Mock.mock({ blockchain, wallet, accounts: { return: accounts - } + }, + connector }) }, [BLOCKCHAIN, this.wallet, [ACCOUNT_MOCK]] @@ -178,6 +190,7 @@ export class EthereumWalletMock { */ async connectToDapp(wallet: WalletMock = 'metamask') { this.wallet = wallet + return this.page.evaluate( ([blockchain, accounts, wallet]) => { // Cannot pass custom class as an argument to `page.evaluate` diff --git a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts index 3eae9cb1..8fce2436 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/initEthereumWalletMock.ts @@ -61,7 +61,7 @@ export async function initEthereumWalletMock(port: number) { ethereumObjectLoaded = true } - ethereumWalletMock = new EthereumWalletMock(cypressPage) + ethereumWalletMock = new EthereumWalletMock(cypressPage, 'coinbase') await ethereumWalletMock.importWallet(SEED_PHRASE) } diff --git a/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts b/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts index 6a801b90..aed5ac9a 100644 --- a/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts +++ b/wallets/ethereum-wallet-mock/src/cypress/setupTasks.ts @@ -1,27 +1,39 @@ -import { getEthereumWalletMock } from './initEthereumWalletMock' +import { getEthereumWalletMock } from "./initEthereumWalletMock"; +import type { WalletMock } from "../EthereumWalletMock"; export default function setupTasks(on: Cypress.PluginEvents) { - on('task', { + on("task", { importWallet: async function (seedPhrase: string) { - const ethereumWalletMock = getEthereumWalletMock() + const ethereumWalletMock = getEthereumWalletMock(); if (ethereumWalletMock) { - await ethereumWalletMock.importWallet(seedPhrase) + await ethereumWalletMock.importWallet(seedPhrase); + return true; } - return true + return false; }, addNewAccount: async function () { - const ethereumWalletMock = getEthereumWalletMock() + const ethereumWalletMock = getEthereumWalletMock(); if (ethereumWalletMock) { - await ethereumWalletMock.addNewAccount() + await ethereumWalletMock.addNewAccount(); + return true; } - return true + return false; }, getAllAccounts: async function () { - const ethereumWalletMock = getEthereumWalletMock() + const ethereumWalletMock = getEthereumWalletMock(); if (ethereumWalletMock) { - return await ethereumWalletMock.getAllAccounts() + return await ethereumWalletMock.getAllAccounts(); } - return [] - } - }) + return []; + }, + connectToDapp: async function (walletName: WalletMock) { + const ethereumWalletMock = getEthereumWalletMock(); + + if (ethereumWalletMock) { + await ethereumWalletMock.connectToDapp(walletName); + return true; + } + return false; + }, + }); } diff --git a/wallets/ethereum-wallet-mock/test/cypress/mock/mockEthereum.cy.ts b/wallets/ethereum-wallet-mock/test/cypress/mock/mockEthereum.cy.ts new file mode 100644 index 00000000..e0dae3be --- /dev/null +++ b/wallets/ethereum-wallet-mock/test/cypress/mock/mockEthereum.cy.ts @@ -0,0 +1,48 @@ +// it("should be able to access ethereum API", () => { +// cy.window().then((window) => { +// expect(!!window.ethereum).to.be.true; +// }); +// }); +// +// it("should be connected to metamask by default", () => { +// cy.window().then((window) => { +// expect(window.ethereum.isMetaMask).to.be.true; +// }); +// }); +// +// it("should connect to ethereum", () => { +// cy.window().then((window) => { +// window.ethereum +// .request({ +// method: "eth_chainId", +// }) +// .then((currentChainId: string) => { +// expect(currentChainId).to.equal("0x1"); +// }); +// }); +// }); + +it("should be able to connect to every supported ethereum wallet", () => { + cy.window().then((window) => { + expect(window.ethereum.isMetaMask).to.be.true; + expect(!!window.ethereum.isCoinbaseWallet).to.be.false; + }); + + // cy.connectToDapp("coinbase"); + // cy.window().then((window) => { + // console.log(window.ethereum) + // expect(window.ethereum.isCoinbaseWallet).to.be.true; + // }); + + // cy.connectToDapp("walletconnect"); + cy.importWallet('test test test test test test test test test test test junk') + // cy.window().then((window) => { + // expect(window.ethereum.isWalletLink).to.be.true; + // }); + + cy.reload(); + + cy.getAllAccounts().then(console.log) + + cy.wait(1000000) +}); diff --git a/wallets/ethereum-wallet-mock/test/playwright/addNewAccount.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/addNewAccount.spec.ts deleted file mode 100644 index 9baf68fd..00000000 --- a/wallets/ethereum-wallet-mock/test/playwright/addNewAccount.spec.ts +++ /dev/null @@ -1,17 +0,0 @@ -import test from '../synpress' - -const { expect } = test - -test('should add a new account with specified name', async ({ ethereumWalletMock }) => { - // Imported wallet includes 1 account - expect(await ethereumWalletMock.getAllAccounts()).toHaveLength(1) - - await ethereumWalletMock.addNewAccount() - - expect(await ethereumWalletMock.getAllAccounts()).toHaveLength(2) - - await ethereumWalletMock.addNewAccount() - await ethereumWalletMock.addNewAccount() - - expect(await ethereumWalletMock.getAllAccounts()).toHaveLength(4) -}) diff --git a/wallets/ethereum-wallet-mock/test/playwright/importWalletFromPrivateKey.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/importWalletFromPrivateKey.spec.ts deleted file mode 100644 index 345c6b8a..00000000 --- a/wallets/ethereum-wallet-mock/test/playwright/importWalletFromPrivateKey.spec.ts +++ /dev/null @@ -1,12 +0,0 @@ -import test from '../synpress' - -const { expect } = test - -test('should import account using private key', async ({ page, ethereumWalletMock }) => { - await ethereumWalletMock.importWalletFromPrivateKey( - '0xea084c575a01e2bbefcca3db101eaeab1d8af15554640a510c73692db24d0a6a' - ) - - await page.locator('#getAccounts').click() - await expect(page.locator('#getAccountsResult')).toHaveText('0xa2ce797cA71d0EaE1be5a7EffD27Fd6C38126801') -}) diff --git a/wallets/ethereum-wallet-mock/test/playwright/metamask/mock/mockEthereum.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/metamask/mock/mockEthereum.spec.ts deleted file mode 100644 index 6b8ccf5e..00000000 --- a/wallets/ethereum-wallet-mock/test/playwright/metamask/mock/mockEthereum.spec.ts +++ /dev/null @@ -1,42 +0,0 @@ -import synpress from '../../../synpress' - -const test = synpress - -const { expect } = test - -test('should be able to access ethereum API', async ({ page }) => { - const ethereum = await page.evaluate(() => window.ethereum) - expect(ethereum).toBeTruthy() -}) - -test('should be connected to metamask by default', async ({ page }) => { - const ethereum = await page.evaluate(() => window.ethereum) - expect(ethereum.isMetaMask).toBe(true) -}) - -test('should connect to ethereum', async ({ page }) => { - const currentChainId = await page.evaluate(() => - window.ethereum.request({ - method: 'eth_chainId' - }) - ) - - expect(currentChainId).toEqual('0x1') -}) - -test('should be able to connect to every supported ethereum wallet', async ({ page, ethereumWalletMock }) => { - // Metamask - let ethereum = await page.evaluate(() => window.ethereum) - expect(ethereum.isMetaMask).toBe(true) - expect(ethereum.isCoinbaseWallet).toBe(undefined) - - // Coinbase wallet - await ethereumWalletMock.connectToDapp('coinbase') - ethereum = await page.evaluate(() => window.ethereum) - expect(ethereum.isCoinbaseWallet).toBe(true) - - // Walletconnect - await ethereumWalletMock.connectToDapp('walletconnect') - ethereum = await page.evaluate(() => window.ethereum) - expect(ethereum.isWalletLink).toBe(true) -}) diff --git a/wallets/ethereum-wallet-mock/test/playwright/switchAccount.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/switchAccount.spec.ts deleted file mode 100644 index d2472155..00000000 --- a/wallets/ethereum-wallet-mock/test/playwright/switchAccount.spec.ts +++ /dev/null @@ -1,10 +0,0 @@ -import test from '../synpress' - -const { expect } = test - -test('should switch account', async ({ page, ethereumWalletMock }) => { - await ethereumWalletMock.switchAccount('0x4444797cA71d0EaE1be5a7EffD27Fd6C38126801') - - await page.locator('#getAccounts').click() - await expect(page.locator('#getAccountsResult')).toHaveText('0x4444797cA71d0EaE1be5a7EffD27Fd6C38126801') -}) diff --git a/wallets/ethereum-wallet-mock/test/playwright/switchNetwork.spec.ts b/wallets/ethereum-wallet-mock/test/playwright/switchNetwork.spec.ts deleted file mode 100644 index 039fe2ae..00000000 --- a/wallets/ethereum-wallet-mock/test/playwright/switchNetwork.spec.ts +++ /dev/null @@ -1,34 +0,0 @@ -import { ANVIL_CHAIN_ID, ANVIL_URL_URL } from '../../src' - -import test from '../synpress' - -const { expect } = test - -function createAnvilNetwork() { - return { - name: 'Anvil', - rpcUrl: ANVIL_URL_URL, - chainId: ANVIL_CHAIN_ID, - blockExplorerUrl: 'https://etherscan.io/', - nativeCurrency: { - decimals: 18, - name: 'Anvil', - symbol: 'ETH' - } - } -} - -test('should switch network', async ({ ethereumWalletMock, page }) => { - const network = createAnvilNetwork() - - await ethereumWalletMock.addNetwork(network) - - await ethereumWalletMock.switchNetwork(network.name) - - const chainId = await page.evaluate(async () => { - return await window.ethereum.request({ method: 'eth_chainId' }) - }) - - // Mocked Optimism chain id due to https://github.com/DePayFi/web3-mock/issues/33 - expect(chainId).toBe('0xa') -})