You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
description: Run startup sequence (steps 1-6 from docs/WORKFLOW.md)
3
+
description: Run startup sequence and pick a story from the Jira epic
4
4
---
5
5
6
6
# Session Onboard
7
7
8
-
Execute the startup sequence from `docs/WORKFLOW.md`. AGENTS.md is always in context — no need to read it explicitly.
9
-
10
8
## Steps
11
9
12
10
1.**Confirm working directory** — run `pwd`.
@@ -17,8 +15,10 @@ Execute the startup sequence from `docs/WORKFLOW.md`. AGENTS.md is always in con
17
15
```
18
16
19
17
3.**Check struggles** — read `docs/agent-struggles.json`. If unresolved entries exist, present to user.
20
-
4.**Pick feature** — read `docs/features.json`, find first `"passes": false` entry.
21
-
5.**Start dev env** — run `./init.sh`.
22
-
6.**Read ports** — read `.dev-env.json` and note the backend, plugin, and console ports.
23
-
7.**Run tests** — run `yarn test` and verify app is healthy.
24
-
8.**Wait** — tell the user you're oriented, report the picked feature and which step of the Feature Development Sequence you'd start at. When the user says to proceed, follow the Feature Development Sequence in `docs/WORKFLOW.md` step by step. Do NOT start any work autonomously.
18
+
4.**CI check** — run `yarn ci` (lint, test, build) and verify the project is healthy.
19
+
5.**Start dev env** — run `./init.sh`. If it fails (e.g. nono sandbox blocks `oc`), tell the user to start it manually from their terminal.
20
+
6.**Read ports** — read `.dev-env.json` and note the backend, plugin, and console ports. If init.sh failed, skip this step.
21
+
7.**Pick story** — tell the user you're oriented and propose picking a story from the PoC epic: <https://redhat.atlassian.net/browse/SRVOCF-810>. Ask the user to provide the story description (title, acceptance criteria, or a Jira link). The user may pick one story or a few small ones.
22
+
8.**Create feature entry** — once the user provides a story, create a new entry in `docs/features.json` for it (append to the array, `"passes": false`).
23
+
9.**Branch** — create a feature branch per [Branching](docs/WORKFLOW.md#branching) convention and open a draft PR (`gh pr create --draft`).
24
+
10.**Propose planning** — tell the user the branch is ready and propose to start planning (step 2 of the Feature Development Sequence in `docs/WORKFLOW.md`). Do NOT start any work autonomously.
-Views never import Services directly (always through Hooks)
39
-
- Services never import Components or Views
38
+
-Pages never import Services directly (always through Hooks)
39
+
- Services never import Components or Pages
40
40
- No circular dependencies
41
41
42
+
### Co-location Convention
43
+
44
+
-`src/pages/<name>/` contains the page component, its test, and a `components/` subdir
45
+
-`src/pages/<name>/components/` contains components used only by that page
46
+
-`src/common/` contains everything shared across pages (components, services, utils, context)
47
+
-**Ownership rule:** if a component is imported by only one page (test imports don't count), it lives in `pages/<name>/components/`. If imported by multiple pages, it lives in `common/components/`.
48
+
42
49
## React
43
50
44
-
### Page / Component / Hook Rules
51
+
### Pages
52
+
53
+
-**Smart for page-specific data** — pages use central hooks (e.g. `useClusterService`, `useSourceControl`) to fetch, prepare, and transform all data needed for downstream components.
54
+
55
+
### Components
45
56
46
-
**Components are simple by default** — they receive data via props, render it, and call callbacks. No logic at the top of a component.
57
+
-**Simple by default** — they receive data via props, render it, and call callbacks. No logic at the top of a component.
58
+
-**May own data when self-contained** — a component may own its own data and state when it encapsulates a self-contained capability that is not specific to any one page (e.g., forge connection, auth flows, notification subscriptions). The component becomes the single owner of that concern. Pages consume it without orchestrating its internals.
59
+
-**Sub-components** — if a sub-component is only used by one parent, keep it in the parent's file, unexported. Extract to its own file only when the sub-component is used by multiple siblings.
47
60
48
-
**A component may own its own data and state when it encapsulates a self-contained capability that is not specific to any one page** (e.g., forge connection, auth flows, notification subscriptions). The component becomes the single owner of that concern. Pages consume it without orchestrating its internals.
61
+
### Hooks
49
62
50
-
**Pages are smart for page-specific data** — they use central hooks (e.g. `useClusterService`, `useSourceControl`) to fetch, prepare, and transform all data needed for downstream components.
63
+
-**Extract logic into hooks** — if a page or component has any logic (state management, data transformation, side effects), extract it into a custom hook. If the hook is only used by one component, keep it in the same file, do not export it. If the hook is reused by multiple components within one page, put it in `src/pages/<name>/hooks/`. If reused across pages, put it in `src/common/hooks/`. If there is no logic, no hook is needed.
51
64
52
-
**Extract logic into hooks** — if a page or component has any logic (state management, data transformation, side effects), extract it into a custom hook. If the hook is reused by multiple components, put it in a separate file: `useFunctionTable.ts`. If the hook is only used by one component, keep it in the same file, do not export it. If there is no logic, no hook is needed.
65
+
### File Ordering
53
66
54
-
**File ordering** — within a file, put the exported component at the top, then its hook below, then helper functions at the bottom. Readers see the main thing first and can drill down.
67
+
Within a file, put the exported component at the top, then its hook below, then sub-components, then helper functions at the bottom. Readers see the main thing first and can drill down.
55
68
56
69
### Performance
57
70
@@ -60,6 +73,7 @@ Arrows mean "imports / depends on."
60
73
## Architectural Guidance
61
74
62
75
- PatternFly components preferred over custom HTML
76
+
- PatternFly styling and styling rules over custom CSS
63
77
- Error handling through ErrorProvider/addError pattern
64
-
- Shared utilities in `utils/`, not hand-rolled per component
78
+
- Shared utilities in `common/utils/`, not hand-rolled per component
65
79
- Services consumed through hooks, never imported directly
Copy file name to clipboardExpand all lines: docs/TESTING.md
+51-20Lines changed: 51 additions & 20 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -15,23 +15,31 @@ Do NOT write all test cases first and then implement everything at once.
15
15
16
16
| Layer | Tool | Scope |
17
17
|-------|------|-------|
18
-
| Unit / Component |Jest + React Testing Library | Hooks, services, component rendering, form logic |
18
+
| Unit / Component |Vitest + React Testing Library | Hooks, services, component rendering, form logic |
19
19
| E2e / Feature validation | Cypress | Validate features.json entries in real browser |
20
20
| API mocking | MSW (Mock Service Worker) | GitHub API + K8s API — mock everything first, real cluster later |
21
21
22
22
## Mock Strategy
23
23
24
-
Use MSW for all API mocking (GitHub + K8s). If SDK hooks require module-level mocks in unit tests (because they depend on Console runtime internals), fall back to Jest mocks — but try MSW first.
24
+
MSW is the primary mocking strategy for anything that hits the network (GitHub API, K8s API, Go backend). K8s API mocking uses MSW WebSocket capability.
25
25
26
-
-**Start:** Mock everything via MSW (GitHub API, K8s API)
27
-
-**Later:** Real cluster for e2e — SDK hooks work natively, GitHub API remains mocked
28
-
-**Fallback:** If SDK hooks can't be driven by MSW alone in unit tests, use Jest module mocks
26
+
`vi.mock` is only for framework and library internals that have no external service:
27
+
28
+
-`react-i18next` (translation hook)
29
+
-`@openshift-console/dynamic-plugin-sdk` (console shell runtime components like DocumentTitle, ListPageHeader, consoleFetchJSON)
30
+
-`@patternfly/react-icons` (UI library)
31
+
-`react-router-dom-v5-compat` (framework routing)
32
+
-`libsodium-wrappers` (WASM crypto library)
33
+
34
+
If it makes an HTTP or WebSocket call, mock it with MSW, not `vi.mock`.
29
35
30
36
## File Conventions
31
37
32
38
| Type | Location |
33
39
|------|----------|
34
-
| Unit / Component tests |`src/**/*.test.ts\|tsx`|
| User flows | E2e | Create form → submit → list shows new function |
47
55
56
+
## Component vs. Page Tests
57
+
58
+
Every component gets its own exhaustive test file. Every page gets its own test file that tests the page's orchestration and integration with its components.
59
+
60
+
**Component tests** cover:
61
+
62
+
- Rendering based on props (all states and variants)
63
+
- User interactions that trigger callbacks (clicks, input, form validation)
64
+
- Internal state (expand/collapse, selection)
65
+
66
+
**Page tests** cover:
67
+
68
+
- Component is present on the page and wired correctly
69
+
- Data flows from hooks/services to components (correct props)
70
+
- User actions that trigger cross-component effects or service calls (e.g., form submit calls service, then navigates)
71
+
- Page-level states: loading, error, empty
72
+
73
+
Overlap between component tests and page tests is expected and acceptable. They test at different levels: component tests verify the component works in isolation, page tests verify the page's orchestration logic works correctly.
74
+
48
75
## Testing Best Practices
49
76
50
77
1.**User-Centric Testing** — Test what users see and interact with.
@@ -61,50 +88,54 @@ Use MSW for all API mocking (GitHub + K8s). If SDK hooks require module-level mo
61
88
-**Act:** Perform user actions
62
89
-**Assert:** Verify expected state
63
90
91
+
6.**Scoping** — Place beforeEach, afterEach, and afterAll inside describe blocks.
92
+
64
93
## Mocking Patterns
65
94
95
+
MSW is the primary approach. `vi.mock` is rare (see Mock Strategy above).
96
+
66
97
Use ESM `import` at top of file. Never use `require('react')` or `React.createElement()` in mocks.
67
-
Prefer `jest.mock()` for modules, `jest.fn()` for components. Keep mocks simple.
98
+
Keep mocks simple.
68
99
69
-
**Correct patterns:**
100
+
**Correct patterns (for the rare `vi.mock` cases):**
3. Read `docs/agent-struggles.json` — if unresolved entries exist, present to user
10
-
4. Read `docs/features.json` — pick first `"passes": false` entry
11
-
5. Run `./init.sh` — start dev env
12
-
6. Read `.dev-env.json` — note the dev server ports (backend, plugin, console)
13
-
7. Run tests — verify app is healthy
14
-
8. If broken → fix first. If clean → start [Feature Development Sequence](#feature-development-sequence).
5
+
Handled by the `init-session` command (`.claude/commands/init-session.md`).
15
6
16
7
## Feature Development Sequence
17
8
18
9
After [Startup Sequence](#startup-sequence), work through the picked feature:
19
10
20
-
1.**Plan** — read `docs/ARCHITECTURE.md` + `docs/STYLEGUIDE.md` + `docs/TESTING.md`, then use `/brainstorming` to design the chosen feature from `docs/features.json`, then use `/writing-plans` to create implementation plan → `docs/plans/active/<NNN>-<type>-<short-name>.md`
21
-
2.**Branch** — create feature branch per [Branching](#branching) convention. Immediately push and open a **draft PR** (`gh pr create --draft`) to reserve the PR number for other contributors' branch numbering.
11
+
1.**Branch** — create feature branch per [Branching](#branching) convention. Immediately push and open a **draft PR** (`gh pr create --draft`) to reserve the PR number for other contributors' branch numbering.
12
+
2.**Plan** — read `docs/ARCHITECTURE.md` + `docs/STYLEGUIDE.md` + `docs/TESTING.md`, then use `/brainstorming` to design the chosen feature from `docs/features.json`, then use `/writing-plans` to create implementation plan → `docs/plans/active/<NNN>-<type>-<short-name>.md`
22
13
3.**Implement** — using `/executing-plans` skill
23
14
4.**Review** — code review using `/requesting-code-review` skill, fix found issues
24
15
5.**Manual Test** — use browser automation and validate it works in the browser
Worked on: Restructure src/ into pages/ and common/, update workflow and docs
27
+
Completed:
28
+
- Updated .pi/prompts/init-session.md and docs/WORKFLOW.md: dropped old step 4 (pick from features.json), added Jira epic story selection flow, swapped Feature Dev steps 1 and 2 (Branch before Plan), removed duplicate startup sequence from WORKFLOW.md
29
+
- Created features.json entry for SRVOCF-845, branch 031-refactor-page-colocation, draft PR #31
30
+
- Moved all shared code to src/common/ (services, utils, context, UserAvatar)
31
+
- Moved pages to src/pages/function-list/, function-create/, function-edit/ with components/ subdirs
32
+
- Extracted EditToolbar and LeaveModal from FunctionEditPage into separate files
33
+
- Updated package.json exposedModules paths
34
+
- Updated ARCHITECTURE.md with co-location convention and ownership rule
35
+
- Updated TESTING.md: component vs. page test rules, Vitest/MSW migration, updated file conventions
0 commit comments