diff --git a/shiny/playwright/controller/_accordion.py b/shiny/playwright/controller/_accordion.py index 890b03bde..60e7de370 100644 --- a/shiny/playwright/controller/_accordion.py +++ b/shiny/playwright/controller/_accordion.py @@ -297,10 +297,16 @@ def set( """ if isinstance(open, str): open = [open] - for element in self.loc.element_handles(): - element.wait_for_element_state(state="visible", timeout=timeout) - element.scroll_into_view_if_needed(timeout=timeout) - elem_value = element.get_attribute("data-value") + + # TODO-future: XOR on the next open state and the current open state + for i in range(self.loc.count()): + el_loc = self.loc.nth(i) + el_loc.element_handle().wait_for_element_state( + state="visible", timeout=timeout + ) + el_loc.scroll_into_view_if_needed(timeout=timeout) + + elem_value = el_loc.get_attribute("data-value") if elem_value is None: raise ValueError( "Accordion panel does not have a `data-value` attribute" diff --git a/shiny/playwright/controller/_input_controls.py b/shiny/playwright/controller/_input_controls.py index 98235831a..a3fde3dfa 100644 --- a/shiny/playwright/controller/_input_controls.py +++ b/shiny/playwright/controller/_input_controls.py @@ -805,16 +805,17 @@ def in_selected(value: str) -> bool: return True return False - # Could do with multiple locator calls, - # but unchecking the elements that are not in `selected` is not possible - # as `set_checked()` likes a single element. - for checkbox in self.loc_choices.element_handles(): + for i in range(self.loc_choices.count()): + checkbox = self.loc_choices.nth(i) is_selected = in_selected(checkbox.input_value(timeout=timeout)) - checkbox.set_checked( - is_selected, - timeout=timeout, - **kwargs, # pyright: ignore[reportArgumentType] - ) + currently_selected = checkbox.is_checked() + # Only update if needed + if is_selected != currently_selected: + checkbox.set_checked( + is_selected, + timeout=timeout, + **kwargs, # pyright: ignore[reportArgumentType] + ) def expect_choices( self, diff --git a/shiny/playwright/controller/_output.py b/shiny/playwright/controller/_output.py index dc4a0bbe7..6cedebf83 100644 --- a/shiny/playwright/controller/_output.py +++ b/shiny/playwright/controller/_output.py @@ -1212,12 +1212,10 @@ def set_filter( The maximum time to wait for the action to complete. Defaults to `None`. """ # reset all filters - all_input_handles = self.loc_column_filter.locator( - "> input, > div > input" - ).element_handles() - for input_handle in all_input_handles: - input_handle.scroll_into_view_if_needed() - input_handle.fill("", timeout=timeout) + all_input_locs = self.loc_column_filter.locator("> input, > div > input") + for i in range(all_input_locs.count()): + input_el = all_input_locs.nth(i) + input_el.fill("", timeout=timeout) if filter is None: return diff --git a/tests/playwright/shiny/components/data_frame/filter_reset/test_filter_reset.py b/tests/playwright/shiny/components/data_frame/filter_reset/test_filter_reset.py index cfb6e9f25..ce9b90963 100644 --- a/tests/playwright/shiny/components/data_frame/filter_reset/test_filter_reset.py +++ b/tests/playwright/shiny/components/data_frame/filter_reset/test_filter_reset.py @@ -17,8 +17,8 @@ def test_filters_are_reset(page: Page, local_app: ShinyAppProc) -> None: expect(filter_inputs).to_have_count(8 + 5) # 8 columns including 5 numeric columns penguin_code.expect_value("()") - for element in filter_inputs.element_handles(): - assert element.input_value() == "" + for i in range(filter_inputs.count()): + expect(filter_inputs.nth(i)).to_have_value("") update_filters.click() @@ -30,14 +30,13 @@ def test_filters_are_reset(page: Page, local_app: ShinyAppProc) -> None: "{'col': 4, 'value': (220, 225)}" ")" ) - for value, element in zip( - ["Gentoo", "", "50", "", "", "17", "220", "225", "", "", "", "", ""], - filter_inputs.element_handles(), + for i, value in enumerate( + ["Gentoo", "", "50", "", "", "17", "220", "225", "", "", "", "", ""] ): - assert element.input_value() == value + expect(filter_inputs.nth(i)).to_have_value(value) reset_filters.click() penguin_code.expect_value("()") - for element in filter_inputs.element_handles(): - assert element.input_value() == "" + for i in range(filter_inputs.count()): + expect(filter_inputs.nth(i)).to_have_value("")