diff --git a/cypress/e2e/pages/load_safe.pages.js b/cypress/e2e/pages/load_safe.pages.js index 488b343bc6..eaf2dc1dee 100644 --- a/cypress/e2e/pages/load_safe.pages.js +++ b/cypress/e2e/pages/load_safe.pages.js @@ -3,17 +3,26 @@ import * as constants from '../../support/constants' const addExistingAccountBtnStr = 'Add existing one' const contactStr = 'Name, address & network' const invalidAddressFormatErrorMsg = 'Invalid address format' +const invalidAddressNameLengthErrorMsg = 'Maximum 50 symbols' const safeDataForm = '[data-testid=load-safe-form]' const nameInput = 'input[name="name"]' const addressInput = 'input[name="address"]' -const sideBarIcon = '[data-testid=ChevronRightIcon]' -const sidebarCheckIcon = '[data-testid=CheckIcon]' +const sideBarIcon = '[data-testid="ChevronRightIcon"]' +const sidebarCheckIcon = '[data-testid="CheckIcon"]' +const addressStepNextBtn = '[data-testid="load-safe-next-btn"]' +const qrCodeBtn = '[data-testid="address-qr-scan"]' +const typeFile = '[type="file"]' const nextBtnStr = 'Next' const addBtnStr = 'Add' const settingsBtnStr = 'Settings' const ownersConfirmationsStr = 'Owners and confirmations' const transactionStr = 'Transactions' +const qrErrorMsg = 'The QR could not be read' + +export function verifyQRCodeErrorMsg() { + cy.contains(qrErrorMsg).should('be.visible') +} export function openLoadSafeForm() { cy.contains('a', addExistingAccountBtnStr).click() @@ -52,14 +61,24 @@ export function verifyIncorrectAddressErrorMessage() { cy.get(addressInput).parent().prev('label').contains(invalidAddressFormatErrorMsg) } +export function verifyNameLengthErrorMessage() { + cy.get(nameInput).parent().prev('label').contains(invalidAddressNameLengthErrorMsg) +} + +export function scanQRCode(image) { + cy.get(qrCodeBtn).click() + cy.contains('Upload an image').click() + cy.get(typeFile).attachFile(image) +} + export function inputAddress(address) { cy.get(addressInput).clear().type(address) } -export function verifyAddressInputValue() { +export function verifyAddressInputValue(safeAddress) { // The address field should be filled with the "bare" QR code's address - const [, address] = constants.SEPOLIA_TEST_SAFE_1.split(':') - cy.get('input[name="address"]').should('have.value', address) + const [, address] = safeAddress.split(':') + cy.get(addressInput).should('have.value', address) } export function clickOnNextBtn() { @@ -119,3 +138,7 @@ export function verifyTransactionSectionIsVisible() { export function verifyNumberOfTransactions(startNumber, endNumber) { cy.get(`span:contains("${startNumber} out of ${endNumber}")`).should('have.length', 1) } + +export function verifyNextButtonStatus(param) { + cy.get(addressStepNextBtn).should(param) +} diff --git a/cypress/e2e/smoke/load_safe.cy.js b/cypress/e2e/smoke/load_safe.cy.js index 1d9122eb47..3837a21616 100644 --- a/cypress/e2e/smoke/load_safe.cy.js +++ b/cypress/e2e/smoke/load_safe.cy.js @@ -26,6 +26,68 @@ describe('[SMOKE] Load Safe tests', () => { cy.wait(2000) }) + it('Verify a network can be selected in the Safe', () => { + safe.clickNetworkSelector(constants.networks.sepolia) + safe.selectPolygon() + cy.wait(2000) + safe.clickNetworkSelector(constants.networks.polygon) + safe.selectSepolia() + }) + + it('Verify only valid Safe name can be accepted', () => { + // alias the address input label + cy.get('input[name="address"]').parent().prev('label').as('addressLabel') + + createwallet.verifyDefaultWalletName(createwallet.defaltSepoliaPlaceholder) + safe.verifyIncorrectAddressErrorMessage() + safe.inputNameAndAddress(testSafeName, constants.SEPOLIA_TEST_SAFE_1) + + safe.verifyAddressInputValue(constants.SEPOLIA_TEST_SAFE_1) + safe.verifyNextButtonStatus('be.enabled') + safe.clickOnNextBtn() + }) + + it('Verify names cannot have more than 50 characters', () => { + safe.inputName(main.generateRandomString(51)) + safe.verifyNameLengthErrorMessage() + }) + + it('Verify ENS name is translated to a valid address', () => { + cy.visit(constants.loadNewSafeEthUrl) + safe.inputAddress(constants.ENS_TEST_ETH) + safe.verifyAddressInputValue(constants.ETH_ENS_SAFE_ADDRESS_1) + safe.verifyNextButtonStatus('be.enabled') + safe.clickOnNextBtn() + }) + + it('Verify a valid QR code is accepted', () => { + safe.scanQRCode(constants.VALID_QR_CODE_PATH) + safe.verifyAddressInputValue(constants.SEPOLIA_TEST_SAFE_6) + safe.verifyNextButtonStatus('be.enabled') + safe.clickOnNextBtn() + }) + + it('Verify a non QR code is not accepted', () => { + safe.scanQRCode(constants.INVALID_QR_CODE_PATH) + safe.verifyQRCodeErrorMsg() + }) + + it('Verify custom name in the first owner an be set', () => { + safe.inputNameAndAddress(testSafeName, constants.SEPOLIA_TEST_SAFE_1) + safe.clickOnNextBtn() + createwallet.typeOwnerName(testOwnerName, 0) + safe.clickOnNextBtn() + }) + + it('Verify Safe and owner names are displayed in the Review step', () => { + safe.inputNameAndAddress(testSafeName, constants.SEPOLIA_TEST_SAFE_1) + safe.clickOnNextBtn() + createwallet.typeOwnerName(testOwnerName, 0) + safe.clickOnNextBtn() + safe.verifyDataInReviewSection(testSafeName, testOwnerName) + safe.clickOnAddBtn() + }) + it('[SMOKE] Verify the custom Safe name is successfully loaded', () => { safe.inputNameAndAddress(testSafeName, constants.SEPOLIA_TEST_SAFE_2) safe.clickOnNextBtn() diff --git a/cypress/fixtures/goerli_safe_QR.png b/cypress/fixtures/goerli_safe_QR.png deleted file mode 100644 index 8db09e5771..0000000000 Binary files a/cypress/fixtures/goerli_safe_QR.png and /dev/null differ diff --git a/cypress/fixtures/invalid_image_QR_test.png b/cypress/fixtures/invalid_image_QR_test.png new file mode 100644 index 0000000000..e001d86a40 Binary files /dev/null and b/cypress/fixtures/invalid_image_QR_test.png differ diff --git a/cypress/fixtures/sepolia_test_safe_QR.png b/cypress/fixtures/sepolia_test_safe_QR.png new file mode 100644 index 0000000000..122768d0d0 Binary files /dev/null and b/cypress/fixtures/sepolia_test_safe_QR.png differ diff --git a/cypress/support/constants.js b/cypress/support/constants.js index 70c65e95df..deb4dab3fe 100644 --- a/cypress/support/constants.js +++ b/cypress/support/constants.js @@ -11,6 +11,7 @@ export const SEPOLIA_TEST_SAFE_4 = 'sep:0x03042B890b99552b60A073F808100517fb148F export const SEPOLIA_TEST_SAFE_5 = 'sep:0xBd69b0a9DC90eB6F9bAc3E4a5875f437348b6415' export const SEPOLIA_TEST_SAFE_6 = 'sep:0x6d0b6F96f665Bb4490f9ddb2e450Da2f7e546dC1' export const SEPOLIA_TEST_SAFE_7 = 'sep:0xBf30F749FC027a5d79c4710D988F0D3C8e217A4F' +export const ETH_ENS_SAFE_ADDRESS_1 = 'eth:0x8675B754342754A30A2AeF474D114d8460bca19b' export const GNO_TEST_SAFE = 'gno:0xB8d760a90a5ed54D3c2b3EFC231277e99188642A' export const PAGINATION_TEST_SAFE = 'gor:0x850493a15914aAC05a821A3FAb973b4598889A7b' export const TEST_SAFE = 'gor:0x04f8b1EA3cBB315b87ced0E32deb5a43cC151a91' @@ -26,6 +27,9 @@ export const SIDEBAR_ADDRESS = '0x04f8...1a91' export const ENS_TEST_SEPOLIA = 'testenssepolia.eth' export const ENS_TEST_GOERLI = 'goerli-safe-test.eth' export const ENS_TEST_SEPOLIA_INVALID = 'ivladitestenssepolia.eth' +export const ENS_TEST_ETH = 'mainnetsafe.eth' +export const VALID_QR_CODE_PATH = '../fixtures/sepolia_test_safe_QR.png' //converts to SEPOLIA_TEST_SAFE_6 address +export const INVALID_QR_CODE_PATH = '../fixtures/invalid_image_QR_test.png' //A blank square export const BROWSER_PERMISSIONS_KEY = `${LS_NAMESPACE}SafeApps__browserPermissions` export const SAFE_PERMISSIONS_KEY = `${LS_NAMESPACE}SafeApps__safePermissions` @@ -50,6 +54,7 @@ export const welcomeUrl = '/welcome' export const chainMaticUrl = '/welcome?chain=matic' export const createNewSafeSepoliaUrl = '/new-safe/create?chain=sep' export const loadNewSafeSepoliaUrl = '/new-safe/load?chain=sep' +export const loadNewSafeEthUrl = '/new-safe/load?chain=eth' export const appsUrl = '/apps' export const requestPermissionsUrl = '/request-permissions' export const getPermissionsUrl = '/get-permissions' @@ -155,3 +160,7 @@ export const localStorageKeys = { export const connectWalletNames = { e2e: 'E2E Wallet', } + +export const longNames = { + safeName: 'Lorem ipsum dolor sit amet, consectetur adipiscing elit', +} diff --git a/src/components/common/ScanQRModal/ScanQRButton.tsx b/src/components/common/ScanQRModal/ScanQRButton.tsx index e960ae5691..97101607c9 100644 --- a/src/components/common/ScanQRModal/ScanQRButton.tsx +++ b/src/components/common/ScanQRModal/ScanQRButton.tsx @@ -29,7 +29,7 @@ const ScanQRButton = ({ onScan }: Props): ReactElement => { return ( <> - + diff --git a/src/components/new-safe/load/steps/SetAddressStep/index.tsx b/src/components/new-safe/load/steps/SetAddressStep/index.tsx index 89bfb3b9b6..cb91c1aead 100644 --- a/src/components/new-safe/load/steps/SetAddressStep/index.tsx +++ b/src/components/new-safe/load/steps/SetAddressStep/index.tsx @@ -157,7 +157,13 @@ const SetAddressStep = ({ data, onSubmit, onBack }: StepRenderProps}> Back -