Skip to content

Commit

Permalink
Tests: add csv import tests (#3232)
Browse files Browse the repository at this point in the history
* tests: add csv import tests

* tests: change network from gnosis to etherium
  • Loading branch information
mike10ca authored Feb 9, 2024
1 parent 88c5b56 commit 629dedf
Show file tree
Hide file tree
Showing 13 changed files with 172 additions and 53 deletions.
81 changes: 63 additions & 18 deletions cypress/e2e/pages/address_book.page.js
Original file line number Diff line number Diff line change
@@ -1,41 +1,86 @@
export const acceptSelection = 'Save settings'
export const addressBook = 'Address book'
const createEntryBtn = 'Create entry'
import * as main from '../pages/main.page'

export const addressBookRecipient = '[data-testid="address-book-recipient"]'
const beameriFrameContainer = '#beamerOverlay .iframeCointaner'
const beamerInput = 'input[id="beamer"]'
const nameInput = 'input[name="name"]'
const addressInput = 'input[name="address"]'
export const addressBookRecipient = '[data-testid="address-book-recipient"]'
const saveBtn = 'Save'
const exportModalBtn = '[data-testid="export-modal-btn"]'
export const editEntryBtn = 'button[aria-label="Edit entry"]'
export const deleteEntryBtn = 'button[aria-label="Delete entry"]'
export const deleteEntryModalBtnSection = '.MuiDialogActions-root'
const tableContainer = '[data-testid="table-container"]'
const tableRow = '[data-testid="table-row"]'
const importBtn = '[data-testid="import-btn"]'
const cancelImportBtn = '[data-testid="cancel-btn"]'
const uploadErrorMsg = '[data-testid="error-message"]'
const modalSummaryMessage = '[data-testid="summary-message"]'

export const acceptSelection = 'Save settings'
export const addressBook = 'Address book'
const createEntryBtn = 'Create entry'
export const delteEntryModaldeleteBtn = 'Delete'
const importBtn = 'Import'
const exportBtn = 'Export'
const exportModalBtn = '[data-testid="export-modal-btn"]'
const saveBtn = 'Save'
const whatsNewBtnStr = "What's new"
const beamrCookiesStr = 'accept the "Beamer" cookies'
const headerImportBtnStr = 'Import'

export const emptyCSVFile = '../fixtures/address_book_empty_test.csv'
export const nonCSVFile = '../fixtures/balances.json'
export const duplicatedCSVFile = 'address_book_duplicated.csv'
export const validCSVFile = '../fixtures/address_book_test.csv'
export const networksCSVFile = '../fixtures/address_book_networks.csv'
export const addedSafesCSVFile = '../fixtures/address_book_addedsafes.csv'

export const entries = [
'0x6E834E9D04ad6b26e1525dE1a37BFd9b215f40B7',
'test-sepolia-3',
'0xf405BC611F4a4c89CCB3E4d083099f9C36D966f8',
'sepolia-test-4',
'0x03042B890b99552b60A073F808100517fb148F60',
'sepolia-test-5',
'0xBd69b0a9DC90eB6F9bAc3E4a5875f437348b6415',
'assets-test-sepolia',
]

export function verifyModalSummaryMessage(entryCount, chainCount) {
cy.get(modalSummaryMessage).should(
'contain',
`Found ${entryCount} entries on ${chainCount} ${chainCount > 1 ? 'chains' : 'chain'}`,
)
}
export const uploadErrorMessages = {
fileType: 'File type must be text/csv',
emptyFile: 'No entries found in address book',
}

export function verifyUploadExportMessage(msg) {
main.verifyValuesExist(uploadErrorMsg, msg)
}

export function verifyImportBtnStatus(status) {
main.verifyElementsStatus([importBtn], status)
}

export function verifyNumberOfRows(number) {
main.verifyElementsCount(tableRow, number)
}

export function clickOnImportFileBtn() {
cy.contains(importBtn).click()
cy.contains(headerImportBtnStr).click()
}

export function importFile() {
cy.get('[type="file"]').attachFile('../fixtures/address_book_test.csv')
// Import button should be enabled
cy.get('.MuiDialogActions-root').contains('Import').should('not.be.disabled')
cy.get('.MuiDialogActions-root').contains('Import').click()
export function importCSVFile(file) {
cy.get('[type="file"]').attachFile(file)
}

export function verifyImportModalIsClosed() {
cy.get('Import address book').should('not.exist')
export function clickOnImportBtn() {
cy.get(importBtn).click()
}

export function verifyDataImported(name, address) {
cy.contains(name).should('exist')
cy.contains(address).should('exist')
export function verifyDataImported(data) {
main.verifyValuesExist(tableContainer, data)
}

export function clickOnExportFileBtn() {
Expand Down
2 changes: 1 addition & 1 deletion cypress/e2e/pages/sidebar.pages.js
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ const currencySection = '[data-testid="currency-section"]'
const missingSignatureInfo = '[data-testid="missing-signature-info"]'
const queuedTxInfo = '[data-testid="queued-tx-info"]'

export const addedSafesGnosis = ['0x17b3...98C8', '0x11A6...F1BB', '0xB8d7...642A']
export const addedSafesEth = ['0x8675...a19b']
export const addedSafesSepolia = ['0x6d0b...6dC1', '0x5912...fFdb', '0x0637...708e', '0xD157...DE9a']
export const sideBarListItems = ['Home', 'Assets', 'Transactions', 'Address book', 'Apps', 'Settings']
export const testSafeHeaderDetails = ['2/2', constants.SEPOLIA_TEST_SAFE_13_SHORT]
Expand Down
38 changes: 36 additions & 2 deletions cypress/e2e/regression/address_book.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@ import * as constants from '../../support/constants'
import * as addressBook from '../../e2e/pages/address_book.page'
import * as main from '../../e2e/pages/main.page'
import * as ls from '../../support/localstorage_data.js'
import * as sidebar from '../pages/sidebar.pages.js'

const NAME = 'Owner1'
const EDITED_NAME = 'Edited Owner1'
const importedSafe = 'imported-safe'

describe('Address book tests', () => {
beforeEach(() => {
Expand Down Expand Up @@ -51,8 +53,7 @@ describe('Address book tests', () => {
cy.contains(constants.GNO_CSV_ENTRY.address).should('exist')
})

// TODO: Change title in Testrail. New title "...exported"
it('Verify the address book file can be downloaded', () => {
it('Verify the address book file can be exported', () => {
main.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addressBook, ls.addressBookData.dataSet).then(() => {
main
.isItemInLocalstorage(constants.localStorageKeys.SAFE_v2__addressBook, ls.addressBookData.dataSet)
Expand All @@ -72,4 +73,37 @@ describe('Address book tests', () => {
})
})
})

it('Verify that importing a csv file does not alter addresses in the Address book not present in the file', () => {
main
.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addressBook, ls.addressBookData.sepoliaAddress1)
.then(() => {
main
.isItemInLocalstorage(constants.localStorageKeys.SAFE_v2__addressBook, ls.addressBookData.sepoliaAddress1)
.then(() => {
cy.wait(1000)
cy.reload()
addressBook.clickOnImportFileBtn()
addressBook.importCSVFile(addressBook.validCSVFile)
addressBook.clickOnImportBtn()
addressBook.verifyDataImported([constants.RECIPIENT_ADDRESS])
})
})
})

it('Verify Safe name changes after uploading a csv file', () => {
main.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addedSafes, ls.addedSafes.set4).then(() => {
main
.addToLocalStorage(constants.localStorageKeys.SAFE_v2__addressBook, ls.addressBookData.addedSafesImport)
.then(() => {
cy.wait(1000)
cy.reload()
addressBook.clickOnImportFileBtn()
addressBook.importCSVFile(addressBook.addedSafesCSVFile)
addressBook.clickOnImportBtn()
sidebar.openSidebar()
sidebar.verifyAddedSafesExist([importedSafe])
})
})
})
})
15 changes: 7 additions & 8 deletions cypress/e2e/regression/sidebar_2.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,7 @@ import * as ls from '../../support/localstorage_data.js'
import * as assets from '../pages/assets.pages.js'

const newSafeName = 'Added safe 3'
const oldSafeName = 'Added safe 900'
const staticSafe100 = 'Added safe 100'
const addedSafe900 = 'Added safe 900'
const staticSafe200 = 'Added safe 200'

describe('Sidebar added sidebar tests', () => {
Expand All @@ -21,31 +20,31 @@ describe('Sidebar added sidebar tests', () => {

it('Verify the safe added are listed in the sidebar', () => {
sideBar.openSidebar()
sideBar.verifyAddedSafesExist(sideBar.addedSafesGnosis, sideBar.addedSafesSepolia)
sideBar.verifyAddedSafesExist(sideBar.addedSafesSepolia)
})

it('Verify Safes are separated by networks', () => {
sideBar.openSidebar()
sideBar.verifySafesByNetwork(constants.networks.gnosis, sideBar.addedSafesGnosis)
sideBar.verifySafesByNetwork(constants.networks.ethereum, sideBar.addedSafesEth)
sideBar.verifySafesByNetwork(constants.networks.sepolia, sideBar.addedSafesSepolia)
})

it('Verify a safe can be renamed', () => {
sideBar.openSidebar()
sideBar.renameSafeItem(oldSafeName, newSafeName)
sideBar.renameSafeItem(addedSafe900, newSafeName)
sideBar.clickOnSaveBtn()
sideBar.verifySafeNameExists(newSafeName)
})

it('Verify a safe can be removed', () => {
sideBar.openSidebar()
sideBar.removeSafeItem(oldSafeName)
sideBar.verifySafeRemoved([oldSafeName])
sideBar.removeSafeItem(addedSafe900)
sideBar.verifySafeRemoved([addedSafe900])
})

it('Verify the "Read only" tag if the connected user is not an owner of a safe', () => {
sideBar.openSidebar()
sideBar.verifySafeReadOnlyState(staticSafe100)
sideBar.verifySafeReadOnlyState(addedSafe900)
})

it('Verify Fiat currency changes when edited in the assets tab', () => {
Expand Down
39 changes: 36 additions & 3 deletions cypress/e2e/smoke/address_book.cy.js
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@ import * as ls from '../../support/localstorage_data.js'

const NAME = 'Owner1'
const EDITED_NAME = 'Edited Owner1'
const duplicateEntry = 'test-sepolia-90'

describe('[SMOKE] Address book tests', () => {
beforeEach(() => {
Expand Down Expand Up @@ -37,8 +38,40 @@ describe('[SMOKE] Address book tests', () => {

it('[SMOKE] Verify csv file can be imported', () => {
addressBook.clickOnImportFileBtn()
addressBook.importFile()
addressBook.verifyImportModalIsClosed()
addressBook.verifyDataImported(constants.SEPOLIA_CSV_ENTRY.name, constants.SEPOLIA_CSV_ENTRY.address)
addressBook.importCSVFile(addressBook.validCSVFile)
addressBook.verifyImportBtnStatus(constants.enabledStates.enabled)
addressBook.clickOnImportBtn()
addressBook.verifyDataImported(addressBook.entries)
addressBook.verifyNumberOfRows(4)
})

it('[SMOKE] Import a csv file with an empty address/name/network in one row', () => {
addressBook.clickOnImportFileBtn()
addressBook.importCSVFile(addressBook.emptyCSVFile)
addressBook.verifyImportBtnStatus(constants.enabledStates.disabled)
addressBook.verifyUploadExportMessage([addressBook.uploadErrorMessages.emptyFile])
})

it('[SMOKE] Import a non-csv file', () => {
addressBook.clickOnImportFileBtn()
addressBook.importCSVFile(addressBook.nonCSVFile)
addressBook.verifyImportBtnStatus(constants.enabledStates.disabled)
addressBook.verifyUploadExportMessage([addressBook.uploadErrorMessages.fileType])
})

it('[SMOKE] Import a csv file with a repeated address and same network', () => {
addressBook.clickOnImportFileBtn()
addressBook.importCSVFile(addressBook.duplicatedCSVFile)
addressBook.verifyImportBtnStatus(constants.enabledStates.enabled)
addressBook.clickOnImportBtn()
addressBook.verifyDataImported([duplicateEntry])
addressBook.verifyNumberOfRows(1)
})

it('[SMOKE] Verify modal shows the amount of entries and networks detected', () => {
addressBook.clickOnImportFileBtn()
addressBook.importCSVFile(addressBook.networksCSVFile)
addressBook.verifyImportBtnStatus(constants.enabledStates.enabled)
addressBook.verifyModalSummaryMessage(4, 3)
})
})
2 changes: 2 additions & 0 deletions cypress/fixtures/address_book_addedsafes.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
address,name,chainId
0x6d0b6F96f665Bb4490f9ddb2e450Da2f7e546dC1,imported-safe,11155111
3 changes: 3 additions & 0 deletions cypress/fixtures/address_book_duplicated.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
address,name,chainId
0x6E834E9D04ad6b26e1525dE1a37BFd9b215f40B7,test-sepolia-9,11155111
0x6E834E9D04ad6b26e1525dE1a37BFd9b215f40B7,test-sepolia-90,11155111
1 change: 1 addition & 0 deletions cypress/fixtures/address_book_empty_test.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
address,name,chainId
5 changes: 5 additions & 0 deletions cypress/fixtures/address_book_networks.csv
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
address,name,chainId
0x8675B754342754A30A2AeF474D114d8460bca19b,"mainnet safe ",1
0xB8d760a90a5ed54D3c2b3EFC231277e99188642A,"xDai Safe B8", 100
0x91e11585c114129f3Ec940Aa648A4ac13668d0c2,"Biance safe91", 56
0x61a0c717d18232711bC788F19C9Cd56a43cc8872,"MM account 1", 1
20 changes: 4 additions & 16 deletions cypress/support/localstorage_data.js
Original file line number Diff line number Diff line change
Expand Up @@ -317,10 +317,8 @@ export const addressBookData = {
},
},
addedSafes: {
100: {
'0x17b34aEf1428A358bA2eA360a098b8A3BEb698C8': 'Added safe 1',
'0x11A6B41322C57Bd0e56cEe06abB11A1E5c1FF1BB': 'Added safe 900',
'0xB8d760a90a5ed54D3c2b3EFC231277e99188642A': 'Added safe 100',
1: {
'0x8675B754342754A30A2AeF474D114d8460bca19b': 'Added safe 900',
},
11155111: {
'0x0A0EEb6fBCc7c82259E548Fc4617175A357b3e71': 'Added safe 200',
Expand Down Expand Up @@ -529,22 +527,12 @@ export const addedSafes = {
ethBalance: '0',
},
},
100: {
'0x17b34aEf1428A358bA2eA360a098b8A3BEb698C8': {
1: {
'0x8675B754342754A30A2AeF474D114d8460bca19b': {
owners: [{ value: '0x11B1D54B66e5e226D6f89069c21A569A22D98cfd' }],
threshold: 1,
ethBalance: '0.001000002',
},
'0x11A6B41322C57Bd0e56cEe06abB11A1E5c1FF1BB': {
owners: [{ value: '0x7724b234c9099C205F03b458944942bcEBA13408' }],
threshold: 1,
ethBalance: '0',
},
'0xB8d760a90a5ed54D3c2b3EFC231277e99188642A': {
owners: [{ value: '0x11B1D54B66e5e226D6f89069c21A569A22D98cfd' }],
threshold: 1,
ethBalance: '0.92132507668989',
},
},
},
set3: {
Expand Down
14 changes: 11 additions & 3 deletions src/components/address-book/ImportDialog/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -128,7 +128,7 @@ const ImportDialog = ({ handleClose }: { handleClose: () => void }): ReactElemen
name: acceptedFile.name,
additionalInfo: formatFileSize(acceptedFile.size),
summary: [
<Typography key="abSummary">
<Typography data-testid="summary-message" key="abSummary">
{`Found ${entryCount} entries on ${chainCount} ${chainCount > 1 ? 'chains' : 'chain'}`}
</Typography>,
],
Expand Down Expand Up @@ -163,8 +163,16 @@ const ImportDialog = ({ handleClose }: { handleClose: () => void }): ReactElemen
</Typography>
</DialogContent>
<DialogActions>
<Button onClick={handleClose}>Cancel</Button>
<Button onClick={handleImport} variant="contained" disableElevation disabled={!csvData || !!error}>
<Button data-testid="cancel-btn" onClick={handleClose}>
Cancel
</Button>
<Button
data-testid="import-btn"
onClick={handleImport}
variant="contained"
disableElevation
disabled={!csvData || !!error}
>
Import
</Button>
</DialogActions>
Expand Down
3 changes: 2 additions & 1 deletion src/components/common/EnhancedTable/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -135,13 +135,14 @@ function EnhancedTable({ rows, headCells, mobileVariant }: EnhancedTableProps) {

return (
<Box sx={{ width: '100%' }}>
<TableContainer component={Paper} sx={{ width: '100%', mb: 2 }}>
<TableContainer data-testid="table-container" component={Paper} sx={{ width: '100%', mb: 2 }}>
<Table aria-labelledby="tableTitle" className={mobileVariant ? css.mobileColumn : undefined}>
<EnhancedTableHead headCells={headCells} order={order} orderBy={orderBy} onRequestSort={handleRequestSort} />
<TableBody>
{pagedRows.length > 0 ? (
pagedRows.map((row, index) => (
<TableRow
data-testid="table-row"
tabIndex={-1}
key={row.key ?? index}
selected={row.selected}
Expand Down
2 changes: 1 addition & 1 deletion src/components/tx/ErrorMessage/index.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ const ErrorMessage = ({
}

return (
<div className={classNames(css.container, css[level], className, 'errorMessage')}>
<div data-testid="error-message" className={classNames(css.container, css[level], className, 'errorMessage')}>
<div className={css.message}>
<SvgIcon
component={level === 'info' ? InfoIcon : WarningIcon}
Expand Down

0 comments on commit 629dedf

Please sign in to comment.