Skip to content

Add kitchensink tests for valuebox #1229

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 10 commits into from
Mar 22, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
193 changes: 174 additions & 19 deletions tests/playwright/controls.py
Original file line number Diff line number Diff line change
Expand Up @@ -2552,62 +2552,143 @@ def toggle(self, *, timeout: Timeout = None) -> None:


class _CardBodyP(_InputBaseP, Protocol):
"""
Represents the body of a card control.
"""

loc_body: Locator
"""
The locator for the body element of the card control.
"""


class _CardBodyM:
"""Represents a card body element with additional methods for testing."""

def expect_body(
self: _CardBodyP,
text: PatternOrStr | list[PatternOrStr],
*,
timeout: Timeout = None,
) -> None:
"""Note: If testing against multiple elements, text should be an array"""
"""Expect the card body element to have the specified text.

Parameters
----------
text
The expected text or a list of expected texts.
timeout
The maximum time to wait for the text to appear. Defaults to None.
"""
playwright_expect(self.loc).to_have_text(
text,
timeout=timeout,
)


class _CardFooterLayoutP(_InputBaseP, Protocol):
"""
Represents the layout of the footer in a card.
"""

loc_footer: Locator
"""
The locator for the footer element.
"""


class _CardFooterM:
"""
Represents the footer section of a card.
"""

def expect_footer(
self: _CardFooterLayoutP,
text: PatternOrStr,
*,
timeout: Timeout = None,
) -> None:
"""
Asserts that the footer section of the card has the expected text.

Parameters
----------
text
The expected text in the footer section.
timeout
The maximum time to wait for the footer text to appear. Defaults to None.
"""
playwright_expect(self.loc_footer).to_have_text(
text,
timeout=timeout,
)


class _CardFullScreenLayoutP(_OutputBaseP, Protocol):
"""
Represents a card full-screen layout for the Playwright controls.
"""

loc_title: Locator
"""
The locator for the title element.
"""
_loc_fullscreen: Locator
"""
The locator for the full-screen element.
"""
_loc_close_button: Locator
"""
The locator for the close button element.
"""


class _CardFullScreenM:
"""
Represents a class for managing full screen functionality of a card.
"""

def open_full_screen(
self: _CardFullScreenLayoutP, *, timeout: Timeout = None
) -> None:
"""
Opens the card in full screen mode.

Parameters
----------
timeout
The maximum time to wait for the card to open in full screen mode. Defaults to None.
"""
self.loc_title.hover(timeout=timeout)
self._loc_fullscreen.wait_for(state="visible", timeout=timeout)
self._loc_fullscreen.click(timeout=timeout)

def close_full_screen(
self: _CardFullScreenLayoutP, *, timeout: Timeout = None
) -> None:
"""
Closes the card from full screen mode.

Parameters
----------
timeout
The maximum time to wait for the card to close from full screen mode. Defaults to None.
"""
self._loc_close_button.click(timeout=timeout)

def expect_full_screen(
self: _CardFullScreenLayoutP, open: bool, *, timeout: Timeout = None
) -> None:
"""
Verifies if the card is expected to be in full screen mode.

Parameters
----------
open
True if the card is expected to be in full screen mode, False otherwise.
timeout
The maximum time to wait for the verification. Defaults to None.
"""
playwright_expect(self._loc_close_button).to_have_count(
int(open), timeout=timeout
)
Expand All @@ -2618,24 +2699,44 @@ class ValueBox(
_CardFullScreenM,
_InputWithContainer,
):
# title: TagChild,
# value: TagChild,
# *args: TagChild | TagAttrs,
# showcase: TagChild = None,
# showcase_layout: ((TagChild, Tag) -> CardItem) | None = None,
# full_screen: bool = False,
# theme_color: str | None = "primary",
# height: CssUnit | None = None,
# max_height: CssUnit | None = None,
# fill: bool = True,
# class_: str | None = None,
# **kwargs: TagAttrValue
"""
ValueBox control for shiny.ui.value_box - https://shiny.posit.co/py/api/core/ui.value_box.html
"""

loc: Locator
"""
Locator for the value box's value
"""
loc_showcase: Locator
"""
Locator for the value box showcase
"""
loc_title: Locator
"""
Locator for the value box title
"""
loc_body: Locator
"""
Locator for the value box body
"""

