mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 19:21:50 +02:00
test: add function scoped rpc_widgets e2e test; closes #510
This commit is contained in:
@ -29,7 +29,7 @@ def gui_id():
|
||||
|
||||
|
||||
@pytest.fixture
|
||||
def connected_client_gui_obj(gui_id, bec_client_lib):
|
||||
def connected_client_gui_obj(qtbot, gui_id, bec_client_lib):
|
||||
"""
|
||||
Fixture to create a new BECGuiClient object and start a server in the background.
|
||||
|
||||
@ -38,6 +38,7 @@ def connected_client_gui_obj(gui_id, bec_client_lib):
|
||||
gui = BECGuiClient(gui_id=gui_id)
|
||||
try:
|
||||
gui.start(wait=True)
|
||||
qtbot.waitUntil(lambda: hasattr(gui, "bec"), timeout=5000)
|
||||
yield gui
|
||||
finally:
|
||||
gui.kill_server()
|
||||
|
@ -110,6 +110,7 @@ def test_rpc_waveform_scan(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
assert plt_data["bpm4d-bpm4d"]["y"] == last_scan_data["bpm4d"]["bpm4d"].val
|
||||
|
||||
|
||||
@pytest.mark.timeout(100)
|
||||
def test_async_plotting(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
gui = connected_client_gui_obj
|
||||
dock = gui.bec
|
||||
@ -122,12 +123,12 @@ def test_async_plotting(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
# Test add
|
||||
dev.waveform.sim.select_model("GaussianModel")
|
||||
dev.waveform.sim.params = {"amplitude": 1000, "center": 4000, "sigma": 300}
|
||||
dev.waveform.async_update.put("add")
|
||||
dev.waveform.waveform_shape.put(10000)
|
||||
dev.waveform.async_update.set("add").wait()
|
||||
dev.waveform.waveform_shape.set(1000).wait()
|
||||
wf = dock.new("wf_dock").new("Waveform")
|
||||
curve = wf.plot(y_name="waveform")
|
||||
|
||||
status = scans.line_scan(dev.samx, -5, 5, steps=10, exp_time=0.05, relative=False)
|
||||
status = scans.line_scan(dev.samx, -5, 5, steps=5, exp_time=0.05, relative=False)
|
||||
status.wait()
|
||||
|
||||
# Wait for the scan to finish and the data to be available in history
|
||||
|
88
tests/end-2-end/test_rpc_widgets_e2e.py
Normal file
88
tests/end-2-end/test_rpc_widgets_e2e.py
Normal file
@ -0,0 +1,88 @@
|
||||
from typing import TYPE_CHECKING
|
||||
|
||||
import pytest
|
||||
|
||||
from bec_widgets.cli.rpc.rpc_base import RPCBase, RPCReference
|
||||
|
||||
# pylint: disable=protected-access
|
||||
# pylint: disable=used-before-assignment
|
||||
|
||||
|
||||
def wait_for_namespace_change(
|
||||
qtbot,
|
||||
gui: RPCBase,
|
||||
parent_widget: RPCBase | RPCReference,
|
||||
object_name: str,
|
||||
widget_gui_id: str,
|
||||
timeout: int = 10000,
|
||||
exists: bool = True,
|
||||
):
|
||||
"""Utility method to wait for the namespace to be created in the widget."""
|
||||
# GUI object is not registered in the registry (yet)
|
||||
if parent_widget is gui:
|
||||
|
||||
def check_reference_registered():
|
||||
# Check that the widget is in ipython registry
|
||||
obj = gui._ipython_registry.get(widget_gui_id, None)
|
||||
if obj is None:
|
||||
if not exists:
|
||||
return True
|
||||
return False
|
||||
# _rpc_references do not exist on BECGuiClient class somehow..
|
||||
|
||||
else:
|
||||
|
||||
def check_reference_registered():
|
||||
obj = gui._ipython_registry.get(widget_gui_id, None)
|
||||
if obj is None:
|
||||
if not exists:
|
||||
return True
|
||||
return False
|
||||
ref = parent_widget._rpc_references.get(widget_gui_id, None)
|
||||
if exists:
|
||||
return ref is not None
|
||||
return ref is None
|
||||
|
||||
try:
|
||||
qtbot.waitUntil(check_reference_registered, timeout=timeout)
|
||||
except Exception as e:
|
||||
raise RuntimeError(
|
||||
f"Timeout waiting for {parent_widget.object_name}.{object_name} to be created."
|
||||
) from e
|
||||
|
||||
|
||||
def create_widget(
|
||||
qtbot, gui: RPCBase, dock_area: RPCReference, widget_cls_name: str
|
||||
) -> tuple[RPCReference, RPCReference, RPCReference]:
|
||||
"""Utility method to create a widget and wait for the namespaces to be created."""
|
||||
dock = dock_area.new(widget=widget_cls_name)
|
||||
wait_for_namespace_change(qtbot, gui, dock_area, dock.object_name, dock._gui_id)
|
||||
widget = dock.element_list[-1]
|
||||
wait_for_namespace_change(qtbot, gui, dock, widget.object_name, widget._gui_id)
|
||||
return dock, widget
|
||||
|
||||
|
||||
@pytest.mark.timeout(100)
|
||||
def test_available_widgets(qtbot, connected_client_gui_obj):
|
||||
"""This test checks that all widgets that are available via gui.available_widgets can be created and removed."""
|
||||
gui = connected_client_gui_obj
|
||||
dock_area = gui.bec
|
||||
for object_name in gui.available_widgets.__dict__:
|
||||
# Skip private attributes
|
||||
if object_name.startswith("_"):
|
||||
continue
|
||||
# Skip VSCode widget as Code server is not available in the Docker image
|
||||
if object_name == "VSCodeEditor":
|
||||
continue
|
||||
# Create widget the widget
|
||||
dock, widget = create_widget(
|
||||
qtbot, gui, dock_area, getattr(gui.available_widgets, object_name)
|
||||
)
|
||||
# The create_widget method already waits for the widget to be created
|
||||
# and added to the ipython registry. We can here assert if the dock_area
|
||||
# has the dock and the widget
|
||||
assert gui._ipython_registry.get(widget._gui_id, None) is not None
|
||||
assert hasattr(dock_area, dock.object_name)
|
||||
assert hasattr(dock, widget.object_name)
|
||||
# Now we remove the widget again
|
||||
dock_area.delete(dock.object_name)
|
Reference in New Issue
Block a user