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-2141: Onboarding TOS not accepted E2E & OCT-2142: Onboarding TOS accepted E2E #556

Merged
merged 12 commits into from
Nov 21, 2024
Merged
103 changes: 103 additions & 0 deletions client/cypress/e2e/_6onboardingTOSNotAccepted.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,103 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import chaiColors from 'chai-colors';

import {
beforeSetup,
checkChangeStepsByClickingEdgeOfTheScreenMoreThan25px,
checkChangeStepsByClickingEdgeOfTheScreenUpTo25px,
checkChangeStepsBySwipingOnScreenDifferenceLessThanl5px,
checkChangeStepsBySwipingOnScreenDifferenceMoreThanOrEqual5px,
checkChangeStepsWithArrowKeys,
checkCurrentElement,
checkProgressStepperSlimIsCurrentAndClickNext,
connectWalletOnboarding,
} from 'cypress/utils/onboarding';
import viewports from 'cypress/utils/viewports';
import { QUERY_KEYS } from 'src/api/queryKeys';
import {
getStepsDecisionWindowClosed,
getStepsDecisionWindowOpen,
} from 'src/hooks/helpers/useOnboardingSteps/steps';

chai.use(chaiColors);

Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight }, index, arr) => {
describe(`Onboarding (TOS not accepted): ${device}`, { viewportHeight, viewportWidth }, () => {
before(() => {
beforeSetup();
});

beforeEach(() => {
connectWalletOnboarding();
});

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

it('onboarding TOS step should be first and active', () => {
checkCurrentElement(0, true);
cy.get('[data-test=ModalOnboardingTOS]').should('be.visible');
});

it('user is not able to click through entire onboarding flow', () => {
cy.window().then(win => {
const isDecisionWindowOpen = win.clientReactQuery.getQueryData(
QUERY_KEYS.isDecisionWindowOpen,
);

const onboardingSteps = isDecisionWindowOpen
? getStepsDecisionWindowOpen('2', '16 Jan')
: getStepsDecisionWindowClosed('2', '16 Jan');

for (let i = 1; i < onboardingSteps.length; i++) {
checkProgressStepperSlimIsCurrentAndClickNext(i, i === 1);
}
});
});

it('user is not able to close the modal by clicking button in the top-right', () => {
cy.get('[data-test=ModalOnboarding]').should('be.visible');
cy.get('[data-test=ModalOnboarding__Button]').click({ force: true });
cy.get('[data-test=ModalOnboarding]').should('be.visible');
});

it('renders every time page is refreshed', () => {
cy.get('[data-test=ModalOnboarding]').should('be.visible');
cy.reload();
cy.get('[data-test=ModalOnboarding]').should('be.visible');
});

it('user cannot change steps with arrow keys (left, right)', () => {
checkChangeStepsWithArrowKeys(false);
});

it('user cannot change steps by clicking the edge of the screen (up to 25px from each edge)', () => {
checkChangeStepsByClickingEdgeOfTheScreenUpTo25px(false);
});

it('user cannot change steps by clicking the edge of the screen (more than 25px from each edge)', () => {
checkChangeStepsByClickingEdgeOfTheScreenMoreThan25px(false);
});

it('user cannot change steps by swiping on screen (difference more than or equal 5px)', () => {
checkChangeStepsBySwipingOnScreenDifferenceMoreThanOrEqual5px(false);
});

it('user cannot change steps by swiping on screen (difference less than 5px)', () => {
checkChangeStepsBySwipingOnScreenDifferenceLessThanl5px(false);
});

if (index === arr.length - 1) {
it('TOS acceptance changes onboarding step to next step and allows the user to close the modal by clicking button in the top-right', () => {
checkCurrentElement(0, true);
cy.get('[data-test=TOS_InputCheckbox]').check();
cy.switchToMetamaskNotification();
cy.confirmMetamaskSignatureRequest();
checkCurrentElement(1, true);
cy.get('[data-test=ModalOnboarding__Button]').click();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
});
}
});
});
224 changes: 224 additions & 0 deletions client/cypress/e2e/_7onboardingTOSAccepted.cy.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,224 @@
// eslint-disable-next-line import/no-extraneous-dependencies
import chaiColors from 'chai-colors';

