Skip to content

Commit 1653cde

Browse files
Improve UI robot layout coverage (#681)
Co-authored-by: GuilaumeDemets <g.demets02@gmail.com>
1 parent b327464 commit 1653cde

7 files changed

Lines changed: 290 additions & 11 deletions

File tree

src/agilab/apps/builtin/tescia_diagnostic_project/src/tescia_diagnostic/ui/app_surface.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ def render(*, mode: str = "analysis", active_app: Path | None = None, **_kwargs:
550550
)
551551

552552
catalog_tab, answer_tab, classroom_tab, authoring_tab, coverage_tab = st.tabs(
553-
["Catalog", "Self-evaluation", "Classroom live", "Teacher authoring", "Coverage"]
553+
["Catalog", "Self-check", "Live class", "Authoring", "Coverage"]
554554
)
555555

556556
with catalog_tab:

src/agilab/orchestrate/orchestrate_execute.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -979,7 +979,7 @@ def _render_run_panel_controls() -> None:
979979
st.session_state.pop(delete_confirm_key, None)
980980

981981
if controls_visible:
982-
st.markdown("#### 5. Run and inspect outputs")
982+
st.markdown("## 5. Run and inspect outputs")
983983
if dag_based_app:
984984
st.caption("Run the selected DAG workflow. Inspect stage artifacts and run evidence from WORKFLOW.")
985985
else:

test/test_agilab_widget_robot.py

Lines changed: 171 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -653,6 +653,106 @@ def test_layout_integrity_result_probe_accepts_clean_geometry() -> None:
653653
assert "no obvious overflow" in probe.detail
654654

655655

656+
def test_layout_integrity_result_probe_ignores_framework_artifacts() -> None:
657+
module = _load_module()
658+
659+
probe = module._layout_integrity_result_probe(
660+
app_name="flight_telemetry_project",
661+
display="PROJECT",
662+
url="http://demo/PROJECT",
663+
issues=[
664+
{"kind": "zero_size_control", "label": "INPUT", "detail": "control rendered at 1.0x1.0"},
665+
{"kind": "text_overflow", "label": "Install agi-app", "detail": "text width 95px exceeds container 79px"},
666+
{
667+
"kind": "control_overlap",
668+
"label": "view_maps, close by backspace",
669+
"detail": "overlaps Selected view_maps by 504.0px2",
670+
},
671+
{
672+
"kind": "control_overlap",
673+
"label": "Show/hide columns",
674+
"detail": "overlaps Action None by 501.3px2",
675+
},
676+
{
677+
"kind": "control_overlap",
678+
"label": "Download as CSV",
679+
"detail": "overlaps Action None by 501.3px2",
680+
},
681+
{
682+
"kind": "control_overlap",
683+
"label": "Search",
684+
"detail": "overlaps Action None by 501.3px2",
685+
},
686+
{
687+
"kind": "control_overlap",
688+
"label": "Fullscreen",
689+
"detail": "overlaps Action None by 501.3px2",
690+
},
691+
{
692+
"kind": "control_overlap",
693+
"label": "INPUT",
694+
"detail": "overlaps upload Upload by 1.0px2",
695+
},
696+
{
697+
"kind": "control_overlap",
698+
"label": "Coverage",
699+
"detail": "overlaps Scroll tabs right by 800.0px2",
700+
},
701+
{
702+
"kind": "horizontal_overflow",
703+
"label": "keyboard_double_arrow_left",
704+
"detail": "control spans x=-270.0..-242.0 viewport=390",
705+
},
706+
{
707+
"kind": "horizontal_overflow",
708+
"label": "Catalog pypi.org",
709+
"detail": "control spans x=-263.0..-247.0 viewport=390",
710+
},
711+
],
712+
)
713+
714+
assert probe.status == "interacted"
715+
assert "ignored 11" in probe.detail
716+
717+
718+
def test_layout_integrity_result_probe_ignores_workflow_content_overflow() -> None:
719+
module = _load_module()
720+
721+
probe = module._layout_integrity_result_probe(
722+
app_name="flight_telemetry_project",
723+
display="WORKFLOW",
724+
url="http://demo/WORKFLOW",
725+
issues=[
726+
{
727+
"kind": "text_overflow",
728+
"label": "UAV queue to relay handoff MVP",
729+
"detail": "text width 479px exceeds container 305px",
730+
},
731+
],
732+
)
733+
734+
assert probe.status == "interacted"
735+
assert "ignored 1" in probe.detail
736+
737+
738+
def test_layout_integrity_result_probe_keeps_actionable_issue_after_filtering() -> None:
739+
module = _load_module()
740+
741+
probe = module._layout_integrity_result_probe(
742+
app_name="flight_telemetry_project",
743+
display="PROJECT",
744+
url="http://demo/PROJECT",
745+
issues=[
746+
{"kind": "zero_size_control", "label": "INPUT", "detail": "control rendered at 1.0x1.0"},
747+
{"kind": "horizontal_overflow", "label": "RUN", "detail": "control spans outside viewport"},
748+
],
749+
)
750+
751+
assert probe.status == "failed"
752+
assert "horizontal_overflow" in probe.detail
753+
assert "ignored 1" in probe.detail
754+
755+
656756
def test_accessibility_result_probe_reports_first_issue() -> None:
657757
module = _load_module()
658758

@@ -682,6 +782,58 @@ def test_accessibility_result_probe_accepts_clean_semantics() -> None:
682782
assert "ARIA references" in probe.detail
683783

684784

785+
def test_accessibility_result_probe_ignores_framework_noise() -> None:
786+
module = _load_module()
787+
788+
probe = module._accessibility_result_probe(
789+
app_name="flight_telemetry_project",
790+
display="PROJECT",
791+
url="http://demo/PROJECT",
792+
issues=[
793+
{
794+
"kind": "contrast_risk",
795+
"label": "PROJECT",
796+
"detail": "text/background contrast ratio 1.97 is below robot threshold 2.2",
797+
},
798+
{
799+
"kind": "missing_accessible_name",
800+
"label": "stNumberInputStepDown",
801+
"detail": "visible interactive control has no accessible name",
802+
},
803+
{
804+
"kind": "heading_level_jump",
805+
"label": "Runtime diagnostics",
806+
"detail": "heading jumps from h2 to h4",
807+
},
808+
],
809+
)
810+
811+
assert probe.status == "interacted"
812+
assert "ignored 3" in probe.detail
813+
814+
815+
def test_accessibility_result_probe_keeps_actionable_issues_after_filtering() -> None:
816+
module = _load_module()
817+
818+
probe = module._accessibility_result_probe(
819+
app_name="flight_telemetry_project",
820+
display="PROJECT",
821+
url="http://demo/PROJECT",
822+
issues=[
823+
{
824+
"kind": "contrast_risk",
825+
"label": "PROJECT",
826+
"detail": "text/background contrast ratio 1.97 is below robot threshold 2.2",
827+
},
828+
{"kind": "missing_accessible_name", "label": "Run now", "detail": "visible control has no name"},
829+
],
830+
)
831+
832+
assert probe.status == "failed"
833+
assert "Run now" in probe.detail
834+
assert "ignored 1" in probe.detail
835+
836+
685837
def test_browser_error_check_probe_records_clean_capture() -> None:
686838
module = _load_module()
687839

@@ -782,6 +934,25 @@ def test_above_fold_result_probe_accepts_primary_targets() -> None:
782934
assert "primary targets visible" in probe.detail
783935

784936

937+
def test_above_fold_expected_labels_ignore_app_identity_in_shared_chrome() -> None:
938+
module = _load_module()
939+
940+
assert module._above_fold_expected_labels("ORCHESTRATE", app_name="data_quality_gate_project") == (
941+
"ORCHESTRATE",
942+
"Deploy",
943+
)
944+
assert module._above_fold_expected_labels("ANALYSIS", app_name="weather_forecast_project") == (
945+
"ANALYSIS",
946+
)
947+
assert module._above_fold_expected_labels("WORKFLOW", app_name="weather_forecast_project") == (
948+
"WORKFLOW",
949+
)
950+
assert module._above_fold_expected_labels("ANALYSIS", app_name="flight_telemetry_project") == (
951+
"ANALYSIS",
952+
"view_maps",
953+
)
954+
955+
785956
def test_above_fold_probe_reports_collector_exception() -> None:
786957
module = _load_module()
787958

test/test_agilab_widget_robot_matrix.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -259,6 +259,7 @@ def test_opt_in_mobile_and_release_evidence_scenarios_are_not_part_of_default_al
259259
assert all_builtin_core_render.page_timeout_seconds == 120.0
260260
assert pytorch_analysis.apps == "pytorch_playground_project"
261261
assert pytorch_analysis.pages == "ANALYSIS"
262+
assert pytorch_analysis.route_query == "current_page=app_ui"
262263
assert pytorch_analysis.required_text == "PyTorch Playground,Refresh evidence,Synced RUN snippet,Settings"
263264
assert pytorch_analysis.forbidden_sidebar_text == "Project:"
264265
assert pytorch_analysis.required_links == "PyTorch Playground=>current_page=app_ui"
@@ -596,6 +597,7 @@ def test_build_robot_command_covers_pytorch_playground_analysis_text(tmp_path) -
596597
assert argv[argv.index("--apps") + 1] == "pytorch_playground_project"
597598
assert argv[argv.index("--pages") + 1] == "ANALYSIS"
598599
assert argv[argv.index("--apps-pages") + 1] == "none"
600+
assert argv[argv.index("--route-query") + 1] == "current_page=app_ui"
599601
assert argv[argv.index("--required-text") + 1] == "PyTorch Playground,Refresh evidence,Synced RUN snippet,Settings"
600602
assert argv[argv.index("--forbidden-sidebar-text") + 1] == "Project:"
601603
assert argv[argv.index("--required-links") + 1] == "PyTorch Playground=>current_page=app_ui"
@@ -2260,6 +2262,7 @@ def test_build_robot_command_passes_analysis_contract_controls(tmp_path) -> None
22602262

22612263
assert _value_after(argv, "--apps") == "pytorch_playground_project"
22622264
assert _value_after(argv, "--pages") == "ANALYSIS"
2265+
assert _value_after(argv, "--route-query") == "current_page=app_ui"
22632266
assert _value_after(argv, "--required-text") == "PyTorch Playground,Refresh evidence,Synced RUN snippet,Settings"
22642267
assert _value_after(argv, "--forbidden-sidebar-text") == "Project:"
22652268
assert _value_after(argv, "--required-links") == "PyTorch Playground=>current_page=app_ui"

test/test_orchestrate_execute.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -943,7 +943,7 @@ def clear(self):
943943
assert fake_st.session_state[orchestrate_execute.EXECUTE_NOTICE_KEY]["kind"] == "success"
944944
assert "Dataframe exported successfully" in fake_st.session_state[orchestrate_execute.EXECUTE_NOTICE_KEY]["message"]
945945
assert ("rerun_fragment_or_app", "called") in fake_st.messages
946-
assert ("markdown", "#### 5. Run and inspect outputs") in fake_st.messages
946+
assert ("markdown", "## 5. Run and inspect outputs") in fake_st.messages
947947
assert any(kind == "preview" for kind, _ in fake_st.messages)
948948

949949
fake_st.button_calls.clear()

0 commit comments

Comments
 (0)