mirror of
https://github.com/luxfi/safe-wallet.git
synced 2026-10-30 15:19:21 +00:00
* tests(web): connect wallet via seeded storage in e2e Replace the UI-driven connectSigner flow with storage-seeded auto-reconnect across the Cypress suite. Adds connectSignerViaStorage (seed on visit, or seed + reload) and migrates 139 entry connects; keeps UI connectSigner for the 27 connect/switch-flow sites that act on in-page state. * tests(web): seed batch via single page load in batch e2e Add optional extraStorage to connectSignerViaStorage so localStorage is seeded in onBeforeLoad on the initial visit. Split batch_tx into build-via-UI and pre-seeded describes, dropping addToLocalStorage + cy.reload() double-loads. * tests(web): seed state on a single page load across e2e specs Replace visit-then-write-then-reload double-loads with a single seeded load (extraStorage on connectSignerViaStorage, or onBeforeLoad on cy.visit), and drop the arbitrary post-reload settle waits. Covers the multichain, nested-safes, batch, address-book, safe-selector and create-safe specs (regression, smoke, visual). * tests(web): seed state on a single page load in more e2e specs Fold pre-seeded localStorage into the initial visit (extraStorage / onBeforeLoad) and drop the follow-up reloads across the address-book, messages-popup, CF-safe, import/export and load-safe specs. Split specs whose shared beforeEach served both seeding and non-seeding tests into nested describes so no test double-loads. * tests(web): remove redundant wallet reconnect reloads in e2e specs Pass the URL to connectSignerViaStorage so the wallet is seeded on the initial visit instead of visiting then reconnecting (which reloaded). Where a shared beforeEach served both connected and disconnected (or differently-seeded) tests, split into nested describes so no test double-loads. Covers proposers, swaps, twaps, assets, swaps_tokens, sidebar, spending_limits, bulk_execution, proposers_2, safe_selector. * tests(web): single-load owner-management e2e specs Split add/remove/replace-owner specs into connected / disconnected / non-owner / pre-seeded describes so the wallet is seeded on the initial visit (no reconnect reload) without forcing a connect onto tests that assert disconnected or non-owner state. * tests(web): wait for wallet connection after seeded connect The last wallet reconnects asynchronously after the page loads, so connectSignerViaStorage now waits for the connected-wallet header chip (open-account-center) before resolving, instead of letting tests proceed while still disconnected. Opt out via waitForConnection:false for pages without that chip (welcome/accounts in safe_selector). * tests(web): address review on seeded-connect PR - Drop the explicit 30s timeout on the connected-wallet wait; the repo default (10s) is plenty for the post-load reconnect and fails faster. - Make recovery.cy.js consistent: the remaining connectSigner calls now use connectSignerViaStorage like the rest of the file. All connects are at test start (none mid-flow), matching the already-converted tests. * fix: wait for the wallet connection to establish to avoid failing tests due to disconnected wallet --------- Co-authored-by: vmosharova <[email protected]>
172 lines
6.2 KiB
JavaScript
172 lines
6.2 KiB
JavaScript
import * as constants from '../../support/constants'
|
|
import * as main from '../pages/main.page'
|
|
import * as assets from '../pages/assets.pages'
|
|
import * as createTx from '../pages/create_tx.pages'
|
|
import * as tx from '../pages/transactions.page'
|
|
import { ethers } from 'ethers'
|
|
import SafeApiKit from '@safe-global/api-kit'
|
|
import { createSigners } from '../../support/api/utils_ether'
|
|
import { createSafes } from '../../support/api/utils_protocolkit'
|
|
import { getSafes, CATEGORIES } from '../../support/safes/safesHandler.js'
|
|
import * as wallet from '../../support/utils/wallet.js'
|
|
import * as ls from '../../support/localstorage_data.js'
|
|
import * as navigation from '../pages/navigation.page.js'
|
|
import * as fundSafes from '../../fixtures/safes/funds.json'
|
|
|
|
const walletCredentials = JSON.parse(Cypress.env('CYPRESS_WALLET_CREDENTIALS'))
|
|
const receiver = walletCredentials.OWNER_2_WALLET_ADDRESS
|
|
const signer = walletCredentials.OWNER_4_PRIVATE_KEY
|
|
|
|
const tokenAmount = '0.0001'
|
|
const netwrok = 'sepolia'
|
|
const network_pref = 'sep:'
|
|
const unit_eth = 'ether'
|
|
let apiKit,
|
|
protocolKitOwnerS1,
|
|
protocolKitOwnerS2,
|
|
protocolKitOwner1_S3,
|
|
protocolKitOwner2_S3,
|
|
existingSafeAddress1,
|
|
existingSafeAddress2,
|
|
existingSafeAddress3
|
|
|
|
let safes = []
|
|
let safesData = []
|
|
|
|
const provider = new ethers.InfuraProvider(netwrok, Cypress.env('INFURA_API_KEY'))
|
|
const privateKeys = [walletCredentials.OWNER_1_PRIVATE_KEY, walletCredentials.OWNER_2_PRIVATE_KEY]
|
|
|
|
const signers = createSigners(privateKeys, provider)
|
|
|
|
const owner1Signer = signers[0]
|
|
const owner2Signer = signers[1]
|
|
|
|
function visit(url) {
|
|
cy.visit(url)
|
|
}
|
|
|
|
function executeTransactionFlow(fromSafe) {
|
|
visit(constants.transactionQueueUrl + fromSafe)
|
|
wallet.connectSignerViaStorage(signer)
|
|
createTx.clickOnConfirmBtn(0)
|
|
tx.executeFlow_1()
|
|
cy.wait(5000)
|
|
}
|
|
|
|
describe('Send funds from queue happy path tests 1', () => {
|
|
before(async () => {
|
|
cy.clearLocalStorage().then(() => {
|
|
main.addToLocalStorage(constants.localStorageKeys.SAFE_v2_cookies, ls.cookies.acceptedCookies)
|
|
main.addToLocalStorage(
|
|
constants.localStorageKeys.SAFE_v2__tokenlist_onboarding,
|
|
ls.cookies.acceptedTokenListOnboarding,
|
|
)
|
|
})
|
|
|
|
safesData = fundSafes
|
|
apiKit = new SafeApiKit({
|
|
chainId: BigInt(1),
|
|
txServiceUrl: constants.stagingTxServiceUrl,
|
|
})
|
|
|
|
existingSafeAddress1 = safesData.SEP_FUNDS_SAFE_3.substring(4)
|
|
existingSafeAddress2 = safesData.SEP_FUNDS_SAFE_4.substring(4)
|
|
existingSafeAddress3 = safesData.SEP_FUNDS_SAFE_5.substring(4)
|
|
|
|
const safeConfigurations = [
|
|
{ signer: privateKeys[0], safeAddress: existingSafeAddress1, provider },
|
|
{ signer: privateKeys[0], safeAddress: existingSafeAddress2, provider },
|
|
{ signer: privateKeys[0], safeAddress: existingSafeAddress3, provider },
|
|
{ signer: privateKeys[1], safeAddress: existingSafeAddress3, provider },
|
|
]
|
|
|
|
safes = await createSafes(safeConfigurations)
|
|
|
|
protocolKitOwnerS1 = safes[0]
|
|
protocolKitOwnerS2 = safes[1]
|
|
protocolKitOwner1_S3 = safes[2]
|
|
protocolKitOwner2_S3 = safes[3]
|
|
})
|
|
|
|
it('Verify confirmation and execution of native token queued tx by second signer with connected wallet', () => {
|
|
cy.wrap(null)
|
|
.then(() => {
|
|
return main.fetchCurrentNonce(network_pref + existingSafeAddress1)
|
|
})
|
|
.then(async (currentNonce) => {
|
|
const amount = ethers.parseUnits(tokenAmount, unit_eth).toString()
|
|
const safeTransactionData = {
|
|
to: receiver,
|
|
data: '0x',
|
|
value: amount.toString(),
|
|
}
|
|
|
|
const safeTransaction = await protocolKitOwnerS1.createTransaction({ transactions: [safeTransactionData] })
|
|
const safeTxHash = await protocolKitOwnerS1.getTransactionHash(safeTransaction)
|
|
const senderSignature = await protocolKitOwnerS1.signHash(safeTxHash)
|
|
const safeAddress = existingSafeAddress1
|
|
|
|
await apiKit.proposeTransaction({
|
|
safeAddress,
|
|
safeTransactionData: safeTransaction.data,
|
|
safeTxHash,
|
|
senderAddress: await owner1Signer.getAddress(),
|
|
senderSignature: senderSignature.data,
|
|
})
|
|
|
|
executeTransactionFlow(safeAddress)
|
|
cy.wait(5000)
|
|
main.verifyNonceChange(network_pref + safeAddress, currentNonce + 1)
|
|
navigation.clickOnWalletExpandMoreIcon()
|
|
navigation.clickOnDisconnectBtn()
|
|
})
|
|
})
|
|
|
|
it('Verify 1 signer can execute a tx confirmed by 2 signers', { defaultCommandTimeout: 300000 }, () => {
|
|
function executeTransaction(fromSafe) {
|
|
visit(constants.transactionQueueUrl + fromSafe)
|
|
wallet.connectSignerViaStorage(signer)
|
|
createTx.clickOnExecuteBtn(0)
|
|
tx.executeFlow_3()
|
|
cy.wait(5000)
|
|
}
|
|
cy.wrap(null)
|
|
.then(() => {
|
|
return main.fetchCurrentNonce(network_pref + existingSafeAddress3)
|
|
})
|
|
.then(async (currentNonce) => {
|
|
const amount = ethers.parseUnits(tokenAmount, unit_eth).toString()
|
|
const safeTransactionData = {
|
|
to: receiver,
|
|
data: '0x',
|
|
value: amount.toString(),
|
|
}
|
|
|
|
const safeTransaction = await protocolKitOwner1_S3.createTransaction({ transactions: [safeTransactionData] })
|
|
const safeTxHash = await protocolKitOwner1_S3.getTransactionHash(safeTransaction)
|
|
const senderSignature = await protocolKitOwner1_S3.signHash(safeTxHash)
|
|
const safeAddress = existingSafeAddress3
|
|
|
|
await apiKit.proposeTransaction({
|
|
safeAddress,
|
|
safeTransactionData: safeTransaction.data,
|
|
safeTxHash,
|
|
senderAddress: await owner1Signer.getAddress(),
|
|
senderSignature: senderSignature.data,
|
|
})
|
|
|
|
const pendingTransactions = await apiKit.getPendingTransactions(safeAddress)
|
|
const safeTxHashofExistingTx = pendingTransactions.results[0].safeTxHash
|
|
|
|
const signature = await protocolKitOwner2_S3.signHash(safeTxHashofExistingTx)
|
|
await apiKit.confirmTransaction(safeTxHashofExistingTx, signature.data)
|
|
|
|
executeTransaction(safeAddress)
|
|
cy.wait(5000)
|
|
main.verifyNonceChange(network_pref + safeAddress, currentNonce + 1)
|
|
navigation.clickOnWalletExpandMoreIcon()
|
|
navigation.clickOnDisconnectBtn()
|
|
})
|
|
})
|
|
})
|