Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OCT-2229: Patron mode E2E & OCT-2229: Project admin mode E2E #605

Open
wants to merge 12 commits into
base: master
Choose a base branch
from
19 changes: 19 additions & 0 deletions client/cypress/e2e/_11settings.cy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@ Object.values(viewports).forEach(
});

beforeEach(() => {
cy.disconnectMetamaskWalletFromAllDapps();
mockCoinPricesServer();
localStorage.setItem(IS_ONBOARDING_ALWAYS_VISIBLE, 'false');
localStorage.setItem(IS_ONBOARDING_DONE, 'true');
Expand Down Expand Up @@ -298,6 +299,24 @@ Object.values(viewports).forEach(

cy.disconnectMetamaskWalletFromAllDapps();
});

it('"Enable patron mode" option is visible only when wallet is connected', () => {
cy.wait(500);
cy.get('[data-test=SettingsPatronModeBox]').should('not.exist');

if (isLargeDesktop || isDesktop) {
cy.get('[data-test=SettingsDrawer__closeButton]').click();
cy.wait(500);
}

connectWallet({ isPatronModeEnabled: false });
cy.wait(2000);

if (isLargeDesktop || isDesktop) {
cy.get('[data-test=LayoutTopBar__settingsButton]').click();
}
cy.get('[data-test=SettingsPatronModeBox]').should('be.visible');
});
});
},
);
884 changes: 884 additions & 0 deletions client/cypress/e2e/_23patronMode.cy.ts

Large diffs are not rendered by default.

107 changes: 107 additions & 0 deletions client/cypress/e2e/_24projectAdmin.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,107 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import chaiColors from 'chai-colors';

import { connectWallet, visitWithLoader } from 'cypress/utils/e2e';
import viewports from 'cypress/utils/viewports';
import {
HAS_ONBOARDING_BEEN_CLOSED,
IS_ONBOARDING_ALWAYS_VISIBLE,
IS_ONBOARDING_DONE,
} from 'src/constants/localStorageKeys';
import { CYPRESS_IS_PROJECT_ADMIN } from 'src/constants/window';
import { ROOT_ROUTES } from 'src/routes/RootRoutes/routes';

chai.use(chaiColors);

