Skip to content

Commit 3147848

Browse files
feat(ui): hide validation from install wizard navigation (#2327)
* consolidate validation into the setup step and update tests * remove uneeded goToPreviousStep function * run installation start after setup and validation * revert accidental changes to operator and e2e files * move validation back to its own component * minor changes to validation step * Revert unintended changes to helm charts and operator metadata * add newline to validation step * fex web unit test * revert to using validation as a separate step but hide it from navbar and only show setup step to user * complete reversion of setup and validation step * add test for step navigation * remove newline * Update web/src/components/wizard/StepNavigation.tsx Co-authored-by: Salah Al Saleh <sg.alsaleh@gmail.com> * fix variable naming * fix lint error --------- Co-authored-by: Salah Al Saleh <sg.alsaleh@gmail.com>
1 parent 81aa71f commit 3147848

File tree

2 files changed

+167
-5
lines changed

2 files changed

+167
-5
lines changed

web/src/components/wizard/StepNavigation.tsx

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -13,20 +13,26 @@ const StepNavigation: React.FC<StepNavigationProps> = ({ currentStep }) => {
1313
const { prototypeSettings } = useConfig();
1414
const themeColor = prototypeSettings.themeColor;
1515

16+
// Navigation steps (validation is hidden but still part of the wizard flow)
1617
const steps = [
1718
{ id: 'welcome', name: 'Welcome', icon: ClipboardList },
1819
{ id: 'setup', name: 'Setup', icon: Settings },
19-
{ id: 'validation', name: 'Validation', icon: CheckCircle },
2020
{ id: 'installation', name: mode === 'upgrade' ? 'Upgrade' : 'Installation', icon: Download },
2121
{ id: 'completion', name: 'Completion', icon: CheckCircle },
2222
];
2323

24+
// All wizard steps for progress calculation
25+
const allSteps: WizardStep[] = ['welcome', 'setup', 'validation', 'installation', 'completion'];
26+
2427
const getStepStatus = (step: { id: string }) => {
25-
const stepIndex = steps.findIndex((s) => s.id === step.id);
26-
const currentIndex = steps.findIndex((s) => s.id === currentStep);
28+
const stepIndex = allSteps.indexOf(step.id as WizardStep);
29+
const currentStepIndex = allSteps.indexOf(currentStep);
30+
31+
// Treat validation as part of setup for navigation purposes
32+
const adjustedCurrentIndex = currentStep === 'validation' ? allSteps.indexOf('setup') : currentStepIndex;
2733

28-
if (stepIndex < currentIndex) return 'complete';
29-
if (stepIndex === currentIndex) return 'current';
34+
if (stepIndex < adjustedCurrentIndex) return 'complete';
35+
if (stepIndex === adjustedCurrentIndex || (step.id === 'setup' && currentStep === 'validation')) return 'current';
3036
return 'upcoming';
3137
};
3238

Lines changed: 156 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,156 @@
1+
import React from "react";
2+
import { describe, it, expect } from "vitest";
3+
import { screen } from "@testing-library/react";
4+
import { renderWithProviders } from "../../../test/setup.tsx";
5+
import StepNavigation from "../StepNavigation.tsx";
6+
import { WizardStep } from "../../../types/index.ts";
7+
8+
describe("StepNavigation", () => {
9+
const defaultPreloadedState = {
10+
// Use generic settings instead of prototype-specific references
11+
prototypeSettings: {
12+
themeColor: "#316DE6",
13+
},
14+
};
15+
16+
it("renders all navigation steps except validation", () => {
17+
renderWithProviders(<StepNavigation currentStep="welcome" />, {
18+
wrapperProps: {
19+
authenticated: true,
20+
preloadedState: defaultPreloadedState,
21+
},
22+
});
23+
24+
// Should show 4 steps (welcome, setup, installation, completion)
25+
expect(screen.getByText("Welcome")).toBeInTheDocument();
26+
expect(screen.getByText("Setup")).toBeInTheDocument();
27+
expect(screen.getByText("Installation")).toBeInTheDocument();
28+
expect(screen.getByText("Completion")).toBeInTheDocument();
29+
30+
// Should NOT show validation step
31+
expect(screen.queryByText("Validation")).not.toBeInTheDocument();
32+
});
33+
34+
it("shows 'current' status for the current step", () => {
35+
renderWithProviders(<StepNavigation currentStep="setup" />, {
36+
wrapperProps: {
37+
authenticated: true,
38+
preloadedState: defaultPreloadedState,
39+
},
40+
});
41+
42+
const setupStep = screen.getByText("Setup").closest("div");
43+
expect(setupStep).toHaveStyle({
44+
border: "1px solid #316DE6",
45+
});
46+
});
47+
48+
it("treats validation step as part of setup for navigation", () => {
49+
renderWithProviders(<StepNavigation currentStep="validation" />, {
50+
wrapperProps: {
51+
authenticated: true,
52+
preloadedState: defaultPreloadedState,
53+
},
54+
});
55+
56+
// When currentStep is 'validation', setup should show as current
57+
const setupStep = screen.getByText("Setup").closest("div");
58+
expect(setupStep).toHaveStyle({
59+
border: "1px solid #316DE6",
60+
});
61+
62+
// Welcome should be complete
63+
const welcomeStep = screen.getByText("Welcome").closest("div");
64+
expect(welcomeStep).toHaveStyle({
65+
backgroundColor: "#316DE61A",
66+
color: "#316DE6",
67+
});
68+
});
69+
70+
it("shows upcoming steps with default styling", () => {
71+
renderWithProviders(<StepNavigation currentStep="welcome" />, {
72+
wrapperProps: {
73+
authenticated: true,
74+
preloadedState: defaultPreloadedState,
75+
},
76+
});
77+
78+
// Setup, Installation, and Completion should be upcoming
79+
const installationStep = screen.getByText("Installation").closest("div");
80+
const completionStep = screen.getByText("Completion").closest("div");
81+
82+
expect(installationStep).toHaveStyle({
83+
backgroundColor: "rgb(243 244 246)", // gray background
84+
color: "rgb(107 114 128)", // gray text
85+
});
86+
expect(completionStep).toHaveStyle({
87+
backgroundColor: "rgb(243 244 246)",
88+
color: "rgb(107 114 128)",
89+
});
90+
});
91+
92+
it("renders correct icons for each step", () => {
93+
renderWithProviders(<StepNavigation currentStep="welcome" />, {
94+
wrapperProps: {
95+
authenticated: true,
96+
preloadedState: defaultPreloadedState,
97+
},
98+
});
99+
100+
// Check that all step icons are rendered
101+
const stepElements = screen.getAllByRole("listitem");
102+
expect(stepElements).toHaveLength(4); // welcome, setup, installation, completion
103+
104+
// Each step should have an icon (svg element)
105+
stepElements.forEach((step) => {
106+
const icon = step.querySelector("svg");
107+
expect(icon).toBeInTheDocument();
108+
expect(icon).toHaveClass("w-5", "h-5");
109+
});
110+
});
111+
112+
it("maintains proper step progression logic", () => {
113+
// Test different current steps and their expected status
114+
const testCases = [
115+
{ currentStep: "welcome", setupStatus: "upcoming", installStatus: "upcoming" },
116+
{ currentStep: "setup", setupStatus: "current", installStatus: "upcoming" },
117+
{ currentStep: "validation", setupStatus: "current", installStatus: "upcoming" },
118+
{ currentStep: "installation", setupStatus: "complete", installStatus: "current" },
119+
];
120+
121+
testCases.forEach(({ currentStep, setupStatus, installStatus }) => {
122+
const { unmount } = renderWithProviders(
123+
<StepNavigation currentStep={currentStep as WizardStep} />,
124+
{
125+
wrapperProps: {
126+
authenticated: true,
127+
preloadedState: defaultPreloadedState,
128+
},
129+
}
130+
);
131+
132+
const setupStep = screen.getByText("Setup").closest("div");
133+
const installStep = screen.getByText("Installation").closest("div");
134+
135+
if (setupStatus === "current") {
136+
expect(setupStep).toHaveStyle({ border: "1px solid #316DE6" });
137+
} else if (setupStatus === "complete") {
138+
expect(setupStep).toHaveStyle({
139+
backgroundColor: "#316DE61A",
140+
color: "#316DE6"
141+
});
142+
}
143+
144+
if (installStatus === "current") {
145+
expect(installStep).toHaveStyle({ border: "1px solid #316DE6" });
146+
} else if (installStatus === "upcoming") {
147+
expect(installStep).toHaveStyle({
148+
backgroundColor: "rgb(243 244 246)",
149+
color: "rgb(107 114 128)"
150+
});
151+
}
152+
153+
unmount(); // Clean up for next iteration
154+
});
155+
});
156+
});

0 commit comments

Comments
 (0)