## Summary epic r04 - begin refactor ## Change Type - [x] Cowork feature - [ ] Bug fix - [ ] Core AI contribution - [ ] Test / hardening - [ ] Performance - [ ] Documentation ## Related Work Cowork Task: Core Repo: http://34.143.229.138/gitea-admin/fsg-ai-core-assets Core AI Issue: Core Task: Related PR: ## Scope What is intentionally included? What is intentionally NOT included? ## Validation - [ ] Unit tests - [ ] Integration tests - [ ] Manual verification - [ ] Regression check Commands / evidence: ## Security Impact Permission / credential / network / customer data impact: ## Compatibility - [ ] No breaking change - [ ] Breaking change documented ## Reviewer Notes Anything Cowork reviewers should pay attention to. --------- Co-authored-by: Anh Tran Nguyen Minh <anhtnm1@fpt.com> Co-authored-by: Huong Le Thi Thien <huongltt35@fpt.com> Co-authored-by: Nam Pham Dinh Thanh <nampdt@fpt.com> Co-authored-by: Vu Dam Tuan <vudt15@fpt.com> Co-authored-by: Hiep Ha Van <hiephv3@fpt.com> Co-authored-by: Lam Hoang Van <lamhv7@fpt.com> Reviewed-on: #7 Co-authored-by: Duy Le Huu <duylh19@fpt.com>
This commit was merged in pull request #7.
This commit is contained in:
@@ -0,0 +1,138 @@
|
||||
"""Integration test đầu-cuối cho Co4E Studio — dựng THẬT ``Co4ETab`` qua
|
||||
``build_co4e_tab()`` và lái một luồng người dùng thật xuyên qua NHIỀU panel đã
|
||||
tách (canvas, chat, agent/skills list, run control) trong CÙNG MỘT instance,
|
||||
để bắt lỗi mà các characterization test riêng từng panel (test_co4e_canvas_widget,
|
||||
test_co4e_chat_view, test_co4e_runs_page, test_co4e_agent_panel,
|
||||
test_co4e_skills_panel) không thể bắt: các panel đó mỗi cái dựng ĐỘC LẬP, không
|
||||
đi qua ``Co4ETab`` thật nên không lộ lỗi wiring xuyên-panel (ví dụ: alias thiếu,
|
||||
gọi nhầm panel khác, state canvas mất khi chuyển qua trang Runs rồi quay lại).
|
||||
|
||||
PHẠM VI CHỦ ĐỘNG LOẠI TRỪ — KHÔNG bấm nút Run/Stop và KHÔNG gọi bất kỳ
|
||||
method nào dẫn tới ``Co4ERunManager.start()`` (dòng dẫn tới ``AgentWorker``/
|
||||
``QThread``/gọi AI thật) — đúng nguyên tắc đã áp dụng xuyên suốt mọi
|
||||
characterization test của lane N3 (xem ``test_co4e_run_manager_behavior.py``).
|
||||
Trang "Flow Status"/Runs được kiểm ở trạng thái RỖNG (không có run nào), đủ để
|
||||
xác nhận panel + wiring không vỡ khi chuyển trang, không cần một run thật.
|
||||
|
||||
Vì sao chạy trong tiến trình con cô lập HOME/USERPROFILE (giống
|
||||
``test_build_co4e_tab.py``, xem docstring đầu file đó để biết đủ cả 2 cái bẫy
|
||||
CONFIG_DIR/CONFIG_PATH tính lúc import): dựng ``Co4ETab`` thật kéo theo
|
||||
``Co4ERunManager`` (đọc lịch sử run từ ``CO4E_DIR``/``CONFIG_DIR`` lúc
|
||||
``__init__``) — không cô lập sẽ đọc/ghi vào ``~/.cowork_local`` thật của người
|
||||
dùng chạy test.
|
||||
"""
|
||||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import subprocess
|
||||
import sys
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
REPO_PARENT = REPO_ROOT.parent
|
||||
|
||||
_SCRIPT = """
|
||||
import sys
|
||||
sys.path.insert(0, {repo_parent!r})
|
||||
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
from cowork_local.config import AppConfig, CONFIG_DIR
|
||||
from cowork_local.state import AppContext
|
||||
from cowork_local.core.co4e import Step
|
||||
from cowork_local.presentation.co4e.co4e_tab import build_co4e_tab
|
||||
|
||||
sandbox = sys.argv[1]
|
||||
assert str(CONFIG_DIR).startswith(sandbox), "khong co lap: CONFIG_DIR=" + str(CONFIG_DIR)
|
||||
|
||||
app = QApplication([])
|
||||
ctx = AppContext(AppConfig.load())
|
||||
|
||||
|
||||
class _FakeWorkflowService:
|
||||
\"\"\"build_co4e_tab() hien tai chua dung toi (xem presentation/co4e/co4e_tab.py) -
|
||||
chi can mot doi tuong bat ky de kiem factory nhan dung tham so bat buoc thu hai.\"\"\"
|
||||
|
||||
|
||||
tab = build_co4e_tab(ctx, _FakeWorkflowService())
|
||||
|
||||
# ---- 1) sidebar: 4 panel da tach deu co mat, danh sach rong luc moi dung ---
|
||||
assert tab.wf_list.count() == 0, "wf_list phai rong luc moi dung"
|
||||
assert tab.agent_list.count() >= 0 # AgentListPanel.list_widget qua alias
|
||||
assert tab.skill_list.count() >= 0 # SkillsListPanel.list_widget qua alias
|
||||
assert tab.runs_table.rowCount() == 0, "Flow Status phai rong khi chua co run nao"
|
||||
|
||||
# ---- 2) "New" workflow (wf_new_btn -> _new_workflow) -----------------------
|
||||
tab.wf_new_btn.click()
|
||||
assert tab.canvas.nodes() == [], "flow moi phai la canvas rong"
|
||||
assert tab._wf.name, "flow moi phai co ten (untitled)"
|
||||
|
||||
# ---- 3) them 2 node ket noi tren canvas THAT (khong drag-drop, goi truc tiep
|
||||
# dung method public da duoc characterization test_co4e_canvas_widget.py khoa
|
||||
# hanh vi - integration test nay chi kiem NO CHAY DUOC xuyen qua Co4ETab thuc,
|
||||
# khong lap lai chi tiet hanh vi canvas) --------------------------------------
|
||||
n1 = tab.canvas.add_node(Step(label="Buoc 1"), x=60, y=60)
|
||||
n2_id = None
|
||||
tab.canvas.add_step_below(n1)
|
||||
assert len(tab.canvas.nodes()) == 2, "canvas phai co 2 node sau add_node + add_step_below"
|
||||
assert len(tab.canvas.edges()) == 1, "add_step_below phai tu noi edge tu node truoc"
|
||||
|
||||
# ---- 4) mo/thu gon khung chat (ChatPanel + _toggle_messages xuyen panel) ---
|
||||
assert tab.chat_stack.isHidden(), "chat phai COLLAPSED mac dinh (dung dac ta ChatPanel)"
|
||||
tab.chat_toggle_btn.click()
|
||||
assert not tab.chat_stack.isHidden(), "bam nut thu/mo phai HIEN khung chat"
|
||||
tab.chat_toggle_btn.click()
|
||||
assert tab.chat_stack.isHidden(), "bam lan 2 phai AN lai (toggle dung 2 chieu)"
|
||||
|
||||
# ---- 5) chuyen qua trang Flow Status (RunsPagePanel) roi quay lai flow editor,
|
||||
# xac nhan canvas KHONG mat 2 node da them o buoc 3 (rui ro thuc su cua viec
|
||||
# tach RunsPagePanel: state flow co song sot qua center_stack.setCurrentIndex?)
|
||||
tab.runs_btn.setChecked(True)
|
||||
assert tab.center_stack.currentIndex() == 0, "bam Flow Status phai chuyen sang trang Runs"
|
||||
assert tab.runs_table.rowCount() == 0, "van chua co run nao, bang phai rong"
|
||||
tab.runs_btn.setChecked(False)
|
||||
assert tab.center_stack.currentIndex() == 1, "bo chon Flow Status phai tro lai flow editor"
|
||||
assert len(tab.canvas.nodes()) == 2, "quay lai flow editor KHONG duoc mat node da them truoc do"
|
||||
|
||||
# ---- CHU DINH KHONG lam: khong bam run_stop_btn/bat ky nut Run nao, khong goi
|
||||
# tab.manager.start(...) - do se tao AgentWorker/QThread thuc va co the goi AI
|
||||
# thuc (ngoai pham vi integration test nay, xem docstring dau file).
|
||||
|
||||
print("INTEGRATION_OK")
|
||||
"""
|
||||
|
||||
|
||||
def test_co4e_end_to_end_qua_nhieu_panel_da_tach(tmp_path):
|
||||
sandbox = tmp_path / "home"
|
||||
sandbox.mkdir()
|
||||
|
||||
env = dict(os.environ)
|
||||
env["HOME"] = str(sandbox)
|
||||
env["USERPROFILE"] = str(sandbox)
|
||||
env["QT_QPA_PLATFORM"] = "offscreen"
|
||||
env.pop("HOMEDRIVE", None)
|
||||
env.pop("HOMEPATH", None)
|
||||
|
||||
script = _SCRIPT.format(repo_parent=str(REPO_PARENT))
|
||||
result = subprocess.run(
|
||||
[sys.executable, "-c", script, str(sandbox)],
|
||||
cwd=str(REPO_ROOT),
|
||||
env=env,
|
||||
capture_output=True,
|
||||
text=True,
|
||||
timeout=60,
|
||||
)
|
||||
|
||||
assert result.returncode == 0, (
|
||||
f"integration test that bai (exit {result.returncode}):\n"
|
||||
f"--- stdout ---\n{result.stdout}\n--- stderr ---\n{result.stderr}"
|
||||
)
|
||||
assert "INTEGRATION_OK" in result.stdout, result.stdout
|
||||
|
||||
# Sandbox khong duoc dung: khong co run nao duoc kich hoat trong luot nay,
|
||||
# nen Co4ERunManager khong co gi de ghi xuong dia (_save_history chi ghi khi
|
||||
# changed.emit() that su co run/thay doi - _new_workflow khong dung toi
|
||||
# manager, add_node/canvas khong dung toi manager).
|
||||
assert not (sandbox / ".cowork_local" / "co4e" / "run_history.json").exists(), (
|
||||
"chua co run nao thi khong duoc tu ghi lich su run xuong dia"
|
||||
)
|
||||
Reference in New Issue
Block a user