Skip to content

Commit 713e688

Browse files
committed
Add tests for sidebar
1 parent ffd06d3 commit 713e688

File tree

3 files changed

+202
-1
lines changed

3 files changed

+202
-1
lines changed

shiny/playwright/controller/_layout.py

Lines changed: 97 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77

88
from .._types import PatternOrStr, Timeout
99
from ..expect._internal import expect_class_to_have_value as _expect_class_to_have_value
10+
from ..expect._internal import expect_style_to_have_value as _expect_style_to_have_value
1011
from ._base import UiWithContainer, WidthLocM
1112

1213

@@ -32,6 +33,14 @@ class Sidebar(
3233
"""
3334
Playwright `Locator` for the position of the sidebar.
3435
"""
36+
loc_content: Locator
37+
"""
38+
Playwright `Locator` for the content of the sidebar.
39+
"""
40+
loc_title: Locator
41+
"""
42+
Playwright `Locator` for the title of the sidebar.
43+
"""
3544

3645
def __init__(self, page: Page, id: str) -> None:
3746
"""
@@ -52,6 +61,8 @@ def __init__(self, page: Page, id: str) -> None:
5261
)
5362
self.loc_handle = self.loc_container.locator("button.collapse-toggle")
5463
self.loc_position = self.loc.locator("..")
64+
self.loc_content = self.loc.locator("> div.sidebar-content")
65+
self.loc_title = self.loc_content.locator("> header.sidebar-title")
5566

5667
def expect_text(self, value: PatternOrStr, *, timeout: Timeout = None) -> None:
5768
"""
@@ -64,7 +75,92 @@ def expect_text(self, value: PatternOrStr, *, timeout: Timeout = None) -> None:
6475
timeout
6576
The maximum time to wait for the text to appear. Defaults to `None`.
6677
"""
67-
playwright_expect(self.loc).to_have_text(value, timeout=timeout)
78+
playwright_expect(self.loc_content).to_have_text(value, timeout=timeout)
79+
80+
def expect_class(
81+
self,
82+
class_name: str,
83+
*,
84+
has_class: bool = True,
85+
timeout: Timeout = None,
86+
) -> None:
87+
"""
88+
Asserts that the sidebar has or does not have a CSS class.
89+
90+
Parameters
91+
----------
92+
class_name
93+
The CSS class to check for.
94+
has_class
95+
`True` if the sidebar should have the CSS class, `False` otherwise.
96+
timeout
97+
The maximum time to wait for the sidebar to appear. Defaults to `None`.
98+
"""
99+
_expect_class_to_have_value(
100+
self.loc,
101+
class_name,
102+
has_class=has_class,
103+
timeout=timeout,
104+
)
105+
106+
def expect_gap(self, value: PatternOrStr, *, timeout: Timeout = None) -> None:
107+
"""
108+
Asserts that the sidebar has the expected gap.
109+
110+
Parameters
111+
----------
112+
value
113+
The expected gap of the sidebar.
114+
timeout
115+
The maximum time to wait for the gap to appear. Defaults to `None`.
116+
"""
117+
_expect_style_to_have_value(self.loc_content, "gap", value, timeout=timeout)
118+
119+
def expect_bg_color(self, value: PatternOrStr, *, timeout: Timeout = None) -> None:
120+
"""
121+
Asserts that the sidebar has the expected background color.
122+
123+
Parameters
124+
----------
125+
value
126+
The expected background color of the sidebar.
127+
timeout
128+
The maximum time to wait for the background color to appear. Defaults to `None`.
129+
"""
130+
_expect_style_to_have_value(
131+
self.loc_container, "--_sidebar-bg", value, timeout=timeout
132+
)
133+
134+
def expect_title(self, value: PatternOrStr, *, timeout: Timeout = None) -> None:
135+
"""
136+
Asserts that the sidebar has the expected title.
137+
138+
Parameters
139+
----------
140+
value
141+
The expected title of the sidebar.
142+
timeout
143+
The maximum time to wait for the title to appear. Defaults to `None`.
144+
"""
145+
playwright_expect(self.loc_title).to_have_text(value, timeout=timeout)
146+
147+
def expect_padding(
148+
self, value: list[PatternOrStr], *, timeout: Timeout = None
149+
) -> None:
150+
"""
151+
Asserts that the sidebar has the expected padding.
152+
153+
Parameters
154+
----------
155+
value
156+
The expected padding of the sidebar.
157+
timeout
158+
The maximum time to wait for the padding to appear. Defaults to `None`.
159+
"""
160+
padding_val = " ".join(map(str, value))
161+
_expect_style_to_have_value(
162+
self.loc_content, "padding", padding_val, timeout=timeout
163+
)
68164

69165
def expect_position(
70166
self,
Lines changed: 67 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,67 @@
1+
from shiny.express import input, render, ui
2+
3+
ui.page_opts(fillable=True)
4+
5+
with ui.card():
6+
with ui.layout_sidebar():
7+
with ui.sidebar(
8+
id="sidebar_left",
9+
open="desktop",
10+
title="Left sidebar",
11+
bg="dodgerBlue",
12+
class_="text-white",
13+
max_height_mobile="175px",
14+
gap="20px",
15+
padding="10px",
16+
):
17+
"Left sidebar content"
18+
19+
@render.code
20+
def state_left():
21+
return f"input.sidebar_left(): {input.sidebar_left()}"
22+
23+
24+
with ui.card():
25+
with ui.layout_sidebar():
26+
with ui.sidebar(
27+
id="sidebar_right",
28+
position="right",
29+
open="desktop",
30+
padding=["10px", "20px"],
31+
bg="SlateBlue",
32+
):
33+
"Right sidebar content"
34+
35+
@render.code
36+
def state_right():
37+
return f"input.sidebar_right(): {input.sidebar_right()}"
38+
39+
40+
with ui.card():
41+
with ui.layout_sidebar():
42+
with ui.sidebar(
43+
id="sidebar_closed",
44+
open="closed",
45+
bg="LightCoral",
46+
padding=["10px", "20px", "30px"],
47+
):
48+
"Closed sidebar content"
49+
50+
@render.code
51+
def state_closed():
52+
return f"input.sidebar_closed(): {input.sidebar_closed()}"
53+
54+
55+
with ui.card():
56+
with ui.layout_sidebar():
57+
with ui.sidebar(
58+
id="sidebar_always",
59+
open="always",
60+
bg="PeachPuff",
61+
padding=["10px", "20px", "30px", "40px"],
62+
):
63+
"Always sidebar content"
64+
65+
@render.code
66+
def state_always():
67+
return f"input.sidebar_always(): {input.sidebar_always()}"
Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
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_sidebar_position_and_open(page: Page, local_app: ShinyAppProc) -> None:
8+
page.goto(local_app.url)
9+
10+
left_sidebar = controller.Sidebar(page, "sidebar_left")
11+
output_txt_left = controller.OutputTextVerbatim(page, "state_left")
12+
left_sidebar.set(True)
13+
left_sidebar.expect_padding(["10px"])
14+
left_sidebar.expect_title("Left sidebar")
15+
left_sidebar.expect_gap("20px")
16+
left_sidebar.expect_class("text-white", has_class=True)
17+
left_sidebar.expect_bg_color("dodgerBlue")
18+
output_txt_left.expect_value("input.sidebar_left(): True")
19+
left_sidebar.expect_open(True)
20+
left_sidebar.set(False)
21+
output_txt_left.expect_value("input.sidebar_left(): False")
22+
left_sidebar.expect_handle(True)
23+
left_sidebar.expect_open(False)
24+
left_sidebar.loc_handle.click()
25+
left_sidebar.expect_open(True)
26+
output_txt_left.expect_value("input.sidebar_left(): True")
27+
28+
right_sidebar = controller.Sidebar(page, "sidebar_right")
29+
right_sidebar.expect_padding(["10px", "20px"])
30+
right_sidebar.expect_bg_color("SlateBlue")
31+
32+
closed_sidebar = controller.Sidebar(page, "sidebar_closed")
33+
closed_sidebar.expect_padding(["10px", "20px", "30px"])
34+
closed_sidebar.expect_bg_color("LightCoral")
35+
36+
always_sidebar = controller.Sidebar(page, "sidebar_always")
37+
always_sidebar.expect_padding(["10px", "20px", "30px", "40px"])
38+
always_sidebar.expect_bg_color("PeachPuff")

0 commit comments

Comments
 (0)