diff --git a/frontend/packages/console-app/src/components/tour/__tests__/tour-context.spec.ts b/frontend/packages/console-app/src/components/tour/__tests__/tour-context.spec.ts index 6105b92713a..bb52e069d58 100644 --- a/frontend/packages/console-app/src/components/tour/__tests__/tour-context.spec.ts +++ b/frontend/packages/console-app/src/components/tour/__tests__/tour-context.spec.ts @@ -139,6 +139,21 @@ describe('guided-tour-context', () => { expect(tour).toEqual(null); expect(totalSteps).toEqual(undefined); }); + + it('should not flash startTour when loaded transitions to true with completed tour', () => { + useSelectorMock.mockReturnValue({ A: true, B: false }); + useResolvedExtensionsMock.mockReturnValue(mockTourExtension); + // Start with loaded: false (async ConfigMap fetch in progress) + useUserPreferenceMock.mockReturnValue([{ dev: { completed: false } }, () => null, false]); + const { result, rerender } = renderHook(() => useTourValuesForContext()); + expect(result.current.tour).toEqual(null); + + // Simulate ConfigMap load completing with completed: true + useUserPreferenceMock.mockReturnValue([{ dev: { completed: true } }, () => null, true]); + rerender(); + const { tourState } = result.current; + expect(tourState?.startTour).not.toBe(true); + }); }); describe('useTourStatePerspective', () => { diff --git a/frontend/packages/console-app/src/components/tour/tour-context.ts b/frontend/packages/console-app/src/components/tour/tour-context.ts index 62ca051888b..4f5badc7542 100644 --- a/frontend/packages/console-app/src/components/tour/tour-context.ts +++ b/frontend/packages/console-app/src/components/tour/tour-context.ts @@ -1,5 +1,5 @@ import type { Reducer, Dispatch, ReducerAction } from 'react'; -import { createContext, useReducer, useState, useEffect, useCallback } from 'react'; +import { createContext, useReducer, useRef, useState, useEffect, useCallback } from 'react'; import { pick, union, isEqual } from 'lodash'; import { createSelector } from 'reselect'; import { useActivePerspective } from '@console/dynamic-plugin-sdk'; @@ -151,14 +151,18 @@ export const useTourValuesForContext = (): TourContextType => { startTour: !completed, }); + const initializedWithLoadedData = useRef(false); useEffect(() => { tourDispatch({ type: TourActions.initialize, payload: { completed } }); setPerspective(activePerspective); + if (loaded) { + initializedWithLoadedData.current = true; + } // only run effect when the active perspective changes // eslint-disable-next-line react-hooks/exhaustive-deps }, [activePerspective, loaded]); - if (!tour || !loaded) return { tour: null }; + if (!tour || !loaded || !initializedWithLoadedData.current) return { tour: null }; const { properties: { tour: { intro, steps: unfilteredSteps, end },