import asyncio import json import os from pathlib import Path def test_result_browser_prefers_latest_manifest_and_shows_subfamily_evidence(monkeypatch, tmp_path): from apps.web.vue3 import main as web_main workspace_root = tmp_path / "workspace" final_dir = workspace_root / "job-results" / "final" final_dir.mkdir(parents=True) image = final_dir / "Target.PEBP.target-Os.ref-At.subfamily_evidence.motif.png" image.write_bytes(b"png") success = final_dir / "Target.PEBP.target-Os.ref-At.subfamily_evidence.motif.manifest.json" success.write_text( json.dumps( { "stage": "motif", "status": "success", "prefix": "Os.PEBP", "output_prefix": "Target.PEBP.target-Os.ref-At.subfamily_evidence", "scope_id": "PEBP.target-Os.ref-At.target_plus_reference", "scope_mode": "target_plus_reference", "analysis_route": "subfamily_evidence", "result_group": "motif_subfamily_evidence", "elapsed_sec": 3.0, "artifacts": { "motif_plot_png": { "artifact": "motif_plot", "path": f"final/{image.name}", "type": "image", } }, } ), encoding="utf-8", ) failed = final_dir / "Os.PEBP.target_only.motif.manifest.json" failed.write_text( json.dumps( { "stage": "motif", "status": "failed", "prefix": "Os.PEBP", "scope_id": "PEBP.target-Os.target_only", "analysis_route": "multi_species", "parameters": {"error": "old failed attempt"}, "artifacts": {}, } ), encoding="utf-8", ) os.utime(failed, (1, 1)) os.utime(success, (2, 2)) monkeypatch.setattr(web_main, "WORKSPACE_ROOT", workspace_root) result = asyncio.run(web_main.get_results(job_id="job-results", stage="motif")) assert result["motif"]["status"] == "success" assert image.name in json.dumps(result["motif"], ensure_ascii=False) def test_result_panel_has_three_persistent_workflow_groups(): html = (Path(__file__).resolve().parents[2] / "apps/web/vue3/index.html").read_text(encoding="utf-8") assert "RNA-seq" in html assert "基因家族" in html assert "WGS2GWAS(遗传变异与群体分析)" in html assert "const resultGroups = computed" in html assert "const groupStages = stages.filter(stage => resultGroupNameForStage(stage.name) === group.name);" in html assert "wgsPopulationGwasResultRank(a.name) - wgsPopulationGwasResultRank(b.name)" in html assert "name: 'wgs_qc'" in html assert "name: 'wgs_maf_missing_filter'" in html assert "await refreshResults(completedJobId, stageName);" in html assert "await refreshResults(latestConversation.job_id);" in html