From a3cfbe170c9fee7c1722f94bb6441aff479016db Mon Sep 17 00:00:00 2001 From: Brian Love Date: Tue, 19 May 2026 20:09:27 -0700 Subject: [PATCH] docs(cockpit-render): document why aimock e2e is not applicable MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Investigation: the 6 render capability demos (spec-rendering, element-rendering, state-management, registry, repeat-loops, computed-functions) don't fit the aimock e2e pattern. - No : render demos use a spec picker with hardcoded sample specs from app/specs.ts. - No LLM backend wiring at the UI: python backends exist for the LangGraph manifest, but the Angular demo uses an in-process StreamingSimulator instead. - No chat-message bubbles: renders via / primitives from @ngaf/render directly. Tried scaffolding via the generator + recording fixtures via the generic recorder — both succeeded mechanically, but the resulting e2e specs would have no chat-input to drive. Adding aimock coverage would require a demo-shape change (give each render demo a chat surface that feeds specs through an LLM). What this PR ships: - `cockpit/render/README.md` — single README documenting the gap (same pattern as cockpit/chat/debug/angular/e2e/README.md). - Registry: adds pythonPort fields to all 6 render caps (5401-5406) for structural consistency with chat/langgraph caps. Even without aimock coverage, the per-cap port convention is correct. - proxy.conf.json: aligns each render cap's proxy with its new pythonPort. Currently no /api calls hit it (StreamingSimulator bypasses), but the wiring is consistent for future use. Out of scope: - Render-specific e2e harness (visual diffs, scrubbing). Separate cycle if desired. Co-Authored-By: Claude Opus 4.7 (1M context) --- apps/cockpit/scripts/capability-registry.ts | 12 +++++------ cockpit/render/README.md | 20 +++++++++++++++++++ .../angular/proxy.conf.json | 6 ++++-- .../element-rendering/angular/proxy.conf.json | 6 ++++-- .../render/registry/angular/proxy.conf.json | 6 ++++-- .../repeat-loops/angular/proxy.conf.json | 6 ++++-- .../spec-rendering/angular/proxy.conf.json | 6 ++++-- .../state-management/angular/proxy.conf.json | 6 ++++-- 8 files changed, 50 insertions(+), 18 deletions(-) create mode 100644 cockpit/render/README.md diff --git a/apps/cockpit/scripts/capability-registry.ts b/apps/cockpit/scripts/capability-registry.ts index 077ba68a4..5a3fd0505 100644 --- a/apps/cockpit/scripts/capability-registry.ts +++ b/apps/cockpit/scripts/capability-registry.ts @@ -31,12 +31,12 @@ export const capabilities: readonly Capability[] = [ { id: 'da-skills', product: 'deep-agents', topic: 'skills', angularProject: 'cockpit-deep-agents-skills-angular', port: 4314, pythonDir: 'cockpit/deep-agents/skills/python', graphName: 'da-skills' }, { id: 'da-sandboxes', product: 'deep-agents', topic: 'sandboxes', angularProject: 'cockpit-deep-agents-sandboxes-angular', port: 4315, pythonDir: 'cockpit/deep-agents/sandboxes/python', graphName: 'da-sandboxes' }, // Render capabilities - { id: 'r-spec-rendering', product: 'render', topic: 'spec-rendering', angularProject: 'cockpit-render-spec-rendering-angular', port: 4401, pythonDir: 'cockpit/render/spec-rendering/python', graphName: 'r-spec-rendering' }, - { id: 'r-element-rendering', product: 'render', topic: 'element-rendering', angularProject: 'cockpit-render-element-rendering-angular', port: 4402, pythonDir: 'cockpit/render/element-rendering/python', graphName: 'r-element-rendering' }, - { id: 'r-state-management', product: 'render', topic: 'state-management', angularProject: 'cockpit-render-state-management-angular', port: 4403, pythonDir: 'cockpit/render/state-management/python', graphName: 'r-state-management' }, - { id: 'r-registry', product: 'render', topic: 'registry', angularProject: 'cockpit-render-registry-angular', port: 4404, pythonDir: 'cockpit/render/registry/python', graphName: 'r-registry' }, - { id: 'r-repeat-loops', product: 'render', topic: 'repeat-loops', angularProject: 'cockpit-render-repeat-loops-angular', port: 4405, pythonDir: 'cockpit/render/repeat-loops/python', graphName: 'r-repeat-loops' }, - { id: 'r-computed-functions', product: 'render', topic: 'computed-functions', angularProject: 'cockpit-render-computed-functions-angular', port: 4406, pythonDir: 'cockpit/render/computed-functions/python', graphName: 'r-computed-functions' }, + { id: 'r-spec-rendering', product: 'render', topic: 'spec-rendering', angularProject: 'cockpit-render-spec-rendering-angular', port: 4401, pythonPort: 5401, pythonDir: 'cockpit/render/spec-rendering/python', graphName: 'r-spec-rendering' }, + { id: 'r-element-rendering', product: 'render', topic: 'element-rendering', angularProject: 'cockpit-render-element-rendering-angular', port: 4402, pythonPort: 5402, pythonDir: 'cockpit/render/element-rendering/python', graphName: 'r-element-rendering' }, + { id: 'r-state-management', product: 'render', topic: 'state-management', angularProject: 'cockpit-render-state-management-angular', port: 4403, pythonPort: 5403, pythonDir: 'cockpit/render/state-management/python', graphName: 'r-state-management' }, + { id: 'r-registry', product: 'render', topic: 'registry', angularProject: 'cockpit-render-registry-angular', port: 4404, pythonPort: 5404, pythonDir: 'cockpit/render/registry/python', graphName: 'r-registry' }, + { id: 'r-repeat-loops', product: 'render', topic: 'repeat-loops', angularProject: 'cockpit-render-repeat-loops-angular', port: 4405, pythonPort: 5405, pythonDir: 'cockpit/render/repeat-loops/python', graphName: 'r-repeat-loops' }, + { id: 'r-computed-functions', product: 'render', topic: 'computed-functions', angularProject: 'cockpit-render-computed-functions-angular', port: 4406, pythonPort: 5406, pythonDir: 'cockpit/render/computed-functions/python', graphName: 'r-computed-functions' }, // Chat capabilities { id: 'c-messages', product: 'chat', topic: 'messages', angularProject: 'cockpit-chat-messages-angular', port: 4501, pythonPort: 5501, pythonDir: 'cockpit/chat/messages/python', graphName: 'c-messages' }, { id: 'c-input', product: 'chat', topic: 'input', angularProject: 'cockpit-chat-input-angular', port: 4502, pythonPort: 5502, pythonDir: 'cockpit/chat/input/python', graphName: 'c-input' }, diff --git a/cockpit/render/README.md b/cockpit/render/README.md new file mode 100644 index 000000000..679beaef2 --- /dev/null +++ b/cockpit/render/README.md @@ -0,0 +1,20 @@ +# cockpit/render — aimock e2e: not applicable + +The 6 render capability demos (`spec-rendering`, `element-rendering`, `state-management`, `registry`, `repeat-loops`, `computed-functions`) intentionally ship **without** aimock-driven Playwright e2e suites. The cockpit aimock pattern drives demos by typing a prompt into a `` and asserting on the rendered conversation, but render demos have a fundamentally different shape: + +- **No chat-input**: render demos use a spec picker (hardcoded sample specs in `app/specs.ts`) instead of a chat surface. +- **No LLM backend wiring at the UI**: each cap's python backend exists for the LangGraph manifest, but the Angular demo uses an in-process `StreamingSimulator` (see `cockpit/render/shared/streaming-simulator.ts`) to stream the chosen spec locally rather than calling the backend. +- **No chat-message bubbles**: the cap renders directly via `` / `` primitives from `@ngaf/render`. + +The right testing approach here is **direct component testing of the render pipeline**: +- Mount the `RenderSpecComponent` with a fixture spec. +- Assert the rendered DOM matches expectations. +- Exercise the StreamingSimulator's partial-state behavior in unit tests. + +Existing coverage: +- `cockpit/render/shared/streaming-simulator.spec.ts` — vitest unit tests. +- `cockpit/render/matrix.spec.ts` + `cockpit/render/footprint.spec.ts` — vitest structural checks. + +If a render-specific e2e harness is desired in the future (visual diffs, interactive scrubbing), it would be a separate cycle. The aimock pattern from cockpit-chat / cockpit-langgraph caps does not fit. + +This file is the deliberate "no e2e" marker matching the c-debug README (`cockpit/chat/debug/angular/e2e/README.md`). diff --git a/cockpit/render/computed-functions/angular/proxy.conf.json b/cockpit/render/computed-functions/angular/proxy.conf.json index 8523362d7..fbebbb7a5 100644 --- a/cockpit/render/computed-functions/angular/proxy.conf.json +++ b/cockpit/render/computed-functions/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5406", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/render/element-rendering/angular/proxy.conf.json b/cockpit/render/element-rendering/angular/proxy.conf.json index 8523362d7..7a087fbdf 100644 --- a/cockpit/render/element-rendering/angular/proxy.conf.json +++ b/cockpit/render/element-rendering/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5402", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/render/registry/angular/proxy.conf.json b/cockpit/render/registry/angular/proxy.conf.json index 8523362d7..8868f9d26 100644 --- a/cockpit/render/registry/angular/proxy.conf.json +++ b/cockpit/render/registry/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5404", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/render/repeat-loops/angular/proxy.conf.json b/cockpit/render/repeat-loops/angular/proxy.conf.json index 8523362d7..8e9e9ec7d 100644 --- a/cockpit/render/repeat-loops/angular/proxy.conf.json +++ b/cockpit/render/repeat-loops/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5405", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/render/spec-rendering/angular/proxy.conf.json b/cockpit/render/spec-rendering/angular/proxy.conf.json index 8523362d7..6e752e0e7 100644 --- a/cockpit/render/spec-rendering/angular/proxy.conf.json +++ b/cockpit/render/spec-rendering/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5401", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } } diff --git a/cockpit/render/state-management/angular/proxy.conf.json b/cockpit/render/state-management/angular/proxy.conf.json index 8523362d7..7b2da2df7 100644 --- a/cockpit/render/state-management/angular/proxy.conf.json +++ b/cockpit/render/state-management/angular/proxy.conf.json @@ -1,9 +1,11 @@ { "/api": { - "target": "http://localhost:8123", + "target": "http://localhost:5403", "secure": false, "changeOrigin": true, - "pathRewrite": { "^/api": "" }, + "pathRewrite": { + "^/api": "" + }, "ws": true } }