diff --git a/src/bonsai/bonsai/bim/module/drawing/ui.py b/src/bonsai/bonsai/bim/module/drawing/ui.py index 796c36b484..c1809995a0 100644 --- a/src/bonsai/bonsai/bim/module/drawing/ui.py +++ b/src/bonsai/bonsai/bim/module/drawing/ui.py @@ -816,7 +816,6 @@ class BIM_PT_text(Panel): for i, literal_data in enumerate(text_data["Literals"]): box = self.layout.box() - box.label(text=f"Literal[{i}]:") # Combine both approaches: clickable attributes from PR #7292 and display from PR #7106 for attribute in literal_data: diff --git a/src/bonsai/test/bim/feature/drawing.feature b/src/bonsai/test/bim/feature/drawing.feature index cff150b3b4..0f0c5a3b17 100644 --- a/src/bonsai/test/bim/feature/drawing.feature +++ b/src/bonsai/test/bim/feature/drawing.feature @@ -385,6 +385,51 @@ Scenario: Edit text - change literal When I click "Edit Text" Then I see "Hello World" +Scenario: Add text literal + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I save IFC project + And I look at the "Drawings" panel + And I click "IMPORT" + And I click "ADD" + And I press "bim.toggle_target_view(option="EXPAND", target_view='PLAN_VIEW')" + And I select the "PLAN_VIEW" item in the "BIM_UL_drawinglist" list + And I click "VIEW_CAMERA_UNSELECTED" in the row where I see "PLAN_VIEW" in the "1st" list + And I press "bim.add_annotation" + And the object "IfcAnnotation/TEXT" is selected + And I look at the "BIM_PT_text" panel + And I click "Enable Editing Text" + And I click the "ADD" after the text "Literals:" + And I set the "2nd Literal" property to "New Literal" + When I click "Edit Text" + Then I see "New Literal" + +Scenario: Remove text literal + Given an empty IFC project + And I add a cube + And the object "Cube" is selected + And I save IFC project + And I look at the "Drawings" panel + And I click "IMPORT" + And I click "ADD" + And I press "bim.toggle_target_view(option="EXPAND", target_view='PLAN_VIEW')" + And I select the "PLAN_VIEW" item in the "BIM_UL_drawinglist" list + And I click "VIEW_CAMERA_UNSELECTED" in the row where I see "PLAN_VIEW" in the "1st" list + And I press "bim.add_annotation" + And the object "IfcAnnotation/TEXT" is selected + And I look at the "BIM_PT_text" panel + And I click "Enable Editing Text" + And I set the "Literal" property to "Keep This" + And I click the "ADD" after the text "Literals:" + And I set the "2nd Literal" property to "Remove This" + And I click "Edit Text" + And I click "Enable Editing Text" + When I click the "2nd" "X" + And I click "Edit Text" + Then I see "Keep This" + And I don't see "Remove This" + Scenario: Add reference image Given an empty IFC project And I save IFC project diff --git a/src/bonsai/test/bim/test_feature.py b/src/bonsai/test/bim/test_feature.py index fe6fbcba15..3a1efa5d5b 100644 --- a/src/bonsai/test/bim/test_feature.py +++ b/src/bonsai/test/bim/test_feature.py @@ -610,8 +610,9 @@ def i_see_the_prop_property_is_value(prop, value): @then(parsers.parse('I set the "{prop}" property to "{value}"')) def i_set_the_prop_property_to_value(prop: str, value: str): """ - :param prop: Could be either property name, property text, property icon - or property index (e.g. "1st", "2nd", "5th"). + :param prop: Could be either property name, property text, property icon, + property index (e.g. "1st", "2nd", "5th"), or Nth named property + (e.g. "2nd Literal" for the 2nd property called "Literal"). :param value: For boolean propeties - 'TRUE' or 'FALSE'. """ @@ -619,12 +620,28 @@ def i_set_the_prop_property_to_value(prop: str, value: str): assert panel_spy panel_spy.refresh_spy() is_nth = False - if prop[0].isnumeric() and prop.endswith(("st", "nd", "th")): + is_nth_named = False + nth_target = 0 + prop_name = prop + if " " in prop and prop[0].isnumeric(): + parts = prop.split(" ", 1) + if parts[0].endswith(("st", "nd", "th")): + is_nth_named = True + nth_target = int(parts[0][:-2]) - 1 + prop_name = parts[1] + elif prop[0].isnumeric() and prop.endswith(("st", "nd", "th")): is_nth = True + named_count = 0 for nth, spied_prop in enumerate(panel_spy.spied_props): if is_nth and nth != int(prop[:-2]) - 1: continue - if not is_nth and prop not in (spied_prop["name"], spied_prop["text"], spied_prop["icon"]): + if is_nth_named: + if prop_name not in (spied_prop["name"], spied_prop["text"], spied_prop["icon"]): + continue + if named_count != nth_target: + named_count += 1 + continue + elif not is_nth and prop not in (spied_prop["name"], spied_prop["text"], spied_prop["icon"]): continue if spied_prop["prop_type"] == "BOOLEAN": if value == "TRUE": @@ -873,6 +890,29 @@ def i_click_button(button): _i_click_button_on_panel(button, panel_spy) +@given(parsers.parse('I click the "{nth}" "{button}"')) +@when(parsers.parse('I click the "{nth}" "{button}"')) +@then(parsers.parse('I click the "{nth}" "{button}"')) +def i_click_the_nth_button(nth, button): + """ + :param nth: Ordinal like "1st", "2nd", "3rd" to select the Nth matching button. + :param button: The text or icon of the button to click. + """ + assert panel_spy + panel_spy.refresh_spy() + target = int(nth[:-2]) - 1 + count = 0 + for spied_operator in panel_spy.spied_operators: + if spied_operator["text"] == button or spied_operator["icon"] == button: + if count == target: + spied_operator["operator"]("INVOKE_DEFAULT", **spied_operator["kwargs"]) + panel_spy.is_spy_dirty = True + return + count += 1 + debug = "\n".join([f"{i} {v}" for i, v in enumerate(panel_spy.spied_operators)]) + assert False, f"Could not find {nth} {button}:\n{debug}" + + @given(parsers.parse('I click the "{button}" after the text "{text}"')) @when(parsers.parse('I click the "{button}" after the text "{text}"')) @then(parsers.parse('I click the "{button}" after the text "{text}"'))