Skip to content
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
22 changes: 12 additions & 10 deletions src/widgetastic_patternfly4/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,7 @@
from .piechart import PieChart
from .popover import Popover
from .progress import Progress
from .radio import Radio
from .select import CheckboxSelect
from .select import Select
from .select import SelectItemDisabled
Expand Down Expand Up @@ -69,29 +70,28 @@
"ChipGroup",
"ChipGroupToolbar",
"ChipGroupToolbarCategory",
"StandAloneChipGroup",
"Card",
"CardGroup",
"CardForCardGroup",
"CardCheckBox",
"CategoryChipGroup",
"ColumnNotExpandable",
"CompactPagination",
"CompoundExpandableTable",
"CategoryChipGroup",
"ContextSelector",
"DonutChart",
"Dropdown",
"DropdownDisabled",
"DropdownItemDisabled",
"DropdownItemNotFound",
"DualListSelector",
"SearchDualListSelector",
"GroupDropdown",
"InputSlider",
"SplitButtonDropdown",
"ExpandableTable",
"FormSelect",
"FormSelectDisabled",
"FormSelectOptionDisabled",
"FormSelectOptionNotFound",
"GroupDropdown",
"InputSlider",
"Menu",
"MenuItemDisabled",
"MenuItemNotFound",
Expand All @@ -101,19 +101,21 @@
"OptionsMenu",
"Pagination",
"PaginationNavDisabled",
"PatternflyTable",
"PieChart",
"Popover",
"Progress",
"Radio",
"RowNotExpandable",
"SearchDualListSelector",
"Select",
"SelectItemDisabled",
"SelectItemNotFound",
"ContextSelector",
"Slider",
"SplitButtonDropdown",
"StandAloneChipGroup",
"Switch",
"SwitchDisabled",
"ExpandableTable",
"PatternflyTable",
"RowNotExpandable",
"Tab",
"Title",
]
61 changes: 61 additions & 0 deletions src/widgetastic_patternfly4/radio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
from widgetastic.widget import Checkbox
from widgetastic.widget import ParametrizedLocator
from widgetastic.widget import Text
from widgetastic.widget import View

# https://patternfly-react.surge.sh/components/radio


class BaseRadio:
ROOT_ID_LOC = ParametrizedLocator(
".//div[contains(@class, 'pf-c-radio') and " ".//input[@type='radio' and @id={@id|quote}]]"
)
ROOT_LABEL_LOC = ParametrizedLocator(
".//div[contains(@class, 'pf-c-radio') and "
".//*[contains(@class, 'pf-c-radio__label') and normalize-space(.)={@label_text|quote}]]"
)
DESC_LOC = ".//*[contains(@class, 'pf-c-radio__description')]"
BODY_LOC = ".//*[contains(@class, 'pf-c-radio__body')]"
RADIO_LOC = ".//input[contains(@class, 'pf-c-radio__input')]"
LABEL_LOC = ".//*[contains(@class, 'pf-c-radio__label')]"

def __init__(self, parent, id=None, label_text=None, **kwargs):
"""Generate locator based on either id or label (but not both)"""
super().__init__(parent, **kwargs)
if id is not None and label_text is not None:
raise TypeError("Cannot create Radio with id and label set")
self.id = id
self.label_text = label_text
self.locator = self.ROOT_ID_LOC if id is not None else self.ROOT_LABEL_LOC

@property
def body(self):
"""Consider nesting a view when subclassing to override and add widgets"""
return self.browser.element(self.BODY_LOC)


class Radio(BaseRadio, View):
"""Base Radio view, subclass to add widgets to the body"""

ROOT = ParametrizedLocator("{@locator}")

description = Text(BaseRadio.DESC_LOC)
radio = Checkbox(locator=BaseRadio.RADIO_LOC)
label = Text(BaseRadio.LABEL_LOC)
body = Text(BaseRadio.BODY_LOC) # subclass + View.nested class to inject body with more widgets

@property
def selected(self):
return self.radio.selected

@property
def disabled(self):
return "pf-m-disabled" in self.browser.classes(self.label)

def fill(self, values):
"""Can only handle `True` to check the radio, nature of individual radio button"""
return self.radio.fill(values)


# TODO there is a 'name' attribute used by PF for correlating radio buttons
# This could be used to create a `RadioGroup` class of Radio widgets
53 changes: 53 additions & 0 deletions testing/test_radio.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
import pytest
from widgetastic.widget import View

from widgetastic_patternfly4 import Radio


TESTING_PAGE_URL = "https://patternfly-react.surge.sh/components/radio"


class RadioTestView(View):
controlled_id = Radio(id="radio-controlled")
uncontrolled_label = Radio(label_text="Uncontrolled radio example")
description_body = Radio(id="radio-description-body")
disabled_radio = Radio(id="radio-disabled")
disabled_checked = Radio(id="radio-disabled-checked")


@pytest.mark.parametrize(
"test_widget",
[
("controlled_id", dict(radio=False, label="Controlled radio")),
("uncontrolled_label", dict(radio=False, label="Uncontrolled radio example")),
(
"description_body",
dict(
radio=False,
label="Radio with description and body",
description="Single-tenant cloud service hosted and managed by Red Hat that offers "
"high-availability enterprise-grade clusters in a virtual private cloud on "
"AWS or GCP.",
body="This is where custom content goes.",
),
),
],
ids=["id_locator", "label_locator", "with_description"],
)
def test_location(browser, test_widget):
widget_name, expected_read = test_widget
view = RadioTestView(browser)
widget = getattr(view, widget_name)
assert widget.is_displayed
assert widget.read() == expected_read
assert widget.selected is False
assert widget.fill(True) is True
assert widget.selected is True


def test_disabled(browser):
view = RadioTestView(browser)
assert view.disabled_radio.disabled is True
assert view.disabled_radio.selected is False
assert view.disabled_checked.disabled is True
assert view.disabled_checked.selected is True