From 4b837b19a0cb0a2571a7adf499e36be9689388bc Mon Sep 17 00:00:00 2001 From: Kawa Date: Wed, 1 Apr 2026 12:54:16 +0200 Subject: [PATCH] feat(10-01): update App.test.tsx and add step descriptions to all 4 steps MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Update App.test.tsx: add 'shows intro section on initial render' test - Update App.test.tsx: fix 'renders BackendSelectionStep' — click Get Started first - Add fireEvent import for click simulation - BackendSelectionStep: add description below h2 (text-sm text-on-surface-variant) - RemoteConfigStep: add description below h2 - DeploymentStep: add description below h2 - ReviewStep: add h2 heading + description paragraph (step was missing h2) - All descriptions use text-sm text-on-surface-variant mt-1 mb-4 --- src/App.test.tsx | 17 ++++++++++++++++- src/components/wizard/BackendSelectionStep.tsx | 10 ++++++++++ src/components/wizard/DeploymentStep.tsx | 4 ++++ src/components/wizard/RemoteConfigStep.tsx | 4 ++++ src/components/wizard/ReviewStep.tsx | 6 ++++++ 5 files changed, 40 insertions(+), 1 deletion(-) diff --git a/src/App.test.tsx b/src/App.test.tsx index 624fe27..d4b1ab8 100644 --- a/src/App.test.tsx +++ b/src/App.test.tsx @@ -1,7 +1,7 @@ // @vitest-environment jsdom // Covers WIZD-02: App renders the correct step component for currentStep 0, 1, 2 import { describe, it, expect } from 'vitest'; -import { render, screen } from '@testing-library/react'; +import { render, screen, fireEvent } from '@testing-library/react'; import React from 'react'; import App from './App'; import { WizardProvider } from './store/context'; @@ -52,8 +52,23 @@ function renderAtStep(targetStep: number) { } describe('App — step routing', () => { + it('shows intro section on initial render', () => { + render(); + // Intro copy is present + const introHeading = screen.getByText(/Go from zero to a deployable rclone setup in minutes/); + expect(introHeading).toBeDefined(); + // StepIndicator is NOT in the DOM + const stepNav = screen.queryByRole('navigation', { name: /Wizard steps/i }); + expect(stepNav).toBeNull(); + }); + it('renders BackendSelectionStep when currentStep is 0', () => { render(); + // Intro shows first — assert Get Started button is visible + const getStarted = screen.getByRole('button', { name: /Get Started/i }); + expect(getStarted).toBeDefined(); + // Click Get Started to reveal the wizard + fireEvent.click(getStarted); // BackendSelectionStep renders "Step 1: Select Backend" const heading = screen.getByText(/Select Backend/); expect(heading).toBeDefined(); diff --git a/src/components/wizard/BackendSelectionStep.tsx b/src/components/wizard/BackendSelectionStep.tsx index 33883eb..611c310 100644 --- a/src/components/wizard/BackendSelectionStep.tsx +++ b/src/components/wizard/BackendSelectionStep.tsx @@ -8,6 +8,7 @@ import { BACKEND_REGISTRY } from '../../schemas/registry'; import { BackendCard } from '../ui/BackendCard'; import { MD3_BTN_FILLED } from '../../styles/md3-buttons'; import { TextFieldMD3 } from '../ui/TextFieldMD3'; +import { RemoteNamePreview } from '../ui/RemoteNamePreview'; const remoteNameSchema = z.object({ name: z @@ -29,6 +30,7 @@ export function BackendSelectionStep() { const { register, handleSubmit, + watch, formState: { errors }, } = useForm({ resolver: zodResolver(remoteNameSchema), @@ -37,6 +39,8 @@ export function BackendSelectionStep() { defaultValues: { name: state.remote.name }, }); + const remoteName = watch('name'); + function onValidSubmit(values: RemoteNameFormValues) { const backend = pendingBackend.current; if (!backend) return; @@ -54,6 +58,10 @@ export function BackendSelectionStep() { return (

Step 1: Select Backend

+

+ Name your remote and pick the cloud storage provider you want to connect to. + Your choice determines which credentials are required in the next step. +

+
{Object.entries(BACKEND_REGISTRY).map(([type, entry]) => (

Step 3: Deployment Options

+

+ Choose how the generated config gets deployed to the target machine and which deployment + script formats to produce. +

{/* Include rclone installation toggle */}
diff --git a/src/components/wizard/RemoteConfigStep.tsx b/src/components/wizard/RemoteConfigStep.tsx index 5b64a5c..3312541 100644 --- a/src/components/wizard/RemoteConfigStep.tsx +++ b/src/components/wizard/RemoteConfigStep.tsx @@ -56,6 +56,10 @@ export function RemoteConfigStep() { return (

Step 2: Configure {backendLabel[backendType]}

+

+ Enter the credentials for your selected backend. These values are written directly into the + generated rclone.conf and are never sent to any server. +

{backendType === 'azureblob' ? ( <> diff --git a/src/components/wizard/ReviewStep.tsx b/src/components/wizard/ReviewStep.tsx index 70ac134..e4896c7 100644 --- a/src/components/wizard/ReviewStep.tsx +++ b/src/components/wizard/ReviewStep.tsx @@ -72,6 +72,12 @@ export function ReviewStep() { return (
+

Step 4: Review & Download

+

+ Review your generated files and download them. Acknowledge the security notice before + copying or downloading credentials. +

+ {/* SECU-02: client-side only notice */}

No data is sent to any server. All file generation happens in your browser.