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
This commit is contained in:
@@ -0,0 +1,333 @@
|
||||
---
|
||||
phase: 03-wizard-ui
|
||||
plan: "01"
|
||||
type: execute
|
||||
wave: 1
|
||||
depends_on: []
|
||||
files_modified:
|
||||
- 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
|
||||
autonomous: true
|
||||
requirements:
|
||||
- WIZD-01
|
||||
- WIZD-02
|
||||
- WIZD-03
|
||||
- WIZD-04
|
||||
- BACK-01
|
||||
- BACK-02
|
||||
- BACK-03
|
||||
|
||||
must_haves:
|
||||
truths:
|
||||
- "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"
|
||||
artifacts:
|
||||
- path: "vite.config.ts"
|
||||
provides: "jsdom test environment config"
|
||||
contains: "test: { environment: 'jsdom'"
|
||||
- path: "src/App.test.tsx"
|
||||
provides: "Wave 0 stub for WIZD-02 step routing"
|
||||
- path: "src/components/wizard/BackendSelectionStep.test.tsx"
|
||||
provides: "Wave 0 stubs for WIZD-01, WIZD-04"
|
||||
- path: "src/components/wizard/RemoteConfigStep.test.tsx"
|
||||
provides: "Wave 0 stubs for BACK-01, BACK-02, BACK-03"
|
||||
- path: "src/components/wizard/StepIndicator.test.tsx"
|
||||
provides: "Wave 0 stubs for WIZD-03"
|
||||
key_links:
|
||||
- from: "vite.config.ts"
|
||||
to: "src/**/*.test.tsx"
|
||||
via: "test.environment: 'jsdom'"
|
||||
pattern: "environment.*jsdom"
|
||||
---
|
||||
|
||||
<objective>
|
||||
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 03–05 can drive to GREEN.
|
||||
Output: Updated vite.config.ts and four test stub files.
|
||||
</objective>
|
||||
|
||||
<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>
|
||||
|
||||
<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
|
||||
|
||||
<interfaces>
|
||||
<!-- Key types and contracts the executor needs. Extracted from codebase. -->
|
||||
|
||||
From src/store/types.ts:
|
||||
```typescript
|
||||
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:
|
||||
```typescript
|
||||
export type BackendType = 'azureblob' | 's3' | 's3-compatible';
|
||||
```
|
||||
|
||||
From src/store/context.tsx:
|
||||
```typescript
|
||||
export function useWizard(): WizardContextValue;
|
||||
export function WizardProvider({ children }: { children: React.ReactNode }): JSX.Element;
|
||||
```
|
||||
</interfaces>
|
||||
</context>
|
||||
|
||||
<tasks>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 1: Configure Vitest jsdom environment in vite.config.ts</name>
|
||||
<files>vite.config.ts</files>
|
||||
<action>
|
||||
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).
|
||||
</action>
|
||||
<verify>
|
||||
<automated>npx vitest run --reporter=verbose 2>&1 | head -20</automated>
|
||||
</verify>
|
||||
<done>Vitest starts without "document is not defined" errors. If no test files exist yet the suite exits 0 due to passWithNoTests: true.</done>
|
||||
</task>
|
||||
|
||||
<task type="auto">
|
||||
<name>Task 2: Create Wave 0 test stubs (RED baseline for all 7 requirements)</name>
|
||||
<files>
|
||||
src/App.test.tsx,
|
||||
src/components/wizard/BackendSelectionStep.test.tsx,
|
||||
src/components/wizard/RemoteConfigStep.test.tsx,
|
||||
src/components/wizard/StepIndicator.test.tsx
|
||||
</files>
|
||||
<action>
|
||||
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');
|
||||
});
|
||||
});
|
||||
});
|
||||
```
|
||||
</action>
|
||||
<verify>
|
||||
<automated>npx vitest run --reporter=verbose 2>&1 | tail -30</automated>
|
||||
</verify>
|
||||
<done>
|
||||
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.
|
||||
</done>
|
||||
</task>
|
||||
|
||||
</tasks>
|
||||
|
||||
<verification>
|
||||
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.
|
||||
</verification>
|
||||
|
||||
<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>
|
||||
|
||||
<output>
|
||||
After completion, create `.planning/phases/03-wizard-ui/03-01-SUMMARY.md`
|
||||
</output>
|
||||
Reference in New Issue
Block a user