Object.values(viewports).forEach(
({ device, viewportWidth, viewportHeight, isLargeDesktop, isDesktop }) => {
describe(`[AW IS OPEN] project admin: ${device}`, { viewportHeight, viewportWidth }, () => {
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(() => {
cy.disconnectMetamaskWalletFromAllDapps();
localStorage.setItem(IS_ONBOARDING_ALWAYS_VISIBLE, 'false');
localStorage.setItem(IS_ONBOARDING_DONE, 'true');
localStorage.setItem(HAS_ONBOARDING_BEEN_CLOSED, 'true');
visitWithLoader(ROOT_ROUTES.home.absolute);
connectWallet({ isPatronModeEnabled: false }).then(() => {
cy.window().then(win => {
// eslint-disable-next-line no-param-reassign
win[CYPRESS_IS_PROJECT_ADMIN] = true;
});
});
});

after(() => {
cy.disconnectMetamaskWalletFromAllDapps();
});

it('Top bar has project admin mode style', () => {
cy.get('[data-test=Layout__topBarWrapper]')
.invoke('css', 'backgroundColor')
.should('eq', 'rgba(241, 250, 248, 0.6)');
cy.get('[data-test=LayoutTopBar__Button]')
.then($topBar => $topBar.css('backgroundColor'))
.should('be.colored', '#2d9b87');
cy.get('[data-test=LayoutTopBar__Button]').should('contain.text', 'Admin');
});

it('User can go only to project admin mode enabled routes', () => {
if (isLargeDesktop || isDesktop) {
cy.get('[data-test=LayoutTopBar__link--home]').should('be.visible');
cy.get('[data-test=LayoutTopBar__link--projects]').should('be.visible');
cy.get('[data-test=LayoutTopBar__link--metrics]').should('be.visible');
cy.get('[data-test=LayoutTopBar__settingsButton]').should('be.visible');
cy.get('[data-test=LayoutTopBar__allocationButton]').should('not.exist');
} else {
cy.get('[data-test=LayoutNavbar__Button--home]').should('be.visible');
cy.get('[data-test=LayoutNavbar__Button--projects]').should('be.visible');
cy.get('[data-test=LayoutNavbar__Button--allocate]').should('not.exist');
cy.get('[data-test=LayoutNavbar__Button--metrics]').should('be.visible');
cy.get('[data-test=LayoutNavbar__Button--settings]').should('be.visible');
}
});

it('User sees the right tiles in HomeView', () => {
cy.get('[data-test=HomeRewards]').should('be.visible');
cy.get('[data-test=HomeGridCurrentGlmLock]').should('not.exist');
cy.get('[data-test=HomeGridPersonalAllocation]').should('be.visible');
cy.get('[data-test=HomeGridDonations]').should('not.exist');
cy.get('[data-test=HomeGridUQScore]').should('not.exist');
cy.get('[data-test=HomeGridVideoBar]').should('be.visible');
cy.get('[data-test=HomeGridTransactions]').should('be.visible');
cy.get('[data-test=HomeGridRewardsEstimator]').should('be.visible');
cy.get('[data-test=HomeGridEpochResults]').should('be.visible');
});

it('route /allocate redirects to /home and not open allocation drawer', () => {
visitWithLoader(ROOT_ROUTES.allocation.absolute, ROOT_ROUTES.home.absolute);
cy.get('[data-test=HomeView]').should('be.visible');
cy.get('[data-test=AllocationDrawer]').should('not.exist');
});

it('Settings view shows only project admin mode options', () => {
if (isLargeDesktop || isDesktop) {
cy.get('[data-test=LayoutTopBar__settingsButton]').click();
} else {
cy.get('[data-test=LayoutNavbar__Button--settings]').click();
}

cy.wait(500);
cy.get('[data-test=SettingsMainInfoBox]').should('not.exist');
cy.get('[data-test=SettingsCryptoMainValueBox]').should('be.visible');
cy.get('[data-test=SettingsCurrencyBox]').should('be.visible');
cy.get('[data-test=SettingsShowHelpVideosBox]').should('be.visible');
cy.get('[data-test=SettingsPatronModeBox]').should('not.exist');
cy.get('[data-test=SettingsShowOnboardingBox]').should('not.exist');
});
});
},
);
2 changes: 2 additions & 0 deletions client/global.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,12 @@ import { QueryClient, UseMutateAsyncFunction } from '@tanstack/react-query';
import {
WINDOW_PROJECTS_LOADED_ARCHIVED_EPOCHS_NUMBER,
WINDOW_PROJECTS_SCROLL_Y,
CYPRESS_IS_PROJECT_ADMIN,
} from 'constants/window';

export declare global {
interface Window {
[CYPRESS_IS_PROJECT_ADMIN]?: boolean;
Cypress?: Cypress.Cypress;
[WINDOW_PROJECTS_LOADED_ARCHIVED_EPOCHS_NUMBER]?: number;
[WINDOW_PROJECTS_SCROLL_Y]?: number;
Expand Down
81 changes: 44 additions & 37 deletions client/src/components/shared/Layout/LayoutTopBar/LayoutTopBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -111,13 +111,18 @@ const LayoutTopBar: FC<LayoutTopBarProps> = ({ className }) => {
}, [isDesktop, pathname, isSettingsDrawerOpen]);

useEffect(() => {
if (pathname !== ROOT_ROUTES.allocation.absolute || !isDesktop) {
if (
pathname !== ROOT_ROUTES.allocation.absolute ||
!isDesktop ||
isPatronMode ||
isProjectAdminMode
) {
return;
}

setIsAllocationDrawerOpen(true);
// eslint-disable-next-line react-hooks/exhaustive-deps
}, [isDesktop, pathname]);
}, [isDesktop, pathname, isPatronMode, isProjectAdminMode]);

