From 074146d7a5b5639c38d6b214f286815c19b152b6 Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Wed, 7 Feb 2024 10:57:41 +0100 Subject: [PATCH 01/11] Refactor: remove custom ENS resolver for Sepolia (#3204) --- src/components/common/AddressInput/index.tsx | 2 +- .../flows/NftTransfer/SendNftBatch.tsx | 2 +- .../TokenTransfer/CreateTokenTransfer.tsx | 6 +---- .../__tests__/CreateTokenTransfer.test.tsx | 2 +- src/services/ens/config.ts | 6 ----- src/services/ens/custom.ts | 24 ------------------- src/services/ens/index.test.ts | 17 ++----------- src/services/ens/index.ts | 8 ------- 8 files changed, 6 insertions(+), 61 deletions(-) delete mode 100644 src/services/ens/config.ts delete mode 100644 src/services/ens/custom.ts diff --git a/src/components/common/AddressInput/index.tsx b/src/components/common/AddressInput/index.tsx index d4789d5976..a72a2e950e 100644 --- a/src/components/common/AddressInput/index.tsx +++ b/src/components/common/AddressInput/index.tsx @@ -117,7 +117,7 @@ const AddressInput = ({ className={inputCss.input} autoComplete="off" autoFocus={props.focused} - label={<>{error?.message || props.label}} + label={<>{error?.message || props.label || `Recipient address${isDomainLookupEnabled ? ' or ENS' : ''}`}} error={!!error} fullWidth spellCheck={false} diff --git a/src/components/tx-flow/flows/NftTransfer/SendNftBatch.tsx b/src/components/tx-flow/flows/NftTransfer/SendNftBatch.tsx index f60583c5e7..9f2bb7977c 100644 --- a/src/components/tx-flow/flows/NftTransfer/SendNftBatch.tsx +++ b/src/components/tx-flow/flows/NftTransfer/SendNftBatch.tsx @@ -113,7 +113,7 @@ const SendNftBatch = ({ params, onSubmit }: SendNftBatchProps) => {
- + diff --git a/src/components/tx-flow/flows/TokenTransfer/CreateTokenTransfer.tsx b/src/components/tx-flow/flows/TokenTransfer/CreateTokenTransfer.tsx index f312db8aaf..6900b3c3ed 100644 --- a/src/components/tx-flow/flows/TokenTransfer/CreateTokenTransfer.tsx +++ b/src/components/tx-flow/flows/TokenTransfer/CreateTokenTransfer.tsx @@ -103,11 +103,7 @@ export const CreateTokenTransfer = ({ - + diff --git a/src/components/tx-flow/flows/TokenTransfer/__tests__/CreateTokenTransfer.test.tsx b/src/components/tx-flow/flows/TokenTransfer/__tests__/CreateTokenTransfer.test.tsx index af351c4fa9..01c52de3bd 100644 --- a/src/components/tx-flow/flows/TokenTransfer/__tests__/CreateTokenTransfer.test.tsx +++ b/src/components/tx-flow/flows/TokenTransfer/__tests__/CreateTokenTransfer.test.tsx @@ -29,7 +29,7 @@ describe('CreateTokenTransfer', () => { , ) - expect(getAllByText('Recipient address or ENS')[0]).toBeInTheDocument() + expect(getAllByText('Recipient address')[0]).toBeInTheDocument() }) it('should disable the submit button and display a warning if $SAFE token is selected and not transferable', () => { diff --git a/src/services/ens/config.ts b/src/services/ens/config.ts deleted file mode 100644 index 7f96cde9f6..0000000000 --- a/src/services/ens/config.ts +++ /dev/null @@ -1,6 +0,0 @@ -/** - * @see https://docs.ens.domains/ens-deployments - */ -export const CUSTOM_REGISTRIES: Record = { - '11155111': '0x00000000000C2E074eC69A0dFb2997BA6C7d2e1e', // ENS on Sepolia -} diff --git a/src/services/ens/custom.ts b/src/services/ens/custom.ts deleted file mode 100644 index ca6d629596..0000000000 --- a/src/services/ens/custom.ts +++ /dev/null @@ -1,24 +0,0 @@ -import { Contract, namehash, ZeroAddress, type Provider } from 'ethers' - -// ENS Registry ABI (simplified version) -const ensRegistryAbi = ['function resolver(bytes32 node) external view returns (address)'] -const resolverAbi = ['function addr(bytes32 node) external view returns (address)'] - -export const customResolveName = async ( - registryAddress: string, - rpcProvider: Provider, - name: string, -): Promise => { - const ensRegistry = new Contract(registryAddress, ensRegistryAbi, rpcProvider) - const nhash = namehash(name) - const resolverAddress = await ensRegistry.resolver(nhash) - - if (resolverAddress === ZeroAddress) { - return undefined - } - - const resolver = new Contract(resolverAddress, resolverAbi, rpcProvider) - const address = await resolver.addr(nhash) - - return address || undefined -} diff --git a/src/services/ens/index.test.ts b/src/services/ens/index.test.ts index 42ac92a54a..c66abf42d8 100644 --- a/src/services/ens/index.test.ts +++ b/src/services/ens/index.test.ts @@ -4,7 +4,7 @@ import { logError } from '../exceptions' // mock rpcProvider const rpcProvider = { - resolveName: jest.fn(() => Promise.resolve('0x0000000000000000000000000000000000000000')), + resolveName: jest.fn(() => Promise.resolve('0x0000000000000000000000000000000000000001')), lookupAddress: jest.fn(() => Promise.resolve('safe.eth')), getNetwork: jest.fn(() => Promise.resolve({ chainId: 1 })), } as unknown as JsonRpcProvider @@ -20,10 +20,6 @@ jest.mock('../exceptions', () => ({ logError: jest.fn(), })) -jest.mock('./custom', () => ({ - customResolveName: jest.fn(() => Promise.resolve('0x0000001111111111111111111111111111111111')), -})) - describe('domains', () => { describe('isDomain', () => { it('should check the domain format', async () => { @@ -37,7 +33,7 @@ describe('domains', () => { describe('resolveName', () => { it('should resolve names', async () => { - expect(await resolveName(rpcProvider, 'test.eth')).toBe('0x0000000000000000000000000000000000000000') + expect(await resolveName(rpcProvider, 'test.eth')).toBe('0x0000000000000000000000000000000000000001') }) it('should return undefined and log on error', async () => { @@ -45,15 +41,6 @@ describe('domains', () => { expect(address).toBe(undefined) expect(logError).toHaveBeenCalledWith('101: Failed to resolve the address', 'bad resolveName') }) - - it('should look up names on Sepolia', async () => { - // mock rpcProvider - const rpcProvider = { - getNetwork: jest.fn(() => Promise.resolve({ chainId: 11155111 })), - } as unknown as JsonRpcProvider - - expect(await resolveName(rpcProvider, 'sepolia.eth')).toBe('0x0000001111111111111111111111111111111111') - }) }) describe('lookupAddress', () => { diff --git a/src/services/ens/index.ts b/src/services/ens/index.ts index 60b98da554..295f1368fc 100644 --- a/src/services/ens/index.ts +++ b/src/services/ens/index.ts @@ -1,8 +1,6 @@ import { type Provider } from 'ethers' import { logError } from '../exceptions' import ErrorCodes from '../exceptions/ErrorCodes' -import { CUSTOM_REGISTRIES } from './config' -import { customResolveName } from './custom' type EthersError = Error & { reason?: string @@ -22,12 +20,6 @@ export const resolveName = async (rpcProvider: Provider, name: string): Promise< } catch {} try { - // Try custom resolvers first - if (chainId && CUSTOM_REGISTRIES[chainId]) { - return await customResolveName(CUSTOM_REGISTRIES[chainId], rpcProvider, name) - } - - // The default ENS resolver return (await rpcProvider.resolveName(name)) || undefined } catch (e) { const err = e as EthersError From 5908386a71f4294115cb08cd13bde8a7c3a52054 Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Wed, 7 Feb 2024 12:58:02 +0100 Subject: [PATCH 02/11] Fix: update the Safe Apps SDK link (#3213) --- src/components/safe-apps/AddCustomAppModal/index.tsx | 2 +- src/config/constants.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/components/safe-apps/AddCustomAppModal/index.tsx b/src/components/safe-apps/AddCustomAppModal/index.tsx index c32fce32cf..eeae0cc239 100644 --- a/src/components/safe-apps/AddCustomAppModal/index.tsx +++ b/src/components/safe-apps/AddCustomAppModal/index.tsx @@ -45,7 +45,7 @@ type CustomAppFormData = { safeApp: SafeAppData } -const HELP_LINK = 'https://docs.safe.global/safe-core-aa-sdk/safe-apps/get-started' +const HELP_LINK = 'https://docs.safe.global/apps-sdk-overview' const APP_ALREADY_IN_THE_LIST_ERROR = 'This Safe App is already in the list' const MANIFEST_ERROR = "The app doesn't support Safe App functionality" const INVALID_URL_ERROR = 'The url is invalid' diff --git a/src/config/constants.ts b/src/config/constants.ts index 459a1a51e5..7742697469 100644 --- a/src/config/constants.ts +++ b/src/config/constants.ts @@ -37,7 +37,7 @@ export const SAFE_TOKEN_ADDRESSES: { [chainId: string]: string } = { export const SAFE_APPS_INFURA_TOKEN = process.env.NEXT_PUBLIC_SAFE_APPS_INFURA_TOKEN || INFURA_TOKEN export const SAFE_APPS_THIRD_PARTY_COOKIES_CHECK_URL = 'https://third-party-cookies-check.gnosis-safe.com' export const SAFE_APPS_DEMO_SAFE_MAINNET = 'eth:0xfF501B324DC6d78dC9F983f140B9211c3EdB4dc7' -export const SAFE_APPS_SDK_DOCS_URL = 'https://docs.safe.global/safe-core-aa-sdk/safe-apps' +export const SAFE_APPS_SDK_DOCS_URL = 'https://docs.safe.global/apps-sdk-overview' // Google Tag Manager export const GOOGLE_TAG_MANAGER_ID = process.env.NEXT_PUBLIC_GOOGLE_TAG_MANAGER_ID || '' From 18239b2bcd664ebb85c97d5356d7238b53d040c0 Mon Sep 17 00:00:00 2001 From: katspaugh <381895+katspaugh@users.noreply.github.com> Date: Wed, 7 Feb 2024 13:34:43 +0100 Subject: [PATCH 03/11] Chore: update WalletConnect packages (#3216) --- package.json | 11 ++++--- yarn.lock | 90 ++++++++++++++++++++++++++++++++++++++++++++++------ 2 files changed, 86 insertions(+), 15 deletions(-) diff --git a/package.json b/package.json index b939beeaf7..6e485592b3 100644 --- a/package.json +++ b/package.json @@ -27,7 +27,8 @@ "cypress:run": "cypress run", "cypress:ci": "yarn cypress:run --config baseUrl=http://localhost:8080 --spec cypress/e2e/smoke/*.cy.js", "serve": "npx -y serve out -p ${REVERSE_PROXY_UI_PORT:=8080}", - "static-serve": "yarn build && yarn serve" + "static-serve": "yarn build && yarn serve", + "update-wc": "yarn add @walletconnect/web3wallet@latest @walletconnect/utils@latest @walletconnect/types@latest" }, "engines": { "node": ">=16" @@ -54,16 +55,16 @@ "@safe-global/safe-apps-sdk": "^9.0.0-next.1", "@safe-global/safe-core-sdk": "^3.3.5", "@safe-global/safe-core-sdk-utils": "^1.7.4", - "@safe-global/safe-ethers-lib": "^1.9.4", "@safe-global/safe-deployments": "1.32.0", + "@safe-global/safe-ethers-lib": "^1.9.4", "@safe-global/safe-gateway-typescript-sdk": "^3.14.0", "@safe-global/safe-modules-deployments": "^1.2.0", "@sentry/react": "^7.91.0", "@spindl-xyz/attribution-lite": "^1.4.0", "@tkey-mpc/common-types": "^8.2.2", "@truffle/hdwallet-provider": "^2.1.4", - "@walletconnect/utils": "^2.11.0", - "@walletconnect/web3wallet": "^1.10.0", + "@walletconnect/utils": "^2.11.1", + "@walletconnect/web3wallet": "^1.10.1", "@web3-onboard/coinbase": "^2.2.6", "@web3-onboard/core": "^2.21.2", "@web3-onboard/injected-wallets": "^2.10.7", @@ -118,7 +119,7 @@ "@types/react-gtm-module": "^2.0.1", "@types/semver": "^7.3.10", "@typescript-eslint/eslint-plugin": "^5.47.1", - "@walletconnect/types": "^2.11.0", + "@walletconnect/types": "^2.11.1", "cross-env": "^7.0.3", "cypress": "^12.15.0", "cypress-file-upload": "^5.0.8", diff --git a/yarn.lock b/yarn.lock index e7dfb5e69a..ec3a888815 100644 --- a/yarn.lock +++ b/yarn.lock @@ -5749,6 +5749,29 @@ lodash.isequal "4.5.0" uint8arrays "^3.1.0" +"@walletconnect/core@2.11.1": + version "2.11.1" + resolved "https://registry.yarnpkg.com/@walletconnect/core/-/core-2.11.1.tgz#da2be26b8b6514c74f06dc9a5ffb450bdec3456d" + integrity sha512-T57Vd7YdbHPsy3tthBuwrhaZNafN0+PqjISFRNeJy/bsKdXxpJg2hGSARuOTpCO7V6VcaatqlaSMuG3DrnG5rA== + dependencies: + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-provider" "1.0.13" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/jsonrpc-ws-connection" "1.0.14" + "@walletconnect/keyvaluestorage" "^1.1.1" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/relay-auth" "^1.0.4" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.11.1" + "@walletconnect/utils" "2.11.1" + events "^3.3.0" + isomorphic-unfetch "3.1.0" + lodash.isequal "4.5.0" + uint8arrays "^3.1.0" + "@walletconnect/environment@^1.0.1": version "1.0.1" resolved "https://registry.yarnpkg.com/@walletconnect/environment/-/environment-1.0.1.tgz#1d7f82f0009ab821a2ba5ad5e5a7b8ae3b214cd7" @@ -5919,6 +5942,21 @@ "@walletconnect/utils" "2.11.0" events "^3.3.0" +"@walletconnect/sign-client@2.11.1": + version "2.11.1" + resolved "https://registry.yarnpkg.com/@walletconnect/sign-client/-/sign-client-2.11.1.tgz#c073b8d2d594e792bb783d36c8b021bd37a9d4f6" + integrity sha512-s3oKSx6/F5X2WmkV1jfJImBFACf9Km5HpTb+n5q+mobJVpUQw/clvoVyIrNNppLhm1V1S/ylHXh0qCrDppDpCA== + dependencies: + "@walletconnect/core" "2.11.1" + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-utils" "1.0.8" + "@walletconnect/logger" "^2.0.1" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.11.1" + "@walletconnect/utils" "2.11.1" + events "^3.3.0" + "@walletconnect/time@^1.0.2": version "1.0.2" resolved "https://registry.yarnpkg.com/@walletconnect/time/-/time-1.0.2.tgz#6c5888b835750ecb4299d28eecc5e72c6d336523" @@ -5926,7 +5964,7 @@ dependencies: tslib "1.14.1" -"@walletconnect/types@2.11.0", "@walletconnect/types@^2.11.0": +"@walletconnect/types@2.11.0": version "2.11.0" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.11.0.tgz#474a009c56faa9ef4063b76ed84415c801dc9f1e" integrity sha512-AB5b1lrEbCGHxqS2vqfCkIoODieH+ZAUp9rA1O2ftrhnqDJiJK983Df87JhYhECsQUBHHfALphA8ydER0q+9sw== @@ -5938,6 +5976,18 @@ "@walletconnect/logger" "^2.0.1" events "^3.3.0" +"@walletconnect/types@2.11.1", "@walletconnect/types@^2.11.1": + version "2.11.1" + resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-2.11.1.tgz#4f705b43ddc286b69eb9bf91bb6e9496d20de0e3" + integrity sha512-UbdbX+d6MOK0AXKxt5imV3KvAcLVpZUHylaRDIP5ffwVylM/p4DHnKppil1Qq5N+IGDr3RsUwLGFkKjqsQYRKw== + dependencies: + "@walletconnect/events" "^1.0.1" + "@walletconnect/heartbeat" "1.2.1" + "@walletconnect/jsonrpc-types" "1.0.3" + "@walletconnect/keyvaluestorage" "^1.1.1" + "@walletconnect/logger" "^2.0.1" + events "^3.3.0" + "@walletconnect/types@~1.8.0": version "1.8.0" resolved "https://registry.yarnpkg.com/@walletconnect/types/-/types-1.8.0.tgz#3f5e85b2d6b149337f727ab8a71b8471d8d9a195" @@ -5958,7 +6008,7 @@ "@walletconnect/utils" "2.11.0" events "^3.3.0" -"@walletconnect/utils@2.11.0", "@walletconnect/utils@^2.10.1", "@walletconnect/utils@^2.11.0": +"@walletconnect/utils@2.11.0", "@walletconnect/utils@^2.10.1": version "2.11.0" resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.11.0.tgz#31c95151c823022077883dda61800cdea71879b7" integrity sha512-hxkHPlTlDQILHfIKXlmzgNJau/YcSBC3XHUSuZuKZbNEw3duFT6h6pm3HT/1+j1a22IG05WDsNBuTCRkwss+BQ== @@ -5978,19 +6028,39 @@ query-string "7.1.3" uint8arrays "^3.1.0" -"@walletconnect/web3wallet@^1.10.0": - version "1.10.0" - resolved "https://registry.yarnpkg.com/@walletconnect/web3wallet/-/web3wallet-1.10.0.tgz#5a7f181bbea213e8fb5961900a0069e58da36d18" - integrity sha512-JyaYdnBKL1hVpsE5hpjZhohpX1Ak2mwai3GYr8nI1FfK8Z3IPIh+4ImeDMnEao1cQFoItQNompp5y5C7WlI69A== +"@walletconnect/utils@2.11.1", "@walletconnect/utils@^2.11.1": + version "2.11.1" + resolved "https://registry.yarnpkg.com/@walletconnect/utils/-/utils-2.11.1.tgz#56116d9c410c6f2ae8d562017cf6876cccb366f1" + integrity sha512-wRFDHN86dZ05mCET1H3912odIeQa8j7cZKxl1FlWRpV2YsILj9HCYSX6Uq2brwO02Kv2vryke44G1r8XI/LViA== + dependencies: + "@stablelib/chacha20poly1305" "1.0.1" + "@stablelib/hkdf" "1.0.1" + "@stablelib/random" "^1.0.2" + "@stablelib/sha256" "1.0.1" + "@stablelib/x25519" "^1.0.3" + "@walletconnect/relay-api" "^1.0.9" + "@walletconnect/safe-json" "^1.0.2" + "@walletconnect/time" "^1.0.2" + "@walletconnect/types" "2.11.1" + "@walletconnect/window-getters" "^1.0.1" + "@walletconnect/window-metadata" "^1.0.1" + detect-browser "5.3.0" + query-string "7.1.3" + uint8arrays "^3.1.0" + +"@walletconnect/web3wallet@^1.10.1": + version "1.10.1" + resolved "https://registry.yarnpkg.com/@walletconnect/web3wallet/-/web3wallet-1.10.1.tgz#62271183b72b3e0ec47c683bf021549d47225f39" + integrity sha512-lXyfljLLQ/76F5ftgaKaIoPfj/R2Mi2Tv2JnIXNonlIlAITdghYVby+xYbh4b+0yldf8fr8lqxFuHBuVoWhMjw== dependencies: "@walletconnect/auth-client" "2.1.2" - "@walletconnect/core" "2.11.0" + "@walletconnect/core" "2.11.1" "@walletconnect/jsonrpc-provider" "1.0.13" "@walletconnect/jsonrpc-utils" "1.0.8" "@walletconnect/logger" "2.0.1" - "@walletconnect/sign-client" "2.11.0" - "@walletconnect/types" "2.11.0" - "@walletconnect/utils" "2.11.0" + "@walletconnect/sign-client" "2.11.1" + "@walletconnect/types" "2.11.1" + "@walletconnect/utils" "2.11.1" "@walletconnect/window-getters@^1.0.1": version "1.0.1" From 9887d9646bc5ab184064bb15faad17319ce37ee5 Mon Sep 17 00:00:00 2001 From: Michael <30682308+mike10ca@users.noreply.github.com> Date: Wed, 7 Feb 2024 15:09:20 +0100 Subject: [PATCH 04/11] tests: add sidebar tests -p3 (#3211) --- cypress/e2e/pages/assets.pages.js | 11 +++++ cypress/e2e/pages/navigation.page.js | 3 ++ cypress/e2e/pages/sidebar.pages.js | 41 +++++++++------- cypress/e2e/regression/sidebar_2.cy.js | 21 +++++++- cypress/e2e/regression/sidebar_nonowner.cy.js | 29 +++++++++++ cypress/support/constants.js | 6 +++ cypress/support/localstorage_data.js | 49 ++++++++++++++++++- .../balances/CurrencySelect/index.tsx | 3 +- .../sidebar/PendingActions/index.tsx | 2 + 9 files changed, 144 insertions(+), 21 deletions(-) create mode 100644 cypress/e2e/regression/sidebar_nonowner.cy.js diff --git a/cypress/e2e/pages/assets.pages.js b/cypress/e2e/pages/assets.pages.js index 2509eefb30..444e4f58ab 100644 --- a/cypress/e2e/pages/assets.pages.js +++ b/cypress/e2e/pages/assets.pages.js @@ -17,6 +17,8 @@ const hiddenTokenSaveBtn = 'span[data-track="assets: Save hide dialog"]' const hiddenTokenCancelBtn = 'span[data-track="assets: Cancel hide dialog"]' const hiddenTokenDeselectAllBtn = 'span[data-track="assets: Deselect all hide dialog"]' const hiddenTokenIcon = 'svg[data-testid="VisibilityOffOutlinedIcon"]' +const currencySelector = '[data-testid="currency-selector"]' +const currencyItem = '[data-testid="currency-item"]' const hideTokenDefaultString = 'Hide tokens' const assetNameSortBtnStr = 'Asset' @@ -91,6 +93,15 @@ export const currentcyGnosisFormat = '< 0.00001 GNO' export const currencyOx = /^0x$/ export const currentcyOxFormat = '1.003 ZRX' +function clickOnCurrencySelector() { + cy.get(currencySelector).click() +} + +export function changeCurrency(currency) { + clickOnCurrencySelector() + cy.get(currencyItem).contains(currency).click() +} + export function clickOnSendBtn(index) { cy.get('button') .contains(sendBtnStr) diff --git a/cypress/e2e/pages/navigation.page.js b/cypress/e2e/pages/navigation.page.js index 8748d2a581..7b176e398e 100644 --- a/cypress/e2e/pages/navigation.page.js +++ b/cypress/e2e/pages/navigation.page.js @@ -9,6 +9,9 @@ const sentinelStart = 'div[data-testid="sentinelStart"]' const disconnectBtnStr = 'Disconnect' const notConnectedStatus = 'Connect' +export function verifyTxBtnStatus(status) { + cy.get(newTxBtn).should(status) +} export function clickOnSideNavigation(option) { cy.get(option).should('exist').click() } diff --git a/cypress/e2e/pages/sidebar.pages.js b/cypress/e2e/pages/sidebar.pages.js index 9604103e55..5dd6d2bbf5 100644 --- a/cypress/e2e/pages/sidebar.pages.js +++ b/cypress/e2e/pages/sidebar.pages.js @@ -15,7 +15,7 @@ const sideBarListItem = '[data-testid="sidebar-list-item"]' const sideBarListItemWhatsNew = '[data-testid="list-item-whats-new"]' const sideBarListItemNeedHelp = '[data-testid="list-item-need-help"]' const sideSafeListItem = '[data-testid="safe-list-item"]' -const sidebarSafeHeader = '[data-testid="sidebar-safe-header"]' +const sidebarSafeHeader = '[data-testid="safe-header-info"]' const sidebarSafeContainer = '[data-testid="sidebar-safe-container"]' const safeItemOptionsBtn = '[data-testid="safe-options-btn"]' const safeItemOptionsRenameBtn = '[data-testid="rename-btn"]' @@ -26,6 +26,8 @@ const cancelBtn = '[data-testid="cancel-btn"]' const deleteBtn = '[data-testid="delete-btn"]' const readOnlyVisibility = '[data-testid="read-only-visibility"]' const currencySection = '[data-testid="currency-section"]' +const missingSignatureInfo = '[data-testid="missing-signature-info"]' +const queuedTxInfo = '[data-testid="queued-tx-info"]' export const addedSafesGnosis = ['0x17b3...98C8', '0x11A6...F1BB', '0xB8d7...642A'] export const addedSafesSepolia = ['0x6d0b...6dC1', '0x5912...fFdb', '0x0637...708e', '0xD157...DE9a'] @@ -120,27 +122,26 @@ export function verifySafesByNetwork(netwrok, safes) { }) } +function getSafeItemByName(name) { + return cy.get(sidebarSafeContainer).find(sideSafeListItem).contains(name).parents('li') +} + export function verifySafeReadOnlyState(safe) { - cy.get(sidebarSafeContainer).within(() => { - cy.get(sideSafeListItem) - .contains(safe) - .parents('li') - .within(() => { - cy.get(readOnlyVisibility).should('exist') - }) - }) + getSafeItemByName(safe).find(readOnlyVisibility).should('exist') +} + +export function verifyMissingSignature(safe) { + getSafeItemByName(safe).find(missingSignatureInfo).should('exist') +} + +export function verifyQueuedTx(safe) { + return getSafeItemByName(safe).find(queuedTxInfo).should('exist') } function clickOnSafeItemOptionsBtn(name) { - cy.get(sidebarSafeContainer).within(() => { - cy.get(sideSafeListItem) - .contains(name) - .parents('li') - .within(() => { - cy.get(safeItemOptionsBtn).click() - }) - }) + getSafeItemByName(name).find(safeItemOptionsBtn).click() } + export function renameSafeItem(oldName, newName) { clickOnSafeItemOptionsBtn(oldName) clickOnRenameBtn() @@ -188,3 +189,9 @@ export function clickOnSaveBtn() { function verifyModalRemoved() { main.verifyElementsCount(modal.modalTitle, 0) } + +export function checkCurrencyInHeader(currency) { + cy.get(sidebarSafeHeader).within(() => { + cy.get(currencySection).contains(currency) + }) +} diff --git a/cypress/e2e/regression/sidebar_2.cy.js b/cypress/e2e/regression/sidebar_2.cy.js index daef0b5844..fef7fab98c 100644 --- a/cypress/e2e/regression/sidebar_2.cy.js +++ b/cypress/e2e/regression/sidebar_2.cy.js @@ -2,14 +2,16 @@ import * as constants from '../../support/constants' import * as main from '../pages/main.page' import * as sideBar from '../pages/sidebar.pages' import * as ls from '../../support/localstorage_data.js' +import * as assets from '../pages/assets.pages.js' const newSafeName = 'Added safe 3' -const oldSafeName = 'Added safe 2' +const oldSafeName = 'Added safe 900' const staticSafe100 = 'Added safe 100' +const staticSafe200 = 'Added safe 200' describe('Sidebar added sidebar tests', () => { beforeEach(() => { - cy.visit(constants.homeUrl + constants.SEPOLIA_TEST_SAFE_13) + cy.visit(constants.BALANCE_URL + constants.SEPOLIA_TEST_SAFE_13) cy.wait(2000) cy.clearLocalStorage() main.acceptCookies() @@ -45,4 +47,19 @@ describe('Sidebar added sidebar tests', () => { sideBar.openSidebar() sideBar.verifySafeReadOnlyState(staticSafe100) }) + + it('Verify Fiat currency changes when edited in the assets tab', () => { + assets.changeCurrency(constants.currencies.cad) + sideBar.checkCurrencyInHeader(constants.currencies.cad) + }) + + it('Verify "wallet" tag counter if the safe has tx ready for execution', () => { + sideBar.openSidebar() + sideBar.verifyMissingSignature(staticSafe200) + }) + + it('Verify "Wallet" tag counter only shows for owners', () => { + sideBar.openSidebar() + sideBar.verifyQueuedTx(staticSafe200) + }) }) diff --git a/cypress/e2e/regression/sidebar_nonowner.cy.js b/cypress/e2e/regression/sidebar_nonowner.cy.js new file mode 100644 index 0000000000..f88c2faedf --- /dev/null +++ b/cypress/e2e/regression/sidebar_nonowner.cy.js @@ -0,0 +1,29 @@ +import * as constants from '../../support/constants.js' +import * as main from '../pages/main.page.js' +import * as sideBar from '../pages/sidebar.pages.js' +import * as navigation from '../pages/navigation.page.js' +import * as ls from '../../support/localstorage_data.js' + +const addedOwner = 'Added owner' +const addedNonowner = 'Added non-owner' + +describe('Sidebar non-owner tests', () => { + beforeEach(() => { + cy.visit(constants.homeUrl + constants.SEPOLIA_TEST_SAFE_17_SIDEBAR_NONOWNER) + cy.wait(2000) + cy.clearLocalStorage() + main.acceptCookies() + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addedSafes, ls.addedSafes.set3) + main.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addressBook, ls.addressBookData.addedSafes) + }) + + it('Verify New Transaction button enabled for users with Spending limits allowed', () => { + navigation.verifyTxBtnStatus(constants.enabledStates.enabled) + }) + + it('Verify tag counting queue tx show for owners and non-owners', () => { + sideBar.openSidebar() + sideBar.verifyQueuedTx(addedOwner).contains(2) + sideBar.verifyQueuedTx(addedNonowner).contains(2) + }) +}) diff --git a/cypress/support/constants.js b/cypress/support/constants.js index f83fb7cfc0..ffd84749aa 100644 --- a/cypress/support/constants.js +++ b/cypress/support/constants.js @@ -29,6 +29,7 @@ export const SEPOLIA_TEST_SAFE_14 = 'sep:0xC23e061252BFc7967203D054136d8fA7c7df2 // SAFE 15 is a safe with native tokens but the automation user is not its owner export const SEPOLIA_TEST_SAFE_15_TOKEN = 'sep:0xfC0A7ac73Fde7547ac0792Cca1D8A50CE0AFC4Df' export const SEPOLIA_TEST_SAFE_16_CREATE_TX = 'sep:0xc2F3645bfd395516d1a18CA6ad9298299d328C01' +export const SEPOLIA_TEST_SAFE_17_SIDEBAR_NONOWNER = 'sep:0x10B45a24640E2170B6AA63ea3A289D723a0C9cba' export const SEPOLIA_CONTRACT_SHORT = '0x11AB...34aF' export const SEPOLIA_RECIPIENT_ADDR_SHORT = '0x4DD4...7bde' export const GNO_TEST_SAFE = 'gno:0xB8d760a90a5ed54D3c2b3EFC231277e99188642A' @@ -134,6 +135,11 @@ export const tokenAbbreviation = { link: 'LINK', } +export const currencies = { + cad: 'CAD', + aud: 'AUD', +} + export const appNames = { walletConnect: 'walletconnect', customContract: 'compose custom contract', diff --git a/cypress/support/localstorage_data.js b/cypress/support/localstorage_data.js index 62e6a1c879..96c80044e6 100644 --- a/cypress/support/localstorage_data.js +++ b/cypress/support/localstorage_data.js @@ -319,9 +319,14 @@ export const addressBookData = { addedSafes: { 100: { '0x17b34aEf1428A358bA2eA360a098b8A3BEb698C8': 'Added safe 1', - '0x11A6B41322C57Bd0e56cEe06abB11A1E5c1FF1BB': 'Added safe 2', + '0x11A6B41322C57Bd0e56cEe06abB11A1E5c1FF1BB': 'Added safe 900', '0xB8d760a90a5ed54D3c2b3EFC231277e99188642A': 'Added safe 100', }, + 11155111: { + '0x0A0EEb6fBCc7c82259E548Fc4617175A357b3e71': 'Added safe 200', + '0xF21445699e91aC6F2EeeAF1a19510AC4197e59aB': 'Added owner', + '0x9E6DAfe829431e1892EcF8461FDAd02665170c31': 'Added non-owner', + }, }, } @@ -507,6 +512,22 @@ export const addedSafes = { threshold: 1, ethBalance: '0', }, + '0x0A0EEb6fBCc7c82259E548Fc4617175A357b3e71': { + owners: [ + { + value: '0x8aEf2f5c3F17261F6F1C4dA058D022BE92776af8', + name: null, + logoUri: null, + }, + { + value: '0xC16Db0251654C0a72E91B190d81eAD367d2C6fED', + name: null, + logoUri: null, + }, + ], + threshold: 2, + ethBalance: '0', + }, }, 100: { '0x17b34aEf1428A358bA2eA360a098b8A3BEb698C8': { @@ -526,6 +547,32 @@ export const addedSafes = { }, }, }, + set3: { + 11155111: { + '0xF21445699e91aC6F2EeeAF1a19510AC4197e59aB': { + owners: [ + { + value: '0xC16Db0251654C0a72E91B190d81eAD367d2C6fED', + name: null, + logoUri: null, + }, + ], + threshold: 2, + ethBalance: '0', + }, + '0x9E6DAfe829431e1892EcF8461FDAd02665170c31': { + owners: [ + { + value: '0x96D4c6fFC338912322813a77655fCC926b9A5aC5', + name: null, + logoUri: null, + }, + ], + threshold: 2, + ethBalance: '0', + }, + }, + }, } export const pinnedApps = { diff --git a/src/components/balances/CurrencySelect/index.tsx b/src/components/balances/CurrencySelect/index.tsx index bfec864f59..04d9af8e93 100644 --- a/src/components/balances/CurrencySelect/index.tsx +++ b/src/components/balances/CurrencySelect/index.tsx @@ -34,6 +34,7 @@ const CurrencySelect = (): ReactElement => { Currency