diff --git a/src/App.test.tsx b/src/App.test.tsx
index bbd341c..624fe27 100644
--- a/src/App.test.tsx
+++ b/src/App.test.tsx
@@ -7,34 +7,7 @@ import App from './App';
import { WizardProvider } from './store/context';
import { useWizard } from './store/context';
-// Helper: renders App and navigates to a given step via dispatch
-function renderAtStep(targetStep: number) {
- // We wrap App's WizardProvider with an outer one and use a sibling to dispatch
- // Actually App already has its own WizardProvider, so we can't inject state from outside.
- // Instead, we render a standalone shell that mimics App but accepts a step override.
- function TestShell() {
- const { state, dispatch } = useWizard();
- React.useEffect(() => {
- if (targetStep > 0) {
- if (targetStep >= 1) {
- dispatch({ type: 'SET_BACKEND_TYPE', payload: 'azureblob' });
- }
- dispatch({ type: 'SET_STEP', payload: targetStep });
- }
- }, [dispatch]);
- return ;
- }
-
- return render(
-
-
-
- );
-}
-
-// Import the internal WizardShell logic by re-exporting from App — or replicate it here
-// Since App has WizardProvider + WizardShell baked in, we test App directly for step 0
-// and use a custom shell for steps 1 and 2.
+// Helper: renders a wizard shell at a given step (bypassing App's own WizardProvider)
import { BackendSelectionStep } from './components/wizard/BackendSelectionStep';
import { RemoteConfigStep } from './components/wizard/RemoteConfigStep';
import { DeploymentStep } from './components/wizard/DeploymentStep';
@@ -57,23 +30,48 @@ function AppContent({ state }: { state: WizardState }) {
);
}
+function renderAtStep(targetStep: number) {
+ function TestShell() {
+ const { state, dispatch } = useWizard();
+ React.useEffect(() => {
+ if (targetStep >= 1) {
+ dispatch({ type: 'SET_BACKEND_TYPE', payload: 'azureblob' });
+ }
+ if (targetStep > 0) {
+ dispatch({ type: 'SET_STEP', payload: targetStep });
+ }
+ }, [dispatch]);
+ return ;
+ }
+
+ return render(
+
+
+
+ );
+}
+
describe('App — step routing', () => {
it('renders BackendSelectionStep when currentStep is 0', () => {
render();
// BackendSelectionStep renders "Step 1: Select Backend"
const heading = screen.getByText(/Select Backend/);
expect(heading).toBeDefined();
- // StepIndicator should be visible with Backend label
- const backendLabel = screen.getByText(/Backend/);
- expect(backendLabel).toBeDefined();
+ // StepIndicator should be visible — Backend is the active step
+ const stepNav = screen.getByRole('navigation', { name: /Wizard steps/i });
+ expect(stepNav).toBeDefined();
});
it('renders RemoteConfigStep when currentStep is 1', async () => {
renderAtStep(1);
- // RemoteConfigStep renders a heading with "Remote Config" or backend-specific label
- // Wait for the step to render
- const heading = await screen.findByText(/Remote Config|Configure/);
- expect(heading).toBeDefined();
+ // RemoteConfigStep renders "Step 2: Configure {backend name}"
+ // Use getAllByText to handle multiple matches (StepIndicator also contains "Remote Config")
+ const headings = await screen.findAllByText(/Configure/);
+ // At least one heading with "Configure" from RemoteConfigStep
+ expect(headings.length).toBeGreaterThanOrEqual(1);
+ // The h2 specifically should say "Step 2: Configure Azure Blob Storage"
+ const h2 = headings.find((el) => el.tagName === 'H2');
+ expect(h2).toBeDefined();
});
it('renders DeploymentStep when currentStep is 2', async () => {
diff --git a/src/App.tsx b/src/App.tsx
index 4784599..6dc4e53 100644
--- a/src/App.tsx
+++ b/src/App.tsx
@@ -1,12 +1,45 @@
// src/App.tsx
+// Step router — renders the correct step component based on currentStep.
+// StepIndicator renders above each step as persistent breadcrumb navigation.
+
+import { useWizard } from './store/context';
import { WizardProvider } from './store/context';
+import { StepIndicator } from './components/wizard/StepIndicator';
+import { BackendSelectionStep } from './components/wizard/BackendSelectionStep';
+import { RemoteConfigStep } from './components/wizard/RemoteConfigStep';
+import { DeploymentStep } from './components/wizard/DeploymentStep';
+
+function WizardShell() {
+ const { state } = useWizard();
+
+ const steps = [
+ ,
+ // Key on backendType to force remount when backend changes — prevents stale form values
+ ,
+ ,
+ ];
+
+ // Guard: clamp to valid range (phase 4 will add step 3 for review/download)
+ const stepIndex = Math.min(state.currentStep, steps.length - 1);
+ const CurrentStep = steps[stepIndex];
+
+ return (
+
+
+
Ready2Blob
+
+
+ {CurrentStep}
+
+
+
+ );
+}
export default function App() {
return (
-
-
Ready2Blob
-
+
);
}