diff --git a/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx b/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx index 3439c49f5ed..f2eb161fe44 100644 --- a/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx +++ b/src/Apps/Order2/Routes/Checkout/Hooks/__tests__/useCheckoutAutoScroll.jest.tsx @@ -38,6 +38,21 @@ const createSteps = (activeStep: CheckoutStepName) => { })) } +const createStepsWithMultipleActive = (activeSteps: CheckoutStepName[]) => { + const activeIndices = activeSteps.map(s => ALL_STEPS.indexOf(s)) + const firstActive = Math.min(...activeIndices) + const lastActive = Math.max(...activeIndices) + return ALL_STEPS.map((name, index) => ({ + name, + state: + index < firstActive + ? CheckoutStepState.COMPLETED + : index >= firstActive && index <= lastActive + ? CheckoutStepState.ACTIVE + : CheckoutStepState.UPCOMING, + })) +} + describe("useCheckoutAutoScroll", () => { let mockJumpTo: jest.Mock @@ -159,4 +174,77 @@ describe("useCheckoutAutoScroll", () => { offset: 30, }) }) + + describe("combined FULFILLMENT_DETAILS + DELIVERY_OPTION step", () => { + it("scrolls to the first active step (FULFILLMENT_DETAILS) on initial load", () => { + const steps = createStepsWithMultipleActive([ + CheckoutStepName.FULFILLMENT_DETAILS, + CheckoutStepName.DELIVERY_OPTION, + ]) + + mockUseCheckoutContext.mockReturnValue({ isLoading: true, steps }) + + const { rerender } = renderHook(() => useCheckoutAutoScroll()) + + mockUseCheckoutContext.mockReturnValue({ isLoading: false, steps }) + + rerender() + jest.runAllTimers() + + expect(mockJumpTo).toHaveBeenCalledWith("fulfillment-details-step", { + behavior: "smooth", + offset: 30, + }) + }) + + it("scrolls to DELIVERY_OPTION when advancing from the combined step to PAYMENT", () => { + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createStepsWithMultipleActive([ + CheckoutStepName.FULFILLMENT_DETAILS, + CheckoutStepName.DELIVERY_OPTION, + ]), + }) + + const { rerender } = renderHook(() => useCheckoutAutoScroll()) + + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createSteps(CheckoutStepName.PAYMENT), + }) + + rerender() + jest.runAllTimers() + + expect(mockJumpTo).toHaveBeenCalledWith("delivery-options-step", { + behavior: "smooth", + offset: 30, + }) + }) + + it("scrolls to FULFILLMENT_DETAILS when going back from PAYMENT to the combined step", () => { + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createSteps(CheckoutStepName.PAYMENT), + }) + + const { rerender } = renderHook(() => useCheckoutAutoScroll()) + + mockUseCheckoutContext.mockReturnValue({ + isLoading: false, + steps: createStepsWithMultipleActive([ + CheckoutStepName.FULFILLMENT_DETAILS, + CheckoutStepName.DELIVERY_OPTION, + ]), + }) + + rerender() + jest.runAllTimers() + + expect(mockJumpTo).toHaveBeenCalledWith("fulfillment-details-step", { + behavior: "smooth", + offset: 30, + }) + }) + }) }) diff --git a/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts b/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts index 1c6c13ea7ce..6430405443f 100644 --- a/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts +++ b/src/Apps/Order2/Routes/Checkout/Hooks/useCheckoutAutoScroll.ts @@ -24,10 +24,16 @@ export const useCheckoutAutoScroll = () => { const { isLoading, steps } = useCheckoutContext() const { scrollToStep } = useScrollToStep() - const activeStep = steps.find(step => step.state === CheckoutStepState.ACTIVE) + // Combined steps (FULFILLMENT_DETAILS + DELIVERY_OPTION) are ACTIVE + // together, use the last one so forward-advance previousStep is correct. + const activeSteps = steps.filter( + step => step.state === CheckoutStepState.ACTIVE, + ) + const activeStep = activeSteps[0] + const trailingActiveStep = activeSteps[activeSteps.length - 1] const activeStepIndex = stepWithIndex(activeStep, steps) - const previousStep = usePrevious(activeStep) + const previousStep = usePrevious(trailingActiveStep) const previousStepIndex = stepWithIndex(previousStep, steps) const wasLoading = usePrevious(isLoading)