Skip to content

test(e2e): V36ez interactive-control coverage batch + MOGA envelope fix (B62wp) - #742

Open
JavierGOrdonnez wants to merge 2 commits into
jgo/fe-download-buttons-79from
jgo/e2e-testid-coverage-83
Open

JavierGOrdonnez wants to merge 2 commits into
jgo/fe-download-buttons-79from
jgo/e2e-testid-coverage-83

Conversation

@JavierGOrdonnez

@JavierGOrdonnez JavierGOrdonnez commented Oct 15, 2026 •

Copy link
Copy Markdown
Collaborator

What

Closes the first (largest coherent) batch of the V36ez interactive-control audit tracked in JavierGOrdonnez#83 — the gap table (every mmux-testid in node/src × e2e assertion × triggered-state baseline) is posted as a comment on that issue.

New tests/e2e/interactive-controls.spec.ts (3 tests, 19 new baselines) triggers the controls the pixel suites reach but never operate, highest-priority first:

  • Toggles: all 4 correlation toggle ids (correlation-view-toggle + Pearson/Spearman, correlation-scale-toggle + Linear/abslog) and all 6 Sobol' ids (First/Second/Total × Linear/Log) get aria-pressed triggered-state asserts + baselines; moga-pareto-display-scale-x/-z via a 3-objective MOGA run (y, y2 and strictly-positive y4 — deliberately not y3 whose sin+cos span keeps its log gate closed) driven into the 3D view through the Plot Settings modal (the only path that raises the dimension); surrogate-scale-{output} LOG lock with the surrogate-scale-provenance-* = "manual" chip assert + element baseline.
  • Refresh: refresh-job-collections-btn (zero coverage before) — forced refetch response asserted, post-refresh grid element baseline.
  • Confirm controls: add-output-var-btn modal-open baseline, confirm-add-output-btn add-objective flow; validation modal pins the one-step validation-plot-next/-back disabled contract + validation-qoi-select open-menu baseline.
  • Also: footer previous-button (disabled@setup → click → setup-view baseline), uq-plot-back ×2, distribution-form selector Normal→Uniform switch (input-block-x1-Min/Max swap + input-var-box-0 element baseline + restore), WRITE-mode flow extend-sampling-btn → panel-open baseline → refresh → new-sampling-campaign-btn accordion → lhs-number-of-sampling-points-input/lhs-seed-input fills with value asserts → LHS tab-panel element baseline (configured 12/7 + Run inside the frame), run-sampling-btn completion state (new "E2E created collection 1" COMPLETE/12 row pinned in a grid element baseline, button ⊥ stuck), Pareto-table run-sampling-btn-{rowId} render + READ-ONLY-disabled asserts.
  • Prod line: additive moga-settings-button testid on the MOGA Optimization Settings button (root §V13 — purely additive), which makes MOGAModal's 4× duplicated input-block fields reachable (count assert + modal baseline + Discard).

🐛 Found en route — MOGA results were envelope-broken on develop (B62wp / V53wp)

The 3-objective flow exposed that since the itis-sumo engine port (1fc5419), perform_moga_optimization answers wrapped ({optimizationResults: {var:[…]}} — wrapper camelCased, inner map serializer-preserved; a legacy snake_case non_dominated_indices key is still folded when present), while normalizeMogaResults still spread the top level: every results[var] lookup missed. And because the 0.1.0a10 ParetoFrontResult.data carries value columns only (no ndi metadata at all), the front is now derived in the FE as well. The 1D branch's || [] guard papered over it — the committed moga-readonly-pareto baseline silently degraded to sample-points-only + a "No rows" table — while the unguarded 2D/3D branches crashed the swallowed effect (TypeError: … 'slice') into the InsufficientDataWarning fallback.

