mirror of
https://github.com/luxfi/safe-wallet.git
synced 2026-10-30 15:19:21 +00:00
* feat: unify buttons styles for Spaces pages (#7790) * feat: unify buttons styles for Spaces pages * fix: make Actions Tray and Onboarding items responsive on mobile * fix: prevent safe-bar flicker and wrong-safe push by reading URL safeAddress and ignoring base-ui Select auto-resets (#7791) * fix(web): hide global search button on welcome list pages (#7796) * fix(web): hide global search if user is in the welcome page * tests: cover search button visibility on welcome routes in Topbar --------- * fix: add missing data-testId for multichain tests; fix hydration error on 1st load (#7800) * fix(web): show all deployed chains for current safe in selector dropdown (#7798) * fix(web): show all deployed chains for current safe in selector dropdown * fix(web): hide safe bar for setting page when no safe address * tests(web): cover sidebar tx badge for masked queue sizes (#7799) * fix(web): do not parse masked numbers on the sidebar badge * tests(web): cover sidebar tx badge for masked queue sizes Add unit tests for the masked queue size on the Safe sidebar badge (numeric, "20+" string, empty), drop the unused isNumber import, and fix a JSX gotcha in NavItem where badge=0/"" leaked into the DOM because `value && <X/>` returns the falsy value verbatim. --------- * fix: tooltips for the entire NavItem content for every Sidebar item; tests (#7801) * Fix(web): safe selector on tx flow (#7802) * fix(web): disable dropdown selector when the user is at the tx modal flow * fix: add tests * fix: disable nested safe for transaction --------- Co-authored-by: Tong Yao <[email protected]> * hotfix(web/Spaces): frozen scroll after chain selection; styles for sidebar items (#7803) * fix: frozen scroll after chain selection; styles for sidebar items * docs: add an explanation comment about `modal=false` prop in the chain dropdpown * hotfix(web): no Safe Selector on static pages; UI markdown fixes for static pages (#7804) * feat: hide Safe Selector and Topbar on static pages; add a new SafeLogo component * fix: statis pages markdown styling * fix(web): show Safe logo in Topbar on settings without a safe; tighten layout gap (#7806) When opening /settings/* with no ?safe= in the URL, the SpaceSafeBar already hides itself and the header was left empty on the left. Render the SafeLogo in that slot so users can navigate back to /welcome/accounts. Two follow-up adjustments to keep the page balanced in this state: - Vertically center the header so the small logo aligns with the taller right-side button group (only when the logo is shown). - Reduce .mainSpace padding-top from --topbar-height (100px, sized for the full topbar+SafeBar combo) to header-height + space-3 (~80px) so the page content doesn't sit awkwardly far below the single-row topbar. * chore(web): rename sidebar "Add Safe to workspace" trigger to "Add Safe to space" (#7808) Updates visible label and aria-label on the SafeSidebarWorkspaceHeader and SpaceSelectorDropdown (addToWorkspace variant) and the matching unit tests. Internal identifiers (CSS classes, data-testid, triggerVariant) are unchanged. * fix(test): e2e test flows for Spaces (#7822) * fix: Multichain Setup e2e flow * fix: ensure that N spaceds < max before running basic e2e workflow * fix(web): guard against expired session at boot and on a timer (#7821) * fix(web): guard against expired session at boot and on a timer When the JWT session cookie expires, the browser stops sending it but Redux's sessionExpiresAt still says the user is signed in. Components keep firing credentialed requests against the gateway and every one returns 403. Add useSessionExpiryGuard, registered once in InitApp. After store hydration, when the persisted state says the user is signed in: - If sessionExpiresAt has already passed, clear auth + toast immediately (no /v1/auth/me round-trip). - Otherwise fire one /v1/auth/me probe; on 403 clear auth + toast, on 200 keep state. - Schedule a timer to clear auth + toast at sessionExpiresAt so a session that expires mid-tab is cleared without any further request. - On transient /me failures (5xx, network), don't log out — but still schedule the local-expiry timer, otherwise sessionExpiresAt could pass with no cleanup. Skips while useLogoutCallback / useOidcLoginCallback are processing — those hooks already own /me for their flows. Unlike the reverted #7807, this never inspects 403s on component routes (e.g. permission denials on space deletion), so it can't false-positive on legitimate authorization failures. * fix: toast disappears after successful relogin; feat: toast has a link to sign in page --------- Co-authored-by: vmosharova <[email protected]> * chore: update schema hash --------- Co-authored-by: Clóvis Neto <[email protected]> Co-authored-by: Tong Yao <[email protected]> Co-authored-by: Tong Yao <[email protected]> Co-authored-by: katspaugh <[email protected]> Co-authored-by: Hanzo Dev <[email protected]>
71 lines
2.3 KiB
JavaScript
71 lines
2.3 KiB
JavaScript
// ChainSelectorBlock / Add Network
|
|
const addNetworkBtn = '[data-testid="add-network-btn"]'
|
|
const deployedChainBtn = '[data-testid="deployed-chain-btn"]'
|
|
const addChainDialog = '[data-testid="add-chain-dialog"]'
|
|
const addedNetwork = '[data-testid="added-network"]'
|
|
const modalAddNetworkBtn = '[data-testid="modal-add-network-btn"]'
|
|
const allNetworksAccordion = '[data-testid="all-networks-accordion"]'
|
|
const chainNavigationButton = '[data-testid="space-chain-navigation-button"]'
|
|
|
|
export const createSafeMsg = (network) => `Successfully added your account on ${network}`
|
|
|
|
export function clickChainNavigationButton() {
|
|
cy.wait(1000)
|
|
cy.get(chainNavigationButton).should('be.visible').click()
|
|
cy.get(allNetworksAccordion).should('be.visible')
|
|
}
|
|
|
|
export function clickAllNetworksAccordion() {
|
|
cy.get(allNetworksAccordion).should('be.visible').click()
|
|
cy.get(addNetworkBtn).should('be.visible')
|
|
}
|
|
|
|
export function clickAddNetworkBtn(chainName) {
|
|
cy.get(addNetworkBtn).filter(`[aria-label="Add ${chainName}"]`).click()
|
|
cy.get(addChainDialog).should('be.visible')
|
|
}
|
|
|
|
export function clickModalAddNetworkBtn() {
|
|
cy.get(modalAddNetworkBtn).should('be.visible').and('not.be.disabled').click()
|
|
}
|
|
|
|
export function verifyModalAddNetworkBtnDisabled() {
|
|
cy.get(modalAddNetworkBtn).should('be.disabled')
|
|
}
|
|
|
|
export function verifyNetworkNotInAddList(networkName) {
|
|
cy.get(addNetworkBtn).each(($btn) => {
|
|
cy.wrap($btn).should('not.have.attr', 'aria-label', `Add ${networkName}`)
|
|
})
|
|
}
|
|
|
|
export function verifyDeployedChainsInDropdown(chainNames) {
|
|
chainNames.forEach((name) => {
|
|
cy.get(deployedChainBtn).filter(`[aria-label="${name}"]`).should('exist')
|
|
})
|
|
}
|
|
|
|
export function verifyAddedNetworkInDialog(chainName) {
|
|
cy.get(addedNetwork).should('be.visible').and('contain.text', chainName)
|
|
}
|
|
|
|
export function verifyNetworkInputAbsentInDialog() {
|
|
cy.get(addChainDialog).find('[id="network-input"]').should('not.exist')
|
|
}
|
|
|
|
export function verifyAddNetworkBtnListNotEmpty() {
|
|
cy.get(addNetworkBtn).should('have.length.gte', 1)
|
|
}
|
|
|
|
export function verifyAddNetworkBtnExists(chainName) {
|
|
cy.get(addNetworkBtn).filter(`[aria-label="Add ${chainName}"]`).should('exist')
|
|
}
|
|
|
|
export function addNetwork(chainName) {
|
|
clickChainNavigationButton()
|
|
clickAllNetworksAccordion()
|
|
clickAddNetworkBtn(chainName)
|
|
clickModalAddNetworkBtn()
|
|
cy.get(addChainDialog).should('not.exist')
|
|
}
|