mirror of
https://github.com/bec-project/bec_widgets.git
synced 2025-07-13 19:21:50 +02:00
test(scan_control): tests added
This commit is contained in:
@ -2,18 +2,222 @@
|
||||
from unittest.mock import MagicMock
|
||||
|
||||
import pytest
|
||||
from qtpy.QtWidgets import QLineEdit
|
||||
|
||||
from bec_lib.messages import AvailableResourceMessage
|
||||
from bec_widgets.utils.widget_io import WidgetIO
|
||||
from bec_widgets.widgets import ScanControl
|
||||
from tests.unit_tests.test_msgs.available_scans_message import available_scans_message
|
||||
from bec_widgets.widgets.scan_control import ScanControl
|
||||
|
||||
|
||||
from .client_mocks import mocked_client
|
||||
|
||||
|
||||
available_scans_message = AvailableResourceMessage(
|
||||
resource={
|
||||
"line_scan": {
|
||||
"class": "LineScan",
|
||||
"base_class": "ScanBase",
|
||||
"arg_input": {"device": "device", "start": "float", "stop": "float"},
|
||||
"gui_config": {
|
||||
"scan_class_name": "LineScan",
|
||||
"arg_group": {
|
||||
"name": "Scan Arguments",
|
||||
"bundle": 3,
|
||||
"arg_inputs": {"device": "device", "start": "float", "stop": "float"},
|
||||
"inputs": [
|
||||
{
|
||||
"arg": True,
|
||||
"name": "device",
|
||||
"type": "device",
|
||||
"display_name": "Device",
|
||||
"tooltip": None,
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": True,
|
||||
"name": "start",
|
||||
"type": "float",
|
||||
"display_name": "Start",
|
||||
"tooltip": None,
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": True,
|
||||
"name": "stop",
|
||||
"type": "float",
|
||||
"display_name": "Stop",
|
||||
"tooltip": None,
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
],
|
||||
"min": 1,
|
||||
"max": None,
|
||||
},
|
||||
"kwarg_groups": [
|
||||
{
|
||||
"name": "Movement Parameters",
|
||||
"inputs": [
|
||||
{
|
||||
"arg": False,
|
||||
"name": "steps",
|
||||
"type": "int",
|
||||
"display_name": "Steps",
|
||||
"tooltip": "Number of steps",
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": False,
|
||||
"name": "relative",
|
||||
"type": "bool",
|
||||
"display_name": "Relative",
|
||||
"tooltip": "If True, the start and end positions are relative to the current position",
|
||||
"default": False,
|
||||
"expert": False,
|
||||
},
|
||||
],
|
||||
},
|
||||
{
|
||||
"name": "Acquisition Parameters",
|
||||
"inputs": [
|
||||
{
|
||||
"arg": False,
|
||||
"name": "exp_time",
|
||||
"type": "float",
|
||||
"display_name": "Exp Time",
|
||||
"tooltip": "Exposure time in s",
|
||||
"default": 0,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": False,
|
||||
"name": "burst_at_each_point",
|
||||
"type": "int",
|
||||
"display_name": "Burst At Each Point",
|
||||
"tooltip": "Number of acquisition per point",
|
||||
"default": 1,
|
||||
"expert": False,
|
||||
},
|
||||
],
|
||||
},
|
||||
],
|
||||
},
|
||||
"required_kwargs": ["steps", "relative"],
|
||||
"arg_bundle_size": {"bundle": 3, "min": 1, "max": None},
|
||||
},
|
||||
"grid_scan": {
|
||||
"class": "Scan",
|
||||
"base_class": "ScanBase",
|
||||
"arg_input": {"device": "device", "start": "float", "stop": "float", "steps": "int"},
|
||||
"gui_config": {
|
||||
"scan_class_name": "Scan",
|
||||
"arg_group": {
|
||||
"name": "Scan Arguments",
|
||||
"bundle": 4,
|
||||
"arg_inputs": {
|
||||
"device": "device",
|
||||
"start": "float",
|
||||
"stop": "float",
|
||||
"steps": "int",
|
||||
},
|
||||
"inputs": [
|
||||
{
|
||||
"arg": True,
|
||||
"name": "device",
|
||||
"type": "device",
|
||||
"display_name": "Device",
|
||||
"tooltip": None,
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": True,
|
||||
"name": "start",
|
||||
"type": "float",
|
||||
"display_name": "Start",
|
||||
"tooltip": None,
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": True,
|
||||
"name": "stop",
|
||||
"type": "float",
|
||||
"display_name": "Stop",
|
||||
"tooltip": None,
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": True,
|
||||
"name": "steps",
|
||||
"type": "int",
|
||||
"display_name": "Steps",
|
||||
"tooltip": None,
|
||||
"default": None,
|
||||
"expert": False,
|
||||
},
|
||||
],
|
||||
"min": 2,
|
||||
"max": None,
|
||||
},
|
||||
"kwarg_groups": [
|
||||
{
|
||||
"name": "Scan Parameters",
|
||||
"inputs": [
|
||||
{
|
||||
"arg": False,
|
||||
"name": "exp_time",
|
||||
"type": "float",
|
||||
"display_name": "Exp Time",
|
||||
"tooltip": "Exposure time in seconds",
|
||||
"default": 0,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": False,
|
||||
"name": "settling_time",
|
||||
"type": "float",
|
||||
"display_name": "Settling Time",
|
||||
"tooltip": "Settling time in seconds",
|
||||
"default": 0,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": False,
|
||||
"name": "burst_at_each_point",
|
||||
"type": "int",
|
||||
"display_name": "Burst At Each Point",
|
||||
"tooltip": "Number of exposures at each point",
|
||||
"default": 1,
|
||||
"expert": False,
|
||||
},
|
||||
{
|
||||
"arg": False,
|
||||
"name": "relative",
|
||||
"type": "bool",
|
||||
"display_name": "Relative",
|
||||
"tooltip": "If True, the motors will be moved relative to their current position",
|
||||
"default": False,
|
||||
"expert": False,
|
||||
},
|
||||
],
|
||||
}
|
||||
],
|
||||
},
|
||||
"required_kwargs": ["relative"],
|
||||
"arg_bundle_size": {"bundle": 4, "min": 2, "max": None},
|
||||
},
|
||||
"not_supported_scan_class": {"base_class": "NotSupportedScanClass"},
|
||||
}
|
||||
)
|
||||
|
||||
|
||||
@pytest.fixture(scope="function")
|
||||
def scan_control(qtbot, mocked_client): # , mock_dev):
|
||||
mocked_client.connector.set("scans/available_scans", available_scans_message)
|
||||
widget = ScanControl(client=mocked_client)
|
||||
qtbot.addWidget(widget)
|
||||
qtbot.waitExposed(widget)
|
||||
@ -21,81 +225,67 @@ def scan_control(qtbot, mocked_client): # , mock_dev):
|
||||
|
||||
|
||||
def test_populate_scans(scan_control, mocked_client):
|
||||
# The comboBox should be populated with all scan from the message right after initialization
|
||||
expected_scans = available_scans_message.resource.keys()
|
||||
assert scan_control.comboBox_scan_selection.count() == len(expected_scans)
|
||||
for scan in expected_scans: # Each scan should be in the comboBox
|
||||
assert scan_control.comboBox_scan_selection.findText(scan) != -1
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"scan_name", ["line_scan", "grid_scan"]
|
||||
) # TODO now only for line_scan and grid_scan, later for all loaded scans
|
||||
def test_on_scan_selected(scan_control, scan_name):
|
||||
# Expected scan info from the message signature
|
||||
expected_scan_info = available_scans_message.resource[scan_name]
|
||||
|
||||
# Select a scan from the comboBox
|
||||
scan_control.comboBox_scan_selection.setCurrentText(scan_name)
|
||||
|
||||
# Check labels and widgets in args table
|
||||
for index, (arg_key, arg_value) in enumerate(expected_scan_info["arg_input"].items()):
|
||||
label = scan_control.args_table.horizontalHeaderItem(index)
|
||||
assert label.text().lower() == arg_key # labes
|
||||
|
||||
for row in range(expected_scan_info["arg_bundle_size"]["min"]):
|
||||
widget = scan_control.args_table.cellWidget(row, index)
|
||||
assert widget is not None # Confirm that a widget exists
|
||||
expected_widget_type = scan_control.WIDGET_HANDLER.get(arg_value, None)
|
||||
assert isinstance(widget, expected_widget_type) # Confirm the widget type matches
|
||||
|
||||
# kwargs
|
||||
kwargs_from_signature = [
|
||||
param for param in expected_scan_info["signature"] if param["kind"] == "KEYWORD_ONLY"
|
||||
expected_scans = ["line_scan", "grid_scan"]
|
||||
items = [
|
||||
scan_control.comboBox_scan_selection.itemText(i)
|
||||
for i in range(scan_control.comboBox_scan_selection.count())
|
||||
]
|
||||
|
||||
# Check labels and widgets in kwargs grid layout
|
||||
for index, kwarg_info in enumerate(kwargs_from_signature):
|
||||
label_widget = scan_control.kwargs_layout.itemAtPosition(1, index).widget()
|
||||
assert label_widget.text() == kwarg_info["name"].capitalize()
|
||||
widget = scan_control.kwargs_layout.itemAtPosition(2, index).widget()
|
||||
expected_widget_type = scan_control.WIDGET_HANDLER.get(kwarg_info["annotation"], QLineEdit)
|
||||
assert isinstance(widget, expected_widget_type)
|
||||
assert scan_control.comboBox_scan_selection.count() == 2
|
||||
assert sorted(items) == sorted(expected_scans)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("scan_name", ["line_scan", "grid_scan"])
|
||||
def test_add_remove_bundle(scan_control, scan_name):
|
||||
# Expected scan info from the message signature
|
||||
def test_on_scan_selected(scan_control, scan_name):
|
||||
expected_scan_info = available_scans_message.resource[scan_name]
|
||||
scan_control.comboBox_scan_selection.setCurrentText(scan_name)
|
||||
|
||||
# Select a scan from the comboBox
|
||||
# Check arg_box labels and widgets
|
||||
for index, (arg_key, arg_value) in enumerate(expected_scan_info["arg_input"].items()):
|
||||
label = scan_control.arg_box.layout.itemAtPosition(0, index).widget()
|
||||
assert label.text().lower() == arg_key
|
||||
|
||||
for row in range(1, expected_scan_info["arg_bundle_size"]["min"] + 1):
|
||||
widget = scan_control.arg_box.layout.itemAtPosition(row, index).widget()
|
||||
assert widget is not None # Confirm that a widget exists
|
||||
expected_widget_type = scan_control.arg_box.WIDGET_HANDLER.get(arg_value, None)
|
||||
assert isinstance(widget, expected_widget_type) # Confirm the widget type matches
|
||||
|
||||
# Check kwargs boxes
|
||||
kwargs_group = [param for param in expected_scan_info["gui_config"]["kwarg_groups"]]
|
||||
print(kwargs_group)
|
||||
|
||||
for kwarg_box, kwarg_group in zip(scan_control.kwarg_boxes, kwargs_group):
|
||||
assert kwarg_box.title() == kwarg_group["name"]
|
||||
for index, kwarg_info in enumerate(kwarg_group["inputs"]):
|
||||
label = kwarg_box.layout.itemAtPosition(0, index).widget()
|
||||
assert label.text() == kwarg_info["display_name"]
|
||||
widget = kwarg_box.layout.itemAtPosition(1, index).widget()
|
||||
expected_widget_type = kwarg_box.WIDGET_HANDLER.get(kwarg_info["type"], None)
|
||||
assert isinstance(widget, expected_widget_type)
|
||||
|
||||
|
||||
@pytest.mark.parametrize("scan_name", ["line_scan", "grid_scan"])
|
||||
def test_add_remove_bundle(scan_control, scan_name, qtbot):
|
||||
expected_scan_info = available_scans_message.resource[scan_name]
|
||||
scan_control.comboBox_scan_selection.setCurrentText(scan_name)
|
||||
|
||||
# Initial number of args row
|
||||
initial_num_of_rows = scan_control.args_table.rowCount()
|
||||
initial_num_of_rows = scan_control.arg_box.count_arg_rows()
|
||||
|
||||
# Check initial row count of args table
|
||||
assert scan_control.args_table.rowCount() == expected_scan_info["arg_bundle_size"]["min"]
|
||||
assert initial_num_of_rows == expected_scan_info["arg_bundle_size"]["min"]
|
||||
|
||||
# Try to remove default number of args row
|
||||
scan_control.pushButton_remove_bundle.click()
|
||||
assert scan_control.args_table.rowCount() == expected_scan_info["arg_bundle_size"]["min"]
|
||||
scan_control.button_add_bundle.click()
|
||||
scan_control.button_add_bundle.click()
|
||||
|
||||
# Try to add two bundles
|
||||
scan_control.pushButton_add_bundle.click()
|
||||
scan_control.pushButton_add_bundle.click()
|
||||
|
||||
# check the case where no max number of args are defined
|
||||
# TODO do check also for the case where max number of args are defined
|
||||
if expected_scan_info["arg_bundle_size"]["max"] is None:
|
||||
assert scan_control.args_table.rowCount() == initial_num_of_rows + 2
|
||||
assert scan_control.arg_box.count_arg_rows() == initial_num_of_rows + 2
|
||||
|
||||
# Remove one bundle
|
||||
scan_control.pushButton_remove_bundle.click()
|
||||
scan_control.button_remove_bundle.click()
|
||||
qtbot.wait(200)
|
||||
|
||||
# check the case where no max number of args are defined
|
||||
if expected_scan_info["arg_bundle_size"]["max"] is None:
|
||||
assert scan_control.args_table.rowCount() == initial_num_of_rows + 1
|
||||
assert scan_control.arg_box.count_arg_rows() == initial_num_of_rows + 1
|
||||
|
||||
|
||||
def test_run_line_scan_with_parameters(scan_control, mocked_client):
|
||||
@ -103,32 +293,21 @@ def test_run_line_scan_with_parameters(scan_control, mocked_client):
|
||||
kwargs = {"exp_time": 0.1, "steps": 10, "relative": True, "burst_at_each_point": 1}
|
||||
args = {"device": "samx", "start": -5, "stop": 5}
|
||||
|
||||
# Select a scan from the comboBox
|
||||
scan_control.comboBox_scan_selection.setCurrentText(scan_name)
|
||||
|
||||
# Set kwargs in the UI
|
||||
for label_index in range(
|
||||
scan_control.kwargs_layout.rowCount() + 1
|
||||
): # from some reason rowCount() returns 1 less than the actual number of rows
|
||||
label_item = scan_control.kwargs_layout.itemAtPosition(1, label_index)
|
||||
if label_item:
|
||||
label_widget = label_item.widget()
|
||||
kwarg_key = WidgetIO.get_value(label_widget).lower()
|
||||
if kwarg_key in kwargs:
|
||||
widget_item = scan_control.kwargs_layout.itemAtPosition(2, label_index)
|
||||
if widget_item:
|
||||
widget = widget_item.widget()
|
||||
WidgetIO.set_value(widget, kwargs[kwarg_key])
|
||||
|
||||
for kwarg_box in scan_control.kwarg_boxes:
|
||||
for widget in kwarg_box.widgets:
|
||||
for key, value in kwargs.items():
|
||||
if widget.arg_name == key:
|
||||
WidgetIO.set_value(widget, value)
|
||||
break
|
||||
# Set args in the UI
|
||||
for col_index in range(scan_control.args_table.columnCount()):
|
||||
header_item = scan_control.args_table.horizontalHeaderItem(col_index)
|
||||
if header_item:
|
||||
arg_key = header_item.text().lower()
|
||||
if arg_key in args:
|
||||
for row_index in range(scan_control.args_table.rowCount()):
|
||||
widget = scan_control.args_table.cellWidget(row_index, col_index)
|
||||
WidgetIO.set_value(widget, args[arg_key])
|
||||
for widget in scan_control.arg_box.widgets:
|
||||
for key, value in args.items():
|
||||
if widget.arg_name == key:
|
||||
WidgetIO.set_value(widget, value)
|
||||
break
|
||||
|
||||
# Mock the scan function
|
||||
mocked_scan_function = MagicMock()
|
||||
@ -141,13 +320,7 @@ def test_run_line_scan_with_parameters(scan_control, mocked_client):
|
||||
called_args, called_kwargs = mocked_scan_function.call_args
|
||||
|
||||
# Check if the scan function was called correctly
|
||||
expected_device = (
|
||||
mocked_client.device_manager.devices.samx
|
||||
) # This is the FakePositioner instance
|
||||
expected_device = mocked_client.device_manager.devices.samx
|
||||
expected_args_list = [expected_device, args["start"], args["stop"]]
|
||||
assert called_args == tuple(
|
||||
expected_args_list
|
||||
), "The positional arguments passed to the scan function do not match expected values."
|
||||
assert (
|
||||
called_kwargs == kwargs
|
||||
), "The keyword arguments passed to the scan function do not match expected values."
|
||||
assert called_args == tuple(expected_args_list)
|
||||
assert called_kwargs == kwargs
|
||||
|
160
tests/unit_tests/test_scan_control_group_box.py
Normal file
160
tests/unit_tests/test_scan_control_group_box.py
Normal file
@ -0,0 +1,160 @@
|
||||
# pylint: disable = no-name-in-module,missing-class-docstring, missing-module-docstring
|
||||
import pytest
|
||||
|
||||
from bec_widgets.utils.widget_io import WidgetIO
|
||||
from bec_widgets.widgets.scan_control.scan_group_box import ScanGroupBox
|
||||
|
||||
|
||||
def test_kwarg_box(qtbot):
|
||||
group_input = {
|
||||
"name": "Kwarg Test",
|
||||
"inputs": [
|
||||
# Test float
|
||||
{
|
||||
"arg": False,
|
||||
"name": "exp_time",
|
||||
"type": "float",
|
||||
"display_name": "Exp Time",
|
||||
"tooltip": "Exposure time in seconds",
|
||||
"default": 0,
|
||||
"expert": False,
|
||||
},
|
||||
# Test int
|
||||
{
|
||||
"arg": False,
|
||||
"name": "num_points",
|
||||
"type": "int",
|
||||
"display_name": "Num Points",
|
||||
"tooltip": "Number of points",
|
||||
"default": 1,
|
||||
"expert": False,
|
||||
},
|
||||
# Test bool
|
||||
{
|
||||
"arg": False,
|
||||
"name": "relative",
|
||||
"type": "bool",
|
||||
"display_name": "Relative",
|
||||
"tooltip": "If True, the motors will be moved relative to their current position",
|
||||
"default": False,
|
||||
"expert": False,
|
||||
},
|
||||
# Test str
|
||||
{
|
||||
"arg": False,
|
||||
"name": "scan_type",
|
||||
"type": "str",
|
||||
"display_name": "Scan Type",
|
||||
"tooltip": "Type of scan",
|
||||
"default": "line",
|
||||
"expert": False,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
kwarg_box = ScanGroupBox(box_type="kwargs", config=group_input)
|
||||
assert kwarg_box is not None
|
||||
assert kwarg_box.box_type == "kwargs"
|
||||
assert kwarg_box.config == group_input
|
||||
assert kwarg_box.title() == "Kwarg Test"
|
||||
|
||||
# Labels
|
||||
assert kwarg_box.layout.itemAtPosition(0, 0).widget().text() == "Exp Time"
|
||||
assert kwarg_box.layout.itemAtPosition(0, 1).widget().text() == "Num Points"
|
||||
assert kwarg_box.layout.itemAtPosition(0, 2).widget().text() == "Relative"
|
||||
assert kwarg_box.layout.itemAtPosition(0, 3).widget().text() == "Scan Type"
|
||||
|
||||
# Widget 0
|
||||
assert kwarg_box.widgets[0].__class__.__name__ == "ScanDoubleSpinBox"
|
||||
assert kwarg_box.widgets[0].arg_name == "exp_time"
|
||||
assert WidgetIO.get_value(kwarg_box.widgets[0]) == 0
|
||||
assert kwarg_box.widgets[0].toolTip() == "Exposure time in seconds"
|
||||
|
||||
# Widget 1
|
||||
assert kwarg_box.widgets[1].__class__.__name__ == "ScanSpinBox"
|
||||
assert kwarg_box.widgets[1].arg_name == "num_points"
|
||||
assert WidgetIO.get_value(kwarg_box.widgets[1]) == 1
|
||||
assert kwarg_box.widgets[1].toolTip() == "Number of points"
|
||||
|
||||
# Widget 2
|
||||
assert kwarg_box.widgets[2].__class__.__name__ == "ScanCheckBox"
|
||||
assert kwarg_box.widgets[2].arg_name == "relative"
|
||||
assert WidgetIO.get_value(kwarg_box.widgets[2]) == False
|
||||
assert (
|
||||
kwarg_box.widgets[2].toolTip()
|
||||
== "If True, the motors will be moved relative to their current position"
|
||||
)
|
||||
|
||||
# Widget 3
|
||||
assert kwarg_box.widgets[3].__class__.__name__ == "ScanLineEdit"
|
||||
assert kwarg_box.widgets[3].arg_name == "scan_type"
|
||||
assert WidgetIO.get_value(kwarg_box.widgets[3]) == "line"
|
||||
assert kwarg_box.widgets[3].toolTip() == "Type of scan"
|
||||
|
||||
parameters = kwarg_box.get_parameters()
|
||||
assert parameters == {"exp_time": 0, "num_points": 1, "relative": False, "scan_type": "line"}
|
||||
|
||||
|
||||
def test_arg_box(qtbot):
|
||||
group_input = {
|
||||
"name": "Arg Test",
|
||||
"inputs": [
|
||||
# Test device
|
||||
{
|
||||
"arg": True,
|
||||
"name": "device",
|
||||
"type": "str",
|
||||
"display_name": "Device",
|
||||
"tooltip": "Device to scan",
|
||||
"default": "samx",
|
||||
"expert": False,
|
||||
},
|
||||
# Test float
|
||||
{
|
||||
"arg": True,
|
||||
"name": "start",
|
||||
"type": "float",
|
||||
"display_name": "Start",
|
||||
"tooltip": "Start position",
|
||||
"default": 0,
|
||||
"expert": False,
|
||||
},
|
||||
# Test int
|
||||
{
|
||||
"arg": True,
|
||||
"name": "stop",
|
||||
"type": "int",
|
||||
"display_name": "Stop",
|
||||
"tooltip": "Stop position",
|
||||
"default": 1,
|
||||
"expert": False,
|
||||
},
|
||||
],
|
||||
}
|
||||
|
||||
arg_box = ScanGroupBox(box_type="args", config=group_input)
|
||||
assert arg_box is not None
|
||||
assert arg_box.box_type == "args"
|
||||
assert arg_box.config == group_input
|
||||
assert arg_box.title() == "Arg Test"
|
||||
|
||||
# Labels
|
||||
assert arg_box.layout.itemAtPosition(0, 0).widget().text() == "Device"
|
||||
assert arg_box.layout.itemAtPosition(0, 1).widget().text() == "Start"
|
||||
assert arg_box.layout.itemAtPosition(0, 2).widget().text() == "Stop"
|
||||
|
||||
# Widget 0
|
||||
assert arg_box.widgets[0].__class__.__name__ == "ScanLineEdit"
|
||||
assert arg_box.widgets[0].arg_name == "device"
|
||||
assert WidgetIO.get_value(arg_box.widgets[0]) == "samx"
|
||||
assert arg_box.widgets[0].toolTip() == "Device to scan"
|
||||
|
||||
# Widget 1
|
||||
assert arg_box.widgets[1].__class__.__name__ == "ScanDoubleSpinBox"
|
||||
assert arg_box.widgets[1].arg_name == "start"
|
||||
assert WidgetIO.get_value(arg_box.widgets[1]) == 0
|
||||
assert arg_box.widgets[1].toolTip() == "Start position"
|
||||
|
||||
# Widget 2
|
||||
assert arg_box.widgets[2].__class__.__name__ == "ScanSpinBox"
|
||||
assert arg_box.widgets[2].arg_name
|
Reference in New Issue
Block a user