useEffect(() => {
if (isAllocationDrawerOpen && pathname !== ROOT_ROUTES.allocation.absolute && !isDesktop) {
Expand Down Expand Up @@ -238,7 +243,7 @@ const LayoutTopBar: FC<LayoutTopBarProps> = ({ className }) => {
>
<Svg classNameSvg={styles.settingsButtonIcon} img={settings} size={2} />
</div>
{!isProjectAdminMode && !isPatronMode && (
{!(isProjectAdminMode || isPatronMode) && (
<div
className={cx(styles.allocateButton, isTestnet && styles.isTestnet)}
data-test={`${dataTestRoot}__allocationButton`}
Expand Down Expand Up @@ -267,41 +272,43 @@ const LayoutTopBar: FC<LayoutTopBarProps> = ({ className }) => {
>
<Settings />
</Drawer>
<Drawer
CustomCloseButton={
<div
ref={closeButtonRef}
className={cx(
styles.customCloseButton,
isCloseButtonExpanded && styles.isCloseButtonExpanded,
)}
data-test="AllocationDrawer__closeButton"
onClick={() => setIsAllocationDrawerOpen(false)}
>
<AnimatePresence>
{isCloseButtonExpanded && (
<motion.div
animate={{ opacity: 1 }}
className={styles.customCloseButtonText}
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
transition={{ delay: 0.25 }}
>
{t('closeDrawerWithArrow')}
</motion.div>
{!(isPatronMode || isProjectAdminMode) && (
<Drawer
CustomCloseButton={
<div
ref={closeButtonRef}
className={cx(
styles.customCloseButton,
isCloseButtonExpanded && styles.isCloseButtonExpanded,
)}
</AnimatePresence>
<Svg classNameSvg={styles.customCloseButtonSvg} img={cross} size={1} />
</div>
}
dataTest="AllocationDrawer"
isOpen={isAllocationDrawerOpen && !isTimeoutListPresenceModalOpen?.value}
onClose={() => setIsAllocationDrawerOpen(false)}
onMouseLeave={() => setIsCloseButtonExpanded(false)}
onMouseOver={() => setIsCloseButtonExpanded(true)}
>
<Allocation />
</Drawer>
data-test="AllocationDrawer__closeButton"
onClick={() => setIsAllocationDrawerOpen(false)}
>
<AnimatePresence>
{isCloseButtonExpanded && (
<motion.div
animate={{ opacity: 1 }}
className={styles.customCloseButtonText}
exit={{ opacity: 0 }}
initial={{ opacity: 0 }}
transition={{ delay: 0.25 }}
>
{t('closeDrawerWithArrow')}
</motion.div>
)}
</AnimatePresence>
<Svg classNameSvg={styles.customCloseButtonSvg} img={cross} size={1} />
</div>
}
dataTest="AllocationDrawer"
isOpen={isAllocationDrawerOpen && !isTimeoutListPresenceModalOpen?.value}
onClose={() => setIsAllocationDrawerOpen(false)}
onMouseLeave={() => setIsCloseButtonExpanded(false)}
onMouseOver={() => setIsCloseButtonExpanded(true)}
>
<Allocation />
</Drawer>
)}
</>
)}
</div>
Expand Down
1 change: 1 addition & 0 deletions client/src/constants/window.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
export const WINDOW_PROJECTS_LOADED_ARCHIVED_EPOCHS_NUMBER =
'WINDOW_PROJECTS_LOADED_ARCHIVED_EPOCHS_NUMBER';
export const WINDOW_PROJECTS_SCROLL_Y = 'WINDOW_PROJECTS_SCROLL_Y';
export const CYPRESS_IS_PROJECT_ADMIN = 'CYPRESS_IS_PROJECT_ADMIN';
5 changes: 5 additions & 0 deletions client/src/hooks/helpers/useIsProjectAdminMode.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,16 @@
import { useAccount } from 'wagmi';

import { CYPRESS_IS_PROJECT_ADMIN } from 'constants/window';
import useAllProjects from 'hooks/subgraph/useAllProjects';

const useIsProjectAdminMode = (): boolean => {
const { isConnected, address } = useAccount();
const { data: allProjects } = useAllProjects();

if (window.Cypress && CYPRESS_IS_PROJECT_ADMIN) {
return isConnected;
}

return (
isConnected && !!address && !!allProjects?.includes(address.toLowerCase() as `0x${string}`)
);
Expand Down
2 changes: 1 addition & 1 deletion client/src/routes/RootRoutes/RootRoutes.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,7 @@ const RootRoutes = (): ReactElement => {
{!isPreLaunch && (
<>
<>
{(!isPatronMode || !isProjectAdminMode) && (
{!(isPatronMode || isProjectAdminMode) && (
<Route
element={isDesktop ? <Navigate to={lastSeenPathRef.current} /> : <AllocationView />}
path={`${ROOT_ROUTES.allocation.relative}/*`}
Expand Down
Loading