diff --git a/client/cypress/e2e/patronMode.cy.ts b/client/cypress/e2e/patronMode.cy.ts index 0a1dac2b7a..8dd53630e3 100644 --- a/client/cypress/e2e/patronMode.cy.ts +++ b/client/cypress/e2e/patronMode.cy.ts @@ -1,21 +1,8 @@ -import { mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; +import { connectWallet, mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; import viewports from 'cypress/utils/viewports'; import { IS_ONBOARDING_ALWAYS_VISIBLE, IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; import { ROOT_ROUTES } from 'src/routes/RootRoutes/routes'; -import Chainable = Cypress.Chainable; - -const connectWallet = (isTOSAccepted: boolean, isPatronModeEnabled: boolean): Chainable => { - cy.intercept('GET', '/user/*/tos', { body: { accepted: isTOSAccepted } }); - cy.intercept('GET', '/user/*/patron-mode', { body: { status: isPatronModeEnabled } }); - cy.intercept('PATCH', '/user/*/patron-mode', { body: { status: !isPatronModeEnabled } }); - cy.disconnectMetamaskWalletFromAllDapps(); - cy.get('[data-test=MainLayout__Button--connect]').click(); - cy.get('[data-test=ConnectWallet__BoxRounded--browserWallet]').click(); - cy.switchToMetamaskNotification(); - return cy.acceptMetamaskAccess(); -}; - Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight, isDesktop }) => { describe(`patron mode (disabled): ${device}`, { viewportHeight, viewportWidth }, () => { before(() => { diff --git a/client/cypress/e2e/proposal.cy.ts b/client/cypress/e2e/proposal.cy.ts index e53c50aca1..147d277975 100644 --- a/client/cypress/e2e/proposal.cy.ts +++ b/client/cypress/e2e/proposal.cy.ts @@ -1,4 +1,4 @@ -import { mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; +import { connectWallet, mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; import { getNamesOfProposals } from 'cypress/utils/proposals'; import viewports from 'cypress/utils/viewports'; import { IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; @@ -122,4 +122,41 @@ Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight }) => } }); }); + + describe(`proposal (patron mode): ${device}`, { viewportHeight, viewportWidth }, () => { + let proposalNames: string[] = []; + + before(() => { + /** + * Global Metamask setup done by Synpress is not always done. + * Since Synpress needs to have valid provider to fetch the data from contracts, + * setupMetamask is required in each test suite. + */ + cy.setupMetamask(); + }); + + beforeEach(() => { + mockCoinPricesServer(); + localStorage.setItem(IS_ONBOARDING_DONE, 'true'); + visitWithLoader(ROOT_ROUTES.proposals.absolute); + connectWallet(true, true); + cy.get('[data-test^=ProposalItemSkeleton').should('not.exist'); + + /** + * This could be done in before hook, but CY wipes the state after each test + * (could be disabled, but creates other problems) + */ + if (proposalNames.length === 0) { + proposalNames = getNamesOfProposals(); + } + }); + + it('button "add to allocate" is disabled', () => { + for (let i = 0; i < proposalNames.length; i++) { + cy.get('[data-test^=ProposalsView__ProposalsListItem]').eq(i).click(); + getButtonAddToAllocate().should('be.visible').should('be.disabled'); + cy.go('back'); + } + }); + }); }); diff --git a/client/cypress/e2e/proposals.cy.ts b/client/cypress/e2e/proposals.cy.ts index 73ed788814..ed46af2ab2 100644 --- a/client/cypress/e2e/proposals.cy.ts +++ b/client/cypress/e2e/proposals.cy.ts @@ -1,7 +1,7 @@ // eslint-disable-next-line import/no-extraneous-dependencies import chaiColors from 'chai-colors'; -import { mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; +import { connectWallet, mockCoinPricesServer, visitWithLoader } from 'cypress/utils/e2e'; import { getNamesOfProposals } from 'cypress/utils/proposals'; import viewports from 'cypress/utils/viewports'; import { IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; @@ -11,7 +11,7 @@ import Chainable = Cypress.Chainable; chai.use(chaiColors); -function checkProposalItemElements(index, name): Chainable { +function checkProposalItemElements(index, name, isPatronMode = false): Chainable { cy.get('[data-test^=ProposalsView__ProposalsListItem') .eq(index) .find('[data-test=ProposalsListItem__imageProfile]') @@ -31,6 +31,13 @@ function checkProposalItemElements(index, name): Chainable { .find('[data-test=ProposalsListItem__ButtonAddToAllocate]') .should('be.visible'); + if (isPatronMode) { + cy.get('[data-test^=ProposalsView__ProposalsListItem') + .eq(index) + .find('[data-test=ProposalsListItem__ButtonAddToAllocate]') + .should('be.disabled'); + } + return cy .get('[data-test^=ProposalsView__ProposalsListItem') .eq(index) @@ -133,4 +140,39 @@ Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight }) => removeProposalFromAllocate(proposalNames.length, 1, proposalNames.length - 1); }); }); + + describe(`proposals (patron mode): ${device}`, { viewportHeight, viewportWidth }, () => { + let proposalNames: string[] = []; + + before(() => { + /** + * Global Metamask setup done by Synpress is not always done. + * Since Synpress needs to have valid provider to fetch the data from contracts, + * setupMetamask is required in each test suite. + */ + cy.setupMetamask(); + }); + + beforeEach(() => { + mockCoinPricesServer(); + localStorage.setItem(IS_ONBOARDING_DONE, 'true'); + visitWithLoader(ROOT_ROUTES.proposals.absolute); + connectWallet(true, true); + cy.get('[data-test^=ProposalItemSkeleton').should('not.exist'); + /** + * This could be done in before hook, but CY wipes the state after each test + * (could be disabled, but creates other problems) + */ + if (proposalNames.length === 0) { + proposalNames = getNamesOfProposals(); + } + }); + + it('button "add to allocate" is disabled', () => { + for (let i = 0; i < proposalNames.length; i++) { + cy.get('[data-test^=ProposalsView__ProposalsListItem]').eq(i).scrollIntoView(); + checkProposalItemElements(i, proposalNames[i], true); + } + }); + }); }); diff --git a/client/cypress/utils/e2e.ts b/client/cypress/utils/e2e.ts index 2b0e5efc63..c7cd606fd4 100644 --- a/client/cypress/utils/e2e.ts +++ b/client/cypress/utils/e2e.ts @@ -98,3 +98,17 @@ export const moveToNextEpoch = () => // isEpochChanged resolve(Number(currentEpoch) + 1 === Number(currentEpochAfter)); }); + +export const connectWallet = ( + isTOSAccepted: boolean, + isPatronModeEnabled: boolean, +): Chainable => { + cy.intercept('GET', '/user/*/tos', { body: { accepted: isTOSAccepted } }); + cy.intercept('GET', '/user/*/patron-mode', { body: { status: isPatronModeEnabled } }); + cy.intercept('PATCH', '/user/*/patron-mode', { body: { status: !isPatronModeEnabled } }); + cy.disconnectMetamaskWalletFromAllDapps(); + cy.get('[data-test=MainLayout__Button--connect]').click(); + cy.get('[data-test=ConnectWallet__BoxRounded--browserWallet]').click(); + cy.switchToMetamaskNotification(); + return cy.acceptMetamaskAccess(); +}; diff --git a/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx b/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx index b9be6e0748..ea1b7632dc 100644 --- a/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx +++ b/client/src/components/shared/ButtonAddToAllocate/ButtonAddToAllocate.tsx @@ -6,6 +6,7 @@ import { useTranslation } from 'react-i18next'; import Button from 'components/ui/Button'; import Svg from 'components/ui/Svg'; import Tooltip from 'components/ui/Tooltip'; +import useIsPatronMode from 'hooks/queries/useIsPatronMode'; import { checkMark, heart } from 'svg/misc'; import styles from './ButtonAddToAllocate.module.scss'; @@ -23,9 +24,9 @@ const ButtonAddToAllocate: FC = ({ keyPrefix: 'components.dedicated.buttonAddToAllocate', }); const [scope, animate] = useAnimate(); + const { data: isPatronMode } = useIsPatronMode(); const [isTooltipClicked, setIsTooltipClicked] = useState(false); const [isTooltipVisible, setIsTooltipVisible] = useState(false); - const tooltipText = useMemo(() => { if (isAddedToAllocate && isTooltipClicked) { return t('saved'); @@ -60,7 +61,7 @@ const ButtonAddToAllocate: FC = ({ Icon={ { if (isTooltipVisible) { setIsTooltipClicked(true); @@ -78,7 +79,7 @@ const ButtonAddToAllocate: FC = ({ } - isDisabled={isArchivedProposal} + isDisabled={isArchivedProposal || isPatronMode} onClick={onClick} variant="iconOnly" />