Files
Ready2Blob/.planning/phases/03-wizard-ui/03-01-PLAN.md
T
kawa 53bbd00533 docs(05-03): complete act()-warning elimination plan
- SUMMARY.md: userEvent v14 migration + vi.useFakeTimers() for ReviewStep
- STATE.md: advanced to completed 05-03, added patterns as decisions
- ROADMAP.md: phase 5 now 4/4 plans complete (Complete status)
- REQUIREMENTS.md: TECH-05 marked complete
2026-03-30 11:44:59 +02:00

11 KiB
Raw Blame History

phase, plan, type, wave, depends_on, files_modified, autonomous, requirements, must_haves
phase plan type wave depends_on files_modified autonomous requirements must_haves
03-wizard-ui 01 execute 1
vite.config.ts
src/App.test.tsx
src/components/wizard/BackendSelectionStep.test.tsx
src/components/wizard/RemoteConfigStep.test.tsx
src/components/wizard/StepIndicator.test.tsx
true
WIZD-01
WIZD-02
WIZD-03
WIZD-04
BACK-01
BACK-02
BACK-03
truths artifacts key_links
Vitest runs React component tests without 'document is not defined' errors
All four test stub files exist and fail RED with descriptive 'not yet implemented' messages
npx vitest run exits non-zero (tests fail) confirming stubs are RED
path provides contains
vite.config.ts jsdom test environment config test: { environment: 'jsdom'
path provides
src/App.test.tsx Wave 0 stub for WIZD-02 step routing
path provides
src/components/wizard/BackendSelectionStep.test.tsx Wave 0 stubs for WIZD-01, WIZD-04
path provides
src/components/wizard/RemoteConfigStep.test.tsx Wave 0 stubs for BACK-01, BACK-02, BACK-03
path provides
src/components/wizard/StepIndicator.test.tsx Wave 0 stubs for WIZD-03
from to via pattern
vite.config.ts src/**/*.test.tsx test.environment: 'jsdom' environment.*jsdom
Set up the Wave 0 test infrastructure: configure Vitest for jsdom component testing and create failing test stubs for all Phase 3 wizard components.

Purpose: Establish the RED baseline before implementation — tests must fail in a descriptive way so Plans 0305 can drive to GREEN. Output: Updated vite.config.ts and four test stub files.

<execution_context> @C:/Users/SebastienQUEROL/.claude/get-shit-done/workflows/execute-plan.md @C:/Users/SebastienQUEROL/.claude/get-shit-done/templates/summary.md </execution_context>

@.planning/PROJECT.md @.planning/ROADMAP.md @.planning/STATE.md @.planning/phases/03-wizard-ui/03-CONTEXT.md @.planning/phases/03-wizard-ui/03-RESEARCH.md @.planning/phases/03-wizard-ui/03-VALIDATION.md

From src/store/types.ts:

export interface WizardState {
  currentStep: number;
  remote: {
    name: string;
    backendType: BackendType | null;
    params: Record<string, string>;
  };
  deployment: {
    includeInstall: boolean;
    configPath: 'machine-wide' | 'user-profile';
    scriptTargets: ('intune' | 'rmm')[];
  };
}

export type WizardAction =
  | { type: 'SET_STEP'; payload: number }
  | { type: 'SET_BACKEND_TYPE'; payload: BackendType }
  | { type: 'SET_REMOTE_NAME'; payload: string }
  | { type: 'SET_REMOTE_PARAMS'; payload: Record<string, string> }
  | { type: 'SET_DEPLOYMENT'; payload: Partial<WizardState['deployment']> }
  | { type: 'RESET' };

From src/schemas/registry.ts:

export type BackendType = 'azureblob' | 's3' | 's3-compatible';

From src/store/context.tsx:

export function useWizard(): WizardContextValue;
export function WizardProvider({ children }: { children: React.ReactNode }): JSX.Element;
Task 1: Configure Vitest jsdom environment in vite.config.ts vite.config.ts Update vite.config.ts to add a `test` block inside `defineConfig`. The existing config has only `plugins: [react(), tailwindcss()]`. Add:
```typescript
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import tailwindcss from '@tailwindcss/vite';

export default defineConfig({
  plugins: [react(), tailwindcss()],
  test: {
    environment: 'jsdom',
    passWithNoTests: true,
  },
});
```

Do NOT add `/// <reference types="vitest" />` — this is not needed with vitest ^4.x when using `test` config inside `defineConfig`. The `passWithNoTests: true` is already established project convention (see STATE.md decision from Phase 01-01).
npx vitest run --reporter=verbose 2>&1 | head -20 Vitest starts without "document is not defined" errors. If no test files exist yet the suite exits 0 due to passWithNoTests: true. Task 2: Create Wave 0 test stubs (RED baseline for all 7 requirements) src/App.test.tsx, src/components/wizard/BackendSelectionStep.test.tsx, src/components/wizard/RemoteConfigStep.test.tsx, src/components/wizard/StepIndicator.test.tsx Create the `src/components/wizard/` directory (it does not exist yet). Create four test stub files. Each stub imports the component it will test and throws a todo error — this gives RED tests with clear names rather than import errors.
NOTE: The component files do NOT exist yet. Import them anyway. Vitest will fail at import with "Cannot find module" — this is the correct RED state.

**src/App.test.tsx**
```typescript
// @vitest-environment jsdom
// Covers WIZD-02: App renders the correct step component for currentStep 0, 1, 2
import { describe, it, expect } from 'vitest';

describe('App — step routing', () => {
  it('renders BackendSelectionStep when currentStep is 0', () => {
    expect.fail('not yet implemented');
  });

  it('renders RemoteConfigStep when currentStep is 1', () => {
    expect.fail('not yet implemented');
  });

  it('renders DeploymentStep when currentStep is 2', () => {
    expect.fail('not yet implemented');
  });
});
```

**src/components/wizard/BackendSelectionStep.test.tsx**
```typescript
// @vitest-environment jsdom
// Covers WIZD-01: card grid renders Azure Blob, Amazon S3, S3-Compatible (Azure first)
// Covers WIZD-04: remote name field validates alphanumeric/dash/underscore
import { describe, it, expect } from 'vitest';

describe('BackendSelectionStep', () => {
  describe('WIZD-01: backend card grid', () => {
    it('renders Azure Blob Storage card', () => {
      expect.fail('not yet implemented');
    });

    it('renders Amazon S3 card', () => {
      expect.fail('not yet implemented');
    });

    it('renders S3-Compatible card', () => {
      expect.fail('not yet implemented');
    });

    it('Azure Blob is listed before S3 in DOM order', () => {
      expect.fail('not yet implemented');
    });

    it('clicking a backend card dispatches SET_BACKEND_TYPE and SET_STEP', () => {
      expect.fail('not yet implemented');
    });
  });

  describe('WIZD-04: remote name field', () => {
    it('renders remote name input at the top of the step', () => {
      expect.fail('not yet implemented');
    });

    it('shows no error before first Next attempt', () => {
      expect.fail('not yet implemented');
    });

    it('shows inline error after first Next attempt with invalid name', () => {
      expect.fail('not yet implemented');
    });

    it('accepts alphanumeric, dashes, and underscores', () => {
      expect.fail('not yet implemented');
    });

    it('rejects names with spaces or special characters', () => {
      expect.fail('not yet implemented');
    });
  });
});
```

**src/components/wizard/RemoteConfigStep.test.tsx**
```typescript
// @vitest-environment jsdom
// Covers BACK-01: Azure Blob config form — account + SAS/Key toggle, both values preserved
// Covers BACK-02: Amazon S3 config form — access_key_id, secret_access_key, region
// Covers BACK-03: S3-Compatible config form — same as S3 plus endpoint field
import { describe, it, expect } from 'vitest';

describe('RemoteConfigStep', () => {
  describe('BACK-01: Azure Blob form', () => {
    it('renders Storage Account Name field', () => {
      expect.fail('not yet implemented');
    });

    it('shows SAS URL field by default (default auth method)', () => {
      expect.fail('not yet implemented');
    });

    it('switching auth toggle to Access Key shows key field and hides SAS URL', () => {
      expect.fail('not yet implemented');
    });

    it('switching auth toggle does not clear the hidden field value', () => {
      expect.fail('not yet implemented');
    });
  });

  describe('BACK-02: Amazon S3 form', () => {
    it('renders access_key_id field', () => {
      expect.fail('not yet implemented');
    });

    it('renders secret_access_key field', () => {
      expect.fail('not yet implemented');
    });

    it('renders region field', () => {
      expect.fail('not yet implemented');
    });
  });

  describe('BACK-03: S3-Compatible form', () => {
    it('renders endpoint field in addition to S3 fields', () => {
      expect.fail('not yet implemented');
    });
  });
});
```

**src/components/wizard/StepIndicator.test.tsx**
```typescript
// @vitest-environment jsdom
// Covers WIZD-03: going back preserves remote.params; deployment options are untouched
import { describe, it, expect } from 'vitest';

describe('StepIndicator', () => {
  describe('WIZD-03: back navigation preserves state', () => {
    it('clicking a completed step dispatches SET_STEP', () => {
      expect.fail('not yet implemented');
    });

    it('clicking back to step 0 dispatches SET_REMOTE_PARAMS({}) to clear params', () => {
      expect.fail('not yet implemented');
    });

    it('clicking back to step 0 does NOT dispatch RESET (deployment preserved)', () => {
      expect.fail('not yet implemented');
    });

    it('step 0 shows as active when currentStep is 0', () => {
      expect.fail('not yet implemented');
    });

    it('completed steps are clickable', () => {
      expect.fail('not yet implemented');
    });
  });
});
```
npx vitest run --reporter=verbose 2>&1 | tail -30 All four test files exist. Vitest runs and reports failures (RED). The failures are either "Cannot find module" (acceptable — component files not yet created) or "not yet implemented" (from expect.fail). No passing tests exist yet. vite.config.ts has jsdom environment. Run after both tasks complete: ```bash npx vitest run --reporter=verbose 2>&1 ``` Expected: Vitest runs (no "document is not defined"), tests fail RED with module-not-found or "not yet implemented" errors, suite reports failures. The key outcome is that jsdom works and tests are scaffolded.

<success_criteria>

  • vite.config.ts has test: { environment: 'jsdom', passWithNoTests: true }
  • Four test files exist under src/ with descriptive failing test names
  • npx vitest run runs without crashing the vitest process itself (failures are expected)
  • Test names directly trace to requirements (WIZD-01, WIZD-02, WIZD-03, WIZD-04, BACK-01, BACK-02, BACK-03) </success_criteria>
After completion, create `.planning/phases/03-wizard-ui/03-01-SUMMARY.md`