From 7c077c3a815a5eaec5a7e1ab24429268274fe2ae Mon Sep 17 00:00:00 2001 From: Vynnyk Dmytro Date: Wed, 20 Dec 2023 20:24:01 +0200 Subject: [PATCH] Release/1.8.0 (#901) * added listener for window closing (#752) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix displaying amount in CSPR only for Casper (#753) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * UI changed based on a new design (#754) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fixed skeleton for NFT image and made small changes (#755) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * feature: add remembering scroll position in the NFT, Deploys and Tokens list (#759) * added remembering scroll position in the NFT list and removed background fetch for nft * added remembering scroll position in the NFT list and removed background fetch for nft * added remembering scroll position in the Deploys list, removed background fetch for deploys and made some improvements * small improvements * added remembering scroll position in the Casper token activity list and small improvements * added remembering scroll position in the ERC20 token activity list and small improvements * removed duplication and small fix * fixed infinity scroll for NFT * fixed infinity scroll for Deploys tab * fixed infinity scroll for Casper token activity * fixed infinity scroll for ERC20 token activity * unused infinite scroll hook removed * updated error handler for account deploys and NFT tokens request --------- Co-authored-by: ost-ptk * illustrations are updated (#762) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix: fix native transfer in Firefox (#763) * added a check for deploy hash before the extended deploys info request * updated manifest permission for Firefox * removed comment --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * added tooltip on hover hash (#764) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * Redesign list of NFTs (#766) * Redesign list of NFTs * Fix PR issues and add useAsyncEffect hook * Fix issue with audio loading state * Fix issue with deploy timestamp (#768) * Release 1.5.2 version (#777) * feature: add NFT token transfer (#769) * added UI for NFT token transfer flow and business logic draft * added nft transfer logic * added fix for deploy timestamp issue * removed unused packages * removed back button from success screen --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix issues with the layout of a deploy list (#772) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * build(deps): bump sqlite3 from 5.0.8 to 5.1.6 (#694) Bumps [sqlite3](https://github.com/TryGhost/node-sqlite3) from 5.0.8 to 5.1.6. - [Release notes](https://github.com/TryGhost/node-sqlite3/releases) - [Commits](https://github.com/TryGhost/node-sqlite3/compare/v5.0.8...v5.1.6) --- updated-dependencies: - dependency-name: sqlite3 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump json5 from 1.0.1 to 1.0.2 (#695) Bumps [json5](https://github.com/json5/json5) from 1.0.1 to 1.0.2. - [Release notes](https://github.com/json5/json5/releases) - [Changelog](https://github.com/json5/json5/blob/main/CHANGELOG.md) - [Commits](https://github.com/json5/json5/compare/v1.0.1...v1.0.2) --- updated-dependencies: - dependency-name: json5 dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump dns-packet from 5.3.1 to 5.6.0 (#696) Bumps [dns-packet](https://github.com/mafintosh/dns-packet) from 5.3.1 to 5.6.0. - [Changelog](https://github.com/mafintosh/dns-packet/blob/master/CHANGELOG.md) - [Commits](https://github.com/mafintosh/dns-packet/compare/v5.3.1...v5.6.0) --- updated-dependencies: - dependency-name: dns-packet dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump xml2js and web-ext (#697) Bumps [xml2js](https://github.com/Leonidas-from-XIV/node-xml2js) to 0.5.0 and updates ancestor dependency [web-ext](https://github.com/mozilla/web-ext). These dependencies need to be updated together. Updates `xml2js` from 0.4.23 to 0.5.0 - [Commits](https://github.com/Leonidas-from-XIV/node-xml2js/commits/0.5.0) Updates `web-ext` from 7.5.0 to 7.6.2 - [Release notes](https://github.com/mozilla/web-ext/releases) - [Commits](https://github.com/mozilla/web-ext/compare/7.5.0...7.6.2) --- updated-dependencies: - dependency-name: xml2js dependency-type: indirect - dependency-name: web-ext dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Dmytro Vynnyk * build(deps-dev): bump eslint-plugin-jsx-a11y from 6.6.1 to 6.7.1 (#703) Bumps [eslint-plugin-jsx-a11y](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y) from 6.6.1 to 6.7.1. - [Release notes](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/releases) - [Changelog](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/blob/main/CHANGELOG.md) - [Commits](https://github.com/jsx-eslint/eslint-plugin-jsx-a11y/compare/v6.6.1...v6.7.1) --- updated-dependencies: - dependency-name: eslint-plugin-jsx-a11y dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump fs-extra from 11.1.0 to 11.1.1 (#705) Bumps [fs-extra](https://github.com/jprichardson/node-fs-extra) from 11.1.0 to 11.1.1. - [Changelog](https://github.com/jprichardson/node-fs-extra/blob/master/CHANGELOG.md) - [Commits](https://github.com/jprichardson/node-fs-extra/compare/11.1.0...11.1.1) --- updated-dependencies: - dependency-name: fs-extra dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump i18next-conv from 13.1.0 to 14.0.0 (#706) Bumps [i18next-conv](https://github.com/i18next/i18next-gettext-converter) from 13.1.0 to 14.0.0. - [Release notes](https://github.com/i18next/i18next-gettext-converter/releases) - [Changelog](https://github.com/i18next/i18next-gettext-converter/blob/master/CHANGELOG.md) - [Commits](https://github.com/i18next/i18next-gettext-converter/compare/v13.1.0...v14.0.0) --- updated-dependencies: - dependency-name: i18next-conv dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps): bump word-wrap from 1.2.3 to 1.2.4 (#731) Bumps [word-wrap](https://github.com/jonschlinkert/word-wrap) from 1.2.3 to 1.2.4. - [Release notes](https://github.com/jonschlinkert/word-wrap/releases) - [Commits](https://github.com/jonschlinkert/word-wrap/compare/1.2.3...1.2.4) --- updated-dependencies: - dependency-name: word-wrap dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump apollo-server-core from 3.11.1 to 3.12.1 (#765) Bumps [apollo-server-core](https://github.com/apollographql/apollo-server/tree/HEAD/packages/apollo-server-core) from 3.11.1 to 3.12.1. - [Release notes](https://github.com/apollographql/apollo-server/releases) - [Commits](https://github.com/apollographql/apollo-server/commits/apollo-server-core@3.12.1/packages/apollo-server-core) --- updated-dependencies: - dependency-name: apollo-server-core dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump i18next from 21.10.0 to 23.5.1 (#773) Bumps [i18next](https://github.com/i18next/i18next) from 21.10.0 to 23.5.1. - [Release notes](https://github.com/i18next/i18next/releases) - [Changelog](https://github.com/i18next/i18next/blob/master/CHANGELOG.md) - [Commits](https://github.com/i18next/i18next/compare/v21.10.0...v23.5.1) --- updated-dependencies: - dependency-name: i18next dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * fix account status indicator (#775) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump eslint from 8.28.0 to 8.49.0 (#776) Bumps [eslint](https://github.com/eslint/eslint) from 8.28.0 to 8.49.0. - [Release notes](https://github.com/eslint/eslint/releases) - [Changelog](https://github.com/eslint/eslint/blob/main/CHANGELOG.md) - [Commits](https://github.com/eslint/eslint/compare/v8.28.0...v8.49.0) --- updated-dependencies: - dependency-name: eslint dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps): bump got and @redux-devtools/cli (#780) Bumps [got](https://github.com/sindresorhus/got) to 11.8.6 and updates ancestor dependency [@redux-devtools/cli](https://github.com/reduxjs/redux-devtools). These dependencies need to be updated together. Updates `got` from 9.6.0 to 11.8.6 - [Release notes](https://github.com/sindresorhus/got/releases) - [Commits](https://github.com/sindresorhus/got/compare/v9.6.0...v11.8.6) Updates `@redux-devtools/cli` from 1.0.7 to 3.0.1 - [Release notes](https://github.com/reduxjs/redux-devtools/releases) - [Commits](https://github.com/reduxjs/redux-devtools/compare/@redux-devtools/cli@1.0.7...v3.0.1) --- updated-dependencies: - dependency-name: got dependency-type: indirect - dependency-name: "@redux-devtools/cli" dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps): bump react-player from 2.12.0 to 2.13.0 (#785) Bumps [react-player](https://github.com/CookPete/react-player) from 2.12.0 to 2.13.0. - [Changelog](https://github.com/cookpete/react-player/blob/master/CHANGELOG.md) - [Commits](https://github.com/CookPete/react-player/compare/v2.12.0...v2.13.0) --- updated-dependencies: - dependency-name: react-player dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump prettier from 2.8.0 to 3.0.3 (#786) Bumps [prettier](https://github.com/prettier/prettier) from 2.8.0 to 3.0.3. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/2.8.0...3.0.3) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump redux from 4.2.0 to 4.2.1 (#787) Bumps [redux](https://github.com/reduxjs/redux) from 4.2.0 to 4.2.1. - [Release notes](https://github.com/reduxjs/redux/releases) - [Changelog](https://github.com/reduxjs/redux/blob/master/CHANGELOG.md) - [Commits](https://github.com/reduxjs/redux/compare/v4.2.0...v4.2.1) --- updated-dependencies: - dependency-name: redux dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump webpack-dev-server from 4.11.1 to 4.15.1 (#788) Bumps [webpack-dev-server](https://github.com/webpack/webpack-dev-server) from 4.11.1 to 4.15.1. - [Release notes](https://github.com/webpack/webpack-dev-server/releases) - [Changelog](https://github.com/webpack/webpack-dev-server/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-dev-server/compare/v4.11.1...v4.15.1) --- updated-dependencies: - dependency-name: webpack-dev-server dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @types/chrome from 0.0.203 to 0.0.246 (#791) Bumps [@types/chrome](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/chrome) from 0.0.203 to 0.0.246. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/chrome) --- updated-dependencies: - dependency-name: "@types/chrome" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * added message for not supporting reverse look-up modality (#783) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * added a placeholder for the contract logo (#784) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix: fix issue with prettier config (#792) * fixed issue with prettier config * fixed code style errors --------- Co-authored-by: ost-ptk * added new UI for erc-20 action displaying (#790) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump geckodriver from 3.2.0 to 4.2.1 (#793) Bumps [geckodriver](https://github.com/webdriverio-community/node-geckodriver) from 3.2.0 to 4.2.1. - [Release notes](https://github.com/webdriverio-community/node-geckodriver/releases) - [Changelog](https://github.com/webdriverio-community/node-geckodriver/blob/main/CHANGELOG.md) - [Commits](https://github.com/webdriverio-community/node-geckodriver/compare/v3.2.0...v4.2.1) --- updated-dependencies: - dependency-name: geckodriver dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump react-query from 3.39.2 to 3.39.3 (#794) Bumps [react-query](https://github.com/tannerlinsley/react-query) from 3.39.2 to 3.39.3. - [Release notes](https://github.com/tannerlinsley/react-query/releases) - [Commits](https://github.com/tannerlinsley/react-query/commits) --- updated-dependencies: - dependency-name: react-query dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps): bump react-router-dom from 6.4.4 to 6.16.0 (#795) Bumps [react-router-dom](https://github.com/remix-run/react-router/tree/HEAD/packages/react-router-dom) from 6.4.4 to 6.16.0. - [Release notes](https://github.com/remix-run/react-router/releases) - [Changelog](https://github.com/remix-run/react-router/blob/main/packages/react-router-dom/CHANGELOG.md) - [Commits](https://github.com/remix-run/react-router/commits/react-router-dom@6.16.0/packages/react-router-dom) --- updated-dependencies: - dependency-name: react-router-dom dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps): bump @scure/bip39 from 1.1.0 to 1.2.1 (#796) Bumps [@scure/bip39](https://github.com/paulmillr/scure-bip39) from 1.1.0 to 1.2.1. - [Release notes](https://github.com/paulmillr/scure-bip39/releases) - [Commits](https://github.com/paulmillr/scure-bip39/compare/1.1.0...1.2.1) --- updated-dependencies: - dependency-name: "@scure/bip39" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump electron from 25.8.0 to 25.8.1 (#798) Bumps [electron](https://github.com/electron/electron) from 25.8.0 to 25.8.1. - [Release notes](https://github.com/electron/electron/releases) - [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md) - [Commits](https://github.com/electron/electron/compare/v25.8.0...v25.8.1) --- updated-dependencies: - dependency-name: electron dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump lint-staged from 13.0.4 to 14.0.1 (#800) Bumps [lint-staged](https://github.com/okonet/lint-staged) from 13.0.4 to 14.0.1. - [Release notes](https://github.com/okonet/lint-staged/releases) - [Changelog](https://github.com/okonet/lint-staged/blob/master/CHANGELOG.md) - [Commits](https://github.com/okonet/lint-staged/compare/v13.0.4...v14.0.1) --- updated-dependencies: - dependency-name: lint-staged dependency-type: direct:development update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump tsconfig-paths-webpack-plugin from 4.0.0 to 4.1.0 (#801) Bumps [tsconfig-paths-webpack-plugin](https://github.com/dividab/tsconfig-paths-webpack-plugin) from 4.0.0 to 4.1.0. - [Changelog](https://github.com/dividab/tsconfig-paths-webpack-plugin/blob/master/CHANGELOG.md) - [Commits](https://github.com/dividab/tsconfig-paths-webpack-plugin/compare/v4.0.0...v4.1.0) --- updated-dependencies: - dependency-name: tsconfig-paths-webpack-plugin dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump @types/facepaint from 1.2.2 to 1.2.3 (#803) Bumps [@types/facepaint](https://github.com/DefinitelyTyped/DefinitelyTyped/tree/HEAD/types/facepaint) from 1.2.2 to 1.2.3. - [Release notes](https://github.com/DefinitelyTyped/DefinitelyTyped/releases) - [Commits](https://github.com/DefinitelyTyped/DefinitelyTyped/commits/HEAD/types/facepaint) --- updated-dependencies: - dependency-name: "@types/facepaint" dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump webpack-cli from 5.0.0 to 5.1.4 (#804) Bumps [webpack-cli](https://github.com/webpack/webpack-cli) from 5.0.0 to 5.1.4. - [Release notes](https://github.com/webpack/webpack-cli/releases) - [Changelog](https://github.com/webpack/webpack-cli/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack/webpack-cli/compare/webpack-cli@5.0.0...webpack-cli@5.1.4) --- updated-dependencies: - dependency-name: webpack-cli dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * removed input type from the transaction fee fields (#807) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * changed method of creating Keys for signing (#808) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix: fix scope of bugs (#809) * fixed issue with transfer NFT error after wallet unlocking and some improvements * fixed issue with empty NFT details page after wallet unlocking and some improvements * fixed issue with home screen scroll * possible fix for an issue with a gap above the sticky tabs container * fixed an issue with the scrollable Import account screen --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fixed issue with the navigation menu screen scroll (#818) Co-authored-by: ost-ptk * casper logo updated (#817) Co-authored-by: ost-ptk * removed the tooltip with the full public key when the user has only one account (#819) Co-authored-by: ost-ptk * build(deps-dev): bump electron from 25.8.1 to 25.9.0 (#822) Bumps [electron](https://github.com/electron/electron) from 25.8.1 to 25.9.0. - [Release notes](https://github.com/electron/electron/releases) - [Changelog](https://github.com/electron/electron/blob/main/docs/breaking-changes.md) - [Commits](https://github.com/electron/electron/compare/v25.8.1...v25.9.0) --- updated-dependencies: - dependency-name: electron dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * disabled send button on NFT details page after this NFT was sent (#824) Co-authored-by: ost-ptk * fixed issue with the scroll on home page (#825) Co-authored-by: ost-ptk * Release 1.6.0 version (#826) * added countdown for user password length (#806) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * feature: add change password page (#799) * fixed issue with prettier config * fixed code style errors * added change password page and small refactor * merge conflict fixed * merge conflict issues fixed --------- Co-authored-by: ost-ptk * added a checkbox for setting the max transfer amount for CSPR transfer and some refactoring (#805) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fixed issue with words highlighting in the confirm secret phrase view (#823) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * feature: add dark mode (#821) * added dark mode * merge conflict issues fixed * changed png images to svg * Fix DefaultTheme interface --------- Co-authored-by: ost-ptk Co-authored-by: Dmytro Vynnyk * build(deps): bump @scure/bip32 from 1.1.1 to 1.3.2 (#812) Bumps [@scure/bip32](https://github.com/paulmillr/scure-bip32) from 1.1.1 to 1.3.2. - [Release notes](https://github.com/paulmillr/scure-bip32/releases) - [Commits](https://github.com/paulmillr/scure-bip32/compare/1.1.1...1.3.2) --- updated-dependencies: - dependency-name: "@scure/bip32" dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump webpack from 5.76.0 to 5.88.2 (#813) Bumps [webpack](https://github.com/webpack/webpack) from 5.76.0 to 5.88.2. - [Release notes](https://github.com/webpack/webpack/releases) - [Commits](https://github.com/webpack/webpack/compare/v5.76.0...v5.88.2) --- updated-dependencies: - dependency-name: webpack dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump eslint-plugin-react from 7.31.11 to 7.33.2 (#814) Bumps [eslint-plugin-react](https://github.com/jsx-eslint/eslint-plugin-react) from 7.31.11 to 7.33.2. - [Release notes](https://github.com/jsx-eslint/eslint-plugin-react/releases) - [Changelog](https://github.com/jsx-eslint/eslint-plugin-react/blob/master/CHANGELOG.md) - [Commits](https://github.com/jsx-eslint/eslint-plugin-react/compare/v7.31.11...v7.33.2) --- updated-dependencies: - dependency-name: eslint-plugin-react dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @babel/preset-env from 7.20.2 to 7.23.2 (#828) Bumps [@babel/preset-env](https://github.com/babel/babel/tree/HEAD/packages/babel-preset-env) from 7.20.2 to 7.23.2. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.2/packages/babel-preset-env) --- updated-dependencies: - dependency-name: "@babel/preset-env" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Improve skeleton for dark mode (#835) * Release 1.6.1 version (#837) * fixed issue with insufficient data for displaying erc-20 tokens (#840) Co-authored-by: ost-ptk * Update README.md to add reference to CSPR.click for integration (#842) * Improve erc20 tokens fetching (#843) * Release/1.6.2 (#844) * Improve erc20 tokens fetching * Release 1.6.2 version * feature: add QR code option to the settings menu (#774) * added QR code option to the settings menu * added QR generation page and removed unused props * merge conflict issue fixed * temp commit * Get symbol and decimal optional * Add qr code generation for sync wallet * UI and UX fixes, and fixed validation rule * moved qr generation under password protection and removed one time password * Improve qrCode generation * Add multi qr code presenting --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * Release 1.6.3 version (#852) * build(deps-dev): bump ts-jest from 29.0.3 to 29.1.1 (#831) Bumps [ts-jest](https://github.com/kulshekhar/ts-jest) from 29.0.3 to 29.1.1. - [Release notes](https://github.com/kulshekhar/ts-jest/releases) - [Changelog](https://github.com/kulshekhar/ts-jest/blob/main/CHANGELOG.md) - [Commits](https://github.com/kulshekhar/ts-jest/compare/v29.0.3...v29.1.1) --- updated-dependencies: - dependency-name: ts-jest dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump redux-saga from 1.2.1 to 1.2.3 (#832) Bumps [redux-saga](https://github.com/redux-saga/redux-saga) from 1.2.1 to 1.2.3. - [Release notes](https://github.com/redux-saga/redux-saga/releases) - [Changelog](https://github.com/redux-saga/redux-saga/blob/main/CHANGELOG.md) - [Commits](https://github.com/redux-saga/redux-saga/compare/redux-saga@1.2.1...redux-saga@1.2.3) --- updated-dependencies: - dependency-name: redux-saga dependency-type: direct:production update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump css-loader from 6.7.2 to 6.8.1 (#833) Bumps [css-loader](https://github.com/webpack-contrib/css-loader) from 6.7.2 to 6.8.1. - [Release notes](https://github.com/webpack-contrib/css-loader/releases) - [Changelog](https://github.com/webpack-contrib/css-loader/blob/master/CHANGELOG.md) - [Commits](https://github.com/webpack-contrib/css-loader/compare/v6.7.2...v6.8.1) --- updated-dependencies: - dependency-name: css-loader dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * feature: add delegation and undelegation flow (#846) * added delegation and undelegation flow * fixed issue with sticky header in tabs * added a new modal window with buttons on the home page * added empty state UI for undelegation * fixed deploys tab and deploys details page for staking --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * added active address in top nav (#847) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fixed issue with an open modal window (#848) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump @babel/core from 7.20.5 to 7.23.3 (#850) Bumps [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) from 7.20.5 to 7.23.3. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.3/packages/babel-core) --- updated-dependencies: - dependency-name: "@babel/core" dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump @babel/traverse from 7.20.5 to 7.23.3 (#853) Bumps [@babel/traverse](https://github.com/babel/babel/tree/HEAD/packages/babel-traverse) from 7.20.5 to 7.23.3. - [Release notes](https://github.com/babel/babel/releases) - [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md) - [Commits](https://github.com/babel/babel/commits/v7.23.3/packages/babel-traverse) --- updated-dependencies: - dependency-name: "@babel/traverse" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump axios from 1.1.3 to 1.6.1 (#854) Bumps [axios](https://github.com/axios/axios) from 1.1.3 to 1.6.1. - [Release notes](https://github.com/axios/axios/releases) - [Changelog](https://github.com/axios/axios/blob/v1.x/CHANGELOG.md) - [Commits](https://github.com/axios/axios/compare/v1.1.3...v1.6.1) --- updated-dependencies: - dependency-name: axios dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps): bump i18next-http-backend from 1.4.5 to 2.4.1 (#856) Bumps [i18next-http-backend](https://github.com/i18next/i18next-http-backend) from 1.4.5 to 2.4.1. - [Changelog](https://github.com/i18next/i18next-http-backend/blob/master/CHANGELOG.md) - [Commits](https://github.com/i18next/i18next-http-backend/compare/v1.4.5...v2.4.1) --- updated-dependencies: - dependency-name: i18next-http-backend dependency-type: direct:production update-type: version-update:semver-major ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump chromedriver from 107.0.3 to 119.0.1 (#851) Bumps [chromedriver](https://github.com/giggio/node-chromedriver) from 107.0.3 to 119.0.1. - [Commits](https://github.com/giggio/node-chromedriver/compare/107.0.3...119.0.1) --- updated-dependencies: - dependency-name: chromedriver dependency-type: direct:development ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Release 1.7.0 version (#864) * feature: add e2e test with playwright (#849) * added new e2e framework and CI config * change test dir * removed test example * added onboarding tests and changed CI script * removed CI scripts for selenium tests * fixed CI script and removed unused function * removed unused import * CI config improvements * added onboarding tests for firefox * increase workers for CI tests * added docker container for CI tests * fixing flaky test and removed docker container form CI * added headless mode for tests * updated PR template and fixed whitespaces in the CI config file * clean up playwright config * added a few e2e tests for popup * added a few e2e tests for popup * added CI config for popup tests * updated CI config for popup tests * skipped all tests except import account * fixing import account test * fixing import account test * fixing import account test * fixing import account test * fixing import account test * fixing import account test * fixing import account test * fixing import account test * fixing tests on CI * use config context * testing * use config context * testing * testing * testing * added docker container to CI config * testing * testing * testing * testing * testing * testing * testing * testing * testing * testing * testing * testing * testing * testing * enabled connect account test * enabled all popup tests * removed Firefox test from CI * cleanup * added container to CI config for onboarding tests * cleanup * testing * added signature tests for popup * added a few new tests * fix import issue * fixed issues with truncated keys * fixed test issue * updated playwright config * removed old e2e config and unused packages * added a new test and minor fixes * minor fix --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * build(deps-dev): bump html-webpack-plugin from 5.5.0 to 5.5.3 (#858) Bumps [html-webpack-plugin](https://github.com/jantimon/html-webpack-plugin) from 5.5.0 to 5.5.3. - [Release notes](https://github.com/jantimon/html-webpack-plugin/releases) - [Changelog](https://github.com/jantimon/html-webpack-plugin/blob/main/CHANGELOG.md) - [Commits](https://github.com/jantimon/html-webpack-plugin/compare/v5.5.0...v5.5.3) --- updated-dependencies: - dependency-name: html-webpack-plugin dependency-type: direct:development update-type: version-update:semver-patch ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump prettier from 3.0.3 to 3.1.0 (#859) Bumps [prettier](https://github.com/prettier/prettier) from 3.0.3 to 3.1.0. - [Release notes](https://github.com/prettier/prettier/releases) - [Changelog](https://github.com/prettier/prettier/blob/main/CHANGELOG.md) - [Commits](https://github.com/prettier/prettier/compare/3.0.3...3.1.0) --- updated-dependencies: - dependency-name: prettier dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Vynnyk Dmytro * build(deps): bump react-loading-skeleton from 3.1.0 to 3.3.1 (#860) Bumps [react-loading-skeleton](https://github.com/dvtng/react-loading-skeleton) from 3.1.0 to 3.3.1. - [Release notes](https://github.com/dvtng/react-loading-skeleton/releases) - [Changelog](https://github.com/dvtng/react-loading-skeleton/blob/master/CHANGELOG.md) - [Commits](https://github.com/dvtng/react-loading-skeleton/compare/v3.1.0...v3.3.1) --- updated-dependencies: - dependency-name: react-loading-skeleton dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @adobe/css-tools from 4.0.1 to 4.3.1 (#865) Bumps [@adobe/css-tools](https://github.com/adobe/css-tools) from 4.0.1 to 4.3.1. - [Changelog](https://github.com/adobe/css-tools/blob/main/History.md) - [Commits](https://github.com/adobe/css-tools/commits) --- updated-dependencies: - dependency-name: "@adobe/css-tools" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * added error handling for transfer and stakes (#867) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix: fix wallet setup kick-off automatically in the Reset Wallet flow (#863) * fixed issue with auto launching onboarding after wallet reset * fixed prettier issues --------- Co-authored-by: ost-ptk * fix: fix truncated public key size (#868) * fixed issue with truncated public key size * fixed prettier issue --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix: fix the moon icon (#869) * updated the moon icon * updated the moon icon * fixed issue with same keys --------- Co-authored-by: ost-ptk * spacing between buttons was fixed (#870) Co-authored-by: ost-ptk * build(deps): bump react-hook-form from 7.40.0 to 7.48.2 (#871) Bumps [react-hook-form](https://github.com/react-hook-form/react-hook-form) from 7.40.0 to 7.48.2. - [Release notes](https://github.com/react-hook-form/react-hook-form/releases) - [Changelog](https://github.com/react-hook-form/react-hook-form/blob/master/CHANGELOG.md) - [Commits](https://github.com/react-hook-form/react-hook-form/compare/v7.40.0...v7.48.2) --- updated-dependencies: - dependency-name: react-hook-form dependency-type: direct:production update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump web-ext from 7.6.2 to 7.8.0 (#874) Bumps [web-ext](https://github.com/mozilla/web-ext) from 7.6.2 to 7.8.0. - [Release notes](https://github.com/mozilla/web-ext/releases) - [Commits](https://github.com/mozilla/web-ext/compare/7.6.2...7.8.0) --- updated-dependencies: - dependency-name: web-ext dependency-type: direct:development update-type: version-update:semver-minor ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * build(deps-dev): bump @adobe/css-tools from 4.3.1 to 4.3.2 (#875) Bumps [@adobe/css-tools](https://github.com/adobe/css-tools) from 4.3.1 to 4.3.2. - [Changelog](https://github.com/adobe/css-tools/blob/main/History.md) - [Commits](https://github.com/adobe/css-tools/commits) --- updated-dependencies: - dependency-name: "@adobe/css-tools" dependency-type: indirect ... Signed-off-by: dependabot[bot] Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> * Release/1.7.1 (#881) * removed the button from the footer and fixed indent * Release 1.7.1 version --------- Co-authored-by: ost-ptk * feature: add contact book to the wallet (#878) * added contact book to the wallet * added contact sort and fixed the issue with updating contact --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * showed user stake amount for validator on undelegate page (#879) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * added new UI for account switcher (#883) Co-authored-by: ost-ptk * updated header UI (#884) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * updated the theme switcher (#885) Co-authored-by: ost-ptk * feature: merge recent recipients with contacts list (#886) * added contact book to the wallet * added contact sort and fixed the issue with updating contact * merged recent recipient with contacts * list height fix --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix: fix issue with empty contact screen (#888) * fixed issue with not trimmed names for contacts * minor fix * minor code improvements --------- Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fix: fix contact list preserving after the wallet reset (#887) * added contact book to the wallet * added contact sort and fixed the issue with updating contact * merged recent recipient with contacts * list height fix * added reset actions for vault settings, contacts and recent recipient --------- Co-authored-by: ost-ptk * opening of the account import window has been updated (#889) Co-authored-by: ost-ptk Co-authored-by: Vynnyk Dmytro * fixed an issue with a scrolled-down window in Firefox (#892) Co-authored-by: ost-ptk * fixed validation issue in recipient dropdown input (#893) Co-authored-by: ost-ptk * updated UI for recipient dropdown input (#894) Co-authored-by: ost-ptk * removed the System option for Safari from the theme switcher (#895) Co-authored-by: ost-ptk * changed 'Contacts list' to 'Contacts' (#896) Co-authored-by: ost-ptk * removed the 'max delegator' rule for the validator field from the Undelegate flow (#897) Co-authored-by: ost-ptk * removed hover tooltip from the public key in the account switcher (#898) Co-authored-by: ost-ptk * feature: add unlock wallet animation (#640) * Added animations lib and lottie dependency Added new unlock animation in the unlock vault view * Changed animation layout * Fixed review comments * Updated unlock animation to the linked animation file. * Optimized build all script * Optimized layout * Optimized animation * fix merge conflict issues * fixed version in package lock * updated unlock animation * updated unlock e2e test --------- Co-authored-by: ost-ptk Co-authored-by: Ostap Piatkovskyi <44294945+ost-ptk@users.noreply.github.com> Co-authored-by: Dmytro Vynnyk * Release 1.8.0 version --------- Signed-off-by: dependabot[bot] Co-authored-by: Ostap Piatkovskyi <44294945+ost-ptk@users.noreply.github.com> Co-authored-by: ost-ptk Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com> Co-authored-by: Muhammet Kara Co-authored-by: Piotr Witek <739075+piotrwitek@users.noreply.github.com> --- .github/pull_request_template.md | 2 +- .github/workflows/e2e-onboarding-tests.yml | 65 +- .github/workflows/e2e-popup-tests.yml | 65 +- .gitignore | 4 + README.md | 13 +- constants.js | 14 +- docker-compose.arm.yml | 23 - docker-compose.yml | 23 - {e2e => e2e-tests}/account_secret_key.pem | 6 +- e2e-tests/constants.ts | 47 + e2e-tests/fixtures.ts | 271 ++ .../confirm-secret-phrase-flow.spec.ts | 65 + .../recover-secret-phrase-flow.spec.ts | 36 + e2e-tests/popup/common/wallet.spec.ts | 83 + .../connect-account/connect-account.spec.ts | 108 + .../create-account/create-account.spec.ts | 41 + .../disconnect-account.spec.ts | 71 + .../import-account-with-file.spec.ts | 63 + .../rename-account/rename-account.spec.ts | 36 + .../signature-request-scenarios.spec.ts | 217 ++ e2e/__fixtures.ts | 4 - e2e/app-routes.ts | 4 - e2e/constants.ts | 26 - e2e/crx3-public.pem | 4 - e2e/crx3.pem | 9 - ...tton-to-open-extension-window-and-focus.ts | 31 - e2e/tests/common/connect-account.ts | 57 - e2e/tests/common/create-account.ts | 16 - e2e/tests/common/create-password.ts | 12 - e2e/tests/common/index.ts | 7 - e2e/tests/common/lock-vault.ts | 7 - e2e/tests/common/open-connected-site-page.ts | 12 - e2e/tests/common/unlock-vault.ts | 8 - .../confirm-secret-phrase-flow.test.ts | 213 -- .../recover-secret-phrase-flow.test.ts | 64 - .../connect-account-flow.test.ts | 191 -- .../disconnect-account-flow.test.ts | 90 - .../import-account-with-file-flow.test.ts | 113 - .../signature-request-scenarios.test.ts | 154 - e2e/tsconfig.json | 14 - e2e/utils/helpers.ts | 14 - e2e/webdriver/WebElementWithAPI.ts | 41 - e2e/webdriver/chrome.ts | 99 - e2e/webdriver/constants.ts | 10 - e2e/webdriver/driver.ts | 446 --- e2e/webdriver/firefox.ts | 81 - e2e/webdriver/index.ts | 58 - e2e/webdriver/types.ts | 55 - package-lock.json | 2540 +++++++---------- package.json | 33 +- playwright.config.ts | 44 + src/apps/connect-to-app/index.tsx | 23 +- src/apps/import-account-with-file/index.tsx | 21 +- src/apps/popup/app-router.tsx | 21 +- src/apps/popup/index.tsx | 29 +- src/apps/popup/pages/add-contact/content.tsx | 59 + src/apps/popup/pages/add-contact/index.tsx | 121 + .../pages/add-contact/success-screen.tsx | 58 + .../pages/backup-secret-phrase/index.tsx | 6 +- .../pages/connect-another-account/index.tsx | 2 +- .../popup/pages/contact-details/deleting.tsx | 36 + .../popup/pages/contact-details/details.tsx | 50 + .../popup/pages/contact-details/editing.tsx | 61 + .../popup/pages/contact-details/index.tsx | 192 ++ src/apps/popup/pages/contacts/content.tsx | 58 + .../popup/pages/contacts/empty-contacts.tsx | 39 + src/apps/popup/pages/contacts/index.tsx | 47 + .../pages/download-secret-keys/index.tsx | 4 +- .../popup/pages/navigation-menu/index.tsx | 165 +- .../index.tsx | 8 +- src/apps/popup/pages/stakes/index.tsx | 21 +- src/apps/popup/pages/token-details/token.tsx | 8 +- src/apps/popup/pages/transfer-nft/content.tsx | 10 +- src/apps/popup/pages/transfer-nft/index.tsx | 71 +- .../popup/pages/transfer/confirm-step.tsx | 5 +- src/apps/popup/pages/transfer/content.tsx | 7 +- src/apps/popup/pages/transfer/index.tsx | 64 +- .../popup/pages/transfer/recipient-step.tsx | 12 +- src/apps/popup/pages/wallet-qr-code/index.tsx | 4 +- src/apps/popup/router/paths.ts | 5 +- src/apps/popup/router/types.ts | 6 +- src/apps/signature-request/index.tsx | 28 +- src/assets/icons/checkbox.svg | 3 - src/assets/icons/contact.svg | 3 + src/assets/icons/moon.svg | 4 +- ...kbox-inactive.svg => radio-button-off.svg} | 0 ...eckbox-checked.svg => radio-button-on.svg} | 0 src/assets/icons/sun.svg | 4 +- src/assets/icons/theme.svg | 3 + src/assets/icons/wallet-original-on-white.svg | 11 + src/assets/illustrations/empty-state.svg | 739 +++++ src/assets/illustrations/error.svg | 711 +++++ src/assets/illustrations/remove-wallet.svg | 920 ++++++ .../close-window-by-reload-extension.ts | 14 +- src/background/create-open-window.ts | 10 +- src/background/index.ts | 24 +- src/background/redux/contacts/actions.ts | 15 + src/background/redux/contacts/reducer.ts | 44 + src/background/redux/contacts/selectors.ts | 15 + src/background/redux/contacts/types.ts | 14 + .../recent-recipient-public-keys/actions.ts | 4 + .../recent-recipient-public-keys/reducer.ts | 14 +- src/background/redux/redux-action.ts | 4 +- src/background/redux/root-reducer.ts | 4 +- .../redux/sagas/onboarding-sagas.ts | 7 + src/background/redux/session/actions.ts | 4 + src/background/redux/session/reducer.ts | 14 +- src/background/redux/session/selectors.ts | 3 + src/background/redux/session/types.ts | 1 + src/background/redux/settings/actions.ts | 9 +- src/background/redux/settings/reducer.ts | 16 +- src/background/redux/settings/selectors.ts | 4 +- src/background/redux/settings/types.ts | 7 + src/background/redux/utils.ts | 22 +- src/fixtures/initial-state-for-popup-tests.ts | 124 +- src/hooks/index.ts | 1 + ...-deploys-list-with-pending-transactions.ts | 4 +- src/hooks/use-system-theme-detector/index.ts | 1 + .../use-system-theme-detector.ts | 21 + src/libs/animations/unlock_animation.json | 370 +++ src/libs/layout/containers.ts | 2 - .../header/header-connection-status.tsx | 2 +- src/libs/layout/header/index.tsx | 34 +- .../unlock-protected-page-content/index.tsx | 16 +- src/libs/layout/unlock-vault/index.tsx | 60 +- .../components/account-list/account-list.tsx | 58 +- src/libs/ui/components/avatar/avatar.tsx | 90 +- src/libs/ui/components/checkbox/checkbox.tsx | 4 +- .../connection-status-badge.tsx | 4 +- .../contacts-plate/contacts-plate.tsx | 41 + src/libs/ui/components/hash/utils.ts | 10 +- src/libs/ui/components/input/input.tsx | 4 +- src/libs/ui/components/modal/modal.tsx | 56 +- src/libs/ui/components/popover/popover.tsx | 1 + .../recipient-dropdown-input.tsx | 139 +- .../recipient-plate/recipient-plate.tsx | 83 +- .../copy-secret-phrase-bar.tsx | 2 +- .../secret-phrase-words-view/word-tag.tsx | 4 +- src/libs/ui/components/textarea/textarea.tsx | 10 +- .../theme-switcher/theme-switcher.tsx | 125 + .../transfer-succeess-screen.tsx | 29 +- .../validator-dropdown-input.tsx | 16 +- src/libs/ui/forms/contact.ts | 40 + src/libs/ui/forms/form-validation-rules.ts | 52 +- src/libs/ui/forms/stakes-form.ts | 2 +- src/libs/ui/forms/transfer.ts | 7 +- src/libs/ui/index.ts | 2 + src/libs/ui/utils/formatters.ts | 14 + src/utils.ts | 1 + webpack.config.js | 7 +- .../Casper Wallet.xcodeproj/project.pbxproj | 8 +- 151 files changed, 7046 insertions(+), 3996 deletions(-) delete mode 100644 docker-compose.arm.yml delete mode 100644 docker-compose.yml rename {e2e => e2e-tests}/account_secret_key.pem (97%) create mode 100644 e2e-tests/constants.ts create mode 100644 e2e-tests/fixtures.ts create mode 100644 e2e-tests/onboarding-flow/confirm-secret-phrase-flow.spec.ts create mode 100644 e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts create mode 100644 e2e-tests/popup/common/wallet.spec.ts create mode 100644 e2e-tests/popup/connect-account/connect-account.spec.ts create mode 100644 e2e-tests/popup/create-account/create-account.spec.ts create mode 100644 e2e-tests/popup/disconnect-account/disconnect-account.spec.ts create mode 100644 e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts create mode 100644 e2e-tests/popup/rename-account/rename-account.spec.ts create mode 100644 e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts delete mode 100644 e2e/__fixtures.ts delete mode 100644 e2e/app-routes.ts delete mode 100644 e2e/constants.ts delete mode 100644 e2e/crx3-public.pem delete mode 100644 e2e/crx3.pem delete mode 100644 e2e/tests/common/click-button-to-open-extension-window-and-focus.ts delete mode 100644 e2e/tests/common/connect-account.ts delete mode 100644 e2e/tests/common/create-account.ts delete mode 100644 e2e/tests/common/create-password.ts delete mode 100644 e2e/tests/common/index.ts delete mode 100644 e2e/tests/common/lock-vault.ts delete mode 100644 e2e/tests/common/open-connected-site-page.ts delete mode 100644 e2e/tests/common/unlock-vault.ts delete mode 100644 e2e/tests/onboarding-flow/confirm-secret-phrase-flow.test.ts delete mode 100644 e2e/tests/onboarding-flow/recover-secret-phrase-flow.test.ts delete mode 100644 e2e/tests/popup/connect-account/connect-account-flow.test.ts delete mode 100644 e2e/tests/popup/disconnect-account/disconnect-account-flow.test.ts delete mode 100644 e2e/tests/popup/import-account-with-file-flow/import-account-with-file-flow.test.ts delete mode 100644 e2e/tests/popup/signature-request-scenarios/signature-request-scenarios.test.ts delete mode 100644 e2e/tsconfig.json delete mode 100644 e2e/utils/helpers.ts delete mode 100644 e2e/webdriver/WebElementWithAPI.ts delete mode 100644 e2e/webdriver/chrome.ts delete mode 100644 e2e/webdriver/constants.ts delete mode 100644 e2e/webdriver/driver.ts delete mode 100644 e2e/webdriver/firefox.ts delete mode 100644 e2e/webdriver/index.ts delete mode 100644 e2e/webdriver/types.ts create mode 100644 playwright.config.ts create mode 100644 src/apps/popup/pages/add-contact/content.tsx create mode 100644 src/apps/popup/pages/add-contact/index.tsx create mode 100644 src/apps/popup/pages/add-contact/success-screen.tsx create mode 100644 src/apps/popup/pages/contact-details/deleting.tsx create mode 100644 src/apps/popup/pages/contact-details/details.tsx create mode 100644 src/apps/popup/pages/contact-details/editing.tsx create mode 100644 src/apps/popup/pages/contact-details/index.tsx create mode 100644 src/apps/popup/pages/contacts/content.tsx create mode 100644 src/apps/popup/pages/contacts/empty-contacts.tsx create mode 100644 src/apps/popup/pages/contacts/index.tsx rename src/apps/popup/pages/{backup-secret-phrase-password => password-protection-page}/index.tsx (91%) delete mode 100644 src/assets/icons/checkbox.svg create mode 100644 src/assets/icons/contact.svg rename src/assets/icons/{checkbox-inactive.svg => radio-button-off.svg} (100%) rename src/assets/icons/{checkbox-checked.svg => radio-button-on.svg} (100%) create mode 100644 src/assets/icons/theme.svg create mode 100644 src/assets/icons/wallet-original-on-white.svg create mode 100644 src/assets/illustrations/empty-state.svg create mode 100644 src/assets/illustrations/error.svg create mode 100644 src/assets/illustrations/remove-wallet.svg create mode 100644 src/background/redux/contacts/actions.ts create mode 100644 src/background/redux/contacts/reducer.ts create mode 100644 src/background/redux/contacts/selectors.ts create mode 100644 src/background/redux/contacts/types.ts create mode 100644 src/hooks/use-system-theme-detector/index.ts create mode 100644 src/hooks/use-system-theme-detector/use-system-theme-detector.ts create mode 100644 src/libs/animations/unlock_animation.json create mode 100644 src/libs/ui/components/contacts-plate/contacts-plate.tsx create mode 100644 src/libs/ui/components/theme-switcher/theme-switcher.tsx create mode 100644 src/libs/ui/forms/contact.ts diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md index 8b3ee598c..550c58db8 100644 --- a/.github/pull_request_template.md +++ b/.github/pull_request_template.md @@ -6,7 +6,7 @@ _**Make sure to fill in all the below sections.**_ ## Linked tickets -// Add a `#XXX` link to a related ticket +[WALLET-XXX](https://make-software.atlassian.net/browse/WALLET-XXX) ## Checklist diff --git a/.github/workflows/e2e-onboarding-tests.yml b/.github/workflows/e2e-onboarding-tests.yml index 798e35f0f..f81a8a7b2 100644 --- a/.github/workflows/e2e-onboarding-tests.yml +++ b/.github/workflows/e2e-onboarding-tests.yml @@ -8,51 +8,36 @@ on: jobs: e2e-onboarding-tests: + timeout-minutes: 60 runs-on: ubuntu-latest - container: - image: node:16 - - strategy: - fail-fast: false - matrix: -# Add Firefox after fixing CI errors - browser: [ 'chrome' ] - node-version: [ 16.x ] - - services: - selenium: - image: selenium/standalone-${{ matrix.browser }} + image: mcr.microsoft.com/playwright:v1.39.0-jammy steps: - uses: actions/checkout@v3 - - - name: Cache npm dependencies - id: cache-npm - uses: actions/cache@v3 - env: - cache-name: cache-node-modules - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + - uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - cache: 'npm' + node-version: 18 - name: Install dependencies - run: | - npm install - - - name: Run E2E onboarding tests on ${{ matrix.browser }} - run: npm run test:e2e:${{ matrix.browser }}:headless:onboarding - env: - SELENIUM_HOST: selenium - SELENIUM_PORT: 4444 + run: npm ci + + - name: Install Playwright Browsers + run: npx playwright install --with-deps + + - name: Run Chrome tests + run: npm run e2e:chrome:headless:onboarding + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 + + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: test-results + path: test-results/ + retention-days: 30 \ No newline at end of file diff --git a/.github/workflows/e2e-popup-tests.yml b/.github/workflows/e2e-popup-tests.yml index 1236ad3e1..dc55998c7 100644 --- a/.github/workflows/e2e-popup-tests.yml +++ b/.github/workflows/e2e-popup-tests.yml @@ -8,59 +8,36 @@ on: jobs: e2e-popup-tests: + timeout-minutes: 60 runs-on: ubuntu-latest - container: - image: node:16 - - strategy: - fail-fast: false - matrix: -# Add Firefox after fixing CI errors - browser: [ 'chrome' ] - node-version: [ 16.x ] - - services: - selenium: - image: selenium/standalone-${{ matrix.browser }} - options: --shm-size=2gb + image: mcr.microsoft.com/playwright:v1.39.0-jammy steps: - uses: actions/checkout@v3 - - - name: Cache npm dependencies - id: cache-npm - uses: actions/cache@v3 - env: - cache-name: cache-node-modules - with: - # npm cache files are stored in `~/.npm` on Linux/macOS - path: ~/.npm - key: ${{ runner.os }}-build-${{ env.cache-name }}-${{ hashFiles('**/package-lock.json') }} - restore-keys: | - ${{ runner.os }}-build-${{ env.cache-name }}- - ${{ runner.os }}-build- - ${{ runner.os }}- - - - name: Use Node.js ${{ matrix.node-version }} - uses: actions/setup-node@v3 + - uses: actions/setup-node@v3 with: - node-version: ${{ matrix.node-version }} - cache: 'npm' + node-version: 18 - name: Install dependencies - run: | - npm install + run: npm ci + + - name: Install Playwright Browsers + run: npx playwright install --with-deps + + - name: Run Chrome tests + run: npm run e2e:chrome:headless:popup - - name: Run E2E popup tests on ${{ matrix.browser }} - run: npm run test:e2e:${{ matrix.browser }}:headless:popup - env: - SELENIUM_HOST: selenium - SELENIUM_PORT: 4444 + - uses: actions/upload-artifact@v3 + if: failure() + with: + name: playwright-report + path: playwright-report/ + retention-days: 30 - - name: Add screenshot - uses: actions/upload-artifact@v3 + - uses: actions/upload-artifact@v3 if: failure() with: - name: ${{ matrix.browser }} - path: test-artifacts/ + name: test-results + path: test-results/ + retention-days: 30 \ No newline at end of file diff --git a/.gitignore b/.gitignore index 59f151052..20c6a544c 100644 --- a/.gitignore +++ b/.gitignore @@ -30,3 +30,7 @@ secrets.*.js # packed extension chrome.crx +/test-results/ +/playwright-report/ +/blob-report/ +/playwright/.cache/ diff --git a/README.md b/README.md index 6b58aa6aa..21a77923a 100755 --- a/README.md +++ b/README.md @@ -158,13 +158,10 @@ You should install Redux DevTools browser extension and connect it to Redux DevT ## E2E tests -Write tests into `e2e/tests` folder. +Write tests into `e2e-tests` folder. -There are a few options to run tests: +To run e2e tests, you must use npm script `npm run e2e:chrome:ui:popup` or `e2e:chrome:ui:onboarding`. +Tests are run in UI mode. -1. In docker container - - Run docker and up containers. `docker compose up` or `docker-compose -f docker-compose.arm.yml up` for Apple M processors - - Use npm scripts `npm run test:e2e:{chrome/firefox}:headless:{popup/onboarding}` depends on target browser and tests - - To see what is happening inside the container, open your web browser and navigate to the URL for Chrome and for Firefox, enter the password `secret`, and run your test again -2. Locally on computer - - Use npm scripts `npm run test:e2e:chrome` or `npm run test:e2e:firefox` depends on target browser +All information +about how to run and debug tests can be found in [playwright docs](https://playwright.dev/docs/running-tests). diff --git a/constants.js b/constants.js index e53534fb8..2d786135d 100644 --- a/constants.js +++ b/constants.js @@ -1,4 +1,3 @@ -const { Browser } = require('selenium-webdriver'); const { NODE_ENV, BROWSER: browserEnvVar } = require('./utils/env'); const extensionName = 'Casper Wallet'; @@ -7,9 +6,9 @@ const buildRootDir = ['test', 'production'].includes(NODE_ENV) : 'output'; const ExtensionBuildPath = { - Chrome: `${buildRootDir}/${Browser.CHROME}`, - Firefox: `${buildRootDir}/${Browser.FIREFOX}`, - Safari: `${buildRootDir}/${Browser.SAFARI}/${extensionName}` + Chrome: `${buildRootDir}/chrome`, + Firefox: `${buildRootDir}/firefox`, + Safari: `${buildRootDir}/safari/${extensionName}` }; const ManifestPath = { @@ -18,16 +17,15 @@ const ManifestPath = { v2_Safari: 'src/manifest.v2.safari.json' }; -const isSafari = browserEnvVar && browserEnvVar === Browser.SAFARI; -const isChrome = browserEnvVar && browserEnvVar === Browser.CHROME; -const isFirefox = browserEnvVar && browserEnvVar === Browser.FIREFOX; +const isSafari = browserEnvVar && browserEnvVar === 'safari'; +const isChrome = browserEnvVar && browserEnvVar === 'chrome'; +const isFirefox = browserEnvVar && browserEnvVar === 'firefox'; module.exports = { ExtensionBuildPath, extensionName, browserEnvVar, ManifestPath, - Browser, isFirefox, isSafari, isChrome diff --git a/docker-compose.arm.yml b/docker-compose.arm.yml deleted file mode 100644 index 57b11ba75..000000000 --- a/docker-compose.arm.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: '3' -services: - chrome: - image: seleniarm/standalone-chromium - container_name: seleniarm-chromium - ports: - - "4444:4444" # Selenium service - - "5900:5900" # VNC server - - "7900:7900" # VNC browser client - firefox: - image: seleniarm/standalone-firefox - container_name: seleniarm-firefox - ports: - - "4445:4444" # Selenium service - - "5901:5900" # VNC server - - "7901:7900" # VNC browser client - node: - image: node:16 - container_name: node-16 - volumes: - - ./../:/project - working_dir: /project - tty: true \ No newline at end of file diff --git a/docker-compose.yml b/docker-compose.yml deleted file mode 100644 index 989beba34..000000000 --- a/docker-compose.yml +++ /dev/null @@ -1,23 +0,0 @@ -version: '3' -services: - chrome: - image: selenium/standalone-chrome - container_name: selenium-chrome - ports: - - "4444:4444" # Selenium service - - "5900:5900" # VNC server - - "7900:7900" # VNC browser client - firefox: - image: selenium/standalone-firefox - container_name: selenium-firefox - ports: - - "4445:4444" # Selenium service - - "5901:5900" # VNC server - - "7901:7900" # VNC browser client - node: - image: node:16 - container_name: node-16 - volumes: - - ./../:/project - working_dir: /project - tty: true \ No newline at end of file diff --git a/e2e/account_secret_key.pem b/e2e-tests/account_secret_key.pem similarity index 97% rename from e2e/account_secret_key.pem rename to e2e-tests/account_secret_key.pem index 4d7430a0a..4321f940d 100644 --- a/e2e/account_secret_key.pem +++ b/e2e-tests/account_secret_key.pem @@ -1,3 +1,3 @@ ------BEGIN PRIVATE KEY----- -MC4CAQAwBQYDK2VwBCIEIHRZr1HEgKVbgchuatwA7dCWDWB7QZe+bpDb5dguIyLE ------END PRIVATE KEY----- +-----BEGIN PRIVATE KEY----- +MC4CAQAwBQYDK2VwBCIEIHRZr1HEgKVbgchuatwA7dCWDWB7QZe+bpDb5dguIyLE +-----END PRIVATE KEY----- diff --git a/e2e-tests/constants.ts b/e2e-tests/constants.ts new file mode 100644 index 000000000..a31e3dca8 --- /dev/null +++ b/e2e-tests/constants.ts @@ -0,0 +1,47 @@ +import path from 'path'; + +export const vaultPassword = '3hQqzYn4C7Y8rEZTVEZb'; +export const recoverSecretPhrase = + 'hold matrix spider subway bottom jazz charge fire lawn valley stay coil moral hospital dream cycle multiply december agree huge major tower devote old'; +export const secretKeyPath = path.join(__dirname, './account_secret_key.pem'); + +export const ACCOUNT_NAMES = { + defaultFirstAccountName: 'Account 1', + defaultSecondAccountName: 'Account 2', + createdAccountName: 'New account 1', + importedAccountName: 'Imported account', + renamedAccountName: 'Renamed account' +}; + +export const PLAYGROUND_URL = 'https://casper-wallet-playground.make.services/'; + +export const IMPORTED_ACCOUNT = { + accountName: ACCOUNT_NAMES.importedAccountName, + publicKey: + '0184f6d260f4ee6869ddb36affe15456de6ae045278fa2f467bb677561ce0dad55', + truncatedPublicKey: '0184f...dad55' +}; + +export const DEFAULT_FIRST_ACCOUNT = { + accountName: ACCOUNT_NAMES.defaultFirstAccountName, + publicKey: + '0202b1943511b8c23b1b2b8ed7ddcedffcc7be70d9366a5005c7beab08a81b7ae633', + truncatedPublicKey: '0202b...ae633' +}; + +export const DEFAULT_SECOND_ACCOUNT = { + accountName: ACCOUNT_NAMES.defaultSecondAccountName, + publicKey: + '0203b2e05f074452f5e69ba512310deceaca152ebd3394eadcec26c6e68e91aa7724', + truncatedPublicKey: '0203b...a7724' +}; + +export const VALIDATOR = { + name: 'Validator', + truncatedPublicKey: '0106c...ca2ca' +}; + +export const NEW_VALIDATOR = { + name: 'New validator', + truncatedPublicKey: '017d9...2009e' +}; diff --git a/e2e-tests/fixtures.ts b/e2e-tests/fixtures.ts new file mode 100644 index 000000000..598dca7a4 --- /dev/null +++ b/e2e-tests/fixtures.ts @@ -0,0 +1,271 @@ +import { + test as base, + chromium, + type BrowserContext, + Page +} from '@playwright/test'; +import path from 'path'; + +import { PLAYGROUND_URL, vaultPassword } from './constants'; + +export const test = base.extend<{ + context: BrowserContext; + extensionId: string; +}>({ + // eslint-disable-next-line no-empty-pattern + context: async ({}, use) => { + // For now playwright only support chrome extensions + // https://github.com/microsoft/playwright/issues/7297 + const pathToExtension = path.join(__dirname, `../build/chrome`); + const context = await chromium.launchPersistentContext('', { + headless: false, + args: [ + `--headless=new`, + `--disable-extensions-except=${pathToExtension}`, + `--load-extension=${pathToExtension}` + ] + }); + + await use(context); + await context.close(); + }, + extensionId: async ({ context }, use) => { + let [background] = context.serviceWorkers(); + + if (!background) { + background = await context.waitForEvent('serviceworker'); + } + + const extensionId = background.url().split('/')[2]; + + await use(extensionId); + } +}); + +export const onboarding = test.extend<{ + page: Page; + createOnboardingPassword: () => Promise; + createSecretPhrase: () => Promise; + copySecretPhrase: () => Promise; + confirmSecretPhraseSuccess: (phrase: string[]) => Promise; + confirmSecretPhraseFailure: (phrase: string[]) => Promise; +}>({ + page: async ({ extensionId, page }, use) => { + await page.goto(`chrome-extension://${extensionId}/onboarding.html`); + await use(page); + }, + createOnboardingPassword: async ({ page }, use) => { + const createOnboardingPassword = async () => { + await onboardingExpect( + page.getByRole('heading', { + name: 'Ready to create your new wallet?' + }) + ).toBeVisible(); + + await page.getByRole('button', { name: 'Get started' }).click(); + + await onboardingExpect(page).toHaveURL(/.*create-vault-password/); + + await page + .getByPlaceholder('Password', { exact: true }) + .fill(vaultPassword); + await page + .getByPlaceholder('Confirm password', { exact: true }) + .fill(vaultPassword); + await page.getByTestId('terms-checkbox').click(); + await page.getByRole('button', { name: 'Create password' }).click(); + }; + + await use(createOnboardingPassword); + }, + createSecretPhrase: async ({ page }, use) => { + const createSecretPhrase = async () => { + await onboardingExpect( + page.getByText('Create secret recovery phrase') + ).toBeVisible(); + + await page + .getByRole('button', { name: 'Create my secret recovery phrase' }) + .click(); + + await onboardingExpect( + page.getByText( + 'Before we generate your secret recovery phrase, please remember' + ) + ).toBeVisible(); + + await page + .getByText( + 'I understand that I am solely responsible for storing and protecting my secret recovery phrase. Access to my funds depend on it.' + ) + .click(); + + await page.getByRole('button', { name: 'Next' }).click(); + }; + + await use(createSecretPhrase); + }, + copySecretPhrase: async ({ page }, use) => { + const copySecretPhrase = async () => { + await onboardingExpect( + page.getByText('Write down your secret recovery phrase') + ).toBeVisible(); + + await page.getByText('Copy secret recovery phrase').click(); + + const copiedPhrase = await page.evaluate(() => + navigator.clipboard.readText() + ); + const phrase = copiedPhrase.split(' '); + + onboardingExpect(phrase.length).toEqual(24); + + await page + .getByText( + 'I confirm I have written down and securely stored my secret recovery phrase' + ) + .click(); + + await page.getByRole('button', { name: 'Next' }).click(); + + return phrase; + }; + + await use(copySecretPhrase); + }, + confirmSecretPhraseSuccess: async ({ page }, use) => { + const confirmSecretPhraseSuccess = async (phrase: string[]) => { + await onboardingExpect( + page.getByText('Confirm your secret recovery phrase') + ).toBeVisible(); + onboardingExpect( + page.getByRole('button', { name: 'Confirm' }).isDisabled() + ); + + const wordPicker = page.getByTestId('word-picker'); + const visibleWords = ( + await page.getByTestId('word-list').innerText() + ).split('\n'); + + const hiddenWords = phrase.filter( + word => !visibleWords.includes(word) && isNaN(Number(word)) + ); + + for (let i = 0; i < phrase.length; i++) { + const word = phrase[i]; + + if (hiddenWords.includes(word)) { + await wordPicker.getByText(word, { exact: true }).click(); + } + } + + onboardingExpect( + page.getByRole('button', { name: 'Confirm' }).isEnabled() + ); + + await page.getByRole('button', { name: 'Confirm' }).click(); + }; + + await use(confirmSecretPhraseSuccess); + }, + confirmSecretPhraseFailure: async ({ page }, use) => { + const confirmSecretPhraseFailure = async (phrase: string[]) => { + await onboardingExpect( + page.getByText('Confirm your secret recovery phrase') + ).toBeVisible(); + onboardingExpect( + page.getByRole('button', { name: 'Confirm' }).isDisabled() + ); + + const wordPicker = page.getByTestId('word-picker'); + const pickerWords = (await wordPicker.innerText()).split('\n'); + + for (let i = phrase.length; i > 0; i--) { + const word = phrase[i]; + + if (pickerWords.includes(word)) { + await wordPicker.getByText(word, { exact: true }).click(); + } + } + + onboardingExpect( + page.getByRole('button', { name: 'Confirm' }).isEnabled() + ); + + await page.getByRole('button', { name: 'Confirm' }).click(); + }; + + await use(confirmSecretPhraseFailure); + } +}); + +export const onboardingExpect = onboarding.expect; + +export const popup = test.extend<{ + popupPage: Page; + unlockVault: (popupPage?: Page) => Promise; + lockVault: () => Promise; + createAccount: (newAccountName: string) => Promise; + connectAccounts: () => Promise; +}>({ + popupPage: async ({ extensionId, page }, use) => { + await page.goto(`chrome-extension://${extensionId}/popup.html`); + await use(page); + }, + unlockVault: async ({ page }, use) => { + const unlockVault = async (popupPage?: Page) => { + const currentPage = popupPage || page; + + await currentPage + .getByPlaceholder('Password', { exact: true }) + .fill(vaultPassword); + await currentPage.getByRole('button', { name: 'Unlock wallet' }).click(); + }; + + await use(unlockVault); + }, + lockVault: async ({ page }, use) => { + const lockVault = async () => { + await page.getByTestId('menu-open-icon').click(); + await page.getByText('Lock wallet').click(); + }; + + await use(lockVault); + }, + createAccount: async ({ page }, use) => { + const createAccount = async (newAccountName: string) => { + await page.getByTestId('menu-open-icon').click(); + await page.getByText('Create account').click(); + + await page + .getByPlaceholder('Account name', { exact: true }) + .fill(newAccountName); + await page.getByRole('button', { name: 'Create account' }).click(); + }; + + await use(createAccount); + }, + connectAccounts: async ({ page, unlockVault, context }, use) => { + const connectAccounts = async () => { + await page.goto(PLAYGROUND_URL); + + const [connectAccountPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByRole('button', { name: 'Connect', exact: true }).click() + ]); + + await unlockVault(connectAccountPage); + + await connectAccountPage.getByText('select all', { exact: true }).click(); + + await connectAccountPage.getByRole('button', { name: 'Next' }).click(); + await connectAccountPage + .getByRole('button', { name: 'Connect to 2 accounts' }) + .click(); + }; + + await use(connectAccounts); + } +}); + +export const popupExpect = popup.expect; diff --git a/e2e-tests/onboarding-flow/confirm-secret-phrase-flow.spec.ts b/e2e-tests/onboarding-flow/confirm-secret-phrase-flow.spec.ts new file mode 100644 index 000000000..44be77eb4 --- /dev/null +++ b/e2e-tests/onboarding-flow/confirm-secret-phrase-flow.spec.ts @@ -0,0 +1,65 @@ +import { onboardingExpect, onboarding } from '../fixtures'; +import { DEFAULT_FIRST_ACCOUNT } from '../constants'; + +onboarding.describe('Onboarding UI: confirm secret phrase flow', () => { + onboarding( + 'should create a new vault when the user enters the correct secret phrase', + async ({ + page, + createOnboardingPassword, + createSecretPhrase, + copySecretPhrase, + confirmSecretPhraseSuccess, + extensionId + }) => { + await createOnboardingPassword(); + await createSecretPhrase(); + + const phrase = await copySecretPhrase(); + + await confirmSecretPhraseSuccess(phrase); + + await onboardingExpect(page).toHaveURL(/.*confirm-secret-phrase-success/); + + await page.getByRole('button', { name: 'Done' }).click(); + + await onboardingExpect(page.getByText('Got it')).toBeVisible(); + + await page.goto(`chrome-extension://${extensionId}/popup.html`); + + await onboardingExpect( + page.getByText(DEFAULT_FIRST_ACCOUNT.accountName) + ).toBeVisible(); + } + ); + + onboarding( + 'should NOT create a vault when the user entered the wrong secret phrase', + async ({ + page, + createOnboardingPassword, + createSecretPhrase, + copySecretPhrase, + confirmSecretPhraseFailure + }) => { + await createOnboardingPassword(); + await createSecretPhrase(); + + const phrase = await copySecretPhrase(); + + await confirmSecretPhraseFailure(phrase); + + await onboardingExpect(page).toHaveURL(/.*error/); + + await page + .getByRole('button', { + name: 'Generate a new secret recovery phrase' + }) + .click(); + + await onboardingExpect(page).toHaveURL( + /.*create-secret-phrase-confirmation/ + ); + } + ); +}); diff --git a/e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts b/e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts new file mode 100644 index 000000000..568d680b7 --- /dev/null +++ b/e2e-tests/onboarding-flow/recover-secret-phrase-flow.spec.ts @@ -0,0 +1,36 @@ +import { onboardingExpect, onboarding } from '../fixtures'; +import { DEFAULT_FIRST_ACCOUNT, recoverSecretPhrase } from '../constants'; + +onboarding.describe('Onboarding UI: recover secret phrase flow', () => { + onboarding( + 'should recover account via secret phrase', + async ({ page, createOnboardingPassword, extensionId }) => { + await createOnboardingPassword(); + + await page + .getByRole('button', { + name: 'Import an existing secret recovery phrase' + }) + .click(); + + await onboardingExpect( + page.getByText('Please enter your secret recovery phrase') + ).toBeVisible(); + + await page + .getByPlaceholder('e.g. Bobcat Lemon Blanket…') + .fill(recoverSecretPhrase); + + await page.getByRole('button', { name: 'Recover my wallet' }).click(); + + await page.goto(`chrome-extension://${extensionId}/popup.html`); + + await onboardingExpect( + page.getByText(DEFAULT_FIRST_ACCOUNT.accountName) + ).toBeVisible(); + await onboardingExpect( + page.getByText(DEFAULT_FIRST_ACCOUNT.truncatedPublicKey).nth(0) + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/common/wallet.spec.ts b/e2e-tests/popup/common/wallet.spec.ts new file mode 100644 index 000000000..c81c680c2 --- /dev/null +++ b/e2e-tests/popup/common/wallet.spec.ts @@ -0,0 +1,83 @@ +import { popup, popupExpect } from '../../fixtures'; +import { ACCOUNT_NAMES } from '../../constants'; + +popup.describe('Popup UI: lock/unlock/reset wallet', () => { + popup( + 'should unlock and lock wallet', + async ({ popupPage, unlockVault, lockVault }) => { + await popupExpect( + popupPage.getByText('Your wallet is locked') + ).toBeVisible(); + + await unlockVault(); + + await popupExpect(popupPage.getByText('Unlocking...')).toBeVisible(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.defaultFirstAccountName) + ).toBeVisible(); + + await lockVault(); + + await popupExpect( + popupPage.getByText('Your wallet is locked') + ).toBeVisible(); + } + ); + + popup('should reset wallet', async ({ context, popupPage }) => { + await popupExpect( + popupPage.getByText('Your wallet is locked') + ).toBeVisible(); + + await popupPage.getByRole('button', { name: 'Reset wallet' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { + name: 'Are you sure you want to reset your wallet?' + }) + ).toBeVisible(); + await popupExpect( + popupPage.getByRole('button', { name: 'Reset wallet' }) + ).toBeDisabled(); + + await popupPage.getByText('I’ve read and understand the above').click(); + await popupExpect( + popupPage.getByRole('button', { name: 'Reset wallet' }) + ).toBeEnabled(); + + const [onboardingPage] = await Promise.all([ + context.waitForEvent('page'), + popupPage.getByRole('button', { name: 'Reset wallet' }).click() + ]); + + await popupExpect( + onboardingPage.getByRole('heading', { + name: 'Ready to create your new wallet?' + }) + ).toBeVisible(); + }); + + popup( + 'should lock wallet for 5 minutes when user types wrong password 5 times', + async ({ popupPage }) => { + await popupExpect( + popupPage.getByText('Your wallet is locked') + ).toBeVisible(); + + await popupPage + .getByPlaceholder('Password', { exact: true }) + .fill('wrong password'); + + for (let i = 0; i < 5; i++) { + await popupPage.getByRole('button', { name: 'Unlock wallet' }).click(); + } + + await popupExpect( + popupPage.getByRole('heading', { + name: 'Please wait before the next attempt to unlock your wallet' + }) + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/connect-account/connect-account.spec.ts b/e2e-tests/popup/connect-account/connect-account.spec.ts new file mode 100644 index 000000000..24f64de87 --- /dev/null +++ b/e2e-tests/popup/connect-account/connect-account.spec.ts @@ -0,0 +1,108 @@ +import { Page } from '@playwright/test'; + +import { popup, popupExpect } from '../../fixtures'; +import { ACCOUNT_NAMES, PLAYGROUND_URL } from '../../constants'; + +popup.describe('Popup UI: connect account', () => { + let connectAccountPage: Page; + + popup.beforeEach(async ({ page, context, unlockVault }) => { + await page.goto(PLAYGROUND_URL); + + [connectAccountPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByRole('button', { name: 'Connect', exact: true }).click() + ]); + + await unlockVault(connectAccountPage); + }); + + popup( + 'should connect one account to playground', + async ({ extensionId, page }) => { + await popupExpect( + connectAccountPage.getByText('Connect with Casper Wallet Playground') + ).toBeVisible(); + + await popupExpect( + connectAccountPage.getByRole('button', { name: 'Next' }) + ).toBeDisabled(); + + await connectAccountPage + .getByText(ACCOUNT_NAMES.defaultFirstAccountName, { exact: true }) + .click(); + + await popupExpect( + connectAccountPage.getByRole('button', { name: 'Next' }) + ).toBeEnabled(); + + await connectAccountPage.getByRole('button', { name: 'Next' }).click(); + await connectAccountPage + .getByRole('button', { name: 'Connect to 1 account' }) + .click(); + + await page.goto(`chrome-extension://${extensionId}/popup.html`); + + await page.getByTestId('menu-open-icon').click(); + await page.getByText('Connected sites').click(); + + await popupExpect( + page.getByText('Casper Wallet Playground') + ).toBeVisible(); + await popupExpect( + page.getByText('casper-wallet-playground.make.services') + ).toBeVisible(); + await popupExpect( + page.getByRole('button', { name: 'Disconnect' }) + ).toBeVisible(); + await popupExpect( + page.getByText(ACCOUNT_NAMES.defaultFirstAccountName) + ).toBeVisible(); + } + ); + + popup( + 'should connect two accounts to playground', + async ({ extensionId, page }) => { + await popupExpect( + connectAccountPage.getByText('Connect with Casper Wallet Playground') + ).toBeVisible(); + + await popupExpect( + connectAccountPage.getByRole('button', { name: 'Next' }) + ).toBeDisabled(); + + await connectAccountPage.getByText('select all', { exact: true }).click(); + + await popupExpect( + connectAccountPage.getByRole('button', { name: 'Next' }) + ).toBeEnabled(); + + await connectAccountPage.getByRole('button', { name: 'Next' }).click(); + await connectAccountPage + .getByRole('button', { name: 'Connect to 2 accounts' }) + .click(); + + await page.goto(`chrome-extension://${extensionId}/popup.html`); + + await page.getByTestId('menu-open-icon').click(); + await page.getByText('Connected sites').click(); + + await popupExpect( + page.getByText('Casper Wallet Playground') + ).toBeVisible(); + await popupExpect( + page.getByText('casper-wallet-playground.make.services') + ).toBeVisible(); + await popupExpect( + page.getByRole('button', { name: 'Disconnect' }) + ).toBeVisible(); + await popupExpect( + page.getByText(ACCOUNT_NAMES.defaultFirstAccountName) + ).toBeVisible(); + await popupExpect( + page.getByText(ACCOUNT_NAMES.defaultSecondAccountName) + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/create-account/create-account.spec.ts b/e2e-tests/popup/create-account/create-account.spec.ts new file mode 100644 index 000000000..d22a7be51 --- /dev/null +++ b/e2e-tests/popup/create-account/create-account.spec.ts @@ -0,0 +1,41 @@ +import { popup, popupExpect } from '../../fixtures'; +import { ACCOUNT_NAMES } from '../../constants'; + +popup.describe('Popup UI: create account', () => { + popup.beforeEach(async ({ unlockVault, popupPage }) => { + await unlockVault(popupPage); + }); + + popup( + 'should create account from navigation menu', + async ({ popupPage, createAccount }) => { + await createAccount(ACCOUNT_NAMES.createdAccountName); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.createdAccountName) + ).toBeVisible(); + } + ); + + popup( + 'should create account from account list modal', + async ({ popupPage }) => { + await popupPage.getByTestId('connection-status-modal').click(); + + await popupPage.getByRole('button', { name: 'Create' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Create account' }) + ).toBeVisible(); + + await popupPage + .getByPlaceholder('Account name', { exact: true }) + .fill(ACCOUNT_NAMES.createdAccountName); + await popupPage.getByRole('button', { name: 'Create account' }).click(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.createdAccountName) + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/disconnect-account/disconnect-account.spec.ts b/e2e-tests/popup/disconnect-account/disconnect-account.spec.ts new file mode 100644 index 000000000..47064c612 --- /dev/null +++ b/e2e-tests/popup/disconnect-account/disconnect-account.spec.ts @@ -0,0 +1,71 @@ +import { popup, popupExpect } from '../../fixtures'; +import { ACCOUNT_NAMES, PLAYGROUND_URL } from '../../constants'; + +popup.describe('Popup UI: disconnect account', () => { + popup.beforeEach(async ({ connectAccounts }) => { + await connectAccounts(); + }); + + popup( + 'should click the disconnect button on dapp and disconnect all accounts from the site', + async ({ page, extensionId }) => { + await page.goto(PLAYGROUND_URL); + + await page.getByRole('button', { name: 'Disconnect' }).click(); + + await page.goto(`chrome-extension://${extensionId}/popup.html`); + await page.getByTestId('menu-open-icon').click(); + await page.getByText('Connected sites').click(); + + await popupExpect(page.getByText('No connected sites yet')).toBeVisible(); + } + ); + + popup( + 'should click the disconnect button on connecting site page and disconnect one account from the site', + async ({ popupPage }) => { + await popupPage.getByTestId('menu-open-icon').click(); + await popupPage.getByText('Connected sites').click(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.defaultFirstAccountName) + ).toBeVisible(); + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.defaultSecondAccountName) + ).toBeVisible(); + + const disconnectIcons = await popupPage + .getByTestId('disconnect-account-icon') + .all(); + await disconnectIcons[0].click(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.defaultFirstAccountName) + ).not.toBeVisible(); + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.defaultSecondAccountName) + ).toBeVisible(); + } + ); + + popup( + 'should click the disconnect button on connecting site page and disconnect all accounts from the site', + async ({ popupPage }) => { + await popupPage.getByTestId('menu-open-icon').click(); + await popupPage.getByText('Connected sites').click(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.defaultFirstAccountName) + ).toBeVisible(); + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.defaultSecondAccountName) + ).toBeVisible(); + + await popupPage.getByRole('button', { name: 'Disconnect' }).click(); + + await popupExpect( + popupPage.getByText('No connected sites yet') + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts b/e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts new file mode 100644 index 000000000..92104ef5d --- /dev/null +++ b/e2e-tests/popup/import-account-with-file/import-account-with-file.spec.ts @@ -0,0 +1,63 @@ +import { popup, popupExpect } from '../../fixtures'; +import { + ACCOUNT_NAMES, + IMPORTED_ACCOUNT, + secretKeyPath +} from '../../constants'; + +popup.describe('Popup UI: import account with file', () => { + popup( + 'should import account via a file', + async ({ unlockVault, context, popupPage }) => { + await unlockVault(); + + await popupPage.getByTestId('menu-open-icon').click(); + + const [importAccountPage] = await Promise.all([ + context.waitForEvent('page'), + popupPage.getByText('Import account').click() + ]); + + const fileChooserPromise = importAccountPage.waitForEvent('filechooser'); + + await popupExpect( + importAccountPage.getByRole('heading', { + name: 'Import account from secret key file' + }) + ).toBeVisible(); + + await importAccountPage + .getByRole('button', { name: 'Upload your file' }) + .click(); + + const fileChooser = await fileChooserPromise; + await fileChooser.setFiles(secretKeyPath); + + await importAccountPage + .getByPlaceholder('Account name', { exact: true }) + .fill(ACCOUNT_NAMES.importedAccountName); + + await importAccountPage.getByRole('button', { name: 'Import' }).click(); + + await popupExpect( + importAccountPage.getByRole('heading', { + name: 'Your account was successfully imported' + }) + ).toBeVisible(); + + await importAccountPage.getByRole('button', { name: 'Done' }).click(); + + await popupPage.getByTestId('connection-status-modal').click(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.importedAccountName) + ).toBeVisible(); + await popupExpect( + popupPage.getByText(IMPORTED_ACCOUNT.truncatedPublicKey) + ).toBeVisible(); + await popupExpect( + popupPage.getByText('Imported', { exact: true }) + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/rename-account/rename-account.spec.ts b/e2e-tests/popup/rename-account/rename-account.spec.ts new file mode 100644 index 000000000..2ab7f8b94 --- /dev/null +++ b/e2e-tests/popup/rename-account/rename-account.spec.ts @@ -0,0 +1,36 @@ +import { popup, popupExpect } from '../../fixtures'; +import { ACCOUNT_NAMES } from '../../constants'; + +popup.describe('Popup UI: rename account', () => { + popup( + 'should rename account from account popover', + async ({ popupPage, unlockVault }) => { + await unlockVault(); + + await popupPage.getByTestId('popover-children-container').click(); + + await popupPage.getByText('Rename').click(); + + await popupExpect( + popupPage.getByRole('heading', { name: 'Rename account' }) + ).toBeVisible(); + + await popupPage + .getByPlaceholder('New account name', { exact: true }) + .fill(ACCOUNT_NAMES.renamedAccountName); + await popupPage.getByRole('button', { name: 'Update' }).click(); + + await popupExpect( + popupPage.getByRole('heading', { + name: ACCOUNT_NAMES.renamedAccountName + }) + ).toBeVisible(); + + await popupPage.getByText('Close').click(); + + await popupExpect( + popupPage.getByText(ACCOUNT_NAMES.renamedAccountName) + ).toBeVisible(); + } + ); +}); diff --git a/e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts b/e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts new file mode 100644 index 000000000..7c3ba2850 --- /dev/null +++ b/e2e-tests/popup/signature-request-scenarios/signature-request-scenarios.spec.ts @@ -0,0 +1,217 @@ +import { popup, popupExpect } from '../../fixtures'; +import { + DEFAULT_FIRST_ACCOUNT, + NEW_VALIDATOR, + PLAYGROUND_URL, + VALIDATOR +} from '../../constants'; + +popup.describe('Popup UI: signature request scenarios', () => { + popup.beforeEach(async ({ connectAccounts, page }) => { + await connectAccounts(); + // need to wait for the connection status modal to disappear + await page.waitForTimeout(3000); + }); + + popup('should signing the transfer deploy', async ({ page, context }) => { + await page.goto(PLAYGROUND_URL); + + const [signatureRequestPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByRole('button', { name: 'Transfer' }).click() + ]); + + await popupExpect( + signatureRequestPage.getByRole('heading', { name: 'Signature Request' }) + ).toBeVisible(); + + await signatureRequestPage.getByText('Transfer Data').click(); + + await popupExpect( + signatureRequestPage.getByText('Transfer Call') + ).toBeVisible(); + + await popupExpect( + signatureRequestPage.getByText('Recipient (Key)') + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(VALIDATOR.truncatedPublicKey) + ).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('Amount')).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('2.5 CSPR')).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText('Transfer ID') + ).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('1234')).toBeVisible(); + + page.on('dialog', async dialog => { + popupExpect(dialog.message()).toContain('Sign successful'); + await dialog.accept(); + }); + + await signatureRequestPage.getByRole('button', { name: 'Sign' }).click(); + }); + + popup('should signing the delegate deploy', async ({ page, context }) => { + await page.goto(PLAYGROUND_URL); + + const [signatureRequestPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByRole('button', { name: 'Delegate', exact: true }).click() + ]); + + await popupExpect( + signatureRequestPage.getByRole('heading', { name: 'Signature Request' }) + ).toBeVisible(); + + await signatureRequestPage.getByText('Contract arguments').click(); + + await popupExpect( + signatureRequestPage.getByText('Contract Call') + ).toBeVisible(); + + await popupExpect(signatureRequestPage.getByText('delegate')).toBeVisible(); + + await popupExpect( + signatureRequestPage.getByText('Delegator') + ).toBeVisible(); + await popupExpect( + signatureRequestPage + .getByText(DEFAULT_FIRST_ACCOUNT.truncatedPublicKey) + .nth(2) + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(VALIDATOR.name) + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(VALIDATOR.truncatedPublicKey) + ).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('Amount')).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText('2.5 CSPR').nth(1) + ).toBeVisible(); + + page.on('dialog', async dialog => { + popupExpect(dialog.message()).toContain('Sign successful'); + await dialog.accept(); + }); + + await signatureRequestPage.getByRole('button', { name: 'Sign' }).click(); + }); + + popup('should signing the undelegate deploy', async ({ page, context }) => { + await page.goto(PLAYGROUND_URL); + + const [signatureRequestPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByRole('button', { name: 'Undelegate', exact: true }).click() + ]); + + await popupExpect( + signatureRequestPage.getByRole('heading', { name: 'Signature Request' }) + ).toBeVisible(); + + await signatureRequestPage.getByText('Contract arguments').click(); + + await popupExpect( + signatureRequestPage.getByText('Contract Call') + ).toBeVisible(); + + await popupExpect( + signatureRequestPage.getByText('undelegate') + ).toBeVisible(); + + await popupExpect( + signatureRequestPage.getByText('Delegator') + ).toBeVisible(); + await popupExpect( + signatureRequestPage + .getByText(DEFAULT_FIRST_ACCOUNT.truncatedPublicKey) + .nth(2) + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(VALIDATOR.name) + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(VALIDATOR.truncatedPublicKey) + ).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('Amount')).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('2.5 CSPR')).toBeVisible(); + + page.on('dialog', async dialog => { + popupExpect(dialog.message()).toContain('Sign successful'); + await dialog.accept(); + }); + + await signatureRequestPage.getByRole('button', { name: 'Sign' }).click(); + }); + + popup('should signing the redelegate deploy', async ({ page, context }) => { + await page.goto(PLAYGROUND_URL); + + const [signatureRequestPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByRole('button', { name: 'Redelegate', exact: true }).click() + ]); + + await popupExpect( + signatureRequestPage.getByRole('heading', { name: 'Signature Request' }) + ).toBeVisible(); + + await signatureRequestPage.getByText('Contract arguments').click(); + + await popupExpect( + signatureRequestPage.getByText('Contract Call') + ).toBeVisible(); + + await popupExpect( + signatureRequestPage.getByText('redelegate') + ).toBeVisible(); + + await popupExpect( + signatureRequestPage.getByText('Delegator') + ).toBeVisible(); + await popupExpect( + signatureRequestPage + .getByText(DEFAULT_FIRST_ACCOUNT.truncatedPublicKey) + .nth(2) + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(VALIDATOR.name, { exact: true }) + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(VALIDATOR.truncatedPublicKey) + ).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('Amount')).toBeVisible(); + await popupExpect(signatureRequestPage.getByText('2.5 CSPR')).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(NEW_VALIDATOR.name) + ).toBeVisible(); + await popupExpect( + signatureRequestPage.getByText(NEW_VALIDATOR.truncatedPublicKey) + ).toBeVisible(); + + page.on('dialog', async dialog => { + popupExpect(dialog.message()).toContain('Sign successful'); + await dialog.accept(); + }); + + await signatureRequestPage.getByRole('button', { name: 'Sign' }).click(); + }); + + popup('should cancel the signing process', async ({ page, context }) => { + await page.goto(PLAYGROUND_URL); + + const [signatureRequestPage] = await Promise.all([ + context.waitForEvent('page'), + page.getByRole('button', { name: 'Transfer' }).click() + ]); + + page.on('dialog', async dialog => { + popupExpect(dialog.message()).toContain('Sign cancelled'); + await dialog.accept(); + }); + + await signatureRequestPage.getByRole('button', { name: 'Cancel' }).click(); + }); +}); diff --git a/e2e/__fixtures.ts b/e2e/__fixtures.ts deleted file mode 100644 index 38e0500a7..000000000 --- a/e2e/__fixtures.ts +++ /dev/null @@ -1,4 +0,0 @@ -export const vaultPassword = '3hQqzYn4C7Y8rEZTVEZb'; -export const recoverSecretPhrase = - 'hold matrix spider subway bottom jazz charge fire lawn valley stay coil moral hospital dream cycle multiply december agree huge major tower devote old'; -export const secretKeyPath = 'e2e/account_secret_key.pem'; diff --git a/e2e/app-routes.ts b/e2e/app-routes.ts deleted file mode 100644 index bac0879d6..000000000 --- a/e2e/app-routes.ts +++ /dev/null @@ -1,4 +0,0 @@ -export enum AppRoutes { - Onboarding = 'onboarding', - Popup = 'popup' -} diff --git a/e2e/constants.ts b/e2e/constants.ts deleted file mode 100644 index 30873ecd5..000000000 --- a/e2e/constants.ts +++ /dev/null @@ -1,26 +0,0 @@ -export const ACCOUNT_NAMES = { - defaultAccountName: 'Account 1', - createdAccountName: 'New account 1', - importedAccountName: 'Imported account' -}; - -export const PLAYGROUND_URL = 'https://casper-wallet-playground.make.services/'; - -export const IMPORTED_ACCOUNT = { - accountName: ACCOUNT_NAMES.importedAccountName, - publicKey: - '0184f6d260f4ee6869ddb36affe15456de6ae045278fa2f467bb677561ce0dad55', - truncatedPublicKey: '0184f...dad55' -}; - -export const DEFAULT_ACCOUNT = { - accountName: ACCOUNT_NAMES.defaultAccountName, - publicKey: - '02021006f7e7ecba9dda1fbd68bd88b0b509ce07a24c4ce8a96c62d44bec4beb9f9d', - truncatedPublicKey: '02021...b9f9d' -}; - -export enum TIMEOUT { - '15sec' = 1000 * 15, - '50sec' = 1000 * 50 -} diff --git a/e2e/crx3-public.pem b/e2e/crx3-public.pem deleted file mode 100644 index 78de8175e..000000000 --- a/e2e/crx3-public.pem +++ /dev/null @@ -1,4 +0,0 @@ ------BEGIN PUBLIC KEY----- -MFswDQYJKoZIhvcNAQEBBQADSgAwRwJAWuDoW01t8OTlxAo+uOu/0tR0U/LjsDwO -vEk5yHBqfOSSIuMRd7grr09CrfScI2QqF7InrUOSuDCTd8oB/taxUQIDAQAB ------END PUBLIC KEY----- \ No newline at end of file diff --git a/e2e/crx3.pem b/e2e/crx3.pem deleted file mode 100644 index 84377d4c1..000000000 --- a/e2e/crx3.pem +++ /dev/null @@ -1,9 +0,0 @@ ------BEGIN RSA PRIVATE KEY----- -MIIBOAIBAAJAWuDoW01t8OTlxAo+uOu/0tR0U/LjsDwOvEk5yHBqfOSSIuMRd7gr -r09CrfScI2QqF7InrUOSuDCTd8oB/taxUQIDAQABAkAZuLBrLxYf6VlSzCeGhUss -q+8k14k0FzuAdSVCovaw1FXRe5z1Fj1nkUmGIIL8lbhW2uiNNpUou7ru8iUr9xcx -AiEAqy5622hvGPDkAa/1wvVhX3eNUGtEONZdlDNMZa28L+UCIQCH6GTdfLoVy+u+ -GFd2/v51fcZ50km8IQymUp9BqyAs/QIgXMkV2MWTqn4v6GY7HRCqVffURinOUcyH -7qObnmV8Yq0CIGByPwIe/T9ykz03sPo1QwbF1w+kd8cV/RAbGgFUG2VRAiBqCsE/ -JfG6vhqyisXxvbqI4+n9Isb2RPxWoPCfQVtblA== ------END RSA PRIVATE KEY----- \ No newline at end of file diff --git a/e2e/tests/common/click-button-to-open-extension-window-and-focus.ts b/e2e/tests/common/click-button-to-open-extension-window-and-focus.ts deleted file mode 100644 index 760f336a3..000000000 --- a/e2e/tests/common/click-button-to-open-extension-window-and-focus.ts +++ /dev/null @@ -1,31 +0,0 @@ -import { strict as assert } from 'assert'; - -import { Driver } from '../../webdriver/driver'; -import { byText } from '../../utils/helpers'; -import { TIMEOUT } from '../../constants'; - -export const clickButtonToOpenExtensionWindowAndFocus = async ( - driver: Driver, - currentWindow: string, - clickElement: string -) => { - // Check if there is one window open - assert.equal((await driver.getAllWindowHandles()).length, 1); - - await driver.clickElement(byText(clickElement)); - - // Wait for the new window - await driver.wait( - async () => (await driver.getAllWindowHandles()).length === 2, - TIMEOUT['15sec'] - ); - - // Loop through until we find a new window handle - const windows = await driver.getAllWindowHandles(); - - for (const handle of windows) { - if (handle !== currentWindow) { - await driver.switchToWindow(handle); - } - } -}; diff --git a/e2e/tests/common/connect-account.ts b/e2e/tests/common/connect-account.ts deleted file mode 100644 index ee2e3ee53..000000000 --- a/e2e/tests/common/connect-account.ts +++ /dev/null @@ -1,57 +0,0 @@ -import { strict as assert } from 'assert'; - -import { unlockVault } from './unlock-vault'; -import { clickButtonToOpenExtensionWindowAndFocus } from './click-button-to-open-extension-window-and-focus'; - -import { Driver } from '../../webdriver/driver'; -import { byTestId, byText } from '../../utils/helpers'; -import { ACCOUNT_NAMES, TIMEOUT } from '../../constants'; - -export const connectAccount = async ({ - driver, - currentWindow, - connectAllAccounts -}: { - driver: Driver; - currentWindow: string; - connectAllAccounts?: boolean; -}) => { - await clickButtonToOpenExtensionWindowAndFocus( - driver, - currentWindow, - 'Connect' - ); - - const isWalletLocked = await driver.isElementPresent( - byText('Your wallet is locked') - ); - - if (isWalletLocked) { - await unlockVault(driver); - - assert.ok( - await driver.isElementPresent( - byText('Connect with Casper Wallet Playground'), - 'Connect with Casper Wallet Playground', - TIMEOUT['50sec'] - ), - `Wallet still locked` - ); - } - - if (connectAllAccounts) { - await driver.clickElement(byText('select all')); - } else { - await driver.clickElement(byText(ACCOUNT_NAMES.defaultAccountName)); - } - - await driver.clickElement(byText('Next')); - - await driver.clickElement(byTestId('connect-accounts-button')); - - // Wait for connecting - await driver.wait( - async () => (await driver.getAllWindowHandles()).length === 1, - TIMEOUT['15sec'] - ); -}; diff --git a/e2e/tests/common/create-account.ts b/e2e/tests/common/create-account.ts deleted file mode 100644 index 5e6b8e41a..000000000 --- a/e2e/tests/common/create-account.ts +++ /dev/null @@ -1,16 +0,0 @@ -import { Driver } from '../../webdriver/driver'; -import { byInputName, byTestId, byText } from '../../utils/helpers'; - -export const createAccount = async (driver: Driver, newAccountName: string) => { - await driver.clickElement(byTestId('menu-open-icon')); - - await driver.clickElement(byText('Create account')); - - const accountNameInput = await driver.findElement(byInputName('name')); - - await accountNameInput.fill(newAccountName); - - await driver.clickElement(byText('Create Account')); - - await driver.findElement(byText(newAccountName)); -}; diff --git a/e2e/tests/common/create-password.ts b/e2e/tests/common/create-password.ts deleted file mode 100644 index 8679c606c..000000000 --- a/e2e/tests/common/create-password.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Driver } from '../../webdriver/driver'; -import { vaultPassword } from '../../__fixtures'; -import { byButtonText, byInputName, byTestId } from '../../utils/helpers'; - -export const createPassword = async (driver: Driver) => { - await driver.fill(byInputName('password'), vaultPassword); - await driver.fill(byInputName('confirmPassword'), vaultPassword); - - const checkbox = await driver.findElement(byTestId('terms-checkbox')); - await checkbox.click(); - await driver.clickElement(byButtonText('Create password')); -}; diff --git a/e2e/tests/common/index.ts b/e2e/tests/common/index.ts deleted file mode 100644 index 9648c1026..000000000 --- a/e2e/tests/common/index.ts +++ /dev/null @@ -1,7 +0,0 @@ -export * from './create-password'; -export * from './unlock-vault'; -export * from './create-account'; -export * from './click-button-to-open-extension-window-and-focus'; -export * from './lock-vault'; -export * from './open-connected-site-page'; -export * from './connect-account'; diff --git a/e2e/tests/common/lock-vault.ts b/e2e/tests/common/lock-vault.ts deleted file mode 100644 index cc5ecbc12..000000000 --- a/e2e/tests/common/lock-vault.ts +++ /dev/null @@ -1,7 +0,0 @@ -import { Driver } from '../../webdriver/driver'; -import { byTestId, byText } from '../../utils/helpers'; - -export const lockVault = async (driver: Driver) => { - await driver.clickElement(byTestId('menu-open-icon')); - await driver.clickElement(byText('Lock wallet')); -}; diff --git a/e2e/tests/common/open-connected-site-page.ts b/e2e/tests/common/open-connected-site-page.ts deleted file mode 100644 index 129633c8a..000000000 --- a/e2e/tests/common/open-connected-site-page.ts +++ /dev/null @@ -1,12 +0,0 @@ -import { Driver } from '../../webdriver/driver'; -import { AppRoutes } from '../../app-routes'; -import { byTestId, byText } from '../../utils/helpers'; - -export const openConnectedSitePage = async (driver: Driver) => { - await driver.createNewWindowOrTabAndSwitch('window'); - - await driver.navigate(AppRoutes.Popup); - - await driver.clickElement(byTestId('menu-open-icon')); - await driver.clickElement(byText('Connected sites')); -}; diff --git a/e2e/tests/common/unlock-vault.ts b/e2e/tests/common/unlock-vault.ts deleted file mode 100644 index c5db1186a..000000000 --- a/e2e/tests/common/unlock-vault.ts +++ /dev/null @@ -1,8 +0,0 @@ -import { Driver } from '../../webdriver/driver'; -import { vaultPassword } from '../../__fixtures'; -import { byButtonText, byInputName } from '../../utils/helpers'; - -export const unlockVault = async (driver: Driver) => { - await driver.fill(byInputName('password'), vaultPassword); - await driver.clickElement(byButtonText('Unlock wallet')); -}; diff --git a/e2e/tests/onboarding-flow/confirm-secret-phrase-flow.test.ts b/e2e/tests/onboarding-flow/confirm-secret-phrase-flow.test.ts deleted file mode 100644 index 2b1e8d59e..000000000 --- a/e2e/tests/onboarding-flow/confirm-secret-phrase-flow.test.ts +++ /dev/null @@ -1,213 +0,0 @@ -import { until } from 'selenium-webdriver'; -import { strict as assert } from 'assert'; - -import { Driver } from '../../webdriver/driver'; -import { buildWebDriver } from '../../webdriver'; -import { AppRoutes } from '../../app-routes'; -import { byText, byTestId, getUrlPath } from '../../utils/helpers'; -import { WebElementWithAPI } from '../../webdriver/WebElementWithAPI'; -import { createPassword } from '../common'; - -describe('Onboarding UI: confirm secret phrase flow [happy path]', () => { - let driver: Driver; - let copiedPhrase: string; - let secretPhraseList: WebElementWithAPI; - let secretPhrase: string[]; - - beforeAll(async () => { - driver = await buildWebDriver(); - await driver.navigate(AppRoutes.Onboarding); - }); - - afterAll(async () => { - await driver.quit(); - }); - - it('should contain `Get started` button with text, which navigates to `Create password` page by clicking on it', async () => { - await driver.clickElement(byText('Get started')); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'create-vault-password' - ); - }); - - it('should navigate to `Create secret phrase` page when the user filled the password, checked the checkbox, and click on `Create password` button', async () => { - await createPassword(driver); - - // Need to wait for the finishing script for creating the password - await driver.wait( - until.elementLocated(byText('Create secret recovery phrase')) - ); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'create-secret-phrase' - ); - }); - - it('should navigate to `Create Secret Phrase Confirmation` page by clicking on `Create my secret recovery phrase` button', async () => { - await driver.clickElement(byText('Create my secret recovery phrase')); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'create-secret-phrase-confirmation' - ); - }); - - it('should navigate to `Write Down Secret Phrase` page when the user checked the checkbox and clicks on `Next` button', async () => { - await driver.clickElement( - byText( - 'I understand that I am solely responsible for storing and protecting my secret recovery phrase. Access to my funds depend on it.' - ) - ); - - await driver.clickElement(byText('Next')); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'write-down-secret-phrase' - ); - }); - - it('should contain a `Copy secret recovery phrase` link which copies a phrase with 24 words to the clipboard', async () => { - await driver.clickElement(byText('Copy secret recovery phrase')); - - secretPhraseList = await driver.findElement(byTestId('word-list')); - secretPhrase = (await secretPhraseList.getText()).split('\n'); - - // Firefox only supports reading the clipboard in browser extensions. - // So this is the hack to pass this test for it. - // Disabled this test for Chrome as well, until we find a way to fix clipboard permission. - if (driver.browser === 'firefox' || driver.browser === 'chrome') { - expect(true); - } else { - copiedPhrase = (await driver.executeScript( - 'return navigator.clipboard.readText();' - )) as string; - - assert.equal(copiedPhrase.split(' ').length, 24); - } - }); - - it('should navigate to `Confirm Secret Phrase` page when the user checks the checkbox and clicks on `Next` button', async () => { - await driver.clickElement( - byText( - 'I confirm I have written down and securely stored my secret recovery phrase' - ) - ); - - await driver.clickElement(byText('Next')); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'confirm-secret-phrase' - ); - }); - - it('should navigate to `Confirm Secret Phrase Success` page when the user completed the puzzle test and clicks on `Confirm` button', async () => { - const phrase = copiedPhrase?.split(' ') || secretPhrase; - - const wordPicker = await driver.findElement(byTestId('word-picker')); - const wordList = await driver.findElement(byTestId('word-list')); - - const visibleWords = (await wordList.getText()).split('\n'); - - const hiddenWords = phrase.filter( - word => !visibleWords.includes(word) && isNaN(Number(word)) - ); - - for (let i = 0; i < phrase.length; i++) { - const word = phrase[i]; - - if (hiddenWords.includes(word)) { - await wordPicker.findElement(byText(word)).click(); - } - } - - await driver.clickElement(byText('Confirm')).catch(async () => { - await driver.verboseReportOnFailure('Confirm button should be clickable'); - }); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'confirm-secret-phrase-success' - ); - }); - - it('should navigate to `Onboarding Success` page when the user clicks on `Done` button', async () => { - await driver.clickElement(byText('Done')); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'onboarding-success' - ); - }); - - it('should contains a `Got it` button', async () => { - assert.ok(await driver.findElement(byText('Got it'))); - }); -}); - -describe('Onboarding UI: confirm secret phrase flow [unhappy path]', () => { - let driver: Driver; - let secretPhraseList: WebElementWithAPI; - let secretPhrase: string[]; - - beforeAll(async () => { - driver = await buildWebDriver(); - await driver.navigate(AppRoutes.Onboarding); - - // Welcome page - await driver.clickElement(byText('Get started')); - - // Create password page - await createPassword(driver); - - // Create Secret Phrase page - await driver.clickElement(byText('Create my secret recovery phrase')); - - // Create Secret Phrase Confirmation page - await driver.clickElement( - byText( - 'I understand that I am solely responsible for storing and protecting my secret recovery phrase. Access to my funds depend on it.' - ) - ); - await driver.clickElement(byText('Next')); - - // Write Down Secret Phrase page - await driver.clickElement(byText('Copy secret recovery phrase')); - - secretPhraseList = await driver.findElement(byTestId('word-list')); - secretPhrase = (await secretPhraseList.getText()).split('\n'); - - await driver.clickElement( - byText( - 'I confirm I have written down and securely stored my secret recovery phrase' - ) - ); - await driver.clickElement(byText('Next')); - }); - - afterAll(async () => { - await driver.quit(); - }); - - it('should navigate to `Error` page when the user does not pass the puzzle test and clicked on `Confirm` button', async () => { - const wordPicker = await driver.findElement(byTestId('word-picker')); - - const pickerWords = (await wordPicker.getText()).split('\n'); - - for (let i = secretPhrase.length; i > 0; i--) { - const word = secretPhrase[i]; - - if (pickerWords.includes(word)) { - await wordPicker.findElement(byText(word)).click(); - } - } - - await driver.clickElement(byText('Confirm')); - - assert.equal(await driver.driver.getCurrentUrl().then(getUrlPath), 'error'); - }); -}); diff --git a/e2e/tests/onboarding-flow/recover-secret-phrase-flow.test.ts b/e2e/tests/onboarding-flow/recover-secret-phrase-flow.test.ts deleted file mode 100644 index b26c5b16e..000000000 --- a/e2e/tests/onboarding-flow/recover-secret-phrase-flow.test.ts +++ /dev/null @@ -1,64 +0,0 @@ -import { By, error as webdriverError } from 'selenium-webdriver'; -import { strict as assert } from 'assert'; - -import { Driver } from '../../webdriver/driver'; -import { buildWebDriver } from '../../webdriver'; -import { AppRoutes } from '../../app-routes'; -import { recoverSecretPhrase } from '../../__fixtures'; -import { byText, getUrlPath } from '../../utils/helpers'; -import { createPassword } from '../common'; - -describe('Onboarding UI: recover secret phrase flow [happy path]', () => { - let driver: Driver; - - beforeAll(async () => { - driver = await buildWebDriver(); - await driver.navigate(AppRoutes.Onboarding); - // This testsuits should test a scenario for recovery wallet, so we should navigate to start place - // Welcome page - await driver.clickElement(byText('Get started')); - // Create password page - await createPassword(driver); - }); - - afterAll(async () => { - await driver.quit(); - }); - - describe('`Create Secret Phrase` page', () => { - it('should navigate to `Recover From Secret Phrase` page when the user clicked on `Import an existing secret recovery phrase` button', async () => { - await driver.clickElement( - byText('Import an existing secret recovery phrase') - ); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'recover-from-secret-phrase' - ); - }); - }); - - describe('`Recover From Secret Phrase` page', () => { - it('should recover the wallet without errors when the user correctly entered the recovery secret phrase in the text area and click on `Recover my wallet` button', async () => { - await driver.fill( - By.xpath("//textarea[@placeholder='e.g. Bobcat Lemon Blanket…']"), - recoverSecretPhrase - ); - - await driver.clickElement(byText('Recover my wallet')); - - // Check if window is close - assert.equal((await driver.getAllWindowHandles()).length, 1); - - try { - assert.notEqual( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'error' - ); - } catch (error) { - console.log(error); - assert.ok(error instanceof webdriverError.NoSuchWindowError); - } - }); - }); -}); diff --git a/e2e/tests/popup/connect-account/connect-account-flow.test.ts b/e2e/tests/popup/connect-account/connect-account-flow.test.ts deleted file mode 100644 index 7e9f6ae35..000000000 --- a/e2e/tests/popup/connect-account/connect-account-flow.test.ts +++ /dev/null @@ -1,191 +0,0 @@ -import { strict as assert } from 'assert'; - -import { Driver } from '../../../webdriver/driver'; -import { buildWebDriver } from '../../../webdriver'; -import { AppRoutes } from '../../../app-routes'; -import { - clickButtonToOpenExtensionWindowAndFocus, - unlockVault, - createAccount, - lockVault, - openConnectedSitePage -} from '../../common'; -import { byText, getUrlPath } from '../../../utils/helpers'; -import { ACCOUNT_NAMES, PLAYGROUND_URL, TIMEOUT } from '../../../constants'; - -describe.each([ - { - testName: 'account', - selectAllAccounts: false, - createdAccountName: ACCOUNT_NAMES.createdAccountName, - defaultAccountName: ACCOUNT_NAMES.defaultAccountName - }, - { - testName: 'two accounts', - selectAllAccounts: true, - createdAccountName: ACCOUNT_NAMES.createdAccountName, - defaultAccountName: ACCOUNT_NAMES.defaultAccountName - } -])( - `Popup UI: Connect $testName`, - ({ selectAllAccounts, defaultAccountName, createdAccountName, testName }) => { - let driver: Driver; - // Store the ID of the original window - let playgroundWindow: string; - - beforeAll(async () => { - driver = await buildWebDriver(); - - await driver.navigate(AppRoutes.Popup); - - await unlockVault(driver); - await driver.findElement(byText(ACCOUNT_NAMES.defaultAccountName)); - - if (selectAllAccounts) { - await createAccount(driver, createdAccountName); - } - - // For now, we disabled this test for Firefox. It failed all the time on CI - if (driver.browser !== 'firefox') { - await lockVault(driver); - } - - await driver.get(PLAYGROUND_URL); - - playgroundWindow = await driver.getWindowHandle(); - }); - - afterAll(async () => { - await driver.quit(); - }); - - it('should open connect account window and unlock vault', async () => { - await clickButtonToOpenExtensionWindowAndFocus( - driver, - playgroundWindow, - 'Connect' - ); - - // For now, we disabled this test for Firefox. It failed all the time on CI - if (driver.browser !== 'firefox') { - await unlockVault(driver); - } - - assert.ok( - await driver.isElementPresent( - byText('Connect with Casper Wallet Playground'), - 'Connect with Casper Wallet Playground', - TIMEOUT['50sec'] - ), - `Wallet still locked` - ); - }); - - it(`should select ${testName} and navigate to the next page`, async () => { - if (selectAllAccounts) { - await driver.clickElement(byText('select all')).catch(async () => { - await driver.verboseReportOnFailure( - `Failed on - ${testName}/select all` - ); - }); - } else { - await driver - .clickElement(byText(defaultAccountName)) - .catch(async () => { - await driver.verboseReportOnFailure( - `Failed on - ${testName}/one account` - ); - }); - } - - await driver.clickElement(byText('Next')); - - assert.ok( - await driver.isElementPresent( - byText( - selectAllAccounts ? 'Connect to 2 accounts' : 'Connect to 1 account' - ), - selectAllAccounts ? 'Connect to 2 accounts' : 'Connect to 1 account' - ) - ); - }); - - it(`should connect the ${ - selectAllAccounts ? 'accounts' : 'account' - } and close the window`, async () => { - await driver.clickElement( - byText( - selectAllAccounts ? 'Connect to 2 accounts' : 'Connect to 1 account' - ) - ); - - // Wait for connecting - await driver.wait( - async () => (await driver.getAllWindowHandles()).length === 1, - TIMEOUT['15sec'] - ); - - // Check if there is one window open - assert.equal((await driver.getAllWindowHandles()).length, 1); - }); - - it('should open connected site page', async () => { - await driver.switchToWindow(playgroundWindow); - - await openConnectedSitePage(driver); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'connected-sites' - ); - }); - - it(`should find the ${ - selectAllAccounts ? 'accounts' : 'account' - } that connected to the site`, async () => { - if (selectAllAccounts) { - assert.ok( - await driver.isElementPresent(byText(createdAccountName)), - `Can't find - ${createdAccountName}` - ); - assert.ok( - await driver.isElementPresent(byText(defaultAccountName)), - `Can't find - ${defaultAccountName}` - ); - } else { - assert.ok( - await driver.isElementPresent(byText(defaultAccountName)), - `Can't find - ${defaultAccountName}` - ); - assert.equal( - await driver.isElementPresent(byText(createdAccountName)), - false, - `Found - ${createdAccountName}, but shouldn't` - ); - } - }); - - it.each([ - { - describe: 'connected site title', - expectedElement: 'Casper Wallet Playground' - }, - { - describe: 'connected site URL', - expectedElement: 'casper-wallet-playground.make.services' - }, - { - describe: 'disconnect button', - expectedElement: 'Disconnect' - } - ])( - 'should find the $describe on the connected site list', - async ({ expectedElement }) => { - assert.ok( - await driver.isElementPresent(byText(expectedElement)), - `Can't find - ${expectedElement}` - ); - } - ); - } -); diff --git a/e2e/tests/popup/disconnect-account/disconnect-account-flow.test.ts b/e2e/tests/popup/disconnect-account/disconnect-account-flow.test.ts deleted file mode 100644 index 0b588b849..000000000 --- a/e2e/tests/popup/disconnect-account/disconnect-account-flow.test.ts +++ /dev/null @@ -1,90 +0,0 @@ -import { strict as assert } from 'assert'; - -import { Driver } from '../../../webdriver/driver'; -import { buildWebDriver } from '../../../webdriver'; -import { AppRoutes } from '../../../app-routes'; -import { - createAccount, - unlockVault, - openConnectedSitePage, - connectAccount -} from '../../common'; -import { byTestId, byText } from '../../../utils/helpers'; -import { ACCOUNT_NAMES, PLAYGROUND_URL } from '../../../constants'; - -describe('Popup UI: Disconnect account', () => { - let driver: Driver; - // Store the ID of the original window - let playgroundWindow: string; - - beforeEach(async () => { - driver = await buildWebDriver(); - - await driver.navigate(AppRoutes.Popup); - - await unlockVault(driver); - await createAccount(driver, ACCOUNT_NAMES.createdAccountName); - - await driver.get(PLAYGROUND_URL); - playgroundWindow = await driver.getWindowHandle(); - - await connectAccount({ - driver, - currentWindow: playgroundWindow, - connectAllAccounts: true - }); - - await driver.switchToWindow(playgroundWindow); - }); - - afterEach(async () => { - await driver.quit(); - }); - - it('should click the disconnect button on dapp and disconnect all accounts from the site', async () => { - await driver.clickElement(byText('Disconnect')); - - await openConnectedSitePage(driver); - - const areAnyAccountsConnected = await driver.areElementsPresent( - byTestId('account-name') - ); - - assert.equal(areAnyAccountsConnected, false); - assert.ok( - await driver.isElementPresent(byText('No connected sites yet')), - "Can't find - No connected sites yet" - ); - }); - - it.each([ - { - describe: 'one account', - disconnectButton: byTestId('disconnect-account-icon'), - areElementsExpected: true, - expectedElement: ACCOUNT_NAMES.createdAccountName - }, - { - describe: 'all accounts', - disconnectButton: byText('Disconnect'), - areElementsExpected: false, - expectedElement: 'No connected sites yet' - } - ])( - 'should click the disconnect button on connecting site page and disconnect $describe from the site', - async ({ disconnectButton, areElementsExpected, expectedElement }) => { - await openConnectedSitePage(driver); - await driver.clickElement(disconnectButton); - - const areAccountsPresent = await driver.areElementsPresent( - byTestId('account-name') - ); - - assert.equal(areAccountsPresent, areElementsExpected); - assert.ok( - await driver.isElementPresent(byText(expectedElement)), - `Can't find - ${expectedElement}` - ); - } - ); -}); diff --git a/e2e/tests/popup/import-account-with-file-flow/import-account-with-file-flow.test.ts b/e2e/tests/popup/import-account-with-file-flow/import-account-with-file-flow.test.ts deleted file mode 100644 index 5b9bb9e49..000000000 --- a/e2e/tests/popup/import-account-with-file-flow/import-account-with-file-flow.test.ts +++ /dev/null @@ -1,113 +0,0 @@ -import { strict as assert } from 'assert'; - -import { Driver } from '../../../webdriver/driver'; -import { buildWebDriver } from '../../../webdriver'; -import { AppRoutes } from '../../../app-routes'; -import { secretKeyPath } from '../../../__fixtures'; -import { - clickButtonToOpenExtensionWindowAndFocus, - unlockVault -} from '../../common'; -import { - byText, - byTestId, - getUrlPath, - byInputName -} from '../../../utils/helpers'; -import { IMPORTED_ACCOUNT } from '../../../constants'; - -describe('Popup UI: Import account with file', () => { - let driver: Driver; - // Store the ID of the original window - let popupWindow: string; - - beforeAll(async () => { - driver = await buildWebDriver(); - - await driver.navigate(AppRoutes.Popup); - await unlockVault(driver); - }); - - afterAll(async () => { - await driver.quit(); - }); - - it('should open navigation menu', async () => { - await driver.clickElement(byTestId('menu-open-icon')); - - assert.ok( - await driver.isElementPresent(byText('Import account')), - "Can't find - Import account" - ); - }); - - it('should open import account window', async () => { - popupWindow = await driver.getWindowHandle(); - - await clickButtonToOpenExtensionWindowAndFocus( - driver, - popupWindow, - 'Import account' - ); - - assert.ok( - driver.isElementPresent(byText('Import account from secret key file')), - "Can't find - Import account from secret key file" - ); - }); - - it('should upload the file and fill the account name', async () => { - await driver.clickElement(byText('Upload your file')); - - const fileInput = await driver.findElement(byInputName('secretKeyFile')); - const accountNameInput = await driver.findElement(byInputName('name')); - const importButton = await driver.findElement(byText('Import')); - - await fileInput.fill(secretKeyPath); - await accountNameInput.fill(IMPORTED_ACCOUNT.accountName); - - assert.ok(importButton.isEnabled()); - }); - - it('should import successfully and close the import account window', async () => { - await driver.clickElement(byText('Import')); - - await driver.clickElement(byText('Done')); - - assert.equal((await driver.getAllWindowHandles()).length, 1); - }); - - it('should open account list page', async () => { - await driver.switchToWindow(popupWindow); - - await driver.clickElement(byText('Switch account')); - - assert.equal( - await driver.driver.getCurrentUrl().then(getUrlPath), - 'account-list' - ); - }); - - it.each([ - { - describe: 'imported account name', - expectedElement: IMPORTED_ACCOUNT.accountName - }, - { - describe: 'truncated public key of the imported account', - expectedElement: IMPORTED_ACCOUNT.truncatedPublicKey - }, - { - describe: 'imported tag', - expectedElement: 'Imported' - } - ])( - 'should find the $describe on the accounts list', - async ({ expectedElement }) => { - assert.ok( - await driver.isElementPresent(byText(expectedElement), expectedElement), - `Can't find - ${expectedElement}` - ); - } - ); -}); diff --git a/e2e/tests/popup/signature-request-scenarios/signature-request-scenarios.test.ts b/e2e/tests/popup/signature-request-scenarios/signature-request-scenarios.test.ts deleted file mode 100644 index 234f7a849..000000000 --- a/e2e/tests/popup/signature-request-scenarios/signature-request-scenarios.test.ts +++ /dev/null @@ -1,154 +0,0 @@ -import { until } from 'selenium-webdriver'; -import { strict as assert } from 'assert'; - -import { Driver } from '../../../webdriver/driver'; -import { buildWebDriver } from '../../../webdriver'; -import { - clickButtonToOpenExtensionWindowAndFocus, - connectAccount -} from '../../common'; -import { DEFAULT_ACCOUNT, PLAYGROUND_URL } from '../../../constants'; -import { byText } from '../../../utils/helpers'; - -describe('Popup UI: Signature request scenarios', () => { - let driver: Driver; - // Store the ID of the original window - let playgroundWindow: string; - - beforeAll(async () => { - driver = await buildWebDriver(); - - await driver.get(PLAYGROUND_URL); - playgroundWindow = await driver.getWindowHandle(); - - await connectAccount({ - driver, - currentWindow: playgroundWindow, - connectAllAccounts: false - }); - - await driver.switchToWindow(playgroundWindow); - }); - - afterAll(async () => { - await driver.quit(); - }); - - describe.each([ - { - describe: 'transfer', - clickElement: 'Transfer', - deployType: 'Transfer Call', - clickOpenArgumentsElement: 'Transfer Data', - contractArguments: { - 'Recipient (Key)': DEFAULT_ACCOUNT.truncatedPublicKey, - Amount: '2.5 CSPR', - 'Transfer ID': '1234' - } - }, - { - describe: 'delegate', - clickElement: 'Delegate', - deployType: 'Contract Call', - entryPoint: 'delegate', - clickOpenArgumentsElement: 'Contract arguments', - contractArguments: { - Delegator: DEFAULT_ACCOUNT.truncatedPublicKey, - Validator: '0106c...ca2ca', - Amount: '2.5 CSPR' - } - }, - { - describe: 'undelegate', - clickElement: 'Undelegate', - deployType: 'Contract Call', - entryPoint: 'undelegate', - clickOpenArgumentsElement: 'Contract arguments', - contractArguments: { - Delegator: DEFAULT_ACCOUNT.truncatedPublicKey, - Validator: '0106c...ca2ca', - Amount: '2.5 CSPR' - } - }, - { - describe: 'redelegate', - clickElement: 'Redelegate', - deployType: 'Contract Call', - entryPoint: 'redelegate', - clickOpenArgumentsElement: 'Contract arguments', - contractArguments: { - Delegator: DEFAULT_ACCOUNT.truncatedPublicKey, - Validator: '0106c...ca2ca', - Amount: '2.5 CSPR', - 'New validator': '017d9...2009e' - } - } - ])( - 'should sign the $describe request', - ({ - clickElement, - deployType, - entryPoint, - contractArguments, - clickOpenArgumentsElement, - describe - }) => { - it(`should click the ${describe} button on dapp and open signature request window`, async () => { - await clickButtonToOpenExtensionWindowAndFocus( - driver, - playgroundWindow, - clickElement - ); - - assert.ok( - await driver.isElementPresent(byText('Signature Request')), - "Can't find - Signature Request" - ); - }); - - it('should find signature request data', async () => { - await driver.clickElement(byText(clickOpenArgumentsElement)); - - assert.ok( - await driver.isElementPresent(byText(deployType)), - `Can't find - ${deployType}` - ); - - if (entryPoint) { - assert.ok( - await driver.isElementPresent(byText(entryPoint)), - `Can't find - ${entryPoint}` - ); - } - - for (const [key, value] of Object.entries(contractArguments)) { - assert.ok( - await driver.isElementPresent(byText(key)), - `Can't find - ${key}` - ); - assert.ok( - await driver.isElementPresent(byText(value)), - `Can't find - ${value}` - ); - } - }); - - it(`should successfully sign the ${describe} request`, async () => { - await driver.clickElement(byText('Sign')); - - await driver.switchToWindow(playgroundWindow); - - // Wait for the alert to be displayed - await driver.wait(until.alertIsPresent()); - - // Store the alert in a variable - const alert = await driver.driver.switchTo().alert(); - - const alertText = await alert.getText(); - - assert.match(alertText, /Sign successful/); - await alert.accept(); - }); - } - ); -}); diff --git a/e2e/tsconfig.json b/e2e/tsconfig.json deleted file mode 100644 index e929a5894..000000000 --- a/e2e/tsconfig.json +++ /dev/null @@ -1,14 +0,0 @@ -{ - "compilerOptions": { - "target": "esnext", - "module": "commonjs", - "allowJs": true, - "esModuleInterop": true, - "allowSyntheticDefaultImports": true, - "strict": true, - "isolatedModules": true, - "resolveJsonModule": true, - "noEmit": true, - "baseUrl": "." - }, -} diff --git a/e2e/utils/helpers.ts b/e2e/utils/helpers.ts deleted file mode 100644 index b6a83301c..000000000 --- a/e2e/utils/helpers.ts +++ /dev/null @@ -1,14 +0,0 @@ -import { By } from 'selenium-webdriver'; - -export const getUrlPath = (url: string) => url.split('#/')[1]; - -export const byText = (text: string) => By.xpath(`//*[text()='${text}']`); - -export const byTestId = (dataTestId: string) => - By.xpath(`//*[@data-testid='${dataTestId}']`); - -export const byInputName = (name: string) => - By.xpath(`//input[@name='${name}']`); - -export const byButtonText = (text: string) => - By.xpath(`//button[text()='${text}']`); diff --git a/e2e/webdriver/WebElementWithAPI.ts b/e2e/webdriver/WebElementWithAPI.ts deleted file mode 100644 index 53b6fb62e..000000000 --- a/e2e/webdriver/WebElementWithAPI.ts +++ /dev/null @@ -1,41 +0,0 @@ -import { until, WebElement } from 'selenium-webdriver'; - -import { IWebElementWithAPI, Key } from './types'; -import { Driver } from './driver'; -import { ElementState } from './constants'; - -export class WebElementWithAPI - extends WebElement - implements IWebElementWithAPI -{ - element: WebElement; - driver: Driver; - - constructor(driver: Driver, element: WebElement) { - super(driver.driver, element.getId()); - this.driver = driver; - this.element = element; - } - - async press(key: Key): Promise { - return this.element.sendKeys(key); - } - async fill(input: Key): Promise { - await this.element.clear(); - await this.element.sendKeys(input); - } - async waitForElementState(state: string, timeout: number): Promise { - switch (state) { - case ElementState.Hidden: - // @ts-ignore TODO: clarify Condition case here - return await driver.wait(until.stalenessOf(element), timeout); - case ElementState.Visible: - return await this.driver.wait( - until.elementIsVisible(this.element), - timeout - ); - default: - throw new Error(`Provided state: '${state}' is not supported`); - } - } -} diff --git a/e2e/webdriver/chrome.ts b/e2e/webdriver/chrome.ts deleted file mode 100644 index 0f331c05f..000000000 --- a/e2e/webdriver/chrome.ts +++ /dev/null @@ -1,99 +0,0 @@ -import * as chrome from 'selenium-webdriver/chrome'; -import { Builder, ThenableWebDriver, Browser } from 'selenium-webdriver'; -import remote from 'selenium-webdriver/remote'; - -import { WebDriverObject } from './types'; -import { extensionName } from '../../constants'; -import { SeleniumPort } from './constants'; - -export class ChromeDriver { - _driver: ThenableWebDriver; - - static async build( - port: number | undefined, - headless: boolean, - seleniumHost: string, - seleniumPort?: string - ): Promise { - const options = new chrome.Options(); - - // Allow Selenium to use Chrome's clipboard for tests - // options.setUserPreferences({ - // profile: { - // content_settings: { - // exceptions: { - // clipboard: { - // '[*.],*': { - // expiration: '0', - // last_modified: Date.now(), - // model: 0, - // setting: 1 - // } - // } - // } - // } - // } - // }); - options.addExtensions('chrome.crx'); - options.setAcceptInsecureCerts(true); - - const builder = new Builder() - .forBrowser(Browser.CHROME) - .setChromeOptions(options); - - if (headless) { - builder.usingServer( - `http://${seleniumHost}:${seleniumPort || SeleniumPort.Chrome}/` - ); - } - - const service = new chrome.ServiceBuilder(); - - // Enables Chrome logging. Default: enabled - // Especially useful for discovering why Chrome has crashed, but can also - // be useful for revealing console errors (from the page or background). - if (process.env.ENABLE_CHROME_LOGGING !== 'false') { - // @ts-ignore - service.setStdio('inherit').enableChromeLogging(); - } - if (port) { - service.setPort(port); - } - builder.setChromeService(service); - - const driver = builder.build(); - const chromeDriver = new ChromeDriver(driver); - const extensionId = await chromeDriver.getExtensionIdByName(extensionName); - driver.setFileDetector(new remote.FileDetector()); - - return { - driver, - extensionUrl: `chrome-extension://${extensionId}` - }; - } - - constructor(driver: ThenableWebDriver) { - this._driver = driver; - } - - async getExtensionIdByName( - extensionName: string - ): Promise { - await this._driver.get('chrome://extensions'); - return await this._driver.executeScript(` - const extensions = document.querySelector("extensions-manager").shadowRoot - .querySelector("extensions-item-list").shadowRoot - .querySelectorAll("extensions-item") - - for (let i = 0; i < extensions.length; i++) { - const extension = extensions[i].shadowRoot - const name = extension.querySelector('#name').textContent - if (name === "${extensionName}") { - return extensions[i].getAttribute("id") - } - } - - return undefined - `); - } -} diff --git a/e2e/webdriver/constants.ts b/e2e/webdriver/constants.ts deleted file mode 100644 index 3f1ecb252..000000000 --- a/e2e/webdriver/constants.ts +++ /dev/null @@ -1,10 +0,0 @@ -export enum ElementState { - Visible = 'visible', - Detached = 'detached', - Hidden = 'hidden' -} - -export enum SeleniumPort { - Chrome = 4444, - Firefox = 4445 -} diff --git a/e2e/webdriver/driver.ts b/e2e/webdriver/driver.ts deleted file mode 100644 index fed79c573..000000000 --- a/e2e/webdriver/driver.ts +++ /dev/null @@ -1,446 +0,0 @@ -import { promises as fs } from 'fs'; -import { strict as assert } from 'assert'; -import { - error as webdriverError, - ThenableWebDriver, - WebElement, - until, - By, - Condition, - WebDriver -} from 'selenium-webdriver'; -// @ts-ignore TODO: clarify types for package -import cssToXPath from 'css-to-xpath'; - -import { WebElementWithAPI } from './WebElementWithAPI'; - -import { DriverKey, PerformanceResults, RawLocator } from './types'; -import { ElementState } from './constants'; -import { TIMEOUT } from '../constants'; - -function wrapElementWithAPI( - element: WebElement, - driver: Driver -): WebElementWithAPI { - return new WebElementWithAPI(driver, element); -} - -/** - * For Selenium WebDriver API documentation, see: - * https://www.selenium.dev/selenium/docs/api/javascript/module/selenium-webdriver/index_exports_WebDriver.html - */ -export class Driver { - driver: ThenableWebDriver; - browser: string; - extensionUrl: string; - timeout: number; - - static Key: DriverKey; - static PAGES = { - POPUP: 'popup' - }; - - constructor( - driver: ThenableWebDriver, - browser: string, - extensionUrl: string, - timeout = 15000 - ) { - this.driver = driver; - this.browser = browser; - this.extensionUrl = extensionUrl; - this.timeout = timeout; - // The following values are found in - // https://github.com/SeleniumHQ/selenium/blob/trunk/javascript/node/selenium-webdriver/lib/input.js#L50-L110 - // These should be replaced with string constants 'Enter' etc for playwright. - Driver.Key = { - BACK_SPACE: '\uE003', - ENTER: '\uE007' - }; - } - - async executeAsyncScript(script: string, ...args: string[]) { - return this.driver.executeAsyncScript(script, args); - } - - async executeScript(script: string, ...args: string[]) { - return this.driver.executeScript(script, args); - } - - buildLocator(locator: RawLocator): By { - if (typeof locator === 'string') { - return By.css(locator); - } else if (locator.value) { - return locator as By; - } else if (locator.xpath) { - return By.xpath(locator.xpath); - } else if (locator.text) { - if (locator.css) { - const xpath = cssToXPath - .parse(locator.css) - .where( - cssToXPath.xPathBuilder - .string() - .contains(locator.text) - .or( - cssToXPath.xPathBuilder - .string() - .contains(locator.text.split(' ').join('')) - ) - ) - .toXPath(); - return By.xpath(xpath); - } - return By.xpath( - `//${locator.tag ?? '*'}[contains(text(), '${locator.text}')]` - ); - } - throw new Error( - `The locator '${locator}' is not supported by the E2E test driver` - ); - } - - async get(url: string) { - await this.driver.get(url); - } - - async fill(rawLocator: RawLocator, input: string) { - const element = await this.findElement(rawLocator); - await element.fill(input); - return element; - } - - async press(rawLocator: RawLocator, keys: string) { - const element = await this.findElement(rawLocator); - await element.press(keys); - return element; - } - - async delay(time: number) { - await new Promise(resolve => setTimeout(resolve, time)); - } - - async wait( - condition: - | PromiseLike - | Condition - | ((driver: WebDriver) => T | PromiseLike) - | Function, - timeout = this.timeout - ) { - return await this.driver.wait(condition, timeout); - } - - async waitForSelector( - rawLocator: RawLocator, - { timeout = this.timeout, state = ElementState.Visible } = {} - ) { - const selector = this.buildLocator(rawLocator); - let element; - if (![ElementState.Visible, ElementState.Detached].includes(state)) { - throw new Error(`Provided state selector ${state} is not supported`); - } - if (state === ElementState.Visible) { - element = await this.driver.wait(until.elementLocated(selector), timeout); - } else if (state === ElementState.Detached) { - element = await this.driver.wait( - until.stalenessOf(await this.findElement(selector)), - timeout - ); - } - return wrapElementWithAPI(element as WebElement, this); - } - - async quit() { - await this.driver.quit(); - } - - // Element interactions - - async findElement(rawLocator: RawLocator, timeout?: number) { - const locator = this.buildLocator(rawLocator); - const element = await this.driver.wait( - until.elementLocated(locator), - timeout || this.timeout - ); - return wrapElementWithAPI(element, this); - } - - async findVisibleElement(rawLocator: string) { - const locator = this.buildLocator(rawLocator); - const element = await this.findElement(locator); - await this.driver.wait(until.elementIsVisible(element), this.timeout); - return wrapElementWithAPI(element, this); - } - - async findClickableElement(rawLocator: RawLocator) { - const locator = this.buildLocator(rawLocator); - const element = await this.findElement(locator); - await Promise.all([ - this.driver.wait(until.elementIsVisible(element), this.timeout), - this.driver.wait(until.elementIsEnabled(element), this.timeout) - ]); - return wrapElementWithAPI(element, this); - } - - async findElements(rawLocator: RawLocator) { - const locator = this.buildLocator(rawLocator); - const elements = await this.driver.wait( - until.elementsLocated(locator), - this.timeout - ); - return elements.map(element => wrapElementWithAPI(element, this)); - } - - async findClickableElements(rawLocator: RawLocator) { - const locator = this.buildLocator(rawLocator); - const elements = await this.findElements(locator); - await Promise.all( - elements.reduce((acc, element) => { - acc.push( - // @ts-ignore - this.driver.wait(until.elementIsVisible(element), this.timeout), - this.driver.wait(until.elementIsEnabled(element), this.timeout) - ); - return acc; - }, []) - ); - return elements.map(element => wrapElementWithAPI(element, this)); - } - - async clickElement(rawLocator: RawLocator) { - const locator = this.buildLocator(rawLocator); - const element = await this.findClickableElement(locator); - await element.click(); - } - - async clickPoint(rawLocator: RawLocator, x: number, y: number) { - const locator = this.buildLocator(rawLocator); - const element = await this.findElement(locator); - await this.driver - .actions() - .move({ origin: element, x, y }) - .click() - .perform(); - } - - async scrollToElement(element: WebElement) { - await this.driver.executeScript( - 'arguments[0].scrollIntoView(true)', - element - ); - } - - async assertElementNotPresent(rawLocator: RawLocator) { - const locator = this.buildLocator(rawLocator); - let dataTab; - try { - dataTab = await this.findElement(locator); - } catch (err) { - assert( - err instanceof webdriverError.NoSuchElementError || - err instanceof webdriverError.TimeoutError - ); - } - assert.ok(!dataTab, 'Found element that should not be present'); - } - - async isElementPresent( - locatorKey: By, - elementName?: string, - timeout?: TIMEOUT - ) { - try { - return Boolean( - await this.wait( - until.elementLocated(locatorKey), - timeout || this.timeout - ) - ); - } catch (e) { - if (elementName) { - await this.verboseReportOnFailure( - `Can't find element - ${elementName}` - ); - } - - return false; - } - } - - async areElementsPresent(locatorKey: By) { - const elements = await this.wait( - () => this.driver.findElements(locatorKey), - TIMEOUT['15sec'] - ); - - return elements.length > 0; - } - - // Navigation - - async navigate(page = Driver.PAGES.POPUP) { - return await this.driver.get(`${this.extensionUrl}/${page}.html`); - } - - // Metrics - - async collectMetrics() { - return await this.driver.executeScript(collectMetrics); - } - - // Window management - - async openNewPage(url: string) { - const newHandle = await this.driver.switchTo().newWindow(''); - await this.driver.get(url); - return newHandle; - } - - async switchToWindow(handle: string) { - await this.driver.switchTo().window(handle); - } - - // https://www.selenium.dev/documentation/webdriver/interactions/windows/#create-new-window-or-new-tab-and-switch - async createNewWindowOrTabAndSwitch(handle: 'tab' | 'window') { - // Opens a new tab/window and switches to new tab/window - await this.driver.switchTo().newWindow(handle); - } - - // Get the window handles of the all windows - async getAllWindowHandles() { - return await this.driver.getAllWindowHandles(); - } - - // Get the window handle of the current window - async getWindowHandle() { - return await this.driver.getWindowHandle(); - } - - async waitUntilXWindowHandles(x: number, delayStep = 1000, timeout = 5000) { - let timeElapsed = 0; - let windowHandles = []; - while (timeElapsed <= timeout) { - windowHandles = await this.driver.getAllWindowHandles(); - if (windowHandles.length === x) { - return windowHandles; - } - await this.delay(delayStep); - timeElapsed += delayStep; - } - throw new Error('waitUntilXWindowHandles timed out polling window handles'); - } - - async switchToWindowWithTitle( - title: string, - initialWindowHandles: string, - delayStep = 1000, - timeout = 5000 - ) { - let windowHandles = - initialWindowHandles || (await this.driver.getAllWindowHandles()); - let timeElapsed = 0; - while (timeElapsed <= timeout) { - for (const handle of windowHandles) { - await this.driver.switchTo().window(handle); - const handleTitle = await this.driver.getTitle(); - if (handleTitle === title) { - return handle; - } - } - await this.delay(delayStep); - timeElapsed += delayStep; - // refresh the window handles - windowHandles = await this.driver.getAllWindowHandles(); - } - - throw new Error(`No window with title: ${title}`); - } - - async closeAllWindowHandlesExcept( - exceptions: string[], - windowHandles: string[] - ): Promise { - // eslint-disable-next-line no-param-reassign - windowHandles = windowHandles || (await this.driver.getAllWindowHandles()); - - for (const handle of windowHandles) { - if (!exceptions.includes(handle)) { - await this.driver.switchTo().window(handle); - await this.delay(1000); - await this.driver.close(); - await this.delay(1000); - } - } - } - - // Error handling - - async verboseReportOnFailure(title: string) { - const artifactDir = `./test-artifacts/${this.browser}/${title}`; - const filepathBase = `${artifactDir}/test-failure`; - await fs.mkdir(artifactDir, { recursive: true }); - const screenshot = await this.driver.takeScreenshot(); - await fs.writeFile(`${filepathBase}-screenshot.png`, screenshot, { - encoding: 'base64' - }); - const htmlSource = await this.driver.getPageSource(); - await fs.writeFile(`${filepathBase}-dom.html`, htmlSource); - const uiState = await this.driver.executeScript( - // @ts-ignore TODO: modify `window` in global.d.ts - () => window.getCleanAppState && window.getCleanAppState() - ); - await fs.writeFile( - `${filepathBase}-state.json`, - JSON.stringify(uiState, null, 2) - ); - } - - async checkBrowserForConsoleErrors() { - const ignoredLogTypes = ['WARNING']; - const ignoredErrorMessages = [ - // Third-party Favicon 404s show up as errors - 'favicon.ico - Failed to load resource: the server responded with a status of 404 (Not Found)', - // Sentry rate limiting - 'Failed to load resource: the server responded with a status of 429', - // 4Byte - 'Failed to load resource: the server responded with a status of 502 (Bad Gateway)' - ]; - const browserLogs = await this.driver.manage().logs().get('browser'); - const errorEntries = browserLogs.filter( - entry => !ignoredLogTypes.includes(entry.level.toString()) - ); - const errorObjects = errorEntries.map(entry => entry.toJSON()); - return errorObjects.filter( - entry => - !ignoredErrorMessages.some(message => entry.message.includes(message)) - ); - } -} - -function collectMetrics() { - const results: PerformanceResults = { - paint: {}, - navigation: [] - }; - - window.performance - .getEntriesByType('paint') - .forEach(({ name, startTime }: PerformanceEntry) => { - results.paint[name] = startTime; - }); - window.performance - .getEntriesByType('navigation') - // @ts-ignore TODO: remote ts-ignore directive - .forEach((navigationEntry: PerformanceNavigationTiming) => { - results.navigation.push({ - domContentLoaded: navigationEntry.domContentLoadedEventEnd, - load: navigationEntry.loadEventEnd, - domInteractive: navigationEntry.domInteractive, - redirectCount: navigationEntry.redirectCount, - type: navigationEntry.type - }); - }); - - return results; -} diff --git a/e2e/webdriver/firefox.ts b/e2e/webdriver/firefox.ts deleted file mode 100644 index b9c3ecb41..000000000 --- a/e2e/webdriver/firefox.ts +++ /dev/null @@ -1,81 +0,0 @@ -import * as fs from 'fs'; -import * as os from 'os'; -import * as path from 'path'; -import * as firefox from 'selenium-webdriver/firefox'; -import { ThenableWebDriver, Browser } from 'selenium-webdriver'; -import { Builder, until, By } from 'selenium-webdriver'; -import remote from 'selenium-webdriver/remote'; - -import { WebDriverObject } from './types'; -import { ExtensionBuildPath } from '../../constants'; -import { SeleniumPort } from './constants'; - -const TEMP_PROFILE_PATH_PREFIX = path.join( - os.tmpdir(), - 'Casper-Signer-Profile' -); - -export class FirefoxDriver { - _driver: ThenableWebDriver; - - static async build( - port: number | undefined, - headless: boolean, - seleniumHost: string, - seleniumPort?: string - ): Promise { - const templateProfile = fs.mkdtempSync(TEMP_PROFILE_PATH_PREFIX); - const options = new firefox.Options().setProfile(templateProfile); - - options.setAcceptInsecureCerts(true); - options.setPreference('dom.events.asyncClipboard.read', true); - - const builder = new Builder() - .forBrowser(Browser.FIREFOX) - .setFirefoxOptions(options); - - if (port) { - const service = new firefox.ServiceBuilder().setPort(port); - builder.setFirefoxService(service); - } - - if (headless) { - builder.usingServer( - `http://${seleniumHost}:${seleniumPort || SeleniumPort.Firefox}/` - ); - } - - const driver = builder.build(); - const fxDriver = new FirefoxDriver(driver); - const extensionId = await fxDriver.installExtension( - ExtensionBuildPath.Firefox - ); - const internalExtensionId = await fxDriver.getInternalId(); - driver.setFileDetector(new remote.FileDetector()); - - return { - driver, - extensionId, - extensionUrl: `moz-extension://${internalExtensionId}` - }; - } - - constructor(driver: ThenableWebDriver) { - this._driver = driver; - } - - async installExtension(addonPath: string): Promise { - // @ts-ignore TODO: clarify firefox driver type - return await this._driver.installAddon(addonPath, true); - } - - async getInternalId() { - await this._driver.get('about:debugging#addons'); - return await this._driver - .wait( - until.elementLocated(By.xpath("//dl/div[contains(., 'UUID')]/dd")), - 1000 - ) - .getText(); - } -} diff --git a/e2e/webdriver/index.ts b/e2e/webdriver/index.ts deleted file mode 100644 index 0c7e84264..000000000 --- a/e2e/webdriver/index.ts +++ /dev/null @@ -1,58 +0,0 @@ -import { Browser } from 'selenium-webdriver'; -import { Driver } from './driver'; -import { ChromeDriver } from './chrome'; -import { FirefoxDriver } from './firefox'; - -import { BuildWebDriver, Browser as BrowserString } from './types'; - -export async function buildWebDriver( - buildWebDriver?: BuildWebDriver -): Promise { - const browser: BrowserString = - buildWebDriver?.browser || - (process.env.SELENIUM_BROWSER as BrowserString) || - 'chrome'; - const headless = !!process.env.SELENIUM_HEADLESS; - const seleniumHost = process.env.SELENIUM_HOST || 'localhost'; - const seleniumPort = process.env.SELENIUM_PORT; - - const { driver: seleniumDriver, extensionUrl } = await buildBrowserWebDriver({ - ...buildWebDriver, - browser, - headless, - seleniumHost, - seleniumPort - }); - - return new Driver(seleniumDriver, browser, extensionUrl); -} - -async function buildBrowserWebDriver({ - browser, - port, - headless, - seleniumHost, - seleniumPort -}: BuildWebDriver) { - switch (browser) { - case Browser.CHROME: { - return await ChromeDriver.build( - port, - headless, - seleniumHost, - seleniumPort - ); - } - case Browser.FIREFOX: { - return await FirefoxDriver.build( - port, - headless, - seleniumHost, - seleniumPort - ); - } - default: { - throw new Error(`Unrecognized browser: ${browser}`); - } - } -} diff --git a/e2e/webdriver/types.ts b/e2e/webdriver/types.ts deleted file mode 100644 index 641b02bf3..000000000 --- a/e2e/webdriver/types.ts +++ /dev/null @@ -1,55 +0,0 @@ -import { ThenableWebDriver, WebElement } from 'selenium-webdriver'; - -export type RawLocator = string | LocatorObject; -export type Key = string | number | Promise; -export type Browser = 'chrome' | 'firefox' | 'safari'; - -export interface BuildWebDriver { - port?: number; - browser: Browser; - headless: boolean; - seleniumHost: string; - seleniumPort?: string; -} - -export interface DriverKey { - BACK_SPACE: string; - ENTER: string; -} - -interface LocatorObject { - value?: string; - xpath?: string; - text?: string; - css?: string; - tag?: string; -} - -export interface WebDriverObject { - driver: ThenableWebDriver; - extensionUrl: string; - extensionId?: string; -} - -export interface IWebElementWithAPI extends WebElement { - fill: (input: Key) => Promise; - press: (key: Key) => Promise; - waitForElementState: (state: string, timeout: number) => Promise; -} - -// Metrics - -interface NavigationResult { - domContentLoaded: number; - load: number; - domInteractive: number; - redirectCount: number; - type: string; -} - -export interface PerformanceResults { - paint: { - [key: string]: number; - }; - navigation: NavigationResult[]; -} diff --git a/package-lock.json b/package-lock.json index 44235e29d..40886c620 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,17 +1,18 @@ { "name": "Casper Wallet", - "version": "1.7.0", + "version": "1.8.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "Casper Wallet", - "version": "1.7.0", + "version": "1.8.0", "dependencies": { "@formatjs/intl": "2.6.2", "@hookform/resolvers": "2.9.10", "@hot-loader/react-dom": "^17.0.1", "@lapo/asn1js": "1.2.4", + "@lottiefiles/react-lottie-player": "3.5.3", "@make-software/ces-js-parser": "1.3.2", "@noble/ciphers": "^0.3.0", "@scure/bip32": "1.3.2", @@ -22,7 +23,6 @@ "big.js": "^6.2.1", "casper-cep18-js-client": "1.0.2", "casper-js-sdk": "2.13.3", - "crx3": "^1.1.3", "date-fns": "^2.30.0", "facepaint": "^1.2.1", "i18next": "^23.5.1", @@ -35,13 +35,13 @@ "qrcode.react": "^3.1.0", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-hook-form": "7.40.0", + "react-hook-form": "7.48.2", "react-hot-loader": "4.13.1", "react-i18next": "12.0.0", "react-identicons": "^1.2.5", "react-infinite-scroll-hook": "^4.1.1", "react-inlinesvg": "^3.0.1", - "react-loading-skeleton": "^3.1.0", + "react-loading-skeleton": "^3.3.1", "react-player": "^2.13.0", "react-query": "^3.39.3", "react-redux": "8.0.5", @@ -58,6 +58,7 @@ "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/preset-env": "7.23.2", "@babel/preset-react": "7.18.6", + "@playwright/test": "^1.39.0", "@redux-devtools/cli": "^3.0.1", "@testing-library/dom": "8.19.0", "@testing-library/jest-dom": "^5.16.5", @@ -70,20 +71,18 @@ "@types/facepaint": "^1.2.3", "@types/jest": "29.2.3", "@types/lodash.throttle": "4.1.7", + "@types/node": "^20.9.0", "@types/react": "^17.0.33", "@types/react-dom": "^17.0.10", "@types/remote-redux-devtools": "^0.5.5", - "@types/selenium-webdriver": "4.1.9", "@types/styled-components": "^5.1.26", "@types/testing-library__react": "^10.2.0", "babel-eslint": "^10.1.0", "babel-loader": "9.1.0", "babel-preset-react-app": "^10.0.0", - "chromedriver": "^119.0.1", "concurrently": "7.6.0", "copy-webpack-plugin": "^11.0.0", "css-loader": "6.8.1", - "css-to-xpath": "^0.1.0", "eslint": "8.49.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^8.3.0", @@ -96,9 +95,8 @@ "eslint-plugin-react-hooks": "4.6.0", "file-loader": "^6.2.0", "fs-extra": "11.1.1", - "geckodriver": "4.2.1", "html-loader": "4.2.0", - "html-webpack-plugin": "^5.5.0", + "html-webpack-plugin": "^5.5.3", "husky": "8.0.2", "i18next-conv": "14.0.0", "jest": "29.3.1", @@ -106,9 +104,8 @@ "lint-staged": "14.0.1", "markdownlint": "0.26.2", "markdownlint-cli": "0.32.2", - "prettier": "3.0.3", + "prettier": "3.1.0", "remote-redux-devtools": "^0.5.16", - "selenium-webdriver": "4.10.0", "source-map-loader": "4.0.1", "style-loader": "^3.3.1", "terser-webpack-plugin": "5.3.6", @@ -118,7 +115,7 @@ "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "4.9.3", "url-loader": "^4.1.1", - "web-ext": "7.6.2", + "web-ext": "7.8.0", "webextension-polyfill": "0.10.0", "webpack": "5.88.2", "webpack-cli": "5.1.4", @@ -136,9 +133,9 @@ } }, "node_modules/@adobe/css-tools": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.0.1.tgz", - "integrity": "sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz", + "integrity": "sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==", "dev": true }, "node_modules/@ampproject/remapping": { @@ -2942,35 +2939,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/@eslint/eslintrc/node_modules/eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, - "node_modules/@eslint/eslintrc/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/@eslint/eslintrc/node_modules/globals": { "version": "13.21.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", @@ -2999,9 +2967,9 @@ } }, "node_modules/@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -3315,6 +3283,79 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "node_modules/@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "dependencies": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-regex?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "dependencies": { + "ansi-regex": "^6.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/strip-ansi?sponsor=1" + } + }, + "node_modules/@isaacs/cliui/node_modules/wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "dependencies": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + }, + "engines": { + "node": ">=12" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, "node_modules/@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -4225,6 +4266,17 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, + "node_modules/@lottiefiles/react-lottie-player": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@lottiefiles/react-lottie-player/-/react-lottie-player-3.5.3.tgz", + "integrity": "sha512-6pGbiTMjGnPddR1ur8M/TIDCiogZMc1aKIUbMEKXKAuNeYwZ2hvqwBJ+w5KRm88ccdcU88C2cGyLVsboFlSdVQ==", + "dependencies": { + "lottie-web": "^5.10.2" + }, + "peerDependencies": { + "react": "16 - 18" + } + }, "node_modules/@make-software/ces-js-parser": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@make-software/ces-js-parser/-/ces-js-parser-1.3.2.tgz", @@ -4272,9 +4324,9 @@ } }, "node_modules/@mdn/browser-compat-data": { - "version": "5.2.42", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.2.42.tgz", - "integrity": "sha512-CD/2ai1W45cDN/zN2AcYduDavU+nq9aStyQizi4MHxnwkRvS/H24WIjgc1qD8CISoqXa8AAIe+A+zpWxwV7a2Q==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.14.tgz", + "integrity": "sha512-Y9XQrphVcE6u9xMm+gIqN86opbU/5s2W1pdPyKRyFV5B7+2jWM2gLI5JpfhZncaoDKvhy6FYwK04aCz5UM/bTQ==", "dev": true }, "node_modules/@noble/ciphers": { @@ -4416,6 +4468,16 @@ "ws": "^7.0.0" } }, + "node_modules/@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true, + "engines": { + "node": ">=14" + } + }, "node_modules/@pkgr/utils": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", @@ -4472,6 +4534,21 @@ "integrity": "sha512-AEYxH93jGFPn/a2iVAwW87VuUIkR1FVUKB77NwMF7nBTDkDrrT/Hpt/IrCJ0QXhW27jTBDcf5ZY7w6RiqTMw2Q==", "dev": true }, + "node_modules/@playwright/test": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", + "dev": true, + "dependencies": { + "playwright": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/@pnpm/network.ca-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", @@ -5607,12 +5684,6 @@ "node": ">=10" } }, - "node_modules/@testim/chrome-version": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", - "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", - "dev": true - }, "node_modules/@testing-library/dom": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", @@ -6555,9 +6626,12 @@ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" }, "node_modules/@types/node": { - "version": "18.17.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.15.tgz", - "integrity": "sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==" + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "dependencies": { + "undici-types": "~5.26.4" + } }, "node_modules/@types/node-fetch": { "version": "2.6.4", @@ -6687,15 +6761,6 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, - "node_modules/@types/selenium-webdriver": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.1.9.tgz", - "integrity": "sha512-QNCYI3Rgjf3bZ2GZwXnUpOJUPR8p7+c9Um9MEKggLaUaF8UfjitH5aPCV1PF0DHVEiPYsXayGVS6+67DO3VILw==", - "dev": true, - "dependencies": { - "@types/ws": "*" - } - }, "node_modules/@types/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", @@ -7102,60 +7167,6 @@ "node": "^12.22.0 || ^14.17.0 || >=16.0.0" } }, - "node_modules/@wdio/logger": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.11.0.tgz", - "integrity": "sha512-IsuKSaYi7NKEdgA57h8muzlN/MVp1dQG+V4C//7g4m03YJUnNQLvDhJzLjdeNTfvZy61U7foQSyt+3ktNzZkXA==", - "dev": true, - "dependencies": { - "chalk": "^5.1.2", - "loglevel": "^1.6.0", - "loglevel-plugin-prefix": "^0.8.4", - "strip-ansi": "^7.1.0" - }, - "engines": { - "node": "^16.13 || >=18" - } - }, - "node_modules/@wdio/logger/node_modules/ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/ansi-regex?sponsor=1" - } - }, - "node_modules/@wdio/logger/node_modules/chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true, - "engines": { - "node": "^12.17.0 || ^14.13 || >=16.0.0" - }, - "funding": { - "url": "https://github.com/chalk/chalk?sponsor=1" - } - }, - "node_modules/@wdio/logger/node_modules/strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "dependencies": { - "ansi-regex": "^6.0.1" - }, - "engines": { - "node": ">=12" - }, - "funding": { - "url": "https://github.com/chalk/strip-ansi?sponsor=1" - } - }, "node_modules/@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -7445,55 +7456,55 @@ } }, "node_modules/addons-linter": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-5.32.0.tgz", - "integrity": "sha512-Lf6oOyw8X9z5BMd9xhQwSbPlN2PUlzDLnYLAVT5lkrgXEx0fO9hRk4JRxWZ8+rFGz+mCIA2TTClZF2f+MKgJQA==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.13.0.tgz", + "integrity": "sha512-vYgDXl8aLmN1zU4HmsQdG6tUFByg499mHnTEMWDUbSkoYDq3koTne08EsqU6sD+o814u8FxclQP7580L0g/tPQ==", "dev": true, "dependencies": { "@fluent/syntax": "0.19.0", - "@mdn/browser-compat-data": "5.2.42", + "@mdn/browser-compat-data": "5.3.14", "addons-moz-compare": "1.3.0", - "addons-scanner-utils": "8.5.0", + "addons-scanner-utils": "9.3.0", "ajv": "8.12.0", "chalk": "4.1.2", "cheerio": "1.0.0-rc.12", "columnify": "1.6.0", "common-tags": "1.8.2", "deepmerge": "4.3.1", - "eslint": "8.36.0", + "eslint": "8.48.0", "eslint-plugin-no-unsanitized": "4.0.2", - "eslint-visitor-keys": "3.3.0", - "espree": "9.5.0", + "eslint-visitor-keys": "3.4.3", + "espree": "9.6.1", "esprima": "4.0.1", "fast-json-patch": "3.1.1", - "glob": "9.3.0", + "glob": "10.3.4", "image-size": "1.0.2", "is-mergeable-object": "1.1.1", "jed": "1.1.1", "json-merge-patch": "1.0.2", "os-locale": "5.0.0", - "pino": "8.11.0", - "postcss": "8.4.21", + "pino": "8.15.0", + "postcss": "8.4.29", "relaxed-json": "1.0.3", - "semver": "7.3.8", + "semver": "7.5.4", "sha.js": "2.4.11", "source-map-support": "0.5.21", "tosource": "1.0.0", "upath": "2.0.1", - "yargs": "17.7.1", + "yargs": "17.7.2", "yauzl": "2.10.0" }, "bin": { "addons-linter": "bin/addons-linter" }, "engines": { - "node": ">=12.21.0" + "node": ">=16.0.0" } }, "node_modules/addons-linter/node_modules/addons-scanner-utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-8.5.0.tgz", - "integrity": "sha512-X35SYZRdSnxx7UZuAk+DizKihQp2Ze2c5GV+5nnRr/FFyx/fOgE3Zo8jdhzSne57PENE9w1ZVocBLJTN6UDB3g==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.3.0.tgz", + "integrity": "sha512-YZWzNpP+em650XlZNH7NbTUcHJXqC0ihLEgwn17GGTqervyChqQffd9sm/QXNur0dmj7Ks1mD77iTg9XcJw64A==", "dev": true, "dependencies": { "@types/yauzl": "2.10.0", @@ -7506,7 +7517,7 @@ "peerDependencies": { "body-parser": "1.20.2", "express": "4.18.2", - "node-fetch": "2.6.7", + "node-fetch": "2.6.11", "safe-compare": "1.1.4" }, "peerDependenciesMeta": { @@ -7617,6 +7628,20 @@ "url": "https://github.com/chalk/chalk?sponsor=1" } }, + "node_modules/addons-linter/node_modules/cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "dependencies": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + }, + "engines": { + "node": ">=12" + } + }, "node_modules/addons-linter/node_modules/color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -7646,6 +7671,12 @@ "node": ">= 0.6" } }, + "node_modules/addons-linter/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "node_modules/addons-linter/node_modules/escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -7659,27 +7690,27 @@ } }, "node_modules/addons-linter/node_modules/eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "dependencies": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.48.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -7687,22 +7718,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "bin": { @@ -7716,12 +7744,15 @@ } }, "node_modules/addons-linter/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/addons-linter/node_modules/eslint/node_modules/ajv": { @@ -7762,16 +7793,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/addons-linter/node_modules/foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "dependencies": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, "node_modules/addons-linter/node_modules/glob": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", - "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", + "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", "dev": true, "dependencies": { - "fs.realpath": "^1.0.0", - "minimatch": "^7.4.1", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" + }, + "bin": { + "glob": "dist/cjs/src/bin.js" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -7793,24 +7844,24 @@ } }, "node_modules/addons-linter/node_modules/glob/node_modules/minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "dependencies": { "brace-expansion": "^2.0.1" }, "engines": { - "node": ">=10" + "node": ">=16 || 14 >=14.17" }, "funding": { "url": "https://github.com/sponsors/isaacs" } }, "node_modules/addons-linter/node_modules/globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "dependencies": { "type-fest": "^0.20.2" @@ -7831,6 +7882,15 @@ "node": ">=8" } }, + "node_modules/addons-linter/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/addons-linter/node_modules/json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -7853,12 +7913,12 @@ } }, "node_modules/addons-linter/node_modules/minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { - "node": ">=8" + "node": ">=16 || 14 >=14.17" } }, "node_modules/addons-linter/node_modules/ms": { @@ -7911,9 +7971,9 @@ } }, "node_modules/addons-linter/node_modules/semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "dependencies": { "lru-cache": "^6.0.0" @@ -7925,6 +7985,32 @@ "node": ">=10" } }, + "node_modules/addons-linter/node_modules/signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + } + }, + "node_modules/addons-linter/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/addons-linter/node_modules/supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -7949,6 +8035,33 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/addons-linter/node_modules/yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "dependencies": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + }, + "engines": { + "node": ">=12" + } + }, + "node_modules/addons-linter/node_modules/yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true, + "engines": { + "node": ">=12" + } + }, "node_modules/addons-moz-compare": { "version": "1.3.0", "resolved": "https://registry.npmjs.org/addons-moz-compare/-/addons-moz-compare-1.3.0.tgz", @@ -8538,17 +8651,6 @@ "node": ">=4" } }, - "node_modules/axios": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", - "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", - "dev": true, - "dependencies": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "node_modules/axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -8558,12 +8660,6 @@ "dequal": "^2.0.3" } }, - "node_modules/b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", - "dev": true - }, "node_modules/babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", @@ -8959,19 +9055,6 @@ "url": "https://opencollective.com/bigjs" } }, - "node_modules/binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", - "dev": true, - "dependencies": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - }, - "engines": { - "node": "*" - } - }, "node_modules/binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -9026,12 +9109,6 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, - "node_modules/bo-selector": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/bo-selector/-/bo-selector-0.0.10.tgz", - "integrity": "sha512-Drm8W3MFLNhzHTXG93g8ll7wBlmiRr5C9W8R0sbsNQp/8h1IoPnzDH4dEQuJx8VaNq02io2ZfFnzKC1s64xRJg==", - "dev": true - }, "node_modules/body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -9421,6 +9498,7 @@ "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true, "engines": { "node": "*" } @@ -9444,24 +9522,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "node_modules/buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "dev": true, - "engines": { - "node": ">=0.10" - } - }, - "node_modules/buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", - "dev": true, - "engines": { - "node": ">=0.2.0" - } - }, "node_modules/bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -9798,30 +9858,6 @@ "typedjson": "^1.6.0-rc2" } }, - "node_modules/casper-js-sdk/node_modules/node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", - "dependencies": { - "whatwg-url": "^5.0.0" - }, - "engines": { - "node": "4.x || >=6.0.0" - }, - "peerDependencies": { - "encoding": "^0.1.0" - }, - "peerDependenciesMeta": { - "encoding": { - "optional": true - } - } - }, - "node_modules/casper-js-sdk/node_modules/tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "node_modules/casper-js-sdk/node_modules/ts-results": { "name": "@casperlabs/ts-results", "version": "3.3.5", @@ -9836,32 +9872,6 @@ "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" }, - "node_modules/casper-js-sdk/node_modules/webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "node_modules/casper-js-sdk/node_modules/whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "dependencies": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } - }, - "node_modules/chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", - "dev": true, - "dependencies": { - "traverse": ">=0.3.0 <0.4" - }, - "engines": { - "node": "*" - } - }, "node_modules/chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -10139,28 +10149,6 @@ "node": ">=6.0" } }, - "node_modules/chromedriver": { - "version": "119.0.1", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-119.0.1.tgz", - "integrity": "sha512-lpCFFLaXPpvElTaUOWKdP74pFb/sJhWtWqMjn7Ju1YriWn8dT5JBk84BGXMPvZQs70WfCYWecxdMmwfIu1Mupg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@testim/chrome-version": "^1.1.4", - "axios": "^1.6.0", - "compare-versions": "^6.1.0", - "extract-zip": "^2.0.1", - "https-proxy-agent": "^5.0.1", - "proxy-from-env": "^1.1.0", - "tcp-port-used": "^1.0.2" - }, - "bin": { - "chromedriver": "bin/chromedriver" - }, - "engines": { - "node": ">=18" - } - }, "node_modules/ci-info": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", @@ -10520,12 +10508,6 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "node_modules/compare-versions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", - "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", - "dev": true - }, "node_modules/component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -11062,22 +11044,6 @@ "node": ">= 8" } }, - "node_modules/crx3": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/crx3/-/crx3-1.1.3.tgz", - "integrity": "sha512-E4c3y/2ak83wAGN4h9Q8j3A2ii4bpRVf2vxinYYy+wJs8pyscMfEnKGzhgngZcRfOhUMr7/sxzy+lTZmQ/4KpQ==", - "dependencies": { - "mri": "^1.1.6", - "pbf": "^3.2.1", - "yazl": "^2.5.1" - }, - "bin": { - "crx3": "bin/crx3.js" - }, - "engines": { - "node": ">=12" - } - }, "node_modules/crypto-random-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", @@ -11180,16 +11146,6 @@ "postcss-value-parser": "^4.0.2" } }, - "node_modules/css-to-xpath": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/css-to-xpath/-/css-to-xpath-0.1.0.tgz", - "integrity": "sha1-rA0cJs7wI/e9jPLh/B93E0vHDEc=", - "dev": true, - "dependencies": { - "bo-selector": "0.0.10", - "xpath-builder": "0.0.7" - } - }, "node_modules/css-vendor": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", @@ -12406,39 +12362,6 @@ "node": ">=0.10" } }, - "node_modules/duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "dependencies": { - "readable-stream": "^2.0.2" - } - }, - "node_modules/duplexer2/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/duplexer2/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -12527,6 +12450,15 @@ "integrity": "sha512-/Ng/W/kFv7wdEHYzxdK7Cv0BHEGSkSB3M0Ssl8Ndr1eMiYeas/+Mv4cNaDqamqWx6nd2uQZfPz6g25z25M/sdw==", "dev": true }, + "node_modules/electron/node_modules/@types/node": { + "version": "18.18.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.9.tgz", + "integrity": "sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ==", + "dev": true, + "dependencies": { + "undici-types": "~5.26.4" + } + }, "node_modules/elliptic": { "version": "6.5.4", "resolved": "https://registry.npmjs.org/elliptic/-/elliptic-6.5.4.tgz", @@ -13509,23 +13441,6 @@ "url": "https://opencollective.com/eslint" } }, - "node_modules/eslint/node_modules/espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "dependencies": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - }, - "engines": { - "node": "^12.22.0 || ^14.17.0 || >=16.0.0" - }, - "funding": { - "url": "https://opencollective.com/eslint" - } - }, "node_modules/eslint/node_modules/find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -13651,14 +13566,14 @@ } }, "node_modules/espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "dependencies": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -13668,12 +13583,15 @@ } }, "node_modules/espree/node_modules/eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" + }, + "funding": { + "url": "https://opencollective.com/eslint" } }, "node_modules/esprima": { @@ -14008,9 +13926,9 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "node_modules/fast-redact": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz", - "integrity": "sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", + "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", "dev": true, "engines": { "node": ">=6" @@ -14576,45 +14494,6 @@ "node": "^8.16.0 || ^10.6.0 || >=11.0.0" } }, - "node_modules/fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dev": true, - "dependencies": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "engines": { - "node": ">=0.6" - } - }, - "node_modules/fstream/node_modules/mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "dependencies": { - "minimist": "^1.2.6" - }, - "bin": { - "mkdirp": "bin/cmd.js" - } - }, - "node_modules/fstream/node_modules/rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "dependencies": { - "glob": "^7.1.3" - }, - "bin": { - "rimraf": "bin.js" - } - }, "node_modules/function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -14771,109 +14650,6 @@ "node": ">=8" } }, - "node_modules/geckodriver": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.2.1.tgz", - "integrity": "sha512-4m/CRk0OI8MaANRuFIahvOxYTSjlNAO2p9JmE14zxueknq6cdtB5M9UGRQ8R9aMV0bLGNVHHDnDXmoXdOwJfWg==", - "dev": true, - "hasInstallScript": true, - "dependencies": { - "@wdio/logger": "^8.11.0", - "decamelize": "^6.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.1", - "tar-fs": "^3.0.4", - "unzipper": "^0.10.14", - "which": "^4.0.0" - }, - "bin": { - "geckodriver": "bin/geckodriver.js" - }, - "engines": { - "node": "^16.13 || >=18 || >=20" - } - }, - "node_modules/geckodriver/node_modules/agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dev": true, - "dependencies": { - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/geckodriver/node_modules/http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", - "dev": true, - "dependencies": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/geckodriver/node_modules/https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", - "dev": true, - "dependencies": { - "agent-base": "^7.0.2", - "debug": "4" - }, - "engines": { - "node": ">= 14" - } - }, - "node_modules/geckodriver/node_modules/isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true, - "engines": { - "node": ">=16" - } - }, - "node_modules/geckodriver/node_modules/node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "dependencies": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - }, - "engines": { - "node": "^12.20.0 || ^14.13.1 || >=16.0.0" - }, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/node-fetch" - } - }, - "node_modules/geckodriver/node_modules/which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "dependencies": { - "isexe": "^3.1.1" - }, - "bin": { - "node-which": "bin/which.js" - }, - "engines": { - "node": "^16.13.0 || >=18.0.0" - } - }, "node_modules/gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -15348,12 +15124,6 @@ "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", "dev": true }, - "node_modules/grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "node_modules/graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -15801,9 +15571,9 @@ } }, "node_modules/html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", "dev": true, "dependencies": { "@types/html-minifier-terser": "^6.0.0", @@ -16252,6 +16022,7 @@ "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true, "funding": [ { "type": "github", @@ -16464,15 +16235,6 @@ "dev": true, "optional": true }, - "node_modules/ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "dev": true, - "engines": { - "node": ">=8" - } - }, "node_modules/ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -17019,12 +16781,6 @@ "node": ">=0.10.0" } }, - "node_modules/is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, "node_modules/is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -17101,20 +16857,6 @@ "node": ">=12" } }, - "node_modules/is2": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz", - "integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==", - "dev": true, - "dependencies": { - "deep-is": "^0.1.3", - "ip-regex": "^4.1.0", - "is-url": "^1.2.4" - }, - "engines": { - "node": ">=v0.10.0" - } - }, "node_modules/isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -17267,6 +17009,24 @@ "set-function-name": "^2.0.1" } }, + "node_modules/jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "dependencies": { + "@isaacs/cliui": "^8.0.2" + }, + "engines": { + "node": ">=14" + }, + "funding": { + "url": "https://github.com/sponsors/isaacs" + }, + "optionalDependencies": { + "@pkgjs/parseargs": "^0.11.0" + } + }, "node_modules/javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -19198,16 +18958,6 @@ "url": "https://github.com/sponsors/panva" } }, - "node_modules/js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", - "dev": true, - "funding": { - "type": "opencollective", - "url": "https://opencollective.com/js-sdsl" - } - }, "node_modules/js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -20290,12 +20040,6 @@ "node": ">= 14" } }, - "node_modules/listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", - "dev": true - }, "node_modules/listr2": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", @@ -20654,12 +20398,6 @@ "url": "https://tidelift.com/funding/github/npm/loglevel" } }, - "node_modules/loglevel-plugin-prefix": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", - "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true - }, "node_modules/long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -20677,6 +20415,11 @@ "loose-envify": "cli.js" } }, + "node_modules/lottie-web": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.11.0.tgz", + "integrity": "sha512-9vSt0AtdOH98GKDXwD5LPfFg9Pcmxt5+1BllAbudKM5iqPxpJnJUfuGaP45OyudDrESCOBgsjnntVUTygBNlzw==" + }, "node_modules/lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -21280,12 +21023,6 @@ "node": ">=10" } }, - "node_modules/mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "node_modules/mktemp": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", @@ -21347,14 +21084,6 @@ "node": ">= 0.8" } }, - "node_modules/mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==", - "engines": { - "node": ">=4" - } - }, "node_modules/ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -21493,10 +21222,16 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "node_modules/nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true, + "funding": [ + { + "type": "github", + "url": "https://github.com/sponsors/ai" + } + ], "bin": { "nanoid": "bin/nanoid.cjs" }, @@ -21571,9 +21306,9 @@ } }, "node_modules/node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "dependencies": { "whatwg-url": "^5.0.0" }, @@ -22011,10 +21746,13 @@ "dev": true }, "node_modules/on-exit-leak-free": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", - "dev": true + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", + "dev": true, + "engines": { + "node": ">=14.0.0" + } }, "node_modules/on-finished": { "version": "2.4.1", @@ -22660,13 +22398,13 @@ "integrity": "sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8=" }, "node_modules/path-scurry": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.0.tgz", - "integrity": "sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "dependencies": { "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2" + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "engines": { "node": ">=16 || 14 >=14.17" @@ -22676,18 +22414,18 @@ } }, "node_modules/path-scurry/node_modules/lru-cache": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz", - "integrity": "sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "dev": true, "engines": { "node": "14 || >=16.14" } }, "node_modules/path-scurry/node_modules/minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true, "engines": { "node": ">=16 || 14 >=14.17" @@ -22708,18 +22446,6 @@ "node": ">=8" } }, - "node_modules/pbf": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", - "dependencies": { - "ieee754": "^1.1.12", - "resolve-protobuf-schema": "^2.1.0" - }, - "bin": { - "pbf": "bin/pbf" - } - }, "node_modules/pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -22768,9 +22494,9 @@ } }, "node_modules/pino": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", - "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz", + "integrity": "sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ==", "dev": true, "dependencies": { "atomic-sleep": "^1.0.0", @@ -22824,15 +22550,16 @@ } }, "node_modules/pino-abstract-transport/node_modules/readable-stream": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.1.tgz", - "integrity": "sha512-llAHX9QC25bz5RPIoTeJxPaA/hgryaldValRhVZ2fK9bzbmFiscpz8fw6iBTvJfAk1w4FC1KXQme/nO7fbKyKg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", "dev": true, "dependencies": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", - "process": "^0.11.10" + "process": "^0.11.10", + "string_decoder": "^1.3.0" }, "engines": { "node": "^12.22.0 || ^14.17.0 || >=16.0.0" @@ -22926,10 +22653,40 @@ "node": ">=8" } }, + "node_modules/playwright": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", + "dev": true, + "dependencies": { + "playwright-core": "1.39.0" + }, + "bin": { + "playwright": "cli.js" + }, + "engines": { + "node": ">=16" + }, + "optionalDependencies": { + "fsevents": "2.3.2" + } + }, + "node_modules/playwright-core": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", + "dev": true, + "bin": { + "playwright-core": "cli.js" + }, + "engines": { + "node": ">=16" + } + }, "node_modules/postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "dev": true, "funding": [ { @@ -22939,10 +22696,14 @@ { "type": "tidelift", "url": "https://tidelift.com/funding/github/npm/postcss" + }, + { + "type": "github", + "url": "https://github.com/sponsors/ai" } ], "dependencies": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" }, @@ -23037,9 +22798,9 @@ } }, "node_modules/prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", + "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", "dev": true, "bin": { "prettier": "bin/prettier.cjs" @@ -23119,9 +22880,9 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "node_modules/process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.1.tgz", + "integrity": "sha512-JjBvFEn7MwFbzUDa2SRtKJSsyO0LlER4V/FmwLMhBlXNbGgGxdyFCxIdMDLerWUycsVUyaoM9QFLvppFy4IWaQ==", "dev": true }, "node_modules/progress": { @@ -23223,11 +22984,6 @@ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", "dev": true }, - "node_modules/protocol-buffers-schema": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", - "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" - }, "node_modules/proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -23241,12 +22997,6 @@ "node": ">= 0.10" } }, - "node_modules/proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "node_modules/psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -23565,9 +23315,9 @@ } }, "node_modules/react-hook-form": { - "version": "7.40.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.40.0.tgz", - "integrity": "sha512-0rokdxMPJs0k9bvFtY6dbcSydyNhnZNXCR49jgDr/aR03FDHFOK6gfh8ccqB3fl696Mk7lqh04xdm+agqWXKSw==", + "version": "7.48.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.48.2.tgz", + "integrity": "sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A==", "engines": { "node": ">=12.22.0" }, @@ -23714,9 +23464,9 @@ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "node_modules/react-loading-skeleton": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.1.0.tgz", - "integrity": "sha512-j1U1CWWs68nBPOg7tkQqnlFcAMFF6oEK6MgqAo15f8A5p7mjH6xyKn2gHbkcimpwfO0VQXqxAswnSYVr8lWzjw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz", + "integrity": "sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA==", "peerDependencies": { "react": ">=16.8.0" } @@ -24429,14 +24179,6 @@ "node": ">= 0.10" } }, - "node_modules/resolve-protobuf-schema": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", - "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", - "dependencies": { - "protocol-buffers-schema": "^3.3.1" - } - }, "node_modules/resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -24799,41 +24541,6 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, - "node_modules/selenium-webdriver": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.10.0.tgz", - "integrity": "sha512-hSQPw6jgc+ej/UEcdQPG/iBwwMeCEgZr9HByY/J8ToyXztEqXzU9aLsIyrlj1BywBcStO4JQK/zMUWWrV8+riA==", - "dev": true, - "dependencies": { - "jszip": "^3.10.1", - "tmp": "^0.2.1", - "ws": ">=8.13.0" - }, - "engines": { - "node": ">= 14.20.0" - } - }, - "node_modules/selenium-webdriver/node_modules/ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "engines": { - "node": ">=10.0.0" - }, - "peerDependencies": { - "bufferutil": "^4.0.1", - "utf-8-validate": ">=5.0.2" - }, - "peerDependenciesMeta": { - "bufferutil": { - "optional": true - }, - "utf-8-validate": { - "optional": true - } - } - }, "node_modules/selfsigned": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", @@ -25445,9 +25152,9 @@ } }, "node_modules/sonic-boom": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", + "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==", "dev": true, "dependencies": { "atomic-sleep": "^1.0.0" @@ -25879,6 +25586,36 @@ "url": "https://github.com/sponsors/sindresorhus" } }, + "node_modules/string-width-cjs": { + "name": "string-width", + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, + "node_modules/string-width-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/string-width-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, "node_modules/string-width/node_modules/ansi-regex": { "version": "6.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", @@ -25982,6 +25719,19 @@ "node": ">=8" } }, + "node_modules/strip-ansi-cjs": { + "name": "strip-ansi", + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "dependencies": { + "ansi-regex": "^5.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -26204,28 +25954,6 @@ "node": ">= 10" } }, - "node_modules/tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "dependencies": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "node_modules/tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", - "dev": true, - "dependencies": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "node_modules/tarn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", @@ -26235,33 +25963,6 @@ "node": ">=8.0.0" } }, - "node_modules/tcp-port-used": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz", - "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==", - "dev": true, - "dependencies": { - "debug": "4.3.1", - "is2": "^2.0.6" - } - }, - "node_modules/tcp-port-used/node_modules/debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "dependencies": { - "ms": "2.1.2" - }, - "engines": { - "node": ">=6.0" - }, - "peerDependenciesMeta": { - "supports-color": { - "optional": true - } - } - }, "node_modules/teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", @@ -26388,9 +26089,9 @@ } }, "node_modules/thread-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", - "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz", + "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==", "dev": true, "dependencies": { "real-require": "^0.2.0" @@ -26634,15 +26335,6 @@ "node": ">=12" } }, - "node_modules/traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", - "dev": true, - "engines": { - "node": "*" - } - }, "node_modules/tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -27270,6 +26962,11 @@ "node": "*" } }, + "node_modules/undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "node_modules/unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -27389,54 +27086,6 @@ "node": ">=8" } }, - "node_modules/unzipper": { - "version": "0.10.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", - "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", - "dev": true, - "dependencies": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - } - }, - "node_modules/unzipper/node_modules/bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", - "dev": true - }, - "node_modules/unzipper/node_modules/readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "dependencies": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "node_modules/unzipper/node_modules/string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "dependencies": { - "safe-buffer": "~5.1.0" - } - }, "node_modules/upath": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", @@ -27974,14 +27623,14 @@ } }, "node_modules/web-ext": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.6.2.tgz", - "integrity": "sha512-xlxbzgFBIS/UWWlvWxyR1PIqRRzDj1cutoHh+VZu4ZTcJTfv35KVdKkLRZv4PQwHu4dg8VfTg7WEcNP4QLaaFQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.8.0.tgz", + "integrity": "sha512-ta+VjbNfK5q0pqRmrlH/DQMdJ89sAJFfgcvpqoUoe2gPxLu18zZ5mIakGvyjmfjrkJLOZ2NCNF7suj/qd6xaEQ==", "dev": true, "dependencies": { "@babel/runtime": "7.21.0", "@devicefarmer/adbkit": "3.2.3", - "addons-linter": "5.32.0", + "addons-linter": "6.13.0", "bunyan": "1.8.15", "camelcase": "7.0.1", "chrome-launcher": "0.15.1", @@ -28746,6 +28395,86 @@ "url": "https://github.com/chalk/wrap-ansi?sponsor=1" } }, + "node_modules/wrap-ansi-cjs": { + "name": "wrap-ansi", + "version": "7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "dependencies": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "engines": { + "node": ">=10" + }, + "funding": { + "url": "https://github.com/chalk/wrap-ansi?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "dependencies": { + "color-convert": "^2.0.1" + }, + "engines": { + "node": ">=8" + }, + "funding": { + "url": "https://github.com/chalk/ansi-styles?sponsor=1" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "dependencies": { + "color-name": "~1.1.4" + }, + "engines": { + "node": ">=7.0.0" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "node_modules/wrap-ansi-cjs/node_modules/is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true, + "engines": { + "node": ">=8" + } + }, + "node_modules/wrap-ansi-cjs/node_modules/string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "dependencies": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "engines": { + "node": ">=8" + } + }, "node_modules/wrap-ansi/node_modules/ansi-styles": { "version": "4.3.0", "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", @@ -28912,12 +28641,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "node_modules/xpath-builder": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/xpath-builder/-/xpath-builder-0.0.7.tgz", - "integrity": "sha1-Z9a7w/ajIOwxfj5jaMVwa2ER3uw=", - "dev": true - }, "node_modules/xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -29039,14 +28762,6 @@ "fd-slicer": "~1.1.0" } }, - "node_modules/yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "dependencies": { - "buffer-crc32": "~0.2.3" - } - }, "node_modules/yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", @@ -29110,9 +28825,9 @@ "dev": true }, "@adobe/css-tools": { - "version": "4.0.1", - "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.0.1.tgz", - "integrity": "sha512-+u76oB43nOHrF4DDWRLWDCtci7f3QJoEBigemIdIeTi1ODqjx6Tad9NCVnPRwewWlKkVab5PlK8DCtPTyX7S8g==", + "version": "4.3.2", + "resolved": "https://registry.npmjs.org/@adobe/css-tools/-/css-tools-4.3.2.tgz", + "integrity": "sha512-DA5a1C0gD/pLOvhv33YMrbf2FK3oUzwNl9oOJqE4XVjuEtt6XIakRcsd7eLiOSPkp1kTRQGICTA8cKra/vFbjw==", "dev": true }, "@ampproject/remapping": { @@ -31117,23 +30832,6 @@ "strip-json-comments": "^3.1.1" }, "dependencies": { - "eslint-visitor-keys": { - "version": "3.4.3", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", - "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", - "dev": true - }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, "globals": { "version": "13.21.0", "resolved": "https://registry.npmjs.org/globals/-/globals-13.21.0.tgz", @@ -31152,9 +30850,9 @@ } }, "@eslint/js": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", - "integrity": "sha512-lxJ9R5ygVm8ZWgYdUweoq5ownDlJ4upvoWmO4eLxBYHdMo+vZ/Rx0EN6MbKWDJOSUGrqJy2Gt+Dyv/VKml0fjg==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.48.0.tgz", + "integrity": "sha512-ZSjtmelB7IJfWD2Fvb7+Z+ChTIKWq6kjda95fLcQKNS5aheVHn4IkfgRQE3sIIzTcSLwLcLZUD9UBt+V7+h+Pw==", "dev": true }, "@ethersproject/bignumber": { @@ -31389,6 +31087,54 @@ "integrity": "sha512-ZnQMnLV4e7hDlUvw8H+U8ASL02SS2Gn6+9Ac3wGGLIe7+je2AeAOxPY+izIPJDfFDb7eDjev0Us8MO1iFRN8hA==", "dev": true }, + "@isaacs/cliui": { + "version": "8.0.2", + "resolved": "https://registry.npmjs.org/@isaacs/cliui/-/cliui-8.0.2.tgz", + "integrity": "sha512-O8jcjabXaleOG9DQ0+ARXWZBTfnP4WNAqzuiJK7ll44AmxGKv/J2M4TPjxjY3znBCfvBXFzucm1twdyFybFqEA==", + "dev": true, + "requires": { + "string-width": "^5.1.2", + "string-width-cjs": "npm:string-width@^4.2.0", + "strip-ansi": "^7.0.1", + "strip-ansi-cjs": "npm:strip-ansi@^6.0.1", + "wrap-ansi": "^8.1.0", + "wrap-ansi-cjs": "npm:wrap-ansi@^7.0.0" + }, + "dependencies": { + "ansi-regex": { + "version": "6.0.1", + "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", + "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", + "dev": true + }, + "ansi-styles": { + "version": "6.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-6.2.1.tgz", + "integrity": "sha512-bN798gFfQX+viw3R7yrGWRqnrN2oRkEkUjjl4JNn4E8GxxbjtG3FbrEIIY3l8/hrwUwIeCZvi4QuOTP4MErVug==", + "dev": true + }, + "strip-ansi": { + "version": "7.1.0", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", + "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", + "dev": true, + "requires": { + "ansi-regex": "^6.0.1" + } + }, + "wrap-ansi": { + "version": "8.1.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-8.1.0.tgz", + "integrity": "sha512-si7QWI6zUMq56bESFvagtmzMdGOtoxfR+Sez11Mobfc7tm+VkUckk9bW2UeffTGVUbOksxmSw0AA2gs8g71NCQ==", + "dev": true, + "requires": { + "ansi-styles": "^6.1.0", + "string-width": "^5.0.1", + "strip-ansi": "^7.0.1" + } + } + } + }, "@istanbuljs/load-nyc-config": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/@istanbuljs/load-nyc-config/-/load-nyc-config-1.1.0.tgz", @@ -32091,6 +31837,14 @@ "integrity": "sha512-Hcv+nVC0kZnQ3tD9GVu5xSMR4VVYOteQIr/hwFPVEvPdlXqgGEuRjiheChHgdM+JyqdgNcmzZOX/tnl0JOiI7A==", "dev": true }, + "@lottiefiles/react-lottie-player": { + "version": "3.5.3", + "resolved": "https://registry.npmjs.org/@lottiefiles/react-lottie-player/-/react-lottie-player-3.5.3.tgz", + "integrity": "sha512-6pGbiTMjGnPddR1ur8M/TIDCiogZMc1aKIUbMEKXKAuNeYwZ2hvqwBJ+w5KRm88ccdcU88C2cGyLVsboFlSdVQ==", + "requires": { + "lottie-web": "^5.10.2" + } + }, "@make-software/ces-js-parser": { "version": "1.3.2", "resolved": "https://registry.npmjs.org/@make-software/ces-js-parser/-/ces-js-parser-1.3.2.tgz", @@ -32128,9 +31882,9 @@ } }, "@mdn/browser-compat-data": { - "version": "5.2.42", - "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.2.42.tgz", - "integrity": "sha512-CD/2ai1W45cDN/zN2AcYduDavU+nq9aStyQizi4MHxnwkRvS/H24WIjgc1qD8CISoqXa8AAIe+A+zpWxwV7a2Q==", + "version": "5.3.14", + "resolved": "https://registry.npmjs.org/@mdn/browser-compat-data/-/browser-compat-data-5.3.14.tgz", + "integrity": "sha512-Y9XQrphVcE6u9xMm+gIqN86opbU/5s2W1pdPyKRyFV5B7+2jWM2gLI5JpfhZncaoDKvhy6FYwK04aCz5UM/bTQ==", "dev": true }, "@noble/ciphers": { @@ -32232,6 +31986,13 @@ "ws": "^7.0.0" } }, + "@pkgjs/parseargs": { + "version": "0.11.0", + "resolved": "https://registry.npmjs.org/@pkgjs/parseargs/-/parseargs-0.11.0.tgz", + "integrity": "sha512-+1VkjdD0QBLPodGrJUeqarH8VAIvQODIbwh9XpP5Syisf7YoQgsJKPNFoqqLQlu+VQ/tVSshMR6loPMn8U+dPg==", + "dev": true, + "optional": true + }, "@pkgr/utils": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/@pkgr/utils/-/utils-2.4.2.tgz", @@ -32272,6 +32033,15 @@ } } }, + "@playwright/test": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/@playwright/test/-/test-1.39.0.tgz", + "integrity": "sha512-3u1iFqgzl7zr004bGPYiN/5EZpRUSFddQBra8Rqll5N0/vfpqlP9I9EXqAoGacuAbX6c9Ulg/Cjqglp5VkK6UQ==", + "dev": true, + "requires": { + "playwright": "1.39.0" + } + }, "@pnpm/network.ca-file": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/@pnpm/network.ca-file/-/network.ca-file-1.0.2.tgz", @@ -33147,12 +32917,6 @@ "defer-to-connect": "^2.0.0" } }, - "@testim/chrome-version": { - "version": "1.1.4", - "resolved": "https://registry.npmjs.org/@testim/chrome-version/-/chrome-version-1.1.4.tgz", - "integrity": "sha512-kIhULpw9TrGYnHp/8VfdcneIcxKnLixmADtukQRtJUmsVlMg0niMkwV0xZmi8hqa57xqilIHjWFA0GKvEjVU5g==", - "dev": true - }, "@testing-library/dom": { "version": "8.19.0", "resolved": "https://registry.npmjs.org/@testing-library/dom/-/dom-8.19.0.tgz", @@ -34011,9 +33775,12 @@ "integrity": "sha512-Klz949h02Gz2uZCMGwDUSDS1YBlTdDDgbWHi+81l29tQALUtvz4rAYi5uoVhE5Lagoq6DeqAUlbrHvW/mXDgdQ==" }, "@types/node": { - "version": "18.17.15", - "resolved": "https://registry.npmjs.org/@types/node/-/node-18.17.15.tgz", - "integrity": "sha512-2yrWpBk32tvV/JAd3HNHWuZn/VDN1P+72hWirHnvsvTGSqbANi+kSeuQR9yAHnbvaBvHDsoTdXV0Fe+iRtHLKA==" + "version": "20.9.0", + "resolved": "https://registry.npmjs.org/@types/node/-/node-20.9.0.tgz", + "integrity": "sha512-nekiGu2NDb1BcVofVcEKMIwzlx4NjHlcjhoxxKBNLtz15Y1z7MYf549DFvkHSId02Ax6kGwWntIBPC3l/JZcmw==", + "requires": { + "undici-types": "~5.26.4" + } }, "@types/node-fetch": { "version": "2.6.4", @@ -34142,15 +33909,6 @@ "resolved": "https://registry.npmjs.org/@types/scheduler/-/scheduler-0.16.2.tgz", "integrity": "sha512-hppQEBDmlwhFAXKJX2KnWLYu5yMfi91yazPb2l+lbJiwW+wdo1gNeRA+3RgNSO39WYX2euey41KEwnqesU2Jew==" }, - "@types/selenium-webdriver": { - "version": "4.1.9", - "resolved": "https://registry.npmjs.org/@types/selenium-webdriver/-/selenium-webdriver-4.1.9.tgz", - "integrity": "sha512-QNCYI3Rgjf3bZ2GZwXnUpOJUPR8p7+c9Um9MEKggLaUaF8UfjitH5aPCV1PF0DHVEiPYsXayGVS6+67DO3VILw==", - "dev": true, - "requires": { - "@types/ws": "*" - } - }, "@types/send": { "version": "0.17.1", "resolved": "https://registry.npmjs.org/@types/send/-/send-0.17.1.tgz", @@ -34444,41 +34202,6 @@ } } }, - "@wdio/logger": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/@wdio/logger/-/logger-8.11.0.tgz", - "integrity": "sha512-IsuKSaYi7NKEdgA57h8muzlN/MVp1dQG+V4C//7g4m03YJUnNQLvDhJzLjdeNTfvZy61U7foQSyt+3ktNzZkXA==", - "dev": true, - "requires": { - "chalk": "^5.1.2", - "loglevel": "^1.6.0", - "loglevel-plugin-prefix": "^0.8.4", - "strip-ansi": "^7.1.0" - }, - "dependencies": { - "ansi-regex": { - "version": "6.0.1", - "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-6.0.1.tgz", - "integrity": "sha512-n5M855fKb2SsfMIiFFoVrABHJC8QtHwVx+mHWP3QcEqBHYienj5dHSgjbxtC0WEZXYt4wcD6zrQElDPhFuZgfA==", - "dev": true - }, - "chalk": { - "version": "5.3.0", - "resolved": "https://registry.npmjs.org/chalk/-/chalk-5.3.0.tgz", - "integrity": "sha512-dLitG79d+GV1Nb/VYcCDFivJeK1hiukt9QjRNVOsUtTy1rR1YJsmpGGTZ3qJos+uw7WmWF4wUwBd9jxjocFC2w==", - "dev": true - }, - "strip-ansi": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-7.1.0.tgz", - "integrity": "sha512-iq6eVVI64nQQTRYq2KtEg2d2uU7LElhTJwsH4YzIHZshxlgZms/wIc4VoDQTlG/IvVIrBKG06CrZnp0qv7hkcQ==", - "dev": true, - "requires": { - "ansi-regex": "^6.0.1" - } - } - } - }, "@webassemblyjs/ast": { "version": "1.11.6", "resolved": "https://registry.npmjs.org/@webassemblyjs/ast/-/ast-1.11.6.tgz", @@ -34726,49 +34449,49 @@ "dev": true }, "addons-linter": { - "version": "5.32.0", - "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-5.32.0.tgz", - "integrity": "sha512-Lf6oOyw8X9z5BMd9xhQwSbPlN2PUlzDLnYLAVT5lkrgXEx0fO9hRk4JRxWZ8+rFGz+mCIA2TTClZF2f+MKgJQA==", + "version": "6.13.0", + "resolved": "https://registry.npmjs.org/addons-linter/-/addons-linter-6.13.0.tgz", + "integrity": "sha512-vYgDXl8aLmN1zU4HmsQdG6tUFByg499mHnTEMWDUbSkoYDq3koTne08EsqU6sD+o814u8FxclQP7580L0g/tPQ==", "dev": true, "requires": { "@fluent/syntax": "0.19.0", - "@mdn/browser-compat-data": "5.2.42", + "@mdn/browser-compat-data": "5.3.14", "addons-moz-compare": "1.3.0", - "addons-scanner-utils": "8.5.0", + "addons-scanner-utils": "9.3.0", "ajv": "8.12.0", "chalk": "4.1.2", "cheerio": "1.0.0-rc.12", "columnify": "1.6.0", "common-tags": "1.8.2", "deepmerge": "4.3.1", - "eslint": "8.36.0", + "eslint": "8.48.0", "eslint-plugin-no-unsanitized": "4.0.2", - "eslint-visitor-keys": "3.3.0", - "espree": "9.5.0", + "eslint-visitor-keys": "3.4.3", + "espree": "9.6.1", "esprima": "4.0.1", "fast-json-patch": "3.1.1", - "glob": "9.3.0", + "glob": "10.3.4", "image-size": "1.0.2", "is-mergeable-object": "1.1.1", "jed": "1.1.1", "json-merge-patch": "1.0.2", "os-locale": "5.0.0", - "pino": "8.11.0", - "postcss": "8.4.21", + "pino": "8.15.0", + "postcss": "8.4.29", "relaxed-json": "1.0.3", - "semver": "7.3.8", + "semver": "7.5.4", "sha.js": "2.4.11", "source-map-support": "0.5.21", "tosource": "1.0.0", "upath": "2.0.1", - "yargs": "17.7.1", + "yargs": "17.7.2", "yauzl": "2.10.0" }, "dependencies": { "addons-scanner-utils": { - "version": "8.5.0", - "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-8.5.0.tgz", - "integrity": "sha512-X35SYZRdSnxx7UZuAk+DizKihQp2Ze2c5GV+5nnRr/FFyx/fOgE3Zo8jdhzSne57PENE9w1ZVocBLJTN6UDB3g==", + "version": "9.3.0", + "resolved": "https://registry.npmjs.org/addons-scanner-utils/-/addons-scanner-utils-9.3.0.tgz", + "integrity": "sha512-YZWzNpP+em650XlZNH7NbTUcHJXqC0ihLEgwn17GGTqervyChqQffd9sm/QXNur0dmj7Ks1mD77iTg9XcJw64A==", "dev": true, "requires": { "@types/yauzl": "2.10.0", @@ -34854,6 +34577,17 @@ "supports-color": "^7.1.0" } }, + "cliui": { + "version": "8.0.1", + "resolved": "https://registry.npmjs.org/cliui/-/cliui-8.0.1.tgz", + "integrity": "sha512-BSeNnyus75C4//NQ9gQt1/csTXyo/8Sb+afLAkzAptFuMsod9HFokGNudZpi/oQV73hnVK+sR+5PVRMd+Dr7YQ==", + "dev": true, + "requires": { + "string-width": "^4.2.0", + "strip-ansi": "^6.0.1", + "wrap-ansi": "^7.0.0" + } + }, "color-convert": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", @@ -34877,6 +34611,12 @@ "optional": true, "peer": true }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, "escape-string-regexp": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-4.0.0.tgz", @@ -34884,27 +34624,27 @@ "dev": true }, "eslint": { - "version": "8.36.0", - "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.36.0.tgz", - "integrity": "sha512-Y956lmS7vDqomxlaaQAHVmeb4tNMp2FWIvU/RnU5BD3IKMD/MJPr76xdyr68P8tV1iNMvN2mRK0yy3c+UjL+bw==", + "version": "8.48.0", + "resolved": "https://registry.npmjs.org/eslint/-/eslint-8.48.0.tgz", + "integrity": "sha512-sb6DLeIuRXxeM1YljSe1KEx9/YYeZFQWcV8Rq9HfigmdDEugjLEVEa1ozDjL6YDjBpQHPJxJzze+alxi4T3OLg==", "dev": true, "requires": { "@eslint-community/eslint-utils": "^4.2.0", - "@eslint-community/regexpp": "^4.4.0", - "@eslint/eslintrc": "^2.0.1", - "@eslint/js": "8.36.0", - "@humanwhocodes/config-array": "^0.11.8", + "@eslint-community/regexpp": "^4.6.1", + "@eslint/eslintrc": "^2.1.2", + "@eslint/js": "8.48.0", + "@humanwhocodes/config-array": "^0.11.10", "@humanwhocodes/module-importer": "^1.0.1", "@nodelib/fs.walk": "^1.2.8", - "ajv": "^6.10.0", + "ajv": "^6.12.4", "chalk": "^4.0.0", "cross-spawn": "^7.0.2", "debug": "^4.3.2", "doctrine": "^3.0.0", "escape-string-regexp": "^4.0.0", - "eslint-scope": "^7.1.1", - "eslint-visitor-keys": "^3.3.0", - "espree": "^9.5.0", + "eslint-scope": "^7.2.2", + "eslint-visitor-keys": "^3.4.3", + "espree": "^9.6.1", "esquery": "^1.4.2", "esutils": "^2.0.2", "fast-deep-equal": "^3.1.3", @@ -34912,22 +34652,19 @@ "find-up": "^5.0.0", "glob-parent": "^6.0.2", "globals": "^13.19.0", - "grapheme-splitter": "^1.0.4", + "graphemer": "^1.4.0", "ignore": "^5.2.0", - "import-fresh": "^3.0.0", "imurmurhash": "^0.1.4", "is-glob": "^4.0.0", "is-path-inside": "^3.0.3", - "js-sdsl": "^4.1.4", "js-yaml": "^4.1.0", "json-stable-stringify-without-jsonify": "^1.0.1", "levn": "^0.4.1", "lodash.merge": "^4.6.2", "minimatch": "^3.1.2", "natural-compare": "^1.4.0", - "optionator": "^0.9.1", + "optionator": "^0.9.3", "strip-ansi": "^6.0.1", - "strip-json-comments": "^3.1.0", "text-table": "^0.2.0" }, "dependencies": { @@ -34952,9 +34689,9 @@ } }, "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, "find-up": { @@ -34967,22 +34704,33 @@ "path-exists": "^4.0.0" } }, + "foreground-child": { + "version": "3.1.1", + "resolved": "https://registry.npmjs.org/foreground-child/-/foreground-child-3.1.1.tgz", + "integrity": "sha512-TMKDUnIte6bfb5nWv7V/caI169OHgvwjb7V4WkeUvbQQdjr5rWKqHFiKWb/fcOwB+CzBT+qbWjvj+DVwRskpIg==", + "dev": true, + "requires": { + "cross-spawn": "^7.0.0", + "signal-exit": "^4.0.1" + } + }, "glob": { - "version": "9.3.0", - "resolved": "https://registry.npmjs.org/glob/-/glob-9.3.0.tgz", - "integrity": "sha512-EAZejC7JvnQINayvB/7BJbpZpNOJ8Lrw2OZNEvQxe0vaLn1SuwMcfV7/MNaX8L/T0wmptBFI4YMtDvSBxYDc7w==", + "version": "10.3.4", + "resolved": "https://registry.npmjs.org/glob/-/glob-10.3.4.tgz", + "integrity": "sha512-6LFElP3A+i/Q8XQKEvZjkEWEOTgAIALR9AO2rwT8bgPhDd1anmqDJDZ6lLddI4ehxxxR1S5RIqKe1uapMQfYaQ==", "dev": true, "requires": { - "fs.realpath": "^1.0.0", - "minimatch": "^7.4.1", - "minipass": "^4.2.4", - "path-scurry": "^1.6.1" + "foreground-child": "^3.1.0", + "jackspeak": "^2.0.3", + "minimatch": "^9.0.1", + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0", + "path-scurry": "^1.10.1" }, "dependencies": { "minimatch": { - "version": "7.4.6", - "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-7.4.6.tgz", - "integrity": "sha512-sBz8G/YjVniEz6lKPNpKxXwazJe4c19fEfV2GDMX6AjFz+MX9uDWIZW8XreVhkFW3fkIdTv/gxWr/Kks5FFAVw==", + "version": "9.0.3", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-9.0.3.tgz", + "integrity": "sha512-RHiac9mvaRw0x3AYRgDC1CxAP7HTcNrrECeA8YYJeWnpo+2Q5CegtZjaotWTWxDG3UeGA1coE05iH1mPjT/2mg==", "dev": true, "requires": { "brace-expansion": "^2.0.1" @@ -35000,9 +34748,9 @@ } }, "globals": { - "version": "13.20.0", - "resolved": "https://registry.npmjs.org/globals/-/globals-13.20.0.tgz", - "integrity": "sha512-Qg5QtVkCy/kv3FUSlu4ukeZDVf9ee0iXLAUYX13gbR17bnejFTzr4iS9bY7kwCf1NztRNm1t91fjOiyx4CSwPQ==", + "version": "13.23.0", + "resolved": "https://registry.npmjs.org/globals/-/globals-13.23.0.tgz", + "integrity": "sha512-XAmF0RjlrjY23MA51q3HltdlGxUpXPvg0GioKiD9X6HD28iMjo2dKC8Vqwm7lne4GNr78+RHTfliktR6ZH09wA==", "dev": true, "requires": { "type-fest": "^0.20.2" @@ -35014,6 +34762,12 @@ "integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==", "dev": true }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, "json-schema-traverse": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", @@ -35030,9 +34784,9 @@ } }, "minipass": { - "version": "4.2.8", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-4.2.8.tgz", - "integrity": "sha512-fNzuVyifolSLFL4NzpF+wEF4qrgqaaKX0haXPQEdQ7NKAN+WecoKMHV09YcuL/DHxrUsYQOK3MiuDf7Ip2OXfQ==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true }, "ms": { @@ -35073,14 +34827,31 @@ } }, "semver": { - "version": "7.3.8", - "resolved": "https://registry.npmjs.org/semver/-/semver-7.3.8.tgz", - "integrity": "sha512-NB1ctGL5rlHrPJtFDVIVzTyQylMLu9N9VICA6HSFJo8MCGVTMW6gfpicwKmmK/dAjTOrqu5l63JJOpDSrAis3A==", + "version": "7.5.4", + "resolved": "https://registry.npmjs.org/semver/-/semver-7.5.4.tgz", + "integrity": "sha512-1bCSESV6Pv+i21Hvpxp3Dx+pSD8lIPt8uVjRrxAUt/nbswYc+tK6Y2btiULjd4+fnq15PX+nqQDC7Oft7WkwcA==", "dev": true, "requires": { "lru-cache": "^6.0.0" } }, + "signal-exit": { + "version": "4.1.0", + "resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-4.1.0.tgz", + "integrity": "sha512-bzyZ1e88w9O1iNJbKnOlvYTrWPDl46O1bG0D3XInv+9tkPrxrN8jUUTiFlDkkmKWgn1M6CfIA13SuGqOa9Korw==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + }, "supports-color": { "version": "7.2.0", "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz", @@ -35095,6 +34866,27 @@ "resolved": "https://registry.npmjs.org/type-fest/-/type-fest-0.20.2.tgz", "integrity": "sha512-Ne+eE4r0/iWnpAxD852z3A+N0Bt5RN//NjJwRd2VFHEmrywxf5vsZlh4R6lixl6B+wz/8d+maTSAkN1FIkI3LQ==", "dev": true + }, + "yargs": { + "version": "17.7.2", + "resolved": "https://registry.npmjs.org/yargs/-/yargs-17.7.2.tgz", + "integrity": "sha512-7dSzzRQ++CKnNI/krKnYRV7JKKPUXMEh61soaHKg9mrWEhzFWhFnxPxGl+69cD1Ou63C13NUPCnmIcrvqCuM6w==", + "dev": true, + "requires": { + "cliui": "^8.0.1", + "escalade": "^3.1.1", + "get-caller-file": "^2.0.5", + "require-directory": "^2.1.1", + "string-width": "^4.2.3", + "y18n": "^5.0.5", + "yargs-parser": "^21.1.1" + } + }, + "yargs-parser": { + "version": "21.1.1", + "resolved": "https://registry.npmjs.org/yargs-parser/-/yargs-parser-21.1.1.tgz", + "integrity": "sha512-tVpsJW7DdjecAiFpbIB1e3qxIQsE6NoPc5/eTdrbbIC4h0LVsWhnoa3g+m2HclBIujHzsxZ4VJVA+GUuc2/LBw==", + "dev": true } } }, @@ -35567,17 +35359,6 @@ "integrity": "sha512-zIURGIS1E1Q4pcrMjp+nnEh+16G56eG/MUllJH8yEvw7asDo7Ac9uhC9KIH5jzpITueEZolfYglnCGIuSBz39g==", "dev": true }, - "axios": { - "version": "1.6.1", - "resolved": "https://registry.npmjs.org/axios/-/axios-1.6.1.tgz", - "integrity": "sha512-vfBmhDpKafglh0EldBEbVuoe7DyAavGSLWhuSm5ZSEKQnHhBf0xAAwybbNH1IkrJNGnS/VG4I5yxig1pCEXE4g==", - "dev": true, - "requires": { - "follow-redirects": "^1.15.0", - "form-data": "^4.0.0", - "proxy-from-env": "^1.1.0" - } - }, "axobject-query": { "version": "3.2.1", "resolved": "https://registry.npmjs.org/axobject-query/-/axobject-query-3.2.1.tgz", @@ -35587,12 +35368,6 @@ "dequal": "^2.0.3" } }, - "b4a": { - "version": "1.6.4", - "resolved": "https://registry.npmjs.org/b4a/-/b4a-1.6.4.tgz", - "integrity": "sha512-fpWrvyVHEKyeEvbKZTVOeZF3VSKKWtJxFIxX/jaVPf+cLbGUSitjb49pHLqPV2BUNNZ0LcoeEGfE/YCpyDYHIw==", - "dev": true - }, "babel-eslint": { "version": "10.1.0", "resolved": "https://registry.npmjs.org/babel-eslint/-/babel-eslint-10.1.0.tgz", @@ -35888,16 +35663,6 @@ "resolved": "https://registry.npmjs.org/big.js/-/big.js-6.2.1.tgz", "integrity": "sha512-bCtHMwL9LeDIozFn+oNhhFoq+yQ3BNdnsLSASUxLciOb1vgvpHsIO1dsENiGMgbb4SkP5TrzWzRiLddn8ahVOQ==" }, - "binary": { - "version": "0.3.0", - "resolved": "https://registry.npmjs.org/binary/-/binary-0.3.0.tgz", - "integrity": "sha512-D4H1y5KYwpJgK8wk1Cue5LLPgmwHKYSChkbspQg5JtVuR5ulGckxfR62H3AE9UDkdMC8yyXlqYihuz3Aqg2XZg==", - "dev": true, - "requires": { - "buffers": "~0.1.1", - "chainsaw": "~0.1.0" - } - }, "binary-extensions": { "version": "2.2.0", "resolved": "https://registry.npmjs.org/binary-extensions/-/binary-extensions-2.2.0.tgz", @@ -35951,12 +35716,6 @@ "resolved": "https://registry.npmjs.org/bn.js/-/bn.js-4.12.0.tgz", "integrity": "sha512-c98Bf3tPniI+scsdk237ku1Dc3ujXQTSgyiPUDEOe7tRkhrqridvh8klBv0HCEso1OLOYcHuCv/cS6DNxKH+ZA==" }, - "bo-selector": { - "version": "0.0.10", - "resolved": "https://registry.npmjs.org/bo-selector/-/bo-selector-0.0.10.tgz", - "integrity": "sha512-Drm8W3MFLNhzHTXG93g8ll7wBlmiRr5C9W8R0sbsNQp/8h1IoPnzDH4dEQuJx8VaNq02io2ZfFnzKC1s64xRJg==", - "dev": true - }, "body-parser": { "version": "1.20.1", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.20.1.tgz", @@ -36243,7 +36002,8 @@ "buffer-crc32": { "version": "0.2.13", "resolved": "https://registry.npmjs.org/buffer-crc32/-/buffer-crc32-0.2.13.tgz", - "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==" + "integrity": "sha512-VO9Ht/+p3SN7SKWqcrgEzjGbRSJYTx+Q1pTQC0wrWqHx0vpJraQ6GtHx8tvcg1rlK1byhU5gccxgOgj7B0TDkQ==", + "dev": true }, "buffer-equal": { "version": "1.0.0", @@ -36261,18 +36021,6 @@ "resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.2.tgz", "integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==" }, - "buffer-indexof-polyfill": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/buffer-indexof-polyfill/-/buffer-indexof-polyfill-1.0.2.tgz", - "integrity": "sha512-I7wzHwA3t1/lwXQh+A5PbNvJxgfo5r3xulgpYDB5zckTu/Z9oUK9biouBKQUjEqzaz3HnAT6TYoovmE+GqSf7A==", - "dev": true - }, - "buffers": { - "version": "0.1.1", - "resolved": "https://registry.npmjs.org/buffers/-/buffers-0.1.1.tgz", - "integrity": "sha512-9q/rDEGSb/Qsvv2qvzIzdluL5k7AaJOTrw23z9reQthrbF7is4CtlT0DXyO1oei2DCp4uojjzQ7igaSHp1kAEQ==", - "dev": true - }, "bundle-name": { "version": "3.0.0", "resolved": "https://registry.npmjs.org/bundle-name/-/bundle-name-3.0.0.tgz", @@ -36524,19 +36272,6 @@ "typedjson": "^1.6.0-rc2" }, "dependencies": { - "node-fetch": { - "version": "2.6.11", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", - "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", - "requires": { - "whatwg-url": "^5.0.0" - } - }, - "tr46": { - "version": "0.0.3", - "resolved": "https://registry.npmjs.org/tr46/-/tr46-0.0.3.tgz", - "integrity": "sha512-N3WMsuqV66lT30CrXNbEjx4GEwlow3v6rr4mCcv6prnfwhS01rkgyFdjPNBYd9br7LpXV1+Emh01fHnq2Gdgrw==" - }, "ts-results": { "version": "npm:@casperlabs/ts-results@3.3.5", "resolved": "https://registry.npmjs.org/@casperlabs/ts-results/-/ts-results-3.3.5.tgz", @@ -36549,32 +36284,9 @@ "version": "2.5.3", "resolved": "https://registry.npmjs.org/tslib/-/tslib-2.5.3.tgz", "integrity": "sha512-mSxlJJwl3BMEQCUNnxXBU9jP4JBktcEGhURcPR6VQVlnP0FdDEsIaz0C35dXNGLyRfrATNofF0F5p2KPxQgB+w==" - }, - "webidl-conversions": { - "version": "3.0.1", - "resolved": "https://registry.npmjs.org/webidl-conversions/-/webidl-conversions-3.0.1.tgz", - "integrity": "sha512-2JAn3z8AR6rjK8Sm8orRC0h/bcl/DqL7tRPdGZ4I1CjdF+EaMLmYxBHyXuKL849eucPFhvBoxMsflfOb8kxaeQ==" - }, - "whatwg-url": { - "version": "5.0.0", - "resolved": "https://registry.npmjs.org/whatwg-url/-/whatwg-url-5.0.0.tgz", - "integrity": "sha512-saE57nupxk6v3HY35+jzBwYa0rKSy0XR8JSxZPwgLr7ys0IBzhGviA1/TUGJLmSVqs8pb9AnvICXEuOHLprYTw==", - "requires": { - "tr46": "~0.0.3", - "webidl-conversions": "^3.0.0" - } } } }, - "chainsaw": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/chainsaw/-/chainsaw-0.1.0.tgz", - "integrity": "sha512-75kWfWt6MEKNC8xYXIdRpDehRYY/tNSgwKaJq+dbbDcxORuVrrQ+SEHoWsniVn9XPYfP4gmdWIeDk/4YNp1rNQ==", - "dev": true, - "requires": { - "traverse": ">=0.3.0 <0.4" - } - }, "chalk": { "version": "2.4.2", "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", @@ -36765,21 +36477,6 @@ "integrity": "sha512-p3KULyQg4S7NIHixdwbGX+nFHkoBiA4YQmyWtjb8XngSKV124nJmRysgAeujbUVb15vh+RvFUfCPqU7rXk+hZg==", "dev": true }, - "chromedriver": { - "version": "119.0.1", - "resolved": "https://registry.npmjs.org/chromedriver/-/chromedriver-119.0.1.tgz", - "integrity": "sha512-lpCFFLaXPpvElTaUOWKdP74pFb/sJhWtWqMjn7Ju1YriWn8dT5JBk84BGXMPvZQs70WfCYWecxdMmwfIu1Mupg==", - "dev": true, - "requires": { - "@testim/chrome-version": "^1.1.4", - "axios": "^1.6.0", - "compare-versions": "^6.1.0", - "extract-zip": "^2.0.1", - "https-proxy-agent": "^5.0.1", - "proxy-from-env": "^1.1.0", - "tcp-port-used": "^1.0.2" - } - }, "ci-info": { "version": "3.4.0", "resolved": "https://registry.npmjs.org/ci-info/-/ci-info-3.4.0.tgz", @@ -37074,12 +36771,6 @@ "integrity": "sha1-3dgA2gxmEnOTzKWVDqloo6rxJTs=", "dev": true }, - "compare-versions": { - "version": "6.1.0", - "resolved": "https://registry.npmjs.org/compare-versions/-/compare-versions-6.1.0.tgz", - "integrity": "sha512-LNZQXhqUvqUTotpZ00qLSaify3b4VFD588aRr8MKFw4CMUr98ytzCW5wDH5qx/DEY5kCDXcbcRuCqL0szEf2tg==", - "dev": true - }, "component-emitter": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/component-emitter/-/component-emitter-1.2.1.tgz", @@ -37488,16 +37179,6 @@ "which": "^2.0.1" } }, - "crx3": { - "version": "1.1.3", - "resolved": "https://registry.npmjs.org/crx3/-/crx3-1.1.3.tgz", - "integrity": "sha512-E4c3y/2ak83wAGN4h9Q8j3A2ii4bpRVf2vxinYYy+wJs8pyscMfEnKGzhgngZcRfOhUMr7/sxzy+lTZmQ/4KpQ==", - "requires": { - "mri": "^1.1.6", - "pbf": "^3.2.1", - "yazl": "^2.5.1" - } - }, "crypto-random-string": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/crypto-random-string/-/crypto-random-string-4.0.0.tgz", @@ -37570,16 +37251,6 @@ "postcss-value-parser": "^4.0.2" } }, - "css-to-xpath": { - "version": "0.1.0", - "resolved": "https://registry.npmjs.org/css-to-xpath/-/css-to-xpath-0.1.0.tgz", - "integrity": "sha1-rA0cJs7wI/e9jPLh/B93E0vHDEc=", - "dev": true, - "requires": { - "bo-selector": "0.0.10", - "xpath-builder": "0.0.7" - } - }, "css-vendor": { "version": "2.0.8", "resolved": "https://registry.npmjs.org/css-vendor/-/css-vendor-2.0.8.tgz", @@ -38470,41 +38141,6 @@ "nan": "^2.14.0" } }, - "duplexer2": { - "version": "0.1.4", - "resolved": "https://registry.npmjs.org/duplexer2/-/duplexer2-0.1.4.tgz", - "integrity": "sha512-asLFVfWWtJ90ZyOUHMqk7/S2w2guQKxUI2itj3d92ADHhxUSbCMGi1f1cBcJ7xM1To+pE/Khbwo1yuNbMEPKeA==", - "dev": true, - "requires": { - "readable-stream": "^2.0.2" - }, - "dependencies": { - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "duplexify": { "version": "3.7.1", "resolved": "https://registry.npmjs.org/duplexify/-/duplexify-3.7.1.tgz", @@ -38580,6 +38216,17 @@ "@electron/get": "^2.0.0", "@types/node": "^18.11.18", "extract-zip": "^2.0.1" + }, + "dependencies": { + "@types/node": { + "version": "18.18.9", + "resolved": "https://registry.npmjs.org/@types/node/-/node-18.18.9.tgz", + "integrity": "sha512-0f5klcuImLnG4Qreu9hPj/rEfFq6YRc5n2mAjSsH+ec/mJL+3voBH0+8T7o8RpFjH7ovc+TRsL/c7OYIQsPTfQ==", + "dev": true, + "requires": { + "undici-types": "~5.26.4" + } + } } }, "electron-to-chromium": { @@ -39024,17 +38671,6 @@ "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true }, - "espree": { - "version": "9.6.1", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", - "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", - "dev": true, - "requires": { - "acorn": "^8.9.0", - "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.4.1" - } - }, "find-up": { "version": "5.0.0", "resolved": "https://registry.npmjs.org/find-up/-/find-up-5.0.0.tgz", @@ -39413,20 +39049,20 @@ "dev": true }, "espree": { - "version": "9.5.0", - "resolved": "https://registry.npmjs.org/espree/-/espree-9.5.0.tgz", - "integrity": "sha512-JPbJGhKc47++oo4JkEoTe2wjy4fmMwvFpgJT9cQzmfXKp22Dr6Hf1tdCteLz1h0P3t+mGvWZ+4Uankvh8+c6zw==", + "version": "9.6.1", + "resolved": "https://registry.npmjs.org/espree/-/espree-9.6.1.tgz", + "integrity": "sha512-oruZaFkjorTpF32kDSI5/75ViwGeZginGGy2NoOSg3Q9bnwlnmDm4HLnkl0RE3n+njDXR037aY1+x58Z/zFdwQ==", "dev": true, "requires": { - "acorn": "^8.8.0", + "acorn": "^8.9.0", "acorn-jsx": "^5.3.2", - "eslint-visitor-keys": "^3.3.0" + "eslint-visitor-keys": "^3.4.1" }, "dependencies": { "eslint-visitor-keys": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.3.0.tgz", - "integrity": "sha512-mQ+suqKJVyeuwGYHAdjMFqjCyfl8+Ldnxuyp3ldiMBFKkvytrXUZWaiPCEav8qDHKty44bD+qV1IP4T+w+xXRA==", + "version": "3.4.3", + "resolved": "https://registry.npmjs.org/eslint-visitor-keys/-/eslint-visitor-keys-3.4.3.tgz", + "integrity": "sha512-wpc+LXeiyiisxPlEkUzU6svyS1frIO3Mgxj1fdy7Pm8Ygzguax2N3Fa/D/ag1WqbOprdI+uY6wMUl8/a2G+iag==", "dev": true } } @@ -39687,9 +39323,9 @@ "integrity": "sha1-PYpcZog6FqMMqGQ+hR8Zuqd5eRc=" }, "fast-redact": { - "version": "3.2.0", - "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.2.0.tgz", - "integrity": "sha512-zaTadChr+NekyzallAMXATXLOR8MNx3zqpZ0MUF2aGf4EathnG0f32VLODNlY8IuGY3HoRO2L6/6fSzNsLaHIw==", + "version": "3.3.0", + "resolved": "https://registry.npmjs.org/fast-redact/-/fast-redact-3.3.0.tgz", + "integrity": "sha512-6T5V1QK1u4oF+ATxs1lWUmlEk6P2T9HqJG3e2DnHOdVgZy2rFJBoEnrIedcTXlkAHU/zKC+7KETJ+KGGKwxgMQ==", "dev": true }, "fastest-levenshtein": { @@ -40135,38 +39771,6 @@ "dev": true, "optional": true }, - "fstream": { - "version": "1.0.12", - "resolved": "https://registry.npmjs.org/fstream/-/fstream-1.0.12.tgz", - "integrity": "sha512-WvJ193OHa0GHPEL+AycEJgxvBEwyfRkN1vhjca23OaPVMCaLCXTd5qAu82AjTcgP1UJmytkOKb63Ypde7raDIg==", - "dev": true, - "requires": { - "graceful-fs": "^4.1.2", - "inherits": "~2.0.0", - "mkdirp": ">=0.5 0", - "rimraf": "2" - }, - "dependencies": { - "mkdirp": { - "version": "0.5.6", - "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", - "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", - "dev": true, - "requires": { - "minimist": "^1.2.6" - } - }, - "rimraf": { - "version": "2.7.1", - "resolved": "https://registry.npmjs.org/rimraf/-/rimraf-2.7.1.tgz", - "integrity": "sha512-uWjbaKIK3T1OSVptzX7Nl6PvQ3qAGtKEtVRjRuazjfL3Bx5eI409VZSqgND+4UNnmzLVdPj9FqFJNPqBZFve4w==", - "dev": true, - "requires": { - "glob": "^7.1.3" - } - } - } - }, "function-bind": { "version": "1.1.1", "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", @@ -40294,79 +39898,6 @@ } } }, - "geckodriver": { - "version": "4.2.1", - "resolved": "https://registry.npmjs.org/geckodriver/-/geckodriver-4.2.1.tgz", - "integrity": "sha512-4m/CRk0OI8MaANRuFIahvOxYTSjlNAO2p9JmE14zxueknq6cdtB5M9UGRQ8R9aMV0bLGNVHHDnDXmoXdOwJfWg==", - "dev": true, - "requires": { - "@wdio/logger": "^8.11.0", - "decamelize": "^6.0.0", - "http-proxy-agent": "^7.0.0", - "https-proxy-agent": "^7.0.1", - "node-fetch": "^3.3.1", - "tar-fs": "^3.0.4", - "unzipper": "^0.10.14", - "which": "^4.0.0" - }, - "dependencies": { - "agent-base": { - "version": "7.1.0", - "resolved": "https://registry.npmjs.org/agent-base/-/agent-base-7.1.0.tgz", - "integrity": "sha512-o/zjMZRhJxny7OyEF+Op8X+efiELC7k7yOjMzgfzVqOzXqkBkWI79YoTdOtsuWd5BWhAGAuOY/Xa6xpiaWXiNg==", - "dev": true, - "requires": { - "debug": "^4.3.4" - } - }, - "http-proxy-agent": { - "version": "7.0.0", - "resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-7.0.0.tgz", - "integrity": "sha512-+ZT+iBxVUQ1asugqnD6oWoRiS25AkjNfG085dKJGtGxkdwLQrMKU5wJr2bOOFAXzKcTuqq+7fZlTMgG3SRfIYQ==", - "dev": true, - "requires": { - "agent-base": "^7.1.0", - "debug": "^4.3.4" - } - }, - "https-proxy-agent": { - "version": "7.0.2", - "resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-7.0.2.tgz", - "integrity": "sha512-NmLNjm6ucYwtcUmL7JQC1ZQ57LmHP4lT15FQ8D61nak1rO6DH+fz5qNK2Ap5UN4ZapYICE3/0KodcLYSPsPbaA==", - "dev": true, - "requires": { - "agent-base": "^7.0.2", - "debug": "4" - } - }, - "isexe": { - "version": "3.1.1", - "resolved": "https://registry.npmjs.org/isexe/-/isexe-3.1.1.tgz", - "integrity": "sha512-LpB/54B+/2J5hqQ7imZHfdU31OlgQqx7ZicVlkm9kzg9/w8GKLEcFfJl/t7DCEDueOyBAD6zCCwTO6Fzs0NoEQ==", - "dev": true - }, - "node-fetch": { - "version": "3.3.2", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-3.3.2.tgz", - "integrity": "sha512-dRB78srN/l6gqWulah9SrxeYnxeddIG30+GOqK/9OlLVyLg3HPnr6SqOWTWOXKRwC2eGYCkZ59NNuSgvSrpgOA==", - "dev": true, - "requires": { - "data-uri-to-buffer": "^4.0.0", - "fetch-blob": "^3.1.4", - "formdata-polyfill": "^4.0.10" - } - }, - "which": { - "version": "4.0.0", - "resolved": "https://registry.npmjs.org/which/-/which-4.0.0.tgz", - "integrity": "sha512-GlaYyEb07DPxYCKhKzplCWBJtvxZcZMrL+4UkrTSJHHPyZU4mYYTv3qaOe77H7EODLSSopAUFAc6W8U4yqvscg==", - "dev": true, - "requires": { - "isexe": "^3.1.1" - } - } - } - }, "gensync": { "version": "1.0.0-beta.2", "resolved": "https://registry.npmjs.org/gensync/-/gensync-1.0.0-beta.2.tgz", @@ -40719,12 +40250,6 @@ "integrity": "sha512-8tLu60LgxF6XpdbK8OW3FA+IfTNBn1ZHGHKF4KQbEeSkajYw5PlYJcKluntgegDPTg8UkHjpet1T82vk6TQ68w==", "dev": true }, - "grapheme-splitter": { - "version": "1.0.4", - "resolved": "https://registry.npmjs.org/grapheme-splitter/-/grapheme-splitter-1.0.4.tgz", - "integrity": "sha512-bzh50DW9kTPM00T8y4o8vQg89Di9oLJVLW/KaOGIXJWP/iqCN6WKYkbNOF04vFLJhwcpYUh9ydh/+5vpOqV4YQ==", - "dev": true - }, "graphemer": { "version": "1.4.0", "resolved": "https://registry.npmjs.org/graphemer/-/graphemer-1.4.0.tgz", @@ -41085,9 +40610,9 @@ } }, "html-webpack-plugin": { - "version": "5.5.0", - "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.0.tgz", - "integrity": "sha512-sy88PC2cRTVxvETRgUHFrL4No3UxvcH8G1NepGhqaTT+GXN2kTamqasot0inS5hXeg1cMbFDt27zzo9p35lZVw==", + "version": "5.5.3", + "resolved": "https://registry.npmjs.org/html-webpack-plugin/-/html-webpack-plugin-5.5.3.tgz", + "integrity": "sha512-6YrDKTuqaP/TquFH7h4srYWsZx+x6k6+FbsTm0ziCwGHDP78Unr1r9F/H4+sGmMbX08GQcJ+K64x55b+7VM/jg==", "dev": true, "requires": { "@types/html-minifier-terser": "^6.0.0", @@ -41407,7 +40932,8 @@ "ieee754": { "version": "1.2.1", "resolved": "https://registry.npmjs.org/ieee754/-/ieee754-1.2.1.tgz", - "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==" + "integrity": "sha512-dcyqhDvX1C46lXZcVqCpK+FtMRQVdIMN6/Df5js2zouUsqG7I6sFxitIC+7KYK29KdXOLHdu9zL4sFnoVQnqaA==", + "dev": true }, "ignore": { "version": "5.2.0", @@ -41554,12 +41080,6 @@ "dev": true, "optional": true }, - "ip-regex": { - "version": "4.3.0", - "resolved": "https://registry.npmjs.org/ip-regex/-/ip-regex-4.3.0.tgz", - "integrity": "sha512-B9ZWJxHHOHUhUjCPrMpLD4xEq35bUTClHM1S6CBU5ixQnkZmwipwgc96vAd7AAGM9TGHvJR+Uss+/Ak6UphK+Q==", - "dev": true - }, "ipaddr.js": { "version": "1.9.1", "resolved": "https://registry.npmjs.org/ipaddr.js/-/ipaddr.js-1.9.1.tgz", @@ -41919,12 +41439,6 @@ "unc-path-regex": "^0.1.2" } }, - "is-url": { - "version": "1.2.4", - "resolved": "https://registry.npmjs.org/is-url/-/is-url-1.2.4.tgz", - "integrity": "sha512-ITvGim8FhRiYe4IQ5uHSkj7pVaPDrCTkNd3yq3cV7iZAcJdHTUMPMEHcqSOy9xZ9qFenQCvi+2wjH9a1nXqHww==", - "dev": true - }, "is-utf8": { "version": "0.2.1", "resolved": "https://registry.npmjs.org/is-utf8/-/is-utf8-0.2.1.tgz", @@ -41980,17 +41494,6 @@ "integrity": "sha512-/kppl+R+LO5VmhYSEWARUFjodS25D68gvj8W7z0I7OWhUla5xWu8KL6CtB2V0R6yqhnRgbcaREMr4EEM6htLPQ==", "dev": true }, - "is2": { - "version": "2.0.7", - "resolved": "https://registry.npmjs.org/is2/-/is2-2.0.7.tgz", - "integrity": "sha512-4vBQoURAXC6hnLFxD4VW7uc04XiwTTl/8ydYJxKvPwkWQrSjInkuM5VZVg6BGr1/natq69zDuvO9lGpLClJqvA==", - "dev": true, - "requires": { - "deep-is": "^0.1.3", - "ip-regex": "^4.1.0", - "is-url": "^1.2.4" - } - }, "isarray": { "version": "1.0.0", "resolved": "https://registry.npmjs.org/isarray/-/isarray-1.0.0.tgz", @@ -42118,6 +41621,16 @@ "set-function-name": "^2.0.1" } }, + "jackspeak": { + "version": "2.3.6", + "resolved": "https://registry.npmjs.org/jackspeak/-/jackspeak-2.3.6.tgz", + "integrity": "sha512-N3yCS/NegsOBokc8GAdM8UcmfsKiSS8cipheD/nivzr700H+nsMOxJjQnvwOcRYVuFkdH0wGUvW2WbXGmrZGbQ==", + "dev": true, + "requires": { + "@isaacs/cliui": "^8.0.2", + "@pkgjs/parseargs": "^0.11.0" + } + }, "javascript-stringify": { "version": "2.1.0", "resolved": "https://registry.npmjs.org/javascript-stringify/-/javascript-stringify-2.1.0.tgz", @@ -43546,12 +43059,6 @@ "integrity": "sha512-MSJQC5vXco5Br38mzaQKiq9mwt7lwj2eXpgpRyQYNHYt2lq1PjkWa7DLXX0WVcQLE9HhMh3jPiufS7fhJf+CLQ==", "dev": true }, - "js-sdsl": { - "version": "4.2.0", - "resolved": "https://registry.npmjs.org/js-sdsl/-/js-sdsl-4.2.0.tgz", - "integrity": "sha512-dyBIzQBDkCqCu+0upx25Y2jGdbTGxE9fshMsCdK0ViOongpV+n5tXRcZY9v7CaVQ79AGS9KA1KHtojxiM7aXSQ==", - "dev": true - }, "js-sha3": { "version": "0.8.0", "resolved": "https://registry.npmjs.org/js-sha3/-/js-sha3-0.8.0.tgz", @@ -44418,12 +43925,6 @@ } } }, - "listenercount": { - "version": "1.0.1", - "resolved": "https://registry.npmjs.org/listenercount/-/listenercount-1.0.1.tgz", - "integrity": "sha512-3mk/Zag0+IJxeDrxSgaDPy4zZ3w05PRZeJNnlWhzFz5OkX49J4krc+A8X2d2M69vGMBEX0uyl8M+W+8gH+kBqQ==", - "dev": true - }, "listr2": { "version": "6.6.1", "resolved": "https://registry.npmjs.org/listr2/-/listr2-6.6.1.tgz", @@ -44692,12 +44193,6 @@ "integrity": "sha512-tCRIJM51SHjAayKwC+QAg8hT8vg6z7GSgLJKGvzuPb1Wc+hLzqtuVLxp6/HzSPOozuK+8ErAhy7U/sVzw8Dgfg==", "dev": true }, - "loglevel-plugin-prefix": { - "version": "0.8.4", - "resolved": "https://registry.npmjs.org/loglevel-plugin-prefix/-/loglevel-plugin-prefix-0.8.4.tgz", - "integrity": "sha512-WpG9CcFAOjz/FtNht+QJeGpvVl/cdR6P0z6OcXSkr8wFJOsV2GRj2j10JLfjuA4aYkcKCNIEqRGCyTife9R8/g==", - "dev": true - }, "long": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/long/-/long-4.0.0.tgz", @@ -44712,6 +44207,11 @@ "js-tokens": "^3.0.0 || ^4.0.0" } }, + "lottie-web": { + "version": "5.11.0", + "resolved": "https://registry.npmjs.org/lottie-web/-/lottie-web-5.11.0.tgz", + "integrity": "sha512-9vSt0AtdOH98GKDXwD5LPfFg9Pcmxt5+1BllAbudKM5iqPxpJnJUfuGaP45OyudDrESCOBgsjnntVUTygBNlzw==" + }, "lower-case": { "version": "2.0.2", "resolved": "https://registry.npmjs.org/lower-case/-/lower-case-2.0.2.tgz", @@ -45181,12 +44681,6 @@ "integrity": "sha512-vVqVZQyf3WLx2Shd0qJ9xuvqgAyKPLAiqITEtqW0oIUjzo3PePDd6fW9iFz30ef7Ysp/oiWqbhszeGWW2T6Gzw==", "dev": true }, - "mkdirp-classic": { - "version": "0.5.3", - "resolved": "https://registry.npmjs.org/mkdirp-classic/-/mkdirp-classic-0.5.3.tgz", - "integrity": "sha512-gKLcREMhtuZRwRAfqP3RFW+TK4JqApVBtOIftVgjuABpAtpxhPGaDcfvbhNvD0B8iD1oUr/txX35NjcaY6Ns/A==", - "dev": true - }, "mktemp": { "version": "0.4.0", "resolved": "https://registry.npmjs.org/mktemp/-/mktemp-0.4.0.tgz", @@ -45238,11 +44732,6 @@ } } }, - "mri": { - "version": "1.2.0", - "resolved": "https://registry.npmjs.org/mri/-/mri-1.2.0.tgz", - "integrity": "sha512-tzzskb3bG8LvYGFF/mDTpq3jpI6Q9wc3LEmBaghu+DdCssd1FakN7Bc0hVNmEyGq1bq3RgfkCb3cmQLpNPOroA==" - }, "ms": { "version": "2.1.2", "resolved": "https://registry.npmjs.org/ms/-/ms-2.1.2.tgz", @@ -45358,9 +44847,9 @@ "integrity": "sha512-wynEP02LmIbLpcYw8uBKpcfF6dmg2vcpKqxeH5UcoKEYdExslsdUA4ugFauuaeYdTB76ez6gJW8XAZ6CgkXYxA==" }, "nanoid": { - "version": "3.3.4", - "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.4.tgz", - "integrity": "sha512-MqBkQh/OHTS2egovRtLk45wEyNXwF+cokD+1YPf9u5VfJiRdAiRwB2froX5Co9Rh20xs4siNPm8naNotSD6RBw==", + "version": "3.3.7", + "resolved": "https://registry.npmjs.org/nanoid/-/nanoid-3.3.7.tgz", + "integrity": "sha512-eSRppjcPIatRIMC1U6UngP8XFcz8MQWGQdt1MTBQ7NaAmvXDfvNxbvWV3x2y6CdEUciCSsDHDQZbhYaB8QEo2g==", "dev": true }, "natural-compare": { @@ -45411,9 +44900,9 @@ "dev": true }, "node-fetch": { - "version": "2.6.7", - "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.7.tgz", - "integrity": "sha512-ZjMPFEfVx5j+y2yF35Kzx5sF7kDzxuDj6ziH4FFbOp87zKDZNx8yExJIb05OGF4Nlt9IHFIMBkRl41VdvcNdbQ==", + "version": "2.6.11", + "resolved": "https://registry.npmjs.org/node-fetch/-/node-fetch-2.6.11.tgz", + "integrity": "sha512-4I6pdBY1EthSqDmJkiNk3JIT8cswwR9nfeW/cPdUagJYEQG7R95WRH74wpz7ma8Gh/9dI9FP+OU+0E4FvtA55w==", "requires": { "whatwg-url": "^5.0.0" }, @@ -45747,9 +45236,9 @@ "dev": true }, "on-exit-leak-free": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.0.tgz", - "integrity": "sha512-VuCaZZAjReZ3vUwgOB8LxAosIurDiAW0s13rI1YwmaP++jvcxP77AWoQvenZebpCA2m8WC1/EosPYPMjnRAp/w==", + "version": "2.1.2", + "resolved": "https://registry.npmjs.org/on-exit-leak-free/-/on-exit-leak-free-2.1.2.tgz", + "integrity": "sha512-0eJJY6hXLGf1udHwfNftBqH+g73EU4B504nZeKpz1sYRKafAghwxEJunB2O7rDZkL4PGfsMVnTXZ2EjibbqcsA==", "dev": true }, "on-finished": { @@ -46222,25 +45711,25 @@ "integrity": "sha1-BrJhE/Vr6rBCVFojv6iAA8ysJg8=" }, "path-scurry": { - "version": "1.10.0", - "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.0.tgz", - "integrity": "sha512-tZFEaRQbMLjwrsmidsGJ6wDMv0iazJWk6SfIKnY4Xru8auXgmJkOBa5DUbYFcFD2Rzk2+KDlIiF0GVXNCbgC7g==", + "version": "1.10.1", + "resolved": "https://registry.npmjs.org/path-scurry/-/path-scurry-1.10.1.tgz", + "integrity": "sha512-MkhCqzzBEpPvxxQ71Md0b1Kk51W01lrYvlMzSUaIzNsODdd7mqhiimSZlr+VegAz5Z6Vzt9Xg2ttE//XBhH3EQ==", "dev": true, "requires": { "lru-cache": "^9.1.1 || ^10.0.0", - "minipass": "^5.0.0 || ^6.0.2" + "minipass": "^5.0.0 || ^6.0.2 || ^7.0.0" }, "dependencies": { "lru-cache": { - "version": "10.0.0", - "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.0.0.tgz", - "integrity": "sha512-svTf/fzsKHffP42sujkO/Rjs37BCIsQVRCeNYIm9WN8rgT7ffoUnRtZCqU+6BqcSBdv8gwJeTz8knJpgACeQMw==", + "version": "10.1.0", + "resolved": "https://registry.npmjs.org/lru-cache/-/lru-cache-10.1.0.tgz", + "integrity": "sha512-/1clY/ui8CzjKFyjdvwPWJUYKiFVXG2I2cY0ssG7h4+hwk+XOIX7ZSG9Q7TW8TW3Kp3BUSqgFWBLgL4PJ+Blag==", "dev": true }, "minipass": { - "version": "6.0.2", - "resolved": "https://registry.npmjs.org/minipass/-/minipass-6.0.2.tgz", - "integrity": "sha512-MzWSV5nYVT7mVyWCwn2o7JH13w2TBRmmSqSRCKzTw+lmft9X4z+3wjvs06Tzijo5z4W/kahUCDpRXTF+ZrmF/w==", + "version": "7.0.4", + "resolved": "https://registry.npmjs.org/minipass/-/minipass-7.0.4.tgz", + "integrity": "sha512-jYofLM5Dam9279rdkWzqHozUo4ybjdZmCsDHePy5V/PbBcVMiSZR97gmAy45aqi8CK1lG2ECd356FU86avfwUQ==", "dev": true } } @@ -46257,15 +45746,6 @@ "integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==", "dev": true }, - "pbf": { - "version": "3.2.1", - "resolved": "https://registry.npmjs.org/pbf/-/pbf-3.2.1.tgz", - "integrity": "sha512-ClrV7pNOn7rtmoQVF4TS1vyU0WhYRnP92fzbfF75jAIwpnzdJXf8iTd4CMEqO4yUenH6NDqLiwjqlh6QgZzgLQ==", - "requires": { - "ieee754": "^1.1.12", - "resolve-protobuf-schema": "^2.1.0" - } - }, "pend": { "version": "1.2.0", "resolved": "https://registry.npmjs.org/pend/-/pend-1.2.0.tgz", @@ -46302,9 +45782,9 @@ "dev": true }, "pino": { - "version": "8.11.0", - "resolved": "https://registry.npmjs.org/pino/-/pino-8.11.0.tgz", - "integrity": "sha512-Z2eKSvlrl2rH8p5eveNUnTdd4AjJk8tAsLkHYZQKGHP4WTh2Gi1cOSOs3eWPqaj+niS3gj4UkoreoaWgF3ZWYg==", + "version": "8.15.0", + "resolved": "https://registry.npmjs.org/pino/-/pino-8.15.0.tgz", + "integrity": "sha512-olUADJByk4twxccmAxb1RiGKOSvddHugCV3wkqjyv+3Sooa2KLrmXrKEWOKi0XPCLasRR5jBXxioE1jxUa4KzQ==", "dev": true, "requires": { "atomic-sleep": "^1.0.0", @@ -46341,15 +45821,16 @@ } }, "readable-stream": { - "version": "4.4.1", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.1.tgz", - "integrity": "sha512-llAHX9QC25bz5RPIoTeJxPaA/hgryaldValRhVZ2fK9bzbmFiscpz8fw6iBTvJfAk1w4FC1KXQme/nO7fbKyKg==", + "version": "4.4.2", + "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-4.4.2.tgz", + "integrity": "sha512-Lk/fICSyIhodxy1IDK2HazkeGjSmezAWX2egdtJnYhtzKEsBPJowlI6F6LPb5tqIQILrMbx22S5o3GuJavPusA==", "dev": true, "requires": { "abort-controller": "^3.0.0", "buffer": "^6.0.3", "events": "^3.3.0", - "process": "^0.11.10" + "process": "^0.11.10", + "string_decoder": "^1.3.0" } } } @@ -46420,13 +45901,29 @@ } } }, + "playwright": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright/-/playwright-1.39.0.tgz", + "integrity": "sha512-naE5QT11uC/Oiq0BwZ50gDmy8c8WLPRTEWuSSFVG2egBka/1qMoSqYQcROMT9zLwJ86oPofcTH2jBY/5wWOgIw==", + "dev": true, + "requires": { + "fsevents": "2.3.2", + "playwright-core": "1.39.0" + } + }, + "playwright-core": { + "version": "1.39.0", + "resolved": "https://registry.npmjs.org/playwright-core/-/playwright-core-1.39.0.tgz", + "integrity": "sha512-+k4pdZgs1qiM+OUkSjx96YiKsXsmb59evFoqv8SKO067qBA+Z2s/dCzJij/ZhdQcs2zlTAgRKfeiiLm8PQ2qvw==", + "dev": true + }, "postcss": { - "version": "8.4.21", - "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.21.tgz", - "integrity": "sha512-tP7u/Sn/dVxK2NnruI4H9BG+x+Wxz6oeZ1cJ8P6G/PZY0IKk4k/63TDsQf2kQq3+qoJeLm2kIBUNlZe3zgb4Zg==", + "version": "8.4.29", + "resolved": "https://registry.npmjs.org/postcss/-/postcss-8.4.29.tgz", + "integrity": "sha512-cbI+jaqIeu/VGqXEarWkRCCffhjgXc0qjBtXpqJhTBohMUjUQnbBr0xqX3vEKudc4iviTewcJo5ajcec5+wdJw==", "dev": true, "requires": { - "nanoid": "^3.3.4", + "nanoid": "^3.3.6", "picocolors": "^1.0.0", "source-map-js": "^1.0.2" } @@ -46489,9 +45986,9 @@ "dev": true }, "prettier": { - "version": "3.0.3", - "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.0.3.tgz", - "integrity": "sha512-L/4pUDMxcNa8R/EthV08Zt42WBO4h1rarVtK0K+QJG0X187OLo7l699jWw0GKuwzkPQ//jMFA/8Xm6Fh3J/DAg==", + "version": "3.1.0", + "resolved": "https://registry.npmjs.org/prettier/-/prettier-3.1.0.tgz", + "integrity": "sha512-TQLvXjq5IAibjh8EpBIkNKxO749UEWABoiIZehEPiY4GNpVdhaFKqSTu+QrlU6D2dPAfubRmtJTi4K4YkQ5eXw==", "dev": true }, "prettier-linter-helpers": { @@ -46549,9 +46046,9 @@ "integrity": "sha512-3ouUOpQhtgrbOa17J7+uxOTpITYWaGP7/AhoR3+A+/1e9skrzelGi/dXzEYyvbxubEF6Wn2ypscTKiKJFFn1ag==" }, "process-warning": { - "version": "2.2.0", - "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.2.0.tgz", - "integrity": "sha512-/1WZ8+VQjR6avWOgHeEPd7SDQmFQ1B5mC1eRXsCm5TarlNmx/wCsa5GEaxGm05BORRtyG/Ex/3xq3TuRvq57qg==", + "version": "2.3.1", + "resolved": "https://registry.npmjs.org/process-warning/-/process-warning-2.3.1.tgz", + "integrity": "sha512-JjBvFEn7MwFbzUDa2SRtKJSsyO0LlER4V/FmwLMhBlXNbGgGxdyFCxIdMDLerWUycsVUyaoM9QFLvppFy4IWaQ==", "dev": true }, "progress": { @@ -46639,11 +46136,6 @@ "integrity": "sha1-IS1b/hMYMGpCD2QCuOJv85ZHqEk=", "dev": true }, - "protocol-buffers-schema": { - "version": "3.6.0", - "resolved": "https://registry.npmjs.org/protocol-buffers-schema/-/protocol-buffers-schema-3.6.0.tgz", - "integrity": "sha512-TdDRD+/QNdrCGCE7v8340QyuXd4kIWIgapsE2+n/SaGiSSbomYl4TjHlvIoCWRpE7wFt02EpB35VVA2ImcBVqw==" - }, "proxy-addr": { "version": "2.0.7", "resolved": "https://registry.npmjs.org/proxy-addr/-/proxy-addr-2.0.7.tgz", @@ -46654,12 +46146,6 @@ "ipaddr.js": "1.9.1" } }, - "proxy-from-env": { - "version": "1.1.0", - "resolved": "https://registry.npmjs.org/proxy-from-env/-/proxy-from-env-1.1.0.tgz", - "integrity": "sha512-D+zkORCbA9f1tdWRK0RaCR3GPv50cMxcrz4X8k5LTSUD1Dkw47mKJEZQNunItRTkWwgtaUSo1RVFRIG9ZXiFYg==", - "dev": true - }, "psl": { "version": "1.8.0", "resolved": "https://registry.npmjs.org/psl/-/psl-1.8.0.tgz", @@ -46911,9 +46397,9 @@ "requires": {} }, "react-hook-form": { - "version": "7.40.0", - "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.40.0.tgz", - "integrity": "sha512-0rokdxMPJs0k9bvFtY6dbcSydyNhnZNXCR49jgDr/aR03FDHFOK6gfh8ccqB3fl696Mk7lqh04xdm+agqWXKSw==", + "version": "7.48.2", + "resolved": "https://registry.npmjs.org/react-hook-form/-/react-hook-form-7.48.2.tgz", + "integrity": "sha512-H0T2InFQb1hX7qKtDIZmvpU1Xfn/bdahWBN1fH19gSe4bBEqTfmlr7H3XWTaVtiK4/tpPaI1F3355GPMZYge+A==", "requires": {} }, "react-hot-loader": { @@ -47005,9 +46491,9 @@ "integrity": "sha512-fBASbA6LnOU9dOU2eW7aQ8xmYBSXUIWr+UmF9b1efZBazGNO+rcXT/icdKnYm2pTwcRylVUYwW7H1PHfLekVzA==" }, "react-loading-skeleton": { - "version": "3.1.0", - "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.1.0.tgz", - "integrity": "sha512-j1U1CWWs68nBPOg7tkQqnlFcAMFF6oEK6MgqAo15f8A5p7mjH6xyKn2gHbkcimpwfO0VQXqxAswnSYVr8lWzjw==", + "version": "3.3.1", + "resolved": "https://registry.npmjs.org/react-loading-skeleton/-/react-loading-skeleton-3.3.1.tgz", + "integrity": "sha512-NilqqwMh2v9omN7LteiDloEVpFyMIa0VGqF+ukqp0ncVlYu1sKYbYGX9JEl+GtOT9TKsh04zCHAbavnQ2USldA==", "requires": {} }, "react-player": { @@ -47551,14 +47037,6 @@ "value-or-function": "^3.0.0" } }, - "resolve-protobuf-schema": { - "version": "2.1.0", - "resolved": "https://registry.npmjs.org/resolve-protobuf-schema/-/resolve-protobuf-schema-2.1.0.tgz", - "integrity": "sha512-kI5ffTiZWmJaS/huM8wZfEMer1eRd7oJQhDuxeCLe3t7N7mX3z94CN0xPxBQxFYQTSNz9T0i+v6inKqSdK8xrQ==", - "requires": { - "protocol-buffers-schema": "^3.3.1" - } - }, "resolve.exports": { "version": "1.1.0", "resolved": "https://registry.npmjs.org/resolve.exports/-/resolve.exports-1.1.0.tgz", @@ -47841,26 +47319,6 @@ "integrity": "sha1-Yl2GWPhlr0Psliv8N2o3NZpJlMo=", "dev": true }, - "selenium-webdriver": { - "version": "4.10.0", - "resolved": "https://registry.npmjs.org/selenium-webdriver/-/selenium-webdriver-4.10.0.tgz", - "integrity": "sha512-hSQPw6jgc+ej/UEcdQPG/iBwwMeCEgZr9HByY/J8ToyXztEqXzU9aLsIyrlj1BywBcStO4JQK/zMUWWrV8+riA==", - "dev": true, - "requires": { - "jszip": "^3.10.1", - "tmp": "^0.2.1", - "ws": ">=8.13.0" - }, - "dependencies": { - "ws": { - "version": "8.13.0", - "resolved": "https://registry.npmjs.org/ws/-/ws-8.13.0.tgz", - "integrity": "sha512-x9vcZYTrFPC7aSIbj7sRCYo7L/Xb8Iy+pW0ng0wt2vCJv7M9HOMy0UoN3rr+IFC7hb7vXoqS+P9ktyLLLhO+LA==", - "dev": true, - "requires": {} - } - } - }, "selfsigned": { "version": "2.1.1", "resolved": "https://registry.npmjs.org/selfsigned/-/selfsigned-2.1.1.tgz", @@ -48368,9 +47826,9 @@ } }, "sonic-boom": { - "version": "3.3.0", - "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.3.0.tgz", - "integrity": "sha512-LYxp34KlZ1a2Jb8ZQgFCK3niIHzibdwtwNUWKg0qQRzsDoJ3Gfgkf8KdBTFU3SkejDEIlWwnSnpVdOZIhFMl/g==", + "version": "3.7.0", + "resolved": "https://registry.npmjs.org/sonic-boom/-/sonic-boom-3.7.0.tgz", + "integrity": "sha512-IudtNvSqA/ObjN97tfgNmOKyDOs4dNcg4cUUsHDebqsgb8wGBBwb31LIgShNO8fye0dFI52X1+tFoKKI6Rq1Gg==", "dev": true, "requires": { "atomic-sleep": "^1.0.0" @@ -48732,6 +48190,31 @@ } } }, + "string-width-cjs": { + "version": "npm:string-width@4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + }, + "dependencies": { + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + } + } + }, "string.prototype.matchall": { "version": "4.0.8", "resolved": "https://registry.npmjs.org/string.prototype.matchall/-/string.prototype.matchall-4.0.8.tgz", @@ -48790,6 +48273,15 @@ "ansi-regex": "^5.0.1" } }, + "strip-ansi-cjs": { + "version": "npm:strip-ansi@6.0.1", + "resolved": "https://registry.npmjs.org/strip-ansi/-/strip-ansi-6.0.1.tgz", + "integrity": "sha512-Y38VPSHcqkFrCpFnQ9vuSXmquuv5oXOKpGeT6aGrr3o3Gc9AlVa6JBfUSOCnbxGGZF+/0ooI7KrPuUSztUdU5A==", + "dev": true, + "requires": { + "ansi-regex": "^5.0.1" + } + }, "strip-bom": { "version": "4.0.0", "resolved": "https://registry.npmjs.org/strip-bom/-/strip-bom-4.0.0.tgz", @@ -48944,55 +48436,12 @@ "yallist": "^4.0.0" } }, - "tar-fs": { - "version": "3.0.4", - "resolved": "https://registry.npmjs.org/tar-fs/-/tar-fs-3.0.4.tgz", - "integrity": "sha512-5AFQU8b9qLfZCX9zp2duONhPmZv0hGYiBPJsyUdqMjzq/mqVpy/rEUSeHk1+YitmxugaptgBh5oDGU3VsAJq4w==", - "dev": true, - "requires": { - "mkdirp-classic": "^0.5.2", - "pump": "^3.0.0", - "tar-stream": "^3.1.5" - } - }, - "tar-stream": { - "version": "3.1.6", - "resolved": "https://registry.npmjs.org/tar-stream/-/tar-stream-3.1.6.tgz", - "integrity": "sha512-B/UyjYwPpMBv+PaFSWAmtYjwdrlEaZQEhMIBFNC5oEG8lpiW8XjcSdmEaClj28ArfKScKHs2nshz3k2le6crsg==", - "dev": true, - "requires": { - "b4a": "^1.6.4", - "fast-fifo": "^1.2.0", - "streamx": "^2.15.0" - } - }, "tarn": { "version": "3.0.2", "resolved": "https://registry.npmjs.org/tarn/-/tarn-3.0.2.tgz", "integrity": "sha512-51LAVKUSZSVfI05vjPESNc5vwqqZpbXCsU+/+wxlOrUjk2SnFTt97v9ZgQrD4YmxYW1Px6w2KjaDitCfkvgxMQ==", "dev": true }, - "tcp-port-used": { - "version": "1.0.2", - "resolved": "https://registry.npmjs.org/tcp-port-used/-/tcp-port-used-1.0.2.tgz", - "integrity": "sha512-l7ar8lLUD3XS1V2lfoJlCBaeoaWo/2xfYt81hM7VlvR4RrMVFqfmzfhLVk40hAb368uitje5gPtBRL1m/DGvLA==", - "dev": true, - "requires": { - "debug": "4.3.1", - "is2": "^2.0.6" - }, - "dependencies": { - "debug": { - "version": "4.3.1", - "resolved": "https://registry.npmjs.org/debug/-/debug-4.3.1.tgz", - "integrity": "sha512-doEwdvm4PCeK4K3RQN2ZC2BYUBaxwLARCqZmMjtF8a51J2Rb0xpVloFRnCODwqjpwnAoao4pelN8l3RJdv3gRQ==", - "dev": true, - "requires": { - "ms": "2.1.2" - } - } - } - }, "teex": { "version": "1.0.1", "resolved": "https://registry.npmjs.org/teex/-/teex-1.0.1.tgz", @@ -49083,9 +48532,9 @@ } }, "thread-stream": { - "version": "2.3.0", - "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.3.0.tgz", - "integrity": "sha512-kaDqm1DET9pp3NXwR8382WHbnpXnRkN9xGN9dQt3B2+dmXiW8X1SOwmFOxAErEQ47ObhZ96J6yhZNXuyCOL7KA==", + "version": "2.4.1", + "resolved": "https://registry.npmjs.org/thread-stream/-/thread-stream-2.4.1.tgz", + "integrity": "sha512-d/Ex2iWd1whipbT681JmTINKw0ZwOUBZm7+Gjs64DHuX34mmw8vJL2bFAaNacaW72zYiTJxSHi5abUuOi5nsfg==", "dev": true, "requires": { "real-require": "^0.2.0" @@ -49296,12 +48745,6 @@ "punycode": "^2.1.1" } }, - "traverse": { - "version": "0.3.9", - "resolved": "https://registry.npmjs.org/traverse/-/traverse-0.3.9.tgz", - "integrity": "sha512-iawgk0hLP3SxGKDfnDJf8wTz4p2qImnyihM5Hh/sGvQ3K37dPi/w8sRhdNIxYA1TwFwc5mDhIJq+O0RsvXBKdQ==", - "dev": true - }, "tree-kill": { "version": "1.2.2", "resolved": "https://registry.npmjs.org/tree-kill/-/tree-kill-1.2.2.tgz", @@ -49747,6 +49190,11 @@ "util-deprecate": "^1.0.2" } }, + "undici-types": { + "version": "5.26.5", + "resolved": "https://registry.npmjs.org/undici-types/-/undici-types-5.26.5.tgz", + "integrity": "sha512-JlCMO+ehdEIKqlFxk6IfVoAUVmgz7cU7zD/h9XZ0qzeosSHmUJVOzSQvvYSYWXkFXC+IfLKSIffhv0sVZup6pA==" + }, "unicode-canonical-property-names-ecmascript": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/unicode-canonical-property-names-ecmascript/-/unicode-canonical-property-names-ecmascript-2.0.0.tgz", @@ -49839,56 +49287,6 @@ "integrity": "sha512-KK8xQ1mkzZeg9inewmFVDNkg3l5LUhoq9kN6iWYB/CC9YMG8HA+c1Q8HwDe6dEX7kErrEVNVBO3fWsVq5iDgtw==", "dev": true }, - "unzipper": { - "version": "0.10.14", - "resolved": "https://registry.npmjs.org/unzipper/-/unzipper-0.10.14.tgz", - "integrity": "sha512-ti4wZj+0bQTiX2KmKWuwj7lhV+2n//uXEotUmGuQqrbVZSEGFMbI68+c6JCQ8aAmUWYvtHEz2A8K6wXvueR/6g==", - "dev": true, - "requires": { - "big-integer": "^1.6.17", - "binary": "~0.3.0", - "bluebird": "~3.4.1", - "buffer-indexof-polyfill": "~1.0.0", - "duplexer2": "~0.1.4", - "fstream": "^1.0.12", - "graceful-fs": "^4.2.2", - "listenercount": "~1.0.1", - "readable-stream": "~2.3.6", - "setimmediate": "~1.0.4" - }, - "dependencies": { - "bluebird": { - "version": "3.4.7", - "resolved": "https://registry.npmjs.org/bluebird/-/bluebird-3.4.7.tgz", - "integrity": "sha512-iD3898SR7sWVRHbiQv+sHUtHnMvC1o3nW5rAcqnq3uOn07DSAppZYUkIGslDz6gXC7HfunPe7YVBgoEJASPcHA==", - "dev": true - }, - "readable-stream": { - "version": "2.3.8", - "resolved": "https://registry.npmjs.org/readable-stream/-/readable-stream-2.3.8.tgz", - "integrity": "sha512-8p0AUk4XODgIewSi0l8Epjs+EVnWiK7NoDIEGU0HhE7+ZyY8D1IMY7odu5lRrFXGg71L15KG8QrPmum45RTtdA==", - "dev": true, - "requires": { - "core-util-is": "~1.0.0", - "inherits": "~2.0.3", - "isarray": "~1.0.0", - "process-nextick-args": "~2.0.0", - "safe-buffer": "~5.1.1", - "string_decoder": "~1.1.1", - "util-deprecate": "~1.0.1" - } - }, - "string_decoder": { - "version": "1.1.1", - "resolved": "https://registry.npmjs.org/string_decoder/-/string_decoder-1.1.1.tgz", - "integrity": "sha512-n/ShnvDi6FHbbVfviro+WojiFzv+s8MPMHBczVePfUpDJLwoLT0ht1l4YwBCbi8pJAveEEdnkHyPyTP/mzRfwg==", - "dev": true, - "requires": { - "safe-buffer": "~5.1.0" - } - } - } - }, "upath": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/upath/-/upath-2.0.1.tgz", @@ -50317,14 +49715,14 @@ } }, "web-ext": { - "version": "7.6.2", - "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.6.2.tgz", - "integrity": "sha512-xlxbzgFBIS/UWWlvWxyR1PIqRRzDj1cutoHh+VZu4ZTcJTfv35KVdKkLRZv4PQwHu4dg8VfTg7WEcNP4QLaaFQ==", + "version": "7.8.0", + "resolved": "https://registry.npmjs.org/web-ext/-/web-ext-7.8.0.tgz", + "integrity": "sha512-ta+VjbNfK5q0pqRmrlH/DQMdJ89sAJFfgcvpqoUoe2gPxLu18zZ5mIakGvyjmfjrkJLOZ2NCNF7suj/qd6xaEQ==", "dev": true, "requires": { "@babel/runtime": "7.21.0", "@devicefarmer/adbkit": "3.2.3", - "addons-linter": "5.32.0", + "addons-linter": "6.13.0", "bunyan": "1.8.15", "camelcase": "7.0.1", "chrome-launcher": "0.15.1", @@ -50892,6 +50290,66 @@ } } }, + "wrap-ansi-cjs": { + "version": "npm:wrap-ansi@7.0.0", + "resolved": "https://registry.npmjs.org/wrap-ansi/-/wrap-ansi-7.0.0.tgz", + "integrity": "sha512-YVGIj2kamLSTxw6NsZjoBxfSwsn0ycdesmc4p+Q21c5zPuZ1pl+NfxVdxPtdHvmNVOQ6XSYG4AUtyt/Fi7D16Q==", + "dev": true, + "requires": { + "ansi-styles": "^4.0.0", + "string-width": "^4.1.0", + "strip-ansi": "^6.0.0" + }, + "dependencies": { + "ansi-styles": { + "version": "4.3.0", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz", + "integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==", + "dev": true, + "requires": { + "color-convert": "^2.0.1" + } + }, + "color-convert": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz", + "integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==", + "dev": true, + "requires": { + "color-name": "~1.1.4" + } + }, + "color-name": { + "version": "1.1.4", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz", + "integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==", + "dev": true + }, + "emoji-regex": { + "version": "8.0.0", + "resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-8.0.0.tgz", + "integrity": "sha512-MSjYzcWNOA0ewAHpz0MxpYFvwg6yjy1NG3xteoqz644VCo/RPgnr1/GGt+ic3iJTzQ8Eu3TdM14SawnVUmGE6A==", + "dev": true + }, + "is-fullwidth-code-point": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/is-fullwidth-code-point/-/is-fullwidth-code-point-3.0.0.tgz", + "integrity": "sha512-zymm5+u+sCsSWyD9qNaejV3DFvhCKclKdizYaJUuHA83RLjb7nSuGnddCHGv0hk+KY7BMAlsWeK4Ueg6EV6XQg==", + "dev": true + }, + "string-width": { + "version": "4.2.3", + "resolved": "https://registry.npmjs.org/string-width/-/string-width-4.2.3.tgz", + "integrity": "sha512-wKyQRQpjJ0sIp62ErSZdGsjMJWsap5oRNihHhu6G7JVO/9jIB6UyevL+tXuOqrng8j/cxKTWyWUwvSTriiZz/g==", + "dev": true, + "requires": { + "emoji-regex": "^8.0.0", + "is-fullwidth-code-point": "^3.0.0", + "strip-ansi": "^6.0.1" + } + } + } + }, "wrappy": { "version": "1.0.2", "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", @@ -50967,12 +50425,6 @@ "integrity": "sha512-JZnDKK8B0RCDw84FNdDAIpZK+JuJw+s7Lz8nksI7SIuU3UXJJslUthsi+uWBUYOwPFwW7W7PRLRfUKpxjtjFCw==", "dev": true }, - "xpath-builder": { - "version": "0.0.7", - "resolved": "https://registry.npmjs.org/xpath-builder/-/xpath-builder-0.0.7.tgz", - "integrity": "sha1-Z9a7w/ajIOwxfj5jaMVwa2ER3uw=", - "dev": true - }, "xtend": { "version": "4.0.2", "resolved": "https://registry.npmjs.org/xtend/-/xtend-4.0.2.tgz", @@ -51069,14 +50521,6 @@ "fd-slicer": "~1.1.0" } }, - "yazl": { - "version": "2.5.1", - "resolved": "https://registry.npmjs.org/yazl/-/yazl-2.5.1.tgz", - "integrity": "sha512-phENi2PLiHnHb6QBVot+dJnaAZ0xosj7p3fWl+znIjBDlnMI2PsZCJZ306BPTFOaHf5qdDEI8x5qFrSOBN5vrw==", - "requires": { - "buffer-crc32": "~0.2.3" - } - }, "yn": { "version": "3.1.1", "resolved": "https://registry.npmjs.org/yn/-/yn-3.1.1.tgz", diff --git a/package.json b/package.json index c2f82f35a..2efadb5b9 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "name": "Casper Wallet", "description": "Securely manage your CSPR tokens and interact with dapps with the self-custody wallet for the Casper blockchain.", - "version": "1.7.1", + "version": "1.8.0", "author": "MAKE LLC", "scripts": { "devtools:redux": "redux-devtools --hostname=localhost", @@ -25,12 +25,6 @@ "dev:firefox": "npm run dev:build:firefox && NODE_ENV=development BABEL_ENV=development BROWSER=firefox HASH=$(git rev-parse HEAD) PORT=3002 node utils/webserver.js", "start:firefox": "concurrently -k -n start,redux \"npm run dev:firefox\" \"npm run devtools:redux -- --port=8001\"", "start:safari": "npm run dev:build:manifest:v2:safari && ./convert-web-extension.sh && NODE_ENV=development BABEL_ENV=development BROWSER=safari PORT=3003 node utils/webserver.js", - "test:e2e:chrome": "npm run build:chrome && npm run pack-extension:chrome && SELENIUM_BROWSER=chrome jest --config=jest.e2e.config.js --detectOpenHandles e2e/tests && npm run remove-packed-extension:chrome", - "test:e2e:firefox": "npm run build:firefox && SELENIUM_BROWSER=firefox jest --config=jest.e2e.config.js --detectOpenHandles e2e/tests", - "test:e2e:chrome:headless:onboarding": "npm run build:chrome && npm run pack-extension:chrome && SELENIUM_BROWSER=chrome SELENIUM_HEADLESS=true jest --config=jest.e2e.config.js --detectOpenHandles e2e/tests/onboarding-flow && npm run remove-packed-extension:chrome", - "test:e2e:chrome:headless:popup": "MOCK_STATE=true npm run build:chrome && npm run pack-extension:chrome && SELENIUM_BROWSER=chrome SELENIUM_HEADLESS=true jest --config=jest.e2e.config.js --detectOpenHandles e2e/tests/popup && npm run remove-packed-extension:chrome", - "test:e2e:firefox:headless:onboarding": "npm run build:firefox && SELENIUM_BROWSER=firefox SELENIUM_HEADLESS=true jest --config=jest.e2e.config.js --detectOpenHandles e2e/tests/onboarding-flow", - "test:e2e:firefox:headless:popup": "MOCK_STATE=true npm run build:firefox && SELENIUM_BROWSER=firefox SELENIUM_HEADLESS=true jest --config=jest.e2e.config.js --detectOpenHandles e2e/tests/popup", "format:check": "prettier --check 'src/*.{js,jsx,ts,tsx,json,md}'", "format:write": "prettier --write 'src/*.{js,jsx,ts,tsx,json,md}'", "lint": "eslint ./src --ext .js,.jsx,.ts,.tsx", @@ -43,8 +37,10 @@ "dependency:graph": "npx madge --ts-config=tsconfig.json --image=graph.svg src/background/index.ts", "dependency:circular": "npx madge --ts-config=tsconfig.json --circular src/background/index.ts", "dependency:orphans": "npx madge --ts-config=tsconfig.json --orphans src/**/*", - "pack-extension:chrome": "crx3 --keyPath e2e/crx3.pem build/chrome", - "remove-packed-extension:chrome": "rm -rf chrome.crx" + "e2e:chrome:headless:onboarding": "TEST_ENV=true npm run build:chrome && PLAYWRIGHT_BROWSER=chromium npx playwright test e2e-tests/onboarding-flow --project chromium", + "e2e:chrome:ui:onboarding": "TEST_ENV=true npm run build:chrome && PLAYWRIGHT_BROWSER=chromium npx playwright test e2e-tests/onboarding-flow --ui --project chromium", + "e2e:chrome:headless:popup": "TEST_ENV=true MOCK_STATE=true npm run build:chrome && PLAYWRIGHT_BROWSER=chromium npx playwright test e2e-tests/popup --project chromium", + "e2e:chrome:ui:popup": "TEST_ENV=true MOCK_STATE=true npm run build:chrome && PLAYWRIGHT_BROWSER=chromium npx playwright test e2e-tests/popup --ui --project chromium" }, "lint-staged": { "*.md": "markdownlint", @@ -61,6 +57,7 @@ "@hot-loader/react-dom": "^17.0.1", "@lapo/asn1js": "1.2.4", "@make-software/ces-js-parser": "1.3.2", + "@lottiefiles/react-lottie-player": "3.5.3", "@noble/ciphers": "^0.3.0", "@scure/bip32": "1.3.2", "@scure/bip39": "1.2.1", @@ -70,7 +67,6 @@ "big.js": "^6.2.1", "casper-cep18-js-client": "1.0.2", "casper-js-sdk": "2.13.3", - "crx3": "^1.1.3", "date-fns": "^2.30.0", "facepaint": "^1.2.1", "i18next": "^23.5.1", @@ -83,13 +79,13 @@ "qrcode.react": "^3.1.0", "react": "^17.0.2", "react-dom": "^17.0.2", - "react-hook-form": "7.40.0", + "react-hook-form": "7.48.2", "react-hot-loader": "4.13.1", "react-i18next": "12.0.0", "react-identicons": "^1.2.5", "react-infinite-scroll-hook": "^4.1.1", "react-inlinesvg": "^3.0.1", - "react-loading-skeleton": "^3.1.0", + "react-loading-skeleton": "^3.3.1", "react-player": "^2.13.0", "react-query": "^3.39.3", "react-redux": "8.0.5", @@ -106,6 +102,7 @@ "@babel/plugin-proposal-class-properties": "7.18.6", "@babel/preset-env": "7.23.2", "@babel/preset-react": "7.18.6", + "@playwright/test": "^1.39.0", "@redux-devtools/cli": "^3.0.1", "@testing-library/dom": "8.19.0", "@testing-library/jest-dom": "^5.16.5", @@ -118,20 +115,18 @@ "@types/facepaint": "^1.2.3", "@types/jest": "29.2.3", "@types/lodash.throttle": "4.1.7", + "@types/node": "^20.9.0", "@types/react": "^17.0.33", "@types/react-dom": "^17.0.10", "@types/remote-redux-devtools": "^0.5.5", - "@types/selenium-webdriver": "4.1.9", "@types/styled-components": "^5.1.26", "@types/testing-library__react": "^10.2.0", "babel-eslint": "^10.1.0", "babel-loader": "9.1.0", "babel-preset-react-app": "^10.0.0", - "chromedriver": "^119.0.1", "concurrently": "7.6.0", "copy-webpack-plugin": "^11.0.0", "css-loader": "6.8.1", - "css-to-xpath": "^0.1.0", "eslint": "8.49.0", "eslint-config-airbnb": "^19.0.4", "eslint-config-prettier": "^8.3.0", @@ -144,9 +139,8 @@ "eslint-plugin-react-hooks": "4.6.0", "file-loader": "^6.2.0", "fs-extra": "11.1.1", - "geckodriver": "4.2.1", "html-loader": "4.2.0", - "html-webpack-plugin": "^5.5.0", + "html-webpack-plugin": "^5.5.3", "husky": "8.0.2", "i18next-conv": "14.0.0", "jest": "29.3.1", @@ -154,9 +148,8 @@ "lint-staged": "14.0.1", "markdownlint": "0.26.2", "markdownlint-cli": "0.32.2", - "prettier": "3.0.3", + "prettier": "3.1.0", "remote-redux-devtools": "^0.5.16", - "selenium-webdriver": "4.10.0", "source-map-loader": "4.0.1", "style-loader": "^3.3.1", "terser-webpack-plugin": "5.3.6", @@ -166,7 +159,7 @@ "tsconfig-paths-webpack-plugin": "^4.1.0", "typescript": "4.9.3", "url-loader": "^4.1.1", - "web-ext": "7.6.2", + "web-ext": "7.8.0", "webextension-polyfill": "0.10.0", "webpack": "5.88.2", "webpack-cli": "5.1.4", diff --git a/playwright.config.ts b/playwright.config.ts new file mode 100644 index 000000000..52684bdac --- /dev/null +++ b/playwright.config.ts @@ -0,0 +1,44 @@ +import { defineConfig, devices } from '@playwright/test'; + +/** + * Read environment variables from file. + * https://github.com/motdotla/dotenv + */ +// require('dotenv').config(); + +/** + * See https://playwright.dev/docs/test-configuration. + */ +export default defineConfig({ + testDir: './e2e-tests', + /* Run tests in files in parallel */ + fullyParallel: true, + /* Fail the build on CI if you accidentally left test.only in the source code. */ + forbidOnly: !!process.env.CI, + /* Retry on CI only */ + retries: process.env.CI ? 2 : 0, + /* Opt out of parallel tests on CI. */ + workers: process.env.CI ? 2 : undefined, + /* Reporter to use. See https://playwright.dev/docs/test-reporters */ + reporter: 'html', + /* Shared settings for all the projects below. See https://playwright.dev/docs/api/class-testoptions. */ + use: { + /* Base URL to use in actions like `await page.goto('/')`. */ + // baseURL: 'http://127.0.0.1:3000', + + /* Collect trace when retrying the failed test. See https://playwright.dev/docs/trace-viewer */ + trace: 'on-first-retry', + + contextOptions: { + permissions: ['clipboard-read', 'clipboard-write', 'accessibility-events'] + } + }, + + /* Configure projects for major browsers */ + projects: [ + { + name: 'chromium', + use: { ...devices['Desktop Chrome'] } + } + ] +}); diff --git a/src/apps/connect-to-app/index.tsx b/src/apps/connect-to-app/index.tsx index 1178bb570..43148a6b7 100644 --- a/src/apps/connect-to-app/index.tsx +++ b/src/apps/connect-to-app/index.tsx @@ -11,15 +11,22 @@ import { ErrorBoundary } from '@src/libs/layout/error'; import { createMainStoreReplica, + dispatchToMainStore, PopupState } from '@src/background/redux/utils'; import { connectWindowInit } from '@src/background/redux/windowManagement/actions'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { selectDarkModeSetting } from '@background/redux/settings/selectors'; +import { selectThemeModeSetting } from '@background/redux/settings/selectors'; +import { useSystemThemeDetector } from '@src/hooks'; +import { themeModeSettingChanged } from '@background/redux/settings/actions'; +import { ThemeMode } from '@background/redux/settings/types'; +import { isSafariBuild } from '@src/utils'; const Tree = () => { const [state, setState] = useState(null); + const isSystemDarkTheme = useSystemThemeDetector(); + useSubscribeToRedux({ windowInitAction: connectWindowInit, setPopupState: setState @@ -31,7 +38,19 @@ const Tree = () => { const store = createMainStoreReplica(state); - const isDarkMode = selectDarkModeSetting(store.getState()); + const themeMode = selectThemeModeSetting(store.getState()); + + // Set theme mode to system if it is no present in the store + if (themeMode === undefined && !isSafariBuild) { + dispatchToMainStore(themeModeSettingChanged(ThemeMode.SYSTEM)); + } else if (themeMode === undefined && isSafariBuild) { + dispatchToMainStore(themeModeSettingChanged(ThemeMode.LIGHT)); + } + + const isDarkMode = + themeMode === ThemeMode.SYSTEM + ? isSystemDarkTheme + : themeMode === ThemeMode.DARK; return ( diff --git a/src/apps/import-account-with-file/index.tsx b/src/apps/import-account-with-file/index.tsx index 3d4c3f07e..eb909f2cf 100644 --- a/src/apps/import-account-with-file/index.tsx +++ b/src/apps/import-account-with-file/index.tsx @@ -8,6 +8,7 @@ import { Provider as ReduxProvider } from 'react-redux'; import { importWindowInit } from '@src/background/redux/windowManagement/actions'; import { createMainStoreReplica, + dispatchToMainStore, PopupState } from '@src/background/redux/utils'; import { darkTheme, GlobalStyle, lightTheme } from '@libs/ui'; @@ -15,11 +16,17 @@ import { ErrorBoundary } from '@src/libs/layout/error'; import { AppRouter } from './app-router'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; -import { selectDarkModeSetting } from '@background/redux/settings/selectors'; +import { selectThemeModeSetting } from '@background/redux/settings/selectors'; +import { useSystemThemeDetector } from '@src/hooks'; +import { themeModeSettingChanged } from '@background/redux/settings/actions'; +import { ThemeMode } from '@background/redux/settings/types'; +import { isSafariBuild } from '@src/utils'; const Tree = () => { const [state, setState] = useState(null); + const isDarkTheme = useSystemThemeDetector(); + useSubscribeToRedux({ windowInitAction: importWindowInit, setPopupState: setState @@ -31,7 +38,17 @@ const Tree = () => { const store = createMainStoreReplica(state); - const isDarkMode = selectDarkModeSetting(store.getState()); + const themeMode = selectThemeModeSetting(store.getState()); + + // Set theme mode to system if it is no present in the store + if (themeMode === undefined && !isSafariBuild) { + dispatchToMainStore(themeModeSettingChanged(ThemeMode.SYSTEM)); + } else if (themeMode === undefined && isSafariBuild) { + dispatchToMainStore(themeModeSettingChanged(ThemeMode.LIGHT)); + } + + const isDarkMode = + themeMode === ThemeMode.SYSTEM ? isDarkTheme : themeMode === ThemeMode.DARK; return ( diff --git a/src/apps/popup/app-router.tsx b/src/apps/popup/app-router.tsx index 10691c271..5f6a3ecce 100644 --- a/src/apps/popup/app-router.tsx +++ b/src/apps/popup/app-router.tsx @@ -21,7 +21,7 @@ import { CreateAccountPage } from '@src/apps/popup/pages/create-account'; import { DownloadSecretKeysPage } from '@popup/pages/download-secret-keys'; import { DownloadedSecretKeysPage } from '@popup/pages/downloaded-secret-keys'; -import { RouterPath, useTypedLocation } from '@popup/router'; +import { RouterPath, useTypedLocation, useTypedNavigate } from '@popup/router'; import { selectVaultHasAccounts } from '@background/redux/vault/selectors'; @@ -38,6 +38,10 @@ import { WalletQrCodePage } from '@popup/pages/wallet-qr-code'; import { TransferNftPage } from '@popup/pages/transfer-nft'; import { ChangePasswordPage } from '@popup/pages/change-password'; import { StakesPage } from '@popup/pages/stakes'; +import { ErrorPath, WindowErrorPage } from '@layout/error'; +import { ContactsBookPage } from '@popup/pages/contacts'; +import { AddContactPage } from '@popup/pages/add-contact'; +import { ContactDetailsPage } from '@popup/pages/contact-details'; export function AppRouter() { const isLocked = useSelector(selectVaultIsLocked); @@ -255,6 +259,21 @@ function AppRoutes() { /> } /> } /> + + } + /> + } /> + } /> + } + /> ); } diff --git a/src/apps/popup/index.tsx b/src/apps/popup/index.tsx index ca275e9c1..c5adf3aed 100644 --- a/src/apps/popup/index.tsx +++ b/src/apps/popup/index.tsx @@ -6,10 +6,17 @@ import { ThemeProvider } from 'styled-components'; import { darkTheme, GlobalStyle, lightTheme } from '@libs/ui'; import { ErrorBoundary } from '@src/libs/layout/error'; import { useSubscribeToRedux } from '@src/hooks/use-subscribe-to-redux'; - -import { createMainStoreReplica, PopupState } from '@background/redux/utils'; +import { + createMainStoreReplica, + dispatchToMainStore, + PopupState +} from '@background/redux/utils'; import { popupWindowInit } from '@background/redux/windowManagement/actions'; -import { selectDarkModeSetting } from '@background/redux/settings/selectors'; +import { selectThemeModeSetting } from '@background/redux/settings/selectors'; +import { ThemeMode } from '@background/redux/settings/types'; +import { useSystemThemeDetector } from '@src/hooks'; +import { themeModeSettingChanged } from '@background/redux/settings/actions'; +import { isSafariBuild } from '@src/utils'; import { AppRouter } from './app-router'; @@ -19,6 +26,8 @@ import 'react-loading-skeleton/dist/skeleton.css'; const Tree = () => { const [state, setState] = useState(null); + const isSystemDarkTheme = useSystemThemeDetector(); + useSubscribeToRedux({ windowInitAction: popupWindowInit, setPopupState: setState @@ -30,7 +39,19 @@ const Tree = () => { const store = createMainStoreReplica(state); - const isDarkMode = selectDarkModeSetting(store.getState()); + const themeMode = selectThemeModeSetting(store.getState()); + + // Set theme mode to system if it is no present in the store + if (themeMode === undefined && !isSafariBuild) { + dispatchToMainStore(themeModeSettingChanged(ThemeMode.SYSTEM)); + } else if (themeMode === undefined && isSafariBuild) { + dispatchToMainStore(themeModeSettingChanged(ThemeMode.LIGHT)); + } + + const isDarkMode = + themeMode === ThemeMode.SYSTEM + ? isSystemDarkTheme + : themeMode === ThemeMode.DARK; return ( diff --git a/src/apps/popup/pages/add-contact/content.tsx b/src/apps/popup/pages/add-contact/content.tsx new file mode 100644 index 000000000..945888e68 --- /dev/null +++ b/src/apps/popup/pages/add-contact/content.tsx @@ -0,0 +1,59 @@ +import React from 'react'; +import { FieldErrors, UseFormRegister } from 'react-hook-form'; +import { useTranslation } from 'react-i18next'; + +import { + ContentContainer, + InputsContainer, + ParagraphContainer, + SpacingSize +} from '@libs/layout'; +import { + FormField, + FormFieldStatus, + Input, + TextArea, + Typography +} from '@libs/ui'; +import { ContactFromValues } from '@libs/ui/forms/contact'; + +interface AddContactPageContentProps { + register: UseFormRegister; + errors: FieldErrors; +} + +export const AddContactPageContent = ({ + register, + errors +}: AddContactPageContentProps) => { + const { t } = useTranslation(); + + return ( + + + New contact + + + + +