From 2a408aeb7f7b2606ece20c671b2bef7927d75aba Mon Sep 17 00:00:00 2001 From: Michael <30682308+mike10ca@users.noreply.github.com> Date: Thu, 7 Dec 2023 16:42:36 +0100 Subject: [PATCH] History tests - part 2 (#2980) Add more tx history tests --- cypress/e2e/pages/create_tx.pages.js | 15 +- cypress/e2e/pages/main.page.js | 10 +- cypress/e2e/regression/remove_owner.cy.js | 4 +- cypress/e2e/regression/tx_history.cy.js | 35 ++--- cypress/e2e/regression/tx_history_2.cy.js | 168 ++++++++++++++++++++++ cypress/e2e/smoke/add_owner.cy.js | 4 +- cypress/e2e/smoke/address_book.cy.js | 2 +- cypress/fixtures/txhistory_data_data.json | 126 +++++++++------- 8 files changed, 285 insertions(+), 79 deletions(-) create mode 100644 cypress/e2e/regression/tx_history_2.cy.js diff --git a/cypress/e2e/pages/create_tx.pages.js b/cypress/e2e/pages/create_tx.pages.js index 799655cbab..272ca8d129 100644 --- a/cypress/e2e/pages/create_tx.pages.js +++ b/cypress/e2e/pages/create_tx.pages.js @@ -2,6 +2,7 @@ import * as constants from '../../support/constants' import * as main from '../pages/main.page' export const delegateCallWarning = '[data-testid="delegate-call-warning"]' +export const policyChangeWarning = '[data-testid="threshold-warning"]' const newTransactionBtnStr = 'New transaction' const recepientInput = 'input[name="recipient"]' const sendTokensBtnStr = 'Send tokens' @@ -10,7 +11,6 @@ const amountInput = 'input[name="amount"]' const nonceInput = 'input[name="nonce"]' const gasLimitInput = '[name="gasLimit"]' const rotateLeftIcon = '[data-testid="RotateLeftIcon"]' -const transactionActionsList = '[data-testid="transaction-actions-list"]' const transactionItem = '[data-testid="transaction-item"]' const connectedWalletExecMethod = '[data-testid="connected-wallet-execution-method"]' const addToBatchBtn = '[data-track="batching: Add to batch"]' @@ -25,6 +25,8 @@ const collapseAllBtn = '[data-testid="collapse-all-btn"]' const txRowTitle = '[data-testid="tx-row-title"]' const advancedDetails = '[data-testid="tx-advanced-details"]' const baseGas = '[data-testid="tx-bas-gas"]' +const requiredConfirmation = '[data-testid="required-confirmations"]' +const txDate = '[data-testid="tx-date"]' const viewTransactionBtn = 'View transaction' const transactionDetailsTitle = 'Transaction details' @@ -46,6 +48,15 @@ const signBtnStr = 'Sign' const expandAllBtnStr = 'Expand all' const collapseAllBtnStr = 'Collapse all' +export function verifyNumberOfTransactions(count) { + cy.get(txDate).should('have.length.at.least', count) + cy.get(transactionItem).should('have.length.at.least', count) +} + +export function checkRequiredThreshold(count) { + cy.get(requiredConfirmation).should('be.visible').and('include.text', count) +} + export function verifyCopyIconWorks(index, data) { cy.get(copyIcon) .parent() @@ -168,7 +179,7 @@ export function clickOnTransactionItem(item) { } export function verifyTransactionActionsVisibility(option) { - cy.get(transactionActionsList).should(option) + cy.get(transactionSideList).should(option) } export function clickOnNewtransactionBtn() { diff --git a/cypress/e2e/pages/main.page.js b/cypress/e2e/pages/main.page.js index 04af23bac9..d7c7b7302d 100644 --- a/cypress/e2e/pages/main.page.js +++ b/cypress/e2e/pages/main.page.js @@ -11,7 +11,7 @@ export function clickOnSideMenuItem(item) { cy.get('p').contains(item).click() } -export function waitForTrnsactionHistoryToComplete() { +export function waitForHistoryCallToComplete() { cy.intercept('GET', constants.transactionHistoryEndpoint).as('History') cy.wait('@History') } @@ -51,9 +51,11 @@ export function verifyHomeSafeUrl(safe) { export function checkTextsExistWithinElement(element, texts) { texts.forEach((text) => { - cy.get(element).within(() => { - cy.get('div').contains(text).should('be.visible') - }) + cy.get(element) + .should('be.visible') + .within(() => { + cy.get('div').contains(text).should('be.visible') + }) }) } diff --git a/cypress/e2e/regression/remove_owner.cy.js b/cypress/e2e/regression/remove_owner.cy.js index 84758dc45a..62563557ab 100644 --- a/cypress/e2e/regression/remove_owner.cy.js +++ b/cypress/e2e/regression/remove_owner.cy.js @@ -5,7 +5,7 @@ import * as owner from '../pages/owners.pages' describe('Remove Owners tests', () => { beforeEach(() => { cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_3) - main.waitForTrnsactionHistoryToComplete() + main.waitForHistoryCallToComplete() cy.clearLocalStorage() main.acceptCookies() owner.waitForConnectionStatus() @@ -18,7 +18,7 @@ describe('Remove Owners tests', () => { it('Verify Tooltip displays correct message for Non-Owner', () => { cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_4) - main.waitForTrnsactionHistoryToComplete() + main.waitForHistoryCallToComplete() owner.waitForConnectionStatus() owner.verifyRemoveBtnIsDisabled() }) diff --git a/cypress/e2e/regression/tx_history.cy.js b/cypress/e2e/regression/tx_history.cy.js index 5f6fb5c1a3..feaf083a29 100644 --- a/cypress/e2e/regression/tx_history.cy.js +++ b/cypress/e2e/regression/tx_history.cy.js @@ -15,23 +15,23 @@ const typeDeleteAllowance = data.type.deleteSpendingLimit const typeSideActions = data.type.sideActions const typeGeneral = data.type.general -describe('Transaction history tests', () => { +describe('Tx history tests 1', () => { beforeEach(() => { cy.clearLocalStorage() cy.visit(constants.transactionsHistoryUrl + constants.SEPOLIA_TEST_SAFE_8) main.acceptCookies() }) - // Contract creation + // Account creation it('Verify summary for account creation', () => { createTx.verifySummaryByName( typeCreateAccount.title, - [typeCreateAccount.actionsSummary, typeCreateAccount.summaryTime, typeGeneral.statusOk], + [typeCreateAccount.actionsSummary, typeGeneral.statusOk], typeCreateAccount.altTmage, ) }) - it('Verify exapnded details for account creation', () => { + it('Verify exapanded details for account creation', () => { createTx.clickOnTransactionItemByName(typeCreateAccount.title) createTx.verifyExpandedDetails([ typeCreateAccount.creator.actionTitle, @@ -61,13 +61,13 @@ describe('Transaction history tests', () => { it('Verify summary for token receipt', () => { createTx.verifySummaryByIndex( txItemIndex, - [typeReceive.title, typeReceive.summaryTxInfo, typeReceive.summaryTime, typeGeneral.statusOk], + [typeReceive.title, typeReceive.summaryTxInfo, typeGeneral.statusOk], typeReceive.altImage, typeReceive.altToken, ) }) - it('Verify exapnded details for token receipt', () => { + it('Verify exapanded details for token receipt', () => { createTx.clickOnTransactionItemByIndex(txItemIndex) createTx.verifyExpandedDetails([ typeReceive.title, @@ -87,13 +87,13 @@ describe('Transaction history tests', () => { it('Verify summary for token send', () => { createTx.verifySummaryByName( typeSend.title, - [typeSend.summaryTxInfo, typeSend.summaryTime, typeGeneral.statusOk], + [typeSend.summaryTxInfo, typeGeneral.statusOk], typeSend.altImage, typeSend.altToken, ) }) - it('Verify exapnded details for token send', () => { + it('Verify exapanded details for token send', () => { createTx.clickOnTransactionItemByName(typeSend.title) createTx.verifyExpandedDetails([typeSend.sentTo, typeSend.recipientAddress, typeSend.transactionHash]) createTx.verifyActionListExists([ @@ -103,21 +103,16 @@ describe('Transaction history tests', () => { ]) }) - // Contract interaction + // Spending limits it('Verify summary for setting spend limits', () => { createTx.verifySummaryByIndex( initialSpendingLimitsTx, - [ - typeSpendingLimits.title, - typeSpendingLimits.summaryTxInfo, - typeSpendingLimits.summaryTime, - typeGeneral.statusOk, - ], + [typeSpendingLimits.title, typeSpendingLimits.summaryTxInfo, typeGeneral.statusOk], typeSpendingLimits.altImage, ) }) - it('Verify exapnded details for initial spending limits setup', () => { + it('Verify exapanded details for initial spending limits setup', () => { createTx.clickOnTransactionItemByIndex(initialSpendingLimitsTx) createTx.verifyExpandedDetails( [ @@ -160,16 +155,16 @@ describe('Transaction history tests', () => { createTx.collapseAllActions([typeSpendingLimits.addDelegate.delegateAddressTitle]) }) - // Contract interaction + // Spending limit deletion it('Verify summary for allowance deletion', () => { createTx.verifySummaryByName( typeDeleteAllowance.title, - [typeDeleteAllowance.summaryTxInfo, typeDeleteAllowance.summaryTime, typeGeneral.statusOk], + [typeDeleteAllowance.summaryTxInfo, typeGeneral.statusOk], typeDeleteAllowance.altImage, ) }) - it('Verify exapnded details for allowance deletion', () => { + it('Verify exapanded details for allowance deletion', () => { createTx.clickOnTransactionItemByName(typeDeleteAllowance.title) createTx.verifyExpandedDetails([ typeDeleteAllowance.description, @@ -182,7 +177,7 @@ describe('Transaction history tests', () => { ]) }) - it('Verify advanced details displayed in exapnded details for allowance deletion', () => { + it('Verify advanced details displayed in exapanded details for allowance deletion', () => { createTx.clickOnTransactionItemByName(typeDeleteAllowance.title) createTx.expandAdvancedDetails([typeDeleteAllowance.baseGas]) createTx.collapseAdvancedDetails([typeDeleteAllowance.baseGas]) diff --git a/cypress/e2e/regression/tx_history_2.cy.js b/cypress/e2e/regression/tx_history_2.cy.js new file mode 100644 index 0000000000..22cbdfce2c --- /dev/null +++ b/cypress/e2e/regression/tx_history_2.cy.js @@ -0,0 +1,168 @@ +import * as constants from '../../support/constants' +import * as main from '../pages/main.page' +import * as createTx from '../pages/create_tx.pages' +import * as data from '../../fixtures/txhistory_data_data.json' + +const batchTx = 13 +const thresholdTx = 0 + +const typeOnchainRejection = data.type.onchainRejection +const typeBatch = data.type.batchNativeTransfer +const typeAddOwner = data.type.addOwner +const typeChangeOwner = data.type.swapOwner +const typeRemoveOwner = data.type.removeOwner +const typeDisableOwner = data.type.disableModule +const typeChangeThreshold = data.type.changeThreshold +const typeSideActions = data.type.sideActions +const typeGeneral = data.type.general + +describe('Tx history tests 2', () => { + beforeEach(() => { + cy.clearLocalStorage() + cy.visit(constants.transactionsHistoryUrl + constants.SEPOLIA_TEST_SAFE_8) + main.acceptCookies() + }) + + it('Verify number of transactions is correct', () => { + createTx.verifyNumberOfTransactions(20) + }) + + // On-chain rejection + it('Verify summary for on-chain rejection', () => { + createTx.verifySummaryByName(typeOnchainRejection.title, [typeGeneral.statusOk], typeOnchainRejection.altImage) + }) + + it('Verify exapanded details for on-chain rejection', () => { + createTx.clickOnTransactionItemByName(typeOnchainRejection.title) + createTx.verifyExpandedDetails([ + typeOnchainRejection.description, + typeOnchainRejection.transactionHash, + typeOnchainRejection.safeTxHash, + ]) + createTx.verifyActionListExists([ + typeSideActions.rejectionCreated, + typeSideActions.confirmations, + typeSideActions.executedBy, + ]) + }) + + // Batch transaction + it('Verify summary for batch', () => { + createTx.verifySummaryByIndex( + batchTx, + [typeBatch.title, typeBatch.summaryTxInfo, typeGeneral.statusOk], + typeBatch.altImage, + typeBatch.altToken, + ) + }) + + it('Verify exapanded details for batch', () => { + createTx.clickOnTransactionItemByIndex(batchTx) + createTx.verifyExpandedDetails( + [ + typeBatch.description, + typeBatch.contractTitle, + typeBatch.contractAddress, + typeBatch.transactionHash, + typeBatch.safeTxHash, + ], + createTx.delegateCallWarning, + ) + createTx.verifyActions([typeBatch.nativeTransfer.title]) + }) + + // Add owner + it('Verify summary for adding owner', () => { + createTx.verifySummaryByName(typeAddOwner.title, [typeGeneral.statusOk], typeAddOwner.altImage) + }) + + it('Verify exapanded details for adding owner', () => { + createTx.clickOnTransactionItemByName(typeAddOwner.title) + createTx.verifyExpandedDetails( + [ + typeAddOwner.description, + typeAddOwner.requiredConfirmationsTitle, + typeAddOwner.ownerAddress, + typeAddOwner.transactionHash, + typeAddOwner.safeTxHash, + ], + createTx.policyChangeWarning, + ) + }) + + // Change owner + it('Verify summary for changing owner', () => { + createTx.verifySummaryByName(typeChangeOwner.title, [typeGeneral.statusOk], typeChangeOwner.altImage) + }) + + it('Verify exapanded details for changing owner', () => { + createTx.clickOnTransactionItemByName(typeChangeOwner.title) + createTx.verifyExpandedDetails([ + typeChangeOwner.description, + typeChangeOwner.newOwner.actionTitile, + typeChangeOwner.newOwner.ownerAddress, + typeChangeOwner.oldOwner.actionTitile, + typeChangeOwner.oldOwner.ownerAddress, + + typeChangeOwner.transactionHash, + typeChangeOwner.safeTxHash, + ]) + }) + + // Remove owner + it('Verify summary for removing owner', () => { + createTx.verifySummaryByName(typeRemoveOwner.title, [typeGeneral.statusOk], typeRemoveOwner.altImage) + }) + + it('Verify exapanded details for removing owner', () => { + createTx.clickOnTransactionItemByName(typeRemoveOwner.title) + createTx.verifyExpandedDetails( + [ + typeRemoveOwner.description, + typeRemoveOwner.requiredConfirmationsTitle, + typeRemoveOwner.ownerAddress, + typeRemoveOwner.transactionHash, + typeRemoveOwner.safeTxHash, + ], + createTx.policyChangeWarning, + ) + createTx.checkRequiredThreshold(1) + }) + + // Disbale module + it('Verify summary for disable module', () => { + createTx.verifySummaryByName(typeDisableOwner.title, [typeGeneral.statusOk], typeDisableOwner.altImage) + }) + + it('Verify exapanded details for disable module', () => { + createTx.clickOnTransactionItemByName(typeDisableOwner.title) + createTx.verifyExpandedDetails([ + typeDisableOwner.description, + typeDisableOwner.address, + typeDisableOwner.transactionHash, + typeDisableOwner.safeTxHash, + ]) + }) + + // Change threshold + it('Verify summary for changing threshold', () => { + createTx.verifySummaryByIndex( + thresholdTx, + [typeChangeThreshold.title, typeGeneral.statusOk], + typeChangeThreshold.altImage, + ) + }) + + it('Verify exapanded details for changing threshold', () => { + createTx.clickOnTransactionItemByIndex(thresholdTx) + createTx.verifyExpandedDetails( + [ + typeChangeThreshold.requiredConfirmationsTitle, + typeChangeThreshold.transactionHash, + typeChangeThreshold.safeTxHash, + ], + createTx.policyChangeWarning, + ) + createTx.checkRequiredThreshold(2) + }) +}) diff --git a/cypress/e2e/smoke/add_owner.cy.js b/cypress/e2e/smoke/add_owner.cy.js index a4588e261c..26c85dd85e 100644 --- a/cypress/e2e/smoke/add_owner.cy.js +++ b/cypress/e2e/smoke/add_owner.cy.js @@ -7,7 +7,7 @@ describe('[SMOKE] Add Owners tests', () => { beforeEach(() => { cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_1) cy.clearLocalStorage() - main.waitForTrnsactionHistoryToComplete() + main.waitForHistoryCallToComplete() main.acceptCookies() main.verifyElementsExist([navigation.setupSection]) }) @@ -18,7 +18,7 @@ describe('[SMOKE] Add Owners tests', () => { it('[SMOKE] Verify “Add new owner” button tooltip displays correct message for Non-Owner', () => { cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_2) - main.waitForTrnsactionHistoryToComplete() + main.waitForHistoryCallToComplete() owner.verifyAddOwnerBtnIsDisabled() }) diff --git a/cypress/e2e/smoke/address_book.cy.js b/cypress/e2e/smoke/address_book.cy.js index 67e0f19a9d..2f396ab06d 100644 --- a/cypress/e2e/smoke/address_book.cy.js +++ b/cypress/e2e/smoke/address_book.cy.js @@ -11,7 +11,7 @@ describe('[SMOKE] Address book tests', () => { beforeEach(() => { cy.clearLocalStorage() cy.visit(constants.addressBookUrl + constants.SEPOLIA_TEST_SAFE_1) - main.waitForTrnsactionHistoryToComplete() + main.waitForHistoryCallToComplete() main.acceptCookies() }) diff --git a/cypress/fixtures/txhistory_data_data.json b/cypress/fixtures/txhistory_data_data.json index 9c4eabf084..1d0a66b507 100644 --- a/cypress/fixtures/txhistory_data_data.json +++ b/cypress/fixtures/txhistory_data_data.json @@ -5,19 +5,10 @@ }, "sideActions": { "created": "Created", + "rejectionCreated": "On-chain rejection created", "confirmations": "Confirmations", "executedBy": "Executed" }, - "advancedDetails": { - "operation": {}, - "safeTxGas": {}, - "baseGas": {}, - "gasPrice": {}, - "gasToken": {}, - "refundReceiver": {}, - "signature": {}, - "rawData": {} - }, "accountCreation": { "actionsSummary": "Safe Account created by 0xC16D...6fED", "transactionSafehash": {}, @@ -61,6 +52,82 @@ "altImage": "Sent", "altToken": "ETH" }, + "onchainRejection": { + "title": "On-chain rejection", + "summaryTime": "11:17 AM", + "altImage": "On-chain rejection", + "description": "This is an on-chain rejection that didn't send any funds. This on-chain rejection replaced all transactions with nonce 3.", + "transactionHash": "0x4fbf...067d", + "safeTxHash": "0x1303...0fe2" + }, + "batchNativeTransfer": { + "title": "Safe: MultiSendCallOnly 1.3.0", + "summaryTxInfo": "2 actions", + "summaryTime": "11:24 AM", + "description": "MultiSend contract", + "altImage":"Safe: MultiSendCallOnly 1.3.0", + "contractTitle": "Safe: MultiSendCallOnly 1.3.0", + "contractAddress": "sep:0xA1dabEF33b3B82c7814B6D82A79e50F4AC44102B", + "transactionHash": "0x833e...b88c", + "safeTxHash": "0x4172...665d", + "nativeTransfer": { + "title": "native transfer", + "description": "Interact with (and send < 0.00001 ETH to)" + } + }, + "addOwner": { + "title": "addOwnerWithThreshold", + "summaryTime": "11:27 AM", + "description": "Add owner", + "altImage":"addOwnerWithThreshold", + "requiredConfirmationsTitle": "Required confirmations for new transactions", + "ownerAddress": "sep:0x01A9F68e339da12565cfBc47fe7D6EdEcB11C46f", + "transactionHash": "0x51d5...da62", + "safeTxHash": "0xdcc5...e1b2" + }, + "removeOwner": { + "title": "removeOwner", + "summaryTime": "11:46 AM", + "description": "Remove owner", + "altImage":"removeOwner", + "requiredConfirmationsTitle": "Required confirmations for new transactions", + "ownerAddress": "sep:0x8a39cE4E27C326B87B75AaFf820D442311CD8E4E", + "transactionHash": "0xac66...a4b8", + "safeTxHash": "0xafd5...7929" + }, + "disableModule": { + "title": "disableModule", + "summaryTime": "7:37 AM", + "description": "Disable module", + "altImage":"disableModule", + "address": "sep:0xCFbFaC74C26F8647cBDb8c5caf80BB5b32E43134", + "transactionHash": "0x8b39...adeb", + "safeTxHash": "0xb820...bc4a" + }, + "changeThreshold": { + "title": "changeThreshold", + "summaryTime": "8:36 AM", + "altImage":"changeThreshold", + "requiredConfirmationsTitle": "Required confirmations for new transactions", + "transactionHash": "0xf3d2...26df", + "safeTxHash": "0x46eb...e7d5" + }, + "swapOwner": { + "title": "swapOwner", + "summaryTime": "11:45 AM", + "description": "Swap owner", + "altImage":"swapOwner", + "transactionHash": "0x8cf9...2f17", + "safeTxHash": "0xd7a2...af6f", + "newOwner": { + "actionTitile": "New owner", + "ownerAddress": "sep:0x8a39cE4E27C326B87B75AaFf820D442311CD8E4E" + }, + "oldOwner": { + "actionTitile": "Old owner", + "ownerAddress": "sep:0x01A9F68e339da12565cfBc47fe7D6EdEcB11C46f" + } + }, "deleteSpendingLimit": { "title": "Contract interaction", "summaryTxInfo": "deleteAllowance", @@ -100,7 +167,6 @@ "delegateAddress": "sep:0xC16D...6fED", "delegateAddressTitle": "delegate(address)" }, - "setAllowance": { "title": "setAllowance", "delegateAddress": "sep:0xC16D...6fED", @@ -109,43 +175,7 @@ "resetTimeMin": "0", "resetBaseMin": "0", "delegateAddressTitle": "delegate(address)" - }, - - "onchainRejection": { - "description": {} - }, - "batchNativeTransfer": { - "nativeTransfer": {} - }, - "addOwner": { - "ownerAddress": { - "actionTitile": {}, - "ownerAddress": {} - }, - "confirmations": {} - }, - "swapOwner": { - "newOwner": { - "actionTitile": {}, - "ownerAddress": {} - }, - "oldOwner": { - "actionTitile": {}, - "ownerAddress": {} - } - }, - "removeOwner": { - "actionTitile": {}, - "ownerAddress": {} - }, - "changeThreshold": { - "requiredConfirmations": {} - }, - "disableModule": { - "actionTitle": {}, - "address": {} } - }, - "": {} + } } } \ No newline at end of file