Skip to content

Commit dee9a99

Browse files
authored
tests(checkbox): Add kitchensink tests for checkbox and checkbox_group (#1702)
1 parent 91a56cb commit dee9a99

File tree

7 files changed

+198
-48
lines changed

7 files changed

+198
-48
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3939

4040
* Fixed the `InputDate` and `InputDateRange` playwright controllers to check the `width` property within the `style` attribute. (#1696)
4141

42+
* Fixed the `InputCheckbox` and `InputCheckboxGroup` playwright controllers' `.expect_width()` to check the `width` property within the `style` attribute. (#1702)
43+
4244
## [1.1.0] - 2024-09-03
4345

4446
### New features

shiny/playwright/controller/_base.py

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -387,6 +387,30 @@ def expect_width(
387387
)
388388

389389

390+
class WidthContainerStyleM:
391+
"""
392+
A mixin class that provides methods to control the width of input elements, such as checkboxes, sliders and radio buttons.
393+
"""
394+
395+
def expect_width(
396+
self: UiWithContainerP,
397+
value: AttrValue,
398+
*,
399+
timeout: Timeout = None,
400+
) -> None:
401+
"""
402+
Expect the input element to have a specific width.
403+
404+
Parameters
405+
----------
406+
value
407+
The expected width.
408+
timeout
409+
The maximum time to wait for the expectation to be fulfilled. Defaults to `None`.
410+
"""
411+
_expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout)
412+
413+
390414
class InputActionBase(UiBase):
391415
def expect_label(
392416
self,

shiny/playwright/controller/_input_controls.py

Lines changed: 18 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -17,9 +17,8 @@
1717
from ..expect._internal import expect_style_to_have_value as _expect_style_to_have_value
1818
from ._base import (
1919
InitLocator,
20-
UiWithContainerP,
2120
UiWithLabel,
22-
WidthContainerM,
21+
WidthContainerStyleM,
2322
all_missing,
2423
not_is_missing,
2524
)
@@ -29,7 +28,10 @@
2928
)
3029

3130

32-
class _InputSliderBase(UiWithLabel):
31+
class _InputSliderBase(
32+
WidthContainerStyleM,
33+
UiWithLabel,
34+
):
3335

3436
loc_irs: Locator
3537
"""
@@ -202,19 +204,6 @@ def expect_max(self, value: AttrValue, *, timeout: Timeout = None) -> None:
202204
self.loc, "data-max", value=value, timeout=timeout
203205
)
204206

205-
def expect_width(self, value: str, *, timeout: Timeout = None) -> None:
206-
"""
207-
Expects the slider to have the specified width.
208-
209-
Parameters
210-
----------
211-
value
212-
The expected width.
213-
timeout
214-
The maximum time to wait for the expectation to be fulfilled. Defaults to `None`.
215-
"""
216-
_expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout)
217-
218207
def expect_step(self, value: AttrValue, *, timeout: Timeout = None) -> None:
219208
"""
220209
Expect the input element to have the expected `step` attribute value.
@@ -463,7 +452,10 @@ def _handle_center(
463452
return handle_center
464453

465454

466-
class _RadioButtonCheckboxGroupBase(UiWithLabel):
455+
class _RadioButtonCheckboxGroupBase(
456+
WidthContainerStyleM,
457+
UiWithLabel,
458+
):
467459
loc_choice_labels: Locator
468460

469461
def expect_choice_labels(
@@ -511,7 +503,6 @@ def expect_inline(self, value: bool, *, timeout: Timeout = None) -> None:
511503

512504

513505
class InputRadioButtons(
514-
WidthContainerM,
515506
_RadioButtonCheckboxGroupBase,
516507
):
517508
"""Controller for :func:`shiny.ui.input_radio_buttons`."""
@@ -646,7 +637,7 @@ def expect_selected(
646637

647638

648639
class _InputCheckboxBase(
649-
WidthContainerM,
640+
WidthContainerStyleM,
650641
UiWithLabel,
651642
):
652643
def __init__(
@@ -721,7 +712,6 @@ def expect_checked(self, value: bool, *, timeout: Timeout = None) -> None:
721712

722713

723714
class InputCheckboxGroup(
724-
WidthContainerM,
725715
_RadioButtonCheckboxGroupBase,
726716
):
727717
"""Controller for :func:`shiny.ui.input_checkbox_group`."""
@@ -935,33 +925,10 @@ def __init__(
935925
)
936926

937927

938-
class InputSelectWidthM:
939-
"""
940-
A base class representing the input `select` and `selectize` widths.
941-
942-
This class provides methods to expect the width attribute of a DOM element.
943-
"""
944-
945-
def expect_width(
946-
self: UiWithContainerP,
947-
value: AttrValue,
948-
*,
949-
timeout: Timeout = None,
950-
) -> None:
951-
"""
952-
Expect the input select to have a specific width.
953-
954-
Parameters
955-
----------
956-
value
957-
The expected width.
958-
timeout
959-
The maximum time to wait for the expectation to be fulfilled. Defaults to `None`.
960-
"""
961-
_expect_style_to_have_value(self.loc_container, "width", value, timeout=timeout)
962-
963-
964-
class InputSelect(InputSelectWidthM, UiWithLabel):
928+
class InputSelect(
929+
WidthContainerStyleM,
930+
UiWithLabel,
931+
):
965932
"""
966933
Controller for :func:`shiny.ui.input_select`.
967934
@@ -1188,7 +1155,10 @@ def expect_size(self, value: AttrValue, *, timeout: Timeout = None) -> None:
11881155
)
11891156

11901157

1191-
class InputSelectize(InputSelectWidthM, UiWithLabel):
1158+
class InputSelectize(
1159+
WidthContainerStyleM,
1160+
UiWithLabel,
1161+
):
11921162
"""Controller for :func:`shiny.ui.input_selectize`."""
11931163

11941164
def __init__(self, page: Page, id: str) -> None:
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
from shiny.express import input, render, ui
2+
3+
ui.page_opts(title="Checkbox Kitchen Sink", fillable=True)
4+
5+
with ui.layout_columns():
6+
with ui.card():
7+
ui.card_header("Default checkbox with label")
8+
ui.input_checkbox("default", "Basic Checkbox")
9+
10+
@render.code
11+
def default_txt():
12+
return str(input.default())
13+
14+
with ui.card():
15+
ui.card_header("Checkbox With Value")
16+
ui.input_checkbox("value", "Checkbox with Value", value=True)
17+
18+
@render.code
19+
def value_txt():
20+
return str(input.value())
21+
22+
with ui.card():
23+
ui.card_header("Checkbox With Width")
24+
ui.input_checkbox("width", "Checkbox with Width", width="10px")
25+
26+
@render.code
27+
def width_txt():
28+
return str(input.width())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
from playwright.sync_api import Page
2+
3+
from shiny.playwright import controller
4+
from shiny.run import ShinyAppProc
5+
6+
7+
def test_checkbox_kitchen(page: Page, local_app: ShinyAppProc) -> None:
8+
page.goto(local_app.url)
9+
10+
default = controller.InputCheckbox(page, "default")
11+
default.expect_label("Basic Checkbox")
12+
default.expect_checked(False)
13+
default_code = controller.OutputCode(page, "default_txt")
14+
default_code.expect_value("False")
15+
default.set(True)
16+
default_code.expect_value("True")
17+
default.set(False)
18+
default_code.expect_value("False")
19+
20+
value = controller.InputCheckbox(page, "value")
21+
value.expect_checked(True)
22+
controller.OutputCode(page, "value_txt").expect_value("True")
23+
24+
width = controller.InputCheckbox(page, "width")
25+
width.expect_width("10px")
26+
controller.OutputCode(page, "width_txt").expect_value("False")
Lines changed: 64 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
from shiny.express import input, render, ui
2+
3+
ui.page_opts(title="Checkbox Group Kitchen Sink", fillable=True)
4+
5+
choices = ["Option A", "Option B", "Option C", "Option D"]
6+
7+
choices_dict = {
8+
"value1": "Option A",
9+
"value2": "Option B",
10+
"value3": "Option C",
11+
"value4": "Option D",
12+
}
13+
14+
with ui.layout_columns():
15+
with ui.card():
16+
ui.card_header("Default Checkbox Group with label")
17+
ui.input_checkbox_group("default", "Basic Checkbox Group", choices=choices)
18+
19+
@render.code
20+
def default_txt():
21+
return str(input.default())
22+
23+
with ui.card():
24+
ui.card_header("With Selected Values")
25+
ui.input_checkbox_group(
26+
"selected",
27+
"Selected Values",
28+
choices=choices,
29+
selected=["Option B", "Option C"],
30+
)
31+
32+
@render.code
33+
def selected_txt():
34+
return str(input.selected())
35+
36+
with ui.card():
37+
ui.card_header("With Width")
38+
ui.input_checkbox_group("width", "Custom Width", choices=choices, width="30px")
39+
40+
@render.code
41+
def width_txt():
42+
return str(input.width())
43+
44+
with ui.card():
45+
ui.card_header("Inline")
46+
ui.input_checkbox_group(
47+
"inline", "Inline Checkbox Group", choices=choices, inline=True
48+
)
49+
50+
@render.code
51+
def inline_txt():
52+
return str(input.inline())
53+
54+
with ui.card():
55+
ui.card_header("With dict of values")
56+
ui.input_checkbox_group(
57+
"dict_values",
58+
"Dict Values",
59+
choices=choices_dict,
60+
)
61+
62+
@render.code
63+
def dict_values_txt():
64+
return str(input.dict_values())
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
from playwright.sync_api import Page
2+
3+
from shiny.playwright import controller
4+
from shiny.run import ShinyAppProc
5+
6+
7+
def test_checkbox_group_kitchen(page: Page, local_app: ShinyAppProc) -> None:
8+
page.goto(local_app.url)
9+
10+
default = controller.InputCheckboxGroup(page, "default")
11+
default.expect_label("Basic Checkbox Group")
12+
default.expect_selected([])
13+
controller.OutputCode(page, "default_txt").expect_value("()")
14+
15+
selected = controller.InputCheckboxGroup(page, "selected")
16+
selected.expect_selected(["Option B", "Option C"])
17+
controller.OutputCode(page, "selected_txt").expect_value("('Option B', 'Option C')")
18+
19+
width = controller.InputCheckboxGroup(page, "width")
20+
width.expect_width("30px")
21+
22+
inline = controller.InputCheckboxGroup(page, "inline")
23+
inline.expect_inline(True)
24+
inline_txt = controller.OutputCode(page, "inline_txt")
25+
inline_txt.expect_value("()")
26+
# Set in wrong order
27+
inline.set(["Option D", "Option A"])
28+
inline.expect_selected(["Option A", "Option D"])
29+
inline_txt.expect_value("('Option A', 'Option D')")
30+
31+
dict_values = controller.InputCheckboxGroup(page, "dict_values")
32+
dict_values.expect_selected([])
33+
dict_values.set(["value1", "value4"])
34+
dict_values.expect_selected(["value1", "value4"])
35+
dict_values_txt = controller.OutputCode(page, "dict_values_txt")
36+
dict_values_txt.expect_value("('value1', 'value4')")

0 commit comments

Comments
 (0)