import { moveTime, setupAndMoveToPlayground } from 'cypress/utils/moveTime';
import {
beforeSetup,
checkChangeStepsByClickingEdgeOfTheScreenMoreThan25px,
checkChangeStepsByClickingEdgeOfTheScreenUpTo25px,
checkChangeStepsBySwipingOnScreenDifferenceLessThanl5px,
checkChangeStepsBySwipingOnScreenDifferenceMoreThanOrEqual5px,
checkChangeStepsWithArrowKeys,
checkProgressStepperSlimIsCurrentAndClickNext,
connectWalletOnboarding,
} from 'cypress/utils/onboarding';
import viewports from 'cypress/utils/viewports';
import { QUERY_KEYS } from 'src/api/queryKeys';
import { HAS_ONBOARDING_BEEN_CLOSED, IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys';
import {
getStepsDecisionWindowClosed,
getStepsDecisionWindowOpen,
} from 'src/hooks/helpers/useOnboardingSteps/steps';

chai.use(chaiColors);

describe('move time', () => {
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();
});

it('allocation window is open, when it is not, move time', () => {
setupAndMoveToPlayground();

cy.window().then(async win => {
moveTime(win, 'nextEpochDecisionWindowOpen').then(() => {
const isDecisionWindowOpenAfter = win.clientReactQuery.getQueryData(
QUERY_KEYS.isDecisionWindowOpen,
);
expect(isDecisionWindowOpenAfter).to.be.true;
});
});
});
});

Object.values(viewports).forEach(
({ device, viewportWidth, viewportHeight, isDesktop, isLargeDesktop }) => {
describe(`onboarding (TOS accepted): ${device}`, { viewportHeight, viewportWidth }, () => {
before(() => {
beforeSetup();
});

beforeEach(() => {
cy.clearLocalStorage();
connectWalletOnboarding();
});

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

it('user is able to click through entire onboarding flow', () => {
cy.window().then(win => {
const isDecisionWindowOpen = win.clientReactQuery.getQueryData(
QUERY_KEYS.isDecisionWindowOpen,
);

const onboardingSteps = isDecisionWindowOpen
? getStepsDecisionWindowOpen('2', '16 Jan')
: getStepsDecisionWindowClosed('2', '16 Jan');

for (let i = 1; i < onboardingSteps.length - 1; i++) {
checkProgressStepperSlimIsCurrentAndClickNext(i);
}

cy.get('[data-test=ModalOnboarding__ProgressStepperSlim__element]')
.eq(onboardingSteps.length - 1)
.click();
cy.get('[data-test=ModalOnboarding__Button]').click();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
cy.get('[data-test=HomeView]').should('be.visible');
});
});

it('user is able to close the modal by clicking button in the top-right', () => {
cy.get('[data-test=ModalOnboarding]').should('be.visible');
cy.get('[data-test=ModalOnboarding__Button]').click();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
cy.get('[data-test=HomeView]').should('be.visible');
});

it('renders every time page is refreshed when "Always show Allocate onboarding" option is checked', () => {
cy.get('[data-test=ModalOnboarding__Button]').click();
if (isLargeDesktop || isDesktop) {
cy.get('[data-test=LayoutTopBar__settingsButton]').click();
} else {
cy.get(`[data-test=LayoutNavbar__Button--settings]`).click();
}
cy.get('[data-test=SettingsShowOnboardingBox__InputToggle]').check().should('be.checked');
cy.reload();
// For the unknown reason reloads sometimes cause app to disconnect in E2E env.
cy.disconnectMetamaskWalletFromAllDapps();
connectWalletOnboarding();
cy.get('[data-test=ModalOnboarding]').should('be.visible');
});

it('renders only once when "Always show Allocate onboarding" option is not checked', () => {
cy.get('[data-test=ModalOnboarding__Button]').click();
if (isLargeDesktop || isDesktop) {
cy.get('[data-test=LayoutTopBar__settingsButton]').click();
} else {
cy.get(`[data-test=LayoutNavbar__Button--settings]`).click();
}
cy.get('[data-test=SettingsShowOnboardingBox__InputToggle]').should('not.be.checked');
cy.reload();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
});

it('user can change steps with arrow keys (left, right)', () => {
checkChangeStepsWithArrowKeys(true);
});

it('user can change steps by clicking the edge of the screen (up to 25px from each edge)', () => {
checkChangeStepsByClickingEdgeOfTheScreenUpTo25px(true);
});

it('user cannot change steps by clicking the edge of the screen (more than 25px from each edge)', () => {
checkChangeStepsByClickingEdgeOfTheScreenMoreThan25px(true);
});

it('user can change steps by swiping on screen (difference more than or equal 5px)', () => {
checkChangeStepsBySwipingOnScreenDifferenceMoreThanOrEqual5px(true);
});

it('user cannot change steps by swiping on screen (difference less than 5px)', () => {
checkChangeStepsBySwipingOnScreenDifferenceLessThanl5px(true);
});

it('user cannot change steps by swiping on screen (difference less than 5px)', () => {
checkChangeStepsBySwipingOnScreenDifferenceLessThanl5px(true);
});

it('user is able to close the onboarding, and after page reload, onboarding does not show up again', () => {
cy.get('[data-test=ModalOnboarding]').should('be.visible');
cy.get('[data-test=ModalOnboarding__Button]').click();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
cy.reload();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
});

it('Onboarding stepper is visible after closing onboarding modal without going to the last step', () => {
cy.get('[data-test=ModalOnboarding__Button]').click();
cy.get('[data-test=OnboardingStepper]').should('be.visible');
});

it('Onboarding stepper opens onboarding modal', () => {
cy.get('[data-test=ModalOnboarding__Button]').click();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
cy.get('[data-test=OnboardingStepper]').click();
cy.get('[data-test=ModalOnboarding]').should('be.visible');
});

it(`Onboarding stepper is not visible if "${IS_ONBOARDING_DONE}" is set to "true"`, () => {
localStorage.setItem(IS_ONBOARDING_DONE, 'true');
localStorage.setItem(HAS_ONBOARDING_BEEN_CLOSED, 'true');
cy.reload();
cy.get('[data-test=ModalOnboarding]').should('not.exist');
cy.get('[data-test=OnboardingStepper]').should('not.exist');
});

if (isDesktop) {
it(`Onboarding stepper has tooltip`, () => {
cy.get('[data-test=ModalOnboarding__Button]').click();
cy.get('[data-test=OnboardingStepper]').trigger('mouseover');
cy.get('[data-test=OnboardingStepper__Tooltip__content]').should('be.visible');
cy.get('[data-test=OnboardingStepper__Tooltip__content]')
.invoke('text')
.should('eq', 'Reopen onboarding');
});
}

it('Onboarding stepper has right amount of steps and highlights correct amount of passed steps', () => {
const onboardingSteps = getStepsDecisionWindowOpen('2', '16 Jan');

cy.get('[data-test=ModalOnboarding__Button]').click();

cy.get(`[data-test*=OnboardingStepper__circle]`).should(
'have.length',
onboardingSteps.length,
);

for (let i = 0; i < onboardingSteps.length - 1; i++) {
cy.get(`[data-test=OnboardingStepper__circle--${i}]`)
.then($el => $el.css('stroke'))
.should('be.colored', i > 0 ? '#ffffff' : '#2d9b87');
}
cy.get('[data-test=OnboardingStepper]').click();
checkProgressStepperSlimIsCurrentAndClickNext(1);
cy.get('[data-test=ModalOnboarding__Button]').click();
for (let i = 0; i < onboardingSteps.length - 1; i++) {
cy.get(`[data-test=OnboardingStepper__circle--${i}]`)
.then($el => $el.css('stroke'))
.should('be.colored', i > 1 ? '#ffffff' : '#2d9b87');
}
cy.get('[data-test=OnboardingStepper]').click();
checkProgressStepperSlimIsCurrentAndClickNext(2);
cy.get('[data-test=ModalOnboarding__Button]').click();
for (let i = 0; i < onboardingSteps.length - 1; i++) {
cy.get(`[data-test=OnboardingStepper__circle--${i}]`)
.then($el => $el.css('stroke'))
.should('be.colored', i > 2 ? '#ffffff' : '#2d9b87');
}
cy.get('[data-test=OnboardingStepper]').click();
checkProgressStepperSlimIsCurrentAndClickNext(3);
cy.get('[data-test=ModalOnboarding__Button]').click();

cy.get('[data-test=OnboardingStepper]').should('not.exist');
});
});
},
);
4 changes: 2 additions & 2 deletions client/cypress/utils/onboarding.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,10 +20,10 @@ export const connectWalletOnboarding = (mockedTOSResponse?: boolean): Chainable<
}

