Skip to content

Commit 805ea80

Browse files
authored
Merge pull request #529 from seleniumbase/checkbox-and-radio-button-methods
Add methods for checkboxes and radio buttons
2 parents 463c103 + 1e83b77 commit 805ea80

File tree

12 files changed

+126
-17
lines changed

12 files changed

+126
-17
lines changed

examples/test_checkboxes.py

Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from seleniumbase import BaseCase
2+
3+
4+
class MyTestClass(BaseCase):
5+
6+
def test_checkboxes_and_radio_buttons(self):
7+
self.open("https://www.w3schools.com/tags/tryit.asp"
8+
"?filename=tryhtml5_input_type_checkbox")
9+
self.switch_to_frame("iframeResult")
10+
checkbox = "input#vehicle2"
11+
self.assert_false(self.is_selected(checkbox))
12+
self.click(checkbox)
13+
self.assert_true(self.is_selected(checkbox))
14+
self.open("https://www.w3schools.com/tags/tryit.asp"
15+
"?filename=tryhtml5_input_type_radio")
16+
self.switch_to_frame("iframeResult")
17+
option_button = "input#male"
18+
self.assert_false(self.is_selected(option_button))
19+
self.click(option_button)
20+
self.assert_true(self.is_selected(option_button))

examples/translations/italian_test_1.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Italian Language Test
1+
# Italian Language Test - Python 3 Only!
22
from seleniumbase.translate.italian import CasoDiProva
33

44

help_docs/method_summary.md

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,10 +54,10 @@ self.is_link_text_present(link_text)
5454

5555
self.is_partial_link_text_present(link_text)
5656

57-
self.get_link_attribute(link_text, attribute, hard_fail)
58-
# Duplicates: self.get_link_text_attribute(link_text, attribute, hard_fail)
57+
self.get_link_attribute(link_text, attribute, hard_fail=True)
58+
# Duplicates: self.get_link_text_attribute(link_text, attribute, hard_fail=True)
5959

60-
self.get_partial_link_text_attribute(link_text, attribute, hard_fail)
60+
self.get_partial_link_text_attribute(link_text, attribute, hard_fail=True)
6161

6262
self.click_link(link_text, timeout=None)
6363
# Duplicates: self.click_link_text(link_text, timeout=None)
@@ -66,7 +66,7 @@ self.click_partial_link_text(partial_link_text, timeout=None)
6666

6767
self.get_text(selector, by=By.CSS_SELECTOR, timeout=None)
6868

69-
self.get_attribute(selector, attribute, by=By.CSS_SELECTOR, timeout=None)
69+
self.get_attribute(selector, attribute, by=By.CSS_SELECTOR, timeout=None, hard_fail=True)
7070

7171
self.set_attribute(selector, attribute, value, by=By.CSS_SELECTOR, timeout=None)
7272

@@ -91,6 +91,15 @@ self.click_nth_visible_element(selector, number, by=By.CSS_SELECTOR)
9191

9292
self.click_if_visible(selector, by=By.CSS_SELECTOR)
9393

94+
self.is_selected(selector, by=By.CSS_SELECTOR, timeout=None)
95+
# Duplicates: self.is_checked(selector, by=By.CSS_SELECTOR, timeout=None)
96+
97+
self.select_if_unselected(selector, by=By.CSS_SELECTOR)
98+
# Duplicates: self.check_if_unchecked(selector, by=By.CSS_SELECTOR)
99+
100+
self.unselect_if_selected(selector, by=By.CSS_SELECTOR)
101+
# Duplicates: self.uncheck_if_checked(selector, by=By.CSS_SELECTOR)
102+
94103
self.is_element_in_an_iframe(selector, by=By.CSS_SELECTOR)
95104

96105
self.switch_to_frame_of_element(selector, by=By.CSS_SELECTOR)

