How to use __switch_to_newest_window_if_not_blank method in SeleniumBase

Best Python code snippet using SeleniumBase

webdriver_test.py

Source:webdriver_test.py Github

copy

Full Screen

...251 latest_ge = latest_window_count > pre_window_count252 switch = settings.SWITCH_TO_NEW_TABS_ON_CLICK253 pre = self.driver.current_url == pre_action_url254 if latest_ge and (switch or pre):255 self.__switch_to_newest_window_if_not_blank()256 if settings.WAIT_FOR_RSC_ON_CLICKS:257 self.wait_for_ready_state_complete()258 else:259 # A smaller subset of self.wait_for_ready_state_complete()260 self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT)261 if self.driver.current_url != pre_action_url:262 self.__ad_block_as_needed()263 if browser_name == "safari":264 time.sleep(0.02)265 if self.demo_mode:266 if self.driver.current_url != pre_action_url:267 self._demo_mode_pause_if_active()268 else:269 self._demo_mode_pause_if_active(tiny=True)270 elif self.slow_mode:271 self._slow_mode_pause_if_active()272 @validate_arguments273 def slow_click(274 self,275 how: SeleniumBy,276 selector: str = Field(default="", strict=True, min_length=1),277 timeout: OptionalInt = None278 ) -> None:279 self.__check_scope__()280 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)281 if not self.demo_mode and not self.slow_mode:282 self.click(how, selector, timeout=timeout, delay=1.05)283 elif self.slow_mode:284 self.click(how, selector, timeout=timeout, delay=0.65)285 else:286 self.click(how, selector, timeout=timeout, delay=0.25)287 def double_click(288 self,289 how: SeleniumBy,290 selector: str = Field(..., strict=True, min_length=1),291 timeout: OptionalInt = None,292 ) -> None:293 from selenium.webdriver.common.action_chains import ActionChains294 self.__check_scope__()295 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)296 element = element_actions.wait_for_element_interactable(self.driver, how, selector, timeout=timeout)297 self.__demo_mode_highlight_if_active(how, selector)298 if not self.demo_mode and not self.slow_mode:299 self.__scroll_to_element(element, how, selector)300 self.wait_for_ready_state_complete()301 logger.debug("Find the element one more time in case scrolling hid it")302 element = element_actions.wait_for_element_visible(self.driver, how, selector, timeout=timeout)303 pre_action_url = self.driver.current_url304 try:305 if self.browser == "safari":306 # Jump to the "except" block where the other script should work307 raise WebDriverException("This Exception will be caught.")308 actions = ActionChains(self.driver)309 actions.double_click(element).perform()310 except WebDriverException:311 css_selector = self.convert_to_css_selector(how, selector)312 css_selector = re.escape(css_selector) # Add "\\" to special chars313 css_selector = shared.escape_quotes_if_needed(css_selector)314 double_click_script = (315 """var targetElement1 = document.querySelector('%s');316 var clickEvent1 = document.createEvent('MouseEvents');317 clickEvent1.initEvent('dblclick', true, true);318 targetElement1.dispatchEvent(clickEvent1);"""319 % css_selector320 )321 if ":contains\\(" not in css_selector:322 self.execute_script(double_click_script)323 else:324 double_click_script = (325 """jQuery('%s').dblclick();""" % css_selector326 )327 self.safe_execute_script(double_click_script)328 if settings.WAIT_FOR_RSC_ON_CLICKS:329 self.wait_for_ready_state_complete()330 else:331 # A smaller subset of self.wait_for_ready_state_complete()332 self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT)333 if self.driver.current_url != pre_action_url:334 self._ad_block_as_needed()335 if self.demo_mode:336 if self.driver.current_url != pre_action_url:337 self._demo_mode_pause_if_active()338 else:339 self._demo_mode_pause_if_active(tiny=True)340 elif self.slow_mode:341 self._slow_mode_pause_if_active()342 def click_chain(343 self, selectors_list, by=By.CSS_SELECTOR, timeout=None, spacing=0344 ):345 """This method clicks on a list of elements in succession.346 @Params347 selectors_list - The list of selectors to click on.348 by - The type of selector to search by (Default: CSS_Selector).349 timeout - How long to wait for the selector to be visible.350 spacing - The amount of time to wait between clicks (in seconds).351 """352 self.__check_scope__()353 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)354 for selector in selectors_list:355 self.click(selector, by=by, timeout=timeout)356 if spacing > 0:357 time.sleep(spacing)358 def update_text(359 self,360 text: str | None,361 how: SeleniumBy,362 selector: str = Field(..., strict=True, min_length=1),363 timeout: OptionalInt = None,364 retry=False365 ) -> None:366 self.__check_scope__()367 timeout = self.get_timeout(timeout, constants.LARGE_TIMEOUT)368 if self._is_shadow_selector(selector):369 self._shadow.shadow_type(selector, text, timeout)370 return371 element = self.wait_for_element_interactable(how, selector, timeout)372 self.__demo_mode_highlight_if_active(how, selector)373 if not self.demo_mode and not self.slow_mode:374 self.__scroll_to_element(element, how, selector)375 try:376 element.clear() # May need https://stackoverflow.com/a/50691625377 backspaces = Keys.BACK_SPACE * 42 # Is the answer to everything378 element.send_keys(backspaces) # In case autocomplete keeps text379 except (StaleElementReferenceException, ElementNotInteractableException):380 self.wait_for_ready_state_complete()381 time.sleep(0.16)382 element = self.wait_for_element_visible(how, selector, timeout)383 try:384 element.clear()385 except Exception:386 pass # Clearing the text field first might not be necessary387 except Exception:388 pass # Clearing the text field first might not be necessary389 self._demo_mode_pause_if_active(tiny=True)390 pre_action_url = self.driver.current_url391 if type(text) is int or type(text) is float:392 text = str(text)393 try:394 if not text.endswith("\n"):395 element.send_keys(text)396 if settings.WAIT_FOR_RSC_ON_PAGE_LOADS:397 self.wait_for_ready_state_complete()398 else:399 element.send_keys(text[:-1])400 element.send_keys(Keys.RETURN)401 if settings.WAIT_FOR_RSC_ON_PAGE_LOADS:402 self.wait_for_ready_state_complete()403 except (StaleElementReferenceException, ElementNotInteractableException):404 self.wait_for_ready_state_complete()405 time.sleep(0.16)406 element = self.wait_for_element_visible(how, selector, timeout=timeout)407 element.clear()408 if not text.endswith("\n"):409 element.send_keys(text)410 else:411 element.send_keys(text[:-1])412 element.send_keys(Keys.RETURN)413 if settings.WAIT_FOR_RSC_ON_PAGE_LOADS:414 self.wait_for_ready_state_complete()415 if (416 retry417 and element.get_attribute("value") != text418 and not text.endswith("\n")419 ):420 logger.debug("update_text() is falling back to JavaScript!")421 self.set_value(selector, text, by=by)422 if self.demo_mode:423 if self.driver.current_url != pre_action_url:424 self._demo_mode_pause_if_active()425 else:426 self._demo_mode_pause_if_active(tiny=True)427 elif self.slow_mode:428 self._slow_mode_pause_if_active()429 @validate_arguments430 def add_text(431 self,432 text: str | None,433 how: SeleniumBy,434 selector: str = Field(..., strict=True, min_length=1),435 timeout: OptionalInt = None436 ):437 """The more-reliable version of driver.send_keys()438 Similar to update_text(), but won't clear the text field first."""439 self.__check_scope__()440 timeout = self.get_timeout(timeout, constants.LARGE_TIMEOUT)441 if self._is_shadow_selector(selector):442 self._shadow.shadow_type(selector, text, timeout, clear_first=False)443 return444 element = self.wait_for_element_visible(how, selector, timeout)445 self.__demo_mode_highlight_if_active(how, selector)446 if not self.demo_mode and not self.slow_mode:447 self.__scroll_to_element(element, how, selector)448 pre_action_url = self.driver.current_url449 if type(text) is int or type(text) is float:450 text = str(text)451 try:452 if not text.endswith("\n"):453 element.send_keys(text)454 else:455 element.send_keys(text[:-1])456 element.send_keys(Keys.RETURN)457 if settings.WAIT_FOR_RSC_ON_PAGE_LOADS:458 self.wait_for_ready_state_complete()459 except (StaleElementReferenceException, ElementNotInteractableException):460 self.wait_for_ready_state_complete()461 time.sleep(0.16)462 element = self.wait_for_element_visible(how, selector, timeout)463 if not text.endswith("\n"):464 element.send_keys(text)465 else:466 element.send_keys(text[:-1])467 element.send_keys(Keys.RETURN)468 if settings.WAIT_FOR_RSC_ON_PAGE_LOADS:469 self.wait_for_ready_state_complete()470 if self.demo_mode:471 if self.driver.current_url != pre_action_url:472 self._demo_mode_pause_if_active()473 else:474 self._demo_mode_pause_if_active(tiny=True)475 elif self.slow_mode:476 self._slow_mode_pause_if_active()477 def submit(self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)):478 """ Alternative to self.driver.find_element_by_*(SELECTOR).submit() """479 self.__check_scope__()480 element = self.wait_for_element_visible(how, selector, timeout=constants.SMALL_TIMEOUT)481 element.submit()482 self._demo_mode_pause_if_active()483 def clear(484 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1), timeout: OptionalInt = None485 ):486 self.__check_scope__()487 timeout = self.get_timeout(timeout, constants.LARGE_TIMEOUT)488 if self._is_shadow_selector(selector):489 self._shadow.shadow_clear(selector, timeout)490 return491 element = self.wait_for_element_visible(how, selector, timeout)492 self.scroll_to(how, selector, timeout=timeout)493 try:494 element.clear()495 backspaces = Keys.BACK_SPACE * 42 # Autofill Defense496 element.send_keys(backspaces)497 except (StaleElementReferenceException, ElementNotInteractableException):498 self.wait_for_ready_state_complete()499 time.sleep(0.16)500 element = self.wait_for_element_visible(how, selector, timeout)501 element.clear()502 try:503 backspaces = Keys.BACK_SPACE * 42 # Autofill Defense504 element.send_keys(backspaces)505 except Exception:506 pass507 except Exception:508 element.clear()509 def focus(510 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1), timeout: OptionalInt = None511 ):512 self.__check_scope__()513 timeout = self.get_timeout(timeout, constants.LARGE_TIMEOUT)514 element = self.wait_for_element_visible(how, selector, timeout)515 self.scroll_to(how, selector, timeout=timeout)516 try:517 element.send_keys(Keys.NULL)518 except (StaleElementReferenceException, ElementNotInteractableException):519 self.wait_for_ready_state_complete()520 time.sleep(0.12)521 element = self.wait_for_element_visible(how, selector, timeout)522 try:523 element.send_keys(Keys.NULL)524 except ElementNotInteractableException:525 # Non-interactable element. Skip focus and continue.526 pass527 self._demo_mode_pause_if_active()528 def refresh_page(self):529 self.__check_scope__()530 self.__last_page_load_url = None531 self._clear_out_console_logs()532 self.driver.refresh()533 self.wait_for_ready_state_complete()534 def refresh(self):535 """ The shorter version of self.refresh_page() """536 self.refresh_page()537 def get_origin(self):538 self.__check_scope__()539 return self.execute_script("return window.location.origin;")540 def get_page_source(self):541 self.wait_for_ready_state_complete()542 return self.driver.page_source543 def get_page_title(self):544 self.wait_for_ready_state_complete()545 self.wait_for_element_present("title", timeout=settings.SMALL_TIMEOUT)546 time.sleep(0.03)547 return self.driver.title548 def get_title(self):549 """ The shorter version of self.get_page_title() """550 return self.get_page_title()551 def get_user_agent(self) -> str:552 self.__check_scope__()553 self.__check_browser__()554 user_agent = self.driver.execute_script("return navigator.userAgent;")555 return user_agent556 def get_locale_code(self) -> str:557 self.__check_scope__()558 self.__check_browser__()559 locale_code = self.driver.execute_script(560 "return navigator.language || navigator.languages[0];"561 )562 return locale_code563 def go_back(self):564 self.__check_scope__()565 self.__last_page_load_url = None566 self.driver.back()567 if self.browser == "safari":568 self.wait_for_ready_state_complete()569 self.driver.refresh()570 self.wait_for_ready_state_complete()571 self._demo_mode_pause_if_active()572 def go_forward(self):573 self.__check_scope__()574 self.__last_page_load_url = None575 self.driver.forward()576 self.wait_for_ready_state_complete()577 self._demo_mode_pause_if_active()578 def open_start_page(self):579 self.__check_scope__()580 start_page = self.start_page581 if type(start_page) is str:582 start_page = start_page.strip() # Remove extra whitespace583 if start_page and len(start_page) >= 4:584 if page_utils.is_valid_url(start_page):585 self.open(start_page)586 else:587 new_start_page = "https://" + start_page588 if page_utils.is_valid_url(new_start_page):589 self.__dont_record_open = True590 self.open(new_start_page)591 self.__dont_record_open = False592 else:593 logger.info('Invalid URL: "%s"!' % start_page)594 self.open("data:,")595 else:596 self.open("data:,")597 def open_if_not_url(self, url):598 """ Opens the url in the browser if it's not the current url. """599 self.__check_scope__()600 if self.driver.current_url != url:601 self.open(url)602 def is_element_present(self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)):603 self.wait_for_ready_state_complete()604 if self._is_shadow_selector(selector):605 return self._shadow.is_shadow_element_present(selector)606 return element_actions.is_element_present(self.driver, how, selector)607 def is_element_visible(self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)):608 self.wait_for_ready_state_complete()609 if self._is_shadow_selector(selector):610 return self._shadow.is_shadow_element_visible(selector)611 return element_actions.is_element_visible(self.driver, selector, by)612 def is_element_enabled(self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)):613 self.wait_for_ready_state_complete()614 if self._is_shadow_selector(selector):615 return self._shadow.is_shadow_element_enabled(selector)616 return element_actions.is_element_enabled(self.driver, selector, by)617 def is_text_visible(618 self, text: str | None, how: SeleniumBy, selector: str = Field(default="html", strict=True, min_length=1)619 ):620 self.wait_for_ready_state_complete()621 time.sleep(0.01)622 if self._is_shadow_selector(selector):623 return self._shadow.is_shadow_text_visible(text, selector)624 return element_actions.is_text_visible(self.driver, text, selector, by)625 @validate_arguments626 def is_attribute_present(627 self,628 attribute_name: str,629 attribute_value: str | None,630 how: SeleniumBy,631 selector: str = Field(..., strict=True, min_length=1)632 ) -> bool:633 """Returns True if the element attribute/value is found.634 If the value is not specified, the attribute only needs to exist."""635 self.wait_for_ready_state_complete()636 time.sleep(0.01)637 if self._is_shadow_selector(selector):638 return self._shadow.is_shadow_attribute_present(selector, attribute_name, attribute_value)639 return element_actions.is_attribute_present(self.driver, attribute_name, attribute_value, how, selector)640 @validate_arguments641 def is_link_text_visible(self, link_text: str) -> bool:642 self.wait_for_ready_state_complete()643 time.sleep(0.01)644 return element_actions.is_element_visible(self.driver, link_text, by=By.LINK_TEXT)645 @validate_arguments646 def is_partial_link_text_visible(self, partial_link_text: str) -> bool:647 self.wait_for_ready_state_complete()648 time.sleep(0.01)649 return element_actions.is_element_visible(650 self.driver, partial_link_text, by=By.PARTIAL_LINK_TEXT651 )652 @validate_arguments653 def is_link_text_present(self, link_text: str) -> bool:654 """Returns True if the link text appears in the HTML of the page.655 The element doesn't need to be visible,656 such as elements hidden inside a dropdown selection."""657 self.wait_for_ready_state_complete()658 soup = self.get_beautiful_soup()659 html_links = soup.find_all("a")660 for html_link in html_links:661 if html_link.text.strip() == link_text.strip():662 return True663 return False664 @validate_arguments665 def is_partial_link_text_present(self, link_text: str) -> bool:666 """Returns True if the partial link appears in the HTML of the page.667 The element doesn't need to be visible,668 such as elements hidden inside a dropdown selection."""669 self.wait_for_ready_state_complete()670 soup = self.get_beautiful_soup()671 html_links = soup.find_all("a")672 for html_link in html_links:673 if link_text.strip() in html_link.text.strip():674 return True675 return False676 def get_link_attribute(self, link_text: str, attribute: str, hard_fail=True):677 self.wait_for_ready_state_complete()678 soup = self.get_beautiful_soup()679 html_links = soup.find_all("a")680 for html_link in html_links:681 if html_link.text.strip() == link_text.strip():682 if html_link.has_attr(attribute):683 attribute_value = html_link.get(attribute)684 return attribute_value685 if hard_fail:686 raise WebDriverException(f"Unable to find attribute {attribute} from link text {link_text}!")687 else:688 return None689 if hard_fail:690 raise Exception("Link text {%s} was not found!" % link_text)691 else:692 return None693 def get_link_text_attribute(self, link_text, attribute, hard_fail=True):694 return self.get_link_attribute(link_text, attribute, hard_fail)695 def get_partial_link_text_attribute(696 self, link_text, attribute, hard_fail=True697 ):698 self.wait_for_ready_state_complete()699 soup = self.get_beautiful_soup()700 html_links = soup.find_all("a")701 for html_link in html_links:702 if link_text.strip() in html_link.text.strip():703 if html_link.has_attr(attribute):704 attribute_value = html_link.get(attribute)705 return attribute_value706 if hard_fail:707 raise Exception(708 "Unable to find attribute {%s} from "709 "partial link text {%s}!" % (attribute, link_text)710 )711 else:712 return None713 if hard_fail:714 raise Exception(715 "Partial Link text {%s} was not found!" % link_text716 )717 else:718 return None719 def click_link_text(self, link_text: str, timeout: OptionalInt = None):720 """ This method clicks link text on a page """721 # If using phantomjs, might need to extract and open the link directly722 self.__check_scope__()723 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)724 pre_action_url = self.driver.current_url725 pre_window_count = len(self.driver.window_handles)726 if self.browser == "phantomjs":727 if self.is_link_text_visible(link_text):728 element = self.wait_for_link_text_visible(729 link_text, timeout=timeout730 )731 element.click()732 return733 self.open(self.__get_href_from_link_text(link_text))734 return735 if self.browser == "safari":736 if self.demo_mode:737 self.wait_for_link_text_present(link_text, timeout=timeout)738 try:739 self.__jquery_slow_scroll_to(link_text, by=By.LINK_TEXT)740 except Exception:741 element = self.wait_for_link_text_visible(742 link_text, timeout=timeout743 )744 self.__slow_scroll_to_element(element)745 o_bs = "" # original_box_shadow746 loops = settings.HIGHLIGHTS747 selector = self.convert_to_css_selector(748 link_text, by=By.LINK_TEXT749 )750 selector = self.__make_css_match_first_element_only(selector)751 try:752 selector = re.escape(selector)753 selector = shared.escape_quotes_if_needed(selector)754 self.__highlight_with_jquery(selector, loops, o_bs)755 except Exception:756 pass # JQuery probably couldn't load. Skip highlighting.757 self.__jquery_click(link_text, by=By.LINK_TEXT)758 return759 if not self.is_link_text_present(link_text):760 self.wait_for_link_text_present(link_text, timeout=timeout)761 pre_action_url = self.get_current_url()762 try:763 element = self.wait_for_link_text_visible(link_text, timeout=0.2)764 self.__demo_mode_highlight_if_active(link_text, by=By.LINK_TEXT)765 try:766 element.click()767 except (StaleElementReferenceException, ElementNotInteractableException):768 self.wait_for_ready_state_complete()769 time.sleep(0.16)770 element = self.wait_for_link_text_visible(771 link_text, timeout=timeout772 )773 element.click()774 except Exception:775 found_css = False776 text_id = self.get_link_attribute(link_text, "id", False)777 if text_id:778 link_css = '[id="%s"]' % link_text779 found_css = True780 if not found_css:781 href = self.__get_href_from_link_text(link_text, False)782 if href:783 if href.startswith("/") or page_utils.is_valid_url(href):784 link_css = '[href="%s"]' % href785 found_css = True786 if not found_css:787 ngclick = self.get_link_attribute(link_text, "ng-click", False)788 if ngclick:789 link_css = '[ng-click="%s"]' % ngclick790 found_css = True791 if not found_css:792 onclick = self.get_link_attribute(link_text, "onclick", False)793 if onclick:794 link_css = '[onclick="%s"]' % onclick795 found_css = True796 success = False797 if found_css:798 if self.is_element_visible(link_css):799 self.click(link_css)800 success = True801 else:802 # The link text might be hidden under a dropdown menu803 success = self.__click_dropdown_link_text(804 link_text, link_css805 )806 if not success:807 element = self.wait_for_link_text_visible(808 link_text, timeout=settings.MINI_TIMEOUT809 )810 element.click()811 latest_window_count = len(self.driver.window_handles)812 if (813 latest_window_count > pre_window_count814 and (815 self.recorder_mode816 or (817 settings.SWITCH_TO_NEW_TABS_ON_CLICK818 and self.driver.current_url == pre_action_url819 )820 )821 ):822 self.__switch_to_newest_window_if_not_blank()823 if settings.WAIT_FOR_RSC_ON_PAGE_LOADS:824 self.wait_for_ready_state_complete()825 if self.demo_mode:826 if self.driver.current_url != pre_action_url:827 self._demo_mode_pause_if_active()828 else:829 self._demo_mode_pause_if_active(tiny=True)830 elif self.slow_mode:831 self._slow_mode_pause_if_active()832 def click_partial_link_text(self, partial_link_text: str, timeout: OptionalInt = None):833 """ This method clicks the partial link text on a page. """834 # If using phantomjs, might need to extract and open the link directly835 self.__check_scope__()836 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)837 if self.browser == "phantomjs":838 if self.is_partial_link_text_visible(partial_link_text):839 element = self.wait_for_partial_link_text(partial_link_text)840 element.click()841 return842 soup = self.get_beautiful_soup()843 html_links = soup.fetch("a")844 for html_link in html_links:845 if partial_link_text in html_link.text:846 for html_attribute in html_link.attrs:847 if html_attribute[0] == "href":848 href = html_attribute[1]849 if href.startswith("//"):850 link = "http:" + href851 elif href.startswith("/"):852 url = self.driver.current_url853 domain_url = self.get_domain_url(url)854 link = domain_url + href855 else:856 link = href857 self.open(link)858 return859 raise Exception(860 "Could not parse link from partial link_text "861 "{%s}" % partial_link_text862 )863 raise Exception(864 "Partial link text {%s} was not found!" % partial_link_text865 )866 if not self.is_partial_link_text_present(partial_link_text):867 self.wait_for_partial_link_text_present(868 partial_link_text, timeout=timeout869 )870 pre_action_url = self.driver.current_url871 pre_window_count = len(self.driver.window_handles)872 try:873 element = self.wait_for_partial_link_text(874 partial_link_text, timeout=0.2875 )876 self.__demo_mode_highlight_if_active(877 partial_link_text, by=By.LINK_TEXT878 )879 try:880 element.click()881 except (StaleElementReferenceException, ElementNotInteractableException):882 self.wait_for_ready_state_complete()883 time.sleep(0.16)884 element = self.wait_for_partial_link_text(885 partial_link_text, timeout=timeout886 )887 element.click()888 except Exception:889 found_css = False890 text_id = self.get_partial_link_text_attribute(891 partial_link_text, "id", False892 )893 if text_id:894 link_css = '[id="%s"]' % partial_link_text895 found_css = True896 if not found_css:897 href = self.__get_href_from_partial_link_text(898 partial_link_text, False899 )900 if href:901 if href.startswith("/") or page_utils.is_valid_url(href):902 link_css = '[href="%s"]' % href903 found_css = True904 if not found_css:905 ngclick = self.get_partial_link_text_attribute(906 partial_link_text, "ng-click", False907 )908 if ngclick:909 link_css = '[ng-click="%s"]' % ngclick910 found_css = True911 if not found_css:912 onclick = self.get_partial_link_text_attribute(913 partial_link_text, "onclick", False914 )915 if onclick:916 link_css = '[onclick="%s"]' % onclick917 found_css = True918 success = False919 if found_css:920 if self.is_element_visible(link_css):921 self.click(link_css)922 success = True923 else:924 # The link text might be hidden under a dropdown menu925 success = self.__click_dropdown_partial_link_text(926 partial_link_text, link_css927 )928 if not success:929 element = self.wait_for_partial_link_text(930 partial_link_text, timeout=settings.MINI_TIMEOUT931 )932 element.click()933 latest_window_count = len(self.driver.window_handles)934 if (935 latest_window_count > pre_window_count936 and (937 self.recorder_mode938 or (939 settings.SWITCH_TO_NEW_TABS_ON_CLICK940 and self.driver.current_url == pre_action_url941 )942 )943 ):944 self.__switch_to_newest_window_if_not_blank()945 if settings.WAIT_FOR_RSC_ON_PAGE_LOADS:946 self.wait_for_ready_state_complete()947 if self.demo_mode:948 if self.driver.current_url != pre_action_url:949 self._demo_mode_pause_if_active()950 else:951 self._demo_mode_pause_if_active(tiny=True)952 elif self.slow_mode:953 self._slow_mode_pause_if_active()954 def get_text(self, selector, by=By.CSS_SELECTOR, timeout=None):955 self.__check_scope__()956 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)957 if self._is_shadow_selector(selector):958 return self._shadow.get_shadow_text(selector, timeout)959 self.wait_for_ready_state_complete()960 time.sleep(0.01)961 element = element_actions.wait_for_element_visible(self.driver, how, selector, timeout)962 try:963 element_text = element.text964 if self.browser == "safari":965 element_text = element.get_attribute("innerText")966 except (StaleElementReferenceException, ElementNotInteractableException):967 self.wait_for_ready_state_complete()968 time.sleep(0.14)969 element = page_actions.wait_for_element_visible(970 self.driver, selector, by, timeout971 )972 element_text = element.text973 if self.browser == "safari":974 element_text = element.get_attribute("innerText")975 return element_text976 def get_attribute(977 self,978 selector,979 attribute,980 by=By.CSS_SELECTOR,981 timeout=None,982 hard_fail=True,983 ):984 """ This method uses JavaScript to get the value of an attribute. """985 self.__check_scope__()986 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)987 self.wait_for_ready_state_complete()988 time.sleep(0.01)989 if self._is_shadow_selector(selector):990 return self._shadow._get_shadow_attribute(991 selector, attribute, timeout=timeout992 )993 element_actions.wait_for_element_present(self.driver, how, selector, timeout)994 try:995 attribute_value = element.get_attribute(attribute)996 except (StaleElementReferenceException, ElementNotInteractableException):997 self.wait_for_ready_state_complete()998 time.sleep(0.14)999 element = element_actions.wait_for_element_present(self.driver, how, selector, timeout)1000 attribute_value = element.get_attribute(attribute)1001 if attribute_value is not None:1002 return attribute_value1003 else:1004 if hard_fail:1005 raise Exception(1006 "Element {%s} has no attribute {%s}!"1007 % (selector, attribute)1008 )1009 else:1010 return None1011 def set_attribute(1012 self,1013 selector,1014 attribute,1015 value,1016 by=By.CSS_SELECTOR,1017 timeout=None,1018 scroll=False,1019 ):1020 """This method uses JavaScript to set/update an attribute.1021 Only the first matching selector from querySelector() is used."""1022 self.__check_scope__()1023 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1024 if scroll and self.is_element_visible(how, selector):1025 try:1026 self.scroll_to(selector, by=by, timeout=timeout)1027 except Exception:1028 pass1029 attribute = re.escape(attribute)1030 attribute = shared.escape_quotes_if_needed(attribute)1031 value = re.escape(value)1032 value = shared.escape_quotes_if_needed(value)1033 css_selector = self.convert_to_css_selector(selector, by=by)1034 css_selector = re.escape(css_selector) # Add "\\" to special chars1035 css_selector = shared.escape_quotes_if_needed(css_selector)1036 script = (1037 """document.querySelector('%s').setAttribute('%s','%s');"""1038 % (css_selector, attribute, value)1039 )1040 self.execute_script(script)1041 def set_attributes(self, selector, attribute, value, by=By.CSS_SELECTOR):1042 """This method uses JavaScript to set/update a common attribute.1043 All matching selectors from querySelectorAll() are used.1044 Example => (Make all links on a website redirect to Google):1045 self.set_attributes("a", "href", "https://google.com")"""1046 self.__check_scope__()1047 attribute = re.escape(attribute)1048 attribute = shared.escape_quotes_if_needed(attribute)1049 value = re.escape(value)1050 value = shared.escape_quotes_if_needed(value)1051 css_selector = self.convert_to_css_selector(selector, by=by)1052 css_selector = re.escape(css_selector) # Add "\\" to special chars1053 css_selector = shared.escape_quotes_if_needed(css_selector)1054 script = """var $elements = document.querySelectorAll('%s');1055 var index = 0, length = $elements.length;1056 for(; index < length; index++){1057 $elements[index].setAttribute('%s','%s');}""" % (1058 css_selector,1059 attribute,1060 value,1061 )1062 try:1063 self.execute_script(script)1064 except Exception:1065 pass1066 def set_attribute_all(1067 self, selector, attribute, value, by=By.CSS_SELECTOR1068 ):1069 """Same as set_attributes(), but using querySelectorAll naming scheme.1070 This method uses JavaScript to set/update a common attribute.1071 All matching selectors from querySelectorAll() are used.1072 Example => (Make all links on a website redirect to Google):1073 self.set_attribute_all("a", "href", "https://google.com")"""1074 self.set_attributes(selector, attribute, value, by=by)1075 def remove_attribute(1076 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1077 timeout: OptionalInt = None,1078 attribute_name: str = Field(..., min_length=1)1079 ):1080 self.__check_scope__()1081 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1082 if self.is_element_visible(how, selector):1083 try:1084 self.scroll_to(how, selector, timeout=timeout)1085 except WebDriverException:1086 pass1087 attribute = re.escape(attribute_name)1088 attribute = shared.escape_quotes_if_needed(attribute)1089 css_selector = self.convert_to_css_selector(selector, by=by)1090 css_selector = re.escape(css_selector) # Add "\\" to special chars1091 css_selector = shared.escape_quotes_if_needed(css_selector)1092 script = f"document.querySelector('{css_selector}').removeAttribute('{attribute_name}');"1093 self.execute_script(script)1094 def remove_attributes(1095 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1096 attribute_name: str = Field(..., min_length=1)1097 ) -> None:1098 """This method uses JavaScript to remove a common attribute.1099 All matching selectors from querySelectorAll() are used."""1100 self.__check_scope__()1101 attribute = re.escape(attribute_name)1102 attribute = shared.escape_quotes_if_needed(attribute)1103 css_selector = self.convert_to_css_selector(how, selector)1104 css_selector = re.escape(css_selector) # Add "\\" to special chars1105 css_selector = shared.escape_quotes_if_needed(css_selector)1106 script = """var $elements = document.querySelectorAll('%s');1107 var index = 0, length = $elements.length;1108 for(; index < length; index++){1109 $elements[index].removeAttribute('%s');}""" % (css_selector, attribute_name)1110 try:1111 self.execute_script(script)1112 except WebDriverException | JavascriptException as e:1113 logger.warning(1114 "Exception {} caught while removing attribute from element ->\n{}",1115 e.__class__.__qualname__, str(e)1116 )1117 pass1118 def has_attribute(1119 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1120 timeout: OptionalInt = None,1121 attribute_name: str = Field(..., min_length=1)1122 ) -> bool:1123 self.__check_scope__()1124 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1125 element = element_actions.wait_for_element_present(self.driver, how, selector, timeout)1126 return element_actions.has_attribute(element, attribute_name)1127 def get_property(1128 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1129 property_name=Field(..., min_length=1),1130 timeout: OptionalInt = None1131 ) -> Optional[Any]:1132 """Returns the property value of an element.1133 This is not the same as self.get_property_value(), which returns1134 the value of an element's computed style using a different algorithm.1135 If no result is found, an empty string (instead of None) is returned.1136 Example:1137 html_text = self.get_property(SELECTOR, "textContent")1138 """1139 self.__check_scope__()1140 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1141 self.wait_for_ready_state_complete()1142 time.sleep(0.01)1143 element = element_actions.wait_for_element_present(self.driver, how, selector, timeout)1144 return element.get_property(property).strip()1145 @validate_arguments1146 def get_text_content(1147 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1148 property_name = Field(..., min_length=1),1149 timeout: OptionalInt = None1150 ) -> str:1151 """Returns the text that appears in the HTML for an element.1152 This is different from "self.get_text(selector, by=By.CSS_SELECTOR)"1153 because that only returns the visible text on a page for an element,1154 rather than the HTML text that's being returned from this method."""1155 self.__check_scope__()1156 return self.get_property(how, selector, property_name, timeout)1157 def get_property_value(1158 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1159 timeout: OptionalInt = None1160 ) -> Any:1161 """Returns the property value of a page element's computed style.1162 Example:1163 opacity = self.get_property_value("html body a", "opacity")1164 self.assertTrue(float(opacity) > 0, "Element not visible!")"""1165 self.__check_scope__()1166 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1167 self.wait_for_ready_state_complete()1168 element_actions.wait_for_element_present(self.driver, how, selector, timeout)1169 try:1170 selector = self.convert_to_css_selector(how, selector)1171 except Exception:1172 # Don't run action if can't convert to CSS_Selector for JavaScript1173 raise WebDriverException(1174 "Exception: Could not convert {how=how}({selector}) to CSS_SELECTOR!"1175 )1176 selector = re.escape(selector)1177 selector = shared.escape_quotes_if_needed(selector)1178 script = """var $elm = document.querySelector('%s');1179 $val = window.getComputedStyle($elm).getPropertyValue('%s');1180 return $val;""" % (1181 selector,1182 property,1183 )1184 value = self.execute_script(script)1185 if value is not None:1186 return value1187 else:1188 return "" # Return an empty string if the property doesn't exist1189 def get_image_url(1190 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1191 timeout: OptionalInt = None1192 ):1193 """ Extracts the URL from an image element on the page. """1194 self.__check_scope__()1195 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1196 return self.get_attribute(how, selector, "src", timeout)1197 def find_elements(1198 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1), limit=01199 ) -> List[WebElement]:1200 """Returns a list of matching WebElements.1201 Elements could be either hidden or visible on the page.1202 If "limit" is set and > 0, will only return that many elements."""1203 self.wait_for_ready_state_complete()1204 time.sleep(0.05)1205 elements = element_actions.find_elements(self.driver, how, selector)1206 if 0 < limit < len(elements):1207 elements = elements[:limit]1208 return elements1209 @validate_arguments1210 def find_visible_elements(1211 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1), limit=0):1212 """Returns a list of matching WebElements that are visible.1213 If "limit" is set and > 0, will only return that many elements."""1214 self.__check_scope__()1215 self.wait_for_ready_state_complete()1216 time.sleep(0.05)1217 v_elems = page_actions.find_visible_elements(self.driver, selector, by)1218 if limit and limit > 0 and len(v_elems) > limit:1219 v_elems = v_elems[:limit]1220 return v_elems1221 @validate_arguments1222 def click_visible_elements(1223 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1224 limit: int = 0, timeout: OptionalInt = None1225 ) -> None:1226 """Finds all matching page elements and clicks visible ones in order.1227 If a click reloads or opens a new page, the clicking will stop.1228 If no matching elements appear, an Exception will be raised.1229 If "limit" is set and > 0, will only click that many elements.1230 Also clicks elements that become visible from previous clicks.1231 Works best for actions such as clicking all checkboxes on a page.1232 """1233 self.__check_scope__()1234 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1235 self.wait_for_element_present(how, selector, timeout=timeout)1236 elements = self.find_elements(how, selector)1237 if self.driver.capabilities.get("browserName") == "safari":1238 if not limit:1239 limit = 01240 num_elements = len(elements)1241 if num_elements == 0:1242 raise Exception(1243 "No matching elements found for selector {%s}!" % selector1244 )1245 elif num_elements < limit or limit == 0:1246 limit = num_elements1247 css_selector = self.convert_to_css_selector(selector, by=by)1248 last_css_chunk = css_selector.split(" ")[-1]1249 if ":" in last_css_chunk:1250 self.__js_click_all(css_selector)1251 self.wait_for_ready_state_complete()1252 return1253 else:1254 for i in range(1, limit + 1):1255 new_selector = css_selector + ":nth-of-type(%s)" % str(i)1256 if self.is_element_visible(new_selector):1257 self.__js_click(new_selector)1258 self.wait_for_ready_state_complete()1259 return1260 pre_action_url = self.driver.current_url1261 pre_window_count = len(self.driver.window_handles)1262 click_count = 01263 for element in elements:1264 if limit and 0 < limit <= click_count:1265 return1266 try:1267 if element.is_displayed():1268 self.__scroll_to_element(element)1269 element.click()1270 click_count += 11271 self.wait_for_ready_state_complete()1272 except ElementClickInterceptedException:1273 continue1274 except (StaleElementReferenceException, ElementNotInteractableException):1275 self.wait_for_ready_state_complete()1276 time.sleep(0.12)1277 try:1278 if element.is_displayed():1279 self.__scroll_to_element(element)1280 element.click()1281 click_count += 11282 self.wait_for_ready_state_complete()1283 except (StaleElementReferenceException, ElementNotInteractableException):1284 latest_window_count = len(self.driver.window_handles)1285 if (1286 latest_window_count > pre_window_count1287 and (1288 self.recorder_mode1289 or (1290 settings.SWITCH_TO_NEW_TABS_ON_CLICK1291 and self.driver.current_url == pre_action_url1292 )1293 )1294 ):1295 self.__switch_to_newest_window_if_not_blank()1296 return # Probably on new page / Elements are all stale1297 latest_window_count = len(self.driver.window_handles)1298 if (1299 latest_window_count > pre_window_count1300 and (1301 self.recorder_mode1302 or (1303 settings.SWITCH_TO_NEW_TABS_ON_CLICK1304 and self.driver.current_url == pre_action_url1305 )1306 )1307 ):1308 self.__switch_to_newest_window_if_not_blank()1309 def click_nth_visible_element(1310 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1311 number: int = 0, timeout: OptionalInt = None1312 ):1313 """Finds all matching page elements and clicks the nth visible one.1314 Example: self.click_nth_visible_element('[type="checkbox"]', 5)1315 (Clicks the 5th visible checkbox on the page.)"""1316 self.__check_scope__()1317 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1318 self.wait_for_ready_state_complete()1319 self.wait_for_element_present(how, selector, timeout=timeout)1320 elements = self.find_visible_elements(how, selector)1321 if len(elements) < number:1322 raise WebDriverException(1323 f"Not enough matching {selector} elements of type {how.upper()} to "1324 f"click number {number}!"1325 )1326 number = number - 11327 if number < 0:1328 number = 01329 element = elements[number]1330 pre_action_url = self.driver.current_url1331 pre_window_count = len(self.driver.window_handles)1332 try:1333 self.__scroll_to_element(element)1334 element.click()1335 except (StaleElementReferenceException, ElementNotInteractableException):1336 time.sleep(0.12)1337 self.wait_for_ready_state_complete()1338 self.wait_for_element_present(how, selector, timeout=timeout)1339 elements = self.find_visible_elements(how, selector)1340 if len(elements) < number:1341 raise WebDriverException(1342 f"Not enough matching {selector} elements of type {how} to click number {number}!"1343 )1344 number = number - 11345 if number < 0:1346 number = 01347 element = elements[number]1348 element.click()1349 latest_window_count = len(self.driver.window_handles)1350 if (1351 latest_window_count > pre_window_count1352 and (1353 self.recorder_mode1354 or (1355 settings.SWITCH_TO_NEW_TABS_ON_CLICK1356 and self.driver.current_url == pre_action_url1357 )1358 )1359 ):1360 self.__switch_to_newest_window_if_not_blank()1361 def click_if_visible(1362 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)1363 ) -> None:1364 """If the page selector exists and is visible, clicks on the element.1365 This method only clicks on the first matching element found.1366 (Use click_visible_elements() to click all matching elements.)"""1367 self.wait_for_ready_state_complete()1368 if self.is_element_visible(how, selector):1369 self.click(how, selector)1370 def click_active_element(self):1371 self.wait_for_ready_state_complete()1372 pre_action_url = self.driver.current_url1373 pre_window_count = len(self.driver.window_handles)1374 self.execute_script("document.activeElement.click();")1375 latest_window_count = len(self.driver.window_handles)1376 if (1377 latest_window_count > pre_window_count1378 and (1379 self.recorder_mode1380 or (1381 settings.SWITCH_TO_NEW_TABS_ON_CLICK1382 and self.driver.current_url == pre_action_url1383 )1384 )1385 ):1386 self.__switch_to_newest_window_if_not_blank()1387 if settings.WAIT_FOR_RSC_ON_CLICKS:1388 self.wait_for_ready_state_complete()1389 else:1390 # A smaller subset of self.wait_for_ready_state_complete()1391 self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT)1392 if self.driver.current_url != pre_action_url:1393 self.__ad_block_as_needed()1394 if self.demo_mode:1395 if self.driver.current_url != pre_action_url:1396 self._demo_mode_pause_if_active()1397 else:1398 self._demo_mode_pause_if_active(tiny=True)1399 elif self.slow_mode:1400 self._slow_mode_pause_if_active()1401 @validate_arguments1402 def is_checked(1403 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1404 timeout: OptionalInt = None1405 ):1406 """Determines if a checkbox or a radio button element is checked.1407 Returns True if the element is checked.1408 Returns False if the element is not checked.1409 If the element is not present on the page, raises an exception.1410 If the element is not a checkbox or radio, raises an exception."""1411 self.__check_scope__()1412 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1413 kind = self.get_attribute(selector, "type", by=by, timeout=timeout)1414 if kind != "checkbox" and kind != "radio":1415 raise Exception("Expecting a checkbox or a radio button element!")1416 is_checked = self.get_attribute(1417 selector, "checked", by=by, timeout=timeout, hard_fail=False1418 )1419 if is_checked:1420 return True1421 else: # (NoneType)1422 return False1423 def is_selected(1424 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1),1425 timeout: OptionalInt = None1426 ):1427 """ Same as is_checked() """1428 return self.is_checked(how, selector, timeout=timeout)1429 def check_if_unchecked(self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)):1430 """ If a checkbox or radio button is not checked, will check it. """1431 self.__check_scope__()1432 if not self.is_checked(how, selector):1433 if self.is_element_visible(how, selector):1434 self.click(how, selector)1435 else:1436 selector = self.convert_to_css_selector(how, selector)1437 self.js_click(By.CSS_SELECTOR, selector)1438 def select_if_unselected(self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)):1439 """ Same as check_if_unchecked() """1440 self.check_if_unchecked(how, selector)1441 def uncheck_if_checked(1442 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)1443 ):1444 """ If a checkbox is checked, will uncheck it. """1445 self.__check_scope__()1446 if self.is_checked(how, selector):1447 if self.is_element_visible(how, selector):1448 self.click(how, selector)1449 else:1450 selector = self.convert_to_css_selector(selector, by=by)1451 self.__dont_record_js_click = True1452 self.js_click(selector, by=By.CSS_SELECTOR)1453 self.__dont_record_js_click = False1454 def unselect_if_selected(self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)):1455 """ Same as uncheck_if_checked() """1456 self.uncheck_if_checked(how, selector)1457 def is_element_in_an_iframe(1458 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)1459 ):1460 """Returns True if the selector's element is located in an iframe.1461 Otherwise returns False."""1462 self.__check_scope__()1463 if self.is_element_present(how, selector):1464 return False1465 soup = self.get_beautiful_soup()1466 iframe_list = soup.select("iframe")1467 for iframe in iframe_list:1468 iframe_identifier = None1469 if iframe.has_attr("name") and len(iframe["name"]) > 0:1470 iframe_identifier = iframe["name"]1471 elif iframe.has_attr("id") and len(iframe["id"]) > 0:1472 iframe_identifier = iframe["id"]1473 elif iframe.has_attr("class") and len(iframe["class"]) > 0:1474 iframe_class = " ".join(iframe["class"])1475 iframe_identifier = '[class="%s"]' % iframe_class1476 else:1477 continue1478 self.switch_to_frame(iframe_identifier)1479 if self.is_element_present(how, selector):1480 self.switch_to_default_content()1481 return True1482 self.switch_to_default_content()1483 return False1484 def switch_to_frame_of_element(1485 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)1486 ) -> None:1487 """Set driver control to the iframe containing element (assuming the1488 element is in a single-nested iframe) and returns the iframe name.1489 If element is not in an iframe, returns None, and nothing happens.1490 May not work if multiple iframes are nested within each other."""1491 self.__check_scope__()1492 if self.is_element_present(how, selector):1493 return None1494 soup = self.get_beautiful_soup()1495 iframe_list = soup.select("iframe")1496 for iframe in iframe_list:1497 iframe_identifier = None1498 if iframe.has_attr("name") and len(iframe["name"]) > 0:1499 iframe_identifier = iframe["name"]1500 elif iframe.has_attr("id") and len(iframe["id"]) > 0:1501 iframe_identifier = iframe["id"]1502 elif iframe.has_attr("class") and len(iframe["class"]) > 0:1503 iframe_class = " ".join(iframe["class"])1504 iframe_identifier = '[class="%s"]' % iframe_class1505 else:1506 continue1507 try:1508 self.switch_to_frame(iframe_identifier, timeout=1)1509 if self.is_element_present(selector, by=by):1510 return iframe_identifier1511 except Exception:1512 pass1513 self.switch_to_default_content()1514 try:1515 self.switch_to_frame(selector, timeout=1)1516 return selector1517 except Exception:1518 if self.is_element_present(selector, by=by):1519 return ""1520 raise Exception(1521 "Could not switch to iframe containing "1522 "element {%s}!" % selector1523 )1524 def hover_on_element(1525 self, how: SeleniumBy, selector: str = Field(..., strict=True, min_length=1)1526 ):1527 self.__check_scope__()1528 if page_utils.is_xpath_selector(selector):1529 selector = self.convert_to_css_selector(selector, By.XPATH)1530 by = By.CSS_SELECTOR1531 self.wait_for_element_visible(how, selector, timeout=settings.SMALL_TIMEOUT)1532 self.__demo_mode_highlight_if_active(how, selector)1533 self.scroll_to(how, selector)1534 time.sleep(0.05) # Settle down from scrolling before hovering1535 if self.browser != "chrome":1536 return page_actions.hover_on_element(self.driver, selector)1537 # Using Chrome1538 # (Pure hover actions won't work on early chromedriver versions)1539 try:1540 return page_actions.hover_on_element(self.driver, selector)1541 except WebDriverException as e:1542 driver_capabilities = self.driver.capabilities1543 if "version" in driver_capabilities:1544 chrome_version = driver_capabilities["version"]1545 else:1546 chrome_version = driver_capabilities["browserVersion"]1547 major_chrome_version = chrome_version.split(".")[0]1548 chrome_dict = self.driver.capabilities["chrome"]1549 chromedriver_version = chrome_dict["chromedriverVersion"]1550 chromedriver_version = chromedriver_version.split(" ")[0]1551 major_chromedriver_version = chromedriver_version.split(".")[0]1552 install_sb = (1553 "seleniumbase install chromedriver %s" % major_chrome_version1554 )1555 if major_chromedriver_version < major_chrome_version:1556 # Upgrading the driver is required for performing hover actions1557 message = (1558 "\n"1559 "You need a newer chromedriver to perform hover actions!\n"1560 "Your version of chromedriver is: %s\n"1561 "And your version of Chrome is: %s\n"1562 "You can fix this issue by running:\n>>> %s\n"1563 % (chromedriver_version, chrome_version, install_sb)1564 )1565 raise Exception(message)1566 else:1567 raise Exception(e)1568 def hover_and_click(1569 self,1570 hover_selector,1571 click_selector,1572 hover_by=By.CSS_SELECTOR,1573 click_by=By.CSS_SELECTOR,1574 timeout=None,1575 ):1576 """When you want to hover over an element or dropdown menu,1577 and then click an element that appears after that."""1578 self.__check_scope__()1579 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1580 original_selector = hover_selector1581 original_by = hover_by1582 hover_selector = self.convert_to_css_selector(hover_selector, hover_by)1583 hover_by = By.CSS_SELECTOR1584 dropdown_element = self.wait_for_element_visible(1585 hover_selector, by=hover_by, timeout=timeout1586 )1587 self.__demo_mode_highlight_if_active(original_selector, original_by)1588 self.scroll_to(hover_selector, by=hover_by)1589 pre_action_url = self.driver.current_url1590 pre_window_count = len(self.driver.window_handles)1591 outdated_driver = False1592 element = None1593 try:1594 if self.mobile_emulator:1595 # On mobile, click to hover the element1596 dropdown_element.click()1597 elif self.browser == "safari":1598 # Use the workaround for hover-clicking on Safari1599 raise Exception("This Exception will be caught.")1600 else:1601 page_actions.hover_element(self.driver, dropdown_element)1602 except Exception:1603 outdated_driver = True1604 element = self.wait_for_element_present(1605 click_selector, click_by, timeout1606 )1607 if click_by == By.LINK_TEXT:1608 self.open(self.__get_href_from_link_text(click_selector))1609 elif click_by == By.PARTIAL_LINK_TEXT:1610 self.open(1611 self.__get_href_from_partial_link_text(click_selector)1612 )1613 else:1614 self.js_click(click_selector, by=click_by)1615 if outdated_driver:1616 pass # Already did the click workaround1617 elif self.mobile_emulator:1618 self.click(click_selector, by=click_by)1619 elif not outdated_driver:1620 element = page_actions.hover_and_click(1621 self.driver,1622 hover_selector,1623 click_selector,1624 hover_by,1625 click_by,1626 timeout,1627 )1628 latest_window_count = len(self.driver.window_handles)1629 if (1630 latest_window_count > pre_window_count1631 and (1632 self.recorder_mode1633 or (1634 settings.SWITCH_TO_NEW_TABS_ON_CLICK1635 and self.driver.current_url == pre_action_url1636 )1637 )1638 ):1639 self.__switch_to_newest_window_if_not_blank()1640 if self.demo_mode:1641 if self.driver.current_url != pre_action_url:1642 self._demo_mode_pause_if_active()1643 else:1644 self._demo_mode_pause_if_active(tiny=True)1645 elif self.slow_mode:1646 self._slow_mode_pause_if_active()1647 return element1648 def hover_and_double_click(1649 self,1650 hover_selector,1651 click_selector,1652 hover_by=By.CSS_SELECTOR,1653 click_by=By.CSS_SELECTOR,1654 timeout=None,1655 ):1656 """When you want to hover over an element or dropdown menu,1657 and then double-click an element that appears after that."""1658 self.__check_scope__()1659 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1660 original_selector = hover_selector1661 original_by = hover_by1662 hover_selector, hover_by = self.__recalculate_selector(1663 hover_selector, hover_by1664 )1665 hover_selector = self.convert_to_css_selector(hover_selector, hover_by)1666 hover_by = By.CSS_SELECTOR1667 click_selector, click_by = self.__recalculate_selector(1668 click_selector, click_by1669 )1670 dropdown_element = self.wait_for_element_visible(1671 hover_selector, by=hover_by, timeout=timeout1672 )1673 self.__demo_mode_highlight_if_active(original_selector, original_by)1674 self.scroll_to(hover_selector, by=hover_by)1675 pre_action_url = self.driver.current_url1676 pre_window_count = len(self.driver.window_handles)1677 outdated_driver = False1678 element = None1679 try:1680 page_actions.hover_element(self.driver, dropdown_element)1681 except Exception:1682 outdated_driver = True1683 element = self.wait_for_element_present(1684 click_selector, click_by, timeout1685 )1686 if click_by == By.LINK_TEXT:1687 self.open(self.__get_href_from_link_text(click_selector))1688 elif click_by == By.PARTIAL_LINK_TEXT:1689 self.open(1690 self.__get_href_from_partial_link_text(click_selector)1691 )1692 else:1693 self.__dont_record_js_click = True1694 self.js_click(click_selector, click_by)1695 self.__dont_record_js_click = False1696 if not outdated_driver:1697 element = page_actions.hover_element_and_double_click(1698 self.driver,1699 dropdown_element,1700 click_selector,1701 click_by=By.CSS_SELECTOR,1702 timeout=timeout,1703 )1704 latest_window_count = len(self.driver.window_handles)1705 if (1706 latest_window_count > pre_window_count1707 and (1708 self.recorder_mode1709 or (1710 settings.SWITCH_TO_NEW_TABS_ON_CLICK1711 and self.driver.current_url == pre_action_url1712 )1713 )1714 ):1715 self.__switch_to_newest_window_if_not_blank()1716 if self.demo_mode:1717 if self.driver.current_url != pre_action_url:1718 self._demo_mode_pause_if_active()1719 else:1720 self._demo_mode_pause_if_active(tiny=True)1721 elif self.slow_mode:1722 self._slow_mode_pause_if_active()1723 return element1724 def drag_and_drop(1725 self,1726 drag_selector,1727 drop_selector,1728 drag_by=By.CSS_SELECTOR,1729 drop_by=By.CSS_SELECTOR,1730 timeout=None,1731 ):1732 """ Drag and drop an element from one selector to another. """1733 self.__check_scope__()1734 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1735 drag_element = self.wait_for_element_visible(1736 drag_selector, by=drag_by, timeout=timeout1737 )1738 self.__demo_mode_highlight_if_active(drag_selector, drag_by)1739 self.wait_for_element_visible(1740 drop_selector, by=drop_by, timeout=timeout1741 )1742 self.__demo_mode_highlight_if_active(drop_selector, drop_by)1743 self.scroll_to(drag_selector, by=drag_by)1744 drag_selector = self.convert_to_css_selector(drag_selector, drag_by)1745 drop_selector = self.convert_to_css_selector(drop_selector, drop_by)1746 drag_and_drop_script = js_utils.get_drag_and_drop_script()1747 self.safe_execute_script(1748 drag_and_drop_script1749 + (1750 "$('%s').simulateDragDrop("1751 "{dropTarget: "1752 "'%s'});" % (drag_selector, drop_selector)1753 )1754 )1755 if self.demo_mode:1756 self._demo_mode_pause_if_active()1757 elif self.slow_mode:1758 self._slow_mode_pause_if_active()1759 return drag_element1760 def drag_and_drop_with_offset(1761 self, selector, x, y, by=By.CSS_SELECTOR, timeout=None1762 ):1763 """ Drag and drop an element to an {X,Y}-offset location. """1764 self.__check_scope__()1765 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1766 css_selector = self.convert_to_css_selector(selector, by=by)1767 element = self.wait_for_element_visible(css_selector, timeout=timeout)1768 self.__demo_mode_highlight_if_active(css_selector, By.CSS_SELECTOR)1769 css_selector = re.escape(css_selector) # Add "\\" to special chars1770 css_selector = shared.escape_quotes_if_needed(css_selector)1771 script = js_utils.get_drag_and_drop_with_offset_script(1772 css_selector, x, y1773 )1774 self.safe_execute_script(script)1775 if self.demo_mode:1776 self._demo_mode_pause_if_active()1777 elif self.slow_mode:1778 self._slow_mode_pause_if_active()1779 return element1780 def __select_option(1781 self,1782 dropdown_selector,1783 option,1784 dropdown_by=By.CSS_SELECTOR,1785 option_by="text",1786 timeout=None,1787 ):1788 """Selects an HTML <select> option by specification.1789 Option specifications are by "text", "index", or "value".1790 Defaults to "text" if option_by is unspecified or unknown."""1791 from selenium.webdriver.support.ui import Select1792 self.__check_scope__()1793 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1794 self.wait_for_ready_state_complete()1795 element = self.wait_for_element_present(1796 dropdown_selector, by=dropdown_by, timeout=timeout1797 )1798 if self.is_element_visible(dropdown_selector, by=dropdown_by):1799 self.__demo_mode_highlight_if_active(1800 dropdown_selector, dropdown_by1801 )1802 pre_action_url = self.driver.current_url1803 pre_window_count = len(self.driver.window_handles)1804 try:1805 if option_by == "index":1806 Select(element).select_by_index(option)1807 elif option_by == "value":1808 Select(element).select_by_value(option)1809 else:1810 Select(element).select_by_visible_text(option)1811 except (StaleElementReferenceException, ElementNotInteractableException):1812 self.wait_for_ready_state_complete()1813 time.sleep(0.14)1814 element = self.wait_for_element_present(1815 dropdown_selector, by=dropdown_by, timeout=timeout1816 )1817 if option_by == "index":1818 Select(element).select_by_index(option)1819 elif option_by == "value":1820 Select(element).select_by_value(option)1821 else:1822 Select(element).select_by_visible_text(option)1823 latest_window_count = len(self.driver.window_handles)1824 if (1825 latest_window_count > pre_window_count1826 and (1827 self.recorder_mode1828 or (1829 settings.SWITCH_TO_NEW_TABS_ON_CLICK1830 and self.driver.current_url == pre_action_url1831 )1832 )1833 ):1834 self.__switch_to_newest_window_if_not_blank()1835 if settings.WAIT_FOR_RSC_ON_CLICKS:1836 self.wait_for_ready_state_complete()1837 else:1838 # A smaller subset of self.wait_for_ready_state_complete()1839 self.wait_for_angularjs(timeout=settings.MINI_TIMEOUT)1840 if self.demo_mode:1841 if self.driver.current_url != pre_action_url:1842 self._demo_mode_pause_if_active()1843 else:1844 self._demo_mode_pause_if_active(tiny=True)1845 elif self.slow_mode:1846 self._slow_mode_pause_if_active()1847 def select_option_by_text(1848 self,1849 dropdown_selector,1850 option,1851 dropdown_by=By.CSS_SELECTOR,1852 timeout=None,1853 ):1854 """Selects an HTML <select> option by option text.1855 @Params1856 dropdown_selector - the <select> selector.1857 option - the text of the option.1858 """1859 self.__check_scope__()1860 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1861 self.__select_option(1862 dropdown_selector,1863 option,1864 dropdown_by=dropdown_by,1865 option_by="text",1866 timeout=timeout,1867 )1868 def select_option_by_index(1869 self,1870 dropdown_selector,1871 option,1872 dropdown_by=By.CSS_SELECTOR,1873 timeout=None,1874 ):1875 """Selects an HTML <select> option by option index.1876 @Params1877 dropdown_selector - the <select> selector.1878 option - the index number of the option.1879 """1880 self.__check_scope__()1881 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1882 self.__select_option(1883 dropdown_selector,1884 option,1885 dropdown_by=dropdown_by,1886 option_by="index",1887 timeout=timeout,1888 )1889 def select_option_by_value(1890 self,1891 dropdown_selector,1892 option,1893 dropdown_by=By.CSS_SELECTOR,1894 timeout=None,1895 ):1896 """Selects an HTML <select> option by option value.1897 @Params1898 dropdown_selector - the <select> selector.1899 option - the value property of the option.1900 """1901 self.__check_scope__()1902 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1903 self.__select_option(1904 dropdown_selector,1905 option,1906 dropdown_by=dropdown_by,1907 option_by="value",1908 timeout=timeout,1909 )1910 def set_content(self, html_string, new_page=False):1911 """ Same as load_html_string(), but "new_page" defaults to False. """1912 self.load_html_string(html_string, new_page=new_page)1913 def load_html_file(self, html_file, new_page=True):1914 """Loads a local html file into the browser from a relative file path.1915 If new_page==True, the page will switch to: "data:text/html,"1916 If new_page==False, will load HTML into the current page.1917 Local images and other local src content WILL BE IGNORED.1918 """1919 self.__check_scope__()1920 if self.__looks_like_a_page_url(html_file):1921 self.open(html_file)1922 return1923 if len(html_file) < 6 or not html_file.endswith(".html"):1924 raise Exception('Expecting a ".html" file!')1925 abs_path = os.path.abspath(".")1926 file_path = None1927 if abs_path in html_file:1928 file_path = html_file1929 else:1930 file_path = abs_path + "/%s" % html_file1931 html_string = None1932 with open(file_path, "r") as f:1933 html_string = f.read().strip()1934 self.load_html_string(html_string, new_page)1935 def open_html_file(self, html_file):1936 """Opens a local html file into the browser from a relative file path.1937 The URL displayed in the web browser will start with "file://".1938 """1939 self.__check_scope__()1940 if self.__looks_like_a_page_url(html_file):1941 self.open(html_file)1942 return1943 if len(html_file) < 6 or not html_file.endswith(".html"):1944 raise Exception('Expecting a ".html" file!')1945 abs_path = os.path.abspath(".")1946 file_path = None1947 if abs_path in html_file:1948 file_path = html_file1949 else:1950 file_path = abs_path + "/%s" % html_file1951 self.open("file://" + file_path)1952 @validate_arguments1953 def set_window_rect(self, x: int, y: int, width: int, height: int):1954 self.__check_scope__()1955 self.driver.set_window_rect(x, y, width, height)1956 self._demo_mode_pause_if_active()1957 @validate_arguments1958 def set_window_size(self, width: int, height: int):1959 self.__check_scope__()1960 self.driver.set_window_size(width, height)1961 self._demo_mode_pause_if_active()1962 def maximize_window(self):1963 self.__check_scope__()1964 self.driver.maximize_window()1965 self._demo_mode_pause_if_active()1966 def fullscreen_window(self):1967 self.__check_scope__()1968 self.driver.fullscreen()1969 self._demo_mode_pause_if_active()1970 def switch_to_frame(self, frame, timeout=None):1971 """Wait for an iframe to appear, and switch to it. This should be1972 usable as a drop-in replacement for driver.switch_to.frame().1973 The iframe identifier can be a selector, an index, an id, a name,1974 or a web element, but scrolling to the iframe first will only occur1975 for visible iframes with a string selector.1976 @Params1977 frame - the frame element, name, id, index, or selector1978 timeout - the time to wait for the alert in seconds1979 """1980 self.__check_scope__()1981 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)1982 if type(frame) is str and self.is_element_visible(frame):1983 try:1984 self.scroll_to(frame, timeout=1)1985 except Exception:1986 pass1987 page_actions.switch_to_frame(self.driver, frame, timeout)1988 def switch_to_default_content(self):1989 """Brings driver control outside the current iframe.1990 (If the driver control is inside an iframe, the driver control1991 will be set to one level above the current frame. If the driver1992 control is not currently in an iframe, nothing will happen.)"""1993 self.__check_scope__()1994 self.driver.switch_to.default_content()1995 def set_content_to_frame(self, frame, timeout=None):1996 """Replaces the page html with an iframe's html from that page.1997 If the iFrame contains an "src" field that includes a valid URL,1998 then instead of replacing the current html, this method will then1999 open up the "src" URL of the iFrame in a new browser tab.2000 To return to default content, use: self.set_content_to_default().2001 This method also sets the state of the browser window so that the2002 self.set_content_to_default() method can bring the user back to2003 the original content displayed, which is similar to how the methods2004 self.switch_to_frame(frame) and self.switch_to_default_content()2005 work together to get the user into frames and out of all of them.2006 """2007 self.__check_scope__()2008 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)2009 current_url = self.get_current_url()2010 c_tab = self.driver.current_window_handle2011 current_page_source = self.get_page_source()2012 self.execute_script("document.cframe_swap = 0;")2013 page_actions.switch_to_frame(self.driver, frame, timeout)2014 iframe_html = self.get_page_source()2015 self.driver.switch_to.default_content()2016 self.wait_for_ready_state_complete()2017 frame_found = False2018 o_frame = frame2019 if self.is_element_present(frame):2020 frame_found = True2021 elif " " not in frame:2022 frame = 'iframe[name="%s"]' % frame2023 if self.is_element_present(frame):2024 frame_found = True2025 url = None2026 if frame_found:2027 url = self.execute_script(2028 """return document.querySelector('%s').src;""" % frame2029 )2030 if not python3:2031 url = str(url)2032 if url and len(url) > 0:2033 if ("http:") in url or ("https:") in url or ("file:") in url:2034 pass2035 else:2036 url = None2037 cframe_tab = False2038 if url:2039 cframe_tab = True2040 self.__page_sources.append([current_url, current_page_source, c_tab])2041 if cframe_tab:2042 self.execute_script("document.cframe_tab = 1;")2043 self.open_new_window(switch_to=True)2044 self.open(url)2045 self.execute_script("document.cframe_tab = 1;")2046 else:2047 self.set_content(iframe_html)2048 if not self.execute_script("return document.cframe_swap;"):2049 self.execute_script("document.cframe_swap = 1;")2050 else:2051 self.execute_script("document.cframe_swap += 1;")2052 def set_content_to_default(self, nested=True):2053 """After using self.set_content_to_frame(), this reverts the page back.2054 If self.set_content_to_frame() hasn't been called here, only refreshes.2055 If "nested" is set to False when the content was set to nested iFrames,2056 then the control will only move above the last iFrame that was entered.2057 """2058 self.__check_scope__()2059 swap_cnt = self.execute_script("return document.cframe_swap;")2060 tab_sta = self.execute_script("return document.cframe_tab;")2061 if nested:2062 if (2063 len(self.__page_sources) > 02064 and (2065 (swap_cnt and int(swap_cnt) > 0)2066 or (tab_sta and int(tab_sta) > 0)2067 )2068 ):2069 past_content = self.__page_sources[0]2070 past_url = past_content[0]2071 past_source = past_content[1]2072 past_tab = past_content[2]2073 current_tab = self.driver.current_window_handle2074 if not current_tab == past_tab:2075 if past_tab in self.driver.window_handles:2076 self.switch_to_window(past_tab)2077 url_of_past_tab = self.get_current_url()2078 if url_of_past_tab == past_url:2079 self.set_content(past_source)2080 else:2081 self.refresh_page()2082 else:2083 self.refresh_page()2084 self.execute_script("document.cframe_swap = 0;")2085 self.__page_sources = []2086 else:2087 just_refresh = False2088 if swap_cnt and int(swap_cnt) > 0 and len(self.__page_sources) > 0:2089 self.execute_script("document.cframe_swap -= 1;")2090 current_url = self.get_current_url()2091 past_content = self.__page_sources.pop()2092 past_url = past_content[0]2093 past_source = past_content[1]2094 if current_url == past_url:2095 self.set_content(past_source)2096 else:2097 just_refresh = True2098 elif tab_sta and int(tab_sta) > 0 and len(self.__page_sources) > 0:2099 past_content = self.__page_sources.pop()2100 past_tab = past_content[2]2101 if past_tab in self.driver.window_handles:2102 self.switch_to_window(past_tab)2103 else:2104 just_refresh = True2105 else:2106 just_refresh = True2107 if just_refresh:2108 self.refresh_page()2109 self.execute_script("document.cframe_swap = 0;")2110 self.__page_sources = []2111 def open_new_window(self, switch_to=True):2112 """ Opens a new browser tab/window and switches to it by default. """2113 self.__check_scope__()2114 self.__check_browser() # Current window must exist to open a new one2115 self.driver.execute_script("window.open('');")2116 time.sleep(0.01)2117 if switch_to:2118 self.switch_to_newest_window()2119 time.sleep(0.01)2120 if self.browser == "safari":2121 self.wait_for_ready_state_complete()2122 def switch_to_window(self, window, timeout=None):2123 """ Switches control of the browser to the specified window.2124 The window can be an integer: 0 -> 1st tab, 1 -> 2nd tab, etc...2125 Or it can be a list item from self.driver.window_handles """2126 self.__check_scope__()2127 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)2128 page_actions.switch_to_window(self.driver, window, timeout)2129 def switch_to_default_window(self):2130 self.switch_to_window(0)2131 def __switch_to_newest_window_if_not_blank(self):2132 current_window = self.driver.current_window_handle2133 try:2134 self.switch_to_window(len(self.driver.window_handles) - 1)2135 if self.get_current_url() == "about:blank":2136 self.switch_to_window(current_window)2137 except Exception:2138 self.switch_to_window(current_window)2139 def switch_to_newest_window(self):2140 self.switch_to_window(len(self.driver.window_handles) - 1)2141 def get_new_driver(2142 self,2143 browser=None,2144 headless=None,2145 locale_code=None,2146 protocol=None,2147 servername=None,2148 port=None,2149 proxy=None,2150 proxy_bypass_list=None,2151 agent=None,2152 switch_to=True,2153 cap_file=None,2154 cap_string=None,2155 recorder_ext=None,2156 disable_csp=None,2157 enable_ws=None,2158 enable_sync=None,2159 use_auto_ext=None,2160 no_sandbox=None,2161 disable_gpu=None,2162 incognito=None,2163 guest_mode=None,2164 devtools=None,2165 remote_debug=None,2166 swiftshader=None,2167 ad_block_on=None,2168 block_images=None,2169 chromium_arg=None,2170 firefox_arg=None,2171 firefox_pref=None,2172 user_data_dir=None,2173 extension_zip=None,2174 extension_dir=None,2175 external_pdf=None,2176 is_mobile=None,2177 d_width=None,2178 d_height=None,2179 d_p_r=None,2180 ):2181 """This method spins up an extra browser for tests that require2182 more than one. The first browser is already provided by tests2183 that import base_case.BaseCase from seleniumbase. If parameters2184 aren't specified, the method uses the same as the default driver.2185 @Params2186 browser - the browser to use. (Ex: "chrome", "firefox")2187 headless - the option to run webdriver in headless mode2188 locale_code - the Language Locale Code for the web browser2189 protocol - if using a Selenium Grid, set the host protocol here2190 servername - if using a Selenium Grid, set the host address here2191 port - if using a Selenium Grid, set the host port here2192 proxy - if using a proxy server, specify the "host:port" combo here2193 proxy_bypass_list - ";"-separated hosts to bypass (Eg. "*.foo.com")2194 switch_to - the option to switch to the new driver (default = True)2195 cap_file - the file containing desired capabilities for the browser2196 cap_string - the string with desired capabilities for the browser2197 recorder_ext - the option to enable the SBase Recorder extension2198 disable_csp - an option to disable Chrome's Content Security Policy2199 enable_ws - the option to enable the Web Security feature (Chrome)2200 enable_sync - the option to enable the Chrome Sync feature (Chrome)2201 use_auto_ext - the option to enable Chrome's Automation Extension2202 no_sandbox - the option to enable the "No-Sandbox" feature (Chrome)2203 disable_gpu - the option to enable Chrome's "Disable GPU" feature2204 incognito - the option to enable Chrome's Incognito mode (Chrome)2205 guest - the option to enable Chrome's Guest mode (Chrome)2206 devtools - the option to open Chrome's DevTools on start (Chrome)2207 remote_debug - the option to enable Chrome's Remote Debugger2208 swiftshader - the option to use Chrome's swiftshader (Chrome-only)2209 ad_block_on - the option to block ads from loading (Chromium-only)2210 block_images - the option to block images from loading (Chrome)2211 chromium_arg - the option to add a Chromium arg to Chrome/Edge2212 firefox_arg - the option to add a Firefox arg to Firefox runs2213 firefox_pref - the option to add a Firefox pref:value set (Firefox)2214 user_data_dir - Chrome's User Data Directory to use (Chrome-only)2215 extension_zip - A Chrome Extension ZIP file to use (Chrome-only)2216 extension_dir - A Chrome Extension folder to use (Chrome-only)2217 external_pdf - "plugins.always_open_pdf_externally": True. (Chrome)2218 is_mobile - the option to use the mobile emulator (Chrome-only)2219 d_width - the device width of the mobile emulator (Chrome-only)2220 d_height - the device height of the mobile emulator (Chrome-only)2221 d_p_r - the device pixel ratio of the mobile emulator (Chrome-only)2222 """2223 self.__check_scope__()2224 if self.browser == "remote" and self.servername == "localhost":2225 raise Exception(2226 'Cannot use "remote" browser driver on localhost!'2227 " Did you mean to connect to a remote Grid server"2228 " such as BrowserStack or Sauce Labs? In that"2229 ' case, you must specify the "server" and "port"'2230 " parameters on the command line! "2231 "Example: "2232 "--server=user:key@hub.browserstack.com --port=80"2233 )2234 browserstack_ref = "https://browserstack.com/automate/capabilities"2235 sauce_labs_ref = (2236 "https://wiki.saucelabs.com/display/DOCS/Platform+Configurator#/"2237 )2238 if self.browser == "remote" and not (self.cap_file or self.cap_string):2239 raise Exception(2240 "Need to specify a desired capabilities file when "2241 'using "--browser=remote". Add "--cap_file=FILE". '2242 "File should be in the Python format used by: "2243 "%s OR "2244 "%s "2245 "See SeleniumBase/examples/sample_cap_file_BS.py "2246 "and SeleniumBase/examples/sample_cap_file_SL.py"2247 % (browserstack_ref, sauce_labs_ref)2248 )2249 if browser is None:2250 browser = self.browser2251 browser_name = browser2252 if headless is None:2253 headless = self.headless2254 if locale_code is None:2255 locale_code = self.locale_code2256 if protocol is None:2257 protocol = self.protocol2258 if servername is None:2259 servername = self.servername2260 if port is None:2261 port = self.port2262 use_grid = False2263 if servername != "localhost":2264 # Use Selenium Grid (Use "127.0.0.1" for localhost Grid)2265 use_grid = True2266 proxy_string = proxy2267 if proxy_string is None:2268 proxy_string = self.proxy_string2269 if proxy_bypass_list is None:2270 proxy_bypass_list = self.proxy_bypass_list2271 user_agent = agent2272 if user_agent is None:2273 user_agent = self.user_agent2274 if recorder_ext is None:2275 recorder_ext = self.recorder_ext2276 if disable_csp is None:2277 disable_csp = self.disable_csp2278 if enable_ws is None:2279 enable_ws = self.enable_ws2280 if enable_sync is None:2281 enable_sync = self.enable_sync2282 if use_auto_ext is None:2283 use_auto_ext = self.use_auto_ext2284 if no_sandbox is None:2285 no_sandbox = self.no_sandbox2286 if disable_gpu is None:2287 disable_gpu = self.disable_gpu2288 if incognito is None:2289 incognito = self.incognito2290 if guest_mode is None:2291 guest_mode = self.guest_mode2292 if devtools is None:2293 devtools = self.devtools2294 if remote_debug is None:2295 remote_debug = self.remote_debug2296 if swiftshader is None:2297 swiftshader = self.swiftshader2298 if ad_block_on is None:2299 ad_block_on = self.ad_block_on2300 if block_images is None:2301 block_images = self.block_images2302 if chromium_arg is None:2303 chromium_arg = self.chromium_arg2304 if firefox_arg is None:2305 firefox_arg = self.firefox_arg2306 if firefox_pref is None:2307 firefox_pref = self.firefox_pref2308 if user_data_dir is None:2309 user_data_dir = self.user_data_dir2310 if extension_zip is None:2311 extension_zip = self.extension_zip2312 if extension_dir is None:2313 extension_dir = self.extension_dir2314 if external_pdf is None:2315 external_pdf = self.external_pdf2316 test_id = self.__get_test_id()2317 if cap_file is None:2318 cap_file = self.cap_file2319 if cap_string is None:2320 cap_string = self.cap_string2321 if is_mobile is None:2322 is_mobile = self.mobile_emulator2323 if d_width is None:2324 d_width = self.__device_width2325 if d_height is None:2326 d_height = self.__device_height2327 if d_p_r is None:2328 d_p_r = self.__device_pixel_ratio2329 valid_browsers = constants.ValidBrowsers.valid_browsers2330 if browser_name not in valid_browsers:2331 raise Exception(2332 "Browser: {%s} is not a valid browser option. "2333 "Valid options = {%s}" % (browser, valid_browsers)2334 )2335 # Launch a web browser2336 from seleniumbase.core import browser_launcher2337 new_driver = browser_launcher.get_driver(2338 browser_name=browser_name,2339 headless=headless,2340 locale_code=locale_code,2341 use_grid=use_grid,2342 protocol=protocol,2343 servername=servername,2344 port=port,2345 proxy_string=proxy_string,2346 proxy_bypass_list=proxy_bypass_list,2347 user_agent=user_agent,2348 cap_file=cap_file,2349 cap_string=cap_string,2350 recorder_ext=recorder_ext,2351 disable_csp=disable_csp,2352 enable_ws=enable_ws,2353 enable_sync=enable_sync,2354 use_auto_ext=use_auto_ext,2355 no_sandbox=no_sandbox,2356 disable_gpu=disable_gpu,2357 incognito=incognito,2358 guest_mode=guest_mode,2359 devtools=devtools,2360 remote_debug=remote_debug,2361 swiftshader=swiftshader,2362 ad_block_on=ad_block_on,2363 block_images=block_images,2364 chromium_arg=chromium_arg,2365 firefox_arg=firefox_arg,2366 firefox_pref=firefox_pref,2367 user_data_dir=user_data_dir,2368 extension_zip=extension_zip,2369 extension_dir=extension_dir,2370 external_pdf=external_pdf,2371 test_id=test_id,2372 mobile_emulator=is_mobile,2373 device_width=d_width,2374 device_height=d_height,2375 device_pixel_ratio=d_p_r,2376 )2377 self._drivers_list.append(new_driver)2378 self.__driver_browser_map[new_driver] = browser_name2379 if switch_to:2380 self.driver = new_driver2381 self.browser = browser_name2382 if self.headless or self.xvfb:2383 # Make sure the invisible browser window is big enough2384 width = settings.HEADLESS_START_WIDTH2385 height = settings.HEADLESS_START_HEIGHT2386 try:2387 self.driver.set_window_size(width, height)2388 self.wait_for_ready_state_complete()2389 except Exception:2390 # This shouldn't fail, but in case it does,2391 # get safely through setUp() so that2392 # WebDrivers can get closed during tearDown().2393 pass2394 else:2395 if self.browser == "chrome" or self.browser == "edge":2396 width = settings.CHROME_START_WIDTH2397 height = settings.CHROME_START_HEIGHT2398 try:2399 if self.maximize_option:2400 self.driver.maximize_window()2401 else:2402 self.driver.set_window_size(width, height)2403 self.wait_for_ready_state_complete()2404 except Exception:2405 pass # Keep existing browser resolution2406 elif self.browser == "firefox":2407 width = settings.CHROME_START_WIDTH2408 try:2409 if self.maximize_option:2410 self.driver.maximize_window()2411 else:2412 self.driver.set_window_size(width, 720)2413 self.wait_for_ready_state_complete()2414 except Exception:2415 pass # Keep existing browser resolution2416 elif self.browser == "safari":2417 width = settings.CHROME_START_WIDTH2418 if self.maximize_option:2419 try:2420 self.driver.maximize_window()2421 self.wait_for_ready_state_complete()2422 except Exception:2423 pass # Keep existing browser resolution2424 else:2425 try:2426 self.driver.set_window_rect(10, 30, width, 630)2427 except Exception:2428 pass2429 elif self.browser == "opera":2430 width = settings.CHROME_START_WIDTH2431 if self.maximize_option:2432 try:2433 self.driver.maximize_window()2434 self.wait_for_ready_state_complete()2435 except Exception:2436 pass # Keep existing browser resolution2437 else:2438 try:2439 self.driver.set_window_rect(10, 30, width, 700)2440 except Exception:2441 pass2442 if self.start_page and len(self.start_page) >= 4:2443 if page_utils.is_valid_url(self.start_page):2444 self.open(self.start_page)2445 else:2446 new_start_page = "https://" + self.start_page2447 if page_utils.is_valid_url(new_start_page):2448 self.__dont_record_open = True2449 self.open(new_start_page)2450 self.__dont_record_open = False2451 return new_driver2452 def switch_to_driver(self, driver):2453 """Switches control of the browser to the specified driver.2454 Also sets the self.driver variable to the specified driver.2455 You may need this if using self.get_new_driver() in your code."""2456 self.__check_scope__()2457 self.driver = driver2458 if self.driver in self.__driver_browser_map:2459 self.browser = self.__driver_browser_map[self.driver]2460 self.bring_active_window_to_front()2461 def switch_to_default_driver(self):2462 """ Sets self.driver to the default/original driver. """2463 self.__check_scope__()2464 self.driver = self._default_driver2465 if self.driver in self.__driver_browser_map:2466 self.browser = self.__driver_browser_map[self.driver]2467 self.bring_active_window_to_front()2468 def save_screenshot(2469 self, name, folder=None, selector=None, by=By.CSS_SELECTOR2470 ):2471 """2472 Saves a screenshot of the current page.2473 If no folder is specified, uses the folder where pytest was called.2474 The screenshot will include the entire page unless a selector is given.2475 If a provided selector is not found, then takes a full-page screenshot.2476 If the folder provided doesn't exist, it will get created.2477 The screenshot will be in PNG format: (*.png)2478 """2479 self.wait_for_ready_state_complete()2480 if selector and by:2481 selector, by = self.__recalculate_selector(selector, by)2482 if page_actions.is_element_present(self.driver, selector, by):2483 return page_actions.save_screenshot(2484 self.driver, name, folder, selector, by2485 )2486 return page_actions.save_screenshot(self.driver, name, folder)2487 def save_screenshot_to_logs(2488 self, name=None, selector=None, by=By.CSS_SELECTOR2489 ):2490 """Saves a screenshot of the current page to the "latest_logs" folder.2491 Naming is automatic:2492 If NO NAME provided: "_1_screenshot.png", "_2_screenshot.png", etc.2493 If NAME IS provided, it becomes: "_1_name.png", "_2_name.png", etc.2494 The screenshot will include the entire page unless a selector is given.2495 If a provided selector is not found, then takes a full-page screenshot.2496 (The last_page / failure screenshot is always "screenshot.png")2497 The screenshot will be in PNG format."""2498 self.wait_for_ready_state_complete()2499 test_logpath = os.path.join(self.log_path, self.__get_test_id())2500 self.__create_log_path_as_needed(test_logpath)2501 if name:2502 name = str(name)2503 self.__screenshot_count += 12504 if not name or len(name) == 0:2505 name = "_%s_screenshot.png" % self.__screenshot_count2506 else:2507 pre_name = "_%s_" % self.__screenshot_count2508 if len(name) >= 4 and name[-4:].lower() == ".png":2509 name = name[:-4]2510 if len(name) == 0:2511 name = "screenshot"2512 name = "%s%s.png" % (pre_name, name)2513 if selector and by:2514 selector, by = self.__recalculate_selector(selector, by)2515 if page_actions.is_element_present(self.driver, selector, by):2516 return page_actions.save_screenshot(2517 self.driver, name, test_logpath, selector, by2518 )2519 return page_actions.save_screenshot(self.driver, name, test_logpath)2520 def save_page_source(self, name, folder=None):2521 """Saves the page HTML to the current directory (or given subfolder).2522 If the folder specified doesn't exist, it will get created.2523 @Params2524 name - The file name to save the current page's HTML to.2525 folder - The folder to save the file to. (Default = current folder)2526 """2527 self.wait_for_ready_state_complete()2528 return page_actions.save_page_source(self.driver, name, folder)2529 # def save_cookies(self, name="cookies.txt"):2530 # """ Saves the page cookies to the "saved_cookies" folder. """2531 # self.wait_for_ready_state_complete()2532 # cookies = self.driver.get_cookies()2533 # json_cookies = json.dumps(cookies)2534 # if name.endswith("/"):2535 # raise Exception("Invalid filename for Cookies!")2536 # if "/" in name:2537 # name = name.split("/")[-1]2538 # if len(name) < 1:2539 # raise Exception("Filename for Cookies is too short!")2540 # if not name.endswith(".txt"):2541 # name = name + ".txt"2542 # folder = constants.SavedCookies.STORAGE_FOLDER2543 # abs_path = os.path.abspath(".")2544 # file_path = abs_path + "/%s" % folder2545 # if not os.path.exists(file_path):2546 # os.makedirs(file_path)2547 # cookies_file_path = "%s/%s" % (file_path, name)2548 # cookies_file = codecs.open(cookies_file_path, "w+", encoding="utf-8")2549 # cookies_file.writelines(json_cookies)2550 # cookies_file.close()2551 #2552 # def load_cookies(self, name="cookies.txt"):2553 # """ Loads the page cookies from the "saved_cookies" folder. """2554 # self.wait_for_ready_state_complete()2555 # if name.endswith("/"):2556 # raise Exception("Invalid filename for Cookies!")2557 # if "/" in name:2558 # name = name.split("/")[-1]2559 # if len(name) < 1:2560 # raise Exception("Filename for Cookies is too short!")2561 # if not name.endswith(".txt"):2562 # name = name + ".txt"2563 # folder = constants.SavedCookies.STORAGE_FOLDER2564 # abs_path = os.path.abspath(".")2565 # file_path = abs_path + "/%s" % folder2566 # cookies_file_path = "%s/%s" % (file_path, name)2567 # json_cookies = None2568 # with open(cookies_file_path, "r") as f:2569 # json_cookies = f.read().strip()2570 # cookies = json.loads(json_cookies)2571 # for cookie in cookies:2572 # if "expiry" in cookie:2573 # del cookie["expiry"]2574 # self.driver.add_cookie(cookie)2575 #2576 # def delete_all_cookies(self):2577 # """Deletes all cookies in the web browser.2578 # Does NOT delete the saved cookies file."""2579 # self.wait_for_ready_state_complete()2580 # self.driver.delete_all_cookies()2581 #2582 # def delete_saved_cookies(self, name: str = "cookies.txt"):2583 # """Deletes the cookies file from the "saved_cookies" folder.2584 # Does NOT delete the cookies from the web browser."""2585 # self.wait_for_ready_state_complete()2586 # if name.endswith("/"):2587 # raise Exception("Invalid filename for Cookies!")2588 # if "/" in name:2589 # name = name.split("/")[-1]2590 # if len(name) < 1:2591 # raise Exception("Filename for Cookies is too short!")2592 # if not name.endswith(".txt"):2593 # name = name + ".txt"2594 # folder = constants.SavedCookies.STORAGE_FOLDER2595 # abs_path = os.path.abspath(".")2596 # file_path = abs_path + "/%s" % folder2597 # cookies_file_path = "%s/%s" % (file_path, name)2598 # if os.path.exists(cookies_file_path):2599 # if cookies_file_path.endswith(".txt"):2600 # os.remove(cookies_file_path)2601 def install_addon(self, xpi_file: FilePath):2602 """Installs a Firefox add-on instantly at run-time.2603 @Params2604 xpi_file - A file archive in .xpi format.2605 """2606 self.wait_for_ready_state_complete()2607 if self.driver.capabilities.get("browseName") != "firefox":2608 raise Exception(2609 "install_addon(xpi_file) is for Firefox ONLY!\n"2610 "To load a Chrome extension, use the comamnd-line:\n"2611 "--extension_zip=CRX_FILE OR --extension_dir=DIR"2612 )2613 xpi_path = os.path.abspath(xpi_file)2614 self.driver.install_addon(xpi_path, temporary=True)2615 def activate_demo_mode(self):2616 self.demo_mode = True2617 def deactivate_demo_mode(self):2618 self.demo_mode = False2619 def activate_design_mode(self):2620 # Activate Chrome's Design Mode, which lets you edit a site directly.2621 # See: https://twitter.com/sulco/status/11775591505633443842622 self.wait_for_ready_state_complete()2623 script = """document.designMode = 'on';"""2624 self.execute_script(script)2625 def deactivate_design_mode(self):2626 # Deactivate Chrome's Design Mode.2627 self.wait_for_ready_state_complete()2628 script = """document.designMode = 'off';"""2629 self.execute_script(script)2630 def bring_active_window_to_front(self):2631 """Brings the active browser window to the front.2632 This is useful when multiple drivers are being used."""2633 self.__check_scope__()2634 try:2635 if not js_utils.is_in_frame():2636 # Only bring the window to the front if not in a frame2637 # because the driver resets itself to default content.2638 self.switch_to_window(self.driver.current_window_handle)2639 except Exception:2640 pass2641 def bring_to_front(self, selector, by=By.CSS_SELECTOR):2642 """Updates the Z-index of a page element to bring it into view.2643 Useful when getting a WebDriverException, such as the one below:2644 { Element is not clickable at point (#, #).2645 Other element would receive the click: ... }"""2646 self.__check_scope__()2647 self.wait_for_element_visible(2648 selector, by=by, timeout=settings.SMALL_TIMEOUT2649 )2650 try:2651 selector = self.convert_to_css_selector(selector, by=by)2652 except Exception:2653 # Don't run action if can't convert to CSS_Selector for JavaScript2654 return2655 selector = re.escape(selector)2656 selector = shared.escape_quotes_if_needed(selector)2657 script = (2658 """document.querySelector('%s').style.zIndex = '999999';"""2659 % selector2660 )2661 self.execute_script(script)2662 def highlight_click(2663 self, selector, by=By.CSS_SELECTOR, loops=3, scroll=True2664 ):2665 self.__check_scope__()2666 if not self.demo_mode:2667 self.highlight(selector, by=by, loops=loops, scroll=scroll)2668 self.click(selector, by=by)2669 def highlight_update_text(2670 self, selector, text, by=By.CSS_SELECTOR, loops=3, scroll=True2671 ):2672 """Highlights the element and then types text into the field."""2673 self.__check_scope__()2674 if not self.demo_mode:2675 self.highlight(selector, by=by, loops=loops, scroll=scroll)2676 self.update_text(selector, text, by=by)2677 def highlight_type(2678 self, selector, text, by=By.CSS_SELECTOR, loops=3, scroll=True2679 ):2680 """Same as self.highlight_update_text()2681 As above, highlights the element and then types text into the field."""2682 self.__check_scope__()2683 if not self.demo_mode:2684 self.highlight(selector, by=by, loops=loops, scroll=scroll)2685 self.update_text(selector, text, by=by)2686 def highlight(self, selector, by=By.CSS_SELECTOR, loops=None, scroll=True):2687 """This method uses fancy JavaScript to highlight an element.2688 Used during demo_mode.2689 @Params2690 selector - the selector of the element to find2691 by - the type of selector to search by (Default: CSS)2692 loops - # of times to repeat the highlight animation2693 (Default: 4. Each loop lasts for about 0.18s)2694 scroll - the option to scroll to the element first (Default: True)2695 """2696 self.__check_scope__()2697 selector, by = self.__recalculate_selector(selector, by, xp_ok=False)2698 element = self.wait_for_element_visible(2699 selector, by=by, timeout=settings.SMALL_TIMEOUT2700 )2701 if not loops:2702 loops = settings.HIGHLIGHTS2703 if scroll:2704 try:2705 if self.browser != "safari":2706 scroll_distance = js_utils.get_scroll_distance_to_element(2707 self.driver, element2708 )2709 if abs(scroll_distance) > settings.SSMD:2710 self.__jquery_slow_scroll_to(selector, by)2711 else:2712 self.__slow_scroll_to_element(element)2713 else:2714 self.__jquery_slow_scroll_to(selector, by)2715 except Exception:2716 self.wait_for_ready_state_complete()2717 time.sleep(0.12)2718 element = self.wait_for_element_visible(2719 selector, by=by, timeout=settings.SMALL_TIMEOUT2720 )2721 self.__slow_scroll_to_element(element)2722 try:2723 selector = self.convert_to_css_selector(selector, by=by)2724 except Exception:2725 # Don't highlight if can't convert to CSS_SELECTOR2726 return2727 if self.highlights:2728 loops = self.highlights2729 if self.browser == "ie":2730 loops = 1 # Override previous setting because IE is slow2731 loops = int(loops)2732 o_bs = "" # original_box_shadow2733 try:2734 style = element.get_attribute("style")2735 except Exception:2736 self.wait_for_ready_state_complete()2737 time.sleep(0.12)2738 element = self.wait_for_element_visible(2739 selector, by=By.CSS_SELECTOR, timeout=settings.SMALL_TIMEOUT2740 )2741 style = element.get_attribute("style")2742 if style:2743 if "box-shadow: " in style:2744 box_start = style.find("box-shadow: ")2745 box_end = style.find(";", box_start) + 12746 original_box_shadow = style[box_start:box_end]2747 o_bs = original_box_shadow2748 orig_selector = selector2749 if ":contains" not in selector and ":first" not in selector:2750 selector = re.escape(selector)2751 selector = shared.escape_quotes_if_needed(selector)2752 self.__highlight_with_js(selector, loops, o_bs)2753 else:2754 selector = self.__make_css_match_first_element_only(selector)2755 selector = re.escape(selector)2756 selector = shared.escape_quotes_if_needed(selector)2757 try:2758 self.__highlight_with_jquery(selector, loops, o_bs)2759 except Exception:2760 pass # JQuery probably couldn't load. Skip highlighting.2761 time.sleep(0.065)2762 def __highlight_with_js(self, selector, loops, o_bs):2763 self.wait_for_ready_state_complete()2764 js_utils.highlight_with_js(self.driver, selector, loops, o_bs)2765 def __highlight_with_jquery(self, selector, loops, o_bs):2766 self.wait_for_ready_state_complete()2767 js_utils.highlight_with_jquery(self.driver, selector, loops, o_bs)2768 def press_up_arrow(self, selector="html", times=1, by=By.CSS_SELECTOR):2769 """Simulates pressing the UP Arrow on the keyboard.2770 By default, "html" will be used as the CSS Selector target.2771 You can specify how many times in-a-row the action happens."""2772 self.__check_scope__()2773 if times < 1:2774 return2775 element = self.wait_for_element_present(selector)2776 self.__demo_mode_highlight_if_active(selector, by)2777 if not self.demo_mode and not self.slow_mode:2778 self.__scroll_to_element(element, selector, by)2779 for i in range(int(times)):2780 try:2781 element.send_keys(Keys.ARROW_UP)2782 except Exception:2783 self.wait_for_ready_state_complete()2784 element = self.wait_for_element_visible(selector)2785 element.send_keys(Keys.ARROW_UP)2786 time.sleep(0.01)2787 if self.slow_mode:2788 time.sleep(0.1)2789 def press_down_arrow(self, selector="html", times=1, by=By.CSS_SELECTOR):2790 """Simulates pressing the DOWN Arrow on the keyboard.2791 By default, "html" will be used as the CSS Selector target.2792 You can specify how many times in-a-row the action happens."""2793 self.__check_scope__()2794 if times < 1:2795 return2796 element = self.wait_for_element_present(selector)2797 self.__demo_mode_highlight_if_active(selector, by)2798 if not self.demo_mode and not self.slow_mode:2799 self.__scroll_to_element(element, selector, by)2800 for i in range(int(times)):2801 try:2802 element.send_keys(Keys.ARROW_DOWN)2803 except Exception:2804 self.wait_for_ready_state_complete()2805 element = self.wait_for_element_visible(selector)2806 element.send_keys(Keys.ARROW_DOWN)2807 time.sleep(0.01)2808 if self.slow_mode:2809 time.sleep(0.1)2810 def press_left_arrow(self, selector="html", times=1, by=By.CSS_SELECTOR):2811 """Simulates pressing the LEFT Arrow on the keyboard.2812 By default, "html" will be used as the CSS Selector target.2813 You can specify how many times in-a-row the action happens."""2814 self.__check_scope__()2815 if times < 1:2816 return2817 element = self.wait_for_element_present(selector)2818 self.__demo_mode_highlight_if_active(selector, by)2819 if not self.demo_mode and not self.slow_mode:2820 self.__scroll_to_element(element, selector, by)2821 for i in range(int(times)):2822 try:2823 element.send_keys(Keys.ARROW_LEFT)2824 except Exception:2825 self.wait_for_ready_state_complete()2826 element = self.wait_for_element_visible(selector)2827 element.send_keys(Keys.ARROW_LEFT)2828 time.sleep(0.01)2829 if self.slow_mode:2830 time.sleep(0.1)2831 def press_right_arrow(self, selector="html", times=1, by=By.CSS_SELECTOR):2832 """Simulates pressing the RIGHT Arrow on the keyboard.2833 By default, "html" will be used as the CSS Selector target.2834 You can specify how many times in-a-row the action happens."""2835 self.__check_scope__()2836 if times < 1:2837 return2838 element = self.wait_for_element_present(selector)2839 self.__demo_mode_highlight_if_active(selector, by)2840 if not self.demo_mode and not self.slow_mode:2841 self.__scroll_to_element(element, selector, by)2842 for i in range(int(times)):2843 try:2844 element.send_keys(Keys.ARROW_RIGHT)2845 except Exception:2846 self.wait_for_ready_state_complete()2847 element = self.wait_for_element_visible(selector)2848 element.send_keys(Keys.ARROW_RIGHT)2849 time.sleep(0.01)2850 if self.slow_mode:2851 time.sleep(0.1)2852 def scroll_to(self, selector, by=By.CSS_SELECTOR, timeout=None):2853 """ Fast scroll to destination """2854 self.__check_scope__()2855 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)2856 if self.demo_mode or self.slow_mode:2857 self.slow_scroll_to(selector, by=by, timeout=timeout)2858 return2859 element = self.wait_for_element_visible(2860 selector, by=by, timeout=timeout2861 )2862 try:2863 self.__scroll_to_element(element, selector, by)2864 except (StaleElementReferenceException, ElementNotInteractableException):2865 self.wait_for_ready_state_complete()2866 time.sleep(0.12)2867 element = self.wait_for_element_visible(2868 selector, by=by, timeout=timeout2869 )2870 self.__scroll_to_element(element, selector, by)2871 def scroll_to_element(self, selector, by=By.CSS_SELECTOR, timeout=None):2872 self.scroll_to(selector, by=by, timeout=timeout)2873 def slow_scroll_to(self, selector, by=By.CSS_SELECTOR, timeout=None):2874 """ Slow motion scroll to destination """2875 self.__check_scope__()2876 timeout = self.get_timeout(timeout, constants.SMALL_TIMEOUT)2877 selector, by = self.__recalculate_selector(selector, by)2878 element = self.wait_for_element_visible(2879 selector, by=by, timeout=timeout2880 )2881 try:2882 scroll_distance = js_utils.get_scroll_distance_to_element(2883 self.driver, element2884 )2885 if abs(scroll_distance) > constants.Values.SSMD:2886 self.__jquery_slow_scroll_to(selector, by)2887 else:2888 self.__slow_scroll_to_element(element)2889 except Exception:2890 self.wait_for_ready_state_complete()2891 time.sleep(0.12)2892 element = self.wait_for_element_visible(2893 selector, by=by, timeout=timeout2894 )2895 self.__slow_scroll_to_element(element)2896 def slow_scroll_to_element(2897 self, selector, by=By.CSS_SELECTOR, timeout=None2898 ):2899 self.slow_scroll_to(selector, by=by, timeout=timeout)2900 def scroll_to_top(self):2901 """ Scroll to the top of the page. """2902 self.__check_scope__()2903 scroll_script = "window.scrollTo(0, 0);"2904 try:2905 self.execute_script(scroll_script)2906 time.sleep(0.012)2907 return True2908 except Exception:2909 return False2910 def scroll_to_bottom(self):2911 """ Scroll to the bottom of the page. """2912 self.__check_scope__()2913 scroll_script = "window.scrollTo(0, 10000);"2914 try:2915 self.execute_script(scroll_script)2916 time.sleep(0.012)2917 return True2918 except Exception:2919 return False2920 def click_xpath(self, xpath):2921 # Technically self.click() will automatically detect an xpath selector,2922 # so self.click_xpath() is just a longer name for the same action.2923 self.click(xpath, by=By.XPATH)2924 def js_click(2925 self, selector, by=By.CSS_SELECTOR, all_matches=False, scroll=True2926 ):2927 """Clicks an element using JavaScript.2928 Can be used to click hidden / invisible elements.2929 If "all_matches" is False, only the first match is clicked.2930 If "scroll" is False, won't scroll unless running in Demo Mode."""2931 self.wait_for_ready_state_complete()2932 selector, by = self.__recalculate_selector(selector, by, xp_ok=False)2933 if by == By.LINK_TEXT:2934 message = (2935 "Pure JavaScript doesn't support clicking by Link Text. "2936 "You may want to use self.jquery_click() instead, which "2937 "allows this with :contains(), assuming jQuery isn't blocked. "2938 "For now, self.js_click() will use a regular WebDriver click."2939 )2940 logger.debug(message)2941 self.click(selector, by=by)2942 return2943 element = self.wait_for_element_present(2944 selector, by=by, timeout=settings.SMALL_TIMEOUT2945 )2946 if self.is_element_visible(how, selector):2947 self.__demo_mode_highlight_if_active(selector, by)2948 if scroll and not self.demo_mode and not self.slow_mode:2949 success = js_utils.scroll_to_element(self.driver, element)2950 if not success:2951 self.wait_for_ready_state_complete()2952 timeout = settings.SMALL_TIMEOUT2953 element = page_actions.wait_for_element_present(2954 self.driver, selector, by, timeout=timeout2955 )2956 css_selector = self.convert_to_css_selector(selector, by=by)2957 css_selector = re.escape(css_selector) # Add "\\" to special chars2958 css_selector = shared.escape_quotes_if_needed(css_selector)2959 action = None2960 pre_action_url = self.driver.current_url2961 pre_window_count = len(self.driver.window_handles)2962 if not all_matches:2963 if ":contains\\(" not in css_selector:2964 self.__js_click(selector, by=by)2965 else:2966 click_script = """jQuery('%s')[0].click();""" % css_selector2967 self.safe_execute_script(click_script)2968 else:2969 if ":contains\\(" not in css_selector:2970 self.__js_click_all(selector, by=by)2971 else:2972 click_script = """jQuery('%s').click();""" % css_selector2973 self.safe_execute_script(click_script)2974 latest_window_count = len(self.driver.window_handles)2975 if (2976 latest_window_count > pre_window_count2977 and (2978 self.recorder_mode2979 or (2980 settings.SWITCH_TO_NEW_TABS_ON_CLICK2981 and self.driver.current_url == pre_action_url2982 )2983 )2984 ):2985 self.__switch_to_newest_window_if_not_blank()2986 self.wait_for_ready_state_complete()2987 self._demo_mode_pause_if_active()2988 def js_click_all(self, selector, by=By.CSS_SELECTOR):2989 """ Clicks all matching elements using pure JS. (No jQuery) """2990 self.js_click(selector, by=By.CSS_SELECTOR, all_matches=True)2991 def jquery_click(self, selector, by=By.CSS_SELECTOR):2992 """Clicks an element using jQuery. (Different from using pure JS.)2993 Can be used to click hidden / invisible elements."""2994 self.__check_scope__()2995 self.wait_for_element_present(2996 selector, by=by, timeout=settings.SMALL_TIMEOUT2997 )2998 if self.is_element_visible(selector, by=by):2999 self.__demo_mode_highlight_if_active(selector, by)...

Full Screen

Full Screen

Automation Testing Tutorials

Learn to execute automation testing from scratch with LambdaTest Learning Hub. Right from setting up the prerequisites to run your first automation test, to following best practices and diving deeper into advanced test scenarios. LambdaTest Learning Hubs compile a list of step-by-step guides to help you be proficient with different test automation frameworks i.e. Selenium, Cypress, TestNG etc.

LambdaTest Learning Hubs:

YouTube

You could also refer to video tutorials over LambdaTest YouTube channel to get step by step demonstration from industry experts.

Run SeleniumBase automation tests on LambdaTest cloud grid

Perform automation testing on 3000+ real desktop and mobile devices online.

Try LambdaTest Now !!

Get 100 minutes of automation test minutes FREE!!

Next-Gen App & Browser Testing Cloud

Was this article helpful?

Helpful

NotHelpful