Fix: unwrap the envelope in normalizeMogaResults (flat unit-test payloads still accepted; both ndi spellings folded) plus deriveNonDominatedIndices — the FE Pareto-front derivation (direction per objective from OutputVarSelection "minimize"/"maximize" with minimize-default, ties mutually non-dominated), unit-tested in MOGAPareto.test.tsx. Consequence: the pre-existing moga-readonly-pareto + -pareto-log-y baselines regenerate to the full render (iteration boxes + Pareto front + table rows). Node §V gains V53wp pinning the envelope + derivation contract; §B logs B62wp; the new spec pins No rows ⊥ + row Run-buttons > 0 as the executable regression guard.

Contract compliance

  • §V12: every baseline (all 44 = 25 pre-existing + 19 new; the 3 changed MOGA ones are -pareto, -pareto-log-y and -inspect-modal, the latter because its shot includes the now-populated Pareto table below the modal) regenerated ONLY inside the pinned mcr.microsoft.com/playwright:v1.64.0-noble image via the make test-e2e-update path, then re-verified in the same image.
  • §V10: full-suite STRICT zero counted-diff (maxDiffPixelRatio 0.0) via make test-e2e-docker — result in the verification comment below.
  • test.describe.configure({ timeout: 300_000 }) in the new file only: one backend boot serializes all Dakota work behind workers:1 and the MOGA test chains a 3-objective optimization; no global timeout change.
  • node/SPEC.md §T row T57ic records the batch + residual gaps (MOGA-WRITE row-Run click, sumo-plot-qoi-select switch baseline, input-block-{v}-Value, single-job input-block-{v}, data-gated advisory pins, MOGAModal/Plot-modal control testids) — all remain tracked on fork#83.

Part of fork issue JavierGOrdonnez#83 (does not close it — residual gaps tracked there).

Rebase note (2026-10-27)

Rebased onto the rebased #741 head (a160b19a). Ledger ids re-minted for collisions with the base: V49wp→V53wp, B59wp→B62wp, T51ic→T57ic (SPEC rows, code refs and commit messages). Baselines: the three MOGA read-only shots (-pareto, -pareto-log-y, -inspect-modal via settings-modal state) re-typed again — the base moved in develop's Pareto-table Performance column (#633) on top of this PR's full-front envelope render. Regenerated and lane-verified in the pinned image with CI semantics (fresh backend per lane: uq-moga 4/4, sumo 5/5 pixel-green). SuMo/UQ/interactive baselines unchanged — their lane-verified bytes still match. (Monolithic update-mode runs leak shared-backend state past the first failing spec, so only lane-owned files were taken from the regen.)

@codecov

codecov Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 96.42857% with 2 lines in your changes missing coverage. Please review.
✅ Project coverage is 90.99%. Comparing base (4384982) to head (1b2aa2e).

Files with missing lines Patch % Lines
node/src/components/plots/MOGAPareto.tsx 96.42% 0 Missing and 2 partials ⚠️
Additional details and impacted files
@@                      Coverage Diff                       @@
##           jgo/fe-download-buttons-79     #742      +/-   ##
==============================================================
+ Coverage                       89.09%   90.99%   +1.90%     
==============================================================
  Files                             117      117              
  Lines                           15077    15127      +50     
  Branches                         1644     1777     +133     
==============================================================
+ Hits                            13433    13765     +332     
+ Misses                           1553     1279     -274     
+ Partials                           91       83       -8     
Flag Coverage Δ
e2e 84.18% <94.64%> (+3.91%) ⬆️
flaskapi 93.58% <ø> (ø)
node 91.90% <92.85%> (+<0.01%) ⬆️

Flags with carried forward coverage won't be shown. Click here to find out more.

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

@codspeed

codspeed Bot commented Oct 15, 2026 •

Copy link
Copy Markdown

Merging this PR will degrade performance by 11%

2 warnings, 1 note

⚠️ 1 benchmark is dominated by system calls

System calls cannot be simulated consistently and are left out of the measure. The reported value understates the real cost. Switch to the Walltime instrument to measure them.

Learn more about system calls

See affected benchmarks

⚠️ Base and head ran on different runner types

Some benchmarks with significant performance changes were compared across different runner types, so the changes might not come from the code. Run base and head on the same runner type, or use CodSpeed Macro Runners for more stable results.

Learn more about Macro Runners

Open the report in CodSpeed to investigate

