diff --git a/cypress/e2e/pages/balances.pages.js b/cypress/e2e/pages/balances.pages.js
index 1dcaf46e5c..0cb82caeb1 100644
--- a/cypress/e2e/pages/balances.pages.js
+++ b/cypress/e2e/pages/balances.pages.js
@@ -44,7 +44,7 @@ export const tokenListOptions = {
export const currencyEUR = 'EUR'
export const currencyUSD = 'USD'
-export const currentcySepoliaFormat = '0.1 ETH'
+export const currentcySepoliaFormat = '0.09996 ETH'
export const currencyAave = 'AAVE'
export const currencyAaveAlttext = 'AAVE'
diff --git a/cypress/e2e/pages/batches.pages.js b/cypress/e2e/pages/batches.pages.js
index dfbb34d7ef..d1c5628475 100644
--- a/cypress/e2e/pages/batches.pages.js
+++ b/cypress/e2e/pages/batches.pages.js
@@ -67,15 +67,19 @@ function addToBatchButton() {
export function openBatchtransactionsModal() {
cy.get(batchTxTopBar).should('be.visible').click()
cy.contains(batchedTransactionsStr).should('be.visible')
- cy.contains(addInitialTransactionStr)
}
export function openNewTransactionModal() {
cy.get(addNewTxBatch).click()
- cy.contains('h1', newTransactionTitle).should('be.visible')
cy.contains(sendTokensButn).click()
}
+export function addNewTransactionToBatch(EOA, currentNonce, funds_first_tx) {
+ openBatchtransactionsModal()
+ openNewTransactionModal()
+ addToBatch(EOA, currentNonce, funds_first_tx)
+}
+
export function verifyAmountTransactionsInBatch(count) {
cy.contains(batchedTransactionsStr, { timeout: 7000 })
.should('be.visible')
diff --git a/cypress/e2e/pages/create_wallet.pages.js b/cypress/e2e/pages/create_wallet.pages.js
index 4545f8dc29..af5ccda2ef 100644
--- a/cypress/e2e/pages/create_wallet.pages.js
+++ b/cypress/e2e/pages/create_wallet.pages.js
@@ -64,15 +64,9 @@ export function clearWalletName() {
export function selectNetwork(network, regex = false) {
cy.wait(1000)
- cy.get(selectNetworkBtn).should('exist').click()
+ cy.get(selectNetworkBtn).should('be.visible').click()
+ cy.wait(1000)
cy.get('li').contains(network).click()
-
- if (regex) {
- regex = constants.networks.goerli
- cy.get(selectNetworkBtn).click().invoke('text').should('match', regex)
- } else {
- cy.get(selectNetworkBtn).click().should('have.text', network)
- }
cy.get('body').click()
}
diff --git a/cypress/e2e/pages/dashboard.pages.js b/cypress/e2e/pages/dashboard.pages.js
index 43ad81fa8a..44b0bb4743 100644
--- a/cypress/e2e/pages/dashboard.pages.js
+++ b/cypress/e2e/pages/dashboard.pages.js
@@ -66,12 +66,8 @@ export function verifyFeaturedAppsSection() {
cy.contains(transactionBuilderStr)
cy.get(txBuilder).should('exist')
- // WalletConnect app
- cy.contains(walletConnectStr)
- cy.get(walletConnect).should('exist')
-
// Featured apps have a Safe-specific link
- cy.get(safeSpecificLink).should('have.length', 2)
+ cy.get(safeSpecificLink).should('have.length', 1)
})
}
diff --git a/cypress/e2e/pages/main.page.js b/cypress/e2e/pages/main.page.js
index 1f38e0ded6..438797b93c 100644
--- a/cypress/e2e/pages/main.page.js
+++ b/cypress/e2e/pages/main.page.js
@@ -6,11 +6,11 @@ export function clickOnSideMenuItem(item) {
cy.get('p').contains(item).click()
}
-export function acceptCookies() {
+export function acceptCookies(index = 0) {
cy.wait(1000)
cy.findAllByText('Got it!')
- .should('have.length.at.least', 0)
+ .should('have.length.at.least', index)
.each(($el) => $el.click())
cy.get('button')
diff --git a/cypress/e2e/pages/nfts.pages.js b/cypress/e2e/pages/nfts.pages.js
index 0800d2bb9f..85775098cb 100644
--- a/cypress/e2e/pages/nfts.pages.js
+++ b/cypress/e2e/pages/nfts.pages.js
@@ -32,8 +32,10 @@ export function verifyDataInTable(name, address, tokenID) {
cy.get('tbody tr:first-child').contains('td:nth-child(2)', tokenID)
}
-export function openFirstNFT() {
- cy.get('tbody tr:first-child td:nth-child(2)').click()
+export function openNFT(index) {
+ cy.get('tbody').within(() => {
+ cy.get('tr').eq(index).click()
+ })
}
export function verifyNameInNFTModal(name) {
diff --git a/cypress/e2e/pages/owners.pages.js b/cypress/e2e/pages/owners.pages.js
index 7799f73854..51d0c658f6 100644
--- a/cypress/e2e/pages/owners.pages.js
+++ b/cypress/e2e/pages/owners.pages.js
@@ -5,7 +5,7 @@ const copyToClipboardBtn = 'button[aria-label="Copy to clipboard"]'
const tooltipLabel = (label) => `span[aria-label="${label}"]`
const removeOwnerBtn = 'span[data-track="settings: Remove owner"] > span > button'
const replaceOwnerBtn = 'span[data-track="settings: Replace owner"] > span > button'
-const addOwnerBtn = 'span[data-track="settings: Add owner"]'
+const addOwnerBtn = 'span[data-track="settings: Add owner"] > button'
const tooltip = 'div[role="tooltip"]'
const expandMoreIcon = 'svg[data-testid="ExpandMoreIcon"]'
const sentinelStart = 'div[data-testid="sentinelStart"]'
@@ -87,6 +87,10 @@ export function verifyRemoveBtnIsEnabled() {
return cy.get(removeOwnerBtn).should('exist')
}
+export function verifyRemoveBtnIsDisabled() {
+ return cy.get(removeOwnerBtn).should('exist').and('be.disabled')
+}
+
export function hoverOverDeleteOwnerBtn(index) {
cy.get(removeOwnerBtn).eq(index).trigger('mouseover', { force: true })
}
@@ -110,6 +114,10 @@ export function verifyReplaceBtnIsEnabled() {
cy.get(replaceOwnerBtn).should('exist').and('not.be.disabled')
}
+export function verifyReplaceBtnIsDisabled() {
+ cy.get(replaceOwnerBtn).should('exist').and('be.disabled')
+}
+
export function hoverOverReplaceOwnerBtn() {
cy.get(replaceOwnerBtn).trigger('mouseover', { force: true })
}
@@ -118,6 +126,10 @@ export function verifyAddOwnerBtnIsEnabled() {
cy.get(addOwnerBtn).should('exist').and('not.be.disabled')
}
+export function verifyAddOwnerBtnIsDisabled() {
+ cy.get(addOwnerBtn).should('exist').and('be.disabled')
+}
+
export function hoverOverAddOwnerBtn() {
cy.get(addOwnerBtn).trigger('mouseover')
}
diff --git a/cypress/e2e/pages/safeapps.pages.js b/cypress/e2e/pages/safeapps.pages.js
index d4626dafc0..1385761e8b 100644
--- a/cypress/e2e/pages/safeapps.pages.js
+++ b/cypress/e2e/pages/safeapps.pages.js
@@ -23,11 +23,12 @@ const allowAllPermissions = /allow all/i
const appNotSupportedMsg = "The app doesn't support Safe App functionality"
export const pinWalletConnectStr = /pin walletconnect/i
-export const transactionBuilderStr = /pin transaction builder/i
+export const transactionBuilderStr = 'Transaction Builder'
export const logoWalletConnect = /logo.*walletconnect/i
export const walletConnectHeadlinePreview = /walletconnect/i
-export const availableNetworksPreview = /available networks/i
-export const connecttextPreview = 'Connect your Safe to any dApp that supports WalletConnect'
+export const transactiobUilderHeadlinePreview = 'Transaction Builder'
+export const availableNetworksPreview = 'Available networks'
+export const connecttextPreview = 'Compose custom contract interactions and batch them into a single transaction'
const warningDefaultAppStr = 'The application you are trying to access is not in the default Safe Apps list'
export const localStorageItem =
'{"https://safe-test-app.com":[{"feature":"camera","status":"granted"},{"feature":"microphone","status":"denied"}]}'
@@ -70,7 +71,7 @@ export function verifyLinkName(name) {
}
export function clickOnApp(app) {
- cy.findByRole('link', { name: app }).click()
+ cy.contains(app).click()
}
export function verifyNoAppsTextPresent() {
@@ -78,12 +79,8 @@ export function verifyNoAppsTextPresent() {
}
export function pinApp(app, pin = true) {
- cy.findByLabelText(app).click()
- cy.wait(200)
- cy.findByLabelText(app).should(($el) => {
- const ariaLabel = $el.attr('aria-label')
- expect(ariaLabel).to.include(pin ? 'Unpin' : 'Pin')
- })
+ const option = pin ? 'Pin' : 'Unpin'
+ cy.get(`[aria-label="${option} ${app}"]`).click()
}
export function clickOnBookmarkedAppsTab() {
@@ -146,7 +143,7 @@ function verifyDisclaimerIsVisible() {
}
export function clickOnContinueBtn() {
- return cy.findByRole('button', { name: continueBtnStr }).click()
+ return cy.findByRole('button', { name: continueBtnStr }).click().wait(1000)
}
export function verifyCameraCheckBoxExists() {
diff --git a/cypress/e2e/safe-apps/apps_list.cy.js b/cypress/e2e/safe-apps/apps_list.cy.js
index c14f41bb38..4081b813cf 100644
--- a/cypress/e2e/safe-apps/apps_list.cy.js
+++ b/cypress/e2e/safe-apps/apps_list.cy.js
@@ -9,7 +9,7 @@ describe('Safe Apps tests', () => {
beforeEach(() => {
cy.clearLocalStorage()
cy.visit(constants.SEPOLIA_TEST_SAFE_4 + constants.appsUrl, { failOnStatusCode: false })
- main.acceptCookies()
+ main.acceptCookies(1)
})
it('Verify app list can be filtered by app name [C56130]', () => {
@@ -32,15 +32,12 @@ describe('Safe Apps tests', () => {
it('Verify apps can be pinned [C56133]', () => {
safeapps.clearSearchAppInput()
- safeapps.pinApp(safeapps.pinWalletConnectStr)
safeapps.pinApp(safeapps.transactionBuilderStr)
- safeapps.verifyPinnedAppCount(2)
+ safeapps.verifyPinnedAppCount(1)
})
it('Verify apps can be unpinned [C56134]', () => {
- safeapps.pinApp(safeapps.pinWalletConnectStr)
safeapps.pinApp(safeapps.transactionBuilderStr)
- safeapps.pinApp(safeapps.pinWalletConnectStr, false)
safeapps.pinApp(safeapps.transactionBuilderStr, false)
safeapps.verifyPinnedAppCount(0)
})
diff --git a/cypress/e2e/safe-apps/browser_permissions.cy.js b/cypress/e2e/safe-apps/browser_permissions.cy.js
index cfd4f8ae41..da34de03ab 100644
--- a/cypress/e2e/safe-apps/browser_permissions.cy.js
+++ b/cypress/e2e/safe-apps/browser_permissions.cy.js
@@ -14,11 +14,11 @@ describe('Browser permissions tests', () => {
safe_apps_permissions: ['camera', 'microphone'],
})
})
+ cy.visitSafeApp(`${constants.testAppUrl}/app`)
+ main.acceptCookies(1)
})
it('Verify a permissions slide to the user is displayed [C56137]', () => {
- cy.visitSafeApp(`${constants.testAppUrl}/app`)
- main.acceptCookies()
safeapps.clickOnContinueBtn()
safeapps.verifyCameraCheckBoxExists()
safeapps.verifyMicrofoneCheckBoxExists()
@@ -29,6 +29,7 @@ describe('Browser permissions tests', () => {
safeapps.clickOnContinueBtn()
safeapps.verifyWarningDefaultAppMsgIsDisplayed()
safeapps.verifyCameraCheckBoxExists()
+ safeapps.clickOnContinueBtn()
safeapps.clickOnContinueBtn().should(() => {
expect(window.localStorage.getItem(constants.BROWSER_PERMISSIONS_KEY)).to.eq(safeapps.localStorageItem)
})
diff --git a/cypress/e2e/safe-apps/info_modal.cy.js b/cypress/e2e/safe-apps/info_modal.cy.js
index d4b93b3aad..63e45f1b0e 100644
--- a/cypress/e2e/safe-apps/info_modal.cy.js
+++ b/cypress/e2e/safe-apps/info_modal.cy.js
@@ -10,17 +10,19 @@ describe('Safe Apps info modal tests', () => {
})
it('Verify the disclaimer is displayed when a Safe App is opened [C56139]', () => {
- safeapps.clickOnApp(safeapps.logoWalletConnect)
+ safeapps.clickOnApp(safeapps.transactionBuilderStr)
safeapps.clickOnOpenSafeAppBtn()
})
- it('Verify the permissions slide is shown if the app require permissions [C56140]', () => {
+ // Skip tests due to changed logic
+ // TODO: Discuss furthers
+ it.skip('Verify the permissions slide is shown if the app require permissions [C56140]', () => {
safeapps.clickOnContinueBtn()
cy.wait(500) // wait for the animation to finish
safeapps.verifyCameraCheckBoxExists()
})
- it('Verify the permissions and consents decision are stored when accepted [C56141]', () => {
+ it.skip('Verify the permissions and consents decision are stored when accepted [C56141]', () => {
safeapps.storeAndVerifyPermissions()
})
})
diff --git a/cypress/e2e/safe-apps/preview_drawer.cy.js b/cypress/e2e/safe-apps/preview_drawer.cy.js
index 0f0b10abef..bae5b9ca94 100644
--- a/cypress/e2e/safe-apps/preview_drawer.cy.js
+++ b/cypress/e2e/safe-apps/preview_drawer.cy.js
@@ -10,16 +10,14 @@ describe('Safe Apps info modal tests', () => {
})
it('Verify the preview drawer is displayed when opening a Safe App from the app list [C56149]', () => {
- safeapps.clickOnApp(safeapps.logoWalletConnect)
+ safeapps.clickOnApp(safeapps.transactionBuilderStr)
cy.findByRole('presentation').within(() => {
safeapps.verifyPreviewWindow(
- safeapps.walletConnectHeadlinePreview,
+ safeapps.transactiobUilderHeadlinePreview,
safeapps.connecttextPreview,
safeapps.availableNetworksPreview,
)
- safeapps.pinApp(safeapps.pinWalletConnectStr)
- safeapps.pinApp(safeapps.pinWalletConnectStr, false)
safeapps.closePreviewWindow()
})
cy.findByRole('presentation').should('not.exist')
diff --git a/cypress/e2e/safe-apps/safe_permissions.cy.js b/cypress/e2e/safe-apps/safe_permissions.cy.js
index af06401a08..771beee30d 100644
--- a/cypress/e2e/safe-apps/safe_permissions.cy.js
+++ b/cypress/e2e/safe-apps/safe_permissions.cy.js
@@ -3,10 +3,8 @@ import * as safeapps from '../pages/safeapps.pages'
import * as main from '../pages/main.page'
describe('Safe permissions system tests', () => {
- before(() => {
- cy.clearLocalStorage()
- })
beforeEach(() => {
+ cy.clearLocalStorage()
cy.fixture('safe-app').then((html) => {
cy.intercept('GET', `${constants.testAppUrl}/*`, html)
cy.intercept('GET', `*/manifest.json`, {
@@ -19,7 +17,7 @@ describe('Safe permissions system tests', () => {
it('Verify that requesting permissions with wallet_requestPermissions shows the permissions prompt and return the permissions on accept [C56150]', () => {
cy.visitSafeApp(constants.testAppUrl + constants.requestPermissionsUrl)
- main.acceptCookies()
+ main.acceptCookies(1)
safeapps.clickOnContinueBtn()
safeapps.verifyWarningDefaultAppMsgIsDisplayed()
safeapps.clickOnContinueBtn()
@@ -58,7 +56,7 @@ describe('Safe permissions system tests', () => {
})
cy.visitSafeApp(constants.testAppUrl + constants.getPermissionsUrl)
- main.acceptCookies()
+ main.acceptCookies(1)
safeapps.clickOnContinueBtn()
safeapps.verifyWarningDefaultAppMsgIsDisplayed()
safeapps.clickOnContinueBtn()
diff --git a/cypress/e2e/smoke/add_owner.cy.js b/cypress/e2e/smoke/add_owner.cy.js
index af9ec0f9c8..a36635750c 100644
--- a/cypress/e2e/smoke/add_owner.cy.js
+++ b/cypress/e2e/smoke/add_owner.cy.js
@@ -7,7 +7,7 @@ describe('Add Owners tests', () => {
beforeEach(() => {
cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_1)
cy.clearLocalStorage()
- main.acceptCookies()
+ main.acceptCookies(1)
cy.contains(owner.safeAccountNonceStr, { timeout: 10000 })
})
@@ -17,16 +17,14 @@ describe('Add Owners tests', () => {
it('Verify “Add new owner” button tooltip displays correct message for Non-Owner [C56018]', () => {
cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_2)
- owner.hoverOverAddOwnerBtn()
- owner.verifyTooltiptext(owner.nonOwnerErrorMsg)
+ owner.verifyAddOwnerBtnIsDisabled()
})
it('Verify Tooltip displays correct message for disconnected user [C56019]', () => {
owner.waitForConnectionStatus()
owner.clickOnWalletExpandMoreIcon()
owner.clickOnDisconnectBtn()
- owner.hoverOverAddOwnerBtn()
- owner.verifyTooltiptext(owner.disconnectedUserErrorMsg)
+ owner.verifyAddOwnerBtnIsDisabled()
})
it('Verify the Add New Owner Form can be opened [C56020]', () => {
diff --git a/cypress/e2e/smoke/assets.cy.js b/cypress/e2e/smoke/assets.cy.js
index e8067221a9..578fc639ee 100644
--- a/cypress/e2e/smoke/assets.cy.js
+++ b/cypress/e2e/smoke/assets.cy.js
@@ -13,7 +13,7 @@ describe('Assets tests', () => {
beforeEach(() => {
cy.visit(constants.BALANCE_URL + constants.SEPOLIA_TEST_SAFE_5)
cy.clearLocalStorage()
- main.acceptCookies()
+ main.acceptCookies(2)
})
it('Verify that the token tab is selected by default and the table is visible [C56039]', () => {
diff --git a/cypress/e2e/smoke/balances.cy.js b/cypress/e2e/smoke/balances.cy.js
index 98f32cad67..47142aa9f5 100644
--- a/cypress/e2e/smoke/balances.cy.js
+++ b/cypress/e2e/smoke/balances.cy.js
@@ -14,7 +14,7 @@ describe('Balance tests', () => {
before(() => {
cy.clearLocalStorage()
cy.visit(constants.BALANCE_URL + constants.SEPOLIA_TEST_SAFE_5)
- main.acceptCookies()
+ main.acceptCookies(2)
cy.contains('Assets')
cy.get(balances.balanceSingleRow).should('have.length.lessThan', ASSETS_LENGTH)
balances.selectTokenList(balances.tokenListOptions.allTokens)
diff --git a/cypress/e2e/smoke/balances_pagination.cy.js b/cypress/e2e/smoke/balances_pagination.cy.js
index 695dfda308..92539761cd 100644
--- a/cypress/e2e/smoke/balances_pagination.cy.js
+++ b/cypress/e2e/smoke/balances_pagination.cy.js
@@ -1,5 +1,6 @@
import * as constants from '../../support/constants'
import * as balances from '../pages/balances.pages'
+import * as main from '../../e2e/pages/main.page'
const ASSETS_LENGTH = 8
@@ -8,9 +9,7 @@ describe('Balance tests', () => {
cy.clearLocalStorage()
// Open the Safe used for testing
cy.visit(constants.BALANCE_URL + constants.PAGINATION_TEST_SAFE)
- cy.contains('button', 'Accept selection').click()
- // Table is loaded
- cy.contains('Görli Ether')
+ main.acceptCookies(2)
cy.contains('div', 'Default tokens').click()
cy.wait(100)
diff --git a/cypress/e2e/smoke/batch_tx.cy.js b/cypress/e2e/smoke/batch_tx.cy.js
index 777621dc43..507b2b3ecd 100644
--- a/cypress/e2e/smoke/batch_tx.cy.js
+++ b/cypress/e2e/smoke/batch_tx.cy.js
@@ -7,10 +7,10 @@ const funds_first_tx = '0.001'
const funds_second_tx = '0.002'
describe('Batch transaction tests', () => {
- before(() => {
+ beforeEach(() => {
cy.clearLocalStorage()
cy.visit(constants.BALANCE_URL + constants.SEPOLIA_TEST_SAFE_5)
- main.acceptCookies()
+ main.acceptCookies(2)
})
it('Verify empty batch list can be opened [C56082]', () => {
@@ -20,10 +20,11 @@ describe('Batch transaction tests', () => {
it('Verify the Add batch button is present in a transaction form [C56084]', () => {
//The "true" is to validate that the add to batch button is not visible if "Yes, execute" is selected
- batch.addToBatch(constants.EOA, currentNonce, funds_first_tx)
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
})
it('Verify a transaction can be added to the batch [C56085]', () => {
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
cy.contains(batch.transactionAddedToBatchStr).should('be.visible')
//The batch button in the header shows the transaction count
batch.verifyBatchIconCount(1)
@@ -32,26 +33,37 @@ describe('Batch transaction tests', () => {
})
it('Verify a second transaction can be added to the batch [C56086]', () => {
- batch.openNewTransactionModal()
- batch.addToBatch(constants.EOA, currentNonce, funds_second_tx)
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
+ cy.wait(1000)
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
batch.verifyBatchIconCount(2)
batch.clickOnBatchCounter()
batch.verifyAmountTransactionsInBatch(2)
})
it('Verify the batch can be confirmed and related transactions exist in the form [C56088]', () => {
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
+ cy.wait(1000)
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
+ batch.clickOnBatchCounter()
+ batch.clickOnConfirmBatchBtn()
+ batch.clickOnBatchCounter()
batch.clickOnConfirmBatchBtn()
batch.verifyBatchTransactionsCount(2)
+ batch.clickOnBatchCounter()
cy.contains(funds_first_tx).parents('ul').as('TransactionList')
cy.get('@TransactionList').find('li').eq(0).find('span').eq(0).contains(funds_first_tx)
- cy.get('@TransactionList').find('li').eq(1).find('span').eq(0).contains(funds_second_tx)
+ cy.get('@TransactionList').find('li').eq(1).find('span').eq(0).contains(funds_first_tx)
})
it('Verify a transaction can be removed from the batch [C56089]', () => {
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
+ cy.wait(1000)
+ batch.addNewTransactionToBatch(constants.EOA, currentNonce, funds_first_tx)
batch.clickOnBatchCounter()
cy.contains(batch.batchedTransactionsStr).should('be.visible').parents('aside').find('ul > li').as('BatchList')
cy.get('@BatchList').find(batch.deleteTransactionbtn).eq(0).click()
cy.get('@BatchList').should('have.length', 1)
- cy.get('@BatchList').contains(funds_first_tx).should('not.exist')
+ cy.get('@BatchList').contains(funds_second_tx).should('not.exist')
})
})
diff --git a/cypress/e2e/smoke/create_tx.cy.js b/cypress/e2e/smoke/create_tx.cy.js
index 055adac173..b1a5e1ac1a 100644
--- a/cypress/e2e/smoke/create_tx.cy.js
+++ b/cypress/e2e/smoke/create_tx.cy.js
@@ -3,13 +3,13 @@ import * as main from '../../e2e/pages/main.page'
import * as createtx from '../../e2e/pages/create_tx.pages'
const sendValue = 0.00002
-const currentNonce = 1
+const currentNonce = 11
describe('Create transactions tests', () => {
before(() => {
cy.clearLocalStorage()
cy.visit(constants.BALANCE_URL + constants.SEPOLIA_TEST_SAFE_5)
- main.acceptCookies()
+ main.acceptCookies(2)
})
it('Verify a new send token transaction can be created [C56104]', () => {
diff --git a/cypress/e2e/smoke/dashboard.cy.js b/cypress/e2e/smoke/dashboard.cy.js
index fac9d8a91f..ad0ca6d0ee 100644
--- a/cypress/e2e/smoke/dashboard.cy.js
+++ b/cypress/e2e/smoke/dashboard.cy.js
@@ -3,27 +3,27 @@ import * as dashboard from '../pages/dashboard.pages'
import * as main from '../pages/main.page'
describe('Dashboard tests', () => {
- before(() => {
+ beforeEach(() => {
cy.clearLocalStorage()
cy.visit(constants.BALANCE_URL + constants.SEPOLIA_TEST_SAFE_5)
- main.acceptCookies()
+ main.acceptCookies(2)
main.clickOnSideMenuItem(constants.mainSideMenuOptions.home)
dashboard.verifyConnectTransactStrIsVisible()
})
- it.skip('Verify the overview widget is displayed [C56107]', () => {
+ it('Verify the overview widget is displayed [C56107]', () => {
dashboard.verifyOverviewWidgetData()
})
- it.skip('Verify the transaction queue widget is displayed [C56108]', () => {
+ it('Verify the transaction queue widget is displayed [C56108]', () => {
dashboard.verifyTxQueueWidget()
})
- it.skip('Verify the featured Safe Apps are displayed [C56109]', () => {
+ it('Verify the featured Safe Apps are displayed [C56109]', () => {
dashboard.verifyFeaturedAppsSection()
})
- it.skip('Verify the Safe Apps Section is displayed [C56110]', () => {
+ it('Verify the Safe Apps Section is displayed [C56110]', () => {
dashboard.verifySafeAppsSection()
})
})
diff --git a/cypress/e2e/smoke/import_export_data.cy.js b/cypress/e2e/smoke/import_export_data.cy.js
index a494e7891d..876d5f57fb 100644
--- a/cypress/e2e/smoke/import_export_data.cy.js
+++ b/cypress/e2e/smoke/import_export_data.cy.js
@@ -24,6 +24,7 @@ describe('Import Export Data tests', () => {
})
it('Verify address book imported data [C56112]', () => {
+ main.acceptCookies(1)
file.clickOnAddressBookBtn()
file.verifyImportedAddressBookData()
})
@@ -32,7 +33,6 @@ describe('Import Export Data tests', () => {
const appNames = ['Transaction Builder']
file.clickOnAppsBtn()
- file.clickOnBookmarkedAppsBtn()
file.verifyAppsAreVisible(appNames)
})
diff --git a/cypress/e2e/smoke/nfts.cy.js b/cypress/e2e/smoke/nfts.cy.js
index d6cb124519..e86f1d671a 100644
--- a/cypress/e2e/smoke/nfts.cy.js
+++ b/cypress/e2e/smoke/nfts.cy.js
@@ -7,34 +7,34 @@ const nftsAddress = '0x373B...866c'
const nftsTokenID = 'CF'
describe('NFTs tests', () => {
- before(() => {
+ beforeEach(() => {
cy.clearLocalStorage()
cy.visit(constants.BALANCE_URL + constants.SEPOLIA_TEST_SAFE_5)
- main.acceptCookies()
+ main.acceptCookies(2)
nfts.clickOnNftsTab()
})
- it.skip('Verify that NFTs exist in the table [C56123]', () => {
+ it('Verify that NFTs exist in the table [C56123]', () => {
nfts.verifyNFTNumber(20)
})
- it.skip('Verify NFT row contains data [C56124]', () => {
+ it('Verify NFT row contains data [C56124]', () => {
nfts.verifyDataInTable(nftsName, nftsAddress, nftsTokenID)
})
- it.skip('Verify NFT preview window can be opened [C56125]', () => {
- nfts.openFirstNFT()
+ it('Verify NFT preview window can be opened [C56125]', () => {
+ nfts.openNFT(1)
nfts.verifyNameInNFTModal(nftsTokenID)
nfts.verifySelectedNetwrokSepolia()
nfts.closeNFTModal()
})
- it.skip('Verify NFT open does not open if no NFT exits [C56126]', () => {
+ it('Verify NFT open does not open if no NFT exits [C56126]', () => {
nfts.clickOn6thNFT()
nfts.verifyNFTModalDoesNotExist()
})
- it.skip('Verify multipls NFTs can be selected and reviewed [C56127]', () => {
+ it('Verify multipls NFTs can be selected and reviewed [C56127]', () => {
nfts.verifyInitialNFTData()
nfts.selectNFTs(3)
nfts.deselectNFTs([2], 3)
diff --git a/cypress/e2e/smoke/remove_owner.cy.js b/cypress/e2e/smoke/remove_owner.cy.js
index bb00c61d9d..b22848c26e 100644
--- a/cypress/e2e/smoke/remove_owner.cy.js
+++ b/cypress/e2e/smoke/remove_owner.cy.js
@@ -18,8 +18,7 @@ describe('Remove Owners tests', () => {
it('Verify Tooltip displays correct message for Non-Owner [C56037]', () => {
cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_4)
owner.waitForConnectionStatus()
- owner.hoverOverDeleteOwnerBtn(0)
- owner.verifyTooltipLabel(owner.nonOwnerErrorMsg)
+ owner.verifyRemoveBtnIsDisabled()
})
it('Verify Tooltip displays correct message for disconnected user [C56031]', () => {
@@ -27,8 +26,7 @@ describe('Remove Owners tests', () => {
owner.waitForConnectionStatus()
owner.clickOnWalletExpandMoreIcon()
owner.clickOnDisconnectBtn()
- owner.hoverOverDeleteOwnerBtn(0)
- owner.verifyTooltipLabel(owner.disconnectedUserErrorMsg)
+ owner.verifyRemoveBtnIsDisabled()
})
it('Verify owner removal form can be opened [C56032]', () => {
diff --git a/cypress/e2e/smoke/replace_owner.cy.js b/cypress/e2e/smoke/replace_owner.cy.js
index d16935dc93..b43ec2a8ce 100644
--- a/cypress/e2e/smoke/replace_owner.cy.js
+++ b/cypress/e2e/smoke/replace_owner.cy.js
@@ -18,16 +18,14 @@ describe('Replace Owners tests', () => {
it('Verify Tooltip displays correct message for Non-Owner [C56016]', () => {
cy.visit(constants.setupUrl + constants.SEPOLIA_TEST_SAFE_2)
owner.waitForConnectionStatus()
- owner.hoverOverReplaceOwnerBtn()
- owner.verifyTooltipLabel(owner.nonOwnerErrorMsg)
+ owner.verifyReplaceBtnIsDisabled()
})
it('Verify Tooltip displays correct message for disconnected user [C56006]', () => {
owner.waitForConnectionStatus()
owner.clickOnWalletExpandMoreIcon()
owner.clickOnDisconnectBtn()
- owner.hoverOverReplaceOwnerBtn()
- owner.verifyTooltipLabel(owner.disconnectedUserErrorMsg)
+ owner.verifyReplaceBtnIsDisabled()
})
it('Verify that the owner replacement form is opened [C56007]', () => {
diff --git a/cypress/e2e/smoke/tx_history.cy.js b/cypress/e2e/smoke/tx_history.cy.js
index b0b7c18c54..cbc49612ed 100644
--- a/cypress/e2e/smoke/tx_history.cy.js
+++ b/cypress/e2e/smoke/tx_history.cy.js
@@ -2,16 +2,14 @@ import * as constants from '../../support/constants'
import * as main from '../pages/main.page'
import * as createTx from '../pages/create_tx.pages'
-const INCOMING = 'Received'
const OUTGOING = 'Sent'
-const CONTRACT_INTERACTION = 'Contract interaction'
const str1 = 'Received'
const str2 = 'Executed'
const str3 = 'Transaction hash'
describe('Transaction history tests', () => {
- before(() => {
+ beforeEach(() => {
cy.clearLocalStorage()
// Go to the test Safe transaction history
cy.visit(constants.transactionsHistoryUrl + constants.SEPOLIA_TEST_SAFE_5)
@@ -19,117 +17,38 @@ describe('Transaction history tests', () => {
// So that tests that rely on this feature don't randomly fail
cy.window().then((win) => win.localStorage.setItem('SAFE_v2__AB_human-readable', true))
- main.acceptCookies()
+ main.acceptCookies(1)
})
- //Skipping this due to test data creation
- it.skip('Verify October 9th transactions are displayed [C56128]', () => {
- const DATE = 'Oct 9, 2023'
- const NEXT_DATE_LABEL = 'Oct 11, 2023'
- const amount = '0.1 ETH'
- const amount2 = '15 TT_A'
- const amount3 = '21 TT_B'
- const amount4 = '82 DAI'
- const amount5 = '73 USDC'
- const amount6 = '27 AAVE'
- const amount7 = '35.94 LINK'
- const amount8 = '< 0.00001 ETH'
- const time = '2:56 AM'
- const time2 = '12:59 AM'
- const time3 = '1:00 AM'
- const time4 = '1:01 AM'
+ it('Verify October 9th transactions are displayed [C56128]', () => {
+ const DATE = 'Oct 29, 2023'
+ const NEXT_DATE_LABEL = 'Oct 20, 2023'
+ const amount = '0.00001 ETH'
+ const time = '10:39 PM'
const success = 'Success'
createTx.verifyDateExists(DATE)
createTx.verifyDateExists(NEXT_DATE_LABEL)
- main.scrollToBottomAndWaitForPageLoad()
- // Transaction summaries from October 9th
const rows = cy.contains('div', DATE).nextUntil(`div:contains(${NEXT_DATE_LABEL})`)
- rows.should('have.length', 3)
+ rows.should('have.length', 10)
- rows
- .last()
- .prev()
- .within(() => {
- // Type
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
+ rows.eq(0).within(() => {
+ // Type
+ createTx.verifyImageAltTxt(0, OUTGOING)
+ createTx.verifyStatus(constants.transactionStatus.sent)
- // Info
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.sep)
- createTx.verifyTransactionStrExists(amount)
- createTx.verifyTransactionStrExists(time)
- createTx.verifyTransactionStrExists(success)
- })
- .prev()
- .within(() => {
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.tta)
- createTx.verifyTransactionStrExists(amount2)
- createTx.verifyTransactionStrExists(time2)
- createTx.verifyTransactionStrExists(success)
- })
- .prev()
- .within(() => {
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.ttb)
- createTx.verifyTransactionStrExists(amount3)
- createTx.verifyTransactionStrExists(time2)
- createTx.verifyTransactionStrExists(success)
- })
- .prev()
- .within(() => {
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.dai)
- createTx.verifyTransactionStrExists(amount4)
- createTx.verifyTransactionStrExists(time2)
- createTx.verifyTransactionStrExists(success)
- })
- .prev()
- .within(() => {
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.usds)
- createTx.verifyTransactionStrExists(amount5)
- createTx.verifyTransactionStrExists(time3)
- createTx.verifyTransactionStrExists(success)
- })
- .prev()
- .within(() => {
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.aave)
- createTx.verifyTransactionStrExists(amount6)
- createTx.verifyTransactionStrExists(time3)
- createTx.verifyTransactionStrExists(success)
- })
- .prev()
- .within(() => {
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.link)
- createTx.verifyTransactionStrExists(amount7)
- createTx.verifyTransactionStrExists(time3)
- createTx.verifyTransactionStrExists(success)
- })
- .prev()
- .within(() => {
- createTx.verifyImageAltTxt(0, INCOMING)
- createTx.verifyStatus(constants.transactionStatus.received)
- createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.sep)
- createTx.verifyTransactionStrExists(amount8)
- createTx.verifyTransactionStrExists(time4)
- createTx.verifyTransactionStrExists(success)
- })
+ // Info
+ createTx.verifyImageAltTxt(1, constants.tokenAbbreviation.sep)
+ createTx.verifyTransactionStrExists(amount)
+ createTx.verifyTransactionStrExists(time)
+ createTx.verifyTransactionStrExists(success)
+ })
})
it('Verify transaction can be expanded/collapsed [C56129]', () => {
- createTx.clickOnTransactionExpandableItem('Oct 9, 2023', () => {
+ createTx.clickOnTransactionExpandableItem('Oct 20, 2023', () => {
createTx.verifyTransactionStrExists(str1)
createTx.verifyTransactionStrExists(str2)
createTx.verifyTransactionStrExists(str3)
diff --git a/src/pages/_app.tsx b/src/pages/_app.tsx
index 3c72dc183d..ec90253c7a 100644
--- a/src/pages/_app.tsx
+++ b/src/pages/_app.tsx
@@ -42,6 +42,7 @@ import { WalletConnectProvider } from '@/services/walletconnect/WalletConnectCon
import useABTesting from '@/services/tracking/useAbTesting'
import { AbTest } from '@/services/tracking/abTesting'
import { useNotificationTracking } from '@/components/settings/PushNotifications/hooks/useNotificationTracking'
+import MobilePairingModal from '@/services/pairing/QRModal'
const GATEWAY_URL = IS_PRODUCTION || cgwDebugStorage.get() ? GATEWAY_URL_PRODUCTION : GATEWAY_URL_STAGING
@@ -123,6 +124,8 @@ const WebCoreApp = ({
+
+
diff --git a/src/services/pairing/QRModal.tsx b/src/services/pairing/QRModal.tsx
index b363838046..47b2e18b14 100644
--- a/src/services/pairing/QRModal.tsx
+++ b/src/services/pairing/QRModal.tsx
@@ -1,95 +1,55 @@
-import { useState } from 'react'
import { Dialog, DialogContent, DialogTitle, IconButton } from '@mui/material'
-import { createRoot } from 'react-dom/client'
import CloseIcon from '@mui/icons-material/Close'
import PairingQRCode from '@/components/common/PairingDetails/PairingQRCode'
import PairingDescription from '@/components/common/PairingDetails/PairingDescription'
-import { StoreHydrator } from '@/store'
-import { AppProviders } from '@/pages/_app'
import { PAIRING_MODULE_LABEL } from '@/services/pairing/module'
-import css from './styles.module.css'
import PairingDeprecationWarning from '@/components/common/PairingDetails/PairingDeprecationWarning'
+import ExternalStore from '@/services/ExternalStore'
-const WRAPPER_ID = 'safe-mobile-qr-modal'
-const QR_CODE_SIZE = 200
+const { useStore: useCloseCallback, setStore: setCloseCallback } = new ExternalStore<() => void>()
-const renderWrapper = () => {
- if (typeof document === 'undefined') {
- return
- }
-
- const wrapper = document.createElement('div')
- wrapper.setAttribute('id', WRAPPER_ID)
-
- document.body.appendChild(wrapper)
-
- return wrapper
-}
-
-const open = (uri: string, cb: () => void) => {
- const wrapper = renderWrapper()
-
- if (!wrapper) {
- return
- }
-
- const root = createRoot(wrapper)
-
- root.render()
+export const open = (cb: () => void) => {
+ setCloseCallback(() => cb)
}
-const close = () => {
- if (typeof document === 'undefined') {
- return
- }
-
- const wrapper = document.getElementById(WRAPPER_ID)
- if (wrapper) {
- document.body.removeChild(wrapper)
- document.body.style.overflow = ''
- }
+export const close = () => {
+ setCloseCallback(undefined)
}
-const Modal = ({ uri, cb }: { uri: string; cb: () => void }) => {
- const [open, setOpen] = useState(true)
+const QRModal = () => {
+ const closeCallback = useCloseCallback()
+ const open = !!closeCallback
const handleClose = () => {
- cb()
- setOpen(false)
+ closeCallback?.()
+ setCloseCallback(undefined)
close()
}
+ if (!open) return null
+
return (
-
-
-
-
-
+
)
}
-const QRModal = {
- open,
- close,
-}
-
export default QRModal
diff --git a/src/services/pairing/module.ts b/src/services/pairing/module.ts
index fe5eba715c..add033b65c 100644
--- a/src/services/pairing/module.ts
+++ b/src/services/pairing/module.ts
@@ -5,6 +5,7 @@ import type { ITxData } from '@walletconnect/types'
import { getPairingConnector, PAIRING_MODULE_STORAGE_ID } from '@/services/pairing/connector'
import local from '@/services/local-storage/local'
import { killPairingSession } from '@/services/pairing/utils'
+import * as QRModal from '@/services/pairing/QRModal'
enum ProviderEvents {
ACCOUNTS_CHANGED = 'accountsChanged',
@@ -44,8 +45,6 @@ const pairingModule = (): WalletInit => {
const { default: WalletConnect } = await import('@walletconnect/client')
- const { default: QRModal } = await import('@/services/pairing/QRModal')
-
const { Subject, fromEvent } = await import('rxjs')
const { takeUntil, take } = await import('rxjs/operators')
@@ -131,7 +130,7 @@ const pairingModule = (): WalletInit => {
return new Promise((resolve, reject) => {
if (!this.connector.connected) {
this.connector.createSession().then(() => {
- QRModal.open(this.connector.uri, () =>
+ QRModal.open(() =>
reject(
new ProviderRpcError({
code: 4001,
diff --git a/src/services/pairing/styles.module.css b/src/services/pairing/styles.module.css
deleted file mode 100644
index d1e8523d06..0000000000
--- a/src/services/pairing/styles.module.css
+++ /dev/null
@@ -1,3 +0,0 @@
-.modal {
- z-index: var(--onboard-modal-z-index) !important;
-}