From d39501e5ba643036b651d5ea26f1bde97358a5a7 Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 3 Dec 2021 11:33:02 -0500 Subject: [PATCH 1/2] Refactor wait_for_ready_state_complete() and related code --- seleniumbase/fixtures/base_case.py | 59 ++++++++++++++++++++++-------- seleniumbase/fixtures/js_utils.py | 5 +++ 2 files changed, 49 insertions(+), 15 deletions(-) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index 403466dac24..70171824bff 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -358,6 +358,11 @@ def click( self.__switch_to_newest_window_if_not_blank() if settings.WAIT_FOR_RSC_ON_CLICKS: self.wait_for_ready_state_complete() + else: + # A smaller subset of self.wait_for_ready_state_complete() + self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT) + if self.driver.current_url != pre_action_url: + self.__ad_block_as_needed() if self.demo_mode: if self.driver.current_url != pre_action_url: self.__demo_mode_pause_if_active() @@ -437,6 +442,11 @@ def double_click(self, selector, by=By.CSS_SELECTOR, timeout=None): self.safe_execute_script(double_click_script) if settings.WAIT_FOR_RSC_ON_CLICKS: self.wait_for_ready_state_complete() + else: + # A smaller subset of self.wait_for_ready_state_complete() + self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT) + if self.driver.current_url != pre_action_url: + self.__ad_block_as_needed() if self.demo_mode: if self.driver.current_url != pre_action_url: self.__demo_mode_pause_if_active() @@ -1064,7 +1074,7 @@ def click_link_text(self, link_text, timeout=None): ) ): self.__switch_to_newest_window_if_not_blank() - if settings.WAIT_FOR_RSC_ON_CLICKS: + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: self.wait_for_ready_state_complete() if self.demo_mode: if self.driver.current_url != pre_action_url: @@ -1196,7 +1206,7 @@ def click_partial_link_text(self, partial_link_text, timeout=None): ) ): self.__switch_to_newest_window_if_not_blank() - if settings.WAIT_FOR_RSC_ON_CLICKS: + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: self.wait_for_ready_state_complete() if self.demo_mode: if self.driver.current_url != pre_action_url: @@ -1641,6 +1651,11 @@ def click_active_element(self): self.__switch_to_newest_window_if_not_blank() if settings.WAIT_FOR_RSC_ON_CLICKS: self.wait_for_ready_state_complete() + else: + # A smaller subset of self.wait_for_ready_state_complete() + self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT) + if self.driver.current_url != pre_action_url: + self.__ad_block_as_needed() if self.demo_mode: if self.driver.current_url != pre_action_url: self.__demo_mode_pause_if_active() @@ -2142,6 +2157,9 @@ def __select_option( self.__switch_to_newest_window_if_not_blank() if settings.WAIT_FOR_RSC_ON_CLICKS: self.wait_for_ready_state_complete() + else: + # A smaller subset of self.wait_for_ready_state_complete() + self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT) if self.demo_mode: if self.driver.current_url != pre_action_url: self.__demo_mode_pause_if_active() @@ -3112,35 +3130,46 @@ def delete_saved_cookies(self, name="cookies.txt"): if cookies_file_path.endswith(".txt"): os.remove(cookies_file_path) + def __ad_block_as_needed(self): + """ This is an internal method for handling ad-blocking. + Use "pytest --ad-block" to enable this during tests. + When not Chromium or in headless mode, use the hack. """ + if self.ad_block_on and (self.headless or not self.is_chromium()): + # (Chromium browsers in headed mode use the extension instead) + current_url = self.get_current_url() + if not current_url == self.__last_page_load_url: + if page_actions.is_element_present( + self.driver, "iframe", By.CSS_SELECTOR + ): + self.ad_block() + self.__last_page_load_url = current_url + def wait_for_ready_state_complete(self, timeout=None): + """ Waits for the "readyState" of the page to be "complete". + Returns True when the method completes. """ self.__check_scope() self.__check_browser() if not timeout: timeout = settings.EXTREME_TIMEOUT if self.timeout_multiplier and timeout == settings.EXTREME_TIMEOUT: timeout = self.__get_new_timeout(timeout) - is_ready = js_utils.wait_for_ready_state_complete(self.driver, timeout) + js_utils.wait_for_ready_state_complete(self.driver, timeout) self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT) if self.js_checking_on: self.assert_no_js_errors() - if self.ad_block_on and (self.headless or not self.is_chromium()): - # For Chromium browsers in headed mode, the extension is used - current_url = self.get_current_url() - if not current_url == self.__last_page_load_url: - if page_actions.is_element_present( - self.driver, "iframe", By.CSS_SELECTOR - ): - self.ad_block() - self.__last_page_load_url = current_url - return is_ready + self.__ad_block_as_needed() + return True def wait_for_angularjs(self, timeout=None, **kwargs): + """ Waits for Angular components of the page to finish loading. + Returns True when the method completes. """ self.__check_scope() if not timeout: - timeout = settings.LARGE_TIMEOUT - if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: + timeout = settings.MINI_TIMEOUT + if self.timeout_multiplier and timeout == settings.MINI_TIMEOUT: timeout = self.__get_new_timeout(timeout) js_utils.wait_for_angularjs(self.driver, timeout, **kwargs) + return True def sleep(self, seconds): self.__check_scope() diff --git a/seleniumbase/fixtures/js_utils.py b/seleniumbase/fixtures/js_utils.py index 41ed1deb958..f1878cadc3f 100755 --- a/seleniumbase/fixtures/js_utils.py +++ b/seleniumbase/fixtures/js_utils.py @@ -80,6 +80,11 @@ def wait_for_angularjs(driver, timeout=settings.LARGE_TIMEOUT, **kwargs): "handler": handler, "suffix": suffix, } + try: + # This closes any pop-up alerts (otherwise the next part fails) + driver.execute_script("") + except Exception: + pass try: execute_async_script(driver, script, timeout=timeout) except Exception: From 56d43d8aa3894b6533e9b3386be460b1e502437a Mon Sep 17 00:00:00 2001 From: Michael Mintz Date: Fri, 3 Dec 2021 11:33:23 -0500 Subject: [PATCH 2/2] Version 2.2.7 --- seleniumbase/__version__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/seleniumbase/__version__.py b/seleniumbase/__version__.py index 2e4dbc7eecd..b0248ca764d 100755 --- a/seleniumbase/__version__.py +++ b/seleniumbase/__version__.py @@ -1,2 +1,2 @@ # seleniumbase package -__version__ = "2.2.6" +__version__ = "2.2.7"