widgetastic.patternfly5 25.2.10.0__py3-none-any.whl → 25.2.17.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {widgetastic.patternfly5-25.2.10.0.dist-info → widgetastic.patternfly5-25.2.17.1.dist-info}/METADATA +9 -12
- widgetastic.patternfly5-25.2.17.1.dist-info/RECORD +46 -0
- widgetastic_patternfly5/__init__.py +39 -50
- widgetastic_patternfly5/charts/alerts_timeline_chart.py +65 -0
- widgetastic_patternfly5/charts/bullet_chart.py +3 -5
- widgetastic_patternfly5/charts/donut_chart.py +2 -6
- widgetastic_patternfly5/charts/line_chart.py +13 -4
- widgetastic_patternfly5/components/alert.py +5 -6
- widgetastic_patternfly5/components/button.py +7 -8
- widgetastic_patternfly5/components/card.py +3 -10
- widgetastic_patternfly5/components/chip.py +11 -14
- widgetastic_patternfly5/components/clipboard_copy.py +1 -3
- widgetastic_patternfly5/components/drawer.py +7 -3
- widgetastic_patternfly5/components/dual_list_selector.py +1 -2
- widgetastic_patternfly5/components/forms/form_select.py +4 -8
- widgetastic_patternfly5/components/forms/radio.py +1 -4
- widgetastic_patternfly5/components/menus/context_selector.py +2 -2
- widgetastic_patternfly5/components/menus/dropdown.py +38 -13
- widgetastic_patternfly5/components/menus/menu.py +19 -18
- widgetastic_patternfly5/components/menus/options_menu.py +4 -3
- widgetastic_patternfly5/components/menus/select.py +14 -18
- widgetastic_patternfly5/components/modal.py +1 -1
- widgetastic_patternfly5/components/navigation.py +3 -3
- widgetastic_patternfly5/components/pagination.py +3 -8
- widgetastic_patternfly5/components/progress.py +2 -3
- widgetastic_patternfly5/components/switch.py +8 -7
- widgetastic_patternfly5/components/table.py +21 -16
- widgetastic_patternfly5/components/tabs.py +7 -4
- widgetastic_patternfly5/components/title.py +1 -2
- widgetastic_patternfly5/ouia.py +5 -10
- widgetastic.patternfly5-25.2.10.0.dist-info/RECORD +0 -45
- {widgetastic.patternfly5-25.2.10.0.dist-info → widgetastic.patternfly5-25.2.17.1.dist-info}/WHEEL +0 -0
- {widgetastic.patternfly5-25.2.10.0.dist-info → widgetastic.patternfly5-25.2.17.1.dist-info}/licenses/LICENSE +0 -0
{widgetastic.patternfly5-25.2.10.0.dist-info → widgetastic.patternfly5-25.2.17.1.dist-info}/METADATA
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: widgetastic.patternfly5
|
|
3
|
-
Version: 25.2.
|
|
3
|
+
Version: 25.2.17.1
|
|
4
4
|
Summary: Patternfly5 widget library for Widgetastic.
|
|
5
5
|
Project-URL: repository, https://github.com/RedHatQE/widgetastic.patternfly5
|
|
6
6
|
Maintainer-email: Nikhil Dhandre <ndhandre@redhat.com>, Egor Shamardin <eshamard@redhat.com>, Mike Shriver <mshriver@redhat.com>
|
|
@@ -21,13 +21,13 @@ License-File: LICENSE
|
|
|
21
21
|
Keywords: patternfly,patternfly5,widgetastic
|
|
22
22
|
Classifier: Programming Language :: Python
|
|
23
23
|
Classifier: Programming Language :: Python :: 3
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.
|
|
25
|
-
Classifier: Programming Language :: Python :: 3.
|
|
26
|
-
Classifier: Programming Language :: Python :: 3.
|
|
24
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
25
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
26
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
27
27
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
28
28
|
Classifier: Topic :: Software Development :: Quality Assurance
|
|
29
29
|
Classifier: Topic :: Software Development :: Testing
|
|
30
|
-
Requires-Python: >=3.
|
|
30
|
+
Requires-Python: >=3.11
|
|
31
31
|
Requires-Dist: widgetastic-core>=1.0.6
|
|
32
32
|
Provides-Extra: dev
|
|
33
33
|
Requires-Dist: codecov; extra == 'dev'
|
|
@@ -55,15 +55,12 @@ Description-Content-Type: text/markdown
|
|
|
55
55
|
<a href="https://github.com/RedHatQE/widgetastic.patternfly5/actions/workflows/tests.yaml">
|
|
56
56
|
<img alt="github actions" src="https://github.com/RedHatQE/widgetastic.patternfly5/actions/workflows/tests.yaml/badge.svg">
|
|
57
57
|
</a>
|
|
58
|
-
<a href="https://pypi.org/project/black">
|
|
59
|
-
<img alt="Code style: black" src="https://img.shields.io/badge/code%20style-black-000000.svg">
|
|
60
|
-
</a>
|
|
61
58
|
<a href="https://results.pre-commit.ci/latest/github/RedHatQE/widgetastic.patternfly5/main">
|
|
62
59
|
<img alt="pre: black" src="https://results.pre-commit.ci/badge/github/RedHatQE/widgetastic.patternfly5/main.svg">
|
|
63
60
|
</a>
|
|
64
61
|
</p>
|
|
65
62
|
|
|
66
|
-
This library offers Widgetastic Widgets for [PatternFly v5](https://www.patternfly.org/), serving as an extended
|
|
63
|
+
This library offers Widgetastic Widgets for [PatternFly v5/v6](https://www.patternfly.org/), serving as an extended
|
|
67
64
|
itteration of [widgetastic.patternfly4](https://github.com/RedHatQE/widgetastic.patternfly4).
|
|
68
65
|
|
|
69
66
|
|
|
@@ -111,7 +108,7 @@ itteration of [widgetastic.patternfly4](https://github.com/RedHatQE/widgetastic.
|
|
|
111
108
|
- [pie-chart](https://www.patternfly.org/charts/pie-chart)
|
|
112
109
|
|
|
113
110
|
### Patterns:
|
|
114
|
-
- [card-view](https://patternfly
|
|
111
|
+
- [card-view](https://www.patternfly.org/patterns/card-view)
|
|
115
112
|
|
|
116
113
|
|
|
117
114
|
### Contribution guide
|
|
@@ -135,7 +132,7 @@ pre-commit install
|
|
|
135
132
|
|
|
136
133
|
### Testing
|
|
137
134
|
|
|
138
|
-
The library has selenium tests that are performed against [Patternfly
|
|
135
|
+
The library has selenium tests that are performed against [Patternfly v6 docs](https://www.patternfly.org) and [Patternfly v5 docs](https://v5-archive.patternfly.org).
|
|
139
136
|
It's also configured to run the tests every time when a new version of that page is released.
|
|
140
137
|
|
|
141
138
|
Tests spawn a container from official selenium image - [selenium/standalone-{chrome/firefox}](https://hub.docker.com/u/selenium).
|
|
@@ -149,5 +146,5 @@ Use `-n` key to specify a number
|
|
|
149
146
|
of workers:
|
|
150
147
|
|
|
151
148
|
```bash
|
|
152
|
-
|
|
149
|
+
pytest --browser-name firefox --pf-version v5 -n 2 -vv
|
|
153
150
|
```
|
|
@@ -0,0 +1,46 @@
|
|
|
1
|
+
widgetastic_patternfly5/__init__.py,sha256=Yv3sZRQsi__Wjp5K5odVRZFr6-UQsPLL6lk6g6GWZIg,3822
|
|
2
|
+
widgetastic_patternfly5/ouia.py,sha256=ZAUgIka9odt4yCKQxD2R0fZ30hZKPtOAL-Fjw2xIGS0,4046
|
|
3
|
+
widgetastic_patternfly5/charts/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
4
|
+
widgetastic_patternfly5/charts/alerts_timeline_chart.py,sha256=U7hJvxAG1Wgj9WFt5QxAmLh9cJm2qzs2YHs2wfEW0Pk,2377
|
|
5
|
+
widgetastic_patternfly5/charts/boxplot_chart.py,sha256=6Ek6gwbmwNeazy-5o2fVfvkjpd6bhbTyitiPomvLBts,405
|
|
6
|
+
widgetastic_patternfly5/charts/bullet_chart.py,sha256=zfAdvxzPFqeGFzDoqJIUxwkERUlHfPohHOjzPJEjVdw,3680
|
|
7
|
+
widgetastic_patternfly5/charts/donut_chart.py,sha256=RmDKyWjhKnGWQwZ1twPN837LYuvlF1inQlYhIgJgFxU,2570
|
|
8
|
+
widgetastic_patternfly5/charts/legend.py,sha256=fhAg-FhsWpvi91BZ29EztKO3QfANRW-hnfzIkq45q3Y,2983
|
|
9
|
+
widgetastic_patternfly5/charts/line_chart.py,sha256=9gjoUqWopSYTng0iRpvppm-CL-QA8H_HpTvFddg0sB4,3995
|
|
10
|
+
widgetastic_patternfly5/charts/pie_chart.py,sha256=rIxMv6vPERj9FnTp8daejL7MxUTKFCTj9057C1KuuKw,218
|
|
11
|
+
widgetastic_patternfly5/components/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
12
|
+
widgetastic_patternfly5/components/alert.py,sha256=8wF4348n7Yp6BnOlbDNGw4_fFKyyjzgpQDOe9a96EsI,2579
|
|
13
|
+
widgetastic_patternfly5/components/breadcrumb.py,sha256=_lQ7pqmh2P9FSwMae_quUTteHsfXFlQvYaXE4Z1gK1g,2035
|
|
14
|
+
widgetastic_patternfly5/components/button.py,sha256=dduqxjnTHsHLkPO9TjbWO4HUfpiObMM4yuq3_q8XlA0,3539
|
|
15
|
+
widgetastic_patternfly5/components/card.py,sha256=YScmzLsxO72ITZFz9u3vyxpD2r0QAzP4yaBmJD9FcZE,2677
|
|
16
|
+
widgetastic_patternfly5/components/chip.py,sha256=t5_9oTJ__9ccwrCMzVYllDFY7oyJcMwwWKbr3jiIK0w,11218
|
|
17
|
+
widgetastic_patternfly5/components/clipboard_copy.py,sha256=r9RESokgZ7s5C2_ByOGLqfIjUx15-ZzFi5usSTdb-ac,1292
|
|
18
|
+
widgetastic_patternfly5/components/description_list.py,sha256=sVhKwKnvJguZh9FqyPC1NU2UA_w7uA3ugkY5eoVRlPk,989
|
|
19
|
+
widgetastic_patternfly5/components/drawer.py,sha256=kr2q042x4ghxu6T_C13mlRZZ-gZavGsVvM9a1GVYZZA,1084
|
|
20
|
+
widgetastic_patternfly5/components/dual_list_selector.py,sha256=jL1SOfnR5z_rWniN-KU9a26n-0HxBcL2pJbBcOFT2b8,4839
|
|
21
|
+
widgetastic_patternfly5/components/expandable_section.py,sha256=QCqonn1kiYfL-mGcjwrG6x4TiJBr9RKXZvyDerVTUmQ,1876
|
|
22
|
+
widgetastic_patternfly5/components/modal.py,sha256=uaOsMxWvgCKrF61YX5Dh9z4YCtB0uheQdQTF6cMswxY,2000
|
|
23
|
+
widgetastic_patternfly5/components/navigation.py,sha256=uaAc-FoOdYt0xiH_oPK564KjztQLEusk3LhhHSX4PQ4,5333
|
|
24
|
+
widgetastic_patternfly5/components/pagination.py,sha256=rumYxlMJcO7F0uQtIU24oANwi6JHHzDkD-YMo-eyltA,8707
|
|
25
|
+
widgetastic_patternfly5/components/popover.py,sha256=_XZlM4v8gsmen73DoSpylMXAMeEkdkjRsuBIIKHHhtE,2242
|
|
26
|
+
widgetastic_patternfly5/components/progress.py,sha256=UXNjRgy7aW0YerRWR6cwMF-9AjitI6LO8qlOdz0dYW8,1391
|
|
27
|
+
widgetastic_patternfly5/components/slider.py,sha256=B9gr8mnndLWivSlS9lIRd3SW6W5Iev9ESnQE9b0A55Y,3128
|
|
28
|
+
widgetastic_patternfly5/components/switch.py,sha256=7-ezYAQ3T_cz70GBIW78vTlVaDmRGRhNgi1hWg14Ig8,2226
|
|
29
|
+
widgetastic_patternfly5/components/table.py,sha256=fA5LM7buASXOH3z32t1D5ZkFXyMa3ZZmzFJ6kjF73ZQ,17183
|
|
30
|
+
widgetastic_patternfly5/components/tabs.py,sha256=tSuS6x3_rnc5z8yUW_75ZtkdFOzzWPMmMa48VEEZWQk,2260
|
|
31
|
+
widgetastic_patternfly5/components/title.py,sha256=bIUzFaptG2i84CF4-AMfjbmdVeKYR32wkOBH9P6V3XQ,920
|
|
32
|
+
widgetastic_patternfly5/components/date_and_time/calendar_month.py,sha256=zGIgIsYEWH3VPVNBVIPVaKlnRY61648tM8rGtohmy7s,3307
|
|
33
|
+
widgetastic_patternfly5/components/forms/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
34
|
+
widgetastic_patternfly5/components/forms/form_select.py,sha256=ht_go5lOXhMzq_FyLxS1ny9jaiBkRI6K_5vMv1DASaw,3531
|
|
35
|
+
widgetastic_patternfly5/components/forms/radio.py,sha256=d1fpzoicgSDgoV8K9bHlXFvHEjH3zw59t_WbxTGZyQ8,2009
|
|
36
|
+
widgetastic_patternfly5/components/menus/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
37
|
+
widgetastic_patternfly5/components/menus/context_selector.py,sha256=Bqj8MrxJypLfjcqrrKQj9jfFWHeSWbHIVcH2aA6sRQ8,1156
|
|
38
|
+
widgetastic_patternfly5/components/menus/dropdown.py,sha256=NUPpKIV-mBzmFVRPjWu0FiCWc9DjcRErK_FOxfag8y0,10471
|
|
39
|
+
widgetastic_patternfly5/components/menus/menu.py,sha256=sRkb46XWMNGueDCkOjs4vyb9Ehjiru71DY3MD2qsorM,8138
|
|
40
|
+
widgetastic_patternfly5/components/menus/menu_toggle.py,sha256=PBwNvg6E2RPdCG6ALBUqyTZxCwThJgk5S-9ghTiZ9hM,1029
|
|
41
|
+
widgetastic_patternfly5/components/menus/options_menu.py,sha256=-7pRukhgxln0rMV77VhNyQ-njLPAE6Wnp2vNAoJUXZk,1474
|
|
42
|
+
widgetastic_patternfly5/components/menus/select.py,sha256=X8DApXg_7tLIOulpmEP-f09bDShYL8jcEb1tYvNHwrE,6482
|
|
43
|
+
widgetastic.patternfly5-25.2.17.1.dist-info/METADATA,sha256=u3xxVUmW53slGMz9XD6BL7XP-TIGG1sH5Khopll1Vw8,6826
|
|
44
|
+
widgetastic.patternfly5-25.2.17.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
45
|
+
widgetastic.patternfly5-25.2.17.1.dist-info/licenses/LICENSE,sha256=nDhhj8jp0XsTdmvWpTWFpOKVn0LPXPb6ecA9zFF3Exk,576
|
|
46
|
+
widgetastic.patternfly5-25.2.17.1.dist-info/RECORD,,
|
|
@@ -1,75 +1,64 @@
|
|
|
1
1
|
from .charts.boxplot_chart import BoxPlotChart
|
|
2
2
|
from .charts.bullet_chart import BulletChart
|
|
3
3
|
from .charts.donut_chart import DonutChart
|
|
4
|
-
from .charts.legend import DataPoint
|
|
5
|
-
from .charts.legend import Legend
|
|
4
|
+
from .charts.legend import DataPoint, Legend
|
|
6
5
|
from .charts.line_chart import LineChart
|
|
7
6
|
from .charts.pie_chart import PieChart
|
|
8
7
|
from .components.alert import Alert
|
|
9
8
|
from .components.breadcrumb import BreadCrumb
|
|
10
9
|
from .components.button import Button
|
|
11
|
-
from .components.card import Card
|
|
12
|
-
from .components.
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
from .components.chip import ChipReadOnlyError
|
|
22
|
-
from .components.chip import StandAloneChipGroup
|
|
10
|
+
from .components.card import Card, CardCheckBox, CardForCardGroup, CardGroup, CardWithActions
|
|
11
|
+
from .components.chip import (
|
|
12
|
+
CategoryChipGroup,
|
|
13
|
+
Chip,
|
|
14
|
+
ChipGroup,
|
|
15
|
+
ChipGroupToolbar,
|
|
16
|
+
ChipGroupToolbarCategory,
|
|
17
|
+
ChipReadOnlyError,
|
|
18
|
+
StandAloneChipGroup,
|
|
19
|
+
)
|
|
23
20
|
from .components.clipboard_copy import ClipboardCopy
|
|
24
21
|
from .components.date_and_time.calendar_month import CalendarMonth
|
|
25
22
|
from .components.description_list import DescriptionList
|
|
26
23
|
from .components.drawer import Drawer
|
|
27
|
-
from .components.dual_list_selector import DualListSelector
|
|
28
|
-
from .components.dual_list_selector import SearchDualListSelector
|
|
24
|
+
from .components.dual_list_selector import DualListSelector, SearchDualListSelector
|
|
29
25
|
from .components.expandable_section import ExpandableSection
|
|
30
|
-
from .components.forms.form_select import
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
26
|
+
from .components.forms.form_select import (
|
|
27
|
+
FormSelect,
|
|
28
|
+
FormSelectDisabled,
|
|
29
|
+
FormSelectOptionDisabled,
|
|
30
|
+
FormSelectOptionNotFound,
|
|
31
|
+
)
|
|
34
32
|
from .components.forms.radio import Radio
|
|
35
33
|
from .components.menus.context_selector import ContextSelector
|
|
36
|
-
from .components.menus.dropdown import
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
from .components.menus.menu import MenuItemDisabled
|
|
44
|
-
from .components.menus.menu import MenuItemNotFound
|
|
34
|
+
from .components.menus.dropdown import (
|
|
35
|
+
Dropdown,
|
|
36
|
+
DropdownDisabled,
|
|
37
|
+
DropdownItemDisabled,
|
|
38
|
+
DropdownItemNotFound,
|
|
39
|
+
GroupDropdown,
|
|
40
|
+
)
|
|
41
|
+
from .components.menus.menu import CheckboxMenu, Menu, MenuItemDisabled, MenuItemNotFound
|
|
45
42
|
from .components.menus.menu_toggle import SplitButtonDropdown
|
|
46
43
|
from .components.menus.options_menu import OptionsMenu
|
|
47
|
-
from .components.menus.select import CheckboxSelect
|
|
48
|
-
from .components.
|
|
49
|
-
from .components.
|
|
50
|
-
from .components.
|
|
51
|
-
from .components.modal import Modal
|
|
52
|
-
from .components.modal import ModalItemNotFound
|
|
53
|
-
from .components.navigation import Navigation
|
|
54
|
-
from .components.navigation import NavSelectionNotFound
|
|
55
|
-
from .components.pagination import CompactPagination
|
|
56
|
-
from .components.pagination import Pagination
|
|
57
|
-
from .components.pagination import PaginationNavDisabled
|
|
44
|
+
from .components.menus.select import CheckboxSelect, Select, SelectItemDisabled, SelectItemNotFound
|
|
45
|
+
from .components.modal import Modal, ModalItemNotFound
|
|
46
|
+
from .components.navigation import Navigation, NavSelectionNotFound
|
|
47
|
+
from .components.pagination import CompactPagination, Pagination, PaginationNavDisabled
|
|
58
48
|
from .components.popover import Popover
|
|
59
49
|
from .components.progress import Progress
|
|
60
|
-
from .components.slider import InputSlider
|
|
61
|
-
from .components.
|
|
62
|
-
from .components.
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
50
|
+
from .components.slider import InputSlider, Slider
|
|
51
|
+
from .components.switch import Switch, SwitchDisabled
|
|
52
|
+
from .components.table import (
|
|
53
|
+
ColumnNotExpandable,
|
|
54
|
+
CompoundExpandableTable,
|
|
55
|
+
ExpandableTable,
|
|
56
|
+
PatternflyTable,
|
|
57
|
+
RowNotExpandable,
|
|
58
|
+
)
|
|
69
59
|
from .components.tabs import Tab
|
|
70
60
|
from .components.title import Title
|
|
71
61
|
|
|
72
|
-
|
|
73
62
|
__all__ = [
|
|
74
63
|
"Alert",
|
|
75
64
|
"BreadCrumb",
|
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
from widgetastic_patternfly5.charts.line_chart import LineChart
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
class AlertsTimelineChart(LineChart):
|
|
5
|
+
"""Represents the Patternfly Alerts Timeline.
|
|
6
|
+
|
|
7
|
+
https://v5-archive.patternfly.org/charts/bar-chart/#alerts-timeline
|
|
8
|
+
|
|
9
|
+
Args:
|
|
10
|
+
id: If you want to look the input up by id, use this parameter, pass the id.
|
|
11
|
+
locator: If you have specific locator else it will take pf-chart.
|
|
12
|
+
"""
|
|
13
|
+
|
|
14
|
+
Y_AXIS_ROW = "./*[name()='svg']/*[name()='g'][3]/*[name()='g']"
|
|
15
|
+
Y_AXIS_ROW_LINE = "./*[name()='path']"
|
|
16
|
+
|
|
17
|
+
TOOLTIP = "./*[name()='svg']/*[name()='g'][5]"
|
|
18
|
+
TOOLTIP_X_AXIS_LABLE = None
|
|
19
|
+
TOOLTIP_LABLES = None
|
|
20
|
+
TOOLTIP_VALUES = ".//*[name()='text']/*[name()='tspan']"
|
|
21
|
+
|
|
22
|
+
@property
|
|
23
|
+
def _y_axis_labels_map(self):
|
|
24
|
+
"""Labels and its webelements in the Y axis
|
|
25
|
+
NOTE: Y labels might not match the number of rows in Y axes.
|
|
26
|
+
"""
|
|
27
|
+
return {self.browser.text(el): el for el in self.browser.elements(self.Y_AXIS_LABELS)}
|
|
28
|
+
|
|
29
|
+
@property
|
|
30
|
+
def labels_y_axis(self):
|
|
31
|
+
"""Return Y-Axis labels."""
|
|
32
|
+
return list(self._y_axis_labels_map.keys())
|
|
33
|
+
|
|
34
|
+
@property
|
|
35
|
+
def _y_axis_map(self):
|
|
36
|
+
"""Dict with Y axis row number as key and the contained lines in each row as values."""
|
|
37
|
+
y_axis_rows_els = self.browser.elements(self.Y_AXIS_ROW)
|
|
38
|
+
y_axis_map = {}
|
|
39
|
+
for row_n, row_el in enumerate(y_axis_rows_els):
|
|
40
|
+
y_axis_map[row_n] = self.browser.elements(self.Y_AXIS_ROW_LINE, parent=row_el)
|
|
41
|
+
return y_axis_map
|
|
42
|
+
|
|
43
|
+
def read(self):
|
|
44
|
+
"""Read chart data."""
|
|
45
|
+
_data = []
|
|
46
|
+
|
|
47
|
+
for lines_el in self._y_axis_map.values():
|
|
48
|
+
_row_data = []
|
|
49
|
+
for line_el in lines_el:
|
|
50
|
+
self.browser.move_to_element(line_el)
|
|
51
|
+
self.browser.click(line_el)
|
|
52
|
+
tooltip_el = self.browser.wait_for_element(self.TOOLTIP)
|
|
53
|
+
|
|
54
|
+
label_data = {}
|
|
55
|
+
value_els = self.browser.elements(self.TOOLTIP_VALUES, parent=tooltip_el)
|
|
56
|
+
for value_el in value_els:
|
|
57
|
+
key, value = self.browser.text(value_el).lower().split(": ")
|
|
58
|
+
label_data[key] = value
|
|
59
|
+
|
|
60
|
+
_row_data.append(label_data)
|
|
61
|
+
_data.append(_row_data)
|
|
62
|
+
|
|
63
|
+
# Just move cursor to avoid mismatch of legend and tooltip text.
|
|
64
|
+
self.root_browser.move_to_element(".//body")
|
|
65
|
+
return _data
|
|
@@ -1,12 +1,10 @@
|
|
|
1
1
|
import re
|
|
2
2
|
|
|
3
3
|
from widgetastic.utils import ParametrizedLocator
|
|
4
|
-
from widgetastic.widget import Text
|
|
5
|
-
from widgetastic.widget import View
|
|
4
|
+
from widgetastic.widget import Text, View
|
|
6
5
|
from widgetastic.xpath import quote
|
|
7
6
|
|
|
8
|
-
from .legend import DataPoint
|
|
9
|
-
from .legend import Legend
|
|
7
|
+
from .legend import DataPoint, Legend
|
|
10
8
|
|
|
11
9
|
|
|
12
10
|
class BulletChart(View):
|
|
@@ -36,7 +34,7 @@ class BulletChart(View):
|
|
|
36
34
|
def __init__(self, parent=None, id=None, locator=None, logger=None, *args, **kwargs):
|
|
37
35
|
View.__init__(self, parent=parent, logger=logger)
|
|
38
36
|
if id:
|
|
39
|
-
self.locator = ".//div[@id={
|
|
37
|
+
self.locator = f".//div[@id={quote(id)}]"
|
|
40
38
|
elif locator:
|
|
41
39
|
self.locator = locator
|
|
42
40
|
else:
|
|
@@ -1,17 +1,13 @@
|
|
|
1
1
|
import re
|
|
2
2
|
|
|
3
|
-
from widgetastic.widget import ClickableMixin
|
|
4
|
-
from widgetastic.widget import ParametrizedLocator
|
|
5
|
-
from widgetastic.widget import ParametrizedView
|
|
6
|
-
from widgetastic.widget import View
|
|
7
|
-
from widgetastic.widget import Widget
|
|
3
|
+
from widgetastic.widget import ClickableMixin, ParametrizedLocator, ParametrizedView, View, Widget
|
|
8
4
|
from widgetastic.xpath import quote
|
|
9
5
|
|
|
10
6
|
|
|
11
7
|
class DonutLegendItem(ParametrizedView, ClickableMixin):
|
|
12
8
|
PARAMETERS = ("label_text",)
|
|
13
9
|
ROOT = ParametrizedLocator(
|
|
14
|
-
".//*[name()='text']
|
|
10
|
+
".//*[name()='text']/*[name()='tspan' and contains(., '{label_text}')]"
|
|
15
11
|
)
|
|
16
12
|
ALL_ITEMS = ".//*[name()='text']/*[name()='tspan']"
|
|
17
13
|
LEGEND_ITEM_REGEX = re.compile(r"(.*?): ([\d]+)")
|
|
@@ -1,5 +1,4 @@
|
|
|
1
|
-
from widgetastic.widget import ParametrizedLocator
|
|
2
|
-
from widgetastic.widget import View
|
|
1
|
+
from widgetastic.widget import ParametrizedLocator, View
|
|
3
2
|
from widgetastic.xpath import quote
|
|
4
3
|
|
|
5
4
|
from .legend import Legend
|
|
@@ -37,7 +36,7 @@ class LineChart(View):
|
|
|
37
36
|
assert id or locator, "Provide id or locator."
|
|
38
37
|
|
|
39
38
|
if id:
|
|
40
|
-
self.locator = ".//div[@id={
|
|
39
|
+
self.locator = f".//div[@id={quote(id)}]"
|
|
41
40
|
else:
|
|
42
41
|
self.locator = locator
|
|
43
42
|
|
|
@@ -96,7 +95,17 @@ class LineChart(View):
|
|
|
96
95
|
self.browser.elements(self.TOOLTIP_LABLES, parent=tooltip_el),
|
|
97
96
|
self.browser.elements(self.TOOLTIP_VALUES, parent=tooltip_el),
|
|
98
97
|
):
|
|
99
|
-
|
|
98
|
+
# Get the label text and handle empty labels
|
|
99
|
+
label_txt = self.browser.text(label_el)
|
|
100
|
+
if label_txt == "":
|
|
101
|
+
label_txt = "Unknown"
|
|
102
|
+
|
|
103
|
+
# Update label_data with the value
|
|
104
|
+
value_txt = self.browser.text(value_el)
|
|
105
|
+
if label_txt in label_data:
|
|
106
|
+
label_data[label_txt] = f"{label_data[label_txt]}, {value_txt}"
|
|
107
|
+
else:
|
|
108
|
+
label_data[label_txt] = value_txt
|
|
100
109
|
|
|
101
110
|
_data[x_axis_label] = label_data
|
|
102
111
|
|
|
@@ -57,12 +57,11 @@ class BaseAlert:
|
|
|
57
57
|
for class_ in self.browser.classes(self):
|
|
58
58
|
if class_ in self.TYPE_MAPPING:
|
|
59
59
|
return self.TYPE_MAPPING[class_]
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
)
|
|
60
|
+
raise ValueError(
|
|
61
|
+
"Could not find a proper alert type."
|
|
62
|
+
f"\nAvailable classes: {self.TYPE_MAPPING!r} "
|
|
63
|
+
f"\nAlert has: {self.browser.classes(self)!r}"
|
|
64
|
+
)
|
|
66
65
|
|
|
67
66
|
def assert_no_error(self):
|
|
68
67
|
"""Asserts that the warning is not of the error type."""
|
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
from widgetastic.utils import ParametrizedLocator
|
|
2
|
-
from widgetastic.widget import ClickableMixin
|
|
3
|
-
from widgetastic.widget import Widget
|
|
2
|
+
from widgetastic.widget import ClickableMixin, Widget
|
|
4
3
|
from widgetastic.xpath import quote
|
|
5
4
|
|
|
6
5
|
|
|
@@ -36,7 +35,7 @@ class BaseButton:
|
|
|
36
35
|
return check1 or check2 or self.browser.get_attribute("disabled", self) is not None
|
|
37
36
|
|
|
38
37
|
def __repr__(self):
|
|
39
|
-
return "{
|
|
38
|
+
return f"{type(self).__name__}{self.locator}"
|
|
40
39
|
|
|
41
40
|
@property
|
|
42
41
|
def title(self):
|
|
@@ -69,25 +68,25 @@ class Button(BaseButton, Widget, ClickableMixin):
|
|
|
69
68
|
if kwargs: # classes should have been the only kwarg combined with text args
|
|
70
69
|
raise TypeError("If you pass button text then only pass classes in addition")
|
|
71
70
|
if len(text) == 1:
|
|
72
|
-
locator_conditions = "normalize-space(.)={
|
|
71
|
+
locator_conditions = f"normalize-space(.)={quote(text[0])}"
|
|
73
72
|
elif len(text) == 2 and text[0].lower() == "contains":
|
|
74
|
-
locator_conditions = "contains(normalize-space(.), {
|
|
73
|
+
locator_conditions = f"contains(normalize-space(.), {quote(text[1])})"
|
|
75
74
|
else:
|
|
76
75
|
raise TypeError("An illegal combination of args/kwargs")
|
|
77
76
|
else:
|
|
78
77
|
# Join the kwargs, if any
|
|
79
78
|
locator_conditions = " and ".join(
|
|
80
|
-
"@{}={
|
|
79
|
+
f"@{attr}={quote(value)}" for attr, value in kwargs.items()
|
|
81
80
|
)
|
|
82
81
|
|
|
83
82
|
if classes:
|
|
84
83
|
if locator_conditions:
|
|
85
84
|
locator_conditions += " and "
|
|
86
85
|
locator_conditions += " and ".join(
|
|
87
|
-
"contains(@class, {
|
|
86
|
+
f"contains(@class, {quote(klass)})" for klass in classes
|
|
88
87
|
)
|
|
89
88
|
if locator_conditions:
|
|
90
|
-
locator_conditions = "and ({})"
|
|
89
|
+
locator_conditions = f"and ({locator_conditions})"
|
|
91
90
|
|
|
92
91
|
return (
|
|
93
92
|
".//*[(self::a or self::button or (self::input and "
|
|
@@ -1,8 +1,5 @@
|
|
|
1
1
|
from widgetastic.utils import ParametrizedLocator
|
|
2
|
-
from widgetastic.widget import Checkbox
|
|
3
|
-
from widgetastic.widget import GenericLocatorWidget
|
|
4
|
-
from widgetastic.widget import ParametrizedView
|
|
5
|
-
from widgetastic.widget import View
|
|
2
|
+
from widgetastic.widget import Checkbox, GenericLocatorWidget, ParametrizedView, View
|
|
6
3
|
|
|
7
4
|
from widgetastic_patternfly5.components.menus.dropdown import Dropdown
|
|
8
5
|
|
|
@@ -34,9 +31,7 @@ class BaseCard:
|
|
|
34
31
|
|
|
35
32
|
|
|
36
33
|
class Card(BaseCard, GenericLocatorWidget):
|
|
37
|
-
DEFAULT_LOCATOR = (
|
|
38
|
-
".//div[@data-ouia-component-type='PF5/Card'] | .//article[contains(@class, '-c-card')]"
|
|
39
|
-
)
|
|
34
|
+
DEFAULT_LOCATOR = ".//div[contains(@data-ouia-component-type, '/Card')] | .//article[contains(@class, '-c-card')]"
|
|
40
35
|
|
|
41
36
|
def __init__(self, parent, locator=None, logger=None):
|
|
42
37
|
locator = locator or self.DEFAULT_LOCATOR
|
|
@@ -46,9 +41,7 @@ class Card(BaseCard, GenericLocatorWidget):
|
|
|
46
41
|
|
|
47
42
|
|
|
48
43
|
class CardForCardGroup(BaseCard, ParametrizedView):
|
|
49
|
-
DEFAULT_LOCATOR = (
|
|
50
|
-
"(.//div[@data-ouia-component-type='PF5/Card'] | .//article[contains(@class, '-c-card')])"
|
|
51
|
-
)
|
|
44
|
+
DEFAULT_LOCATOR = "(.//div[contains(@data-ouia-component-type, '/Card')] | .//article[contains(@class, '-c-card')])"
|
|
52
45
|
|
|
53
46
|
def __init__(self, parent, locator=None, logger=None, **kwargs):
|
|
54
47
|
View.__init__(self, parent, logger=logger, **kwargs)
|
|
@@ -1,9 +1,6 @@
|
|
|
1
1
|
# TODO: This imported directly form wt.pfy4. I thnk we need to restructure it.
|
|
2
2
|
from wait_for import wait_for
|
|
3
|
-
from widgetastic.widget import ParametrizedLocator
|
|
4
|
-
from widgetastic.widget import ParametrizedView
|
|
5
|
-
from widgetastic.widget import Text
|
|
6
|
-
from widgetastic.widget import View
|
|
3
|
+
from widgetastic.widget import ParametrizedLocator, ParametrizedView, Text, View
|
|
7
4
|
|
|
8
5
|
from .button import Button
|
|
9
6
|
|
|
@@ -15,18 +12,18 @@ class ChipReadOnlyError(Exception):
|
|
|
15
12
|
|
|
16
13
|
|
|
17
14
|
CHIP_ROOT = (
|
|
18
|
-
"
|
|
19
|
-
"and not(contains(@class, '-c-chip-group'))]"
|
|
15
|
+
".//*[contains(@data-ouia-component-type, '/Chip') and not(contains(@class, '-m-overflow')) "
|
|
16
|
+
"and not(contains(@class, '-c-chip-group') or contains(@class, '-c-label-group'))]"
|
|
20
17
|
)
|
|
21
|
-
CHIP_TEXT = ".//span[contains(@class, '-c-chip__text')]"
|
|
18
|
+
CHIP_TEXT = ".//span[contains(@class, '-c-chip__text') or contains(@class, '-c-label__text')]"
|
|
22
19
|
CHIP_BADGE = ".//span[contains(@class, '-c-badge')]"
|
|
23
|
-
GROUP_ROOT = ".//div[contains(@class, '-c-chip-group') and @role='group']"
|
|
20
|
+
GROUP_ROOT = ".//div[(contains(@class, '-c-chip-group') and @role='group') or contains(@class, '-c-label-group')]"
|
|
24
21
|
CATEGORY_GROUP_ROOT = (
|
|
25
|
-
".//div[contains(@class, '-c-chip-group') and @role='group' "
|
|
22
|
+
".//div[((contains(@class, '-c-chip-group') and @role='group') or contains(@class, '-c-label-group')) "
|
|
26
23
|
"and contains(@class, 'pf-m-category')]"
|
|
27
24
|
)
|
|
28
|
-
CATEGORY_LABEL = ".//span[contains(@class, '-
|
|
29
|
-
CATEGORY_CLOSE = ".//div[contains(@class, '-
|
|
25
|
+
CATEGORY_LABEL = ".//span[contains(@class, '-group__label')]"
|
|
26
|
+
CATEGORY_CLOSE = ".//div[contains(@class, '-group__close')]/button"
|
|
30
27
|
# For backwards compatibility
|
|
31
28
|
OLD_GROUP_ROOT = ".//ul[contains(@class, '-c-chip-group')]"
|
|
32
29
|
TOOLBAR_GROUP_LABEL = "./li/*[contains(@class, '-c-chip-group__label')]"
|
|
@@ -44,7 +41,7 @@ class _BaseChip(View):
|
|
|
44
41
|
|
|
45
42
|
_text = Text(CHIP_TEXT)
|
|
46
43
|
_badge = Text(f"{CHIP_TEXT}/{CHIP_BADGE}")
|
|
47
|
-
button = Button(
|
|
44
|
+
button = Button()
|
|
48
45
|
|
|
49
46
|
@property
|
|
50
47
|
def badge(self):
|
|
@@ -122,7 +119,7 @@ class OverflowChip(_BaseChip):
|
|
|
122
119
|
The 'Show More'/'Show Less' button is essentially a special kind of chip
|
|
123
120
|
"""
|
|
124
121
|
|
|
125
|
-
ROOT = ".//button[contains(@class, '-c-chip') and contains(@class, 'pf-m-overflow')]"
|
|
122
|
+
ROOT = ".//button[(contains(@class, '-c-chip') or contains(@class, '-c-label')) and contains(@class, 'pf-m-overflow')]"
|
|
126
123
|
|
|
127
124
|
def _show_less_shown(self):
|
|
128
125
|
return self.text.replace(" ", "").lower() == "showless"
|
|
@@ -327,7 +324,7 @@ class ChipGroupToolbar(View):
|
|
|
327
324
|
# The parent of the chip group toolbar can be any element type
|
|
328
325
|
# The locator should be the parent node which holds all the pf-c-chip-group elements
|
|
329
326
|
TOOLBAR_LOCATOR = (
|
|
330
|
-
".//ul[contains(@class, '-c-chip-group') and
|
|
327
|
+
".//ul[contains(@class, '-c-chip-group') and contains(@class, 'pf-m-toolbar')]/parent::*"
|
|
331
328
|
)
|
|
332
329
|
|
|
333
330
|
overflow = OldOverflowChip(
|
|
@@ -1,7 +1,5 @@
|
|
|
1
1
|
from widgetastic.utils import ParametrizedLocator
|
|
2
|
-
from widgetastic.widget import GenericLocatorWidget
|
|
3
|
-
from widgetastic.widget import Text
|
|
4
|
-
from widgetastic.widget import TextInput
|
|
2
|
+
from widgetastic.widget import GenericLocatorWidget, Text, TextInput
|
|
5
3
|
|
|
6
4
|
from widgetastic_patternfly5 import Button
|
|
7
5
|
|
|
@@ -1,14 +1,17 @@
|
|
|
1
|
+
from wait_for import wait_for
|
|
1
2
|
from widgetastic.utils import ParametrizedLocator
|
|
2
3
|
from widgetastic.widget import View
|
|
3
4
|
|
|
5
|
+
from widgetastic_patternfly5 import Button
|
|
6
|
+
|
|
4
7
|
|
|
5
8
|
class BaseDrawer:
|
|
6
|
-
"""Represents drawer component for pf5
|
|
9
|
+
"""Represents drawer component for pf5/pf6
|
|
7
10
|
|
|
8
11
|
https://www.patternfly.org/components/drawer
|
|
9
12
|
"""
|
|
10
13
|
|
|
11
|
-
|
|
14
|
+
close_btn = Button(locator=".//div[contains(@class, '-c-drawer__close')]/button")
|
|
12
15
|
|
|
13
16
|
@property
|
|
14
17
|
def is_open(self):
|
|
@@ -18,7 +21,8 @@ class BaseDrawer:
|
|
|
18
21
|
def close(self):
|
|
19
22
|
"""Close drawer."""
|
|
20
23
|
if self.is_open:
|
|
21
|
-
self.
|
|
24
|
+
self.close_btn.click()
|
|
25
|
+
wait_for(lambda: not self.is_open, num_sec=10)
|
|
22
26
|
|
|
23
27
|
|
|
24
28
|
class Drawer(BaseDrawer, View):
|
|
@@ -81,18 +81,14 @@ class BaseFormSelect:
|
|
|
81
81
|
FormSelectOptionNotFound: if option not found
|
|
82
82
|
"""
|
|
83
83
|
if not self.is_enabled:
|
|
84
|
-
raise FormSelectDisabled("{} is not enabled"
|
|
84
|
+
raise FormSelectDisabled(f"{repr(self)} is not enabled")
|
|
85
85
|
if value not in self.all_options:
|
|
86
86
|
raise FormSelectOptionNotFound(
|
|
87
|
-
'Option "{}" not found in {}. Available options: {}'
|
|
88
|
-
value, repr(self), self.all_options
|
|
89
|
-
)
|
|
87
|
+
f'Option "{value}" not found in {repr(self)}. Available options: {self.all_options}'
|
|
90
88
|
)
|
|
91
89
|
elif value not in self.all_enabled_options:
|
|
92
90
|
raise FormSelectOptionDisabled(
|
|
93
|
-
'Option "{}" is disabled in {}. Enabled options are: {}'
|
|
94
|
-
value, repr(self), self.all_enabled_options
|
|
95
|
-
)
|
|
91
|
+
f'Option "{value}" is disabled in {repr(self)}. Enabled options are: {self.all_enabled_options}'
|
|
96
92
|
)
|
|
97
93
|
self._select_element.select_by_visible_text(value)
|
|
98
94
|
|
|
@@ -101,7 +97,7 @@ class BaseFormSelect:
|
|
|
101
97
|
return self.browser.text(self._select_element.first_selected_option)
|
|
102
98
|
|
|
103
99
|
def __repr__(self):
|
|
104
|
-
return "{
|
|
100
|
+
return f"{type(self).__name__}({self.locator!r})"
|
|
105
101
|
|
|
106
102
|
|
|
107
103
|
class FormSelect(BaseFormSelect, GenericLocatorWidget):
|
|
@@ -1,7 +1,4 @@
|
|
|
1
|
-
from widgetastic.widget import Checkbox
|
|
2
|
-
from widgetastic.widget import ParametrizedLocator
|
|
3
|
-
from widgetastic.widget import Text
|
|
4
|
-
from widgetastic.widget import View
|
|
1
|
+
from widgetastic.widget import Checkbox, ParametrizedLocator, Text, View
|
|
5
2
|
|
|
6
3
|
|
|
7
4
|
class BaseRadio:
|
|
@@ -3,10 +3,10 @@ from .select import Select
|
|
|
3
3
|
|
|
4
4
|
class BaseContextSelector:
|
|
5
5
|
ITEMS_LOCATOR = (
|
|
6
|
-
".//ul[@class
|
|
6
|
+
".//ul[contains(@class, '-c-menu__list') or @class='pf-c-context-selector__menu-list']/li"
|
|
7
7
|
)
|
|
8
8
|
ITEM_LOCATOR = (
|
|
9
|
-
".//*[(contains(@class, '
|
|
9
|
+
".//*[(contains(@class, '-c-menu__list-item') or contains(@class, "
|
|
10
10
|
"'pf-c-context-selector__menu-list-item'))"
|
|
11
11
|
" and normalize-space(.)={}]"
|
|
12
12
|
)
|