diff --git a/help_docs/method_summary.md b/help_docs/method_summary.md index 3d98dcf0..a4714f5b 100755 --- a/help_docs/method_summary.md +++ b/help_docs/method_summary.md @@ -21,33 +21,15 @@ self.double_click(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) self.click_chain(selectors_list, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT, spacing=0) -self.is_link_text_present(link_text) +self.type(selector, text, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT, retry=False) -self.is_partial_link_text_present(link_text) +self.update_text(selector, new_value, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT, retry=False) -self.get_link_attribute(link_text, attribute, hard_fail) +self.add_text(selector, text, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) -self.get_partial_link_text_attribute(link_text, attribute, hard_fail) +self.send_keys(selector, text, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) -self.wait_for_link_text_present(link_text, timeout=settings.SMALL_TIMEOUT) - -self.wait_for_partial_link_text_present(link_text, timeout=settings.SMALL_TIMEOUT) - -self.click_link_text(link_text, timeout=settings.SMALL_TIMEOUT) - -self.click_link(link_text, timeout=settings.SMALL_TIMEOUT) - -self.click_partial_link_text(partial_link_text, timeout=settings.SMALL_TIMEOUT) - -self.get_text(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -self.get_attribute(selector, attribute, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -self.set_attribute(selector, attribute, value, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -self.remove_attribute(selector, attribute, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -self.get_property_value(selector, property, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) +self.submit(selector, by=By.CSS_SELECTOR) self.refresh_page() @@ -65,25 +47,43 @@ self.go_back() self.go_forward() -self.get_image_url(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -self.add_text(selector, text, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -self.send_keys(selector, text, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -self.update_text(selector, new_value, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT, retry=False) - -self.type(selector, text, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT, retry=False) - self.is_element_present(selector, by=By.CSS_SELECTOR) self.is_element_visible(selector, by=By.CSS_SELECTOR) +self.is_text_visible(text, selector="html", by=By.CSS_SELECTOR) + self.is_link_text_visible(link_text) self.is_partial_link_text_visible(partial_link_text) -self.is_text_visible(text, selector="html", by=By.CSS_SELECTOR) +self.is_link_text_present(link_text) + +self.is_partial_link_text_present(link_text) + +self.get_link_attribute(link_text, attribute, hard_fail) + +self.get_link_text_attribute(link_text, attribute, hard_fail) + +self.get_partial_link_text_attribute(link_text, attribute, hard_fail) + +self.click_link_text(link_text, timeout=settings.SMALL_TIMEOUT) + +self.click_link(link_text, timeout=settings.SMALL_TIMEOUT) + +self.click_partial_link_text(partial_link_text, timeout=settings.SMALL_TIMEOUT) + +self.get_text(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.get_attribute(selector, attribute, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.set_attribute(selector, attribute, value, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.remove_attribute(selector, attribute, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.get_property_value(selector, property, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.get_image_url(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) self.find_elements(selector, by=By.CSS_SELECTOR, limit=0) @@ -91,56 +91,64 @@ self.find_visible_elements(selector, by=By.CSS_SELECTOR, limit=0) self.click_visible_elements(selector, by=By.CSS_SELECTOR, limit=0) +self.click_if_visible(selector, by=By.CSS_SELECTOR) + self.is_element_in_an_iframe(selector, by=By.CSS_SELECTOR) self.switch_to_frame_of_element(selector, by=By.CSS_SELECTOR) +self.hover_on_element(selector, by=By.CSS_SELECTOR) + +self.hover_and_click(hover_selector, click_selector, + hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.hover_and_double_click(hover_selector, click_selector, + hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.select_option_by_text(dropdown_selector, option, + dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.select_option_by_index(dropdown_selector, option, + dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + +self.select_option_by_value(dropdown_selector, option, + dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + self.execute_script(script) +self.execute_async_script(script, timeout=settings.EXTREME_TIMEOUT) + +self.safe_execute_script(script) + self.set_window_size(width, height) self.maximize_window() -self.add_css_link(css_link) +self.switch_to_frame(frame, timeout=settings.SMALL_TIMEOUT) -self.add_js_link(js_link) +self.switch_to_default_content() -self.add_css_style(css_style) +self.open_new_window(switch_to=True) -self.add_js_code_from_link(js_link) +self.switch_to_window(window, timeout=settings.SMALL_TIMEOUT) -self.add_meta_tag(http_equiv=None, content=None) +self.switch_to_default_window() + +self.get_new_driver(browser=None, headless=None, servername=None, port=None, + proxy=None, switch_to=True, cap_file=None) + +self.switch_to_driver(driver) + +self.switch_to_default_driver() + +self.save_screenshot(name, folder=None) + +self.wait_for_ready_state_complete(timeout=settings.EXTREME_TIMEOUT) + +self.wait_for_angularjs(timeout=settings.LARGE_TIMEOUT) self.activate_jquery() -self.create_tour(name=None, theme=None) - -self.create_shepherd_tour(name=None, theme=None) - -self.create_bootstrap_tour(name=None) - -self.create_hopscotch_tour(name=None) - -self.create_introjs_tour(name=None) - -self.add_tour_step(message, selector=None, name=None, title=None, theme=None, alignment=None) - -self.play_tour(name=None) - -self.export_tour(name=None, filename="my_tour.js", url=None) - -self.activate_jquery_confirm() - -self.activate_messenger() - -self.post_message(message, duration=None, pause=True, style="info") - -self.post_success_message(message, duration=None, pause=True) - -self.post_error_message(message, duration=None, pause=True) - -self.set_messenger_theme(theme="default", location="default", max_messages="default") - self.bring_to_front(selector, by=By.CSS_SELECTOR) self.highlight(selector, by=By.CSS_SELECTOR, loops=4, scroll=True) @@ -155,8 +163,6 @@ self.js_click(selector, by=By.CSS_SELECTOR) self.jquery_click(selector, by=By.CSS_SELECTOR) -self.submit(selector, by=By.CSS_SELECTOR) - self.hide_element(selector, by=By.CSS_SELECTOR) self.hide_elements(selector, by=By.CSS_SELECTOR) @@ -185,8 +191,6 @@ self.assert_no_404_errors(multithreaded=True) self.print_unique_links_with_status_codes() -self.safe_execute_script(script) - self.create_folder(folder) self.choose_file(selector, file_path, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) @@ -231,22 +235,47 @@ self.js_update_text(selector, new_value, by=By.CSS_SELECTOR, timeout=settings.LA self.jquery_update_text(selector, new_value, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) -self.hover_on_element(selector, by=By.CSS_SELECTOR) +######## -self.hover_and_click(hover_selector, click_selector, - hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) +self.add_css_link(css_link) -self.hover_and_double_click(hover_selector, click_selector, - hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) +self.add_js_link(js_link) -self.select_option_by_text(dropdown_selector, option, - dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) +self.add_css_style(css_style) -self.select_option_by_index(dropdown_selector, option, - dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) +self.add_js_code_from_link(js_link) -self.select_option_by_value(dropdown_selector, option, - dropdown_by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) +self.add_meta_tag(http_equiv=None, content=None) + +######## + +self.create_tour(name=None, theme=None) + +self.create_shepherd_tour(name=None, theme=None) + +self.create_bootstrap_tour(name=None) + +self.create_hopscotch_tour(name=None) + +self.create_introjs_tour(name=None) + +self.add_tour_step(message, selector=None, name=None, title=None, theme=None, alignment=None) + +self.play_tour(name=None) + +self.export_tour(name=None, filename="my_tour.js", url=None) + +self.activate_jquery_confirm() + +self.activate_messenger() + +self.post_message(message, duration=None, pause=True, style="info") + +self.post_success_message(message, duration=None, pause=True) + +self.post_error_message(message, duration=None, pause=True) + +self.set_messenger_theme(theme="default", location="default", max_messages="default") ######## @@ -262,16 +291,14 @@ self.generate_traffic_chain(pages, loops=1) self.wait_for_element_present(selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT) -self.get_element(selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT) - -self.assert_element_present(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) - -######## - self.wait_for_element_visible(selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT) self.wait_for_element(selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT) +self.get_element(selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT) + +self.assert_element_present(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) + self.find_element(selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT) self.assert_element(selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT) @@ -296,6 +323,10 @@ self.assert_exact_text(text, selector="html", by=By.CSS_SELECTOR, timeout=settin ######## +self.wait_for_link_text_present(link_text, timeout=settings.SMALL_TIMEOUT) + +self.wait_for_partial_link_text_present(link_text, timeout=settings.SMALL_TIMEOUT) + self.wait_for_link_text_visible(link_text, timeout=settings.LARGE_TIMEOUT) self.wait_for_link_text(link_text, timeout=settings.LARGE_TIMEOUT) @@ -326,35 +357,16 @@ self.assert_element_not_visible(selector, by=By.CSS_SELECTOR, timeout=settings.S ######## -self.wait_for_ready_state_complete(timeout=settings.EXTREME_TIMEOUT) - self.wait_for_and_accept_alert(timeout=settings.LARGE_TIMEOUT) self.wait_for_and_dismiss_alert(timeout=settings.LARGE_TIMEOUT) self.wait_for_and_switch_to_alert(timeout=settings.LARGE_TIMEOUT) -self.switch_to_frame(frame, timeout=settings.SMALL_TIMEOUT) - -self.switch_to_default_content() - -self.open_new_window(switch_to=True) - -self.switch_to_window(window, timeout=settings.SMALL_TIMEOUT) - -self.switch_to_default_window() +######## self.check_window(name="default", level=0, baseline=False) -self.save_screenshot(name, folder=None) - -self.get_new_driver(browser=None, headless=None, servername=None, port=None, - proxy=None, switch_to=True, cap_file=None) - -self.switch_to_driver(driver) - -self.switch_to_default_driver() - ######## self.delayed_assert_element(selector, by=By.CSS_SELECTOR, timeout=settings.MINI_TIMEOUT) diff --git a/seleniumbase/fixtures/base_case.py b/seleniumbase/fixtures/base_case.py index b6e4bbb0..edf2e8ce 100755 --- a/seleniumbase/fixtures/base_case.py +++ b/seleniumbase/fixtures/base_case.py @@ -222,6 +222,215 @@ class BaseCase(unittest.TestCase): if spacing > 0: time.sleep(spacing) + def type(self, selector, text, by=By.CSS_SELECTOR, + timeout=settings.LARGE_TIMEOUT, retry=False): + """ The short version of update_text(), which clears existing text + and adds new text into the text field. + We want to keep the other version for backward compatibility. """ + if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: + timeout = self.__get_new_timeout(timeout) + if page_utils.is_xpath_selector(selector): + by = By.XPATH + self.update_text(selector, text, by=by, timeout=timeout, retry=retry) + + def update_text(self, selector, new_value, by=By.CSS_SELECTOR, + timeout=settings.LARGE_TIMEOUT, retry=False): + """ This method updates an element's text field with new text. + Has two parts: + 1. Clears the text field. + 2. Types in new text into the text field. + @Params + selector - the selector of the text field + new_value - the new value to type into the text field + by - the type of selector to search by (Default: CSS Selector) + timeout - how long to wait for the selector to be visible + retry - if True, use JS if the Selenium text update fails + """ + if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: + timeout = self.__get_new_timeout(timeout) + if page_utils.is_xpath_selector(selector): + by = By.XPATH + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + self.__demo_mode_highlight_if_active(selector, by) + if not self.demo_mode: + self.__scroll_to_element(element) + try: + element.clear() + except (StaleElementReferenceException, ENI_Exception): + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + element.clear() + except Exception: + pass # Clearing the text field first isn't critical + self.__demo_mode_pause_if_active(tiny=True) + pre_action_url = self.driver.current_url + try: + if not new_value.endswith('\n'): + element.send_keys(new_value) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() + else: + new_value = new_value[:-1] + element.send_keys(new_value) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() + except (StaleElementReferenceException, ENI_Exception): + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + element.clear() + if not new_value.endswith('\n'): + element.send_keys(new_value) + else: + new_value = new_value[:-1] + element.send_keys(new_value) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() + except Exception: + exc_message = self.__get_improved_exception_message() + raise Exception(exc_message) + if (retry and element.get_attribute('value') != new_value and ( + not new_value.endswith('\n'))): + logging.debug('update_text() is falling back to JavaScript!') + self.set_value(selector, new_value, by=by) + if self.demo_mode: + if self.driver.current_url != pre_action_url: + self.__demo_mode_pause_if_active() + else: + self.__demo_mode_pause_if_active(tiny=True) + + def add_text(self, selector, text, by=By.CSS_SELECTOR, + timeout=settings.LARGE_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.LARGE_TIMEOUT: + timeout = self.__get_new_timeout(timeout) + if page_utils.is_xpath_selector(selector): + by = By.XPATH + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + self.__demo_mode_highlight_if_active(selector, by) + if not self.demo_mode: + self.__scroll_to_element(element) + pre_action_url = self.driver.current_url + try: + if not text.endswith('\n'): + element.send_keys(text) + else: + text = text[:-1] + element.send_keys(text) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() + except (StaleElementReferenceException, ENI_Exception): + self.wait_for_ready_state_complete() + time.sleep(0.06) + element = self.wait_for_element_visible( + selector, by=by, timeout=timeout) + if not text.endswith('\n'): + element.send_keys(text) + else: + text = text[:-1] + element.send_keys(text) + element.send_keys(Keys.RETURN) + if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: + self.wait_for_ready_state_complete() + except Exception: + exc_message = self.__get_improved_exception_message() + raise Exception(exc_message) + if self.demo_mode: + if self.driver.current_url != pre_action_url: + self.__demo_mode_pause_if_active() + else: + self.__demo_mode_pause_if_active(tiny=True) + + def send_keys(self, selector, text, by=By.CSS_SELECTOR, + timeout=settings.LARGE_TIMEOUT): + """ Same as add_text() """ + if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: + timeout = self.__get_new_timeout(timeout) + if page_utils.is_xpath_selector(selector): + by = By.XPATH + self.add_text(selector, text, by=by, timeout=timeout) + + def submit(self, selector, by=By.CSS_SELECTOR): + """ Alternative to self.driver.find_element_by_*(SELECTOR).submit() """ + if page_utils.is_xpath_selector(selector): + by = By.XPATH + element = self.wait_for_element_visible( + selector, by=by, timeout=settings.SMALL_TIMEOUT) + element.submit() + self.__demo_mode_pause_if_active() + + def refresh_page(self): + self.__last_page_load_url = None + self.driver.refresh() + self.wait_for_ready_state_complete() + + def refresh(self): + """ The shorter version of self.refresh_page() """ + self.refresh_page() + + def get_current_url(self): + return self.driver.current_url + + def get_page_source(self): + self.wait_for_ready_state_complete() + return self.driver.page_source + + def get_page_title(self): + self.wait_for_ready_state_complete() + self.wait_for_element_present("title", timeout=settings.MINI_TIMEOUT) + return self.driver.title + + def get_title(self): + """ The shorter version of self.get_page_title() """ + self.wait_for_ready_state_complete() + self.wait_for_element_present("title", timeout=settings.MINI_TIMEOUT) + return self.driver.title + + def go_back(self): + self.__last_page_load_url = None + self.driver.back() + self.wait_for_ready_state_complete() + + def go_forward(self): + self.__last_page_load_url = None + self.driver.forward() + self.wait_for_ready_state_complete() + + def is_element_present(self, selector, by=By.CSS_SELECTOR): + selector, by = self.__recalculate_selector(selector, by) + return page_actions.is_element_present(self.driver, selector, by) + + def is_element_visible(self, selector, by=By.CSS_SELECTOR): + selector, by = self.__recalculate_selector(selector, by) + return page_actions.is_element_visible(self.driver, selector, by) + + def is_text_visible(self, text, selector="html", by=By.CSS_SELECTOR): + self.wait_for_ready_state_complete() + time.sleep(0.01) + selector, by = self.__recalculate_selector(selector, by) + return page_actions.is_text_visible(self.driver, text, selector, by) + + def is_link_text_visible(self, link_text): + self.wait_for_ready_state_complete() + time.sleep(0.01) + return page_actions.is_element_visible(self.driver, link_text, + by=By.LINK_TEXT) + + def is_partial_link_text_visible(self, partial_link_text): + self.wait_for_ready_state_complete() + time.sleep(0.01) + return page_actions.is_element_visible(self.driver, partial_link_text, + by=By.PARTIAL_LINK_TEXT) + def is_link_text_present(self, link_text): """ Returns True if the link text appears in the HTML of the page. The element doesn't need to be visible, @@ -266,6 +475,13 @@ class BaseCase(unittest.TestCase): else: return None + def get_link_text_attribute(self, link_text, attribute, hard_fail=True): + """ Same as self.get_link_attribute() + Finds a link by link text and then returns the attribute's value. + If the link text or attribute cannot be found, an exception will + get raised if hard_fail is True (otherwise None is returned). """ + return self.get_link_attribute(link_text, attribute, hard_fail) + def get_partial_link_text_attribute(self, link_text, attribute, hard_fail=True): """ Finds a link by partial link text and then returns the attribute's @@ -292,44 +508,6 @@ class BaseCase(unittest.TestCase): else: return None - def wait_for_link_text_present(self, link_text, - timeout=settings.SMALL_TIMEOUT): - start_ms = time.time() * 1000.0 - stop_ms = start_ms + (timeout * 1000.0) - for x in range(int(timeout * 5)): - try: - if not self.is_link_text_present(link_text): - raise Exception( - "Link text {%s} was not found!" % link_text) - return - except Exception: - now_ms = time.time() * 1000.0 - if now_ms >= stop_ms: - break - time.sleep(0.2) - raise Exception( - "Link text {%s} was not present after %s seconds!" % ( - link_text, timeout)) - - def wait_for_partial_link_text_present(self, link_text, - timeout=settings.SMALL_TIMEOUT): - start_ms = time.time() * 1000.0 - stop_ms = start_ms + (timeout * 1000.0) - for x in range(int(timeout * 5)): - try: - if not self.is_partial_link_text_present(link_text): - raise Exception( - "Partial Link text {%s} was not found!" % link_text) - return - except Exception: - now_ms = time.time() * 1000.0 - if now_ms >= stop_ms: - break - time.sleep(0.2) - raise Exception( - "Partial Link text {%s} was not present after %s seconds!" % ( - link_text, timeout)) - 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 @@ -627,41 +805,6 @@ class BaseCase(unittest.TestCase): else: return "" # Return an empty string if the property doesn't exist - def refresh_page(self): - self.__last_page_load_url = None - self.driver.refresh() - self.wait_for_ready_state_complete() - - def refresh(self): - """ The shorter version of self.refresh_page() """ - self.refresh_page() - - def get_current_url(self): - return self.driver.current_url - - def get_page_source(self): - self.wait_for_ready_state_complete() - return self.driver.page_source - - def get_page_title(self): - self.wait_for_ready_state_complete() - return self.driver.title - - def get_title(self): - """ The shorter version of self.get_page_title() """ - self.wait_for_ready_state_complete() - return self.driver.title - - def go_back(self): - self.__last_page_load_url = None - self.driver.back() - self.wait_for_ready_state_complete() - - def go_forward(self): - self.__last_page_load_url = None - self.driver.forward() - self.wait_for_ready_state_complete() - def get_image_url(self, selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT): """ Extracts the URL from an image element on the page. """ @@ -670,169 +813,6 @@ class BaseCase(unittest.TestCase): return self.get_attribute(selector, attribute='src', by=by, timeout=timeout) - def add_text(self, selector, text, by=By.CSS_SELECTOR, - timeout=settings.LARGE_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.LARGE_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - if page_utils.is_xpath_selector(selector): - by = By.XPATH - element = self.wait_for_element_visible( - selector, by=by, timeout=timeout) - self.__demo_mode_highlight_if_active(selector, by) - if not self.demo_mode: - self.__scroll_to_element(element) - pre_action_url = self.driver.current_url - try: - if not text.endswith('\n'): - element.send_keys(text) - else: - text = text[:-1] - element.send_keys(text) - element.send_keys(Keys.RETURN) - if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: - self.wait_for_ready_state_complete() - except (StaleElementReferenceException, ENI_Exception): - self.wait_for_ready_state_complete() - time.sleep(0.06) - element = self.wait_for_element_visible( - selector, by=by, timeout=timeout) - if not text.endswith('\n'): - element.send_keys(text) - else: - text = text[:-1] - element.send_keys(text) - element.send_keys(Keys.RETURN) - if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: - self.wait_for_ready_state_complete() - except Exception: - exc_message = self.__get_improved_exception_message() - raise Exception(exc_message) - if self.demo_mode: - if self.driver.current_url != pre_action_url: - self.__demo_mode_pause_if_active() - else: - self.__demo_mode_pause_if_active(tiny=True) - - def send_keys(self, selector, text, by=By.CSS_SELECTOR, - timeout=settings.LARGE_TIMEOUT): - """ Same as add_text() -> more reliable, but less name confusion. """ - if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - if page_utils.is_xpath_selector(selector): - by = By.XPATH - self.add_text(selector, text, by=by, timeout=timeout) - - def update_text(self, selector, new_value, by=By.CSS_SELECTOR, - timeout=settings.LARGE_TIMEOUT, retry=False): - """ This method updates an element's text field with new text. - Has two parts: - 1. Clears the text field. - 2. Types in new text into the text field. - @Params - selector - the selector of the text field - new_value - the new value to type into the text field - by - the type of selector to search by (Default: CSS Selector) - timeout - how long to wait for the selector to be visible - retry - if True, use JS if the Selenium text update fails - """ - if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - if page_utils.is_xpath_selector(selector): - by = By.XPATH - element = self.wait_for_element_visible( - selector, by=by, timeout=timeout) - self.__demo_mode_highlight_if_active(selector, by) - if not self.demo_mode: - self.__scroll_to_element(element) - try: - element.clear() - except (StaleElementReferenceException, ENI_Exception): - self.wait_for_ready_state_complete() - time.sleep(0.06) - element = self.wait_for_element_visible( - selector, by=by, timeout=timeout) - element.clear() - except Exception: - pass # Clearing the text field first isn't critical - self.__demo_mode_pause_if_active(tiny=True) - pre_action_url = self.driver.current_url - try: - if not new_value.endswith('\n'): - element.send_keys(new_value) - if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: - self.wait_for_ready_state_complete() - else: - new_value = new_value[:-1] - element.send_keys(new_value) - element.send_keys(Keys.RETURN) - if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: - self.wait_for_ready_state_complete() - except (StaleElementReferenceException, ENI_Exception): - self.wait_for_ready_state_complete() - time.sleep(0.06) - element = self.wait_for_element_visible( - selector, by=by, timeout=timeout) - element.clear() - if not new_value.endswith('\n'): - element.send_keys(new_value) - else: - new_value = new_value[:-1] - element.send_keys(new_value) - element.send_keys(Keys.RETURN) - if settings.WAIT_FOR_RSC_ON_PAGE_LOADS: - self.wait_for_ready_state_complete() - except Exception: - exc_message = self.__get_improved_exception_message() - raise Exception(exc_message) - if (retry and element.get_attribute('value') != new_value and ( - not new_value.endswith('\n'))): - logging.debug('update_text() is falling back to JavaScript!') - self.set_value(selector, new_value, by=by) - if self.demo_mode: - if self.driver.current_url != pre_action_url: - self.__demo_mode_pause_if_active() - else: - self.__demo_mode_pause_if_active(tiny=True) - - def type(self, selector, text, by=By.CSS_SELECTOR, - timeout=settings.LARGE_TIMEOUT, retry=False): - """ The short version of update_text(), 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.LARGE_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - if page_utils.is_xpath_selector(selector): - by = By.XPATH - self.update_text(selector, text, by=by, timeout=timeout, retry=retry) - - def is_element_present(self, selector, by=By.CSS_SELECTOR): - selector, by = self.__recalculate_selector(selector, by) - return page_actions.is_element_present(self.driver, selector, by) - - def is_element_visible(self, selector, by=By.CSS_SELECTOR): - selector, by = self.__recalculate_selector(selector, by) - return page_actions.is_element_visible(self.driver, selector, by) - - def is_link_text_visible(self, link_text): - self.wait_for_ready_state_complete() - time.sleep(0.01) - return page_actions.is_element_visible(self.driver, link_text, - by=By.LINK_TEXT) - - def is_partial_link_text_visible(self, partial_link_text): - self.wait_for_ready_state_complete() - time.sleep(0.01) - return page_actions.is_element_visible(self.driver, partial_link_text, - by=By.PARTIAL_LINK_TEXT) - - def is_text_visible(self, text, selector="html", by=By.CSS_SELECTOR): - self.wait_for_ready_state_complete() - time.sleep(0.01) - selector, by = self.__recalculate_selector(selector, by) - return page_actions.is_text_visible(self.driver, text, selector, by) - def find_elements(self, selector, by=By.CSS_SELECTOR, limit=0): """ Returns a list of matching WebElements. If "limit" is set and > 0, will only return that many elements. """ @@ -889,6 +869,14 @@ class BaseCase(unittest.TestCase): except (StaleElementReferenceException, ENI_Exception): return # Probably on new page / Elements are all stale + def click_if_visible(self, selector, by=By.CSS_SELECTOR): + """ If the page selector exists and is visible, clicks on the element. + This method only clicks on the first matching element found. + (Use click_visible_elements() to click all matching elements.) """ + self.wait_for_ready_state_complete() + if self.is_element_visible(selector, by=by): + self.click(selector, by=by) + def is_element_in_an_iframe(self, selector, by=By.CSS_SELECTOR): """ Returns True if the selector's element is located in an iframe. Otherwise returns False. """ @@ -936,12 +924,169 @@ class BaseCase(unittest.TestCase): self.switch_to_default_content() return None + def hover_on_element(self, selector, by=By.CSS_SELECTOR): + selector, by = self.__recalculate_selector(selector, by) + if page_utils.is_xpath_selector(selector): + selector = self.convert_to_css_selector(selector, By.XPATH) + by = By.CSS_SELECTOR + self.wait_for_element_visible( + selector, by=by, timeout=settings.SMALL_TIMEOUT) + self.__demo_mode_highlight_if_active(selector, by) + self.scroll_to(selector, by=by) + time.sleep(0.05) # Settle down from scrolling before hovering + return page_actions.hover_on_element(self.driver, selector) + + def hover_and_click(self, hover_selector, click_selector, + hover_by=By.CSS_SELECTOR, click_by=By.CSS_SELECTOR, + timeout=settings.SMALL_TIMEOUT): + """ When you want to hover over an element or dropdown menu, + and then click an element that appears after that. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self.__get_new_timeout(timeout) + hover_selector, hover_by = self.__recalculate_selector( + hover_selector, hover_by) + hover_selector = self.convert_to_css_selector( + hover_selector, hover_by) + click_selector, click_by = self.__recalculate_selector( + click_selector, click_by) + self.wait_for_element_visible( + hover_selector, by=hover_by, timeout=timeout) + self.__demo_mode_highlight_if_active(hover_selector, hover_by) + self.scroll_to(hover_selector, by=hover_by) + pre_action_url = self.driver.current_url + element = page_actions.hover_and_click( + self.driver, hover_selector, click_selector, + hover_by, click_by, timeout) + if self.demo_mode: + if self.driver.current_url != pre_action_url: + self.__demo_mode_pause_if_active() + else: + self.__demo_mode_pause_if_active(tiny=True) + return element + + def hover_and_double_click(self, hover_selector, click_selector, + hover_by=By.CSS_SELECTOR, + click_by=By.CSS_SELECTOR, + timeout=settings.SMALL_TIMEOUT): + """ When you want to hover over an element or dropdown menu, + and then double-click an element that appears after that. """ + if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: + timeout = self.__get_new_timeout(timeout) + hover_selector, hover_by = self.__recalculate_selector( + hover_selector, hover_by) + hover_selector = self.convert_to_css_selector( + hover_selector, hover_by) + click_selector, click_by = self.__recalculate_selector( + click_selector, click_by) + hover_element = self.wait_for_element_visible( + hover_selector, by=hover_by, timeout=timeout) + self.__demo_mode_highlight_if_active(hover_selector, hover_by) + self.scroll_to(hover_selector, by=hover_by) + pre_action_url = self.driver.current_url + click_element = page_actions.hover_element_and_double_click( + self.driver, hover_element, click_selector, + click_by=By.CSS_SELECTOR, timeout=timeout) + if self.demo_mode: + if self.driver.current_url != pre_action_url: + self.__demo_mode_pause_if_active() + else: + self.__demo_mode_pause_if_active(tiny=True) + return click_element + + def __select_option(self, dropdown_selector, option, + dropdown_by=By.CSS_SELECTOR, option_by="text", + timeout=settings.SMALL_TIMEOUT): + """ Selects an HTML option by option text. + @Params + dropdown_selector - the option by option index. + @Params + dropdown_selector - the option by option value. + @Params + dropdown_selector - the option by specification. - Option specifications are by "text", "index", or "value". - Defaults to "text" if option_by is unspecified or unknown. """ - if page_utils.is_xpath_selector(dropdown_selector): - dropdown_by = By.XPATH - element = self.wait_for_element_visible( - dropdown_selector, by=dropdown_by, timeout=timeout) - self.__demo_mode_highlight_if_active(dropdown_selector, dropdown_by) - pre_action_url = self.driver.current_url - try: - if option_by == "index": - Select(element).select_by_index(option) - elif option_by == "value": - Select(element).select_by_value(option) - else: - Select(element).select_by_visible_text(option) - except (StaleElementReferenceException, ENI_Exception): - self.wait_for_ready_state_complete() - time.sleep(0.05) - element = self.wait_for_element_visible( - dropdown_selector, by=dropdown_by, timeout=timeout) - if option_by == "index": - Select(element).select_by_index(option) - elif option_by == "value": - Select(element).select_by_value(option) - else: - Select(element).select_by_visible_text(option) - if settings.WAIT_FOR_RSC_ON_CLICKS: - self.wait_for_ready_state_complete() - if self.demo_mode: - if self.driver.current_url != pre_action_url: - self.__demo_mode_pause_if_active() - else: - self.__demo_mode_pause_if_active(tiny=True) - - def select_option_by_text(self, dropdown_selector, option, - dropdown_by=By.CSS_SELECTOR, - timeout=settings.SMALL_TIMEOUT): - """ Selects an HTML selector - option - the text of the option """ - if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - self.__select_option(dropdown_selector, option, - dropdown_by=dropdown_by, option_by="text", - timeout=timeout) - - def select_option_by_index(self, dropdown_selector, option, - dropdown_by=By.CSS_SELECTOR, - timeout=settings.SMALL_TIMEOUT): - """ Selects an HTML selector - option - the index number of the option """ - if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - self.__select_option(dropdown_selector, option, - dropdown_by=dropdown_by, option_by="index", - timeout=timeout) - - def select_option_by_value(self, dropdown_selector, option, - dropdown_by=By.CSS_SELECTOR, - timeout=settings.SMALL_TIMEOUT): - """ Selects an HTML selector - option - the value property of the option """ - if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - self.__select_option(dropdown_selector, option, - dropdown_by=dropdown_by, option_by="value", - timeout=timeout) - ############ def generate_referral(self, start_page, destination_page): @@ -2302,6 +2490,21 @@ class BaseCase(unittest.TestCase): return page_actions.wait_for_element_present( self.driver, selector, by, timeout) + def wait_for_element_visible(self, selector, by=By.CSS_SELECTOR, + timeout=settings.LARGE_TIMEOUT): + """ Waits for an element to appear in the HTML of a page. + The element must be visible (it cannot be hidden). """ + selector, by = self.__recalculate_selector(selector, by) + return page_actions.wait_for_element_visible( + self.driver, selector, by, timeout) + + def wait_for_element(self, selector, by=By.CSS_SELECTOR, + timeout=settings.LARGE_TIMEOUT): + """ The shorter version of wait_for_element_visible() """ + if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: + timeout = self.__get_new_timeout(timeout) + return self.wait_for_element_visible(selector, by=by, timeout=timeout) + def get_element(self, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Same as wait_for_element_present() - returns the element. @@ -2321,26 +2524,6 @@ class BaseCase(unittest.TestCase): self.wait_for_element_present(selector, by=by, timeout=timeout) return True - # For backwards compatibility, earlier method names of the next - # four methods have remained even though they do the same thing, - # with the exception of assert_*, which won't return the element, - # but like the others, will raise an exception if the call fails. - - def wait_for_element_visible(self, selector, by=By.CSS_SELECTOR, - timeout=settings.LARGE_TIMEOUT): - """ Waits for an element to appear in the HTML of a page. - The element must be visible (it cannot be hidden). """ - selector, by = self.__recalculate_selector(selector, by) - return page_actions.wait_for_element_visible( - self.driver, selector, by, timeout) - - def wait_for_element(self, selector, by=By.CSS_SELECTOR, - timeout=settings.LARGE_TIMEOUT): - """ The shorter version of wait_for_element_visible() """ - if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - return self.wait_for_element_visible(selector, by=by, timeout=timeout) - def find_element(self, selector, by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): """ Same as wait_for_element_visible() - returns the element """ @@ -2372,10 +2555,7 @@ class BaseCase(unittest.TestCase): self.assert_element(selector, by=by, timeout=timeout) return True - # For backwards compatibility, earlier method names of the next - # four methods have remained even though they do the same thing, - # with the exception of assert_*, which won't return the element, - # but like the others, will raise an exception if the call fails. + ############ def wait_for_text_visible(self, text, selector="html", by=By.CSS_SELECTOR, timeout=settings.LARGE_TIMEOUT): @@ -2452,10 +2632,45 @@ class BaseCase(unittest.TestCase): self.__highlight_with_assert_success(messenger_post, selector, by) return True - # For backwards compatibility, earlier method names of the next - # four methods have remained even though they do the same thing, - # with the exception of assert_*, which won't return the element, - # but like the others, will raise an exception if the call fails. + ############ + + def wait_for_link_text_present(self, link_text, + timeout=settings.SMALL_TIMEOUT): + start_ms = time.time() * 1000.0 + stop_ms = start_ms + (timeout * 1000.0) + for x in range(int(timeout * 5)): + try: + if not self.is_link_text_present(link_text): + raise Exception( + "Link text {%s} was not found!" % link_text) + return + except Exception: + now_ms = time.time() * 1000.0 + if now_ms >= stop_ms: + break + time.sleep(0.2) + raise Exception( + "Link text {%s} was not present after %s seconds!" % ( + link_text, timeout)) + + def wait_for_partial_link_text_present(self, link_text, + timeout=settings.SMALL_TIMEOUT): + start_ms = time.time() * 1000.0 + stop_ms = start_ms + (timeout * 1000.0) + for x in range(int(timeout * 5)): + try: + if not self.is_partial_link_text_present(link_text): + raise Exception( + "Partial Link text {%s} was not found!" % link_text) + return + except Exception: + now_ms = time.time() * 1000.0 + if now_ms >= stop_ms: + break + time.sleep(0.2) + raise Exception( + "Partial Link text {%s} was not present after %s seconds!" % ( + link_text, timeout)) def wait_for_link_text_visible(self, link_text, timeout=settings.LARGE_TIMEOUT): @@ -2489,11 +2704,6 @@ class BaseCase(unittest.TestCase): messenger_post, link_text, by=By.LINK_TEXT) return True - # For backwards compatibility, earlier method names of the next - # three methods have remained even though they do the same thing, - # with the exception of assert_*, which won't return the element, - # but like the others, will raise an exception if the call fails. - def wait_for_partial_link_text(self, partial_link_text, timeout=settings.LARGE_TIMEOUT): if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: @@ -2574,36 +2784,6 @@ class BaseCase(unittest.TestCase): ############ - def wait_for_ready_state_complete(self, timeout=settings.EXTREME_TIMEOUT): - try: - # If there's an alert, skip - self.driver.switch_to.alert - return - except Exception: - # If there's no alert, continue - pass - 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) - self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT) - if self.js_checking_on: - self.assert_no_js_errors() - if self.ad_block_on: - # If the ad_block feature is enabled, then block ads for new URLs - current_url = self.get_current_url() - if not current_url == self.__last_page_load_url: - time.sleep(0.02) - self.ad_block() - time.sleep(0.01) - if self.is_element_present("iframe"): - time.sleep(0.07) # iframe ads take slightly longer to load - self.ad_block() # Do ad_block on slower-loading iframes - self.__last_page_load_url = current_url - return is_ready - - def wait_for_angularjs(self, timeout=settings.LARGE_TIMEOUT, **kwargs): - js_utils.wait_for_angularjs(self.driver, timeout, **kwargs) - def wait_for_and_accept_alert(self, timeout=settings.LARGE_TIMEOUT): if self.timeout_multiplier and timeout == settings.LARGE_TIMEOUT: timeout = self.__get_new_timeout(timeout) @@ -2619,33 +2799,7 @@ class BaseCase(unittest.TestCase): timeout = self.__get_new_timeout(timeout) return page_actions.wait_for_and_switch_to_alert(self.driver, timeout) - def switch_to_frame(self, frame, timeout=settings.SMALL_TIMEOUT): - """ Sets driver control to the specified browser frame. """ - if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - page_actions.switch_to_frame(self.driver, frame, timeout) - - def switch_to_default_content(self): - """ Brings driver control outside the current iframe. - (If driver control is inside an iframe, the driver control - will be set to one level above the current frame. If the driver - control is not currenly in an iframe, nothing will happen.) """ - self.driver.switch_to.default_content() - - def open_new_window(self, switch_to=True): - """ Opens a new browser tab/window and switches to it by default. """ - self.driver.execute_script("window.open('');") - time.sleep(0.01) - if switch_to: - self.switch_to_window(len(self.driver.window_handles) - 1) - - def switch_to_window(self, window, timeout=settings.SMALL_TIMEOUT): - if self.timeout_multiplier and timeout == settings.SMALL_TIMEOUT: - timeout = self.__get_new_timeout(timeout) - page_actions.switch_to_window(self.driver, window, timeout) - - def switch_to_default_window(self): - self.switch_to_window(0) + ############ def check_window(self, name="default", level=0, baseline=False): """ *** Automated Visual Testing with SeleniumBase *** @@ -2846,153 +3000,6 @@ class BaseCase(unittest.TestCase): except Exception as e: print(e) # Level-0 Dry Run (Only print the differences) - def save_screenshot(self, name, folder=None): - """ The screenshot will be in PNG format. """ - return page_actions.save_screenshot(self.driver, name, folder) - - def get_new_driver(self, browser=None, headless=None, - servername=None, port=None, proxy=None, agent=None, - switch_to=True, cap_file=None, disable_csp=None, - enable_sync=None, user_data_dir=None, - extension_zip=None, extension_dir=None): - """ This method spins up an extra browser for tests that require - more than one. The first browser is already provided by tests - that import base_case.BaseCase from seleniumbase. If parameters - aren't specified, the method uses the same as the default driver. - @Params - browser - the browser to use. (Ex: "chrome", "firefox") - headless - the option to run webdriver in headless mode - servername - if using a Selenium Grid, set the host address here - port - if using a Selenium Grid, set the host port here - proxy - if using a proxy server, specify the "host:port" combo here - switch_to - the option to switch to the new driver (default = True) - cap_file - the file containing desired capabilities for the browser - disable_csp - an option to disable Chrome's Content Security Policy - enable_sync - the option to enable the "Chrome Sync" feature - user_data_dir - Chrome's User Data Directory to use (Chrome-only) - extension_zip - A Chrome Extension ZIP file to use (Chrome-only) - extension_dir - A Chrome Extension folder to use (Chrome-only) - """ - if self.browser == "remote" and self.servername == "localhost": - raise Exception('Cannot use "remote" browser driver on localhost!' - ' Did you mean to connect to a remote Grid server' - ' such as BrowserStack or Sauce Labs? In that' - ' case, you must specify the "server" and "port"' - ' parameters on the command line! ' - 'Example: ' - '--server=user:key@hub.browserstack.com --port=80') - browserstack_ref = ( - 'https://browserstack.com/automate/capabilities') - sauce_labs_ref = ( - 'https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/') - if self.browser == "remote" and not self.cap_file: - raise Exception('Need to specify a desired capabilities file when ' - 'using "--browser=remote". Add "--cap_file=FILE". ' - 'File should be in the Python format used by: ' - '%s OR ' - '%s ' - 'See SeleniumBase/examples/sample_cap_file_BS.py ' - 'and SeleniumBase/examples/sample_cap_file_SL.py' - % (browserstack_ref, sauce_labs_ref)) - if browser is None: - browser = self.browser - browser_name = browser - if headless is None: - headless = self.headless - if servername is None: - servername = self.servername - if port is None: - port = self.port - use_grid = False - if servername != "localhost": - # Use Selenium Grid (Use "127.0.0.1" for localhost Grid) - use_grid = True - proxy_string = proxy - if proxy_string is None: - proxy_string = self.proxy_string - user_agent = agent - if user_agent is None: - user_agent = self.user_agent - if disable_csp is None: - disable_csp = self.disable_csp - if enable_sync is None: - enable_sync = self.enable_sync - if user_data_dir is None: - user_data_dir = self.user_data_dir - if extension_zip is None: - extension_zip = self.extension_zip - if extension_dir is None: - extension_dir = self.extension_dir - if self.demo_mode or self.masterqa_mode: - disable_csp = True - if cap_file is None: - cap_file = self.cap_file - valid_browsers = constants.ValidBrowsers.valid_browsers - if browser_name not in valid_browsers: - raise Exception("Browser: {%s} is not a valid browser option. " - "Valid options = {%s}" % (browser, valid_browsers)) - # Launch a web browser - from seleniumbase.core import browser_launcher - new_driver = browser_launcher.get_driver(browser_name=browser_name, - headless=headless, - use_grid=use_grid, - servername=servername, - port=port, - proxy_string=proxy_string, - user_agent=user_agent, - cap_file=cap_file, - disable_csp=disable_csp, - enable_sync=enable_sync, - user_data_dir=user_data_dir, - extension_zip=extension_zip, - extension_dir=extension_dir) - self._drivers_list.append(new_driver) - if switch_to: - self.driver = new_driver - if self.headless: - # Make sure the invisible browser window is big enough - try: - self.set_window_size(1440, 1880) - self.wait_for_ready_state_complete() - except Exception: - # This shouldn't fail, but in case it does, - # get safely through setUp() so that - # WebDrivers can get closed during tearDown(). - pass - else: - if self.browser == 'chrome' or self.browser == 'opera': - try: - if self.maximize_option: - self.driver.maximize_window() - else: - self.driver.set_window_size(1250, 840) - self.wait_for_ready_state_complete() - except Exception: - pass # Keep existing browser resolution - elif self.browser == 'edge': - try: - self.driver.maximize_window() - self.wait_for_ready_state_complete() - except Exception: - pass # Keep existing browser resolution - if self.start_page and len(self.start_page) >= 4: - if page_utils.is_valid_url(self.start_page): - self.open(self.start_page) - else: - new_start_page = "http://" + self.start_page - if page_utils.is_valid_url(new_start_page): - self.open(new_start_page) - return new_driver - - def switch_to_driver(self, driver): - """ Sets self.driver to the specified driver. - You may need this if using self.get_new_driver() in your code. """ - self.driver = driver - - def switch_to_default_driver(self): - """ Sets self.driver to the default/original driver. """ - self.driver = self._default_driver - ############ def __get_new_timeout(self, timeout):