Skip to content

BrowserWrapper Reference

Wrapper for driver functionality

Source code in BrowserWrapper/browserwrapper.py
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
485
486
487
488
489
490
491
492
493
494
495
496
497
498
499
500
501
502
503
504
505
506
507
508
509
510
511
512
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
533
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
554
555
556
557
558
559
560
561
562
563
564
565
566
567
568
569
570
571
572
573
574
575
576
577
578
579
580
581
582
583
584
585
586
587
588
589
590
591
592
593
594
595
596
597
598
599
600
601
602
603
604
605
606
607
608
609
610
611
612
613
614
615
616
617
618
619
620
621
622
623
624
625
626
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
class BrowserWrapper:
    """Wrapper for driver functionality"""

    def __init__(self, Config=BrowserWrapperConfiguration(), Driver=None, Log=None):
        if Config is None and Driver is None:
            raise EnvironmentError("Neither config nor existing driver was provided, one of which is required")
        self._provided_config = Config
        self.action_logging_enabled = True  # If False, prevents logs from being added on wrapped function calls
        self._previous_action_logging_setting = None  # Used to store the last state of logging for use in toggling
        self._log = Log

        if Driver is not None:
            self.CORE = Driver
        elif self._provided_config.BrowserType == "Chrome":
            self.CORE = create_chrome_instance(self._provided_config)
        elif self._provided_config.BrowserType == "Firefox":
            self.CORE = create_firefox_instance(self._provided_config)
        else:
            raise EnvironmentError(f"{self._provided_config.BrowserType} is not a supported browser type")

    ############################################################################################################################################
    ##### Core Functions #######################################################################################################################
    ############################################################################################################################################
    def log_info(self, msg, *args, **kwargs):
        """Wraps info logging functionality so that it can skipped if needed"""
        if self.action_logging_enabled and self._log is not None:
            self._log.info(msg, *args, **kwargs)
        return

    def log_warning(self, msg, *args, **kwargs):
        """Wraps warning logging functionality so that it can skipped if needed"""
        if self.action_logging_enabled and self._log is not None:
            self._log.warning(msg, *args, **kwargs)
        return

    def disable_logging(self):
        """Used to temporarily disable action logging"""
        if self._previous_action_logging_setting is None:
            self._previous_action_logging_setting = self.action_logging_enabled
            self.action_logging_enabled = False
        return

    def revert_logging(self):
        """Reverting action logging to original settings"""
        if self._previous_action_logging_setting is not None:
            self.action_logging_enabled = self._previous_action_logging_setting
            self._previous_action_logging_setting = None
        return

    def is_alive(self):
        """Determine the current state of the driver object, useful when needing to detect if the browser crashed

        Returns:
            [bool] -- True if the browser is still alive, False otherwise
        """
        try:
            _ = self.CORE.title
            return True
        except SeleniumExceptions.WebDriverException:
            return False

    def change_monitor(self, *, previous_data=None):
        """Determines changes due to actions by providing a snapshot of the current state before the action, and comparing to that snapshot afterwards."""
        snapshot = {'URL': self.CORE.current_url}
        if previous_data is None:
            return snapshot
        else:
            for comparison_type, comparison_data in snapshot.items():
                if previous_data[comparison_type] != comparison_data:
                    self.log_info(f"Browser: {comparison_type} changed from {previous_data[comparison_type]} to {comparison_data}")
            return None

    def format_element(self, element):
        """Changes an element tuple into the format required for unpacking by stripping all items other than locator method and locator string.
        This should be used to interact with CORE functionality, by unpacking the output of this function.

        Arguments:
            element {element tuple} -- Element tuples as defined in PageObjects

        Returns:
            locate_method, locator
        """
        return element[0], element[1]

    ############################################################################################################################################
    ##### Element Status Functions #############################################################################################################
    ############################################################################################################################################
    def elementIsClickable(self, element_tuple):
        """Determine the clickability of an element.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

        Returns:
            Boolean -- True if element is clickable, False otherwise
        """
        result = self.CORE.find_element(*self.format_element(element_tuple)).is_enabled()
        self.log_info(f"Browser.elementIsClickable: {element_tuple} is {'' if result else 'not '}clickable")
        return result

    def elementIsPresent(self, element_tuple):
        """Determine the current presence of an element.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

        Returns:
            Boolean -- True if element is present, False otherwise
        """
        try:
            self.CORE.find_element(*self.format_element(element_tuple))
            result = True
        except SeleniumExceptions.NoSuchElementException:
            result = False
        self.log_info(f"Browser.elementIsPresent: {element_tuple} is {'' if result else 'not '}present")
        return result

    def elementIsVisible(self, element_tuple):
        """Determine the current visibility of an element
        Note: An exception will be raised if the element is not present.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

        Returns:
            Boolean -- True if element is visible, False otherwise
        """
        result = self.CORE.find_element(*self.format_element(element_tuple)).is_displayed()
        self.log_info(f"Browser.elementIsVisible: {element_tuple} is {'' if result else 'not '}present")
        return result

    def elementIsChecked(self, element_tuple):
        """Determine if a checkbox element is checked or unchecked
        Note: An exception will be raised if the element is not present.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

        Returns:
            Boolean -- True if element is checked, False otherwise
        """
        result = self.CORE.find_element(*self.format_element(element_tuple)).is_selected()
        self.log_info(f"Browser.elementIsChecked: {element_tuple} is {'' if result else 'not '}checked")
        return result

    def alertIsPresent(self, *, accept_if_present=False):
        """Determines if an alert is present

        Arguments:
            accept_if_present {bool} -- If set to True will accept the alert after determining that it is present

        Returns:
            Boolean -- True if alert is present, False if not
        """
        self.disable_logging()
        result = self.waitForAlertPresent(timeout=0)
        if accept_if_present and result:
            self.acceptAlert()
            self.revert_logging()
            self.log_info(f"Browser.alertIsPresent: Alert is present, and has been accepted as accept_if_present=True")
        else:
            self.revert_logging()
            self.log_info(f"Browser.alertIsPresent: Alert is {'' if result else 'not '}present")
        return result

    ############################################################################################################################################
    ##### Wait Functions #######################################################################################################################
    ############################################################################################################################################

    def waitForElementVisible(self, element_tuple, *, timeout=5):
        """Wait a configurable period of time for an element to be visible.
        Note: An exception will be raised if the element is not present

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            timeout {int, defaults to 5} -- Max length of time to wait for the condition

        Returns:
            Boolean -- True if element is initially visible or becomes visible during the wait period, False otherwise
        """
        try:
            WebDriverWait(self.CORE, timeout).until(EC.visibility_of_element_located(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
            self.log_info(f"Browser.waitForElementVisible: {element_tuple} is visible within {timeout} seconds")
            return True
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForElementVisible: {element_tuple} did not become visible after {timeout} seconds")
            return False

    def waitForElementNotVisible(self, element_tuple, *, timeout=5):
        """Wait a configurable period of time for an element to be invisible.
        Note: An exception will be raised if the element is not present

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            timeout {int, defaults to 5} -- Max length of time to wait for the condition

        Returns:
            Boolean -- True if element is initially invisible or becomes invisible during the wait period, False otherwise
        """
        try:
            WebDriverWait(self.CORE, timeout).until(EC.invisibility_of_element_located(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
            self.log_info(f"Browser.waitForElementNotVisible: {element_tuple} is invisible within {timeout} seconds")
            return True
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForElementNotVisible: {element_tuple} did not become invisible after {timeout} seconds")
            return False

    def waitForElementPresent(self, element_tuple, *, timeout=5):
        """Wait a configurable period of time for an element to be present.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            timeout {int, defaults to 5} -- Max length of time to wait for the condition

        Returns:
            Boolean -- True if element is initially present or becomes present wait period, False otherwise
        """
        try:
            WebDriverWait(self.CORE, timeout).until(EC.presence_of_element_located(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
            self.log_info(f"Browser.waitForElementPresent: {element_tuple} is present within {timeout} seconds")
            return True
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForElementPresent: {element_tuple} did not become present after {timeout} seconds")
            return False

    def waitForElementNotPresent(self, element_tuple, *, timeout=5):
        """Wait a configurable period of time for an element to not be present.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            timeout {int, defaults to 5} -- Max length of time to wait for the condition

        Returns:
            Boolean -- True if element is initially not present or becomes not present during the wait period, False otherwise
        """
        try:

            self.disable_logging()
            if self.waitForElementNotVisible(element_tuple, timeout=timeout) is False or self.elementIsPresent(element_tuple) is True:
                self.revert_logging()
                raise SeleniumExceptions.TimeoutException()
            self.revert_logging()
            self.log_info(f"Browser.waitForElementNotPresent: {element_tuple} is present within {timeout} seconds")
            return True
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForElementNotPresent: {element_tuple} did not become not present after {timeout} seconds")
            return False

    def waitForAlertPresent(self, *, timeout=5):
        """Wait a configurable period of time for an element to be present.

        Arguments:
            timeout {int, defaults to 5} -- Max length of time to wait for the condition

        Returns:
            Boolean -- True if alert is initially present or becomes present during the wait period, False otherwise
        """
        try:
            WebDriverWait(self.CORE, timeout).until(EC.alert_is_present())
            self.log_info(f"Browser.waitForAlertPresent: Alert is present within {timeout} seconds")
            return True
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForAlertPresent: Alert did not become present after {timeout} seconds")
            return False

    def waitForElementClickable(self, element_tuple, *, timeout=5):
        """Wait a configurable period of time for an element to be clickable.
        Note: An exception will be raised if the element is not present.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            timeout {int, defaults to 5} -- Max length of time to wait for the condition

        Returns:
            Boolean -- True if element is initially clickable or becomes clickable during the wait period, False otherwise
        """
        try:
            WebDriverWait(self.CORE, timeout).until(EC.element_to_be_clickable(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
            self.log_info(f"Browser.waitForElementClickable: {element_tuple} is clickable within {timeout} seconds")
            return True
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForElementClickable: {element_tuple} did not become clickable after {timeout} seconds")
            return False

    def waitForURLToContain(self, url_portion, *, timeout=5):
        """Wait a configurable period of time for the current URL to contain a given string.

        Arguments:
            url_portion {string} -- The string you want to check that the URL contains
            timeout {int} -- Max length of time to wait for the condition
        """
        try:
            WebDriverWait(self.CORE, timeout).until(lambda self: url_portion in self.current_url)
            self.log_info(f"Browser.waitForURLToContain: {self.CORE.current_url} contains {url_portion} within {timeout} seconds")
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForURLToContain: {self.CORE.current_url} does not contain {url_portion} after {timeout} seconds")
            # We're going to capture the timeout as it doesn't matter - the return statement is the bool
        return url_portion in self.CORE.current_url

    def waitForURLToEqual(self, url, *, timeout=5):
        """Wait a configurable period of time for the current URL to equal a given string.

        Arguments:
            url {string} -- The string you want to check that the URL equals
            timeout {int} -- Max length of time to wait for the condition
        """
        try:
            WebDriverWait(self.CORE, timeout).until(lambda self: url == self.current_url)
            self.log_info(f"Browser.waitForURLToEqual: {self.CORE.current_url} equals {url} within {timeout} seconds")
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForURLToEqual: {self.CORE.current_url} does not equal {url} after {timeout} seconds")
            # We're going to capture the timeout as it doesn't matter - the return statement is the bool
        return url in self.CORE.current_url

    def waitForElementTextChange(self, element_tuple, original_text, *, timeout=5):
        """Wait a configurable period of time for an element's text to change
        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            original_text {string} -- The original text you want to see change
            timeout {int} -- Max length of time to wait for the condition
        """
        self.waitForElementVisible(element_tuple, timeout=timeout)
        try:
            self.disable_logging()
            WebDriverWait(self, timeout).until(lambda self: self.getText(element_tuple) != original_text)
            self.revert_logging()
            self.log_info(f"Browser.waitForElementTextChange: {element_tuple} text changed from {original_text} within {timeout} seconds")
            return True
        except SeleniumExceptions.TimeoutException:
            self.log_warning(f"Browser.waitForElementTextChange: {element_tuple} text did not changefrom {original_text} after {timeout} seconds")
            return False

    ############################################################################################################################################
    ##### Action Functions #####################################################################################################################
    ############################################################################################################################################

    def navigate(self, url):
        """Navigate to a url

        Arguments:
            url {string} -- Url to navigate to
        """
        self.log_info(f"Browser.navigate: Navigating to {url}")
        self.CORE.get(url)
        return

    def getText(self, element_tuple):
        """Get the text of an element.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

        Returns:
            string -- Text within the element
        """
        result = self.CORE.find_element(*self.format_element(element_tuple)).text
        self.log_info(f"Browser.getText: {element_tuple} text is {result}")
        return result

    def setText(self, element_tuple, text):
        """Clear an element, then sends keys to it. Typically used for form inputs.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            text {string} -- String to type into the element
        """
        self.log_info(f"Browser.setText: Setting text of {element_tuple} to {text}")

        self.disable_logging()
        self.clearText(element_tuple)
        self.revert_logging()

        self.CORE.find_element(*self.format_element(element_tuple)).send_keys(text)
        return

    def clearText(self, element_tuple):
        """Clear the text of an element, typically an input field

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        """
        self.log_info(f"Browser.clearText: Clearing the text of {element_tuple}")
        self.CORE.find_element(*self.format_element(element_tuple)).clear()
        return

    def click(self, element_tuple):
        """Click on an element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        """
        current_state = self.change_monitor()
        self.log_info(f"Browser.click: Clicking {element_tuple}")
        self.CORE.find_element(*self.format_element(element_tuple)).click()
        self.change_monitor(previous_data=current_state)
        return

    def mouseOver(self, element_tuple):
        """Move the mouse over an element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        """
        self.log_info(f"Browser.mouseOver: Moving mouse over {element_tuple}")
        ActionChains(self.CORE).move_to_element(self.CORE.find_element(*self.format_element(element_tuple))).perform()
        return

    def scrollToElement(self, element_tuple):
        """Scroll to an element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        """
        self.log_info(f"Browser.scrollToElement: Scrolling to {element_tuple}")
        self.disable_logging()
        self.mouseOver(element_tuple)
        self.revert_logging()
        return

    def selectOptionByValue(self, element_tuple, select_value):
        """Select an option by value for a select element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            select_value {string} -- Value of the option to select
        """
        self.log_info(f"Browser.selectOptionByValue: Setting {element_tuple} to {select_value}")
        Select(self.CORE.find_element(*self.format_element(element_tuple))).select_by_value(select_value)
        return

    def selectOptionByLabel(self, element_tuple, select_label):
        """Select an option by label (visible text) for a select element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            select_label {string} -- Label (visible text) of the option to select
        """
        self.log_info(f"Browser.selectOptionByLabel: Setting {element_tuple} to {select_label}")
        Select(self.CORE.find_element(*self.format_element(element_tuple))).select_by_visible_text(select_label)
        return

    def selectRandomOption(self, element_tuple):
        """Select an random option for a select element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        """
        self.log_info(f"Browser.selectRandomOption: Selecting random option for {element_tuple}")
        select = Select(self.CORE.find_element(*self.format_element(element_tuple)))
        select.select_by_index(randint(0, len(select.options) - 1))
        _ = self.getSelectedOption(element_tuple)  # To log what was chosen
        return

    def getSelectedOption(self, element_tuple):
        """Get the currently selected option in select element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        """
        select = Select(self.CORE.find_element(*self.format_element(element_tuple)))
        result = select.first_selected_option
        self.log_info(f"Browser.getSelectedOption: {element_tuple} is currently set to {result}")
        return result

    def check(self, element_tuple, *, wrapper_element_tuple=None):
        """Check a checkbox if it's not already. For checkboxes which can't be interacted with directly (hidden but toggled via JS detecting a click on a different object),
        provide a wrapper element in addition for the click instead.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            wrapper_element_tuple {PageObject Element} -- Default is None, tuple representation of element to be used for locating the wrapper, if needed. Wrappers are clicked in
                                                          place of the checkbox element when it is unreachable.
        """
        self.log_info(f"Browser.check: Setting {element_tuple} checkbox to checked")
        checkbox = self.CORE.find_element(*self.format_element(element_tuple))
        if not checkbox.is_selected():
            if wrapper_element_tuple is not None:
                self.log_info(f"Browser.check: Wrapper element was provided, clicking {wrapper_element_tuple} instead")
                self.click(wrapper_element_tuple)
            else:
                self.click(element_tuple)
        else:
            self.log_info(f"Browser.check: Skipping action as {element_tuple} is already checked")
        return

    def uncheck(self, element_tuple, *, wrapper_element_tuple=None):
        """Uncheck a checkbox if it's not already. For checkboxes which can't be interacted with directly (hidden but toggled via JS detecting a click on a different object),
        provide a wrapper element in addition for the function to click instead.

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            wrapper_element_tuple {PageObject Element} -- Default is None, tuple representation of element to be used for locating the wrapper, if needed. Wrappers are clicked in
                                                          place of the checkbox element when it is unreachable.
        """
        self.log_info(f"Browser.uncheck: Setting {element_tuple} checkbox to unchecked")
        checkbox = self.CORE.find_element(*self.format_element(element_tuple))
        if checkbox.is_selected():
            if wrapper_element_tuple is not None:
                self.log_info(f"Browser.check: Wrapper element was provided, clicking {wrapper_element_tuple} instead")
                self.click(wrapper_element_tuple)
            else:
                self.click(element_tuple)
        else:
            self.log_info(f"Browser.check: Skipping action as {element_tuple} is already unchecked")
        return

    def delay(self, length):
        """Delay for a specified period of time. Should be used as a last resort if no other wait function works.

        Arguments:
            length {int} -- Length of time to delay
        """
        self.log_info(f"Browser.delay: Sleeping for {length} seconds")
        return sleep(length)

    def getAttribute(self, element_tuple, attribute):
        """Get the value of an element's attribute

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            attribute {string} -- Attribute to collect the value of

        Returns:
            string -- Value of the provided attribute
        """
        result = self.CORE.find_element(*self.format_element(element_tuple)).get_attribute(attribute)
        self.log_info(f"Browser.getAttribute: {attribute} attribute of {element_tuple} is {result}")
        return result

    def sendKeys(self, element_tuple, keys):
        """Send keys to an element

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
            keys {string} -- Keys to send to the element
        """
        self.log_info(f"Browser.sendKeys: Sending {keys} to {element_tuple}")
        self.CORE.find_element(*self.format_element(element_tuple)).send_keys(*keys)
        return

    def getUrl(self):
        """Get URL of the current window.

        Returns:
            string -- Current URL
        """
        result = self.CORE.current_url
        self.log_info(f"Browser.getUrl: Current URL is {result}")
        return result

    def refresh(self):
        """Refresh the current window."""
        self.log_info(f"Browser.refresh: Refreshing the page")
        self.CORE.refresh()
        return

    def switchToFrame(self, element_tuple):
        """Switches to the specified iframe in the DOM

        Arguments:
            element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        """
        self.log_info(f"Browser.switchToFrame: Switching to iframe {element_tuple}")
        self.CORE.switch_to.frame(self.CORE.find_element(*self.format_element(element_tuple)))
        return

    def switchToDefaultContent(self):
        """Switches from iframe to default content in the DOM"""
        self.log_info(f"Browser.switchToDefaultContent: Switching to default content")
        self.CORE.switch_to.default_content()
        return

    def switchToWindowByIndex(self, index):
        """Switches to window with provided index

        Arguments:
            index {int} -- Zero-based index of window to switch to.
        """
        self.log_info(f"Browser.switchToWindowByIndex: Switching to window at index {index}")
        self.CORE.switch_to.window(self.CORE.window_handles[index])
        return

    def deleteAllCookies(self):
        """Deletes all cookies"""
        self.CORE.delete_all_cookies()
        return

    def acceptAlert(self):
        """Accepts an active alert on a page"""
        self.log_info(f"Browser.acceptAlert: Accepting alert")
        alert = self.CORE.switch_to.alert
        alert.accept()
        return

    def back(self):
        """Uses the browser back functionality to go to the previous page."""
        self.log_info(f"Browser.back: Telling browser to return to previous page")
        self.CORE.back()
        return

    def quit(self, *, only_if_alive=False):
        """Quits the browser."""
        self.log_info(f"Browser.back: Telling browser to return to previous page")
        if (only_if_alive and self.is_alive()) or not only_if_alive:
            self.CORE.quit()
        return

acceptAlert()

Accepts an active alert on a page

Source code in BrowserWrapper/browserwrapper.py
636
637
638
639
640
641
def acceptAlert(self):
    """Accepts an active alert on a page"""
    self.log_info(f"Browser.acceptAlert: Accepting alert")
    alert = self.CORE.switch_to.alert
    alert.accept()
    return

alertIsPresent(*, accept_if_present=False)

Determines if an alert is present

Returns:

Type Description

Boolean -- True if alert is present, False if not

Source code in BrowserWrapper/browserwrapper.py
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
def alertIsPresent(self, *, accept_if_present=False):
    """Determines if an alert is present

    Arguments:
        accept_if_present {bool} -- If set to True will accept the alert after determining that it is present

    Returns:
        Boolean -- True if alert is present, False if not
    """
    self.disable_logging()
    result = self.waitForAlertPresent(timeout=0)
    if accept_if_present and result:
        self.acceptAlert()
        self.revert_logging()
        self.log_info(f"Browser.alertIsPresent: Alert is present, and has been accepted as accept_if_present=True")
    else:
        self.revert_logging()
        self.log_info(f"Browser.alertIsPresent: Alert is {'' if result else 'not '}present")
    return result

back()

Uses the browser back functionality to go to the previous page.

Source code in BrowserWrapper/browserwrapper.py
643
644
645
646
647
def back(self):
    """Uses the browser back functionality to go to the previous page."""
    self.log_info(f"Browser.back: Telling browser to return to previous page")
    self.CORE.back()
    return

change_monitor(*, previous_data=None)

Determines changes due to actions by providing a snapshot of the current state before the action, and comparing to that snapshot afterwards.

Source code in BrowserWrapper/browserwrapper.py
110
111
112
113
114
115
116
117
118
119
def change_monitor(self, *, previous_data=None):
    """Determines changes due to actions by providing a snapshot of the current state before the action, and comparing to that snapshot afterwards."""
    snapshot = {'URL': self.CORE.current_url}
    if previous_data is None:
        return snapshot
    else:
        for comparison_type, comparison_data in snapshot.items():
            if previous_data[comparison_type] != comparison_data:
                self.log_info(f"Browser: {comparison_type} changed from {previous_data[comparison_type]} to {comparison_data}")
        return None

check(element_tuple, *, wrapper_element_tuple=None)

Check a checkbox if it's not already. For checkboxes which can't be interacted with directly (hidden but toggled via JS detecting a click on a different object), provide a wrapper element in addition for the click instead.

Source code in BrowserWrapper/browserwrapper.py
513
514
515
516
517
518
519
520
521
522
523
524
525
526
527
528
529
530
531
532
def check(self, element_tuple, *, wrapper_element_tuple=None):
    """Check a checkbox if it's not already. For checkboxes which can't be interacted with directly (hidden but toggled via JS detecting a click on a different object),
    provide a wrapper element in addition for the click instead.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        wrapper_element_tuple {PageObject Element} -- Default is None, tuple representation of element to be used for locating the wrapper, if needed. Wrappers are clicked in
                                                      place of the checkbox element when it is unreachable.
    """
    self.log_info(f"Browser.check: Setting {element_tuple} checkbox to checked")
    checkbox = self.CORE.find_element(*self.format_element(element_tuple))
    if not checkbox.is_selected():
        if wrapper_element_tuple is not None:
            self.log_info(f"Browser.check: Wrapper element was provided, clicking {wrapper_element_tuple} instead")
            self.click(wrapper_element_tuple)
        else:
            self.click(element_tuple)
    else:
        self.log_info(f"Browser.check: Skipping action as {element_tuple} is already checked")
    return

clearText(element_tuple)

Clear the text of an element, typically an input field

Source code in BrowserWrapper/browserwrapper.py
424
425
426
427
428
429
430
431
432
def clearText(self, element_tuple):
    """Clear the text of an element, typically an input field

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
    """
    self.log_info(f"Browser.clearText: Clearing the text of {element_tuple}")
    self.CORE.find_element(*self.format_element(element_tuple)).clear()
    return

click(element_tuple)

Click on an element

Source code in BrowserWrapper/browserwrapper.py
434
435
436
437
438
439
440
441
442
443
444
def click(self, element_tuple):
    """Click on an element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
    """
    current_state = self.change_monitor()
    self.log_info(f"Browser.click: Clicking {element_tuple}")
    self.CORE.find_element(*self.format_element(element_tuple)).click()
    self.change_monitor(previous_data=current_state)
    return

delay(length)

Delay for a specified period of time. Should be used as a last resort if no other wait function works.

Source code in BrowserWrapper/browserwrapper.py
555
556
557
558
559
560
561
562
def delay(self, length):
    """Delay for a specified period of time. Should be used as a last resort if no other wait function works.

    Arguments:
        length {int} -- Length of time to delay
    """
    self.log_info(f"Browser.delay: Sleeping for {length} seconds")
    return sleep(length)

deleteAllCookies()

Deletes all cookies

Source code in BrowserWrapper/browserwrapper.py
631
632
633
634
def deleteAllCookies(self):
    """Deletes all cookies"""
    self.CORE.delete_all_cookies()
    return

disable_logging()

Used to temporarily disable action logging

Source code in BrowserWrapper/browserwrapper.py
84
85
86
87
88
89
def disable_logging(self):
    """Used to temporarily disable action logging"""
    if self._previous_action_logging_setting is None:
        self._previous_action_logging_setting = self.action_logging_enabled
        self.action_logging_enabled = False
    return

elementIsChecked(element_tuple)

Determine if a checkbox element is checked or unchecked Note: An exception will be raised if the element is not present.

Returns:

Type Description

Boolean -- True if element is checked, False otherwise

Source code in BrowserWrapper/browserwrapper.py
180
181
182
183
184
185
186
187
188
189
190
191
192
def elementIsChecked(self, element_tuple):
    """Determine if a checkbox element is checked or unchecked
    Note: An exception will be raised if the element is not present.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

    Returns:
        Boolean -- True if element is checked, False otherwise
    """
    result = self.CORE.find_element(*self.format_element(element_tuple)).is_selected()
    self.log_info(f"Browser.elementIsChecked: {element_tuple} is {'' if result else 'not '}checked")
    return result

elementIsClickable(element_tuple)

Determine the clickability of an element.

Returns:

Type Description

Boolean -- True if element is clickable, False otherwise

Source code in BrowserWrapper/browserwrapper.py
136
137
138
139
140
141
142
143
144
145
146
147
def elementIsClickable(self, element_tuple):
    """Determine the clickability of an element.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

    Returns:
        Boolean -- True if element is clickable, False otherwise
    """
    result = self.CORE.find_element(*self.format_element(element_tuple)).is_enabled()
    self.log_info(f"Browser.elementIsClickable: {element_tuple} is {'' if result else 'not '}clickable")
    return result

elementIsPresent(element_tuple)

Determine the current presence of an element.

Returns:

Type Description

Boolean -- True if element is present, False otherwise

Source code in BrowserWrapper/browserwrapper.py
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
def elementIsPresent(self, element_tuple):
    """Determine the current presence of an element.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

    Returns:
        Boolean -- True if element is present, False otherwise
    """
    try:
        self.CORE.find_element(*self.format_element(element_tuple))
        result = True
    except SeleniumExceptions.NoSuchElementException:
        result = False
    self.log_info(f"Browser.elementIsPresent: {element_tuple} is {'' if result else 'not '}present")
    return result

elementIsVisible(element_tuple)

Determine the current visibility of an element Note: An exception will be raised if the element is not present.

Returns:

Type Description

Boolean -- True if element is visible, False otherwise

Source code in BrowserWrapper/browserwrapper.py
166
167
168
169
170
171
172
173
174
175
176
177
178
def elementIsVisible(self, element_tuple):
    """Determine the current visibility of an element
    Note: An exception will be raised if the element is not present.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

    Returns:
        Boolean -- True if element is visible, False otherwise
    """
    result = self.CORE.find_element(*self.format_element(element_tuple)).is_displayed()
    self.log_info(f"Browser.elementIsVisible: {element_tuple} is {'' if result else 'not '}present")
    return result

format_element(element)

Changes an element tuple into the format required for unpacking by stripping all items other than locator method and locator string. This should be used to interact with CORE functionality, by unpacking the output of this function.

Returns:

Type Description

locate_method, locator

Source code in BrowserWrapper/browserwrapper.py
121
122
123
124
125
126
127
128
129
130
131
def format_element(self, element):
    """Changes an element tuple into the format required for unpacking by stripping all items other than locator method and locator string.
    This should be used to interact with CORE functionality, by unpacking the output of this function.

    Arguments:
        element {element tuple} -- Element tuples as defined in PageObjects

    Returns:
        locate_method, locator
    """
    return element[0], element[1]

getAttribute(element_tuple, attribute)

Get the value of an element's attribute

Returns:

Type Description

string -- Value of the provided attribute

Source code in BrowserWrapper/browserwrapper.py
564
565
566
567
568
569
570
571
572
573
574
575
576
def getAttribute(self, element_tuple, attribute):
    """Get the value of an element's attribute

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        attribute {string} -- Attribute to collect the value of

    Returns:
        string -- Value of the provided attribute
    """
    result = self.CORE.find_element(*self.format_element(element_tuple)).get_attribute(attribute)
    self.log_info(f"Browser.getAttribute: {attribute} attribute of {element_tuple} is {result}")
    return result

getSelectedOption(element_tuple)

Get the currently selected option in select element

Source code in BrowserWrapper/browserwrapper.py
502
503
504
505
506
507
508
509
510
511
def getSelectedOption(self, element_tuple):
    """Get the currently selected option in select element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
    """
    select = Select(self.CORE.find_element(*self.format_element(element_tuple)))
    result = select.first_selected_option
    self.log_info(f"Browser.getSelectedOption: {element_tuple} is currently set to {result}")
    return result

getText(element_tuple)

Get the text of an element.

Returns:

Type Description

string -- Text within the element

Source code in BrowserWrapper/browserwrapper.py
395
396
397
398
399
400
401
402
403
404
405
406
def getText(self, element_tuple):
    """Get the text of an element.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.

    Returns:
        string -- Text within the element
    """
    result = self.CORE.find_element(*self.format_element(element_tuple)).text
    self.log_info(f"Browser.getText: {element_tuple} text is {result}")
    return result

getUrl()

Get URL of the current window.

Returns:

Type Description

string -- Current URL

Source code in BrowserWrapper/browserwrapper.py
589
590
591
592
593
594
595
596
597
def getUrl(self):
    """Get URL of the current window.

    Returns:
        string -- Current URL
    """
    result = self.CORE.current_url
    self.log_info(f"Browser.getUrl: Current URL is {result}")
    return result

is_alive()

Determine the current state of the driver object, useful when needing to detect if the browser crashed

Returns:

Type Description

[bool] -- True if the browser is still alive, False otherwise

Source code in BrowserWrapper/browserwrapper.py
 98
 99
100
101
102
103
104
105
106
107
108
def is_alive(self):
    """Determine the current state of the driver object, useful when needing to detect if the browser crashed

    Returns:
        [bool] -- True if the browser is still alive, False otherwise
    """
    try:
        _ = self.CORE.title
        return True
    except SeleniumExceptions.WebDriverException:
        return False

log_info(msg, *args, **kwargs)

Wraps info logging functionality so that it can skipped if needed

Source code in BrowserWrapper/browserwrapper.py
72
73
74
75
76
def log_info(self, msg, *args, **kwargs):
    """Wraps info logging functionality so that it can skipped if needed"""
    if self.action_logging_enabled and self._log is not None:
        self._log.info(msg, *args, **kwargs)
    return

log_warning(msg, *args, **kwargs)

Wraps warning logging functionality so that it can skipped if needed

Source code in BrowserWrapper/browserwrapper.py
78
79
80
81
82
def log_warning(self, msg, *args, **kwargs):
    """Wraps warning logging functionality so that it can skipped if needed"""
    if self.action_logging_enabled and self._log is not None:
        self._log.warning(msg, *args, **kwargs)
    return

mouseOver(element_tuple)

Move the mouse over an element

Source code in BrowserWrapper/browserwrapper.py
446
447
448
449
450
451
452
453
454
def mouseOver(self, element_tuple):
    """Move the mouse over an element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
    """
    self.log_info(f"Browser.mouseOver: Moving mouse over {element_tuple}")
    ActionChains(self.CORE).move_to_element(self.CORE.find_element(*self.format_element(element_tuple))).perform()
    return

navigate(url)

Navigate to a url

Source code in BrowserWrapper/browserwrapper.py
385
386
387
388
389
390
391
392
393
def navigate(self, url):
    """Navigate to a url

    Arguments:
        url {string} -- Url to navigate to
    """
    self.log_info(f"Browser.navigate: Navigating to {url}")
    self.CORE.get(url)
    return

quit(*, only_if_alive=False)

Quits the browser.

Source code in BrowserWrapper/browserwrapper.py
649
650
651
652
653
654
def quit(self, *, only_if_alive=False):
    """Quits the browser."""
    self.log_info(f"Browser.back: Telling browser to return to previous page")
    if (only_if_alive and self.is_alive()) or not only_if_alive:
        self.CORE.quit()
    return

refresh()

Refresh the current window.

Source code in BrowserWrapper/browserwrapper.py
599
600
601
602
603
def refresh(self):
    """Refresh the current window."""
    self.log_info(f"Browser.refresh: Refreshing the page")
    self.CORE.refresh()
    return

revert_logging()

Reverting action logging to original settings

Source code in BrowserWrapper/browserwrapper.py
91
92
93
94
95
96
def revert_logging(self):
    """Reverting action logging to original settings"""
    if self._previous_action_logging_setting is not None:
        self.action_logging_enabled = self._previous_action_logging_setting
        self._previous_action_logging_setting = None
    return

scrollToElement(element_tuple)

Scroll to an element

Source code in BrowserWrapper/browserwrapper.py
456
457
458
459
460
461
462
463
464
465
466
def scrollToElement(self, element_tuple):
    """Scroll to an element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
    """
    self.log_info(f"Browser.scrollToElement: Scrolling to {element_tuple}")
    self.disable_logging()
    self.mouseOver(element_tuple)
    self.revert_logging()
    return

selectOptionByLabel(element_tuple, select_label)

Select an option by label (visible text) for a select element

Source code in BrowserWrapper/browserwrapper.py
479
480
481
482
483
484
485
486
487
488
def selectOptionByLabel(self, element_tuple, select_label):
    """Select an option by label (visible text) for a select element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        select_label {string} -- Label (visible text) of the option to select
    """
    self.log_info(f"Browser.selectOptionByLabel: Setting {element_tuple} to {select_label}")
    Select(self.CORE.find_element(*self.format_element(element_tuple))).select_by_visible_text(select_label)
    return

selectOptionByValue(element_tuple, select_value)

Select an option by value for a select element

Source code in BrowserWrapper/browserwrapper.py
468
469
470
471
472
473
474
475
476
477
def selectOptionByValue(self, element_tuple, select_value):
    """Select an option by value for a select element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        select_value {string} -- Value of the option to select
    """
    self.log_info(f"Browser.selectOptionByValue: Setting {element_tuple} to {select_value}")
    Select(self.CORE.find_element(*self.format_element(element_tuple))).select_by_value(select_value)
    return

selectRandomOption(element_tuple)

Select an random option for a select element

Source code in BrowserWrapper/browserwrapper.py
490
491
492
493
494
495
496
497
498
499
500
def selectRandomOption(self, element_tuple):
    """Select an random option for a select element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
    """
    self.log_info(f"Browser.selectRandomOption: Selecting random option for {element_tuple}")
    select = Select(self.CORE.find_element(*self.format_element(element_tuple)))
    select.select_by_index(randint(0, len(select.options) - 1))
    _ = self.getSelectedOption(element_tuple)  # To log what was chosen
    return

sendKeys(element_tuple, keys)

Send keys to an element

Source code in BrowserWrapper/browserwrapper.py
578
579
580
581
582
583
584
585
586
587
def sendKeys(self, element_tuple, keys):
    """Send keys to an element

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        keys {string} -- Keys to send to the element
    """
    self.log_info(f"Browser.sendKeys: Sending {keys} to {element_tuple}")
    self.CORE.find_element(*self.format_element(element_tuple)).send_keys(*keys)
    return

setText(element_tuple, text)

Clear an element, then sends keys to it. Typically used for form inputs.

Source code in BrowserWrapper/browserwrapper.py
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
def setText(self, element_tuple, text):
    """Clear an element, then sends keys to it. Typically used for form inputs.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        text {string} -- String to type into the element
    """
    self.log_info(f"Browser.setText: Setting text of {element_tuple} to {text}")

    self.disable_logging()
    self.clearText(element_tuple)
    self.revert_logging()

    self.CORE.find_element(*self.format_element(element_tuple)).send_keys(text)
    return

switchToDefaultContent()

Switches from iframe to default content in the DOM

Source code in BrowserWrapper/browserwrapper.py
615
616
617
618
619
def switchToDefaultContent(self):
    """Switches from iframe to default content in the DOM"""
    self.log_info(f"Browser.switchToDefaultContent: Switching to default content")
    self.CORE.switch_to.default_content()
    return

switchToFrame(element_tuple)

Switches to the specified iframe in the DOM

Source code in BrowserWrapper/browserwrapper.py
605
606
607
608
609
610
611
612
613
def switchToFrame(self, element_tuple):
    """Switches to the specified iframe in the DOM

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
    """
    self.log_info(f"Browser.switchToFrame: Switching to iframe {element_tuple}")
    self.CORE.switch_to.frame(self.CORE.find_element(*self.format_element(element_tuple)))
    return

switchToWindowByIndex(index)

Switches to window with provided index

Source code in BrowserWrapper/browserwrapper.py
621
622
623
624
625
626
627
628
629
def switchToWindowByIndex(self, index):
    """Switches to window with provided index

    Arguments:
        index {int} -- Zero-based index of window to switch to.
    """
    self.log_info(f"Browser.switchToWindowByIndex: Switching to window at index {index}")
    self.CORE.switch_to.window(self.CORE.window_handles[index])
    return

uncheck(element_tuple, *, wrapper_element_tuple=None)

Uncheck a checkbox if it's not already. For checkboxes which can't be interacted with directly (hidden but toggled via JS detecting a click on a different object), provide a wrapper element in addition for the function to click instead.

Source code in BrowserWrapper/browserwrapper.py
534
535
536
537
538
539
540
541
542
543
544
545
546
547
548
549
550
551
552
553
def uncheck(self, element_tuple, *, wrapper_element_tuple=None):
    """Uncheck a checkbox if it's not already. For checkboxes which can't be interacted with directly (hidden but toggled via JS detecting a click on a different object),
    provide a wrapper element in addition for the function to click instead.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        wrapper_element_tuple {PageObject Element} -- Default is None, tuple representation of element to be used for locating the wrapper, if needed. Wrappers are clicked in
                                                      place of the checkbox element when it is unreachable.
    """
    self.log_info(f"Browser.uncheck: Setting {element_tuple} checkbox to unchecked")
    checkbox = self.CORE.find_element(*self.format_element(element_tuple))
    if checkbox.is_selected():
        if wrapper_element_tuple is not None:
            self.log_info(f"Browser.check: Wrapper element was provided, clicking {wrapper_element_tuple} instead")
            self.click(wrapper_element_tuple)
        else:
            self.click(element_tuple)
    else:
        self.log_info(f"Browser.check: Skipping action as {element_tuple} is already unchecked")
    return

waitForAlertPresent(*, timeout=5)

Wait a configurable period of time for an element to be present.

Returns:

Type Description

Boolean -- True if alert is initially present or becomes present during the wait period, False otherwise

Source code in BrowserWrapper/browserwrapper.py
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
def waitForAlertPresent(self, *, timeout=5):
    """Wait a configurable period of time for an element to be present.

    Arguments:
        timeout {int, defaults to 5} -- Max length of time to wait for the condition

    Returns:
        Boolean -- True if alert is initially present or becomes present during the wait period, False otherwise
    """
    try:
        WebDriverWait(self.CORE, timeout).until(EC.alert_is_present())
        self.log_info(f"Browser.waitForAlertPresent: Alert is present within {timeout} seconds")
        return True
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForAlertPresent: Alert did not become present after {timeout} seconds")
        return False

waitForElementClickable(element_tuple, *, timeout=5)

Wait a configurable period of time for an element to be clickable. Note: An exception will be raised if the element is not present.

Returns:

Type Description

Boolean -- True if element is initially clickable or becomes clickable during the wait period, False otherwise

Source code in BrowserWrapper/browserwrapper.py
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
def waitForElementClickable(self, element_tuple, *, timeout=5):
    """Wait a configurable period of time for an element to be clickable.
    Note: An exception will be raised if the element is not present.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        timeout {int, defaults to 5} -- Max length of time to wait for the condition

    Returns:
        Boolean -- True if element is initially clickable or becomes clickable during the wait period, False otherwise
    """
    try:
        WebDriverWait(self.CORE, timeout).until(EC.element_to_be_clickable(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
        self.log_info(f"Browser.waitForElementClickable: {element_tuple} is clickable within {timeout} seconds")
        return True
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForElementClickable: {element_tuple} did not become clickable after {timeout} seconds")
        return False

waitForElementNotPresent(element_tuple, *, timeout=5)

Wait a configurable period of time for an element to not be present.

Returns:

Type Description

Boolean -- True if element is initially not present or becomes not present during the wait period, False otherwise

Source code in BrowserWrapper/browserwrapper.py
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
def waitForElementNotPresent(self, element_tuple, *, timeout=5):
    """Wait a configurable period of time for an element to not be present.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        timeout {int, defaults to 5} -- Max length of time to wait for the condition

    Returns:
        Boolean -- True if element is initially not present or becomes not present during the wait period, False otherwise
    """
    try:

        self.disable_logging()
        if self.waitForElementNotVisible(element_tuple, timeout=timeout) is False or self.elementIsPresent(element_tuple) is True:
            self.revert_logging()
            raise SeleniumExceptions.TimeoutException()
        self.revert_logging()
        self.log_info(f"Browser.waitForElementNotPresent: {element_tuple} is present within {timeout} seconds")
        return True
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForElementNotPresent: {element_tuple} did not become not present after {timeout} seconds")
        return False

waitForElementNotVisible(element_tuple, *, timeout=5)

Wait a configurable period of time for an element to be invisible. Note: An exception will be raised if the element is not present

Returns:

Type Description

Boolean -- True if element is initially invisible or becomes invisible during the wait period, False otherwise

Source code in BrowserWrapper/browserwrapper.py
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
def waitForElementNotVisible(self, element_tuple, *, timeout=5):
    """Wait a configurable period of time for an element to be invisible.
    Note: An exception will be raised if the element is not present

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        timeout {int, defaults to 5} -- Max length of time to wait for the condition

    Returns:
        Boolean -- True if element is initially invisible or becomes invisible during the wait period, False otherwise
    """
    try:
        WebDriverWait(self.CORE, timeout).until(EC.invisibility_of_element_located(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
        self.log_info(f"Browser.waitForElementNotVisible: {element_tuple} is invisible within {timeout} seconds")
        return True
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForElementNotVisible: {element_tuple} did not become invisible after {timeout} seconds")
        return False

waitForElementPresent(element_tuple, *, timeout=5)

Wait a configurable period of time for an element to be present.

Returns:

Type Description

Boolean -- True if element is initially present or becomes present wait period, False otherwise

Source code in BrowserWrapper/browserwrapper.py
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
def waitForElementPresent(self, element_tuple, *, timeout=5):
    """Wait a configurable period of time for an element to be present.

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        timeout {int, defaults to 5} -- Max length of time to wait for the condition

    Returns:
        Boolean -- True if element is initially present or becomes present wait period, False otherwise
    """
    try:
        WebDriverWait(self.CORE, timeout).until(EC.presence_of_element_located(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
        self.log_info(f"Browser.waitForElementPresent: {element_tuple} is present within {timeout} seconds")
        return True
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForElementPresent: {element_tuple} did not become present after {timeout} seconds")
        return False

waitForElementTextChange(element_tuple, original_text, *, timeout=5)

Wait a configurable period of time for an element's text to change

Source code in BrowserWrapper/browserwrapper.py
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
def waitForElementTextChange(self, element_tuple, original_text, *, timeout=5):
    """Wait a configurable period of time for an element's text to change
    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        original_text {string} -- The original text you want to see change
        timeout {int} -- Max length of time to wait for the condition
    """
    self.waitForElementVisible(element_tuple, timeout=timeout)
    try:
        self.disable_logging()
        WebDriverWait(self, timeout).until(lambda self: self.getText(element_tuple) != original_text)
        self.revert_logging()
        self.log_info(f"Browser.waitForElementTextChange: {element_tuple} text changed from {original_text} within {timeout} seconds")
        return True
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForElementTextChange: {element_tuple} text did not changefrom {original_text} after {timeout} seconds")
        return False

waitForElementVisible(element_tuple, *, timeout=5)

Wait a configurable period of time for an element to be visible. Note: An exception will be raised if the element is not present

Returns:

Type Description

Boolean -- True if element is initially visible or becomes visible during the wait period, False otherwise

Source code in BrowserWrapper/browserwrapper.py
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
def waitForElementVisible(self, element_tuple, *, timeout=5):
    """Wait a configurable period of time for an element to be visible.
    Note: An exception will be raised if the element is not present

    Arguments:
        element_tuple {PageObject Element} -- Tuple representation of element typically defined on PageObjects used for locating the element.
        timeout {int, defaults to 5} -- Max length of time to wait for the condition

    Returns:
        Boolean -- True if element is initially visible or becomes visible during the wait period, False otherwise
    """
    try:
        WebDriverWait(self.CORE, timeout).until(EC.visibility_of_element_located(self.format_element(element_tuple)))  # Don't unpack, use function to parse out first 2 items
        self.log_info(f"Browser.waitForElementVisible: {element_tuple} is visible within {timeout} seconds")
        return True
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForElementVisible: {element_tuple} did not become visible after {timeout} seconds")
        return False

waitForURLToContain(url_portion, *, timeout=5)

Wait a configurable period of time for the current URL to contain a given string.

Source code in BrowserWrapper/browserwrapper.py
333
334
335
336
337
338
339
340
341
342
343
344
345
346
def waitForURLToContain(self, url_portion, *, timeout=5):
    """Wait a configurable period of time for the current URL to contain a given string.

    Arguments:
        url_portion {string} -- The string you want to check that the URL contains
        timeout {int} -- Max length of time to wait for the condition
    """
    try:
        WebDriverWait(self.CORE, timeout).until(lambda self: url_portion in self.current_url)
        self.log_info(f"Browser.waitForURLToContain: {self.CORE.current_url} contains {url_portion} within {timeout} seconds")
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForURLToContain: {self.CORE.current_url} does not contain {url_portion} after {timeout} seconds")
        # We're going to capture the timeout as it doesn't matter - the return statement is the bool
    return url_portion in self.CORE.current_url

waitForURLToEqual(url, *, timeout=5)

Wait a configurable period of time for the current URL to equal a given string.

Source code in BrowserWrapper/browserwrapper.py
348
349
350
351
352
353
354
355
356
357
358
359
360
361
def waitForURLToEqual(self, url, *, timeout=5):
    """Wait a configurable period of time for the current URL to equal a given string.

    Arguments:
        url {string} -- The string you want to check that the URL equals
        timeout {int} -- Max length of time to wait for the condition
    """
    try:
        WebDriverWait(self.CORE, timeout).until(lambda self: url == self.current_url)
        self.log_info(f"Browser.waitForURLToEqual: {self.CORE.current_url} equals {url} within {timeout} seconds")
    except SeleniumExceptions.TimeoutException:
        self.log_warning(f"Browser.waitForURLToEqual: {self.CORE.current_url} does not equal {url} after {timeout} seconds")
        # We're going to capture the timeout as it doesn't matter - the return statement is the bool
    return url in self.CORE.current_url