def __init__(self, page: Page, id: str) -> None:
"""
Initializes a new instance of the ValueBox class.

Parameters
----------
page
The Playwright page object.
id
The ID of the value box.

"""
super().__init__(
page,
id=id,
loc_container=f"div#{id}.bslib-value-box",
loc="> div > .value-box-grid",
loc="> div.card-body > .value-box-grid, > div.card-body",
)
value_box_grid = self.loc
self.loc_showcase = value_box_grid.locator("> .value-box-showcase")
Expand All @@ -2657,14 +2758,35 @@ def __init__(self, page: Page, id: str) -> None:
)

def expect_height(self, value: StyleValue, *, timeout: Timeout = None) -> None:
expect_to_have_style(self.loc_container, "height", value, timeout=timeout)
"""
Expects the value box to have a specific height.

Parameters
----------
value
The expected height value.
timeout
The maximum time to wait for the expectation to pass. Defaults to None.
"""
expect_to_have_style(self.loc_container, "max-height", value, timeout=timeout)

def expect_title(
self,
text: PatternOrStr,
*,
timeout: Timeout = None,
) -> None:
"""
Expects the value box title to have a specific text.

Parameters
----------
text
The expected text pattern or string.
timeout
The maximum time to wait for the expectation to pass. Defaults to None.

"""
playwright_expect(self.loc_title).to_have_text(
text,
timeout=timeout,
Expand All @@ -2676,6 +2798,16 @@ def expect_value(
*,
timeout: Timeout = None,
) -> None:
"""
Expects the value box value to have a specific text.

Parameters
----------
text
The expected text pattern or string.
timeout
The maximum time to wait for the expectation to pass. Defaults to None.
"""
playwright_expect(self.loc).to_have_text(
text,
timeout=timeout,
Expand All @@ -2687,15 +2819,38 @@ def expect_body(
*,
timeout: Timeout = None,
) -> None:
"""Note: If testing against multiple elements, text should be an array"""
"""
Expects the value box body to have specific text.

Parameters
----------
text
The expected text pattern or list of patterns/strings.
Note: If testing against multiple elements, text should be an array
timeout
The maximum time to wait for the expectation to pass. Defaults to None.
"""
playwright_expect(self.loc_body).to_have_text(
text,
timeout=timeout,
)

# hard to test since it can be customized by user
# def expect_showcase_layout(self, layout, *, timeout: Timeout = None) -> None:
# raise NotImplementedError()
def expect_full_screen_available(
self, available: bool, *, timeout: Timeout = None
) -> None:
"""
Expects the value box to be available for full screen mode.

Parameters
----------
available
True if the value box is expected to be available for full screen mode, False otherwise.
timeout
The maximum time to wait for the expectation to pass. Defaults to None.
"""
playwright_expect(self._loc_fullscreen).to_have_count(
int(available), timeout=timeout
)


class Card(_WidthLocM, _CardFooterM, _CardBodyM, _CardFullScreenM, _InputWithContainer):
Expand Down
52 changes: 52 additions & 0 deletions tests/playwright/shiny/components/value_box/kitchensink/app.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from shiny import App, ui

piggy_bank = ui.HTML(
'<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>'
)

app_ui = ui.page_fluid(
ui.value_box(
ui.span("Red Color theme w/ Fullscreen"),
ui.h1("Showcase top right"),
ui.span("Inside the fullscreen"),
showcase=piggy_bank,
showcase_layout=ui.showcase_top_right(),
theme="red",
full_screen=True,
id="valuebox1",
),
ui.value_box(
"Primary theme w/o Fullscreen",
ui.h5(ui.HTML("Showcase left center")),
showcase=piggy_bank,
showcase_layout=ui.showcase_left_center(),
theme="primary",
full_screen=False,
id="valuebox2",
),
ui.value_box(
ui.span("No theme w/ Fullscreen"),
ui.h3("Showcase bottom"),
showcase=piggy_bank,
showcase_layout=ui.showcase_bottom(),
full_screen=True,
id="valuebox3",
),
ui.value_box(
"No showcase - w/o Fullscreen (default)",
"No theme - only defaults",
id="valuebox4",
),
ui.value_box(
"No showcase w/ showcase layout",
"Red text - fill is False",
max_height="500px",
showcase_layout=ui.showcase_left_center(),
fill=False,
theme="text-red",
id="valuebox5",
),
)


app = App(app_ui, server=None)
Loading