Skip to content

Commit

Permalink
Merge branch 'main' into tbaut-tick-insteadof-waituntil
Browse files Browse the repository at this point in the history
  • Loading branch information
Tbaut authored Oct 13, 2023
2 parents 7e6bd79 + 499b33f commit 1f4fa56
Show file tree
Hide file tree
Showing 19 changed files with 241 additions and 31 deletions.
18 changes: 18 additions & 0 deletions packages/ui/cypress/fixtures/watchAccounts/watchMultisigs.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
import { watchSignatories } from './watchSignatories'

export const watchMultisigs = {
'multisig-with-pure': {
name: 'Multisig With Pure',
address: '5Fa3UUF3S6SVdXZtPrCw2tGUqxJiRJLxEGfujozfZ4xFeAKn',
pureAddress: '5EfdqwwuyjjtEa4UhdjbZJu3UxHEHbzh8LMRvE13xTD7z6Wd',
threshold: 2,
signatories: [watchSignatories[0].address, watchSignatories[1].address]
},

'multisig-without-pure': {
name: 'Multisig No Pure',
address: '5GysXAKXrGjNvpQruKWH3RwxtYrJqqWLN1A15gUMht6EXmzC',
threshold: 2,
signatories: [watchSignatories[2].address, watchSignatories[3].address]
}
}
29 changes: 29 additions & 0 deletions packages/ui/cypress/fixtures/watchAccounts/watchSignatories.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
export const watchSignatories = [
// signatories of multisig-with-pure
{
address: '5GGjPYsz8B8mxAzNScFNDPkZ1g97VWFCPCMexPSkPnibPBez',
name: 'Pure Signatory 1',
type: 'sr25519',
mnemonic: 'citizen heavy warrior cattle enter chef label split differ seek turtle gorilla'
},
{
address: '5EkbU3anZKYP98aXF5MvmCUxvwvM4kxp7osc2Xhj1wHYL6ym',
name: 'Pure Signatory 2',
type: 'sr25519',
mnemonic: 'script spoon elder spawn kite burst theme property hip fatal flight amount'
},

// signatories of multisig-without-pure
{
address: '5HfzjVSWj6mxBnqgJhPfUTpkAJKro9BKToxXB3nozbu2MTpV',
name: 'No Pure Signatory 1',
type: 'sr25519',
mnemonic: 'spring banana desert horse ecology resist tag matrix burden heart stereo fix'
},
{
address: '5Df1JyC6KSbjSp3pQEn85PCnvTtknGiN7JyE7bSZ9zqNL76E',
name: 'No Pure Signatory 2',
type: 'sr25519',
mnemonic: 'mutual pluck punch boy gym key brush dune master aunt track dynamic'
}
]
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const accountDisplay = {
identicon: () => cy.get('[data-cy=icon-identicon]'),
pureBadge: () => cy.get('[data-cy=badge-pure]'),
multisigBadge: () => cy.get('[data-cy=badge-multi]'),
nameLabel: () => cy.get('[data-cy=label-account-name]'),
addressLabel: () => cy.get('[data-cy=label-account-address]')
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
export const editNamesModal = {
body: () => cy.get('[data-cy=modal-edit-names]'),
inputEditPureName: () => cy.get('[data-cy=input-edit-pure-name]'),
inputEditMultisigName: () => cy.get('[data-cy=input-edit-multisig-name]'),
inputEditSignatoryName: () => cy.get('[data-cy=input-edit-signatory-name]'),
saveButton: () => cy.get('[data-cy=button-save-edited-names]')
}
8 changes: 7 additions & 1 deletion packages/ui/cypress/support/page-objects/multisigPage.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,9 @@
export const multisigPage = {
newTransactionButton: () => cy.get('[data-cy="button-new-transaction"]')
// header elements
accountHeader: () => cy.get('[data-cy=header-account]'),
seeOverviewButton: () => cy.get('[data-cy=button-see-overview]'),
newTransactionButton: () => cy.get('[data-cy=button-new-transaction]'),
optionsMenuButton: () => cy.get('[data-cy=button-options-menu]'),
editNamesMenuOption: () => cy.get('[data-cy=menu-option-edit-names]'),
subscanMenuOption: () => cy.get('[data-cy=menu-option-subscan]')
}
8 changes: 4 additions & 4 deletions packages/ui/cypress/support/page-objects/notifications.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const notifications = {
successNotificationIcon: () => cy.get('[data-cy="notification-icon-success"]'),
errorNotificationIcon: () => cy.get('[data-cy="notification-icon-error"]'),
loadingNotificationIcon: () => cy.get('[data-cy="notification-icon-loading"]'),
notificationWrapper: () => cy.get('[data-cy="notification-wrapper"]')
successNotificationIcon: () => cy.get('[data-cy=notification-icon-success]'),
errorNotificationIcon: () => cy.get('[data-cy=notification-icon-error]'),
loadingNotificationIcon: () => cy.get('[data-cy=notification-icon-loading]'),
notificationWrapper: () => cy.get('[data-cy=notification-wrapper]')
}
8 changes: 4 additions & 4 deletions packages/ui/cypress/support/page-objects/sendTxModal.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
export const sendTxModal = {
sendTxTitle: () => cy.get('[data-cy="title-send-tx"]'),
fieldTo: () => cy.get('[data-cy="field-to"]'),
fieldAmount: () => cy.get('[data-cy="field-amount"]'),
buttonSend: () => cy.get('[data-cy="button-send"]')
sendTxTitle: () => cy.get('[data-cy=title-send-tx]'),
fieldTo: () => cy.get('[data-cy=field-to]'),
fieldAmount: () => cy.get('[data-cy=field-amount]'),
buttonSend: () => cy.get('[data-cy=button-send]')
}
3 changes: 0 additions & 3 deletions packages/ui/cypress/support/page-objects/settingsPage.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,6 @@ export const settingsPage = {
accountNameInput: () => cy.get('[data-cy=input-account-name]'),
addButton: () => cy.get('[data-cy=button-add-watched-account]'),
accountContainer: () => cy.get('[data-cy=container-account-details]', { timeout: 20000 }),
accountIcon: () => cy.get('[data-cy=icon-identicon]'),
accountNameLabel: () => cy.get('[data-cy=label-account-name]'),
accountAddressLabel: () => cy.get('[data-cy=label-account-address]'),
accountDeleteButton: () => cy.get('[data-cy=button-delete-watched-account]'),
errorLabel: () => cy.get('[data-cy=label-watch-account-error]')
}
10 changes: 8 additions & 2 deletions packages/ui/cypress/support/page-objects/topMenuItems.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,10 @@
export const topMenuItems = {
connectButton: () => cy.get('[data-cy="button-menu-connect"]'),
multiproxySelector: () => cy.get('[data-cy="select-multiproxy"]')
homeButton: () => cy.get('[data-cy=button-navigate-home]'),
newMultisigButton: () => cy.get('[data-cy=button-new-multisig]'),
settingsButton: () => cy.get('[data-cy=button-navigate-settings]'),
overviewButton: () => cy.get('[data-cy=button-navigate-overview]'),
aboutButton: () => cy.get('[data-cy=button-navigate-about]'),
connectButton: () => cy.get('[data-cy=button-menu-connect]'),
multiproxySelector: () => cy.get('[data-cy=select-multiproxy]', { timeout: 20000 }),
multiproxySelectorOption: () => cy.get('[data-cy=select-multiproxy-option]')
}
138 changes: 133 additions & 5 deletions packages/ui/cypress/tests/watched-accounts.cy.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,12 @@
import { addresses } from '../fixtures/accounts'
import { accountDisplay } from '../support/page-objects/components/accountDisplay'
import { landingPageUrl, settingsPageWatchAccountUrl } from '../fixtures/landingData'
import { landingPage } from '../support/page-objects/landingPage'
import { settingsPage } from '../support/page-objects/settingsPage'
import { topMenuItems } from '../support/page-objects/topMenuItems'
import { watchMultisigs } from '../fixtures/watchAccounts/watchMultisigs'
import { multisigPage } from '../support/page-objects/multisigPage'
import { editNamesModal } from '../support/page-objects/modals/editNamesModal'

const addWatchAccount = (address: string, name?: string) => {
settingsPage.accountAddressInput().type(`${address}{enter}`, { delay: 20 })
Expand All @@ -19,9 +24,9 @@ describe('Watched Accounts', () => {
landingPage.watchAccountButton().click()
addWatchAccount(addresses.Alice, 'Alice')
settingsPage.accountContainer().within(() => {
settingsPage.accountIcon().should('be.visible')
settingsPage.accountAddressLabel().should('be.visible')
settingsPage.accountNameLabel().should('be.visible')
accountDisplay.identicon().should('be.visible')
accountDisplay.addressLabel().should('be.visible')
accountDisplay.nameLabel().should('be.visible')
settingsPage.accountDeleteButton().should('be.visible')
})
})
Expand All @@ -33,8 +38,8 @@ describe('Watched Accounts', () => {
// now remove it
settingsPage.accountContainer().within(() => {
settingsPage.accountDeleteButton().click()
settingsPage.accountIcon().should('not.exist')
settingsPage.accountAddressLabel().should('not.exist')
accountDisplay.identicon().should('not.exist')
accountDisplay.addressLabel().should('not.exist')
})
settingsPage.accountContainer().should('have.length', 0)
})
Expand All @@ -58,4 +63,127 @@ describe('Watched Accounts', () => {
settingsPage.accountContainer().should('have.length', 0)
settingsPage.addButton().should('be.disabled')
})

it('can see the expected account details displayed for a watched multisig', () => {
cy.visit(settingsPageWatchAccountUrl)
addWatchAccount(
watchMultisigs['multisig-without-pure'].address,
watchMultisigs['multisig-without-pure'].name
)
// ensure the multisig name is displayed in the settings account container
settingsPage.accountContainer().within(() => {
accountDisplay.identicon().should('be.visible')
accountDisplay
.nameLabel()
.should('be.visible')
.should('have.text', watchMultisigs['multisig-without-pure'].name)
})
// ensure the name is included in the selectable drop-down option
topMenuItems.multiproxySelector().should('be.visible').first().click()
topMenuItems.multiproxySelectorOption().within(() => {
accountDisplay.identicon().should('be.visible')
accountDisplay.multisigBadge().should('be.visible')
accountDisplay.pureBadge().should('not.exist')
accountDisplay.nameLabel().should('have.text', watchMultisigs['multisig-without-pure'].name)
})
// ensure the name is displayed in the home page header
topMenuItems.homeButton().click()
multisigPage.accountHeader().within(() => {
accountDisplay.identicon().should('be.visible')
accountDisplay.multisigBadge().should('be.visible')
accountDisplay.pureBadge().should('not.exist')
accountDisplay.nameLabel().should('have.text', watchMultisigs['multisig-without-pure'].name)
})
})

it('can see the expected account details displayed for a watched pure', () => {
cy.visit(settingsPageWatchAccountUrl)
addWatchAccount(
watchMultisigs['multisig-with-pure'].pureAddress,
watchMultisigs['multisig-with-pure'].name
)
// ensure the multisig name is displayed in the settings account container
settingsPage.accountContainer().within(() => {
accountDisplay.identicon().should('be.visible')
accountDisplay
.nameLabel()
.should('be.visible')
.should('have.text', watchMultisigs['multisig-with-pure'].name)
})
// ensure the name is included in the selectable drop-down option
topMenuItems.multiproxySelector().should('be.visible').first().click()
topMenuItems.multiproxySelectorOption().within(() => {
accountDisplay.identicon().should('be.visible')
accountDisplay.pureBadge().should('be.visible')
accountDisplay.multisigBadge().should('not.exist')
accountDisplay.nameLabel().should('have.text', watchMultisigs['multisig-with-pure'].name)
})
// navigate to the multisig page and ensure the name is included in the home page header
topMenuItems.homeButton().click()
multisigPage.accountHeader().within(() => {
accountDisplay.identicon().should('be.visible')
accountDisplay.pureBadge().should('be.visible')
accountDisplay.multisigBadge().should('not.exist')
accountDisplay.nameLabel().should('have.text', watchMultisigs['multisig-with-pure'].name)
})
})

it('can edit the name of a watched pure', () => {
cy.visit(settingsPageWatchAccountUrl)
addWatchAccount(
watchMultisigs['multisig-with-pure'].pureAddress,
watchMultisigs['multisig-with-pure'].name
)
// navigate to the home page and edit the name
topMenuItems.homeButton().click()
multisigPage.optionsMenuButton().click()
multisigPage.editNamesMenuOption().click()
editNamesModal.body().should('be.visible')
cy.clock()
editNamesModal.inputEditPureName().type(`{selectall}{del}${`Edited Name Test`}`)
// name edition is debounced by 300ms
cy.tick(300)
editNamesModal.saveButton().should('be.enabled').click()
// ensure the edited name is now displayed in the home page header
multisigPage.accountHeader().within(() => {
accountDisplay.nameLabel().should('have.text', 'Edited Name Test')
})
// navigate to settings and ensure the edited name is displayed
cy.visit(settingsPageWatchAccountUrl)
settingsPage.accountContainer().within(() => {
accountDisplay.nameLabel().should('have.text', 'Edited Name Test')
})
})

it('can open the correct subscan link for a watched pure', () => {
cy.visit(settingsPageWatchAccountUrl)
addWatchAccount(
watchMultisigs['multisig-with-pure'].pureAddress,
watchMultisigs['multisig-with-pure'].name
)
topMenuItems.homeButton().click()
multisigPage.optionsMenuButton().click()
multisigPage.subscanMenuOption().should('be.visible')
// stub window.open to prevent opening a new tab
cy.window().then((win) => {
cy.stub(win, 'open').as('open')
})
multisigPage.subscanMenuOption().click()
// ensure the correct subscan url is opened
cy.get('@open').should(
'have.been.calledOnceWith',
`https://rococo.subscan.io/account/${watchMultisigs['multisig-with-pure'].pureAddress}`
)
})

it('can not see the "New Transaction" button when only a watched account', () => {
cy.visit(settingsPageWatchAccountUrl)
addWatchAccount(
watchMultisigs['multisig-with-pure'].pureAddress,
watchMultisigs['multisig-with-pure'].name
)
topMenuItems.homeButton().click()
multisigPage.accountHeader().should('be.visible')
multisigPage.newTransactionButton().should('not.exist')
})
})
4 changes: 3 additions & 1 deletion packages/ui/src/components/AccountEditName.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,10 @@ interface Props {
className?: string
address: string
onNameChange: (args: OnChangeArgs) => void
testId?: string
}