cy.disconnectMetamaskWalletFromAllDapps();
visitWithLoader(ROOT.absolute, ROOT_ROUTES.projects.absolute);
visitWithLoader(ROOT.absolute, ROOT_ROUTES.home.absolute);

cy.wait(500);
cy.get('[data-test=MainLayout__Button--connect]').click();
cy.get('[data-test=LayoutTopBar__Button]').click();
cy.wait(500);
cy.get('[data-test=ConnectWallet__BoxRounded--browserWallet]').click();
cy.switchToMetamaskNotification();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -68,9 +68,5 @@ $circleDiameter: 5.6rem;
}

.tooltipWrapper {
position: absolute;
width: $circleDiameter;
height: $circleDiameter;
bottom: 4.8rem !important;
right: 4.8rem !important;
pointer-events: initial;
}
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,10 @@ const OnboardingStepper = (): ReactElement => {
{...animationProps}
>
<Tooltip
childrenClassName={styles.tooltipChildrenClassname}
className={styles.tooltip}
dataTest="OnboardingStepper__Tooltip"
position="top"
text={t('reopenOnboarding')}
tooltipWrapperClassName={styles.tooltipWrapper}
variant="small"
>
<div className={styles.wrapper}>
Expand Down
3 changes: 2 additions & 1 deletion client/synpress.config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,8 @@ export default defineConfig({
},
supportFile: 'cypress/support/index.ts',
},
numTestsKeptInMemory: 4,
numTestsKeptInMemory: 2,
experimentalMemoryManagement: true,
video: true,
viewportHeight: 1080,
viewportWidth: 1920,
Expand Down
Loading