From 33d09da69ba06830f805903141a1df6e723827b3 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 28 Apr 2017 20:39:32 -0400 Subject: [PATCH 1/2] Add timeout_multiplier option to boost default timeout lengths --- seleniumbase/fixtures/base_case.py | 114 ++++++++++++++++++++++++ seleniumbase/plugins/pytest_plugin.py | 6 ++ seleniumbase/plugins/selenium_plugin.py | 9 ++ 3 files changed, 129 insertions(+) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 13571272..207ceb78 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -21,6 +21,7 @@ Code becomes greatly simplified and easier to maintain. import getpass import json import logging +import math import os import pytest import sys @@ -81,6 +82,8 @@ class BaseCase(unittest.TestCase): def click(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) if page_utils.is_xpath_selector(selector): by = By.XPATH element = page_actions.wait_for_element_visible( @@ -105,6 +108,8 @@ class BaseCase(unittest.TestCase): def double_click(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) if page_utils.is_xpath_selector(selector): by = By.XPATH element = page_actions.wait_for_element_visible( @@ -137,6 +142,8 @@ class BaseCase(unittest.TestCase): timeout=settings.SMALL_TIMEOUT, spacing=0): """ This method clicks on a list of elements in succession. 'spacing' is the amount of time to wait between clicks. (sec) """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) for selector in selectors_list: self.click(selector, by=by, timeout=timeout) if spacing > 0: @@ -145,6 +152,8 @@ class BaseCase(unittest.TestCase): def click_link_text(self, link_text, timeout=settings.SMALL_TIMEOUT): """ This method clicks link text on a page """ # If using phantomjs, might need to extract and open the link directly + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) if self.browser == 'phantomjs': if self.is_link_text_visible(link_text): element = self.wait_for_link_text_visible(link_text) @@ -195,6 +204,8 @@ class BaseCase(unittest.TestCase): timeout=settings.SMALL_TIMEOUT): """ This method clicks the partial link text on a page. """ # If using phantomjs, might need to extract and open the link directly + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) if self.browser == 'phantomjs': if self.is_partial_link_text_visible(partial_link_text): element = self.wait_for_partial_link_text(partial_link_text) @@ -247,6 +258,8 @@ class BaseCase(unittest.TestCase): def get_text(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) self.wait_for_ready_state_complete() time.sleep(0.01) element = page_actions.wait_for_element_visible( @@ -263,6 +276,8 @@ class BaseCase(unittest.TestCase): def get_attribute(self, selector, attribute, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) self.wait_for_ready_state_complete() time.sleep(0.01) element = page_actions.wait_for_element_present( @@ -302,6 +317,8 @@ class BaseCase(unittest.TestCase): def get_image_url(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): """ Extracts the URL from an image element on the page. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) return self.get_attribute(selector, attribute='src', by=by, timeout=timeout) @@ -309,6 +326,8 @@ class BaseCase(unittest.TestCase): timeout=settings.SMALL_TIMEOUT): """ The more-reliable version of driver.send_keys() Similar to update_text(), but won't clear the text field first. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) element = self.wait_for_element_visible( selector, by=by, timeout=timeout) self._demo_mode_highlight_if_active(selector, by) @@ -344,6 +363,8 @@ class BaseCase(unittest.TestCase): def send_keys(self, selector, new_value, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): """ Same as add_text() -> more reliable, but less name confusion. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) self.add_text(selector, new_value, by=by, timeout=timeout) def update_text_value(self, selector, new_value, by=By.CSS_SELECTOR, @@ -356,6 +377,8 @@ class BaseCase(unittest.TestCase): timeout - how long to wait for the selector to be visible retry - if True, use jquery if the selenium text update fails """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) element = self.wait_for_element_visible( selector, by=by, timeout=timeout) self._demo_mode_highlight_if_active(selector, by) @@ -408,6 +431,8 @@ class BaseCase(unittest.TestCase): """ The shorter version of update_text_value(), which clears existing text and adds new text into the text field. We want to keep the old version for backward compatibility. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) self.update_text_value(selector, new_value, by=by, timeout=timeout, retry=retry) @@ -449,6 +474,8 @@ class BaseCase(unittest.TestCase): return self.driver.execute_script(script) def execute_async_script(self, script, timeout=settings.EXTREME_TIMEOUT): + if self.timeout_multiplier and timeout == settings.EXTREME_TIMEOUT: + timeout = self._get_new_timeout(timeout) self.driver.set_script_timeout(timeout) return self.driver.execute_async_script(script) @@ -564,6 +591,8 @@ class BaseCase(unittest.TestCase): def scroll_to(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): ''' Fast scroll to destination ''' + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) element = self.wait_for_element_visible( selector, by=by, timeout=timeout) try: @@ -578,6 +607,8 @@ class BaseCase(unittest.TestCase): def slow_scroll_to(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): ''' Slow motion scroll to destination ''' + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) element = self.wait_for_element_visible( selector, by=by, timeout=timeout) self._slow_scroll_to_element(element) @@ -664,6 +695,8 @@ class BaseCase(unittest.TestCase): def set_value(self, selector, new_value, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): """ This method uses jQuery to update a text field. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) if page_utils.is_xpath_selector(selector): by = By.XPATH selector = self.convert_to_css_selector(selector, by=by) @@ -691,6 +724,8 @@ class BaseCase(unittest.TestCase): If the new_value string ends with the newline character, WebDriver will finish the call, which simulates pressing {Enter/Return} after the text is entered. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) if page_utils.is_xpath_selector(selector): by = By.XPATH element = self.wait_for_element_visible( @@ -720,6 +755,8 @@ class BaseCase(unittest.TestCase): timeout=settings.SMALL_TIMEOUT): """ The shorter version of jquery_update_text_value() (The longer version remains for backwards compatibility.) """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) self.jquery_update_text_value( selector, new_value, by=by, timeout=timeout) @@ -734,6 +771,8 @@ class BaseCase(unittest.TestCase): def hover_and_click(self, hover_selector, click_selector, hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) if page_utils.is_xpath_selector(hover_selector): hover_by = By.XPATH if page_utils.is_xpath_selector(click_selector): @@ -757,6 +796,8 @@ class BaseCase(unittest.TestCase): dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): """ Picks an HTML option by option index. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self._get_new_timeout(timeout) self._pick_select_option(dropdown_selector, option, dropdown_by=dropdown_by, option_by="index", timeout=timeout) @@ -773,6 +816,8 @@ class BaseCase(unittest.TestCase): dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): """ Picks an HTML