const AccountEditName = ({ address, onNameChange, className }: Props) => {
const AccountEditName = ({ address, onNameChange, className, testId }: Props) => {
const { getNamesWithExtension } = useAccountNames()
const { ownAddressList } = useAccounts()
const [name, setName] = useState(getNamesWithExtension(address) || '')
Expand Down Expand Up @@ -66,6 +67,7 @@ const AccountEditName = ({ address, onNameChange, className }: Props) => {
onChange={onChange}
disabled={isExtensionAccount}
value={name}
data-cy={`input-edit-${testId}-name`}
// onKeyDown={handleSpecialKeys}
/>
</Grid>
Expand Down
4 changes: 2 additions & 2 deletions packages/ui/src/components/CallInfo.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -88,8 +88,8 @@ const handleBalanceDisplay = ({

const getTypeName = (index: number, name: string, value: any, api: ApiPromise) => {
const [palletFromName, methodFromName] = name.split('.')
const pallet = value.section || palletFromName
const method = value.method || methodFromName
const pallet = value?.section || palletFromName
const method = value?.method || methodFromName
const metaArgs = !!pallet && !!method && api.tx[pallet][method].meta.args

return (
Expand Down
12 changes: 5 additions & 7 deletions packages/ui/src/components/EasySetup/FromCallData.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -30,8 +30,6 @@ const FromCallData = ({ className, onSetExtrinsic, isProxySelected, onSetErrorMe
setIsProxyProxyRemoved(false)
if (!api) return call

if (!isProxySelected) return call

const proxyProxyString = u8aToHex(api?.tx.proxy?.proxy.callIndex).toString()

// check if this call is a proxy.proxy
Expand All @@ -46,7 +44,7 @@ const FromCallData = ({ className, onSetExtrinsic, isProxySelected, onSetErrorMe
setIsProxyProxyRemoved(true)
return `0x${call.substring(74)}` as HexString
},
[api, isProxySelected]
[api]
)

// users may erroneously paste callData from the multisig calldata
Expand Down Expand Up @@ -106,12 +104,12 @@ const FromCallData = ({ className, onSetExtrinsic, isProxySelected, onSetErrorMe
error={!!callDataError}
fullWidth
/>
{!!pastedCallData && !!pastedCallInfo && !callDataError && (
{!!callInfo && !!pastedCallInfo && !callDataError && (
<CallInfo
aggregatedData={{
args: getDisplayArgs(pastedCallInfo.call),
callData: pastedCallData,
name: getExtrinsicName(pastedCallInfo.section, pastedCallInfo.method)
args: getDisplayArgs(callInfo.call),
callData: callDataToUse,
name: getExtrinsicName(callInfo.section, callInfo.method)
}}
expanded
withProxyFiltered={false}
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/components/Header/Header.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,6 +42,7 @@ const Header = ({ handleDrawerOpen }: Props) => {
<NavLink
key={name}
to={path}
data-cy={`button-navigate-${name.toLowerCase().replace(/ /g, '-')}`}
>
{name}
</NavLink>
Expand Down
1 change: 1 addition & 0 deletions packages/ui/src/components/IdenticonBadge.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ export const IdenticonBadge = ({
color="primary"
badgeContent={badge}
anchorOrigin={{ horizontal: 'left', vertical: 'top' }}
data-cy={`badge-${badge}`}
>
<AccountIcon />
</BadgeStyled>
Expand Down
2 changes: 2 additions & 0 deletions packages/ui/src/components/OptionsMenu.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,7 @@ const OptionsMenu = ({ className, options, menuButtonBorder }: Props) => {
aria-expanded={open ? 'true' : undefined}
aria-haspopup="true"
onClick={handleMenuClick}
data-cy="button-options-menu"
>
<MoreVertIcon />
</ButtonWithIconStyled>
Expand All @@ -74,6 +75,7 @@ const OptionsMenu = ({ className, options, menuButtonBorder }: Props) => {
className="menuEntry"
key={option.text}
onClick={() => handleClick(option.onClick)}
data-cy={`menu-option-${option.text.toLowerCase().replace(/ /g, '-')}`}
>
<ListItemIcon>{option.icon}</ListItemIcon>
<ListItemText>{option.text}</ListItemText>
Expand Down
Loading

0 comments on commit 1f4fa56

Please sign in to comment.