Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[E2E] Add Safe - qr code + ENS name + name validation #2820

Merged
merged 10 commits into from
Nov 24, 2023
Merged
33 changes: 28 additions & 5 deletions cypress/e2e/pages/load_safe.pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -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()
Expand Down Expand Up @@ -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() {
Expand Down Expand Up @@ -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)
}
62 changes: 62 additions & 0 deletions cypress/e2e/smoke/load_safe.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -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', () => {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I need some help here.
If I leave it commented this way then the ScanQRCode function runs just fine. But for some reason if I uncomment all those lines, the function ScanQRCode is ignored, the VerifyAddressInputValue function (that checks if the address in the input is valid) kicks in first and of course fails since the QR code was not uploaded. I don't know why this happens

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The reason for it is that ETH_ENS_SAFE_ADDRESS_6 does not exist it throws the error as undefined. To fix it add ETH_ENS_SAFE_ADDRESS_6 to constants.js. After this fix everything should work as expected.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wrote the wrong name of the constant. Fixed. Thanks

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()
Expand Down
Binary file removed cypress/fixtures/goerli_safe_QR.png
Binary file not shown.
Binary file added cypress/fixtures/invalid_image_QR_test.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added cypress/fixtures/sepolia_test_safe_QR.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
9 changes: 9 additions & 0 deletions cypress/support/constants.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
Expand All @@ -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`
Expand All @@ -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'
Expand Down Expand Up @@ -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',
}
2 changes: 1 addition & 1 deletion src/components/common/ScanQRModal/ScanQRButton.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const ScanQRButton = ({ onScan }: Props): ReactElement => {
return (
<>
<Track {...MODALS_EVENTS.SCAN_QR}>
<IconButton onClick={openQrModal}>
<IconButton data-testid="address-qr-scan" onClick={openQrModal}>
<SvgIcon component={QrCodeIcon} inheritViewBox color="primary" fontSize="small" />
</IconButton>
</Track>
Expand Down
8 changes: 7 additions & 1 deletion src/components/new-safe/load/steps/SetAddressStep/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -157,7 +157,13 @@ const SetAddressStep = ({ data, onSubmit, onBack }: StepRenderProps<LoadSafeForm
<Button variant="outlined" size="small" onClick={handleBack} startIcon={<ArrowBackIcon fontSize="small" />}>
Back
</Button>
<Button type="submit" variant="contained" size="stretched" disabled={!isValid}>
<Button
data-testid="load-safe-next-btn"
type="submit"
variant="contained"
size="stretched"
disabled={!isValid}
>
Next
</Button>
</Box>
Expand Down
Loading