Skip to content

Commit efbf767

Browse files
authored
Add kitchensink tests for valuebox (#1229)
1 parent 81bc6cc commit efbf767

File tree

5 files changed

+333
-19
lines changed

5 files changed

+333
-19
lines changed

tests/playwright/controls.py

Lines changed: 174 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2552,62 +2552,143 @@ def toggle(self, *, timeout: Timeout = None) -> None:
25522552

25532553

25542554
class _CardBodyP(_InputBaseP, Protocol):
2555+
"""
2556+
Represents the body of a card control.
2557+
"""
2558+
25552559
loc_body: Locator
2560+
"""
2561+
The locator for the body element of the card control.
2562+
"""
25562563

25572564

25582565
class _CardBodyM:
2566+
"""Represents a card body element with additional methods for testing."""
2567+
25592568
def expect_body(
25602569
self: _CardBodyP,
25612570
text: PatternOrStr | list[PatternOrStr],
25622571
*,
25632572
timeout: Timeout = None,
25642573
) -> None:
2565-
"""Note: If testing against multiple elements, text should be an array"""
2574+
"""Expect the card body element to have the specified text.
2575+
2576+
Parameters
2577+
----------
2578+
text
2579+
The expected text or a list of expected texts.
2580+
timeout
2581+
The maximum time to wait for the text to appear. Defaults to None.
2582+
"""
25662583
playwright_expect(self.loc).to_have_text(
25672584
text,
25682585
timeout=timeout,
25692586
)
25702587

25712588

25722589
class _CardFooterLayoutP(_InputBaseP, Protocol):
2590+
"""
2591+
Represents the layout of the footer in a card.
2592+
"""
2593+
25732594
loc_footer: Locator
2595+
"""
2596+
The locator for the footer element.
2597+
"""
25742598

25752599

25762600
class _CardFooterM:
2601+
"""
2602+
Represents the footer section of a card.
2603+
"""
2604+
25772605
def expect_footer(
25782606
self: _CardFooterLayoutP,
25792607
text: PatternOrStr,
25802608
*,
25812609
timeout: Timeout = None,
25822610
) -> None:
2611+
"""
2612+
Asserts that the footer section of the card has the expected text.
2613+
2614+
Parameters
2615+
----------
2616+
text
2617+
The expected text in the footer section.
2618+
timeout
2619+
The maximum time to wait for the footer text to appear. Defaults to None.
2620+
"""
25832621
playwright_expect(self.loc_footer).to_have_text(
25842622
text,
25852623
timeout=timeout,
25862624
)
25872625

25882626

25892627
class _CardFullScreenLayoutP(_OutputBaseP, Protocol):
2628+
"""
2629+
Represents a card full-screen layout for the Playwright controls.
2630+
"""
2631+
25902632
loc_title: Locator
2633+
"""
2634+
The locator for the title element.
2635+
"""
25912636
_loc_fullscreen: Locator
2637+
"""
2638+
The locator for the full-screen element.
2639+
"""
25922640
_loc_close_button: Locator
2641+
"""
2642+
The locator for the close button element.
2643+
"""
25932644

25942645

25952646
class _CardFullScreenM:
2647+
"""
2648+
Represents a class for managing full screen functionality of a card.
2649+
"""
2650+
25962651
def open_full_screen(
25972652
self: _CardFullScreenLayoutP, *, timeout: Timeout = None
25982653
) -> None:
2654+
"""
2655+
Opens the card in full screen mode.
2656+
2657+
Parameters
2658+
----------
2659+
timeout
2660+
The maximum time to wait for the card to open in full screen mode. Defaults to None.
2661+
"""
25992662
self.loc_title.hover(timeout=timeout)
26002663
self._loc_fullscreen.wait_for(state="visible", timeout=timeout)
26012664
self._loc_fullscreen.click(timeout=timeout)
26022665

26032666
def close_full_screen(
26042667
self: _CardFullScreenLayoutP, *, timeout: Timeout = None
26052668
) -> None:
2669+
"""
2670+
Closes the card from full screen mode.
2671+
2672+
Parameters
2673+
----------
2674+
timeout
2675+
The maximum time to wait for the card to close from full screen mode. Defaults to None.
2676+
"""
26062677
self._loc_close_button.click(timeout=timeout)
26072678

26082679
def expect_full_screen(
26092680
self: _CardFullScreenLayoutP, open: bool, *, timeout: Timeout = None
26102681
) -> None:
2682+
"""
2683+
Verifies if the card is expected to be in full screen mode.
2684+
2685+
Parameters
2686+
----------
2687+
open
2688+
True if the card is expected to be in full screen mode, False otherwise.
2689+
timeout
2690+
The maximum time to wait for the verification. Defaults to None.
2691+
"""
26112692
playwright_expect(self._loc_close_button).to_have_count(
26122693
int(open), timeout=timeout
26132694
)
@@ -2618,24 +2699,44 @@ class ValueBox(
26182699
_CardFullScreenM,
26192700
_InputWithContainer,
26202701
):
2621-
# title: TagChild,
2622-
# value: TagChild,
2623-
# *args: TagChild | TagAttrs,
2624-
# showcase: TagChild = None,
2625-
# showcase_layout: ((TagChild, Tag) -> CardItem) | None = None,
2626-
# full_screen: bool = False,
2627-
# theme_color: str | None = "primary",
2628-
# height: CssUnit | None = None,
2629-
# max_height: CssUnit | None = None,
2630-
# fill: bool = True,
2631-
# class_: str | None = None,
2632-
# **kwargs: TagAttrValue
2702+
"""
2703+
ValueBox control for shiny.ui.value_box - https://shiny.posit.co/py/api/core/ui.value_box.html
2704+
"""
2705+
2706+
loc: Locator
2707+
"""
2708+
Locator for the value box's value
2709+
"""
2710+
loc_showcase: Locator
2711+
"""
2712+
Locator for the value box showcase
2713+
"""
2714+
loc_title: Locator
2715+
"""
2716+
Locator for the value box title
2717+
"""
2718+
loc_body: Locator
2719+
"""
2720+
Locator for the value box body
2721+
"""
2722+
26332723
def __init__(self, page: Page, id: str) -> None:
2724+
"""
2725+
Initializes a new instance of the ValueBox class.
2726+
2727+
Parameters
2728+
----------
2729+
page
2730+
The Playwright page object.
2731+
id
2732+
The ID of the value box.
2733+
2734+
"""
26342735
super().__init__(
26352736
page,
26362737
id=id,
26372738
loc_container=f"div#{id}.bslib-value-box",
2638-
loc="> div > .value-box-grid",
2739+
loc="> div.card-body > .value-box-grid, > div.card-body",
26392740
)
26402741
value_box_grid = self.loc
26412742
self.loc_showcase = value_box_grid.locator("> .value-box-showcase")
@@ -2657,14 +2758,35 @@ def __init__(self, page: Page, id: str) -> None:
26572758
)
26582759