ℹ️ 18 benchmarks have no flamegraph

The flamegraph wasn't generated: the symbols of the profiling trace could not be resolved, because no information about the language frames was collected.

See affected benchmarks

❌ 1 regressed benchmark
✅ 26 untouched benchmarks

Warning

Please fix the performance issues or acknowledge them on CodSpeed.

Performance Changes

Benchmark BASE HEAD Efficiency
❌ test_create_run_dir 351.3 µs 394.8 µs -11%

Tip

Investigate this regression by commenting @codspeedbot fix this regression on this PR, or directly use the CodSpeed MCP with your agent.


Comparing jgo/e2e-testid-coverage-83 (1b2aa2e) with jgo/fe-download-buttons-79 (4384982)

Open in CodSpeed

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟢 Approval recommended

The focused result-handling fix matches the backend contract, and no blocking issues remain.

0 open findings

What changed in this PR

Expands interactive-control coverage and fixes MOGA result handling so Pareto plots and tables populate correctly.

Changes:

  • Adds three end-to-end tests covering UQ, sampling, and MOGA controls.
  • Unwraps MOGA responses and derives missing Pareto-front indices, with unit tests.
  • Adds an Optimization Settings test selector and documents contracts and remaining coverage gaps.
File Description
tests/​e2e/​interactive-controls.spec.ts Adds triggered-state assertions and screenshot checks.
node/​src/​views/​MOGA.tsx Adds the settings-button test selector.
node/​src/​components/​plots/​MOGAPareto.tsx Normalizes responses and derives Pareto-front indices.
node/​src/​components/​plots/​MOGAPareto.test.tsx Tests dominance, ties, directions, and empty inputs.
node/​SPEC.md Records the result contract, coverage batch, and bug fix.

🧠 Review effort: Balanced


💡 Add a code-review agent skill or configure MCP servers for context-aware, tailored reviews. Learn more in the docs.

@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator Author

/ponytail-review (over-engineering pass, diff-only)

Lean already. Ship.

deriveNonDominatedIndices is irreducible domain logic (the envelope field the itis-sumo port dropped — dominance filtering has no stdlib equivalent), exercised with plain unit tests, and the e2e batch drives the real stack with no hand-rolled sleeps/waits.

@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator Author

