Skip to content

Commit ead102a

Browse files
tests(accordion): Add kitchensink tests for accordion (#1710)
Co-authored-by: Barret Schloerke <[email protected]>
1 parent 53c5605 commit ead102a

File tree

5 files changed

+146
-6
lines changed

5 files changed

+146
-6
lines changed

CHANGELOG.md

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

1414
* `.expect_layout()` for Navset controllers in `shiny.playwright.controllers` is now renamed to `.expect_fluid()` and requires a `bool` value. To keep behavior the same, use `.expect_fluid(True)` (#1668)
1515

16+
* `.expect_icon()` for Accordion controllers in `shiny.playwright.controllers` now requires a `bool` value instead of a `str`. (#1710)
17+
1618
### New features
1719

1820
* Added [narwhals](https://posit-dev.github.io/py-narwhals) support for `@render.data_frame`. This allows for any eager data frame supported by narwhals to be returned from a `@render.data_frame` output method. All internal methods and helper methods leverage the `narwhals` API to be data frame agnostic. (#1570)
@@ -31,6 +33,8 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
3133

3234
* Small improvements to the default pulse busy indicator to better blend with any background. It's also now slightly smaller by default.(#1707)
3335

36+
* Added `.expect_class()` and `.expect_multiple()` for `Accordion` in `shiny.playwright.controllers` (#1710)
37+
3438
* Added [narwhals](https://posit-dev.github.io/py-narwhals) support for `@render.table`. This allows for any eager data frame supported by narwhals to be returned from a `@render.table` output method. (#1570)
3539

3640
### Bug fixes

shiny/playwright/controller/_accordion.py

Lines changed: 55 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,18 +98,22 @@ def expect_body(self, value: PatternOrStr, *, timeout: Timeout = None) -> None:
9898
"""
9999
playwright_expect(self.loc_body).to_have_text(value, timeout=timeout)
100100

101-
def expect_icon(self, value: PatternOrStr, *, timeout: Timeout = None) -> None:
101+
def expect_icon(self, exists: bool, *, timeout: Timeout = None) -> None:
102102
"""
103-
Expects the accordion panel icon to have the specified text.
103+
Expects the accordion panel icon to exist or not.
104104
105105
Parameters
106106
----------
107-
value
108-
The expected text pattern or string.
107+
exists
108+
`True` if the icon is expected to exist, `False` otherwise.
109109
timeout
110110
The maximum time to wait for the icon to appear. Defaults to `None`.
111111
"""
112-
playwright_expect(self.loc_icon).to_have_text(value, timeout=timeout)
112+
icon_child_loc = self.loc_icon.locator("> *")
113+
if exists:
114+
playwright_expect(icon_child_loc).not_to_have_count(0, timeout=timeout)
115+
else:
116+
playwright_expect(icon_child_loc).to_have_count(0, timeout=timeout)
113117

114118
def expect_open(self, value: bool, *, timeout: Timeout = None) -> None:
115119
"""
@@ -313,6 +317,52 @@ def set(
313317
)
314318
self.accordion_panel(elem_value).set(elem_value in open, timeout=timeout)
315319

320+
def expect_class(
321+
self,
322+
class_name: str,
323+
*,
324+
timeout: Timeout = None,
325+
) -> None:
326+
"""
327+
Expects the accordion to have the specified class.
328+
329+
Parameters
330+
----------
331+
class_name
332+
The class name to expect.
333+
timeout
334+
The maximum time to wait for the class to appear. Defaults to `None`.
335+
"""
336+
_expect_class_to_have_value(
337+
self.loc_container,
338+
class_name,
339+
has_class=True,
340+
timeout=timeout,
341+
)
342+
343+
def expect_multiple(
344+
self,
345+
value: bool,
346+
*,
347+
timeout: Timeout = None,
348+
) -> None:
349+
"""
350+
Expects the accordion to be multiple or not.
351+
352+
Parameters
353+
----------
354+
value
355+
`True` if the accordion is expected to be multiple, `False` otherwise.
356+
timeout
357+
The maximum time to wait for the expectation to pass. Defaults to `None`.
358+
"""
359+
_expect_class_to_have_value(
360+
self.loc_container,
361+
"autoclose",
362+
has_class=not value,
363+
timeout=timeout,
364+
)
365+
316366
def accordion_panel(
317367
self,
318368
data_value: str,

tests/playwright/shiny/components/accordion/test_accordion.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -66,7 +66,7 @@ def test_accordion(page: Page, local_app: ShinyAppProc) -> None:
6666
toggle_updates_button.click()
6767
acc_panel_updated_A.expect_label("Updated title")
6868
acc_panel_updated_A.expect_body("Updated body")
69-
acc_panel_updated_A.expect_icon("Look! An icon! -->")
69+
acc_panel_updated_A.expect_icon(True)
7070

7171
acc.expect_panels(["updated_section_a", "Section B", "Section C", "Section D"])
7272
# workaround - toggle it twice Section A
Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
from faicons import icon_svg
2+
3+
from shiny import App, Inputs, ui
4+
5+
app_ui = ui.page_fluid(
6+
ui.h1("Accordion Kitchensink"),
7+
ui.accordion(
8+
ui.accordion_panel(
9+
"Panel 1",
10+
ui.p("This is the content of Panel 1"),
11+
value="panel1",
12+
),
13+
ui.accordion_panel(
14+
"Panel 2",
15+
ui.p("This is the content of Panel 2"),
16+
icon=icon_svg("trash-arrow-up"),
17+
value="panel2",
18+
),
19+
id="accordion_1",
20+
width="600px",
21+
height="300px",
22+
multiple=False,
23+
class_="bg-light",
24+
),
25+
ui.accordion(
26+
ui.accordion_panel(
27+
"Panel 3",
28+
ui.p("This is the content of Panel 3"),
29+
value="panel3",
30+
),
31+
ui.accordion_panel(
32+
"Panel 4",
33+
ui.p("This is the content of Panel 4"),
34+
value="panel4",
35+
),
36+
id="accordion_2",
37+
multiple=True,
38+
),
39+
)
40+
41+
42+
def server(input: Inputs):
43+
pass
44+
45+
46+
app = App(app_ui, server)
Lines changed: 40 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
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_accordion_kitchensink(page: Page, local_app: ShinyAppProc) -> None:
8+
page.goto(local_app.url)
9+
10+
accordion1 = controller.Accordion(page, "accordion_1")
11+
accordion1.expect_width("600px")
12+
accordion1.expect_height("300px")
13+
accordion1.expect_class("bg-light")
14+
accordion1.expect_multiple(False)
15+
accordion1_panel1 = accordion1.accordion_panel("panel1")
16+
accordion1_panel1.expect_open(True)
17+
accordion1_panel1.expect_label("Panel 1")
18+
accordion1_panel1.expect_icon(False)
19+
20+
accordion1_panel2 = accordion1.accordion_panel("panel2")
21+
accordion1_panel2.expect_open(False)
22+
accordion1_panel2.expect_label("Panel 2")
23+
accordion1_panel2.expect_icon(True)
24+
accordion1_panel2.set(True)
25+
accordion1_panel2.expect_open(True)
26+
accordion1_panel1.expect_open(False)
27+
28+
accordion2 = controller.Accordion(page, "accordion_2")
29+
accordion2.expect_width(None)
30+
accordion2.expect_height(None)
31+
accordion2.expect_multiple(True)
32+
33+
accordion2_panel3 = accordion2.accordion_panel("panel3")
34+
accordion2_panel3.expect_open(True)
35+
36+
accordion2_panel4 = accordion2.accordion_panel("panel4")
37+
accordion2_panel4.expect_open(False)
38+
accordion2_panel4.set(True)
39+
accordion2_panel4.expect_open(True)
40+
accordion2_panel3.expect_open(True)

0 commit comments

Comments
 (0)