26592760
def expect_height(self, value: StyleValue, *, timeout: Timeout = None) -> None:
2660-
expect_to_have_style(self.loc_container, "height", value, timeout=timeout)
2761+
"""
2762+
Expects the value box to have a specific height.
2763+
2764+
Parameters
2765+
----------
2766+
value
2767+
The expected height value.
2768+
timeout
2769+
The maximum time to wait for the expectation to pass. Defaults to None.
2770+
"""
2771+
expect_to_have_style(self.loc_container, "max-height", value, timeout=timeout)
26612772

26622773
def expect_title(
26632774
self,
26642775
text: PatternOrStr,
26652776
*,
26662777
timeout: Timeout = None,
26672778
) -> None:
2779+
"""
2780+
Expects the value box title to have a specific text.
2781+
2782+
Parameters
2783+
----------
2784+
text
2785+
The expected text pattern or string.
2786+
timeout
2787+
The maximum time to wait for the expectation to pass. Defaults to None.
2788+
2789+
"""
26682790
playwright_expect(self.loc_title).to_have_text(
26692791
text,
26702792
timeout=timeout,
@@ -2676,6 +2798,16 @@ def expect_value(
26762798
*,
26772799
timeout: Timeout = None,
26782800
) -> None:
2801+
"""
2802+
Expects the value box value to have a specific text.
2803+
2804+
Parameters
2805+
----------
2806+
text
2807+
The expected text pattern or string.
2808+
timeout
2809+
The maximum time to wait for the expectation to pass. Defaults to None.
2810+
"""
26792811
playwright_expect(self.loc).to_have_text(
26802812
text,
26812813
timeout=timeout,
@@ -2687,15 +2819,38 @@ def expect_body(
26872819
*,
26882820
timeout: Timeout = None,
26892821
) -> None:
2690-
"""Note: If testing against multiple elements, text should be an array"""
2822+
"""
2823+
Expects the value box body to have specific text.
2824+
2825+
Parameters
2826+
----------
2827+
text
2828+
The expected text pattern or list of patterns/strings.
2829+
Note: If testing against multiple elements, text should be an array
2830+
timeout
2831+
The maximum time to wait for the expectation to pass. Defaults to None.
2832+
"""
26912833
playwright_expect(self.loc_body).to_have_text(
26922834
text,
26932835
timeout=timeout,
26942836
)
26952837

2696-
# hard to test since it can be customized by user
2697-
# def expect_showcase_layout(self, layout, *, timeout: Timeout = None) -> None:
2698-
# raise NotImplementedError()
2838+
def expect_full_screen_available(
2839+
self, available: bool, *, timeout: Timeout = None
2840+
) -> None:
2841+
"""
2842+
Expects the value box to be available for full screen mode.
2843+
2844+
Parameters
2845+
----------
2846+
available
2847+
True if the value box is expected to be available for full screen mode, False otherwise.
2848+
timeout
2849+
The maximum time to wait for the expectation to pass. Defaults to None.
2850+
"""
2851+
playwright_expect(self._loc_fullscreen).to_have_count(
2852+
int(available), timeout=timeout
2853+
)
26992854

27002855

27012856
class Card(_WidthLocM, _CardFooterM, _CardBodyM, _CardFullScreenM, _InputWithContainer):
Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,52 @@
1+
from shiny import App, ui
2+
3+
piggy_bank = ui.HTML(
4+
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16" class="bi bi-piggy-bank " style="height:auto;width:100%;fill:currentColor;" aria-hidden="true" role="img" ><path d="M5 6.25a.75.75 0 1 1-1.5 0 .75.75 0 0 1 1.5 0zm1.138-1.496A6.613 6.613 0 0 1 7.964 4.5c.666 0 1.303.097 1.893.273a.5.5 0 0 0 .286-.958A7.602 7.602 0 0 0 7.964 3.5c-.734 0-1.441.103-2.102.292a.5.5 0 1 0 .276.962z"></path>\n<path fill-rule="evenodd" d="M7.964 1.527c-2.977 0-5.571 1.704-6.32 4.125h-.55A1 1 0 0 0 .11 6.824l.254 1.46a1.5 1.5 0 0 0 1.478 1.243h.263c.3.513.688.978 1.145 1.382l-.729 2.477a.5.5 0 0 0 .48.641h2a.5.5 0 0 0 .471-.332l.482-1.351c.635.173 1.31.267 2.011.267.707 0 1.388-.095 2.028-.272l.543 1.372a.5.5 0 0 0 .465.316h2a.5.5 0 0 0 .478-.645l-.761-2.506C13.81 9.895 14.5 8.559 14.5 7.069c0-.145-.007-.29-.02-.431.261-.11.508-.266.705-.444.315.306.815.306.815-.417 0 .223-.5.223-.461-.026a.95.95 0 0 0 .09-.255.7.7 0 0 0-.202-.645.58.58 0 0 0-.707-.098.735.735 0 0 0-.375.562c-.024.243.082.48.32.654a2.112 2.112 0 0 1-.259.153c-.534-2.664-3.284-4.595-6.442-4.595zM2.516 6.26c.455-2.066 2.667-3.733 5.448-3.733 3.146 0 5.536 2.114 5.536 4.542 0 1.254-.624 2.41-1.67 3.248a.5.5 0 0 0-.165.535l.66 2.175h-.985l-.59-1.487a.5.5 0 0 0-.629-.288c-.661.23-1.39.359-2.157.359a6.558 6.558 0 0 1-2.157-.359.5.5 0 0 0-.635.304l-.525 1.471h-.979l.633-2.15a.5.5 0 0 0-.17-.534 4.649 4.649 0 0 1-1.284-1.541.5.5 0 0 0-.446-.275h-.56a.5.5 0 0 1-.492-.414l-.254-1.46h.933a.5.5 0 0 0 .488-.393zm12.621-.857a.565.565 0 0 1-.098.21.704.704 0 0 1-.044-.025c-.146-.09-.157-.175-.152-.223a.236.236 0 0 1 .117-.173c.049-.027.08-.021.113.012a.202.202 0 0 1 .064.199z"></path></svg>'
5+
)
6+
7+
app_ui = ui.page_fluid(
8+
ui.value_box(
9+
ui.span("Red Color theme w/ Fullscreen"),
10+
ui.h1("Showcase top right"),
11+
ui.span("Inside the fullscreen"),
12+
showcase=piggy_bank,
13+
showcase_layout=ui.showcase_top_right(),
14+
theme="red",
15+
full_screen=True,
16+
id="valuebox1",
17+
),
18+
ui.value_box(
19+
"Primary theme w/o Fullscreen",
20+
ui.h5(ui.HTML("Showcase left center")),
21+
showcase=piggy_bank,
22+
showcase_layout=ui.showcase_left_center(),
23+
theme="primary",
24+
full_screen=False,
25+
id="valuebox2",
26+
),
27+
ui.value_box(
28+
ui.span("No theme w/ Fullscreen"),
29+
ui.h3("Showcase bottom"),
30+
showcase=piggy_bank,
31+
showcase_layout=ui.showcase_bottom(),
32+
full_screen=True,
33+
id="valuebox3",
34+
),
35+
ui.value_box(
36+
"No showcase - w/o Fullscreen (default)",
37+
"No theme - only defaults",
38+
id="valuebox4",
39+
),
40+
ui.value_box(
41+
"No showcase w/ showcase layout",
42+
"Red text - fill is False",
43+
max_height="500px",
44+
showcase_layout=ui.showcase_left_center(),
45+
fill=False,
46+
theme="text-red",
47+
id="valuebox5",
48+
),
49+
)
50+
51+
52+
app = App(app_ui, server=None)

0 commit comments

Comments
 (0)