diff --git a/CHANGELOG.md b/CHANGELOG.md index 1f539bd9..e2548af8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -7,6 +7,13 @@ # Changelog +## Sprint 47 Workbench interaction smoke (2026-06-17) + +- Added stable `data-testid` anchors to the existing project, area, map, dataset, QA/QC and export controls for browser regression checks. +- Added `scripts/verify_workbench_interactions.sh` to verify the live backing state for project switching, AOI/map selection, dataset readiness, QA refresh and export refresh. +- Added readiness syntax coverage and static regression tests for the new interaction smoke. +- No API contracts, migrations, provider fetching, AI behavior or product capabilities changed. + ## Sprint 46 Workbench default-state smoke (2026-06-17) - Added `scripts/verify_workbench_default_state.sh` to verify the live frontend/API default demo state through the browser-facing URL. diff --git a/backend/tests/test_sprint47_workbench_interaction_smoke.py b/backend/tests/test_sprint47_workbench_interaction_smoke.py new file mode 100644 index 00000000..8596bf2a --- /dev/null +++ b/backend/tests/test_sprint47_workbench_interaction_smoke.py @@ -0,0 +1,68 @@ +from __future__ import annotations + +from pathlib import Path + + +ROOT = Path(__file__).resolve().parents[2] + + +def test_workbench_components_expose_stable_interaction_test_ids() -> None: + project_panel = (ROOT / "frontend" / "src" / "components" / "project" / "ProjectPanel.tsx").read_text( + encoding="utf-8" + ) + area_panel = (ROOT / "frontend" / "src" / "components" / "project" / "AreaPanel.tsx").read_text( + encoding="utf-8" + ) + map_workspace = (ROOT / "frontend" / "src" / "components" / "map" / "MapWorkspace.tsx").read_text( + encoding="utf-8" + ) + dataset_panel = (ROOT / "frontend" / "src" / "components" / "datasets" / "DatasetPanel.tsx").read_text( + encoding="utf-8" + ) + quality_panel = ( + ROOT / "frontend" / "src" / "components" / "quality" / "QualityResultsPanel.tsx" + ).read_text(encoding="utf-8") + export_center = (ROOT / "frontend" / "src" / "components" / "exports" / "ExportCenter.tsx").read_text( + encoding="utf-8" + ) + + assert 'data-testid="project-panel"' in project_panel + assert 'data-testid={`project-select-${project.id}`}' in project_panel + assert 'data-testid="load-demo-workflow"' in project_panel + assert 'data-testid="area-panel"' in area_panel + assert 'data-testid={`area-show-${area.id}`}' in area_panel + assert 'data-testid="map-workspace"' in map_workspace + assert 'data-testid="map-area-select"' in map_workspace + assert 'data-testid="map-area-visible"' in map_workspace + assert 'data-testid="map-area-opacity"' in map_workspace + assert 'data-testid="map-layer-visible"' in map_workspace + assert 'data-testid="map-layer-opacity"' in map_workspace + assert 'data-testid="dataset-panel"' in dataset_panel + assert 'data-testid={`dataset-select-${dataset.id}`}' in dataset_panel + assert 'data-testid="quality-results-panel"' in quality_panel + assert 'data-testid="refresh-quality-results"' in quality_panel + assert 'data-testid="export-center"' in export_center + assert 'data-testid="refresh-exports"' in export_center + assert 'data-testid="export-project-metadata"' in export_center + + +def test_readiness_gate_checks_workbench_interaction_smoke_script_syntax() -> None: + readiness = (ROOT / "scripts" / "run_readiness_check.sh").read_text(encoding="utf-8") + + assert "bash -n scripts/verify_workbench_interactions.sh" in readiness + + +def test_workbench_interaction_script_verifies_core_control_backing_state() -> None: + script = (ROOT / "scripts" / "verify_workbench_interactions.sh").read_text(encoding="utf-8") + + assert "/api/v1/demo/workflow" in script + assert "/api/v1/projects" in script + assert "/areas" in script + assert "/datasets" in script + assert "/quality-checks" in script + assert "/api/v1/exports/metadata" in script + assert "/api/v1/exports/projects/" in script + assert "GeoIntel Demo - Building QA" in script + assert "Demo AOI - Geel buildings" in script + assert "candidate dataset" in script + assert "reference dataset" in script diff --git a/docs/CODEX_EXECUTION_LOG.md b/docs/CODEX_EXECUTION_LOG.md index 153d9cba..c0a920f8 100644 --- a/docs/CODEX_EXECUTION_LOG.md +++ b/docs/CODEX_EXECUTION_LOG.md @@ -1,3 +1,33 @@ +## Sprint 47 Workbench interaction smoke (2026-06-17) + +Changed: +- Added stable `data-testid` anchors to the existing project, area, map, dataset, QA/QC and export controls so browser checks can target real controls instead of brittle text/layout selectors. +- Added `scripts/verify_workbench_interactions.sh`, a dependency-light runtime smoke that verifies the backing state for project switching, AOI/map selection, dataset selection, QA refresh and export refresh through the browser-facing API proxy. +- Added the script syntax check to `scripts/run_readiness_check.sh`. +- Added `backend/tests/test_sprint47_workbench_interaction_smoke.py` to keep the UI anchors, readiness gate and interaction smoke contract in place. +- Updated `scripts/README.md`, `docs/TODO.md` and `CHANGELOG.md`. + +Validation: +- RED: `cd backend && python -m pytest tests/test_sprint47_workbench_interaction_smoke.py -q` failed before implementation because the UI anchors, readiness script reference and interaction smoke script were missing. +- `cd backend && python -m pytest tests/test_sprint47_workbench_interaction_smoke.py -q` passed: 3 tests. +- `cd frontend && npm run typecheck` passed. +- `bash -n scripts/verify_workbench_interactions.sh` passed. +- `bash scripts/verify_workbench_interactions.sh http://192.168.10.150:1202` passed against the pre-deploy runtime API surface. +- `python -m compileall backend/app` passed. +- `cd backend && python -m pytest -W error::DeprecationWarning` passed: 198 tests. +- `bash scripts/run_readiness_check.sh` passed. +- `cd frontend && npm run build` passed. +- `cd backend && python -m alembic heads` passed: `202606120900 (head)`. +- `cd backend && python -m alembic upgrade head --sql` passed. +- `bash -n scripts/live_migration_smoke.sh` passed. + +Limitations: +- The shell smoke validates the state behind the controls but does not click rendered controls by itself. The added `data-testid` anchors are intended for Codex/browser click checks and future browser artifact automation. +- No API contracts, migrations, provider fetching, AI behavior or product capabilities changed. + +Next recommended pass: +- Run full readiness, deploy to Tower and validate the anchored controls with a live browser click/selection pass. + ## Sprint 46 Workbench default-state smoke (2026-06-17) Changed: diff --git a/docs/TODO.md b/docs/TODO.md index 29dae886..be662bca 100644 --- a/docs/TODO.md +++ b/docs/TODO.md @@ -42,6 +42,7 @@ This file now starts with the current implementation status. Older preparation/b - [x] Compact V1 workbench status strip for project, AOI, datasets, map, QA/QC and exports. - [x] Dry-run-first demo export artifact cleanup tooling. - [x] Browser-facing default workbench state smoke for the offline demo project. +- [x] Browser-facing workbench interaction backing-state smoke and stable UI test anchors. - [x] Live Docker/PostGIS validation on Tower/Unraid. - [x] Real YOLO compatibility smoke with optional AI extras and local model file. - [x] Detection and segmentation workflow hook extraction beyond Sprint 10. @@ -57,7 +58,7 @@ This file now starts with the current implementation status. Older preparation/b - [x] Demo workflow orchestration hook decomposition. - [x] Final `App.tsx` import/encoding cleanup and size audit. - [x] Optional final bootstrap-effect extraction. -- [ ] Decide next V1 stabilization focus: browser screenshot regression automation, backend service contract audit, or golden dataset expansion. +- [ ] Decide next V1 stabilization focus: browser screenshot artifact automation, backend service contract audit, or golden dataset expansion. ## Sprint 8 status diff --git a/frontend/src/components/datasets/DatasetPanel.tsx b/frontend/src/components/datasets/DatasetPanel.tsx index cf9d27db..5b4adc7f 100644 --- a/frontend/src/components/datasets/DatasetPanel.tsx +++ b/frontend/src/components/datasets/DatasetPanel.tsx @@ -62,7 +62,7 @@ export function DatasetPanel({ onRefreshMetadata, }: DatasetPanelProps) { return ( -
+

Datasets