|
| 1 | +# Frontend UI Matrix Rationalization Plan |
| 2 | + |
| 3 | +This plan tracks how to reduce redundant UI matrix coverage now that the app page and generator page share much more of the same component structure. |
| 4 | + |
| 5 | +The earlier matrix work was valuable when the app-hosted test-data panel and the standalone generator UI had meaningfully different implementations. After the component migration, broad app-vs-generator scenario sweeps now provide less unique signal and more duplicated maintenance cost. The goal of this plan is to keep the useful coverage while retiring the parts that mostly re-test shared components through two different shells. |
| 6 | + |
| 7 | +Use this document with: |
| 8 | + |
| 9 | +- `docs/frontend-component-architecture.md` |
| 10 | +- `docs/frontend-component-migration-plan.md` |
| 11 | +- `docs/frontend-legacy-ui-elimination-plan.md` |
| 12 | +- `AGENTS.md` |
| 13 | + |
| 14 | +## Recommended Sequencing |
| 15 | + |
| 16 | +Do not treat matrix rationalization as a reason to pause the active component refactor. The recommended order is: |
| 17 | + |
| 18 | +1. Continue component refactoring and legacy UI elimination first. |
| 19 | +2. Perform only a narrow matrix triage while that refactor is still active. |
| 20 | +3. Perform the full matrix rationalization after the shared app/generator component boundaries are more stable. |
| 21 | +4. Finish with a comprehensive coverage review. |
| 22 | + |
| 23 | +Why this order: |
| 24 | + |
| 25 | +- the right matrix shape depends on where shared behavior finally lives |
| 26 | +- broad parity cleanup done too early will likely need to be revisited as feature boundaries keep moving |
| 27 | +- the highest-value work is still removing legacy UI structure and stabilizing shared components |
| 28 | +- matrix cleanup is more accurate once the remaining page-specific differences are smaller and easier to see |
| 29 | + |
| 30 | +## What To Do Now vs Later |
| 31 | + |
| 32 | +Do now: |
| 33 | + |
| 34 | +- fix or quarantine clearly broken high-noise matrix failures that block routine work |
| 35 | +- avoid adding new broad app-vs-generator parity scenarios |
| 36 | +- document which current matrix suites are likely to shrink later |
| 37 | + |
| 38 | +Do later: |
| 39 | + |
| 40 | +- redesign the retained parity contract |
| 41 | +- move duplicated assertions to component tests |
| 42 | +- shrink or retire broad JSDOM app/generator parity sweeps |
| 43 | +- simplify matrix harnesses after retained coverage is known |
| 44 | + |
| 45 | +## Goal |
| 46 | + |
| 47 | +Keep high-signal automated coverage for: |
| 48 | + |
| 49 | +- shared component behavior |
| 50 | +- page-specific wiring and defaults |
| 51 | +- runtime data-generation semantics |
| 52 | +- real browser workflows |
| 53 | + |
| 54 | +Reduce or remove low-signal automated coverage that: |
| 55 | + |
| 56 | +- runs the same shared schema/test-data behavior through both app and generator shells |
| 57 | +- repeats component behavior already covered by controller, DOM, and browser tests |
| 58 | +- creates expensive parity suites whose failures are hard to interpret |
| 59 | + |
| 60 | +## Target Standard |
| 61 | + |
| 62 | +The frontend test stack should follow these rules: |
| 63 | + |
| 64 | +- Shared component behavior is tested once at the component level, not re-proved through large cross-page matrices. |
| 65 | +- Page-specific composition is tested at the page level with focused integration coverage. |
| 66 | +- Runtime scenario semantics are tested at the engine/runtime layer without depending on page-shell duplication. |
| 67 | +- Browser behavior is tested with Playwright for workflows that need a real browser, real layout, downloads, focus, or page wiring. |
| 68 | +- Cross-page parity tests exist only where the app page and generator page still have genuinely different composition or service boundaries. |
| 69 | +- Large JSDOM matrices are allowed only when they verify behavior that cannot be covered more directly by component, runtime, or browser tests. |
| 70 | + |
| 71 | +## Current State |
| 72 | + |
| 73 | +Current matrix suites under `packages/core-ui/src/tests/interaction/matrix/` cover three different concerns: |
| 74 | + |
| 75 | +- `schema-interaction-runtime-matrix.test.js` |
| 76 | + - scenario execution against the runtime/data-generation layer |
| 77 | +- `generator-schema-interaction-matrix.test.js` |
| 78 | + - standalone generator UI scenario execution in JSDOM |
| 79 | +- `app-schema-interaction-matrix.test.js` |
| 80 | + - embedded app test-data panel scenario execution in JSDOM |
| 81 | +- `ui-schema-interaction-parity.test.js` |
| 82 | + - parity comparison between app and generator scenario outputs |
| 83 | + |
| 84 | +The current issue is not that matrix coverage is useless. The issue is that the app/generator UI and parity matrices now overlap heavily with shared component tests and browser flows, while still being expensive and brittle. |
| 85 | + |
| 86 | +## Keep / Reduce / Remove Guidance |
| 87 | + |
| 88 | +Keep: |
| 89 | + |
| 90 | +- runtime scenario matrix coverage that validates scenario execution semantics |
| 91 | +- focused browser workflows for app and generator pages |
| 92 | +- shared component controller and DOM tests |
| 93 | + |
| 94 | +Reduce: |
| 95 | + |
| 96 | +- broad JSDOM app and generator scenario sweeps that duplicate shared component behavior |
| 97 | +- broad parity comparison across many scenarios where both pages now exercise the same shared internals |
| 98 | + |
| 99 | +Remove when replacement coverage is in place: |
| 100 | + |
| 101 | +- app-vs-generator parity checks that only prove shared component output equality |
| 102 | +- duplicate scenario coverage that can be expressed more clearly as component tests or a small smoke parity set |
| 103 | + |
| 104 | +## Phase 0: Immediate Matrix Triage |
| 105 | + |
| 106 | +Goal: keep the current matrix suite from creating avoidable day-to-day drag while the component refactor continues. |
| 107 | + |
| 108 | +- [ ] Identify matrix failures that are clearly broken or noisy rather than behaviorally useful. |
| 109 | +- [ ] Fix, quarantine, skip, or isolate those failures only where needed to keep normal frontend work moving. |
| 110 | +- [ ] Avoid broad rewrites of the matrix suites during this phase. |
| 111 | +- [ ] Mark likely shrink/remove candidates in the affected test files or follow-up tracking docs. |
| 112 | + |
| 113 | +Exit criteria: |
| 114 | + |
| 115 | +- The matrix suite is no longer a disproportionate source of noise for unrelated frontend changes. |
| 116 | +- We have not spent component-refactor time prematurely redesigning the whole matrix layer. |
| 117 | + |
| 118 | +## Phase 1: Coverage Inventory And Classification |
| 119 | + |
| 120 | +Goal: make each current matrix test justify its existence in the new shared-component architecture. |
| 121 | + |
| 122 | +- [ ] List every current matrix suite and classify its purpose as runtime semantics, shared component behavior, page wiring, or cross-page parity. |
| 123 | +- [ ] Map each scenario assertion to the lowest sensible layer: runtime, component, page integration, or browser. |
| 124 | +- [ ] Mark each current matrix assertion as keep, move, shrink, or retire. |
| 125 | +- [ ] Identify current failures and instability causes separately from redundancy concerns, so cleanup decisions are not driven only by flakiness. |
| 126 | + |
| 127 | +Exit criteria: |
| 128 | + |
| 129 | +- Every matrix suite has a clear purpose statement and a proposed target size. |
| 130 | +- We know which assertions are still unique and which are duplicate coverage. |
| 131 | + |
| 132 | +## Phase 2: Define The Replacement Coverage Model |
| 133 | + |
| 134 | +Goal: agree what should live at each test layer before deleting broad matrix coverage. |
| 135 | + |
| 136 | +- [ ] Define the minimum shared-component test expectations for schema editing, schema/text sync, command selection, preview generation, pairwise availability, and output-format interactions. |
| 137 | +- [ ] Define the minimum page-level integration expectations for the app-hosted panel and standalone generator shell. |
| 138 | +- [ ] Define the minimum browser workflows that must remain for app and generator pages. |
| 139 | +- [ ] Define the minimum cross-page parity contract that still matters after component reuse. |
| 140 | + |
| 141 | +Recommended standard: |
| 142 | + |
| 143 | +- Shared behavior belongs in controller and DOM/component tests. |
| 144 | +- Page-shell behavior belongs in focused app/generator integration tests. |
| 145 | +- Real browser workflows belong in Playwright. |
| 146 | +- Cross-page parity should be reduced to a small representative contract, not a broad scenario sweep. |
| 147 | + |
| 148 | +Exit criteria: |
| 149 | + |
| 150 | +- There is a documented target layer for every major test-data behavior. |
| 151 | +- We have a replacement destination for any matrix assertion we plan to remove. |
| 152 | + |
| 153 | +## Phase 3: Shrink Cross-Page Parity To A Representative Contract |
| 154 | + |
| 155 | +Goal: keep only the parity checks that still prove something unique. |
| 156 | + |
| 157 | +- [ ] Replace the large `ui-schema-interaction-parity.test.js` sweep with a much smaller representative parity set. |
| 158 | +- [ ] Keep scenarios only for composition points that can still diverge between app and generator. |
| 159 | +- [ ] Prefer exact parity checks for a few canonical scenarios rather than structural parity checks for many scenarios. |
| 160 | +- [ ] Remove parity cases that merely re-prove shared component output through both shells. |
| 161 | + |
| 162 | +Candidate parity survivors: |
| 163 | + |
| 164 | +- one simple literal/regex scenario |
| 165 | +- one faker/domain command scenario |
| 166 | +- one pairwise-eligible scenario |
| 167 | +- one structured serialization scenario |
| 168 | +- one page-default/options scenario if app and generator still configure it differently |
| 169 | + |
| 170 | +Exit criteria: |
| 171 | + |
| 172 | +- Cross-page parity coverage is small, fast, and easy to interpret. |
| 173 | +- Failing parity tests point to real app-vs-generator divergence, not broad duplicated behavior. |
| 174 | + |
| 175 | +## Phase 4: Move Shared Behavior Coverage Down To Components |
| 176 | + |
| 177 | +Goal: test shared behavior where it lives now. |
| 178 | + |
| 179 | +- [ ] Add or strengthen controller tests for shared schema logic, generation controls, row-count behavior, and option application. |
| 180 | +- [ ] Add or strengthen DOM/component tests for row editing, schema/text sync, preview triggers, pairwise visibility, and error/status rendering. |
| 181 | +- [ ] Ensure component tests cover the shared behavior previously only exercised through app/generator matrix scenarios. |
| 182 | + |
| 183 | +Exit criteria: |
| 184 | + |
| 185 | +- Shared behavior no longer depends on app/generator matrix suites for primary protection. |
| 186 | +- A contributor can understand a failure by reading the relevant component test rather than a large matrix harness log. |
| 187 | + |
| 188 | +## Phase 5: Keep Focused Page-Level Integration Coverage |
| 189 | + |
| 190 | +Goal: preserve coverage for the parts that are still page-specific. |
| 191 | + |
| 192 | +- [ ] Keep a small app integration suite for embedded test-data panel wiring. |
| 193 | +- [ ] Keep a small generator integration suite for standalone generator-shell wiring. |
| 194 | +- [ ] Remove scenario cases from those suites that only duplicate shared component behavior with no page-specific value. |
| 195 | +- [ ] Ensure page-level integration tests focus on mount wiring, service composition, and page defaults. |
| 196 | + |
| 197 | +Exit criteria: |
| 198 | + |
| 199 | +- The app suite proves the embedded panel wiring still works. |
| 200 | +- The generator suite proves the standalone generator workflow still works. |
| 201 | +- Neither suite acts as a hidden replacement for missing component tests. |
| 202 | + |
| 203 | +## Phase 6: Confirm Real Browser Coverage |
| 204 | + |
| 205 | +Goal: make sure any removed matrix coverage is backed by real browser confidence where needed. |
| 206 | + |
| 207 | +- [ ] Audit existing Playwright app test-data flows under `apps/web/src/tests/browser/app/functional/test-data/`. |
| 208 | +- [ ] Audit existing Playwright generator flows under `apps/web/src/tests/browser/generator/functional/`. |
| 209 | +- [ ] Add or tighten browser coverage only where the removed matrix tests were covering true page/browser behavior. |
| 210 | +- [ ] Do not recreate large scenario matrices in Playwright; keep browser coverage workflow-focused. |
| 211 | + |
| 212 | +Exit criteria: |
| 213 | + |
| 214 | +- Real browser workflows still cover the user-visible paths that matter. |
| 215 | +- Playwright remains focused on browser behavior, not exhaustive scenario enumeration. |
| 216 | + |
| 217 | +## Phase 7: Simplify Or Retire Matrix Harnesses |
| 218 | + |
| 219 | +Goal: reduce maintenance overhead in the test infrastructure itself. |
| 220 | + |
| 221 | +- [ ] Remove harness code that exists only for broad parity sweeps no longer required. |
| 222 | +- [ ] Simplify app/generator interaction harnesses to the smaller retained scenario sets. |
| 223 | +- [ ] Delete helper utilities and fixture complexity that no longer serve a retained suite. |
| 224 | +- [ ] Update contributor docs so the intended role of runtime matrix, component tests, and browser tests is explicit. |
| 225 | + |
| 226 | +Exit criteria: |
| 227 | + |
| 228 | +- The harness layer is easier to understand and cheaper to maintain. |
| 229 | +- New contributors are not pushed toward adding more broad parity scenarios by default. |
| 230 | + |
| 231 | +## Phase 8: Comprehensive Review |
| 232 | + |
| 233 | +Goal: verify that rationalization removed duplication without creating blind spots. |
| 234 | + |
| 235 | +- [ ] Review all retained runtime, component, page-integration, Storybook, and browser coverage for schema/test-data behavior. |
| 236 | +- [ ] Check whether any behavior still depends on broad JSDOM matrix tests as its only protection. |
| 237 | +- [ ] Check whether any remaining parity tests still provide unique signal. |
| 238 | +- [ ] Decide whether more parity reduction is safe, or whether a small additional representative case should remain. |
| 239 | +- [ ] Update this plan and the migration docs with final status and any follow-up actions. |
| 240 | + |
| 241 | +Exit criteria: |
| 242 | + |
| 243 | +- The remaining automated coverage is intentionally layered and non-duplicative. |
| 244 | +- Any remaining matrix coverage has a clear reason to exist. |
| 245 | +- Follow-up work, if any, is captured explicitly rather than left as tribal knowledge. |
| 246 | + |
| 247 | +## Definition Of Done For This Rationalization |
| 248 | + |
| 249 | +This plan is complete when: |
| 250 | + |
| 251 | +- broad duplicated app-vs-generator parity coverage has been reduced to a small intentional contract |
| 252 | +- shared behavior is primarily covered by component tests |
| 253 | +- page-specific behavior is primarily covered by focused integration and browser tests |
| 254 | +- runtime semantics remain covered independently of page-shell duplication |
| 255 | +- the remaining matrix suites are fast enough, stable enough, and clear enough to justify their cost |
| 256 | + |
| 257 | +## Suggested First Slice |
| 258 | + |
| 259 | +The safest first implementation slice is: |
| 260 | + |
| 261 | +1. Complete Phase 0 and Phase 1 as a paper audit. |
| 262 | +2. Complete Phase 2 as the replacement coverage model. |
| 263 | +3. Shrink `ui-schema-interaction-parity.test.js` to a representative subset. |
| 264 | +4. Keep the runtime matrix unchanged. |
| 265 | +5. Re-run coverage review before shrinking the app and generator JSDOM matrices. |
| 266 | + |
| 267 | +That path removes the most obvious duplication first while preserving the highest-signal runtime coverage. |
0 commit comments