修复 Studio 失败测试并新增合并门禁
把丢失的 box 录像放回 apps/studio/tests/data/,修掉第 3 节 3–10 号与两处过时测试桩, 注册 timing 标记并让根目录收集零错误;新增 tools/gate.ps1 与可选的 pre-push 钩子。 验证:studio 524 通过 19 跳过、shared 467 通过 18 跳过、ui_check 632 项 0 失败、gate.ps1 退出码 0。 细节见 docs/test-repair-plan.zh.md。
This commit is contained in:
@@ -0,0 +1,57 @@
|
||||
"""Plain helpers the studio UI tests share, importable without a ``tests`` package.
|
||||
|
||||
These four functions used to live in ``conftest.py`` and were imported as
|
||||
``from tests.conftest import ...``. That import only worked when pytest ran with
|
||||
``apps/studio`` in ``sys.path`` (or as the working directory): run from the
|
||||
repository root, the ``tests`` directory of *any* product could be shadowed, and
|
||||
the suite could not be collected at all. A module beside the tests, with the
|
||||
tests' own directory on ``sys.path``, has none of that ambiguity.
|
||||
|
||||
Fixtures stay in ``conftest.py`` (pytest discovers them); only the functions a
|
||||
test imports by name live here.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
|
||||
def visible_descendants(widget):
|
||||
"""Yield every visible descendant widget of ``widget``."""
|
||||
for child in widget.findChildren(object):
|
||||
if not hasattr(child, "isVisible") or not hasattr(child, "geometry"):
|
||||
continue
|
||||
if child.isVisible():
|
||||
yield child
|
||||
|
||||
|
||||
def show_window(window, size):
|
||||
"""Show a window at ``size`` and flush pending Qt events."""
|
||||
from PySide6.QtWidgets import QApplication
|
||||
|
||||
window.resize(*size)
|
||||
window.show()
|
||||
QApplication.processEvents()
|
||||
return window
|
||||
|
||||
|
||||
def running_window(make_window):
|
||||
"""Return a running window backed by a controllable test worker."""
|
||||
import ui_check
|
||||
|
||||
window = show_window(
|
||||
make_window(sensor_type="box", source_mode="camera"),
|
||||
(1440, 880),
|
||||
)
|
||||
stuck = ui_check._StuckWorker()
|
||||
window._ensure_workers = lambda: None
|
||||
window._box_worker = stuck
|
||||
window._finger_worker = stuck
|
||||
window._start_run()
|
||||
window._run_timer.stop()
|
||||
window._set_phase("running")
|
||||
return window, stuck
|
||||
|
||||
|
||||
def finish_run(window, stuck):
|
||||
"""Stop a test run and release its controllable worker."""
|
||||
window._stop_run(reason="user_stop")
|
||||
stuck.release()
|
||||
Reference in New Issue
Block a user