Skip to content

Commit

Permalink
Merge pull request #36 from digitronik/card_view
Browse files Browse the repository at this point in the history
Card views
  • Loading branch information
LightOfHeaven1994 authored Aug 28, 2023
2 parents 9dcbedc + d98a5a9 commit d9d8a57
Show file tree
Hide file tree
Showing 4 changed files with 140 additions and 21 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,9 @@ itteration of [widgetastic.patternfly4](https://github.com/RedHatQE/widgetastic.
- [line-chart](https://www.patternfly.org/charts/line-chart)
- [pie-chart](https://www.patternfly.org/charts/pie-chart)

### Patterns:
- [card-view](https://patternfly-react-main.surge.sh/patterns/card-view)


### Contribution guide

Expand Down
6 changes: 6 additions & 0 deletions src/widgetastic_patternfly5/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,9 @@
from .components.breadcrumb import BreadCrumb
from .components.button import Button
from .components.card import Card
from .components.card import CardCheckBox
from .components.card import CardForCardGroup
from .components.card import CardGroup
from .components.card import CardWithActions
from .components.chip import CategoryChipGroup
from .components.chip import Chip
Expand Down Expand Up @@ -71,6 +74,9 @@
"Button",
"CalendarMonth",
"Card",
"CardCheckBox",
"CardForCardGroup",
"CardGroup",
"CardWithActions",
"CategoryChipGroup",
"CheckboxMenu",
Expand Down
49 changes: 48 additions & 1 deletion src/widgetastic_patternfly5/components/card.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
from widgetastic.utils import ParametrizedLocator
from widgetastic.widget import Checkbox
from widgetastic.widget import GenericLocatorWidget
from widgetastic.widget import ParametrizedView
from widgetastic.widget import View

from widgetastic_patternfly5.components.menus.dropdown import Dropdown

Expand Down Expand Up @@ -32,13 +34,58 @@ def footer(self):


class Card(BaseCard, GenericLocatorWidget):
DEFAULT_LOCATOR = (
".//div[@data-ouia-component-type='PF5/Card'] | .//article[contains(@class, 'pf-c-card')]"
)

def __init__(self, parent, locator=None, logger=None):
locator = locator or ".//div[contains(@class, '-c-card')]"
locator = locator or self.DEFAULT_LOCATOR
super().__init__(parent, locator, logger=logger)

ROOT = ParametrizedLocator("{@locator}")


class CardForCardGroup(BaseCard, ParametrizedView):
DEFAULT_LOCATOR = (
"(.//div[@data-ouia-component-type='PF5/Card'] | .//article[contains(@class, 'pf-c-card')])"
)

def __init__(self, parent, locator=None, logger=None, **kwargs):
View.__init__(self, parent, logger=logger, **kwargs)
self.locator = locator or self.DEFAULT_LOCATOR

PARAMETERS = ("position",)

ROOT = ParametrizedLocator("{@locator}[{position}]")

def __locator__(self):
return self.ROOT

@classmethod
def all(cls, browser):
# todo: OUIA versions should return component ids
elements = browser.elements(cls.DEFAULT_LOCATOR)
result = []
for index, item in enumerate(elements):
result.append((index + 1,))
return result


class CardGroup(GenericLocatorWidget, View):
def __init__(self, parent, locator=None, logger=None, **kwargs):
View.__init__(self, parent, logger=logger, **kwargs)
self.locator = locator

cards = ParametrizedView.nested(CardForCardGroup)

def __iter__(self):
return iter(self.cards)


class CardWithActions(Card):
dropdown = Dropdown(locator=".//div[contains(@class, '-c-card__actions')]")
checkbox = Checkbox(locator=".//input[contains(@class, '-c-check__input')]")


class CardCheckBox(Checkbox):
ROOT = ".//input[contains(@class, '-c-check__input')]"
103 changes: 83 additions & 20 deletions testing/components/test_card.py
Original file line number Diff line number Diff line change
@@ -1,34 +1,97 @@
import pytest
from widgetastic.widget import View
from widgetastic.widget import ParametrizedView
from widgetastic.widget import Text

from widgetastic_patternfly5 import Card
from widgetastic_patternfly5 import CardCheckBox
from widgetastic_patternfly5 import CardForCardGroup
from widgetastic_patternfly5 import CardGroup
from widgetastic_patternfly5 import CardWithActions
from widgetastic_patternfly5 import Dropdown

TESTING_PAGE_URL = "https://patternfly-react-main.surge.sh/components/card"
TESTING_PAGE_URL = (
"https://patternfly-react-main.surge.sh/patterns/card-view/react-demos/card-view/"
)


@pytest.fixture
def view(browser):
class TestView(View):
card = Card(locator='.//div[@id="ws-react-c-card-basic-cards"]')
card_with_actions = CardWithActions(
locator='.//div[@id="ws-react-c-card-header-images-and-actions"]'
)
def pfy_card(browser):
return CardWithActions(browser, locator='.//div[@id="PatternFly"]')

return TestView(browser)

def test_cards_displayed(pfy_card):
assert pfy_card.wait_displayed()

def test_cards_displayed(view):
assert view.card.is_displayed
assert view.card_with_actions.is_displayed

def test_card_content(pfy_card):
assert pfy_card.title == "PatternFly"
assert pfy_card.body.text == (
"PatternFly is a community project that promotes design commonality and "
"improves user experience."
)

def test_card_content(view):
assert view.card.title == "Title"
assert view.card.body.text == "Body"
assert view.card.footer.text == "Footer"

def test_card_actionable_items_displayed(pfy_card):
assert pfy_card.dropdown.is_displayed
assert pfy_card.checkbox.is_displayed

def test_card_actionable_items_displayed(view):
assert view.card_with_actions.dropdown.is_displayed
assert view.card_with_actions.checkbox.is_displayed

class PageCard(CardForCardGroup):
dropdown = Dropdown(locator=".//div[contains(@class, '-c-card__actions')]")

def delete_action(self):
self.dropdown.item_select("Delete")

checked = CardCheckBox()

header_text = Text(locator=".//div[contains(@class, '-c-card__title')]")


class Cards(CardGroup):
def __init__(self, parent, locator=None, logger=None, **kwargs):
super().__init__(parent, logger=logger, **kwargs)
self.locator = locator or './/div[contains(@class, "pf-v5-l-gallery")]'

cards = ParametrizedView.nested(PageCard)


@pytest.fixture
def cards(browser):
cards = Cards(browser)
cards.wait_displayed("15s")
return cards


def test_read_and_drop_second_card(cards, browser):
second = [*cards][1]

assert second.header_text.read() == "PatternFly"

second.delete_action()

new_second = [*cards][1]

assert new_second.header_text.read() != "PatternFly"
# refresh to get it back :)
browser.refresh()


def read_cards_2_checkmap(cards):
data = cards.cards.read()
return {card["header_text"]: card["checked"] for card in list(data.values())[1:]}


def test_select_all_cards(browser, cards):
name2checked = read_cards_2_checkmap(cards)
assert not any(name2checked.values())
assert all(name2checked.keys())

# first card doesn't have header and checkbox
for card in list(cards)[1:]:
browser.execute_script("arguments[0].scrollIntoView({block: 'center'});", card.checked)
card.checked.fill(True)

name2checked_after = read_cards_2_checkmap(cards)
assert all(name2checked_after.values())
assert all(name2checked_after.keys())

assert name2checked.keys() == name2checked_after.keys()

0 comments on commit d9d8a57

Please sign in to comment.