From 4fd0ecce658ee5924eaf5d11737cb322e8d6993c Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Mon, 23 Sep 2024 19:37:20 -0700 Subject: [PATCH 01/10] Add kitchensink tests for checkbox and checkbox_group --- shiny/api-examples/input_checkbox/app-core.py | 2 +- .../playwright/controller/_input_controls.py | 29 ++++++++-- .../input_checkbox/app.py | 16 ++++++ .../test_input_checkbox_kitchensink.py | 17 ++++++ .../input_checkbox_group/app.py | 53 +++++++++++++++++++ .../test_input_checkbox_group_kitchensink.py | 34 ++++++++++++ 6 files changed, 147 insertions(+), 4 deletions(-) create mode 100644 tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py create mode 100644 tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py create mode 100644 tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py create mode 100644 tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py diff --git a/shiny/api-examples/input_checkbox/app-core.py b/shiny/api-examples/input_checkbox/app-core.py index b84f92de3..241561d2f 100644 --- a/shiny/api-examples/input_checkbox/app-core.py +++ b/shiny/api-examples/input_checkbox/app-core.py @@ -1,7 +1,7 @@ from shiny import App, Inputs, Outputs, Session, render, ui app_ui = ui.page_fluid( - ui.input_checkbox("somevalue", "Some value", False), + ui.input_checkbox("somevalue", "Some value", False, width="600px"), ui.output_ui("value"), ) diff --git a/shiny/playwright/controller/_input_controls.py b/shiny/playwright/controller/_input_controls.py index 663cd039e..142d2f03f 100644 --- a/shiny/playwright/controller/_input_controls.py +++ b/shiny/playwright/controller/_input_controls.py @@ -463,7 +463,31 @@ def _handle_center( return handle_center -class _RadioButtonCheckboxGroupBase(UiWithLabel): +class InputCheckboxWidthM: + """ + A mixin class for input checkboc width. + This mixin class provides methods to expect the width of input checkbox. + """ + + def expect_width( + self: UiWithContainerP, + value: AttrValue, + *, + timeout: Timeout = None, + ) -> None: + """ + Expect the input select to have a specific width. + Parameters + ---------- + value + The expected width. + timeout + The maximum time to wait for the expectation to be fulfilled. Defaults to `None`. + """ + _expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout) + + +class _RadioButtonCheckboxGroupBase(InputCheckboxWidthM, UiWithLabel): loc_choice_labels: Locator def expect_choice_labels( @@ -646,7 +670,7 @@ def expect_selected( class _InputCheckboxBase( - WidthContainerM, + InputCheckboxWidthM, UiWithLabel, ): def __init__( @@ -721,7 +745,6 @@ def expect_checked(self, value: bool, *, timeout: Timeout = None) -> None: class InputCheckboxGroup( - WidthContainerM, _RadioButtonCheckboxGroupBase, ): """Controller for :func:`shiny.ui.input_checkbox_group`.""" diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py new file mode 100644 index 000000000..2929a6a35 --- /dev/null +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py @@ -0,0 +1,16 @@ +from shiny.express import ui + +ui.page_opts(title="Checkbox Kitchen Sink", fillable=True) + +with ui.layout_columns(): + with ui.card(): + ui.card_header("Default checkbox with label") + ui.input_checkbox("default", "Basic Checkbox") + + with ui.card(): + ui.card_header("Checkbox With Value") + ui.input_checkbox("value", "Checkbox with Value", value=True) + + with ui.card(): + ui.card_header("Checkbox With Width") + ui.input_checkbox("width", "Checkbox with Width", width="10px") diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py new file mode 100644 index 000000000..cdc6818a7 --- /dev/null +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py @@ -0,0 +1,17 @@ +from playwright.sync_api import Page + +from shiny.playwright import controller +from shiny.run import ShinyAppProc + + +def test_checkbox_kitchen(page: Page, local_app: ShinyAppProc) -> None: + page.goto(local_app.url) + + default = controller.InputCheckbox(page, "default") + default.expect_label("Basic Checkbox") + + value = controller.InputCheckbox(page, "value") + value.expect_checked(True) + + width = controller.InputCheckbox(page, "width") + width.expect_width("10px") diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py new file mode 100644 index 000000000..d3ba87a43 --- /dev/null +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py @@ -0,0 +1,53 @@ +from shiny import req +from shiny.express import input, render, ui + +ui.page_opts(title="Checkbox Group Kitchen Sink", fillable=True) + +choices = ["Option A", "Option B", "Option C", "Option D"] + +choices_dict = { + "value1": "Option A", + "value2": "Option B", + "value3": "Option C", + "value4": "Option D", +} + +with ui.layout_columns(): + with ui.card(): + ui.card_header("Default Checkbox Group with label") + ui.input_checkbox_group("default", "Basic Checkbox Group", choices=choices) + + with ui.card(): + ui.card_header("With Selected Values") + ui.input_checkbox_group( + "selected", + "Selected Values", + choices=choices, + selected=["Option B", "Option C"], + ) + + with ui.card(): + ui.card_header("With Width") + ui.input_checkbox_group("width", "Custom Width", choices=choices, width="30px") + + with ui.card(): + ui.card_header("Inline") + ui.input_checkbox_group( + "inline", "Inline Checkbox Group", choices=choices, inline=True + ) + + @render.code + def inline_val_txt(): + return "You chose " + ", ".join(input.inline()) + + with ui.card(): + ui.card_header("With dict of values") + ui.input_checkbox_group( + "dict_values", + "Dict Values", + choices=choices_dict, + ) + + @render.code + def dict_value_txt(): + return "You chose " + ", ".join(input.dict_values()) diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py new file mode 100644 index 000000000..f07d7af21 --- /dev/null +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py @@ -0,0 +1,34 @@ +from playwright.sync_api import Page + +from shiny.playwright import controller +from shiny.run import ShinyAppProc + + +def test_checkbox_group_kitchen(page: Page, local_app: ShinyAppProc) -> None: + page.goto(local_app.url) + + default = controller.InputCheckboxGroup(page, "default") + default.expect_label("Basic Checkbox Group") + default.expect_selected([]) + + selected = controller.InputCheckboxGroup(page, "selected") + selected.expect_selected(["Option B", "Option C"]) + + width = controller.InputCheckboxGroup(page, "width") + width.expect_width("30px") + + inline = controller.InputCheckboxGroup(page, "inline") + inline.expect_inline(True) + inline.set(["Option A", "Option D"]) + inline.expect_selected(["Option A", "Option D"]) + + inline_code = controller.OutputCode(page, "inline_val_txt") + inline_code.expect_value("You chose Option A, Option D") + + dict_values = controller.InputCheckboxGroup(page, "dict_values") + dict_values.expect_selected([]) + dict_values.set(["value1", "value4"]) + dict_values.expect_selected(["value1", "value4"]) + + dict_values_code = controller.OutputCode(page, "dict_value_txt") + dict_values_code.expect_value("You chose value1, value4") From b2453823ba09944d1ed0ba32eadfc38e93b22d76 Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Mon, 23 Sep 2024 20:44:48 -0700 Subject: [PATCH 02/10] remove unused imports --- .../input_controls_kitchensink/input_checkbox_group/app.py | 1 - 1 file changed, 1 deletion(-) diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py index d3ba87a43..616aa84d6 100644 --- a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py @@ -1,4 +1,3 @@ -from shiny import req from shiny.express import input, render, ui ui.page_opts(title="Checkbox Group Kitchen Sink", fillable=True) From 0dd396391a306c99c62f7f79ce3cc0449dea5778 Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Mon, 23 Sep 2024 20:54:49 -0700 Subject: [PATCH 03/10] remove incorrect expect_width in tests --- tests/playwright/shiny/inputs/test_input_checkbox.py | 2 -- 1 file changed, 2 deletions(-) diff --git a/tests/playwright/shiny/inputs/test_input_checkbox.py b/tests/playwright/shiny/inputs/test_input_checkbox.py index 3f350741c..659dfb41a 100644 --- a/tests/playwright/shiny/inputs/test_input_checkbox.py +++ b/tests/playwright/shiny/inputs/test_input_checkbox.py @@ -17,8 +17,6 @@ def test_input_checkbox_kitchen(page: Page, app: ShinyAppProc) -> None: somevalue.expect_label("Some value") somevalue.expect_checked(False) - somevalue.expect_width(None) - output_txt.expect.to_have_text("False") somevalue.set(True) From b41a5e25bb5c4f7fa11dd09f1ba74e7c4a04d01d Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Tue, 24 Sep 2024 09:59:35 -0700 Subject: [PATCH 04/10] Update CHANGELOG.md --- CHANGELOG.md | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index db516d0fa..8e7dbec94 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,6 +37,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed the `InputSlider` controller's `.expect_width()` to check the `width` property within the `style` attribute. (#1691) +* Fixed the `InputCheckbox` and `InputCheckboxGroup` controllers' `.expect_width()` to check the `width` property within the `style` attribute. (#1702) + ## [1.1.0] - 2024-09-03 ### New features From 6230a54c78794abf7f96e830bb06ace03be46c39 Mon Sep 17 00:00:00 2001 From: Karan Gathani Date: Tue, 24 Sep 2024 10:26:02 -0700 Subject: [PATCH 05/10] use a single width mixin instead of every component using their own --- .../playwright/controller/_input_controls.py | 98 ++++++------------- 1 file changed, 28 insertions(+), 70 deletions(-) diff --git a/shiny/playwright/controller/_input_controls.py b/shiny/playwright/controller/_input_controls.py index 142d2f03f..93ef19577 100644 --- a/shiny/playwright/controller/_input_controls.py +++ b/shiny/playwright/controller/_input_controls.py @@ -19,7 +19,6 @@ InitLocator, UiWithContainerP, UiWithLabel, - WidthContainerM, all_missing, not_is_missing, ) @@ -29,7 +28,30 @@ ) -class _InputSliderBase(UiWithLabel): +class InputWidthControlMixin: + """ + A mixin class that provides methods to control the width of input elements, such as checkboxes, sliders and radio buttons. + """ + + def expect_width( + self: UiWithContainerP, + value: AttrValue, + *, + timeout: Timeout = None, + ) -> None: + """ + Expect the input select to have a specific width. + Parameters + ---------- + value + The expected width. + timeout + The maximum time to wait for the expectation to be fulfilled. Defaults to `None`. + """ + _expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout) + + +class _InputSliderBase(InputWidthControlMixin, UiWithLabel): loc_irs: Locator """ @@ -202,19 +224,6 @@ def expect_max(self, value: AttrValue, *, timeout: Timeout = None) -> None: self.loc, "data-max", value=value, timeout=timeout ) - def expect_width(self, value: str, *, timeout: Timeout = None) -> None: - """ - Expects the slider to have the specified width. - - Parameters - ---------- - value - The expected width. - timeout - The maximum time to wait for the width to be visible and interactable. Defaults to `None`. - """ - _expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout) - def expect_step(self, value: AttrValue, *, timeout: Timeout = None) -> None: """ Expect the input element to have the expected `step` attribute value. @@ -463,31 +472,7 @@ def _handle_center( return handle_center -class InputCheckboxWidthM: - """ - A mixin class for input checkboc width. - This mixin class provides methods to expect the width of input checkbox. - """ - - def expect_width( - self: UiWithContainerP, - value: AttrValue, - *, - timeout: Timeout = None, - ) -> None: - """ - Expect the input select to have a specific width. - Parameters - ---------- - value - The expected width. - timeout - The maximum time to wait for the expectation to be fulfilled. Defaults to `None`. - """ - _expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout) - - -class _RadioButtonCheckboxGroupBase(InputCheckboxWidthM, UiWithLabel): +class _RadioButtonCheckboxGroupBase(InputWidthControlMixin, UiWithLabel): loc_choice_labels: Locator def expect_choice_labels( @@ -535,7 +520,6 @@ def expect_inline(self, value: bool, *, timeout: Timeout = None) -> None: class InputRadioButtons( - WidthContainerM, _RadioButtonCheckboxGroupBase, ): """Controller for :func:`shiny.ui.input_radio_buttons`.""" @@ -670,7 +654,7 @@ def expect_selected( class _InputCheckboxBase( - InputCheckboxWidthM, + InputWidthControlMixin, UiWithLabel, ): def __init__( @@ -958,33 +942,7 @@ def __init__( ) -class InputSelectWidthM: - """ - A base class representing the input `select` and `selectize` widths. - - This class provides methods to expect the width attribute of a DOM element. - """ - - def expect_width( - self: UiWithContainerP, - value: AttrValue, - *, - timeout: Timeout = None, - ) -> None: - """ - Expect the input select to have a specific width. - - Parameters - ---------- - value - The expected width. - timeout - The maximum time to wait for the expectation to be fulfilled. Defaults to `None`. - """ - _expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout) - - -class InputSelect(InputSelectWidthM, UiWithLabel): +class InputSelect(InputWidthControlMixin, UiWithLabel): """ Controller for :func:`shiny.ui.input_select`. @@ -1211,7 +1169,7 @@ def expect_size(self, value: AttrValue, *, timeout: Timeout = None) -> None: ) -class InputSelectize(InputSelectWidthM, UiWithLabel): +class InputSelectize(InputWidthControlMixin, UiWithLabel): """Controller for :func:`shiny.ui.input_selectize`.""" def __init__(self, page: Page, id: str) -> None: From 0a3d12300ec1c3278f957cbc97f4b5f06b91f6c0 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 24 Sep 2024 14:29:07 -0400 Subject: [PATCH 06/10] Apply suggestions from code review --- CHANGELOG.md | 2 +- shiny/playwright/controller/_input_controls.py | 8 ++++++-- .../input_checkbox/test_input_checkbox_kitchensink.py | 1 + 3 files changed, 8 insertions(+), 3 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8e7dbec94..47bc57a33 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -37,7 +37,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 * Fixed the `InputSlider` controller's `.expect_width()` to check the `width` property within the `style` attribute. (#1691) -* Fixed the `InputCheckbox` and `InputCheckboxGroup` controllers' `.expect_width()` to check the `width` property within the `style` attribute. (#1702) +* Fixed the `InputCheckbox` and `InputCheckboxGroup` playwright controllers' `.expect_width()` to check the `width` property within the `style` attribute. (#1702) ## [1.1.0] - 2024-09-03 diff --git a/shiny/playwright/controller/_input_controls.py b/shiny/playwright/controller/_input_controls.py index 93ef19577..445cc514c 100644 --- a/shiny/playwright/controller/_input_controls.py +++ b/shiny/playwright/controller/_input_controls.py @@ -40,7 +40,8 @@ def expect_width( timeout: Timeout = None, ) -> None: """ - Expect the input select to have a specific width. + Expect the input element to have a specific width. + Parameters ---------- value @@ -472,7 +473,10 @@ def _handle_center( return handle_center -class _RadioButtonCheckboxGroupBase(InputWidthControlMixin, UiWithLabel): +class _RadioButtonCheckboxGroupBase( + InputWidthControlMixin, + UiWithLabel +): loc_choice_labels: Locator def expect_choice_labels( diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py index cdc6818a7..7a0a97090 100644 --- a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py @@ -9,6 +9,7 @@ def test_checkbox_kitchen(page: Page, local_app: ShinyAppProc) -> None: default = controller.InputCheckbox(page, "default") default.expect_label("Basic Checkbox") + default.expect_checked(False) value = controller.InputCheckbox(page, "value") value.expect_checked(True) From 5da09eab7e02ce769316a7d64f25870115871bb4 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 24 Sep 2024 14:34:09 -0400 Subject: [PATCH 07/10] Move new mixin to `_base.py` --- shiny/playwright/controller/_base.py | 24 ++++++++++ .../playwright/controller/_input_controls.py | 47 +++++++------------ 2 files changed, 40 insertions(+), 31 deletions(-) diff --git a/shiny/playwright/controller/_base.py b/shiny/playwright/controller/_base.py index 119e99dab..329a47324 100644 --- a/shiny/playwright/controller/_base.py +++ b/shiny/playwright/controller/_base.py @@ -387,6 +387,30 @@ def expect_width( ) +class WidthContainerStyleM: + """ + A mixin class that provides methods to control the width of input elements, such as checkboxes, sliders and radio buttons. + """ + + def expect_width( + self: UiWithContainerP, + value: AttrValue, + *, + timeout: Timeout = None, + ) -> None: + """ + Expect the input element to have a specific width. + + Parameters + ---------- + value + The expected width. + timeout + The maximum time to wait for the expectation to be fulfilled. Defaults to `None`. + """ + _expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout) + + class InputActionBase(UiBase): def expect_label( self, diff --git a/shiny/playwright/controller/_input_controls.py b/shiny/playwright/controller/_input_controls.py index 445cc514c..98235831a 100644 --- a/shiny/playwright/controller/_input_controls.py +++ b/shiny/playwright/controller/_input_controls.py @@ -17,8 +17,8 @@ from ..expect._internal import expect_style_to_have_value as _expect_style_to_have_value from ._base import ( InitLocator, - UiWithContainerP, UiWithLabel, + WidthContainerStyleM, all_missing, not_is_missing, ) @@ -28,31 +28,10 @@ ) -class InputWidthControlMixin: - """ - A mixin class that provides methods to control the width of input elements, such as checkboxes, sliders and radio buttons. - """ - - def expect_width( - self: UiWithContainerP, - value: AttrValue, - *, - timeout: Timeout = None, - ) -> None: - """ - Expect the input element to have a specific width. - - Parameters - ---------- - value - The expected width. - timeout - The maximum time to wait for the expectation to be fulfilled. Defaults to `None`. - """ - _expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout) - - -class _InputSliderBase(InputWidthControlMixin, UiWithLabel): +class _InputSliderBase( + WidthContainerStyleM, + UiWithLabel, +): loc_irs: Locator """ @@ -474,8 +453,8 @@ def _handle_center( class _RadioButtonCheckboxGroupBase( - InputWidthControlMixin, - UiWithLabel + WidthContainerStyleM, + UiWithLabel, ): loc_choice_labels: Locator @@ -658,7 +637,7 @@ def expect_selected( class _InputCheckboxBase( - InputWidthControlMixin, + WidthContainerStyleM, UiWithLabel, ): def __init__( @@ -946,7 +925,10 @@ def __init__( ) -class InputSelect(InputWidthControlMixin, UiWithLabel): +class InputSelect( + WidthContainerStyleM, + UiWithLabel, +): """ Controller for :func:`shiny.ui.input_select`. @@ -1173,7 +1155,10 @@ def expect_size(self, value: AttrValue, *, timeout: Timeout = None) -> None: ) -class InputSelectize(InputWidthControlMixin, UiWithLabel): +class InputSelectize( + WidthContainerStyleM, + UiWithLabel, +): """Controller for :func:`shiny.ui.input_selectize`.""" def __init__(self, page: Page, id: str) -> None: From ae713d8be51add01a71c9a3564031c1e6bfe34d2 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 24 Sep 2024 14:36:22 -0400 Subject: [PATCH 08/10] Discard changes to shiny/api-examples/input_checkbox/app-core.py --- shiny/api-examples/input_checkbox/app-core.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/shiny/api-examples/input_checkbox/app-core.py b/shiny/api-examples/input_checkbox/app-core.py index 241561d2f..b84f92de3 100644 --- a/shiny/api-examples/input_checkbox/app-core.py +++ b/shiny/api-examples/input_checkbox/app-core.py @@ -1,7 +1,7 @@ from shiny import App, Inputs, Outputs, Session, render, ui app_ui = ui.page_fluid( - ui.input_checkbox("somevalue", "Some value", False, width="600px"), + ui.input_checkbox("somevalue", "Some value", False), ui.output_ui("value"), ) From 1ca380adcee11fd613d2c890dd48fa8005819a6d Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 24 Sep 2024 14:54:34 -0400 Subject: [PATCH 09/10] Add output code for each checkbox group. Test many round trips values --- .../input_checkbox/app.py | 14 ++++++++++++- .../test_input_checkbox_kitchensink.py | 8 ++++++++ .../input_checkbox_group/app.py | 20 +++++++++++++++---- .../test_input_checkbox_group_kitchensink.py | 16 ++++++++------- 4 files changed, 46 insertions(+), 12 deletions(-) diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py index 2929a6a35..647fe4339 100644 --- a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/app.py @@ -1,4 +1,4 @@ -from shiny.express import ui +from shiny.express import input, render, ui ui.page_opts(title="Checkbox Kitchen Sink", fillable=True) @@ -7,10 +7,22 @@ ui.card_header("Default checkbox with label") ui.input_checkbox("default", "Basic Checkbox") + @render.code + def default_txt(): + return str(input.default()) + with ui.card(): ui.card_header("Checkbox With Value") ui.input_checkbox("value", "Checkbox with Value", value=True) + @render.code + def value_txt(): + return str(input.value()) + with ui.card(): ui.card_header("Checkbox With Width") ui.input_checkbox("width", "Checkbox with Width", width="10px") + + @render.code + def width_txt(): + return str(input.width()) diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py index 7a0a97090..731b91650 100644 --- a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox/test_input_checkbox_kitchensink.py @@ -10,9 +10,17 @@ def test_checkbox_kitchen(page: Page, local_app: ShinyAppProc) -> None: default = controller.InputCheckbox(page, "default") default.expect_label("Basic Checkbox") default.expect_checked(False) + default_code = controller.OutputCode(page, "default_txt") + default_code.expect_value("False") + default.set(True) + default_code.expect_value("True") + default.set(False) + default_code.expect_value("False") value = controller.InputCheckbox(page, "value") value.expect_checked(True) + controller.OutputCode(page, "value_txt").expect_value("True") width = controller.InputCheckbox(page, "width") width.expect_width("10px") + controller.OutputCode(page, "width_txt").expect_value("False") diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py index 616aa84d6..47a381c05 100644 --- a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/app.py @@ -16,6 +16,10 @@ ui.card_header("Default Checkbox Group with label") ui.input_checkbox_group("default", "Basic Checkbox Group", choices=choices) + @render.code + def default_txt(): + return str(input.default()) + with ui.card(): ui.card_header("With Selected Values") ui.input_checkbox_group( @@ -25,10 +29,18 @@ selected=["Option B", "Option C"], ) + @render.code + def selected_txt(): + return str(input.selected()) + with ui.card(): ui.card_header("With Width") ui.input_checkbox_group("width", "Custom Width", choices=choices, width="30px") + @render.code + def width_txt(): + return str(input.width()) + with ui.card(): ui.card_header("Inline") ui.input_checkbox_group( @@ -36,8 +48,8 @@ ) @render.code - def inline_val_txt(): - return "You chose " + ", ".join(input.inline()) + def inline_txt(): + return str(input.inline()) with ui.card(): ui.card_header("With dict of values") @@ -48,5 +60,5 @@ def inline_val_txt(): ) @render.code - def dict_value_txt(): - return "You chose " + ", ".join(input.dict_values()) + def dict_values_txt(): + return str(input.dict_values()) diff --git a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py index f07d7af21..6ee55d8be 100644 --- a/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py +++ b/tests/playwright/shiny/inputs/input_controls_kitchensink/input_checkbox_group/test_input_checkbox_group_kitchensink.py @@ -10,25 +10,27 @@ def test_checkbox_group_kitchen(page: Page, local_app: ShinyAppProc) -> None: default = controller.InputCheckboxGroup(page, "default") default.expect_label("Basic Checkbox Group") default.expect_selected([]) + controller.OutputCode(page, "default_txt").expect_value("()") selected = controller.InputCheckboxGroup(page, "selected") selected.expect_selected(["Option B", "Option C"]) + controller.OutputCode(page, "selected_txt").expect_value("('Option B', 'Option C')") width = controller.InputCheckboxGroup(page, "width") width.expect_width("30px") inline = controller.InputCheckboxGroup(page, "inline") inline.expect_inline(True) - inline.set(["Option A", "Option D"]) + inline_txt = controller.OutputCode(page, "inline_txt") + inline_txt.expect_value("()") + # Set in wrong order + inline.set(["Option D", "Option A"]) inline.expect_selected(["Option A", "Option D"]) - - inline_code = controller.OutputCode(page, "inline_val_txt") - inline_code.expect_value("You chose Option A, Option D") + inline_txt.expect_value("('Option A', 'Option D')") dict_values = controller.InputCheckboxGroup(page, "dict_values") dict_values.expect_selected([]) dict_values.set(["value1", "value4"]) dict_values.expect_selected(["value1", "value4"]) - - dict_values_code = controller.OutputCode(page, "dict_value_txt") - dict_values_code.expect_value("You chose value1, value4") + dict_values_txt = controller.OutputCode(page, "dict_values_txt") + dict_values_txt.expect_value("('value1', 'value4')") From 264a60ef0d9727be53fb3fe959e2d1a2f6506793 Mon Sep 17 00:00:00 2001 From: Barret Schloerke Date: Tue, 24 Sep 2024 15:02:02 -0400 Subject: [PATCH 10/10] Discard changes to tests/playwright/shiny/inputs/test_input_checkbox.py --- tests/playwright/shiny/inputs/test_input_checkbox.py | 2 ++ 1 file changed, 2 insertions(+) diff --git a/tests/playwright/shiny/inputs/test_input_checkbox.py b/tests/playwright/shiny/inputs/test_input_checkbox.py index 659dfb41a..3f350741c 100644 --- a/tests/playwright/shiny/inputs/test_input_checkbox.py +++ b/tests/playwright/shiny/inputs/test_input_checkbox.py @@ -17,6 +17,8 @@ def test_input_checkbox_kitchen(page: Page, app: ShinyAppProc) -> None: somevalue.expect_label("Some value") somevalue.expect_checked(False) + somevalue.expect_width(None) + output_txt.expect.to_have_text("False") somevalue.set(True)