diff --git a/client/cypress/e2e/onboardingTOSAccepted.cy.ts b/client/cypress/e2e/onboardingTOSAccepted.cy.ts index 738c2caefb..88b42e9916 100644 --- a/client/cypress/e2e/onboardingTOSAccepted.cy.ts +++ b/client/cypress/e2e/onboardingTOSAccepted.cy.ts @@ -16,10 +16,7 @@ import { 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'; +import { getStepsDecisionWindowOpen } from 'src/hooks/helpers/useOnboardingSteps/steps'; import { ROOT_ROUTES } from 'src/routes/RootRoutes/routes'; chai.use(chaiColors); @@ -60,26 +57,18 @@ Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight, isDes }); 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'); + const onboardingSteps = getStepsDecisionWindowOpen('2', '16 Jan'); - for (let i = 1; i < onboardingSteps.length - 1; i++) { - checkProgressStepperSlimIsCurrentAndClickNext(i); - } + 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=ProjectsView__ProjectsList]').should('be.visible'); - }); + 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=ProjectsView__ProjectsList]').should('be.visible'); }); it('user is able to close the modal by clicking button in the top-right', () => { @@ -169,49 +158,41 @@ Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight, isDes } it('Onboarding stepper has right amount of steps and highlights correct amount of passed steps', () => { - cy.window().then(win => { - const isDecisionWindowOpen = win.clientReactQuery.getQueryData( - QUERY_KEYS.isDecisionWindowOpen, - ); - - const onboardingSteps = isDecisionWindowOpen - ? getStepsDecisionWindowOpen('2', '16 Jan') - : getStepsDecisionWindowClosed('2', '16 Jan'); + const onboardingSteps = getStepsDecisionWindowOpen('2', '16 Jan'); - cy.get('[data-test=ModalOnboarding__Button]').click(); + cy.get('[data-test=ModalOnboarding__Button]').click(); - cy.get(`[data-test*=OnboardingStepper__circle]`).should( - 'have.length', - onboardingSteps.length, - ); + 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(); + 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'); - }); + cy.get('[data-test=OnboardingStepper]').should('not.exist'); }); }); }); diff --git a/client/cypress/e2e/projects.cy.ts b/client/cypress/e2e/projects.cy.ts index 87f81b7be9..474d90042b 100644 --- a/client/cypress/e2e/projects.cy.ts +++ b/client/cypress/e2e/projects.cy.ts @@ -10,7 +10,7 @@ import { import { getNamesOfProjects } from 'cypress/utils/projects'; import viewports from 'cypress/utils/viewports'; import { HAS_ONBOARDING_BEEN_CLOSED, IS_ONBOARDING_DONE } from 'src/constants/localStorageKeys'; -// import getMilestones from 'src/constants/milestones'; +import getMilestones from 'src/constants/milestones'; import { ROOT_ROUTES } from 'src/routes/RootRoutes/routes'; import Chainable = Cypress.Chainable; @@ -160,48 +160,49 @@ Object.values(viewports).forEach(({ device, viewportWidth, viewportHeight }) => cy.get('[data-test=AllocationItem]') .trigger('pointerdown') .trigger('pointermove', { pageX: x - 20 }) - .trigger('pointerup'); + .trigger('pointerup', { pageX: x - 40 }); + cy.wait(500); cy.get('[data-test=AllocationItem__removeButton]').should('be.visible'); - cy.get('[data-test=AllocationItem__removeButton]').click({ force: true }); + cy.get('[data-test=AllocationItem__removeButton]').click(); cy.get('[data-test=AllocationItem__removeButton]').should('not.exist'); cy.get('[data-test=AllocationItem]').should('not.exist'); cy.get('[data-test=Navbar__numberOfAllocations]').should('not.exist'); }); }); - // it('ProjectsTimelineWidgetItem with href opens link when clicked without mouse movement', () => { - // const milestones = getMilestones(); - // cy.get('[data-test=ProjectsTimelineWidget]').should('be.visible'); - // cy.get('[data-test=ProjectsTimelineWidgetItem]').should('have.length', milestones.length); - // for (let i = 0; i < milestones.length; i++) { - // if (milestones[i].href) { - // cy.get('[data-test=ProjectsTimelineWidgetItem]') - // .eq(i) - // .within(() => { - // cy.get('[data-test=ProjectsTimelineWidgetItem__Svg--arrowTopRight]').should( - // 'be.visible', - // ); - // }); - - // cy.get('[data-test=ProjectsTimelineWidgetItem]') - // .eq(i) - // .then(el => { - // const { x } = el[0].getBoundingClientRect(); - // cy.get('[data-test=ProjectsTimelineWidgetItem]') - // .eq(i) - // .trigger('mousedown') - // .trigger('mouseup', { clientX: x + 10 }); - // cy.location('pathname').should('eq', ROOT_ROUTES.projects.absolute); - - // cy.get('[data-test=ProjectsTimelineWidgetItem]') - // .eq(i) - // .trigger('mousedown') - // .trigger('mouseup'); - // cy.location('pathname').should('not.eq', ROOT_ROUTES.projects.absolute); - // }); - // } - // } - // }); + it('ProjectsTimelineWidgetItem with href opens link when clicked without mouse movement', () => { + const milestones = getMilestones(); + cy.get('[data-test=ProjectsTimelineWidget]').should('be.visible'); + cy.get('[data-test=ProjectsTimelineWidgetItem]').should('have.length', milestones.length); + for (let i = 0; i < milestones.length; i++) { + if (milestones[i].href) { + cy.get('[data-test=ProjectsTimelineWidgetItem]') + .eq(i) + .within(() => { + cy.get('[data-test=ProjectsTimelineWidgetItem__Svg--arrowTopRight]').should( + 'be.visible', + ); + }); + + cy.get('[data-test=ProjectsTimelineWidgetItem]') + .eq(i) + .then(el => { + const { x } = el[0].getBoundingClientRect(); + cy.get('[data-test=ProjectsTimelineWidgetItem]') + .eq(i) + .trigger('mousedown') + .trigger('mouseup', { clientX: x + 10 }); + cy.location('pathname').should('eq', ROOT_ROUTES.projects.absolute); + + cy.get('[data-test=ProjectsTimelineWidgetItem]') + .eq(i) + .trigger('mousedown') + .trigger('mouseup'); + cy.location('pathname').should('not.eq', ROOT_ROUTES.projects.absolute); + }); + } + } + }); }); describe(`projects (patron mode): ${device}`, { viewportHeight, viewportWidth }, () => { diff --git a/client/cypress/utils/onboarding.ts b/client/cypress/utils/onboarding.ts index 4c75fd5fed..dc55ab919d 100644 --- a/client/cypress/utils/onboarding.ts +++ b/client/cypress/utils/onboarding.ts @@ -57,9 +57,6 @@ export const checkChangeStepsWithArrowKeys = (isTOSAccepted: boolean): void => { [ { el: 1, key: 'ArrowRight' }, { el: 2, key: 'ArrowRight' }, - // { el: 3, key: 'ArrowRight' }, - // { el: 3, key: 'ArrowRight' }, - // { el: 2, key: 'ArrowLeft' }, { el: 1, key: 'ArrowLeft' }, { el: 0, key: 'ArrowLeft' }, { el: 0, key: 'ArrowLeft' }, @@ -83,10 +80,6 @@ export const checkChangeStepsByClickingEdgeOfTheScreenUpTo25px = (isTOSAccepted: [ { clientX: rightEdgeX - 25, el: 1 }, { clientX: rightEdgeX - 10, el: 2 }, - // { clientX: rightEdgeX - 5, el: 3 }, - // rightEdgeX === browser right frame - // { clientX: rightEdgeX - 1, el: 3 }, - // { clientX: leftEdgeX + 25, el: 2 }, { clientX: leftEdgeX + 10, el: 1 }, { clientX: leftEdgeX + 5, el: 0 }, { clientX: leftEdgeX, el: 0 }, @@ -147,11 +140,6 @@ export const checkChangeStepsBySwipingOnScreenDifferenceMoreThanOrEqual5px = ( touchMoveClientX: window.innerWidth / 2 - 5, touchStartClientX: window.innerWidth / 2, }, - // { - // el: 3, - // touchMoveClientX: window.innerWidth / 2 - 5, - // touchStartClientX: window.innerWidth / 2, - // }, { el: 2, touchMoveClientX: window.innerWidth / 2 + 5, diff --git a/client/src/components/Allocation/AllocationItem/AllocationItem.tsx b/client/src/components/Allocation/AllocationItem/AllocationItem.tsx index 0601316df6..ad159b612f 100644 --- a/client/src/components/Allocation/AllocationItem/AllocationItem.tsx +++ b/client/src/components/Allocation/AllocationItem/AllocationItem.tsx @@ -204,12 +204,12 @@ const AllocationItem: FC = ({ animate( ref.current, // @ts-expect-error e is wrongly typed, doesn't see x property. - { x: e.x < startX ? constraints[0] : constraints[1] }, + { x: e.pageX < startX ? constraints[0] : constraints[1] }, { duration: 0.2 }, ); }} // @ts-expect-error e is wrongly typed, doesn't see x property. - onDragStart={e => setStartX(e.x)} + onDragStart={e => setStartX(e.pageX)} style={{ x }} > {(isLoading || isLoadingError) && } diff --git a/client/src/components/shared/OnboardingStepper/OnboardingStepper.tsx b/client/src/components/shared/OnboardingStepper/OnboardingStepper.tsx index 98226fbaf6..f48cdfbf25 100644 --- a/client/src/components/shared/OnboardingStepper/OnboardingStepper.tsx +++ b/client/src/components/shared/OnboardingStepper/OnboardingStepper.tsx @@ -30,6 +30,18 @@ const OnboardingStepper = (): ReactNode => { const viewBox = '0 0 56 56'; const numberOfSteps = stepsToUse.length; + const animationProps = isDesktop + ? { + animate: { bottom: 48, opacity: 1, right: 48 }, + exit: { bottom: 24, opacity: 0, right: 48 }, + initial: { bottom: 24, opacity: 0, right: 48 }, + } + : { + animate: { bottom: 116, opacity: 1, right: 24 }, + exit: { bottom: 92, opacity: 0, right: 24 }, + initial: { bottom: 92, opacity: 0, right: 24 }, + }; + const svgNumber = useMemo(() => { if (lastSeenStep === 1) { return one; @@ -46,13 +58,11 @@ const OnboardingStepper = (): ReactNode => { return ( setIsOnboardingModalOpen(true)} whileHover={{ scale: 1.1 }} + {...animationProps} > ({ setIsOnboardingModalOpen: payload => { set(state => ({ data: { ...state.data, isOnboardingModalOpen: payload } })); }, - // eslint-disable-next-line @typescript-eslint/naming-convention setLastSeenStep: payload => { localStorage.setItem(LAST_SEEN_STEP, JSON.stringify(payload)); set(state => ({ data: { ...state.data, lastSeenStep: payload } }));