@@ -55,6 +55,7 @@ def test_anything(self):
55
55
from seleniumbase .fixtures import js_utils
56
56
from seleniumbase .fixtures import page_actions
57
57
from seleniumbase .fixtures import page_utils
58
+ from seleniumbase .fixtures import shared_utils
58
59
from seleniumbase .fixtures import xpath_to_css
59
60
logging .getLogger ("requests" ).setLevel (logging .ERROR )
60
61
logging .getLogger ("urllib3" ).setLevel (logging .ERROR )
@@ -976,14 +977,15 @@ def find_visible_elements(self, selector, by=By.CSS_SELECTOR, limit=0):
976
977
def click_visible_elements (self , selector , by = By .CSS_SELECTOR , limit = 0 ):
977
978
""" Finds all matching page elements and clicks visible ones in order.
978
979
If a click reloads or opens a new page, the clicking will stop.
980
+ If no matching elements appear, an Exception will be raised.
981
+ If "limit" is set and > 0, will only click that many elements.
982
+ Also clicks elements that become visible from previous clicks.
979
983
Works best for actions such as clicking all checkboxes on a page.
980
- Example: self.click_visible_elements('input[type="checkbox"]')
981
- If "limit" is set and > 0, will only click that many elements. """
982
- elements = []
983
- try :
984
- elements = self .find_visible_elements (selector , by = by )
985
- except Exception :
986
- elements = self .find_elements (selector , by = by )
984
+ Example: self.click_visible_elements('input[type="checkbox"]') """
985
+ selector , by = self .__recalculate_selector (selector , by )
986
+ self .wait_for_element_present (
987
+ selector , by = by , timeout = settings .SMALL_TIMEOUT )
988
+ elements = self .find_elements (selector , by = by )
987
989
click_count = 0
988
990
for element in elements :
989
991
if limit and limit > 0 and click_count >= limit :
@@ -1661,7 +1663,17 @@ def wait_for_angularjs(self, timeout=None, **kwargs):
1661
1663
js_utils .wait_for_angularjs (self .driver , timeout , ** kwargs )
1662
1664
1663
1665
def sleep (self , seconds ):
1664
- time .sleep (seconds )
1666
+ if not sb_config .time_limit :
1667
+ time .sleep (seconds )
1668
+ else :
1669
+ start_ms = time .time () * 1000.0
1670
+ stop_ms = start_ms + (seconds * 1000.0 )
1671
+ for x in range (int (seconds * 5 )):
1672
+ shared_utils .check_if_time_limit_exceeded ()
1673
+ now_ms = time .time () * 1000.0
1674
+ if now_ms >= stop_ms :
1675
+ break
1676
+ time .sleep (0.2 )
1665
1677
1666
1678
def activate_jquery (self ):
1667
1679
""" If "jQuery is not defined", use this method to activate it for use.
@@ -2455,6 +2467,22 @@ def jquery_update_text(self, selector, new_value, by=By.CSS_SELECTOR,
2455
2467
element .send_keys ('\n ' )
2456
2468
self .__demo_mode_pause_if_active ()
2457
2469
2470
+ def set_time_limit (self , time_limit ):
2471
+ if time_limit :
2472
+ try :
2473
+ sb_config .time_limit = float (time_limit )
2474
+ except Exception :
2475
+ sb_config .time_limit = None
2476
+ else :
2477
+ sb_config .time_limit = None
2478
+ if sb_config .time_limit and sb_config .time_limit > 0 :
2479
+ sb_config .time_limit_ms = int (sb_config .time_limit * 1000.0 )
2480
+ self .time_limit = sb_config .time_limit
2481
+ else :
2482
+ self .time_limit = None
2483
+ sb_config .time_limit = None
2484
+ sb_config .time_limit_ms = None
2485
+
2458
2486
############
2459
2487
2460
2488
def add_css_link (self , css_link ):
@@ -3237,6 +3265,7 @@ def wait_for_link_text_present(self, link_text, timeout=None):
3237
3265
start_ms = time .time () * 1000.0
3238
3266
stop_ms = start_ms + (timeout * 1000.0 )
3239
3267
for x in range (int (timeout * 5 )):
3268
+ shared_utils .check_if_time_limit_exceeded ()
3240
3269
try :
3241
3270
if not self .is_link_text_present (link_text ):
3242
3271
raise Exception (
@@ -3257,6 +3286,7 @@ def wait_for_partial_link_text_present(self, link_text, timeout=None):
3257
3286
start_ms = time .time () * 1000.0
3258
3287
stop_ms = start_ms + (timeout * 1000.0 )
3259
3288
for x in range (int (timeout * 5 )):
3289
+ shared_utils .check_if_time_limit_exceeded ()
3260
3290
try :
3261
3291
if not self .is_partial_link_text_present (link_text ):
3262
3292
raise Exception (
@@ -4145,6 +4175,7 @@ def setUp(self, masterqa_mode=False):
4145
4175
self .demo_mode = sb_config .demo_mode
4146
4176
self .demo_sleep = sb_config .demo_sleep
4147
4177
self .highlights = sb_config .highlights
4178
+ self .time_limit = sb_config .time_limit
4148
4179
self .environment = sb_config .environment
4149
4180
self .env = self .environment # Add a shortened version
4150
4181
self .with_selenium = sb_config .with_selenium # Should be True
@@ -4242,15 +4273,27 @@ def setUp(self, masterqa_mode=False):
4242
4273
# pyvirtualdisplay might not be necessary anymore because
4243
4274
# Chrome and Firefox now have built-in headless displays
4244
4275
pass
4276
+ else :
4277
+ # (Nosetests / Not Pytest)
4278
+ pass # Setup performed in plugins
4245
4279
4246
4280
# Verify that SeleniumBase is installed successfully
4247
4281
if not hasattr (self , "browser" ):
4248
4282
raise Exception ("""SeleniumBase plugins DID NOT load!\n \n """
4249
4283
"""*** Please REINSTALL SeleniumBase using: >\n """
4250
4284
""" >>> "pip install -r requirements.txt"\n """
4251
4285
""" >>> "python setup.py install" """ )
4286
+
4287
+ # Configure the test time limit (if used)
4288
+ self .set_time_limit (self .time_limit )
4289
+
4290
+ # Set the start time for the test (in ms)
4291
+ sb_config .start_time_ms = int (time .time () * 1000.0 )
4292
+
4293
+ # Parse the settings file
4252
4294
if self .settings_file :
4253
4295
settings_parser .set_settings (self .settings_file )
4296
+
4254
4297
# Mobile Emulator device metrics: CSS Width, CSS Height, & Pixel-Ratio
4255
4298
if self .device_metrics :
4256
4299
metrics_string = self .device_metrics
0 commit comments