|
| 1 | +from __future__ import annotations |
| 2 | + |
| 3 | +import uuid |
| 4 | + |
| 5 | +import pytest |
| 6 | +from bec_lib.bl_states import DeviceWithinLimitsStateConfig |
| 7 | + |
| 8 | +from bec_widgets.widgets.services.beamline_states.beamline_state_pill import BeamlineStateManager |
| 9 | + |
| 10 | +# pylint: disable=protected-access |
| 11 | + |
| 12 | + |
| 13 | +def _delete_state_if_present(bec, state_name: str) -> None: |
| 14 | + if hasattr(bec.beamline_states, state_name): |
| 15 | + bec.beamline_states.delete(state_name) |
| 16 | + |
| 17 | + |
| 18 | +@pytest.mark.timeout(100) |
| 19 | +def test_beamline_state_manager_adds_updates_and_deletes_state_e2e(qtbot, bec_client_lib): |
| 20 | + """ |
| 21 | + Verify the real BEC beamline-state flow is reflected by BeamlineStateManager. |
| 22 | +
|
| 23 | + This test requires the e2e BEC servers and is intended to be run with |
| 24 | + ``--start-servers``. |
| 25 | + """ |
| 26 | + bec = bec_client_lib |
| 27 | + dev = bec.device_manager.devices |
| 28 | + scans = bec.scans |
| 29 | + state_name = f"samx_widget_limits_{uuid.uuid4().hex[:8]}" |
| 30 | + config = DeviceWithinLimitsStateConfig( |
| 31 | + name=state_name, |
| 32 | + title="samx widget limits", |
| 33 | + device="samx", |
| 34 | + signal="samx", |
| 35 | + low_limit=0.0, |
| 36 | + high_limit=10.0, |
| 37 | + tolerance=1.0, |
| 38 | + ) |
| 39 | + manager = BeamlineStateManager(client=bec) |
| 40 | + qtbot.addWidget(manager) |
| 41 | + manager.show() |
| 42 | + qtbot.waitExposed(manager) |
| 43 | + |
| 44 | + _delete_state_if_present(bec, state_name) |
| 45 | + |
| 46 | + try: |
| 47 | + bec.beamline_states.add(config) |
| 48 | + |
| 49 | + qtbot.waitUntil(lambda: hasattr(bec.beamline_states, state_name), timeout=10000) |
| 50 | + qtbot.waitUntil(lambda: state_name in manager._state_pills, timeout=10000) |
| 51 | + |
| 52 | + pill = manager._state_pills[state_name] |
| 53 | + assert pill.state_name == state_name |
| 54 | + assert pill._name_label.text() == "samx widget limits" |
| 55 | + |
| 56 | + scans.umv(dev.samx, 5, relative=False).wait() |
| 57 | + qtbot.waitUntil( |
| 58 | + lambda: getattr(bec.beamline_states, state_name).get()["status"] == "valid", |
| 59 | + timeout=10000, |
| 60 | + ) |
| 61 | + qtbot.waitUntil(lambda: pill._status == "valid", timeout=10000) |
| 62 | + assert pill._status_label.text() == "VALID" |
| 63 | + assert pill._detail_label.text() == "Positioner samx within limits" |
| 64 | + |
| 65 | + scans.umv(dev.samx, 20, relative=False).wait() |
| 66 | + qtbot.waitUntil( |
| 67 | + lambda: getattr(bec.beamline_states, state_name).get()["status"] == "invalid", |
| 68 | + timeout=10000, |
| 69 | + ) |
| 70 | + qtbot.waitUntil(lambda: pill._status == "invalid", timeout=10000) |
| 71 | + assert pill._status_label.text() == "INVALID" |
| 72 | + assert pill._detail_label.text() == "Positioner samx out of limits" |
| 73 | + |
| 74 | + bec.beamline_states.delete(state_name) |
| 75 | + qtbot.waitUntil(lambda: not hasattr(bec.beamline_states, state_name), timeout=10000) |
| 76 | + qtbot.waitUntil(lambda: state_name not in manager._state_pills, timeout=10000) |
| 77 | + |
| 78 | + finally: |
| 79 | + _delete_state_if_present(bec, state_name) |
| 80 | + scans.umv(dev.samx, 0, relative=False).wait() |
0 commit comments