FEAT: outcome breakdown visualization on the scenario run page - #2644
WatchTree-19 wants to merge 1 commit into
Conversation
|
Can you add screenshots to the PR description? Also #2378 sounds like it may have overlap. |
|
Roman Lutz (@romanlutz) screenshots coming, though flagging one thing first since it may change what is worth screenshotting. You are right about #2378 overlapping. I pulled the diff. It is not the same feature, but it lands in the same place: #2378 adds per-attack outcome badges to Where they actually collide is mechanical. #2378 touches #2378 is layer 7 of a stack with layers already merged, and mine is a single file addition, so mine should give way rather than the other way round. Happy to rebase this on top once #2378 lands and fold the colour mapping into whatever it establishes, so there is one source of truth for outcome colour. One question that decides how I rebase: would you rather the distribution bar stayed a separate component slotted into the page, or became part of the result-details structure #2378 introduces? I will take direction either way. |
|
Yes, I'm essentially giving you a heads up that it won't be reviewed/merged until the stack is complete. If you have screenshots I'll take a look at those, though. |
|
Hi Roman, understood on the stack, no rush from my end and I will rebase once #2378 is in. Screenshots are below, light and dark. There are three states in each, a typical run at the top, then a run where 48.4% of executions finished undetermined, and the empty state before anything has executed. The middle one is the case I care about. When half a run reaches no verdict you cannot see that in the per-attack view, you have to read down the list and count, whereas here it is the first thing you see. It is the same undetermined handling thread as #2659. These are rendered from the component on this branch rather than mockups, off the current head in FluentProvider inside the real page markup.
|


Description
Adds an accessible outcome-breakdown bar to the scenario run page, showing the distribution of attack outcomes (success, failure, undetermined, error) across a run's executions with per-outcome counts and percentages. The intent is that you can see at a glance how a run went, rather than reading the atomic-group table row by row. It sits between "Overall progress" and "Atomic attack groups", and it is computed from results the page already loads, so no backend change is required.
This addresses the "visualizing results from attacks in the GUI" area that Roman Lutz (@romanlutz) and I discussed alongside the scorer work in #2626 and #2628.
The change adds a pure utility, summarizeAttackOutcomes, which returns counts, total and percentages and is defensive about missing or unrecognised outcomes; a new OutcomeSummaryBar Fluent UI v9 component with co-located styles, fill colours aligned to OutcomeBadge semantics, and a role="img" element whose aria-label reads the full breakdown for screen readers; and the wiring into ScenarioRunPage.
Tests and Documentation
attackOutcomeSummary.test.ts covers counts, percentages, empty input and malformed-outcome handling. OutcomeSummaryBar.test.tsx covers segment rendering, the accessible summary label, legend counts and percentages, and the empty-state hint. The existing ScenarioRunPage.test.tsx heading assertion is updated for the new section. tsc --noEmit is clean, eslint --max-warnings 0 is clean, and jest passes across the util, component and run-page suites (28 tests). No JupyText changes, since this is frontend-only.
The change follows the frontend style guide: tokens-only styling in a co-located .styles.ts, inline style used only for the genuinely dynamic segment width, data-testid selectors, and accessible markup.