fix(ci): restore release gates and contract baseline (fixes #4)
Managed validation / full (pull_request) Canceled after 0s
GeoIntel release gates / Compile, test, contracts and builds (pull_request) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (pull_request) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (pull_request) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Failing after 22s
GeoIntel release gates / Compile, test, contracts and builds (push) Waiting to run
GeoIntel release gates / GIS image, SBOM and container scan (push) Failing after 45s
Managed validation / full (pull_request) Canceled after 0s
GeoIntel release gates / Compile, test, contracts and builds (pull_request) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (pull_request) Canceled after 0s
GeoIntel release gates / GIS image, SBOM and container scan (pull_request) Canceled after 0s
GeoIntel release gates / Python and npm vulnerability policy (push) Failing after 22s
GeoIntel release gates / Compile, test, contracts and builds (push) Waiting to run
GeoIntel release gates / GIS image, SBOM and container scan (push) Failing after 45s
This commit is contained in:
@@ -345,7 +345,7 @@ def test_frontend_exposes_map_bbox_selection_contracts() -> None:
|
||||
theme_hook = read_feature("map_workspace")
|
||||
|
||||
assert "selectVectorFeatures" in api_client
|
||||
assert "Area selection" in map_workspace
|
||||
assert "DEFAULT_AREA_SELECTION_FILENAME" in map_workspace
|
||||
assert "Teken rechthoek" in map_workspace
|
||||
assert "Objecten in gebied ophalen" in map_workspace
|
||||
assert "Gebiedsdownload bewaren" in map_workspace
|
||||
|
||||
@@ -6,7 +6,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
def test_map_selection_qa_shortcut_uses_existing_qa_workflow_contract() -> None:
|
||||
hook_path = ROOT / "frontend" / "src" / "hooks" / "useMapSelectionQa.ts"
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
map_workspace = read_feature("map_workspace")
|
||||
|
||||
assert hook_path.exists()
|
||||
@@ -26,7 +26,7 @@ def test_map_selection_qa_shortcut_uses_existing_qa_workflow_contract() -> None:
|
||||
|
||||
|
||||
def test_app_keeps_qa_api_calls_out_of_orchestration() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
|
||||
assert "qaApi" not in app
|
||||
assert "from './services/api'" not in app
|
||||
|
||||
@@ -13,7 +13,7 @@ def test_map_qa_result_exposes_quality_check_evidence_contract():
|
||||
types = read_text("frontend/src/types.ts")
|
||||
hook = read_text("frontend/src/hooks/useMapSelectionQa.ts")
|
||||
workspace = read_feature("map_workspace")
|
||||
app = read_text("frontend/src/App.tsx")
|
||||
app = read_feature("shell")
|
||||
|
||||
assert "quality_check_id?: string" in types
|
||||
assert "latestMapSelectionQualityCheckId" in hook
|
||||
@@ -35,7 +35,7 @@ def test_map_qa_result_exposes_quality_check_evidence_contract():
|
||||
|
||||
|
||||
def test_map_qa_evidence_keeps_backend_contract_unchanged():
|
||||
app = read_text("frontend/src/App.tsx")
|
||||
app = read_feature("shell")
|
||||
api_contracts = read_text("docs/API_CONTRACTS.md")
|
||||
|
||||
assert "/api/v1/qa/detections-vs-reference" in api_contracts
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import read_feature
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -6,11 +7,10 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
def test_detection_lab_exposes_persisted_threshold_calibration_comparison() -> None:
|
||||
detection_lab = ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx"
|
||||
app = ROOT / "frontend" / "src" / "App.tsx"
|
||||
todo = ROOT / "docs" / "TODO.md"
|
||||
|
||||
source = detection_lab.read_text(encoding="utf-8")
|
||||
app_source = app.read_text(encoding="utf-8")
|
||||
app_source = read_feature("shell")
|
||||
todo_source = todo.read_text(encoding="utf-8")
|
||||
|
||||
assert "qualityChecks: QualityCheckRead[]" in source
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import read_feature
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -7,12 +8,11 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
def test_detection_lab_has_guided_threshold_calibration_runner() -> None:
|
||||
hook = ROOT / "frontend" / "src" / "hooks" / "useDetectionWorkflow.ts"
|
||||
lab = ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx"
|
||||
app = ROOT / "frontend" / "src" / "App.tsx"
|
||||
todo = ROOT / "docs" / "TODO.md"
|
||||
|
||||
hook_source = hook.read_text(encoding="utf-8")
|
||||
lab_source = lab.read_text(encoding="utf-8")
|
||||
app_source = app.read_text(encoding="utf-8")
|
||||
app_source = read_feature("shell")
|
||||
todo_source = todo.read_text(encoding="utf-8")
|
||||
|
||||
assert "interface DetectionCalibrationRunRow" in hook_source
|
||||
@@ -22,22 +22,22 @@ def test_detection_lab_has_guided_threshold_calibration_runner() -> None:
|
||||
assert "detectionCalibrationRows" in hook_source
|
||||
assert "detectionCalibrationError" in hook_source
|
||||
assert "runDetectionCalibration" in hook_source
|
||||
assert "detectionApi.run({" in hook_source
|
||||
assert "executeDetection(" in hook_source
|
||||
# Every requested threshold is reported, but from one inference pass at the
|
||||
# lowest cut: detections above a higher cut are a subset of it, and
|
||||
# suppression walks candidates in descending confidence, so the kept set
|
||||
# above a cut does not depend on the threshold the run used. Asserting the
|
||||
# old per-threshold loop pinned N GPU passes that produced identical numbers.
|
||||
assert "confidence_threshold: lowestThreshold" in hook_source
|
||||
assert "lowestThreshold," in hook_source
|
||||
assert "calibration_thresholds: thresholds" in hook_source
|
||||
assert "calibration_sweep" in hook_source
|
||||
assert "parameters_json: { calibration: true, calibration_thresholds: thresholds }" in hook_source
|
||||
assert "{ calibration: true, calibration_thresholds: thresholds }," in hook_source
|
||||
assert "detectionApi.compareWithReference(result.analysis_run_id" in hook_source
|
||||
assert "reference_dataset_id: detectionReferenceDatasetId" in hook_source
|
||||
assert "Select a reference dataset before calibration" in hook_source
|
||||
assert "Provide at least one valid threshold between 0 and 1" in hook_source
|
||||
assert "Configured YOLO calibration requires a tile manifest" in hook_source
|
||||
assert "Select a local model asset before calibration" in hook_source
|
||||
assert "reference_dataset_id: referenceDatasetId" in hook_source
|
||||
assert "Kies eerst een referentiebron om te kalibreren" in hook_source
|
||||
assert "Geef minstens één geldige drempel tussen 0 en 1 op" in hook_source
|
||||
assert "Kalibratie met YOLO vereist een beeldtegelmanifest" in hook_source
|
||||
assert "Kies eerst een lokaal modelbestand om te kalibreren" in hook_source
|
||||
|
||||
assert "Modelkalibratie voor beheerders" in lab_source
|
||||
assert "Voert het lokale model en een kwaliteitscontrole uit" in lab_source
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
from pathlib import Path
|
||||
from tests.frontend_contract import read_feature
|
||||
|
||||
|
||||
ROOT = Path(__file__).resolve().parents[2]
|
||||
@@ -6,11 +7,10 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
def test_guided_calibration_rows_link_to_existing_qa_evidence_map() -> None:
|
||||
lab = ROOT / "frontend" / "src" / "components" / "detection" / "DetectionLab.tsx"
|
||||
app = ROOT / "frontend" / "src" / "App.tsx"
|
||||
todo = ROOT / "docs" / "TODO.md"
|
||||
|
||||
lab_source = lab.read_text(encoding="utf-8")
|
||||
app_source = app.read_text(encoding="utf-8")
|
||||
app_source = read_feature("shell")
|
||||
todo_source = todo.read_text(encoding="utf-8")
|
||||
|
||||
assert "onOpenCalibrationEvidence" in lab_source
|
||||
|
||||
@@ -15,22 +15,15 @@ def _bash_path(path: Path) -> str:
|
||||
if os.name != "nt":
|
||||
return raw_path
|
||||
|
||||
try:
|
||||
result = subprocess.run(
|
||||
["bash", "-lc", f"wslpath -a {shlex.quote(raw_path)}"],
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=10,
|
||||
check=False,
|
||||
)
|
||||
except (subprocess.TimeoutExpired, OSError):
|
||||
# Starting WSL can exceed ten seconds while the rest of the suite is
|
||||
# running. The fallback below is what this helper already does whenever
|
||||
# the conversion does not work, so a slow shell must not red the suite.
|
||||
return raw_path
|
||||
if result.returncode == 0 and result.stdout.strip():
|
||||
return result.stdout.strip()
|
||||
return raw_path
|
||||
# ``bash`` is WSL on the supported Windows development path. Converting
|
||||
# the drive path directly avoids starting a second WSL process merely to
|
||||
# run ``wslpath``; that process can time out while the full suite is busy
|
||||
# and would leave curl with an invalid file://C:\\... URL.
|
||||
drive, tail = os.path.splitdrive(raw_path)
|
||||
if drive:
|
||||
normalized_tail = tail.lstrip("\\/").replace("\\", "/")
|
||||
return f"/mnt/{drive[0].lower()}/{normalized_tail}"
|
||||
return raw_path.replace("\\", "/")
|
||||
|
||||
|
||||
def test_split_background_promotion_workflow_runs_split_then_split_aware_report() -> None:
|
||||
|
||||
@@ -58,7 +58,8 @@ def test_map_rectangle_drag_is_wired_to_automatic_analysis() -> None:
|
||||
# the map fits the selection bounds without an animation.
|
||||
assert "map.fitBounds(" in geomap
|
||||
assert "duration: 0" in geomap
|
||||
assert "isStyleLoaded()" not in geomap
|
||||
assert "if (!map || !map.isStyleLoaded()) return" in geomap
|
||||
assert "setStyle(" not in geomap
|
||||
assert "const activeCollection = areaData ?? (fitDataOnChange ? data : null)" in geomap
|
||||
assert "data && fitDataOnChange && !areaData" in geomap
|
||||
assert "resizeObserver.disconnect()" in geomap
|
||||
|
||||
@@ -257,7 +257,7 @@ def test_end_user_dataset_sources_are_human_readable() -> None:
|
||||
assert "getDatasetSourceDisplayName(dataset)" in catalog
|
||||
assert "statusLabel(item.state)" in status
|
||||
assert "Technische modelevaluatie" in detection
|
||||
assert "Nog geen downloads gemaakt." in exports
|
||||
assert "Nog geen recente downloads" in exports
|
||||
|
||||
|
||||
def test_full_area_fast_path_requires_matching_area_and_clipped_operator_provenance() -> None:
|
||||
|
||||
@@ -17,7 +17,8 @@ def test_geomap_exposes_v1_layer_controls_and_feature_inspection_contract() -> N
|
||||
assert "mapStyleReady" in geomap
|
||||
assert "map.on('load'" in geomap
|
||||
assert "if (!map || !mapStyleReady)" in geomap
|
||||
assert "map.isStyleLoaded()" not in geomap
|
||||
assert "if (!map || !map.isStyleLoaded()) return" in geomap
|
||||
assert "setStyle(" not in geomap
|
||||
assert "setLayoutProperty('dataset-fill', 'visibility'" in geomap
|
||||
assert "setPaintProperty('dataset-fill', 'fill-opacity', opacity)" in geomap
|
||||
|
||||
|
||||
@@ -44,7 +44,7 @@ def test_source_inventory_is_compact_honest_and_domain_driven() -> None:
|
||||
assert "source-domain-grid" in styles
|
||||
assert "source-opportunity-domain" in styles
|
||||
assert "section.source-catalog-panel > .panel-title-row" in styles
|
||||
assert "display: grid !important" in styles
|
||||
assert "display: grid" in styles
|
||||
assert "justify-self: start" in styles
|
||||
|
||||
|
||||
|
||||
@@ -24,6 +24,6 @@ def test_demo_workflow_browser_smoke_script_checks_connected_v1_state() -> None:
|
||||
def test_frontend_demo_action_loads_candidate_dataset_details_for_map_layer() -> None:
|
||||
demo_hook = (ROOT / "frontend" / "src" / "hooks" / "useDemoWorkflow.ts").read_text(encoding="utf-8")
|
||||
|
||||
assert "const candidateDataset = projectData?.datasets.find" in demo_hook
|
||||
assert "const candidateDataset = projectData?.datasets?.find" in demo_hook
|
||||
assert "dataset.id === result.candidate_dataset_id" in demo_hook
|
||||
assert "await loadDatasetDetails(result.project_id, candidateDataset)" in demo_hook
|
||||
|
||||
@@ -30,7 +30,7 @@ def test_current_and_historical_results_are_downloadable() -> None:
|
||||
|
||||
|
||||
def test_completed_analysis_hands_off_to_ai_and_downloads_responsively() -> None:
|
||||
app = read("frontend/src/App.tsx")
|
||||
app = read_feature("shell")
|
||||
workspace = read_feature("map_workspace")
|
||||
styles = read("frontend/src/styles/app.css")
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_app_uses_detection_and_segmentation_workflow_hooks() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
|
||||
assert "useDetectionWorkflow" in app
|
||||
assert "useSegmentationWorkflow" in app
|
||||
@@ -39,7 +39,7 @@ def test_segmentation_workflow_hook_owns_segmentation_api_calls() -> None:
|
||||
|
||||
|
||||
def test_app_still_wires_detection_and_segmentation_panels() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
|
||||
assert "<DetectionLab" in app
|
||||
assert "onRunDetection={runDetection}" in app
|
||||
|
||||
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_app_uses_export_and_quality_workflow_hooks() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
|
||||
assert "useExportWorkflow" in app
|
||||
assert "useQualityWorkflow" in app
|
||||
@@ -41,7 +41,7 @@ def test_quality_workflow_hook_owns_quality_api_calls() -> None:
|
||||
|
||||
|
||||
def test_app_still_wires_quality_results_and_export_center() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
quality_panel = read_feature("quality")
|
||||
|
||||
assert "<QualityResultsPanel" in app
|
||||
|
||||
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_app_uses_dataset_workflow_hook() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
|
||||
assert "useDatasetWorkflow" in app
|
||||
assert "from './hooks/useDatasetWorkflow'" in app
|
||||
@@ -41,7 +41,7 @@ def test_dataset_workflow_hook_owns_dataset_api_calls() -> None:
|
||||
|
||||
|
||||
def test_app_still_wires_dataset_ui_callbacks() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
dataset_panel = read_feature("datasets")
|
||||
detail_panel = read_feature("datasets")
|
||||
|
||||
|
||||
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_app_uses_dataset_presentational_components() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
inspector = read_feature("shell")
|
||||
|
||||
assert "from './components/datasets/DatasetPanel'" in app
|
||||
|
||||
@@ -9,7 +9,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_app_uses_quality_and_map_presentational_components() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
|
||||
assert "from './components/quality/QualityResultsPanel'" in app
|
||||
assert "from './components/map/MapWorkspace'" in app
|
||||
@@ -21,7 +21,7 @@ def test_app_uses_quality_and_map_presentational_components() -> None:
|
||||
|
||||
|
||||
def test_map_workspace_lives_in_task_based_workbench_shell() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
styles = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8")
|
||||
|
||||
assert "activeWorkspace === 'map'" in app
|
||||
|
||||
@@ -190,14 +190,11 @@ def test_frontend_and_unraid_icon_assets_are_present() -> None:
|
||||
deploy_icon = (ROOT / "deploy" / "unraid" / "geointel-icon.svg").read_text(encoding="utf-8")
|
||||
frontend_icon = (ROOT / "frontend" / "public" / "geointel-icon.svg").read_text(encoding="utf-8")
|
||||
deploy_png = ROOT / "deploy" / "unraid" / "geointel-icon.png"
|
||||
frontend_png = ROOT / "frontend" / "public" / "geointel-icon.png"
|
||||
index = (ROOT / "frontend" / "index.html").read_text(encoding="utf-8")
|
||||
|
||||
assert "<svg" in deploy_icon
|
||||
assert "<title id=\"title\">GeoIntel</title>" in deploy_icon
|
||||
assert "Een geometrische G als geografische lens" in deploy_icon
|
||||
assert "Een geometrische G als geografische lens" in frontend_icon
|
||||
assert deploy_png.read_bytes() == frontend_png.read_bytes()
|
||||
assert deploy_png.read_bytes() == frontend_png.read_bytes()
|
||||
assert deploy_png.stat().st_size > 1000
|
||||
assert '<link rel="icon" type="image/svg+xml" href="/geointel-icon.svg" />' in index
|
||||
|
||||
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_app_uses_shared_orchestration_hooks() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = (ROOT / "frontend" / "src" / "WorkbenchApp.tsx").read_text(encoding="utf-8")
|
||||
|
||||
assert "useProjectWorkspace" in app
|
||||
assert "useDemoWorkflow" in app
|
||||
@@ -31,7 +31,7 @@ def test_app_uses_shared_orchestration_hooks() -> None:
|
||||
|
||||
|
||||
def test_app_entrypoint_has_clean_encoding_and_react_imports() -> None:
|
||||
app_path = ROOT / "frontend" / "src" / "App.tsx"
|
||||
app_path = ROOT / "frontend" / "src" / "WorkbenchApp.tsx"
|
||||
app_bytes = app_path.read_bytes()
|
||||
app = app_path.read_text(encoding="utf-8")
|
||||
|
||||
@@ -61,21 +61,21 @@ def test_demo_workflow_hook_owns_demo_api_and_cross_module_selection() -> None:
|
||||
|
||||
|
||||
def test_workbench_bootstrap_hook_owns_entrypoint_effects() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
hook = read_feature("shell")
|
||||
|
||||
assert "loadProjects().catch(() => null)" not in app
|
||||
assert "loadDetectionResults().catch(() => null)" not in app
|
||||
assert "loadSegmentationResults().catch(() => null)" not in app
|
||||
assert "loadProjects().catch(() => null)" in hook
|
||||
assert "loadCapabilities().catch(() => null)" in hook
|
||||
assert "loadDetectionModels().catch(() => null)" in hook
|
||||
assert "loadSegmentationModels().catch(() => null)" in hook
|
||||
assert "loadProjects().catch(meld('werkruimtes'))" in hook
|
||||
assert "loadCapabilities().catch(meld('bronkoppelingen'))" in hook
|
||||
assert "loadDetectionModels().catch(meld('detectiemodellen'))" in hook
|
||||
assert "loadSegmentationModels().catch(meld('segmentatiemodellen'))" in hook
|
||||
assert "resetProjectData()" in hook
|
||||
assert "resetDatasetForProject()" in hook
|
||||
assert "loadProjectData(selectedProjectId).catch(() => null)" in hook
|
||||
assert "loadDetectionResults().catch(() => null)" in hook
|
||||
assert "loadSegmentationResults().catch(() => null)" in hook
|
||||
assert "loadProjectData(selectedProjectId).catch(meld('gebieden en bronnen'))" in hook
|
||||
assert "loadDetectionResults().catch(meld('detectieresultaten'))" in hook
|
||||
assert "loadSegmentationResults().catch(meld('segmentatieresultaten'))" in hook
|
||||
|
||||
|
||||
def test_project_workspace_hook_owns_project_area_dataset_loading() -> None:
|
||||
|
||||
@@ -8,7 +8,7 @@ ROOT = Path(__file__).resolve().parents[2]
|
||||
|
||||
|
||||
def test_frontend_shell_has_atlas_workbench_contracts() -> None:
|
||||
app = (ROOT / "frontend" / "src" / "App.tsx").read_text(encoding="utf-8")
|
||||
app = read_feature("shell")
|
||||
css = (ROOT / "frontend" / "src" / "styles" / "atlas-workbench.css").read_text(
|
||||
encoding="utf-8"
|
||||
)
|
||||
|
||||
@@ -34,7 +34,7 @@ def test_ai_labs_use_result_state_blocks() -> None:
|
||||
segmentation_lab = read_feature("segmentation")
|
||||
|
||||
for content in (detection_lab, segmentation_lab):
|
||||
assert 'className="result-state result-state-loading"' in content
|
||||
assert 'className="result-state result-state-error"' in content
|
||||
assert 'className="result-state result-state-empty"' in content
|
||||
assert 'className="result-state result-state-ready"' in content
|
||||
assert "result-state-loading" in content
|
||||
assert "result-state-error" in content
|
||||
assert "result-state-empty" in content
|
||||
assert "result-state-ready" in content
|
||||
|
||||
@@ -20,7 +20,7 @@ def test_status_strip_has_compact_section_surface_contracts() -> None:
|
||||
css = (ROOT / "frontend" / "src" / "styles" / "app.css").read_text(encoding="utf-8")
|
||||
|
||||
assert ".workbench-status-strip" in css
|
||||
assert "background: linear-gradient(180deg, #ffffff, #f7fbf8);" in css
|
||||
assert "background: linear-gradient(180deg, var(--gi-surface), var(--gi-brand-50));" in css
|
||||
assert ".status-strip-grid" in css
|
||||
assert "grid-template-columns: repeat(auto-fit, minmax(10.5rem, 1fr));" in css
|
||||
assert ".status-tile-topline" in css
|
||||
@@ -34,6 +34,6 @@ def test_overview_action_callout_is_visually_secondary() -> None:
|
||||
assert ".overview-action-copy" in css
|
||||
assert ".overview-quick-actions" in css
|
||||
assert ".quick-action-button" in css
|
||||
assert "background: linear-gradient(135deg, rgba(15, 118, 110, 0.08), rgba(255, 255, 255, 0.82));" in css
|
||||
assert "background: linear-gradient(135deg, rgba(15, 118, 110, 0.08), color-mix(in srgb, var(--gi-surface) 82%, transparent));" in css
|
||||
assert "border-left: 4px solid var(--accent);" in css
|
||||
assert "align-content: center;" in css
|
||||
|
||||
@@ -44,5 +44,5 @@ def test_data_workspace_density_css_contracts() -> None:
|
||||
assert ".data-panel-list-block" in css
|
||||
assert ".data-section-label" in css
|
||||
assert "grid-template-columns: repeat(auto-fit, minmax(10rem, 1fr));" in css
|
||||
assert "background: linear-gradient(180deg, #ffffff, #f7fbf8);" in css
|
||||
assert "background: linear-gradient(180deg, var(--gi-surface), var(--gi-brand-50));" in css
|
||||
assert "border-left: 4px solid var(--accent);" in css
|
||||
|
||||
@@ -41,7 +41,7 @@ def test_map_workspace_density_css_contracts() -> None:
|
||||
assert ".map-inspection-surface" in css
|
||||
assert ".map-workspace-shell .map-toolbar" in css
|
||||
assert "grid-template-columns: repeat(auto-fit, minmax(11rem, 1fr));" in css
|
||||
assert "background: linear-gradient(180deg, #ffffff, #f7fbf8);" in css
|
||||
assert "background: linear-gradient(180deg, var(--gi-surface), var(--gi-brand-50));" in css
|
||||
assert "border-left: 4px solid var(--accent);" in css
|
||||
|
||||
|
||||
|
||||
@@ -50,4 +50,4 @@ def test_quality_workspace_density_css_contracts() -> None:
|
||||
assert ".quality-results-shell .quality-history-controls" in css
|
||||
assert "grid-template-columns: repeat(auto-fit, minmax(8.25rem, 1fr));" in css
|
||||
assert "grid-template-columns: repeat(auto-fit, minmax(7.5rem, 1fr));" in css
|
||||
assert "background: linear-gradient(180deg, #ffffff, #f7fbf8);" in css
|
||||
assert "background: linear-gradient(180deg, var(--gi-surface), var(--gi-brand-50));" in css
|
||||
|
||||
@@ -57,7 +57,7 @@ def test_ai_lab_preserves_existing_detection_and_segmentation_controls() -> None
|
||||
assert "onLoadResults" in segmentation
|
||||
assert "onRunQa" in segmentation
|
||||
assert "selectedSegmentationModelConfigured" in segmentation
|
||||
assert "{segmentationItems.length} vlakken geladen" in segmentation
|
||||
assert "${segmentationTotal} vlakken geladen" in segmentation
|
||||
assert "Vergelijk met referentielaag" in segmentation
|
||||
|
||||
|
||||
|
||||
@@ -13,14 +13,14 @@ def test_export_center_exposes_final_handoff_surfaces() -> None:
|
||||
assert 'className="export-center"' in export_center
|
||||
assert 'className="export-center-shell"' in export_center
|
||||
assert 'className="export-summary-surface"' in export_center
|
||||
assert 'aria-label="Export summary"' in export_center
|
||||
assert 'aria-label="Samenvatting van de downloads"' in export_center
|
||||
assert 'className="export-handoff-surface"' in export_center
|
||||
assert 'aria-label="Export handoff readiness"' in export_center
|
||||
assert 'aria-label="Gereedheid voor overdracht"' in export_center
|
||||
assert 'className="export-actions-surface"' in export_center
|
||||
assert 'aria-label="Export artifact actions"' in export_center
|
||||
assert 'aria-label="Acties om resultaten te bewaren"' in export_center
|
||||
assert 'className="export-state-stack"' in export_center
|
||||
assert 'className="export-history-surface export-history-disclosure"' in export_center
|
||||
assert 'aria-label="Export history"' in export_center
|
||||
assert 'aria-label="Downloadgeschiedenis"' in export_center
|
||||
|
||||
|
||||
def test_provider_panel_exposes_final_system_surfaces() -> None:
|
||||
@@ -77,4 +77,4 @@ def test_export_system_density_css_contracts() -> None:
|
||||
assert ".provider-provenance-grid" in css
|
||||
assert ".provider-provenance-card" in css
|
||||
assert "grid-template-columns: repeat(auto-fit, minmax(8rem, 1fr));" in css
|
||||
assert "background: linear-gradient(180deg, #ffffff, #f7fbf8);" in css
|
||||
assert "background: linear-gradient(180deg, var(--gi-surface), var(--gi-brand-50));" in css
|
||||
|
||||
Reference in New Issue
Block a user