mirror of
https://github.com/bec-project/bec_widgets.git
synced 2026-04-10 02:30:54 +02:00
Compare commits
10 Commits
docs/wavef
...
test/end_2
| Author | SHA1 | Date | |
|---|---|---|---|
| a8241fd1bb | |||
| 1c4b134f05 | |||
| dfab5512e4 | |||
| 2641230a6e | |||
| 929b1c0e4c | |||
| dc8fe2af69 | |||
| 0bb0d94fd7 | |||
| 9aae8b706b | |||
| e53a94ebd1 | |||
| 91b59adf78 |
@@ -217,7 +217,8 @@ end-2-end-conda:
|
||||
- pip install -e ./ophyd_devices
|
||||
|
||||
- pip install -e .[dev,pyside6]
|
||||
- pytest -v --files-path ./ --start-servers --flush-redis --random-order ./tests/end-2-end
|
||||
- pytest -v --files-path ./ --start-servers --random-order ./tests/end-2-end
|
||||
# - pytest -v --files-path ./ --start-servers --flush-redis --random-order ./tests/end-2-end
|
||||
|
||||
artifacts:
|
||||
when: on_failure
|
||||
|
||||
@@ -418,6 +418,12 @@ class BECProgressBar(RPCBase):
|
||||
>>> progressbar.label_template = "$value / $percentage %"
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def _get_label(self) -> str:
|
||||
"""
|
||||
Return the label text. mostly used for testing rpc.
|
||||
"""
|
||||
|
||||
|
||||
class BECQueue(RPCBase):
|
||||
"""Widget to display the BEC queue."""
|
||||
@@ -433,9 +439,9 @@ class BECStatusBox(RPCBase):
|
||||
"""An autonomous widget to display the status of BEC services."""
|
||||
|
||||
@rpc_call
|
||||
def remove(self):
|
||||
def get_server_state(self) -> "str":
|
||||
"""
|
||||
Cleanup the BECConnector
|
||||
Get the state ("RUNNING", "BUSY", "IDLE", "ERROR") of the BEC server
|
||||
"""
|
||||
|
||||
|
||||
@@ -1354,23 +1360,7 @@ class LMFitDialog(RPCBase):
|
||||
class LogPanel(RPCBase):
|
||||
"""Displays a log panel"""
|
||||
|
||||
@rpc_call
|
||||
def set_plain_text(self, text: str) -> None:
|
||||
"""
|
||||
Set the plain text of the widget.
|
||||
|
||||
Args:
|
||||
text (str): The text to set.
|
||||
"""
|
||||
|
||||
@rpc_call
|
||||
def set_html_text(self, text: str) -> None:
|
||||
"""
|
||||
Set the HTML text of the widget.
|
||||
|
||||
Args:
|
||||
text (str): The text to set.
|
||||
"""
|
||||
...
|
||||
|
||||
|
||||
class Minesweeper(RPCBase): ...
|
||||
|
||||
@@ -439,9 +439,12 @@ class BECGuiClient(RPCBase):
|
||||
names_in_registry = list(self._ipython_registry.keys())
|
||||
names_in_server_state = list(self._server_registry.keys())
|
||||
remove_ids = list(set(names_in_registry) - set(names_in_server_state))
|
||||
# First we clean up the rpc references on the RPCBase objects and the namespace
|
||||
self._cleanup_rpc_references_on_rpc_base(remove_ids)
|
||||
# Next we drop them from the registry
|
||||
for widget_id in remove_ids:
|
||||
self._ipython_registry.pop(widget_id)
|
||||
self._cleanup_rpc_references_on_rpc_base(remove_ids)
|
||||
|
||||
# Clear the exposed widgets
|
||||
self._exposed_widgets.clear() # No longer needed I think
|
||||
|
||||
@@ -449,6 +452,7 @@ class BECGuiClient(RPCBase):
|
||||
"""Cleanup the rpc references on the RPCBase object"""
|
||||
if not remove_ids:
|
||||
return
|
||||
# Loop over all widgets in the ipython registry
|
||||
for widget in self._ipython_registry.values():
|
||||
to_delete = []
|
||||
for attr_name, gui_id in widget._rpc_references.items():
|
||||
@@ -460,6 +464,14 @@ class BECGuiClient(RPCBase):
|
||||
if attr_name.startswith("elements."):
|
||||
delattr(widget.elements, attr_name.split(".")[1])
|
||||
widget._rpc_references.pop(attr_name)
|
||||
# Loop over gui main window, this is not stored in the ipython registry due to recursive references
|
||||
for attr_name, gui_id in self._rpc_references.items():
|
||||
to_delete = []
|
||||
if gui_id in remove_ids:
|
||||
to_delete.append(attr_name)
|
||||
for attr_name in to_delete:
|
||||
delattr(self, attr_name)
|
||||
self._rpc_references.pop(attr_name)
|
||||
|
||||
def _set_dynamic_attributes(self, obj: object, name: str, value: Any) -> None:
|
||||
"""Add an object to the namespace"""
|
||||
@@ -471,6 +483,7 @@ class BECGuiClient(RPCBase):
|
||||
|
||||
def _add_registry_to_namespace(self) -> None:
|
||||
"""Add registry to namespace"""
|
||||
|
||||
# Add dock areas
|
||||
dock_area_states = [
|
||||
state
|
||||
|
||||
@@ -307,9 +307,9 @@ def main():
|
||||
# display message, for people to let it terminate gracefully
|
||||
print("Caught SIGINT, exiting")
|
||||
# Widgets should be all closed.
|
||||
with RPCRegister.delayed_broadcast():
|
||||
for widget in QApplication.instance().topLevelWidgets():
|
||||
widget.close()
|
||||
# with RPCRegister.delayed_broadcast():
|
||||
# for widget in QApplication.instance().topLevelWidgets():
|
||||
# widget.close()
|
||||
app.quit()
|
||||
|
||||
# gui.bec.close()
|
||||
|
||||
@@ -117,7 +117,9 @@ class WebsiteWidget(BECWidget, QWidget):
|
||||
"""
|
||||
Cleanup the widget
|
||||
"""
|
||||
|
||||
self.website.page().deleteLater()
|
||||
super().cleanup()
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
|
||||
@@ -21,6 +21,7 @@ class BECProgressBar(BECWidget, QWidget):
|
||||
"set_minimum",
|
||||
"label_template",
|
||||
"label_template.setter",
|
||||
"_get_label",
|
||||
]
|
||||
ICON_NAME = "page_control"
|
||||
|
||||
@@ -236,6 +237,10 @@ class BECProgressBar(BECWidget, QWidget):
|
||||
(value - self._user_minimum) / (self._user_maximum - self._user_minimum) * self._maximum
|
||||
)
|
||||
|
||||
def _get_label(self) -> str:
|
||||
"""Return the label text. mostly used for testing rpc."""
|
||||
return self.center_label.text()
|
||||
|
||||
|
||||
if __name__ == "__main__": # pragma: no cover
|
||||
app = QApplication(sys.argv)
|
||||
|
||||
@@ -80,6 +80,8 @@ class BECStatusBox(BECWidget, CompactPopupWidget):
|
||||
service_update = Signal(BECServiceInfoContainer)
|
||||
bec_core_state = Signal(str)
|
||||
|
||||
USER_ACCESS = ["get_server_state"]
|
||||
|
||||
def __init__(
|
||||
self,
|
||||
parent=None,
|
||||
@@ -168,6 +170,10 @@ class BECStatusBox(BECWidget, CompactPopupWidget):
|
||||
self.set_global_state("emergency" if status == "NOTCONNECTED" else "success")
|
||||
self.service_update.emit(self.status_container[self.box_name]["info"])
|
||||
|
||||
def get_server_state(self) -> str:
|
||||
"""Get the state ("RUNNING", "BUSY", "IDLE", "ERROR") of the BEC server"""
|
||||
return self.status_container[self.box_name]["info"].status
|
||||
|
||||
def _update_status_container(
|
||||
self, service_name: str, status: BECStatus, info: dict, metrics: dict = None
|
||||
) -> None:
|
||||
|
||||
@@ -380,6 +380,8 @@ class LogPanelToolbar(QWidget):
|
||||
class LogPanel(TextBox):
|
||||
"""Displays a log panel"""
|
||||
|
||||
USER_ACCESS = [] # Overwrite user access from TextBox
|
||||
|
||||
ICON_NAME = "terminal"
|
||||
_new_messages = Signal()
|
||||
service_list_update = Signal(dict, set)
|
||||
|
||||
@@ -1,8 +1,13 @@
|
||||
"""This module contains fixtures that are used in the end-2-end tests."""
|
||||
|
||||
import random
|
||||
from typing import Any, Generator
|
||||
|
||||
import pytest
|
||||
from bec_lib.client import BECClient
|
||||
from bec_lib.redis_connector import RedisConnector
|
||||
from bec_lib.service_config import ServiceConfig
|
||||
from bec_lib.tests.utils import wait_for_empty_queue
|
||||
|
||||
from bec_widgets.cli.client_utils import BECGuiClient, _start_plot_process
|
||||
from bec_widgets.utils import BECDispatcher
|
||||
@@ -44,14 +49,43 @@ def connected_client_gui_obj(gui_id, bec_client_lib):
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def connected_gui_with_scope_session(gui_id, bec_client_lib):
|
||||
def bec_client_lib_with_demo_config_session(
|
||||
bec_redis_fixture, bec_services_config_file_path, bec_servers
|
||||
):
|
||||
"""Session-scoped fixture to create a BECClient object with a demo configuration."""
|
||||
config = ServiceConfig(bec_services_config_file_path)
|
||||
bec = BECClient(config, RedisConnector, forced=True, wait_for_server=True)
|
||||
bec.start()
|
||||
bec.config.load_demo_config()
|
||||
try:
|
||||
yield bec
|
||||
finally:
|
||||
bec.shutdown()
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def bec_client_lib_session(bec_client_lib_with_demo_config_session):
|
||||
"""Session-scoped fixture to create a BECClient object with a demo configuration."""
|
||||
bec = bec_client_lib_with_demo_config_session
|
||||
bec.queue.request_queue_reset()
|
||||
bec.queue.request_scan_continuation()
|
||||
wait_for_empty_queue(bec)
|
||||
yield bec
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def connected_gui_and_bec_with_scope_session(bec_client_lib_session):
|
||||
"""
|
||||
Fixture to create a new BECGuiClient object and start a server in the background.
|
||||
|
||||
This fixture is scoped to the session, meaning it remains alive for all tests in the session.
|
||||
We can use this fixture to create a gui object that is used across multiple tests, and
|
||||
simulate a real-world scenario where the gui is not restarted for each test.
|
||||
|
||||
Returns:
|
||||
The gui object as for the CLI and bec_client_lib object.
|
||||
"""
|
||||
gui_id = "GUIMainWindow_TEST"
|
||||
gui = BECGuiClient(gui_id=gui_id)
|
||||
try:
|
||||
gui.start(wait=True)
|
||||
|
||||
@@ -192,7 +192,7 @@ def test_rpc_gui_obj(connected_client_gui_obj, qtbot):
|
||||
assert gui_info[mw._gui_id]["visible"]
|
||||
|
||||
yw = gui.new("Y")
|
||||
assert len(gui.windows) == 2
|
||||
qtbot.waitUntil(lambda: len(gui.windows) == 2, timeout=3000)
|
||||
yw.remove()
|
||||
assert len(gui.windows) == 1 # only bec is left
|
||||
|
||||
|
||||
5
tests/end-2-end/test_bec_rpc_test.py
Normal file
5
tests/end-2-end/test_bec_rpc_test.py
Normal file
@@ -0,0 +1,5 @@
|
||||
def test_rpc_gui_obj(connected_gui_and_bec_with_scope_session):
|
||||
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
for key in gui.available_widgets.__dict__:
|
||||
gui.new().new().new(key)
|
||||
@@ -147,8 +147,8 @@ def test_rpc_motor_map(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
motor_map = dock.new("mm_dock").new("MotorMap")
|
||||
motor_map.map(x_name="samx", y_name="samy")
|
||||
|
||||
initial_pos_x = dev.samx.read()["samx"]["value"]
|
||||
initial_pos_y = dev.samy.read()["samy"]["value"]
|
||||
initial_pos_x = dev.samx.read(cached=False)["samx"]["value"]
|
||||
initial_pos_y = dev.samy.read(cached=False)["samy"]["value"]
|
||||
|
||||
status = scans.mv(dev.samx, 1, dev.samy, 2, relative=True)
|
||||
status.wait()
|
||||
@@ -159,11 +159,15 @@ def test_rpc_motor_map(qtbot, bec_client_lib, connected_client_gui_obj):
|
||||
# check plotted data
|
||||
motor_map_data = motor_map.get_data()
|
||||
|
||||
np.testing.assert_equal(
|
||||
[motor_map_data["x"][0], motor_map_data["y"][0]], [initial_pos_x, initial_pos_y]
|
||||
np.testing.assert_allclose(
|
||||
[motor_map_data["x"][0], motor_map_data["y"][0]],
|
||||
[initial_pos_x, initial_pos_y],
|
||||
atol=motor_map.precision,
|
||||
)
|
||||
np.testing.assert_equal(
|
||||
[motor_map_data["x"][-1], motor_map_data["y"][-1]], [final_pos_x, final_pos_y]
|
||||
np.testing.assert_allclose(
|
||||
[motor_map_data["x"][-1], motor_map_data["y"][-1]],
|
||||
[final_pos_x, final_pos_y],
|
||||
atol=motor_map.precision,
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -62,7 +62,26 @@ def test_run_line_scan_with_parameters_e2e(scan_control, bec_client_lib, qtbot):
|
||||
|
||||
# Run the scan
|
||||
scan_control.button_run_scan.click()
|
||||
time.sleep(2)
|
||||
# Wait for scan to start
|
||||
qtbot.waitUntil(
|
||||
lambda: len(queue.queue_storage.current_scan_queue["primary"]["info"]) > 0, timeout=3000
|
||||
)
|
||||
# Get scan_id
|
||||
scan_id = queue.queue_storage.current_scan_queue["primary"]["info"][0]["scan_id"][0]
|
||||
# Wait until scan finishes, queue empty
|
||||
qtbot.waitUntil(
|
||||
lambda: len(queue.queue_storage.current_scan_queue["primary"]["info"]) == 0, timeout=3000
|
||||
)
|
||||
|
||||
# Wait until scan_id is in history
|
||||
def _wait_for_scan_in_hisotry():
|
||||
if len(queue.scan_storage.storage) == 0:
|
||||
return False
|
||||
# Once items appear in storage, the last one hast to be the one we just scanned
|
||||
return queue.scan_storage.storage[-1].status_message.info["scan_id"] == scan_id
|
||||
|
||||
qtbot.waitUntil(_wait_for_scan_in_hisotry, timeout=3000)
|
||||
# time.sleep(2)
|
||||
|
||||
last_scan = queue.scan_storage.storage[-1]
|
||||
assert last_scan.status_message.info["scan_name"] == scan_name
|
||||
|
||||
765
tests/end-2-end/test_widgets_rpc_e2e.py
Normal file
765
tests/end-2-end/test_widgets_rpc_e2e.py
Normal file
@@ -0,0 +1,765 @@
|
||||
"""
|
||||
End-to-end tests single gui instance across the full session.
|
||||
|
||||
Each test will use the same gui instance, simulating a real-world scenario where the gui is not
|
||||
restarted for each test. The interaction is tested through the rpc calls.
|
||||
|
||||
Note: wait_for_namespace_created is a utility method that helps to wait for the namespace to be
|
||||
created in the gui. This is necessary because the rpc calls are asynchronous and the namespace
|
||||
may not be created immediately after the rpc call is made.
|
||||
"""
|
||||
|
||||
import random
|
||||
from typing import Generator
|
||||
|
||||
import numpy as np
|
||||
import pytest
|
||||
|
||||
from bec_widgets.cli.rpc.rpc_base import RPCBase, RPCReference
|
||||
|
||||
PYTEST_TIMEOUT = 50
|
||||
|
||||
|
||||
# pylint: disable=redefined-outer-name
|
||||
# pylint: disable=too-many-arguments
|
||||
# pylint: disable=protected-access
|
||||
# pylint: disable=unused-variable
|
||||
|
||||
|
||||
def wait_for_namespace_change(
|
||||
qtbot,
|
||||
gui: RPCBase,
|
||||
widget: RPCBase | RPCReference,
|
||||
attr_name: str,
|
||||
timeout: int = 5000,
|
||||
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 widget is gui:
|
||||
|
||||
def check_reference_registered():
|
||||
return hasattr(gui, attr_name)
|
||||
|
||||
else:
|
||||
|
||||
def check_reference_registered():
|
||||
obj = gui._ipython_registry.get(widget._gui_id, None)
|
||||
if obj is None:
|
||||
return False
|
||||
ref = obj._rpc_references.get(attr_name, None)
|
||||
if exists:
|
||||
return ref is not None
|
||||
return ref is None
|
||||
|
||||
qtbot.waitUntil(check_reference_registered, timeout=timeout)
|
||||
|
||||
|
||||
@pytest.fixture(scope="session")
|
||||
def random_generator_from_seed(request):
|
||||
"""Fixture to get a random seed for the following tests."""
|
||||
seed = request.config.getoption("--random-order-seed").split(":")[-1]
|
||||
try:
|
||||
seed = int(seed)
|
||||
except ValueError: # Should not be required...
|
||||
seed = 42
|
||||
rng = random.Random(seed)
|
||||
yield rng
|
||||
|
||||
|
||||
# @pytest.fixture(scope="session")
|
||||
# def random_generator_from_seed(random_number_gen):
|
||||
# for val in random_number_gen:
|
||||
# yield val
|
||||
|
||||
|
||||
def create_widget(
|
||||
qtbot, gui: RPCBase, widget_cls_name: str
|
||||
) -> tuple[RPCReference, RPCReference, RPCReference]:
|
||||
"""Utility method to create a widget and wait for the namespaces to be created."""
|
||||
dock_area = gui.new()
|
||||
wait_for_namespace_change(qtbot, gui, gui, dock_area.widget_name)
|
||||
dock = dock_area.new(widget=widget_cls_name)
|
||||
wait_for_namespace_change(qtbot, gui, dock_area, dock.widget_name)
|
||||
widget = dock.element_list[-1]
|
||||
wait_for_namespace_change(qtbot, gui, dock, widget.widget_name)
|
||||
return dock_area, dock, widget
|
||||
|
||||
|
||||
def maybe_remove_widget(
|
||||
qtbot, gui: RPCBase, dock: RPCReference, widget: RPCReference, random_int_gen: random.Random
|
||||
):
|
||||
"""Utility method to remove the widget with a 50% chance."""
|
||||
random_int = random_int_gen.randint(0, 100)
|
||||
if random_int >= 50:
|
||||
attr_name = widget.widget_name
|
||||
widget.remove()
|
||||
wait_for_namespace_change(qtbot, gui, dock, attr_name, exists=False)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_abort_button(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the AbortButton widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.AbortButton)
|
||||
|
||||
# No rpc calls to check so far
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_bec_color_map_widget(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the BECColorMapWidget widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.BECColorMapWidget)
|
||||
|
||||
# Check rpc calls
|
||||
assert widget.colormap == "magma"
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_bec_progress_bar(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the BECProgressBar widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.BECProgressBar)
|
||||
|
||||
# Check rpc calls
|
||||
assert widget.label_template == "$value / $maximum - $percentage %"
|
||||
widget.set_maximum(100)
|
||||
widget.set_minimum(50)
|
||||
widget.set_value(75)
|
||||
|
||||
assert widget._get_label() == "75 / 100 - 50 %"
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_bec_queue(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the BECQueue widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.BECQueue)
|
||||
|
||||
# No rpc calls to test so far
|
||||
# maybe we can add an rpc call to check the queue length
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_bec_status_box(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the BECStatusBox widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.BECStatusBox)
|
||||
|
||||
# Check rpc calls
|
||||
assert widget.get_server_state() in ["RUNNING", "IDLE", "BUSY", "ERROR"]
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_dap_combo_box(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the DAPComboBox widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.DapComboBox)
|
||||
|
||||
# Check rpc calls
|
||||
widget.select_fit_model("PseudoVoigtModel")
|
||||
widget.select_x_axis("samx")
|
||||
widget.select_y_axis("bpm4i")
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_dark_mode_button(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the GUIDarkModeButton widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.DarkModeButton)
|
||||
|
||||
# Check rpc call
|
||||
widget.toggle_dark_mode()
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_device_browser(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the DeviceBrowser widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.DeviceBrowser)
|
||||
|
||||
# No rpc calls yet to check
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_device_combo_box(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the DeviceComboBox widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.DeviceComboBox)
|
||||
|
||||
# No rpc calls to check so far, maybe set_device should be exposed
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_device_line_edit(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the DeviceLineEdit widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.DeviceLineEdit)
|
||||
|
||||
# No rpc calls to check so far
|
||||
# Should probably have a set_device method
|
||||
|
||||
# No rpc calls to check so far, maybe set_device should be exposed
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_image(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the Image widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.Image)
|
||||
|
||||
scans = bec.scans
|
||||
dev = bec.device_manager.devices
|
||||
# Test rpc calls
|
||||
img = widget.image(dev.eiger)
|
||||
assert img.get_data() is None
|
||||
# Run a scan and plot the image
|
||||
s = scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False)
|
||||
s.wait()
|
||||
# Check that last image is equivalent to data in Redis
|
||||
last_img = bec.device_monitor.get_data(
|
||||
dev.eiger, count=1
|
||||
) # Get last image from Redis monitor 2D endpoint
|
||||
assert np.allclose(img.get_data(), last_img)
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_lmfit_dialog(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the LMFITDialog widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.LMFitDialog)
|
||||
|
||||
# No rpc calls to check so far
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_log_panel(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the LogPanel widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.LogPanel)
|
||||
|
||||
# No rpc calls to check so far
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_minesweeper(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the MineSweeper widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.Minesweeper)
|
||||
|
||||
# No rpc calls to check so far
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_motor_map(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the MotorMap widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.MotorMap)
|
||||
|
||||
# Test RPC calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
# Set motor map to names
|
||||
widget.map(dev.samx, dev.samy)
|
||||
# Move motor samx to pos
|
||||
pos = dev.samx.limits[1] - 1 # -1 from higher limit
|
||||
scans.mv(dev.samx, pos, relative=False).wait()
|
||||
# Check that data is up to date
|
||||
assert np.isclose(widget.get_data()["x"][-1], pos, dev.samx.precision)
|
||||
# Move motor samy to pos
|
||||
pos = dev.samy.limits[0] + 1 # +1 from lower limit
|
||||
scans.mv(dev.samy, pos, relative=False).wait()
|
||||
# Check that data is up to date
|
||||
assert np.isclose(widget.get_data()["y"][-1], pos, dev.samy.precision)
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_multi_waveform(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test MultiWaveform widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.MultiWaveform)
|
||||
|
||||
# Test RPC calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
# test plotting
|
||||
cm = "cividis"
|
||||
widget.plot(dev.waveform, color_palette=cm)
|
||||
assert widget.monitor == dev.waveform.name
|
||||
assert widget.color_palette == cm
|
||||
|
||||
# Scan with BEC
|
||||
scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False).wait()
|
||||
# TODO how can we check that the data was plotted, implement get_data()
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_positioner_indicator(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the PositionIndicator widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.PositionIndicator)
|
||||
|
||||
# TODO check what these rpc calls are supposed to do! Issue created #461
|
||||
widget.set_value(5)
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_positioner_box(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the PositionerBox widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.PositionerBox)
|
||||
|
||||
# Test rpc calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
# No rpc calls to check so far
|
||||
widget.set_positioner(dev.samx)
|
||||
widget.set_positioner(dev.samy.name)
|
||||
|
||||
scans.mv(dev.samy, -3, relative=False).wait()
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_positioner_box_2d(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the PositionerBox2D widget."""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.PositionerBox2D)
|
||||
|
||||
# Test rpc calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
# No rpc calls to check so far
|
||||
widget.set_positioner_hor(dev.samx)
|
||||
widget.set_positioner_ver(dev.samy)
|
||||
|
||||
# Try moving the motors
|
||||
scans.mv(dev.samx, 3, relative=False).wait()
|
||||
scans.mv(dev.samy, -3, relative=False).wait()
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_positioner_control_line(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the positioner control line widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.PositionerControlLine)
|
||||
|
||||
# Test rpc calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
# Set positioner
|
||||
widget.set_positioner(dev.samx)
|
||||
scans.mv(dev.samx, 3, relative=False).wait()
|
||||
widget.set_positioner(dev.samy.name)
|
||||
scans.mv(dev.samy, -3, relative=False).wait()
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_reset_button(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the reset button widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.ResetButton)
|
||||
|
||||
# No rpc calls to check so far, maybe add push button click!?
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_resume_button(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the reset button widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.ResumeButton)
|
||||
|
||||
# No rpc calls to check so far, maybe add push button click!?
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_ring_progress_bar(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the RingProgressBar widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.RingProgressBar)
|
||||
|
||||
# Test rpc calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
# TODO fix bug in widget #460
|
||||
# Do a scan
|
||||
scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False).wait()
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_scan_control(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the ScanControl widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.ScanControl)
|
||||
|
||||
# No rpc calls to check so far
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_scatter_waveform(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the ScatterWaveform widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.ScatterWaveform)
|
||||
|
||||
# Test rpc calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
widget.plot(dev.samx, dev.samy, dev.bpm4i)
|
||||
scans.grid_scan(dev.samx, -5, 5, 5, dev.samy, -5, 5, 5, exp_time=0.01, relative=False).wait()
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_signal_line_edit(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the SignalComboBox widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.SignalComboBox)
|
||||
|
||||
# No rpc calls to check so far, maybe add set_signal method & set_device
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_signal_combo_box(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the SignalLineEdit widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.SignalLineEdit)
|
||||
|
||||
# No rpc calls to check so far, maybe add set_signal method & set_device
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_stop_button(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the StopButton widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.StopButton)
|
||||
|
||||
# No rpc calls to check so far
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_text_box(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the TextBox widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.TextBox)
|
||||
|
||||
# RPC calls
|
||||
widget.set_plain_text("Hello World")
|
||||
widget.set_html_text("<b> Hello World HTML </b>")
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_vs_code_editor(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the VSCodeEditor widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.VSCodeEditor)
|
||||
|
||||
# No rpc calls to check so far
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_waveform(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the Waveform widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.Waveform)
|
||||
|
||||
# Test rpc calls
|
||||
dev = bec.device_manager.devices
|
||||
scans = bec.scans
|
||||
widget.plot(dev.bpm4i)
|
||||
s = scans.line_scan(dev.samx, -3, 3, steps=50, exp_time=0.01, relative=False)
|
||||
s.wait()
|
||||
|
||||
def _wait_live_data_updated():
|
||||
# Wait until storage exists
|
||||
if len(bec.queue.scan_storage.storage) == 0:
|
||||
return False
|
||||
scan_item = bec.queue.scan_storage.storage[-1]
|
||||
# Wait until scan_id is in history
|
||||
if not scan_item.status_message.info["scan_id"] == s.scan.scan_id:
|
||||
return False
|
||||
# Wait until data for all steps is available
|
||||
return len(scan_item.live_data.samx.samx.val) == 50
|
||||
|
||||
qtbot.waitUntil(_wait_live_data_updated, timeout=7000)
|
||||
# Check if data that is plotted is the same as the scan_item
|
||||
# Plot may not be updated yet, so we need to wait for the data to be updated
|
||||
qtbot.waitUntil(lambda: len(widget.curves[0].get_data()[0]) == 50)
|
||||
scan_item = bec.queue.scan_storage.storage[-1]
|
||||
samx_data = scan_item.live_data.samx.samx.val
|
||||
bpm4i_data = scan_item.live_data.bpm4i.bpm4i.val
|
||||
curve = widget.curves[0]
|
||||
assert np.allclose(curve.get_data()[0], samx_data)
|
||||
assert np.allclose(curve.get_data()[1], bpm4i_data)
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
@pytest.mark.timeout(PYTEST_TIMEOUT)
|
||||
def test_widgets_e2e_website_widget(
|
||||
qtbot, connected_gui_and_bec_with_scope_session, random_generator_from_seed
|
||||
):
|
||||
"""Test the WebsiteWidget widget"""
|
||||
gui = connected_gui_and_bec_with_scope_session
|
||||
bec = gui._client
|
||||
# Create dock_area, dock, widget
|
||||
dock_area, dock, widget = create_widget(qtbot, gui, gui.available_widgets.WebsiteWidget)
|
||||
|
||||
# Test rpc calls, maybe add private method to get current url
|
||||
# widget.set_url("dummy_url")
|
||||
# widget.set_url("next_dummy_url")
|
||||
# # Check url
|
||||
# widget.back()
|
||||
# # Check url
|
||||
# widget.forward()
|
||||
# Check url
|
||||
|
||||
# Test removing the widget, or leaving it open for the next test
|
||||
maybe_remove_widget(qtbot, gui, dock, widget, random_generator_from_seed)
|
||||
|
||||
|
||||
# # AbortButton │ A button that abort the scan. │
|
||||
# # │ BECColorMapWidget │ No description available │
|
||||
# # │ BECMultiWaveformWidget │ No description available │
|
||||
# # │ BECProgressBar │ A custom progress bar with smooth transitions. The displayed text can be customized using a template. │
|
||||
# # │ BECQueue │ Widget to display the BEC queue. │
|
||||
# # │ BECStatusBox │ An autonomous widget to display the status of BEC services. │
|
||||
# # │ DapComboBox │ The DAPComboBox widget is an extension to the QComboBox with all avaialble DAP model from BEC. │
|
||||
# # │ DarkModeButton │ No description available │
|
||||
# # │ DeviceBrowser │ No description available │
|
||||
# # │ DeviceComboBox │ Combobox widget for device input with autocomplete for device names. │
|
||||
# # │ DeviceLineEdit │ Line edit widget for device input with autocomplete for device names. │
|
||||
# # │ Image │ No description available │
|
||||
# # │ LMFitDialog │ Dialog for displaying the fit summary and params for LMFit DAP processes │
|
||||
# # │ LogPanel │ Displays a log panel │
|
||||
# # │ Minesweeper │ No description available │
|
||||
# # │ MotorMap │ No description available │
|
||||
# # │ PositionIndicator │ No description available │
|
||||
# # │ PositionerBox │ Simple Widget to control a positioner in box form │
|
||||
# # │ PositionerBox2D │ Simple Widget to control two positioners in box form │
|
||||
# # │ PositionerControlLine │ A widget that controls a single device. │
|
||||
# # │ ResetButton │ A button that resets the scan queue. │
|
||||
# # │ ResumeButton │ A button that continue scan queue. │
|
||||
# # │ RingProgressBar │ No description available │
|
||||
# # │ ScanControl │ No description available │
|
||||
# # │ ScatterWaveform │ No description available │
|
||||
# # │ SignalComboBox │ Line edit widget for device input with autocomplete for device names. │
|
||||
# # │ SignalLineEdit │ Line edit widget for device input with autocomplete for device names. │
|
||||
# # │ StopButton │ A button that stops the current scan. │
|
||||
# # │ TextBox │ A widget that displays text in plain and HTML format │
|
||||
# # │ VSCodeEditor │ A widget to display the VSCode editor. │
|
||||
# # │ Waveform │ No description available │
|
||||
# # │ WebsiteWidget │ A simple widget to display a website
|
||||
Reference in New Issue
Block a user