requirements.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ soupsieve==1.9.5;python_version<"3.5"
2929
soupsieve==2.0;python_version>="3.5"
3030
beautifulsoup4==4.8.2
3131
atomicwrites==1.3.0
32-
portalocker==1.5.2
32+
portalocker==1.6.0
3333
cryptography==2.8
3434
asn1crypto==1.3.0
3535
pyopenssl==19.1.0
@@ -42,7 +42,7 @@ pymysql==0.9.3
4242
pyotp==2.3.0
4343
boto==2.49.0
4444
cffi==1.14.0
45-
tqdm==4.43.0
45+
tqdm==4.44.1
4646
flake8==3.7.9
4747
certifi>=2019.11.28
4848
pdfminer.six==20191110;python_version<"3.5"

seleniumbase/fixtures/base_case.py

Lines changed: 59 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -794,7 +794,7 @@ def get_text(self, selector, by=By.CSS_SELECTOR, timeout=None):
794794
return element_text
795795

796796
def get_attribute(self, selector, attribute, by=By.CSS_SELECTOR,
797-
timeout=None):
797+
timeout=None, hard_fail=True):
798798
""" This method uses JavaScript to get the value of an attribute. """
799799
if not timeout:
800800
timeout = settings.SMALL_TIMEOUT
@@ -816,8 +816,11 @@ def get_attribute(self, selector, attribute, by=By.CSS_SELECTOR,
816816
if attribute_value is not None:
817817
return attribute_value
818818
else:
819-
raise Exception("Element {%s} has no attribute {%s}!" % (
820-
selector, attribute))
819+
if hard_fail:
820+
raise Exception("Element {%s} has no attribute {%s}!" % (
821+
selector, attribute))
822+
else:
823+
return None
821824

822825
def set_attribute(self, selector, attribute, value, by=By.CSS_SELECTOR,
823826
timeout=None):
@@ -1049,6 +1052,59 @@ def click_if_visible(self, selector, by=By.CSS_SELECTOR):
10491052
if self.is_element_visible(selector, by=by):
10501053
self.click(selector, by=by)
10511054

1055+
def is_checked(self, selector, by=By.CSS_SELECTOR, timeout=None):
1056+
""" Determines if a checkbox or a radio button element is checked.
1057+
Returns True if the element is checked.
1058+
Returns False if the element is not checked.
1059+
If the element is not present on the page, raises an exception.
1060+
If the element is not a checkbox or radio, raises an exception. """
1061+
if not timeout:
1062+
timeout = settings.SMALL_TIMEOUT
1063+
if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT:
1064+
timeout = self.__get_new_timeout(timeout)
1065+
selector, by = self.__recalculate_selector(selector, by)
1066+
kind = self.get_attribute(selector, "type", by=by, timeout=timeout)
1067+
if kind != "checkbox" and kind != "radio":
1068+
raise Exception("Expecting a checkbox or a radio button element!")
1069+
is_checked = self.get_attribute(
1070+
selector, "checked", by=by, timeout=timeout, hard_fail=False)
1071+
if is_checked:
1072+
return True
1073+
else: # (NoneType)
1074+
return False
1075+
1076+
def is_selected(self, selector, by=By.CSS_SELECTOR, timeout=None):
1077+
""" Same as is_checked() """
1078+
return self.is_checked(selector, by=by, timeout=timeout)
1079+
1080+
def check_if_unchecked(self, selector, by=By.CSS_SELECTOR):
1081+
""" If a checkbox or radio button is not checked, will check it. """
1082+
selector, by = self.__recalculate_selector(selector, by)
1083+
if not self.is_checked(selector, by=by):
1084+
if self.is_element_visible(selector, by=by):
1085+
self.click(selector, by=by)
1086+
else:
1087+
selector = self.convert_to_css_selector(selector, by=by)
1088+
self.js_click(selector, by=By.CSS_SELECTOR)
1089+
1090+
def select_if_unselected(self, selector, by=By.CSS_SELECTOR):
1091+
""" Same as check_if_unchecked() """
1092+
self.check_if_unchecked(selector, by=by)
1093+
1094+
def uncheck_if_checked(self, selector, by=By.CSS_SELECTOR):
1095+
""" If a checkbox is checked, will uncheck it. """
1096+
selector, by = self.__recalculate_selector(selector, by)
1097+
if self.is_checked(selector, by=by):
1098+
if self.is_element_visible(selector, by=by):
1099+
self.click(selector, by=by)
1100+
else:
1101+
selector = self.convert_to_css_selector(selector, by=by)
1102+
self.js_click(selector, by=By.CSS_SELECTOR)
1103+
1104+
def unselect_if_selected(self, selector, by=By.CSS_SELECTOR):
1105+
""" Same as uncheck_if_checked() """
1106+
self.uncheck_if_checked(selector, by=by)
1107+
10521108
def is_element_in_an_iframe(self, selector, by=By.CSS_SELECTOR):
10531109
""" Returns True if the selector's element is located in an iframe.
10541110
Otherwise returns False. """

seleniumbase/translate/chinese.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,7 @@ def 滚动到底部(self, *args, **kwargs):
195195
def 悬停并单击(self, *args, **kwargs):
196196
# hover_and_click(hover_selector, click_selector)
197197
return self.hover_and_click(*args, **kwargs)
198+
199+
def 是否被选中(self, *args, **kwargs):
200+
# is_selected(selector)
201+
return self.is_selected(*args, **kwargs)

seleniumbase/translate/french.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,7 @@ def faites_défiler_vers_le_bas(self, *args, **kwargs):
195195
def planer_au_dessus_et_cliquez(self, *args, **kwargs):
196196
# hover_and_click(hover_selector, click_selector)
197197
return self.hover_and_click(*args, **kwargs)
198+
199+
def est_il_sélectionné(self, *args, **kwargs):
200+
# is_selected(selector)
201+
return self.is_selected(*args, **kwargs)

seleniumbase/translate/italian.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
# Italian / italiano - Translations
1+
# Italian / italiano - Translations - Python 3 Only!
22
from seleniumbase import BaseCase
33

44

@@ -88,15 +88,15 @@ def avanti(self, *args, **kwargs):
8888
# go_forward()
8989
return self.go_forward(*args, **kwargs)
9090

91-
def il_testo_viene_visualizzato(self, *args, **kwargs):
91+
def è_testo_visto(self, *args, **kwargs): # noqa
9292
# is_text_visible(text, selector="html")
9393
return self.is_text_visible(*args, **kwargs)
9494

95-
def elemento_viene_visualizzato(self, *args, **kwargs):
95+
def è_elemento_visto(self, *args, **kwargs):
9696
# is_element_visible(selector)
9797
return self.is_element_visible(*args, **kwargs)
9898

99-
def elemento_presente(self, *args, **kwargs):
99+
def è_elemento_presente(self, *args, **kwargs):
100100
# is_element_present(selector)
101101
return self.is_element_present(*args, **kwargs)
102102

@@ -195,3 +195,7 @@ def scorri_verso_il_basso(self, *args, **kwargs):
195195
def passa_il_mouse_sopra_e_fai_clic(self, *args, **kwargs):
196196
# hover_and_click(hover_selector, click_selector)
197197
return self.hover_and_click(*args, **kwargs)
198+
199+
def è_selezionato(self, *args, **kwargs):
200+
# is_selected(selector)
201+
return self.is_selected(*args, **kwargs)

seleniumbase/translate/japanese.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,7 @@ def 一番下までスクロール(self, *args, **kwargs):
195195
def 上にマウスを移動しクリック(self, *args, **kwargs):
196196
# hover_and_click(hover_selector, click_selector)
197197
return self.hover_and_click(*args, **kwargs)
198+
199+
def 選択されていることを(self, *args, **kwargs):
200+
# is_selected(selector)
201+
return self.is_selected(*args, **kwargs)

seleniumbase/translate/korean.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,3 +195,7 @@ def 하단으로_스크롤(self, *args, **kwargs):
195195
def 위로_마우스를_이동하고_클릭(self, *args, **kwargs):
196196
# hover_and_click(hover_selector, click_selector)
197197
return self.hover_and_click(*args, **kwargs)
198+
199+
def 선택되어_있는지(self, *args, **kwargs):
200+
# is_selected(selector)
201+
return self.is_selected(*args, **kwargs)

0 commit comments

Comments
 (0)