Stacked: branch rebased onto jgo/fe-download-buttons-79 (PR #741's head) and base retargeted here — top of the #740 → #741 → #742 stack, so Monday's three merges are sequential and conflict-free.

Rebase resolutions:

No Copilot threads. /ponytail-review: lean, see comment above.

Merge order Monday: #740 → retarget this to develop after #741 merges (auto-retargeted for stacks) → merge. The diff already contains both parents, so no conflicts remain.

@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator Author

e2e flake root-caused and fixed in stacked #745.

The moga-readonly-pareto.png coin flip this PR saw (98 px fail on the first CI run, green on rerun) is a genuine product race, not a test problem: the MOGA table's Performance column was the terminal frame of up to three async writes computing three different values — a naive raw-sum override in the table (0.00 with the seeded empty weights), a parent recalc writing a capital-Performance key the grid never reads, and runMOGA's commit normalizing over all evaluated points while the recalc re-derived min/max from the front rows (a single-objective front is all rows tied → min==max → norm=0 fallback → whole column 0.0; pre-generation closures gave the all-NaN - frame). Proven with the pinned Playwright image on identical committed trees: resolved/-/resolved and 0.0/0.0/1.0/1.0.

#745 (this PR's stack child) makes the parent a single convergent writer over one domain so every write is byte-identical, adds a red→green unit regression (MOGAParetoTable.test.tsx) plus an expectMogaPerformanceComputed settle-gate before every full-page MOGA baseline, and retypes the MOGA baselines to the now-deterministic resolved state. Full suite verified twice back-to-back in the pinned image: 23/23 both runs.

No change needed on this PR: #742's current head and green check stand; the unstable baseline pairs it carries are corrected by #745 as the stack's final word. Merge order stays #740 → #741 → #742 → #745.

@JavierGOrdonnez
JavierGOrdonnez force-pushed the jgo/e2e-testid-coverage-83 branch from 74063e6 to da1491b Compare October 19, 2026 09:37
@JavierGOrdonnez JavierGOrdonnez self-assigned this Oct 19, 2026
@JavierGOrdonnez
JavierGOrdonnez force-pushed the jgo/e2e-testid-coverage-83 branch from da1491b to f0cad30 Compare October 20, 2026 13:44
@JavierGOrdonnez
JavierGOrdonnez force-pushed the jgo/e2e-testid-coverage-83 branch from f0cad30 to 17c6046 Compare October 27, 2026 20:27
@JavierGOrdonnez JavierGOrdonnez changed the title test(e2e): V36ez interactive-control coverage batch + MOGA envelope fix (B59wp) test(e2e): V36ez interactive-control coverage batch + MOGA envelope fix (B62wp) Oct 27, 2026
Javier Garcia Ordonez added 2 commits October 27, 2026 21:47
… contract (B62wp) [fork#83]

- tests/e2e/interactive-controls.spec.ts (3 tests, 19 new baselines): triggers the
  controls the read-only pixel suites reach but never operate — UQ correlation
  (Pearson/Spearman) + scale (linear/abslog) and Sobol' (first/second/total) +
  scale (linear/log) toggle groups w/ aria-pressed triggered-state asserts, footer
  previous-button, UQ back-nav, distribution-form selector (Normal->Uniform->
  Normal), WRITE-mode extend-sampling panel + refresh-job-collections forced
  refetch + new LHS campaign (value asserts + Run completion state), validation-
  modal one-step disabled stepper + QoI selector, MOGA add/confirm-output modal,
  surrogate-scale LOG lock w/ "manual" provenance chip, 3-objective MOGA
  (y,y2,y4) driven into the 3D Pareto view via the Plot Settings modal w/
  per-objective x/z log-display baselines, and the Optimization Settings modal
  behind the new additive `moga-settings-button` testid (root §V13); the two
  flake-prone shots (uq-setup-returned, lhs-configured) wait for the async QoI
  auto-detect commit / anchor a deterministic viewport before pixel-locking.
- B62wp/V53wp fix: perform_moga_optimization answers through the
  {optimizationResults:...} envelope (wrapper camelCased, inner map preserved
  incl. the snake_case ndi spelling — both folded) and itis-sumo 0.1.0a10
  ParetoFrontResult.data carries value columns only, so normalizeMogaResults
  unwraps the envelope (flat payloads still accepted) AND the new
  deriveNonDominatedIndices derives the non-dominated front in FE when the
  metadata is absent (direction per objective from OutputVarSelection
  "minimize"/"maximize" minimize-default, ties mutually non-dominated) + 3
  unit tests in MOGAPareto.test.tsx.
- moga-readonly -pareto/-pareto-log-y baselines regenerate to the FULL render
  (iteration boxes + Pareto front + table rows); -inspect-modal additionally
  shows the now-populated table + scrollbar-driven right-edge shift.
- All baselines regenerated ONLY inside the pinned
  mcr.microsoft.com/playwright:v1.64.0-noble image (§V12, 23/23) and
  re-verified with a STRICT zero counted-diff make test-e2e run (§V10, 23/23).
- node/SPEC.md: §V V53wp (envelope + derivation contract), §T T57ic (batch),
  §B B62wp (bug ledger).

Part of JavierGOrdonnez#83 (residual V36ez gaps stay tracked there).

Rebase note: the new base carries develop #633's test that pinned the PRE-fix
degraded contract ("payload without nonDominatedIndices -> empty rows") — re-titled to
assert the derived front (single non-dominated point + mapped front trace).
…ee (chip, B62wp front, #740 values) — regen inside pinned Playwright image

Base-move refresh (onto re-based #741 @ 4384982): the three MOGA read-only baselines re-
aged again — the base moved in develop's Pareto-table Performance column (#633) on top of
this tree's full-front envelope render. Re-gen disciplined per LANE context: monolithic
update-mode runs leak shared-backend state (a continued-past-failure spec mutates the job
collections the SuMo/UQ views read), so only the MOGA lane's own files were taken from the
pinned-image regen; SuMo/UQ baselines stay at the lane-verified bytes the base ships.
@JavierGOrdonnez
JavierGOrdonnez force-pushed the jgo/e2e-testid-coverage-83 branch from 17c6046 to 1b2aa2e Compare October 27, 2026 20:58
@JavierGOrdonnez

Copy link
Copy Markdown
Collaborator Author

Second rebase round (push 1b2aa2ed, onto re-based #741 head 43849828): the three MOGA read-only baselines were re-typed once more — the base now carries develop's Pareto-table Performance column (#633) on top of this PR's full-front envelope render. Regenerated inside the pinned image and verified with CI lane semantics (each lane its own fresh backend): uq-moga 4/4, sumo 5/5 pixel-green locally. All other baselines (SuMo/UQ/interactive) unchanged. Ledger ids were already re-minted for the base in round 1 (V53wp/B62wp/T57ic); Copilot's envelope-review and the #633 no-ndi test re-title are inside the first commit.

@JavierGOrdonnez

JavierGOrdonnez commented Oct 27, 2026 •

Copy link
Copy Markdown
Collaborator Author

CodSpeed check cleared: the only flagged test_create_run_dir regression is a flaskapi benchmark this PR never touches, and CodSpeed itself warned base/head ran on different runner types. Cured with the repo's own T46cs lever — workflow_dispatch baseline backfill of the base branch + head re-measure — analysis now success. All lanes green on 1b2aa2ed.

JavierGOrdonnez pushed a commit that referenced this pull request Oct 27, 2026
…main (B63px)

The column was the terminal frame of three async writes in arbitrary order:
- the table's [weights] effect overwrote row.performance with a naive
  direction-blind raw sum (empty e2e-seeded weights -> 0.00)
- the parent's [weights] recalc wrote the normalized score into a
  capital-Performance key the grid never reads (dead write)
- runMOGA's own commit normalized over ALL evaluations while the recalc
  re-derived min/max from the front rows; a single-objective front is all
  rows tied at the optimum -> min==max -> norm=0 fallback -> whole column
  0.0, and the runMOGA closure could hold empty weights -> all cells NaN
  (the '-' placeholder)
Pixels settled on '-', 0.00, 0.0 or the resolved 1.0 by write order
(proven: pinned-image regens of one commit -> resolved/-/resolved; post
single-writer verifies -> 0.0/0.0/1.0/1.0).

The parent recalc is now a pure projection of (tableData, weights,
outputTargets): it fires on every tableData commit and every
weights/direction edit, writes only the lowercase rendered field, always
normalizes against raw (the same all-evaluations domain runMOGA uses), and
bailouts via functional update when every row already agrees, so terminal
pixels are write-order independent instead of a coin flip.

- regression test MOGAParetoTable.test.tsx: given scores render verbatim
  (red on the old child code, green on the fix)
- e2e: expectMogaPerformanceComputed gate (cells exist, then no '-'
  placeholder) before every full-page MOGA baseline guards the transient
  window; baselines regenerate in the pinned image in a follow-up commit

Refs JavierGOrdonnez#83, node V49wp/B59wp/T51ic

Re-base adaptations (base moved to develop d764875 + re-based #740-#742):
- the projection effect now falls back to {} for a function with no outputTargets
  entry (same idiom as the scale-detection guard) — the develop #678 lifecycle test
  "falls back to an empty objective set" caught the un-guarded Object.keys crash.
- #633's parent-matrix test read the DEAD capital-Performance key the convergence
  deletes: reads re-targeted to the lowercase rendered field (values identical —
  the raw all-evaluations domain contains the front rows).
- #633's table test pinned the retired child recomputation: re-titled to assert the
  GIVEN scores stand, no realign fires on a weights-only edit (realign is keyed to
  [data] now) and the raw-sum override never appears.
JavierGOrdonnez pushed a commit that referenced this pull request Oct 27, 2026
…erformance column — pinned playwright image, single-writer single-domain tree (B63px)

Base-move refresh (onto re-based #742 @ 1b2aa2e): the three moga-readonly page/element
baselines (-pareto, -pareto-log-y, -settings-modal) re-typed again — the base moved in
#742's full-front envelope render under this tree's converged Performance column. The
other five (inspect-modal + the four interactive MOGA shots) regenerated byte-identical.
Determinism re-proven with CI lane semantics: two consecutive rounds of
{uq-moga 4/4, behavior 12/12}, every boot its own fresh backend — zero flakes.
JavierGOrdonnez pushed a commit that referenced this pull request Oct 27, 2026
base@d764875b + rebased #740/#741/#742 consumed 59-62 while #745 was drafted;
B63px was the next free base. Cross-refs (SPEC row, code comments, specs) remapped
together.
JavierGOrdonnez pushed a commit that referenced this pull request Oct 27, 2026
…main (B63px)

The column was the terminal frame of three async writes in arbitrary order:
- the table's [weights] effect overwrote row.performance with a naive
  direction-blind raw sum (empty e2e-seeded weights -> 0.00)
- the parent's [weights] recalc wrote the normalized score into a
  capital-Performance key the grid never reads (dead write)
- runMOGA's own commit normalized over ALL evaluations while the recalc
  re-derived min/max from the front rows; a single-objective front is all
  rows tied at the optimum -> min==max -> norm=0 fallback -> whole column
  0.0, and the runMOGA closure could hold empty weights -> all cells NaN
  (the '-' placeholder)
Pixels settled on '-', 0.00, 0.0 or the resolved 1.0 by write order
(proven: pinned-image regens of one commit -> resolved/-/resolved; post
single-writer verifies -> 0.0/0.0/1.0/1.0).

The parent recalc is now a pure projection of (tableData, weights,
outputTargets): it fires on every tableData commit and every
weights/direction edit, writes only the lowercase rendered field, always
normalizes against raw (the same all-evaluations domain runMOGA uses), and
bailouts via functional update when every row already agrees, so terminal
pixels are write-order independent instead of a coin flip.

- regression test MOGAParetoTable.test.tsx: given scores render verbatim
  (red on the old child code, green on the fix)
- e2e: expectMogaPerformanceComputed gate (cells exist, then no '-'
  placeholder) before every full-page MOGA baseline guards the transient
  window; baselines regenerate in the pinned image in a follow-up commit

Refs JavierGOrdonnez#83, node V49wp/B59wp/T51ic

Re-base adaptations (base moved to develop d764875 + re-based #740-#742):
- the projection effect now falls back to {} for a function with no outputTargets
  entry (same idiom as the scale-detection guard) — the develop #678 lifecycle test
  "falls back to an empty objective set" caught the un-guarded Object.keys crash.
- #633's parent-matrix test read the DEAD capital-Performance key the convergence
  deletes: reads re-targeted to the lowercase rendered field (values identical —
  the raw all-evaluations domain contains the front rows).
- #633's table test pinned the retired child recomputation: re-titled to assert the
  GIVEN scores stand, no realign fires on a weights-only edit (realign is keyed to
  [data] now) and the raw-sum override never appears.
JavierGOrdonnez pushed a commit that referenced this pull request Oct 27, 2026
…erformance column — pinned playwright image, single-writer single-domain tree (B63px)

Base-move refresh (onto re-based #742 @ 1b2aa2e): the three moga-readonly page/element
baselines (-pareto, -pareto-log-y, -settings-modal) re-typed again — the base moved in
#742's full-front envelope render under this tree's converged Performance column. The
other five (inspect-modal + the four interactive MOGA shots) regenerated byte-identical.
Determinism re-proven with CI lane semantics: two consecutive rounds of
{uq-moga 4/4, behavior 12/12}, every boot its own fresh backend — zero flakes.
JavierGOrdonnez pushed a commit that referenced this pull request Oct 27, 2026
base@d764875b + rebased #740/#741/#742 consumed 59-62 while #745 was drafted;
B63px was the next free base. Cross-refs (SPEC row, code comments, specs) remapped
together.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants