Skip to content

Commit 9e34a7d

Browse files
committed
Refactor webstudio test results view
1 parent 9bd0200 commit 9e34a7d

15 files changed

Lines changed: 907 additions & 163 deletions

docs/webstudio/WEBSTUDIO_FUNCTIONAL_SPEC.md

Lines changed: 84 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -343,13 +343,93 @@ Workspace compatibility:
343343

344344
## Test Results
345345

346-
The results page supports:
346+
The Test Results page supports inspection of Generate and CLI output folders.
347+
348+
### Output Result Selection
349+
350+
The page must support:
347351

348352
- source toggle between Generate and CLI outputs
349-
- output result group selection
350-
- generated file selection
351-
- HTML report rendering
353+
- output result folder selection
354+
- output result folder sorting
355+
- output result folder filtering
356+
- generated file listing for the selected output folder
357+
- generated file filtering
352358
- verdict outcome summarization
359+
- HTML report rendering
360+
361+
Default behavior:
362+
363+
- output result folders are sorted latest first
364+
- selecting an output folder shows a run-level verdict outcome summary by default
365+
- selecting an output folder must not automatically select the first generated file
366+
- selecting a generated test sequence file manually shows the HTML report rendering
367+
368+
### Results Preview
369+
370+
When an output result folder is selected and no generated file is selected, the right preview area must show a run-level verdict outcome summary.
371+
372+
The summary should include:
373+
374+
- verdict outcomes
375+
- failure type distribution
376+
- sequence status overview
377+
- enough metadata to understand which run is selected
378+
379+
When a generated file is selected, the right preview area must show the corresponding HTML report.
380+
381+
The user must be able to return from the HTML report preview to the run-level verdict outcome summary.
382+
383+
### Empty State
384+
385+
The Test Results page must support an empty state.
386+
387+
The empty state is shown when:
388+
389+
- no output result folders exist for the selected source
390+
- filters hide all available output result folders
391+
- the last output result folder was deleted
392+
393+
Expected empty-state behavior:
394+
395+
- the left panel remains visible
396+
- `Output Results` remains available
397+
- `Generated Files` shows an empty message
398+
- the right preview area shows a clear empty-state message
399+
- no stale folder, file, summary, or HTML report remains selected
400+
401+
### Filtering
402+
403+
Output result folder filtering should support:
404+
405+
- all folders
406+
- folders with failures
407+
- folders with only OK sequences
408+
409+
Generated file filtering should support:
410+
411+
- all files
412+
- failed files
413+
- OK files
414+
415+
Filtering must not delete files. It only changes visibility in Web Studio.
416+
417+
Removing the filtering category restores the visibility of all folders and files.
418+
419+
### Deletion
420+
421+
The page may support deleting generated result artifacts.
422+
423+
Deletion rules:
424+
425+
- deleting a generated file deletes only the selected test sequence report file
426+
- deleting an output result folder deletes the whole selected run folder
427+
- deleting an output result folder is more destructive than deleting a generated file
428+
- delete actions must require a modal confirmation
429+
- if confirmation is not explicit and clear, Web Studio must not delete anything
430+
- after deleting a selected generated file, Web Studio must clear the selected file and return to the run-level verdict outcome summary
431+
- after deleting a selected output result folder, Web Studio must refresh the output folder list and clear stale selections
432+
- if deleting an output result folder removes all existing run-level reports, WebStudio must show the default Test Results empty view
353433

354434
## State Model
355435

docs/webstudio/WEBSTUDIO_UX_SPEC.md

Lines changed: 36 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -237,20 +237,52 @@ The results page should provide fast visual understanding of output health.
237237

238238
Expected behavior:
239239

240-
- output source can switch between Generate and CLI
240+
- the left panel contains `Output Results`
241+
- `Output Results` allows switching between Generate and CLI
242+
- `Output Results` includes sorting and filtering controls without hiding the selected source context
243+
- the left panel also contains `Generated Files` for the selected output result
244+
- selecting an output result folder shows a run-level verdict outcome summary in the right preview area
245+
- selecting an output result folder does not automatically select the first generated file
246+
- selecting a generated file replaces the summary with the HTML report preview
247+
- the user can return from HTML report preview to the run-level verdict outcome summary
248+
- output folders can be sorted, with latest first as the default
249+
- output folders can be filtered without deleting or modifying files
250+
- generated files can be filtered without deleting or modifying files
241251
- green/red status color is consistent
242252
- selected result remains visually distinct
243-
- verdict outcome summary has fixed height
244-
- failure type rows scroll internally
245-
- generated files panel has fixed height
253+
- summary cards have fixed or predictable height
254+
- failure type rows scroll internally when needed
255+
- generated files panel has fixed height and scrolls internally when needed
246256
- generated file rows keep fixed or predictable size
247257
- report preview uses the remaining stable area
258+
- destructive delete actions are not embedded as tiny accidental row buttons
259+
- delete actions use a modal confirmation
260+
- unclear confirmation always cancels deletion
261+
- empty states keep the left panel visible and replace stale preview content with clear guidance
248262

249263
Avoid:
250264

251265
- panel height changing based on number of verdicts
252266
- horizontal scrolling for generated file names where a shorter label, ellipsis, or detail tooltip can preserve context
253267
- ambiguous color semantics
268+
- stale selected folders, files, summaries, or HTML reports after filtering or deletion
269+
270+
Deletion confirmation behavior:
271+
272+
- deleting one generated file must name the selected file
273+
- deleting one output result folder must name the selected folder
274+
- deleting one output result folder must use stronger wording than deleting one generated file
275+
- `Cancel` or closing the modal must not delete anything
276+
- if the user does not clearly confirm the exact destructive action, Web Studio must not delete anything
277+
- after deleting a generated file, the preview returns to the run-level verdict outcome summary
278+
- after deleting an output result folder, stale selections are cleared before the list is refreshed
279+
280+
Empty state behavior:
281+
282+
- no output result folders shows an empty message in the right preview area
283+
- filters hiding all output result folders show an empty filtered-results message
284+
- no generated files for a selected output folder shows an empty message in the `Generated Files` panel
285+
- deleting the last output result folder shows the default Test Results empty view
254286

255287
## State Model UX Contract
256288

webstudio/frontend/src/App.svelte

Lines changed: 60 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1379,11 +1379,11 @@
13791379
13801380
async function selectResultGroup(resultGroup) {
13811381
selectedResultGroup = resultGroup;
1382-
if (resultGroup?.files?.length > 0) {
1383-
await loadResultFile(resultGroup.files[0]);
1384-
} else {
1385-
selectedResultFile = null;
1386-
}
1382+
selectedResultFile = null;
1383+
}
1384+
1385+
function showResultSummary() {
1386+
selectedResultFile = null;
13871387
}
13881388
13891389
async function loadResultFile(resultFile) {
@@ -1412,6 +1412,58 @@
14121412
await loadResults(source);
14131413
}
14141414
1415+
function applyRefreshedResults(refreshedResults, preferredGroupPath = "") {
1416+
resultsData = refreshedResults;
1417+
const resultGroups = resultsData?.groups || [];
1418+
if (resultGroups.length > 0) {
1419+
selectedResultGroup = resultGroups.find((resultGroup) => resultGroup.path === preferredGroupPath)
1420+
|| resultGroups[resultGroups.length - 1];
1421+
} else {
1422+
selectedResultGroup = null;
1423+
}
1424+
1425+
selectedResultFile = null;
1426+
}
1427+
1428+
async function deleteResultFile(resultFile) {
1429+
if (!resultFile?.path) {
1430+
return;
1431+
}
1432+
1433+
try {
1434+
const resultPath = encodeURIComponent(resultFile.path);
1435+
const currentGroupPath = selectedResultGroup?.path || "";
1436+
const refreshedResults = await loadJson(
1437+
resultSource === "cli"
1438+
? `/api/execution/cli/results/${resultFile.name}?path=${resultPath}`
1439+
: `/api/execution/scriptless/results/${resultFile.name}?path=${resultPath}`,
1440+
{ method: "DELETE" }
1441+
);
1442+
applyRefreshedResults(refreshedResults, currentGroupPath);
1443+
} catch (deleteError) {
1444+
reportClientError(`Unable to delete result file ${resultFile.name}`, deleteError);
1445+
}
1446+
}
1447+
1448+
async function deleteResultGroup(resultGroup) {
1449+
if (!resultGroup?.path) {
1450+
return;
1451+
}
1452+
1453+
try {
1454+
const resultPath = encodeURIComponent(resultGroup.path);
1455+
const refreshedResults = await loadJson(
1456+
resultSource === "cli"
1457+
? `/api/execution/cli/result-groups?path=${resultPath}`
1458+
: `/api/execution/scriptless/result-groups?path=${resultPath}`,
1459+
{ method: "DELETE" }
1460+
);
1461+
applyRefreshedResults(refreshedResults);
1462+
} catch (deleteError) {
1463+
reportClientError(`Unable to delete result output folder ${resultGroup.name}`, deleteError);
1464+
}
1465+
}
1466+
14151467
async function startRemoteSpyMode() {
14161468
if (!selectedWorkspaceName || !workspaceAvailableInTestar()) {
14171469
return;
@@ -1899,13 +1951,16 @@
18991951
19001952
{#if currentPage === "results"}
19011953
<TestResultsView
1954+
deleteResultFile={deleteResultFile}
1955+
deleteResultGroup={deleteResultGroup}
19021956
loadResultFile={loadResultFile}
19031957
resultsData={resultsData}
19041958
resultSource={resultSource}
19051959
selectedResultFile={selectedResultFile}
19061960
selectedResultGroup={selectedResultGroup}
19071961
selectResultSource={selectResultSource}
19081962
selectResultGroup={selectResultGroup}
1963+
showResultSummary={showResultSummary}
19091964
/>
19101965
{/if}
19111966

0 commit comments

Comments
 (0)