def get_webelements_in_active_area(xpath, **kwargs): """Find element under another element. If ${ACTIVE_AREA_FUNC} returns an element then the xpath is searched from that element. Otherwise the element is searched under body element. Parameters ---------- xpath : str Xpath expression without xpath= prefix. Returns ------- :obj:`list` of :obj:`WebElement` List of visible WebElements. """ active_area_xpath = CONFIG["ActiveAreaXpath"] if ACTIVE_AREA_FUNCTION is not None: active_area = ACTIVE_AREA_FUNCTION() if active_area: xpath = xpath.replace('//', './/', 1) else: driver = browser.get_current_browser() active_area = driver.find_element(By.XPATH, active_area_xpath) else: driver = browser.get_current_browser() try: active_area = driver.find_element(By.XPATH, active_area_xpath) if active_area is None: logger.debug('Got None for active area. Is page still loading ' 'or is it missing body tag?') return None # //body not found, is page still loading? Return None to continue looping except NoSuchElementException: logger.debug( "Cannot locate //body element. Is page still loading?") return None try: webelements = active_area.find_elements(By.XPATH, xpath) logger.trace('XPath {} matched {} webelements'.format( xpath, len(webelements))) webelements = get_visible_elements_from_elements(webelements, **kwargs) except StaleElementReferenceException as se: raise QWebStalingElementError('Got StaleElementException') from se except (JavascriptException, InvalidSelectorException) as e: logger.debug('Got {}, returning None'.format(e)) webelements = None return webelements
def close_remote_browser(): r"""Close remote browser session which is connected to the target browser. Closes only the remote browser session and leaves the target browser running. This makes it possible to continue using the existing browser for other tests. It is important to use this keyword to free up the resources i.e. unnecessary chrome instances are not left to run. However, it is good to monitor chromedriver processes as those might be still running. Examples -------- .. code-block:: robotframework CloseBrowserSession Related keywords ---------------- \`CloseAllBrowsers\`, \`CloseBrowser\`, \`OpenBrowser\` """ driver = browser.get_current_browser() if driver is not None: if _close_remote_browser_session(driver): browser.remove_from_browser_cache(driver) else: logger.info("All browser windows already closed")
def get_webelements(xpath, **kwargs): """Get visible web elements that correspond to given XPath. To check that element is visible it is checked that it has width. This does not handle all cases but it is fast so no need to modify if it works. Replace the visibility check using WebElement's is_displayed method if necessary. Parameters ---------- xpath : str XPath expression without xpath= prefix. Returns ------- :obj:`list` of :obj:`WebElement` List of visible WebElements. """ if xpath.startswith("xpath="): xpath = xpath.split("=", 1)[1] driver = browser.get_current_browser() web_elements = driver.find_elements_by_xpath(xpath) logger.trace("XPath {} matched {} WebElements" .format(xpath, len(web_elements))) web_elements = get_visible_elements_from_elements(web_elements, **kwargs) return web_elements
def use_frame(locator): """Make following keywords to use frame on a page. Examples -------- .. code-block:: robotframework UseFrame //iframe Parameters ---------- locator : str Xpath expression without xpath= prefix or index (first = 1 etc.) Raises ------ NoSuchFrameException If the frame is not found """ frame.wait_page_loaded() try: index = int(locator) - 1 webelement = javascript.execute_javascript( 'document.querySelectorAll("iframe, frame")[{}]'.format(index)) except ValueError: webelement = element.get_unique_element_by_xpath(locator) driver = browser.get_current_browser() try: driver.switch_to_frame(webelement) except NoSuchFrameException: raise NoSuchFrameException('No frame wound with xpath: {0}'.format(locator))
def close_browser(): r"""Close current browser. This will also close remote browser sessions if open. Examples -------- .. code-block:: robotframework CloseBrowser Related keywords ---------------- \`CloseAllBrowsers\`, \`CloseRemoteBrowser\`, \`OpenBrowser\` """ driver = browser.get_current_browser() if driver is not None: _close_remote_browser_session(driver, close_only=True) browser.remove_from_browser_cache(driver) # Clear browser re-use flag as no original session open anymore BuiltIn().set_global_variable('${BROWSER_REUSE}', False) driver.quit() else: logger.info("All browser windows already closed")
def go_to(url, timeout=0): # pylint: disable=unused-argument r"""Switch current page to given url. Examples -------- .. code-block:: robotframework GoTo http://google.com GoTo file://resources/window.html Parameters ---------- url : str URL of the website that will be opened. Raises ------ UnexpectedAlertPresentException If the page opens with alert popup Related keywords ---------------- \`CloseAllBrowsers\`, \`CloseBrowser\`, \`OpenBrowser\`, \`OpenWindow\`, \`SwitchWindow\` """ driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") driver.get(url)
def set_window_size(pixels): width, height = _parse_pixels(pixels) width = int(width) height = int(height) driver = browser.get_current_browser() driver.set_window_size(width, height) return width, height
def maximize_window(): """Maximizes current browser window. Note: This keyword will not fail if maximizing is prevented for some reason. This can happen for example if window manager is not installed or setup correctly. Examples -------- .. code-block:: robotframework MaximizeWindow Parameters ---------- None """ driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") if CONFIG.get_value('Headless') is True: logger.debug("Maximizing browser in headless mode") screen_width_js = driver.execute_script("return screen.width") screen_height_js = driver.execute_script("return screen.height") driver.set_window_size(screen_width_js, screen_height_js) else: driver.maximize_window() size = driver.get_window_size() logger.debug("Window size set to {}x{}".format(size["width"], size["height"]))
def is_tmp_file(filepath): """Is downloaded file a temporary file. When a file is being downloaded at least some browsers download it to a different name. When the file has been fully downloaded the file is renamed to the correct one. Parameters ---------- filepath : str Returns ------- bool """ driver = browser.get_current_browser() if isinstance(driver, webdriver.Chrome): partial_download_suffix = 'crdownload' elif isinstance(driver, webdriver.Firefox): partial_download_suffix = '.part' elif isinstance(driver, Edge): partial_download_suffix = 'crdownload' else: raise ValueError('Unkown browser {}'.format(driver.name)) return filepath.endswith(partial_download_suffix)
def hover_to(web_element, timeout=0): # pylint: disable=unused-argument driver = browser.get_current_browser() # firefox specific fix if driver.capabilities['browserName'].lower() in browser.firefox.NAMES: # use javascript to scroll driver.execute_script("arguments[0].scrollIntoView(true);", web_element) hover = ActionChains(driver).move_to_element(web_element) hover.perform()
def return_browser(): """Return browser instance. Use this function if you need to expand QWeb and require direct browser access. Examples -------- .. code-block:: robotframework ReturnBrowser """ return browser.get_current_browser()
def use_page(): """Make following keywords to use the page and not a frame on a page. Examples -------- .. code-block:: robotframework UsePage """ frame.wait_page_loaded() driver = browser.get_current_browser() driver.switch_to_default_content()
def search_from_frames(driver=None, current_frame=None): keep_frame = kwargs.get('stay_in_current_frame', CONFIG['StayInCurrentFrame']) if keep_frame: return fn(*args, **kwargs) err = None if not driver: driver = browser.get_current_browser() driver.switch_to.default_content() if current_frame: try: driver.switch_to.frame(current_frame) logger.debug('switching to childframe {}'.format(str(fn))) except (StaleElementReferenceException, WebDriverException) as e: logger.warn(e) driver.switch_to.default_content() raise e try: web_element = fn(*args, **kwargs) except QWebElementNotFoundError as e: err = e web_element = None if is_valid(web_element): return web_element start = time.time() timeout = CONFIG['FrameTimeout'] while time.time() < timeout + start: frames = fc.check_frames(driver) for frame in frames: web_element = search_from_frames(driver=driver, current_frame=frame) if is_valid(web_element): logger.debug( 'Found webelement = {}'.format(web_element)) return web_element try: driver.switch_to.parent_frame() except WebDriverException as e: driver.switch_to.default_content() raise e config.set_config('FrameTimeout', float(timeout + start - time.time())) logger.trace('Frame timeout: {}'.format(timeout)) if err: raise err return web_element driver.switch_to.default_content() raise QWebTimeoutError( 'From frame decorator: Unable to locate element in given time')
def refresh_page(): """Refresh the current window. Examples -------- .. code-block:: robotframework RefreshPage """ frame.wait_page_loaded() driver = browser.get_current_browser() driver.refresh()
def refresh_page(): r"""Refresh the current window. Examples -------- .. code-block:: robotframework RefreshPage Related keywords ---------------- \`Back\`, \`GoTo\`, \`MaximizeWindow\` """ frame.wait_page_loaded() driver = browser.get_current_browser() driver.refresh()
def get_text_using_anchor(text, anchor, **kwargs): """Get WebElement that contains text using anchor if necessary. First locates the elements that has the exact text. If no elements were found then searching as a substring using XPath's contains function. If we come up empty then NoSuchElementException is raised. If text corresponded to multiple elements then anchor is taken in to play. Parameters ---------- text : str Text on web page that is wanted to locate. anchor : str Unique text on web page which is close to the first argument. Accepted kwargs: css=False/off: Use this to bypass css search when finding elements by visible text Returns ------- WebElement """ web_elements = get_all_text_elements(text, **kwargs) modal_xpath = CONFIG['IsModalXpath'] driver = browser.get_current_browser() if modal_xpath != "//body": # filter elements by modal (dialog etc) logger.debug("IsModalXpath filtering on, filtering...") modal_exists = driver.find_elements(By.XPATH, modal_xpath) if modal_exists: web_elements = _filter_by_modal_ancestor(web_elements) logger.debug( f"after filtering there are: {len(web_elements)} matching elements" ) if not web_elements: raise QWebElementNotFoundError( 'Webpage did not contain text "{}"'.format(text)) if len(web_elements) == 1: return web_elements[0] # Found many elements, use anchors to determine correct element correct_element = get_element_using_anchor(web_elements, anchor, **kwargs) return correct_element
def forward(): r"""Navigates forward in the current window. Examples -------- .. code-block:: robotframework Forward Related keywords ---------------- \`Back\`, \`GoTo\`, \`RefreshPage\`, \`MaximizeWindow\` """ frame.wait_page_loaded() driver = browser.get_current_browser() driver.forward()
def set_line_break(key): if key == '\ue000': current_browser = browser.get_current_browser( ).capabilities['browserName'] if current_browser == 'firefox': key = '' input_handler.line_break_key = key logger.info( '\n\\ue000 line break does not work with Firefox, using empty string' ' instead. It is recommended to use None instead of \\ue000.') else: input_handler.line_break_key = key elif key.lower() in ('none', 'empty', 'null'): key = '' input_handler.line_break_key = key else: input_handler.line_break_key = key return key
def close_window(): r"""Close current tab and switch context to another window handle. If you need to change to specific tab, use switch window keyword. Examples -------- .. code-block:: robotframework CloseWindow Related keywords ---------------- \`CloseBrowser\`, \`CloseOthers\`, \`GoTo\`, \`OpenWindow\`, \`SwitchWindow\` """ driver = browser.get_current_browser() window_handles = window.get_window_handles() logger.info("Current browser has {} tabs".format(len(window_handles))) if len(window_handles) == 1: logger.info("Only one tab, handle closing without changing context") browser.remove_from_browser_cache(driver) # remove from browser cache driver.close() else: logger.info( "Multiple tabs open, can change window context to another one") current_window = window.get_current_window_handle() current_index = window_handles.index(current_window) logger.info("Current index {}".format(current_index)) driver.close() # "refresh" window handles window_handles = window.get_window_handles() current_length = len(window_handles) logger.info( "After closing, {} tabs remain open".format(current_length)) # if current index is more than new length, move to last handle if current_index > (len(window_handles) - 1): window.switch_to_window(window_handles[(current_index - 1)]) # move to next window (as browsers do) else: window.switch_to_window(window_handles[current_index]) logger.info("Changed context to tab with url {}".format( window.get_url()))
def close_others(): r"""Close all windows except the first window. If you have a test that may open new windows, this keyword closes them and switches to the first window. Examples -------- .. code-block:: robotframework CloseOthers Raises ------ NoSuchWindowException If other windows cannot been closed Related keywords ---------------- \`CloseBrowser\`, \`CloseWindow\`, \`GoTo\`, \`OpenWindow\`, \`SwitchWindow\` """ window_handles = window.get_window_handles() logger.info("Current browser has {} tabs".format(len(window_handles))) if len(window_handles) == 1: return driver = browser.get_current_browser() while len(window_handles) > 1: try: window_handle = window_handles.pop() window.switch_to_window(window_handle) driver.close() except NoSuchWindowException: logger.info('Failed to close window') first_window_handle = window_handles.pop() window.switch_to_window(first_window_handle) number_of_handles = len(window.get_window_handles()) if number_of_handles != 1: raise Exception( 'Expected 1 window open, found {0}'.format(number_of_handles))
def swipe(direction, times='1', start=None): """ Internal swipe function used by the swipe keywords. Uses the arrow keys to "swipe", unless a starting point is given. If a starting point is given, drag and drop is used. Functionality isn't 100% same as in QMobile, but this should work in most cases. """ logger.info('Even though the keyword is called swipe, ' 'it actually uses arrow keys or drag and drop to "swipe".') directions = { 'down': (Keys.ARROW_DOWN, 0, 500), 'up': (Keys.ARROW_UP, 0, -500), 'left': (Keys.ARROW_LEFT, -500, 0), 'right': (Keys.ARROW_RIGHT, 500, 0) } driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") action_chains = ActionChains(driver) try: times = int(times) except ValueError as e: raise ValueError( 'Amount of times swiped needs to be an integer.') from e if not start: default_swipe_length = 20 times = default_swipe_length * times for _ in range(times): action_chains.send_keys(directions[direction][0]) action_chains.pause(0.05) action_chains.perform() time.sleep(.5) else: start_element = text.get_unique_text_element(start) action_chains.click(start_element) action_chains.pause(.5) action_chains.drag_and_drop_by_offset(start_element, directions[direction][1] * times, directions[direction][2] * times) action_chains.perform() time.sleep(.5)
def wait_page_loaded(): """Wait for webpage to be loaded. Examples -------- .. code-block:: robotframework WaitPageLoaded Each keyword should have this in the beginning since it is crucial that page has been loaded fully. Monkeypatch this method to have different wait. """ if CONFIG["DefaultDocument"]: driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") try: driver.switch_to.default_content() except InvalidSessionIdException as ie: CONFIG.set_value("OSScreenshots", True) raise QWebBrowserError( "Browser session lost. Did browser crash?") from ie except (NoSuchWindowException, WebDriverException) as e: logger.warn( 'Cannot switch to default context, maybe window is closed. Err: {}' .format(e)) if any(s in str(e) for s in FATAL_MESSAGES): CONFIG.set_value("OSScreenshots", True) raise QWebBrowserError(e) from e driver.switch_to.default_content() timeout = CONFIG['XHRTimeout'] if timeout.lower() == "none": return try: xhr.wait_xhr(timestr_to_secs(timeout)) except (WebDriverException, QWebDriverError) as e: logger.info('Unable to check AJAX requests due error: {}'.format(e))
def execute_javascript(script, *args): """Run given javascript on current window. Parameters ---------- script : str Javascript code. *args : WebElement WebElement object that is stored in to variable "arguments" which is an array in javascript. Check example. Returns ------- str Output of the executed javascript. Example ------- execute_javascript('arguments[0].setAttribute("style", "background-color:yellow")', web_element) """ driver = browser.get_current_browser() return driver.execute_script(script, *args)
def set_window_size(width, height): """*DEPRECATED!!* Use keyword `SetConfig` instead. Set current window size. Examples -------- .. code-block:: robotframework SetWindowSize 1920 1080 Parameters ---------- width : int The width value of the window height: int The height value of the window """ width = int(width) height = int(height) driver = browser.get_current_browser() driver.set_window_size(width, height)
def verify_title(title, timeout=0): # pylint: disable=unused-argument r"""Verifies that current page's title matches expected title. Examples -------- .. code-block:: robotframework VerifyTitle Google VerifyTitle Google timeout=3 Parameters ---------- title : str The expected title timeout : str | int How long we wait for title to change before failing. Raises ------ QWebValueError If the expected title differs from actual page title Related keywords ---------------- \`GetTitle\`, \`GetUrl\`, \`VerifyUrl\` """ driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") actual = driver.title if actual != title: raise QWebValueError(f"Page title '{actual}'' does not match expected '{title}'")
def get_title(): r"""Gets the title of current page/window. Examples -------- .. code-block:: robotframework ${title}= GetTitle Parameters ---------- None Related keywords ---------------- \`GetUrl\`, \`VerifyTitle\`, \`VerifyUrl\` """ driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") return driver.title
def verify_url(url, timeout=0): # pylint: disable=unused-argument r"""Verifies that current page url/location matches expected url. Examples -------- .. code-block:: robotframework VerifyUrl https://www.google.com VerifyUrl https://www.google.com timeout=5 Parameters ---------- url : str The expected url timeout : str | int How long we wait for url to change before failing. Raises ------ QWebValueError If the expected url differs from current url Related keywords ---------------- \`GetTitle\`, \`GetUrl\`, \`VerifyTitle\` """ driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") current = driver.current_url if current.lower() != url.lower(): raise QWebValueError(f"Current url '{current}'' does not match expected url '{url}'")
def get_url(): r"""Gets current url/location. Examples -------- .. code-block:: robotframework ${url}= GetUrl Parameters ---------- None Related keywords ---------------- \`GetTitle\`,\`VerifyTitle\`, \`VerifyUrl\` """ driver = browser.get_current_browser() if driver is None: raise QWebDriverError("No browser open. Use OpenBrowser keyword" " to open browser first") return driver.current_url
def wait_alert(timeout): # pylint: disable=unused-argument driver = browser.get_current_browser() return driver.switch_to.alert
def get_raw_html(): driver = browser.get_current_browser() return driver.page_source