Beispiel #1
0
    def xpath_should_match_x_times(self,
                                   xpath,
                                   expected_xpath_count,
                                   message='',
                                   loglevel='INFO'):
        """Verifies that the page contains the given number of elements located by the given `xpath`.

        One should not use the xpath= prefix for 'xpath'. XPath is assumed.

        Correct:
        | Xpath Should Match X Times | //div[@id='sales-pop'] | 1
        Incorrect:
        | Xpath Should Match X Times | xpath=//div[@id='sales-pop'] | 1

        See `Page Should Contain Element` for explanation about `message` and
        `loglevel` arguments.
        """
        actual_xpath_count = len(
            self.find_element("xpath=" + xpath,
                              first_only=False,
                              required=False))
        if int(actual_xpath_count) != int(expected_xpath_count):
            if is_falsy(message):
                message = ("Xpath %s should have matched %s times but "
                           "matched %s times" %
                           (xpath, expected_xpath_count, actual_xpath_count))
            self.ctx.log_source(loglevel)
            raise AssertionError(message)
        self.info("Current page contains %s elements matching '%s'." %
                  (actual_xpath_count, xpath))
    def click_element(self, locator, modifier=False):
        """Click element identified by ``locator``.

        See the `Locating elements` section for details about the locator
        syntax.

        The ``modifier`` argument can be used to pass
        [https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys|Selenium Keys]
        when clicking the element. The `+` can be used as a separator
        for different Selenium Keys. The `CTRL` is internally translated to
        `CONTROL` key. The ``modifier`` is space and case insensitive, example
        "alt" and " aLt " are supported formats to
        [https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys.ALT|ALT key]
        . If ``modifier`` does not match to Selenium Keys, keyword fails.

        Example:
        | Click Element | id:button | | # Would click element without any modifiers. |
        | Click Element | id:button | CTRL | # Would click element with CTLR key pressed down. |
        | Click Element | id:button | CTRL+ALT | # Would click element with CTLR and ALT keys pressed down. |

        The ``modifier`` argument is new in SeleniumLibrary 3.2
        """
        if is_falsy(modifier):
            self.info("Clicking element '%s'." % locator)
            self.find_element(locator).click()
        else:
            self._click_with_modifier(locator, [None, None], modifier)
    def get_element_attribute(self, locator, attribute_name=None):
        """Returns value of the element attribute.

        There are two cases how to use this keyword.

        First, if only `locator` is provided, `locator` should consists of
        element locator followed by an @ sign and attribute name.
        This behavior is left for backward compatibility.

        Example:
        | ${id}= | Get Element Attribute | link=Link with id@id |

        Second, if `locator` and `attribute_name` are provided both, `locator`
        should be standard locator and `attribute_name` is name of the
        requested element attribute.

        Examples:
        | ${id}= | Get Element Attribute | link=Link with id | id |
        | ${element_by_dom}= | Get Webelement | dom=document.getElementsByTagName('a')[3] |
        | ${id}= | Get Element Attribute | ${element_by_dom} | id |
        """
        if is_falsy(attribute_name):
            locator, attribute_name = self._parse_attribute_locator(locator)
        element = self.find_element(locator, required=False)
        if not element:
            raise ValueError("Element '%s' not found." % (locator))
        return element.get_attribute(attribute_name)
Beispiel #4
0
    def get_cookies(self, as_dict=False):
        """Returns all cookies of the current page.

        If ``as_dict`` argument evaluates as false, see `Boolean arguments`
        for more details, then cookie information is returned as
        a single string in format ``name1=value1; name2=value2; name3=value3``.
        When ``as_dict`` argument evaluates as true, cookie information
        is returned as Robot Framework dictionary format. The string format
        can be used, for example, for logging purposes or in headers when
        sending HTTP requests. The dictionary format is helpful when
        the result can be passed to requests library's Create Session
        keyword's optional cookies parameter.

        The `` as_dict`` argument is new in SeleniumLibrary 3.3
        """
        if is_falsy(as_dict):
            pairs = []
            for cookie in self.driver.get_cookies():
                pairs.append(f"{cookie['name']}={cookie['value']}")
            return "; ".join(pairs)
        else:
            pairs = DotDict()
            for cookie in self.driver.get_cookies():
                pairs[cookie["name"]] = cookie["value"]
            return pairs
Beispiel #5
0
    def get_element_attribute(self, locator, attribute_name=None):
        """Returns value of the element attribute.

        There are two cases how to use this keyword.

        First, if only `locator` is provided, `locator` should consists of
        element locator followed by an @ sign and attribute name.
        This behavior is left for backward compatibility.

        Example:
        | ${id}= | Get Element Attribute | link=Link with id@id |

        Second, if `locator` and `attribute_name` are provided both, `locator`
        should be standard locator and `attribute_name` is name of the
        requested element attribute.

        Examples:
        | ${id}= | Get Element Attribute | link=Link with id | id |
        | ${element_by_dom}= | Get Webelement | dom=document.getElementsByTagName('a')[3] |
        | ${id}= | Get Element Attribute | ${element_by_dom} | id |
        """
        if is_falsy(attribute_name):
            locator, attribute_name = self._parse_attribute_locator(locator)
        element = self.find_element(locator, required=False)
        if not element:
            raise ValueError("Element '%s' not found." % (locator))
        return element.get_attribute(attribute_name)
Beispiel #6
0
 def create_driver(self,
                   browser,
                   desired_capabilities,
                   remote_url,
                   profile_dir=None,
                   options=None,
                   service_log_path=None,
                   executable_path=None):
     executable_path = None if is_falsy(
         executable_path) else executable_path
     browser = self._normalise_browser_name(browser)
     creation_method = self._get_creator_method(browser)
     desired_capabilities = self._parse_capabilities(
         desired_capabilities, browser)
     service_log_path = self._get_log_path(service_log_path)
     options = self.selenium_options.create(self.browser_names.get(browser),
                                            options)
     if service_log_path:
         logger.info('Browser driver log file created to: %s' %
                     service_log_path)
         self._create_directory(service_log_path)
     if creation_method == self.create_firefox or creation_method == self.create_headless_firefox:
         return creation_method(desired_capabilities,
                                remote_url,
                                profile_dir,
                                options=options,
                                service_log_path=service_log_path,
                                executable_path=executable_path)
     return creation_method(desired_capabilities,
                            remote_url,
                            options=options,
                            service_log_path=service_log_path,
                            executable_path=executable_path)
 def create_phantomjs(
     self,
     desired_capabilities,
     remote_url,
     options=None,
     service_log_path=None,
     executable_path="phantomjs",
 ):
     warnings.warn(
         "SeleniumLibrary support for PhantomJS has been deprecated, "
         "please use headlesschrome or headlessfirefox instead.")
     if is_truthy(remote_url):
         defaul_caps = webdriver.DesiredCapabilities.PHANTOMJS.copy()
         desired_capabilities = self._remote_capabilities_resolver(
             desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
     if options:
         logger.warn("PhantomJS browser does not support Selenium options.")
     if is_falsy(executable_path):
         executable_path = self._get_executable_path(webdriver.PhantomJS)
     return webdriver.PhantomJS(
         service_log_path=service_log_path,
         executable_path=executable_path,
         **desired_capabilities,
     )
 def create_edge(
     self,
     desired_capabilities,
     remote_url,
     options=None,
     service_log_path=None,
     executable_path="MicrosoftWebDriver.exe",
 ):
     if is_truthy(remote_url):
         defaul_caps = webdriver.DesiredCapabilities.EDGE.copy()
         desired_capabilities = self._remote_capabilities_resolver(
             desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
     if is_falsy(executable_path):
         executable_path = self._get_executable_path(webdriver.Edge)
     if self._has_options(webdriver.Edge):
         # options is supported from Selenium 4.0 onwards
         # If can be removed when minimum Selenium version is 4.0 or greater
         return webdriver.Edge(
             options=options,
             service_log_path=service_log_path,
             executable_path=executable_path,
             **desired_capabilities,
         )
     return webdriver.Edge(
         service_log_path=service_log_path,
         executable_path=executable_path,
         **desired_capabilities,
     )
 def create_firefox(
     self,
     desired_capabilities,
     remote_url,
     ff_profile_dir,
     options=None,
     service_log_path=None,
     executable_path="geckodriver",
 ):
     profile = self._get_ff_profile(ff_profile_dir)
     if is_truthy(remote_url):
         default_caps = webdriver.DesiredCapabilities.FIREFOX.copy()
         desired_capabilities = self._remote_capabilities_resolver(
             desired_capabilities, default_caps)
         return self._remote(desired_capabilities, remote_url, profile,
                             options)
     service_log_path = (service_log_path
                         if service_log_path else self._geckodriver_log)
     if is_falsy(executable_path):
         executable_path = self._get_executable_path(webdriver.Firefox)
     return webdriver.Firefox(
         options=options,
         firefox_profile=profile,
         service_log_path=service_log_path,
         executable_path=executable_path,
         **desired_capabilities,
     )
    def get_cookies(self, as_dict=False):
        """Returns all cookies of the current page.

        If ``as_dict`` argument evaluates as false, see `Boolean arguments` 
        for more details, then cookie information is returned as 
        a single string in format ``name1=value1; name2=value2; name3=value3``.
        When ``as_dict`` argument evaluates as true, cookie information
        is returned as Robot Framework dictionary format. The string format 
        can be used, for example, for logging purposes or in headers when
        sending HTTP requests. The dictionary format is helpful when
        the result can be passed to requests library's Create Session
        keyword's optional cookies parameter.
        
        The `` as_dict`` argument is new in SeleniumLibrary 3.3
        """
        if is_falsy(as_dict):
            pairs = []
            for cookie in self.driver.get_cookies():
                pairs.append(cookie['name'] + "=" + cookie['value'])
            return '; '.join(pairs)
        else:
            pairs = DotDict()
            for cookie in self.driver.get_cookies():
                pairs[cookie['name']] = cookie['value']
            return pairs
Beispiel #11
0
    def click_element(self, locator, modifier=False):
        """Click element identified by ``locator``.

        See the `Locating elements` section for details about the locator
        syntax.

        The ``modifier`` argument can be used to pass
        [https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys|Selenium Keys]
        when clicking the element. The `+` can be used as a separator
        for different Selenium Keys. The `CTRL` is internally translated to
        `CONTROL` key. The ``modifier`` is space and case insensitive, example
        "alt" and " aLt " are supported formats to
        [https://seleniumhq.github.io/selenium/docs/api/py/webdriver/selenium.webdriver.common.keys.html#selenium.webdriver.common.keys.Keys.ALT|ALT key]
        . If ``modifier`` does not match to Selenium Keys, keyword fails.

        Example:
        | Click Element | id:button | | # Would click element without any modifiers. |
        | Click Element | id:button | CTRL | # Would click element with CTLR key pressed down. |
        | Click Element | id:button | CTRL+ALT | # Would click element with CTLR and ALT keys pressed down. |

        The ``modifier`` argument is new in SeleniumLibrary 3.2
        """
        if is_falsy(modifier):
            self.info("Clicking element '%s'." % locator)
            self.find_element(locator).click()
        else:
            self._click_with_modifier(locator, [None, None], modifier)
 def _parse_capabilities(self, capabilities, browser=None):
     if is_falsy(capabilities):
         return {}
     if not isinstance(capabilities, dict):
         capabilities = self._string_to_dict(capabilities)
     browser = self.browser_names.get(browser, browser)
     if browser in ["ie", "firefox", "edge"]:
         return {"capabilities": capabilities}
     return {"desired_capabilities": capabilities}
Beispiel #13
0
 def _parse_capabilities(self, capabilities, browser=None):
     if is_falsy(capabilities):
         return {}
     if not isinstance(capabilities, dict):
         capabilities = self._string_to_dict(capabilities)
     browser = self.browser_names.get(browser, browser)
     if browser in ['ie', 'firefox', 'edge']:
         return {'capabilities': capabilities}
     return {'desired_capabilities': capabilities}
 def _parse_capabilities(self, capabilities, browser=None):
     if is_falsy(capabilities):
         return {}
     if not isinstance(capabilities, dict):
         capabilities = self._string_to_dict(capabilities)
     browser = self.browser_names.get(browser, browser)
     if browser in ['ie', 'firefox', 'edge']:
         return {'capabilities': capabilities}
     return {'desired_capabilities': capabilities}
 def _generic_make_browser(self, webdriver_type , desired_cap_type, remote_url, desired_caps):
     '''most of the make browser functions just call this function which creates the
     appropriate web-driver'''
     if is_falsy(remote_url):
         browser = webdriver_type()
     else:
         browser = self._create_remote_web_driver(desired_cap_type,
                                                  remote_url, desired_caps)
     return browser
 def register(self, strategy_name, strategy_keyword, persist=False):
     strategy = CustomLocator(self.ctx, strategy_name, strategy_keyword)
     if strategy.name in self._strategies:
         raise RuntimeError("The custom locator '%s' cannot be registered. "
                            "A locator of that name already exists."
                            % strategy.name)
     self._strategies[strategy.name] = strategy.find
     if is_falsy(persist):
         # Unregister after current scope ends
         events.on('scope_end', 'current', self.unregister, strategy.name)
Beispiel #17
0
 def register(self, strategy_name, strategy_keyword, persist=False):
     strategy = CustomLocator(self.ctx, strategy_name, strategy_keyword)
     if strategy.name in self._strategies:
         raise RuntimeError("The custom locator '%s' cannot be registered. "
                            "A locator of that name already exists." %
                            strategy.name)
     self._strategies[strategy.name] = strategy.find
     if is_falsy(persist):
         # Unregister after current scope ends
         events.on("scope_end", "current", self.unregister, strategy.name)
Beispiel #18
0
 def _parse_capabilities(self, capabilities):
     if isinstance(capabilities, dict):
         return capabilities
     desired_capabilities = {}
     if is_falsy(capabilities):
         return desired_capabilities
     for part in capabilities.split(','):
         key, value = part.split(':')
         desired_capabilities[key.strip()] = value.strip()
     return desired_capabilities
 def create_opera(self, desired_capabilities, remote_url, options=None, service_log_path=None,
                  executable_path='operadriver'):
     if is_truthy(remote_url):
         defaul_caps = webdriver.DesiredCapabilities.OPERA.copy()
         desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url, options=options)
     if is_falsy(executable_path):
         executable_path = self._get_executable_path(webdriver.Opera)
     return webdriver.Opera(options=options, service_log_path=service_log_path, executable_path=executable_path,
                            **desired_capabilities)
 def create_ie(self, desired_capabilities, remote_url, options=None, service_log_path=None,
               executable_path='IEDriverServer.exe'):
     if is_truthy(remote_url):
         defaul_caps = webdriver.DesiredCapabilities.INTERNETEXPLORER.copy()
         desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url, options=options)
     if is_falsy(executable_path):
         executable_path = self._get_executable_path(webdriver.Ie)
     return webdriver.Ie(options=options, service_log_path=service_log_path, executable_path=executable_path,
                         **desired_capabilities)
 def create_safari(self, desired_capabilities, remote_url, options=None, service_log_path=None,
                   executable_path='/usr/bin/safaridriver'):
     if is_truthy(remote_url):
         defaul_caps = webdriver.DesiredCapabilities.SAFARI.copy()
         desired_capabilities = self._remote_capabilities_resolver(desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
     if options or service_log_path:
         logger.warn('Safari browser does not support Selenium options or service_log_path.')
     if is_falsy(executable_path):
         executable_path = self._get_executable_path(webdriver.Safari)
     return webdriver.Safari(executable_path=executable_path, **desired_capabilities)
Beispiel #22
0
    def _make_ff(self, remote, desired_capabilites, profile_dir):

        if is_falsy(profile_dir):
            profile_dir = FIREFOX_PROFILE_DIR
        profile = webdriver.FirefoxProfile(profile_dir)
        if is_truthy(remote):
            browser = self._create_remote_web_driver(
                webdriver.DesiredCapabilities.FIREFOX, remote,
                desired_capabilites, profile)
        else:
            browser = webdriver.Firefox(firefox_profile=profile)
        return browser
Beispiel #23
0
    def submit_form(self, locator=None):
        """Submits a form identified by `locator`.

        If `locator` is empty, first form in the page will be submitted.
        Key attributes for forms are `id` and `name`. See `introduction` for
        details about locating elements.
        """
        self.info("Submitting form '%s'." % locator)
        if is_falsy(locator):
            locator = 'xpath=//form'
        element = self.find_element(locator, tag='form')
        element.submit()
 def locator_should_match_x_times(self, locator, x, message=None, loglevel='TRACE'):
     """*DEPRECATED in SeleniumLibrary 4.0.*, use `Page Should Contain Element` with ``limit`` argument instead."""
     count = len(self.find_elements(locator))
     x = int(x)
     if count != x:
         if is_falsy(message):
             message = ("Locator '%s' should have matched %s time%s but "
                        "matched %s time%s."
                        % (locator, x, s(x), count, s(count)))
         self.ctx.log_source(loglevel)
         raise AssertionError(message)
     self.info("Current page contains %s elements matching '%s'."
               % (count, locator))
Beispiel #25
0
 def locator_should_match_x_times(self, locator, x, message=None, loglevel="TRACE"):
     """*DEPRECATED in SeleniumLibrary 4.0.*, use `Page Should Contain Element` with ``limit`` argument instead."""
     count = len(self.find_elements(locator))
     x = int(x)
     if count != x:
         if is_falsy(message):
             message = (
                 "Locator '%s' should have matched %s time%s but "
                 "matched %s time%s." % (locator, x, s(x), count, s(count))
             )
         self.ctx.log_source(loglevel)
         raise AssertionError(message)
     self.info("Current page contains %s elements matching '%s'." % (count, locator))
    def _generic_make_driver(self, webdriver_type, desired_cap_type,
                             remote_url, desired_caps):
        """Generic driver creation

        Most of the make driver functions just call this function which
        creates the appropriate driver
        """
        if is_falsy(remote_url):
            driver = webdriver_type()
        else:
            driver = self._create_remote_web_driver(desired_cap_type,
                                                    remote_url, desired_caps)
        return driver
Beispiel #27
0
 def locator_should_match_x_times(self, locator, x, message=None, loglevel="TRACE"):
     """*DEPRECATED in SeleniumLibrary 4.0.*, use `Page Should Contain Element` with ``limit`` argument instead."""
     count = len(self.find_elements(locator))
     x = int(x)
     if count != x:
         if is_falsy(message):
             message = (
                 f"Locator '{locator}' should have matched {x} time{plural_or_not(x)} but "
                 f"matched {count} time{plural_or_not(count)}."
             )
         self.ctx.log_source(loglevel)
         raise AssertionError(message)
     self.info(f"Current page contains {count} elements matching '{locator}'.")
Beispiel #28
0
 def create_edge(self, desired_capabilities, remote_url, options=None, service_log_path=None,
                 executable_path='msedgedriver.exe'):
     if is_truthy(remote_url):
         defaul_caps = webdriver.DesiredCapabilities.EDGE.copy()
         desired_capabilities = self._remote_capabilities_resolver(
             desired_capabilities, defaul_caps)
         return self._remote(desired_capabilities, remote_url)
     if is_falsy(executable_path):
         executable_path = self._get_executable_path(EdgePluginDriver)
     return EdgePluginDriver(options=options,
                             service_log_path=service_log_path,
                             executable_path=executable_path,
                             **desired_capabilities)
 def _make_ff(self, remote, desired_capabilites, profile_dir):
     if is_falsy(profile_dir):
         profile = webdriver.FirefoxProfile()
     else:
         profile = webdriver.FirefoxProfile(profile_dir)
     if is_truthy(remote):
         browser = self._create_remote_web_driver(
             webdriver.DesiredCapabilities.FIREFOX, remote,
             desired_capabilites, profile)
     else:
         browser = webdriver.Firefox(firefox_profile=profile,
                                     **self._geckodriver_log_config)
     return browser
Beispiel #30
0
 def _parse_capabilities(self, capabilities, browser=None):
     if is_falsy(capabilities):
         return {}
     if not isinstance(capabilities, dict):
         capabilities = self._string_to_dict(capabilities)
     browser_alias = {'googlechrome': "chrome", 'gc': "chrome",
                      'headlesschrome': 'chrome', 'ff': 'firefox',
                      'headlessfirefox': 'firefox',
                      'internetexplorer': 'ie'}
     browser = browser_alias.get(browser, browser)
     if browser in ['ie', 'firefox', 'edge']:
         return {'capabilities': capabilities}
     return {'desired_capabilities': capabilities}
 def assert_page_contains(self,
                          locator,
                          tag=None,
                          message=None,
                          loglevel='INFO'):
     element_name = tag if tag else 'element'
     if not self.find(locator, tag, required=False):
         if is_falsy(message):
             message = ("Page should have contained %s '%s' but did not" %
                        (element_name, locator))
         self.ctx.log_source(loglevel)  # TODO: Could this moved to base
         raise AssertionError(message)
     logger.info("Current page contains %s '%s'." % (element_name, locator))
    def _parse_capabilities_string(self, capabilities_string):
        '''parses the string based desired_capabilities which should be in the form
        key1:val1,key2:val2
        '''
        desired_capabilities = {}

        if is_falsy(capabilities_string):
            return desired_capabilities

        for cap in capabilities_string.split(","):
            (key, value) = cap.split(":", 1)
            desired_capabilities[key.strip()] = value.strip()

        return desired_capabilities
Beispiel #33
0
    def textfield_should_contain(self, locator, expected, message=''):
        """Verifies text field identified by `locator` contains text `expected`.

        `message` can be used to override default error message.

        Key attributes for text fields are `id` and `name`. See `introduction`
        for details about locating elements.
        """
        actual = self.element_finder.get_value(locator, 'text field')
        if expected not in actual:
            if is_falsy(message):
                message = "Text field '%s' should have contained text '%s' "\
                          "but it contained '%s'" % (locator, expected, actual)
            raise AssertionError(message)
        self.info("Text field '%s' contains text '%s'." % (locator, expected))
Beispiel #34
0
 def create(self, browser, options):
     if is_falsy(options):
         return None
     selenium_options = self._import_options(browser)
     if not is_string(options):
         return options
     options = self._parse(options)
     selenium_options = selenium_options()
     for option in options:
         for key in option:
             attr = getattr(selenium_options, key)
             if callable(attr):
                 attr(*option[key])
             else:
                 setattr(selenium_options, key, *option[key])
     return selenium_options
Beispiel #35
0
    def element_should_not_contain(self, locator, expected, message=''):
        """Verifies element identified by `locator` does not contain text `expected`.

        `message` can be used to override the default error message.

        Key attributes for arbitrary elements are `id` and `name`. See
        `Element Should Contain` for more details.
        """
        self.info("Verifying element '%s' does not contain text '%s'." %
                  (locator, expected))
        actual = self._get_text(locator)
        if expected in actual:
            if is_falsy(message):
                message = "Element '%s' should not contain text '%s' but " \
                          "it did." % (locator, expected)
            raise AssertionError(message)
Beispiel #36
0
    def wait_until_page_contains(self, text, timeout=None, error=None):
        """Waits until `text` appears on current page.

        Fails if `timeout` expires before the text appears. See
        `introduction` for more information about `timeout` and its
        default value.

        `error` can be used to override the default error message.

        See also `Wait Until Page Contains Element`, `Wait For Condition`,
        `Wait Until Element Is Visible` and BuiltIn keyword `Wait Until
        Keyword Succeeds`.
        """
        if is_falsy(error):
            error = "Text '%s' did not appear in <TIMEOUT>" % text
        self._wait_until(timeout, error, self.element.is_text_present, text)
    def wait_until_page_contains(self, text, timeout=None, error=None):
        """Waits until `text` appears on current page.

        Fails if `timeout` expires before the text appears. See
        `introduction` for more information about `timeout` and its
        default value.

        `error` can be used to override the default error message.

        See also `Wait Until Page Contains Element`, `Wait For Condition`,
        `Wait Until Element Is Visible` and BuiltIn keyword `Wait Until
        Keyword Succeeds`.
        """
        if is_falsy(error):
            error = "Text '%s' did not appear in <TIMEOUT>" % text
        self._wait_until(timeout, error, self.element.is_text_present, text)
    def element_should_not_contain(self, locator, expected, message=''):
        """Verifies element identified by `locator` does not contain text `expected`.

        `message` can be used to override the default error message.

        Key attributes for arbitrary elements are `id` and `name`. See
        `Element Should Contain` for more details.
        """
        self.info("Verifying element '%s' does not contain text '%s'."
                  % (locator, expected))
        actual = self._get_text(locator)
        if expected in actual:
            if is_falsy(message):
                message = "Element '%s' should not contain text '%s' but " \
                          "it did." % (locator, expected)
            raise AssertionError(message)
    def element_should_not_be_visible(self, locator, message=''):
        """Verifies that the element identified by `locator` is NOT visible.

        This is the opposite of `Element Should Be Visible`.

        `message` can be used to override the default error message.

        Key attributes for arbitrary elements are `id` and `name`. See
        `introduction` for details about locating elements.
        """
        self.info("Verifying element '%s' is not visible." % locator)
        visible = self.is_visible(locator)
        if visible:
            if is_falsy(message):
                message = ("The element '%s' should not be visible, "
                           "but it is." % locator)
            raise AssertionError(message)
    def click_link(self, locator, modifier=False):
        """Clicks a link identified by ``locator``.

        See the `Locating elements` section for details about the locator
        syntax. When using the default locator strategy, links are searched
        using ``id``, ``name``, ``href`` and the link text.

        See the `Click Element` keyword for details about the
        ``modifier`` argument.

        The ``modifier`` argument is new in SeleniumLibrary 3.3
        """
        if is_falsy(modifier):
            self.info("Clicking link '%s'." % locator)
            self.find_element(locator, tag='link').click()
        else:
            self._click_with_modifier(locator, ['link', 'link'], modifier)
    def set_screenshot_directory(self, path, persist=False):
        """Sets the root output directory for captured screenshots.

        ``path`` argument specifies the absolute path where the screenshots
        should be written to. If the specified ``path`` does not exist,
        it will be created. Setting ``persist`` specifies that the given
        ``path`` should be used for the rest of the test execution, otherwise
        the path will be restored at the end of the currently executing scope.
        """
        path = os.path.abspath(path)
        self._create_directory(path)
        if is_falsy(persist):
            self._screenshot_path_stack.append(self.screenshot_root_directory)
            # Restore after current scope ends
            events.on('scope_end', 'current',
                      self._restore_screenshot_directory)
        self.screenshot_root_directory = path
    def wait_until_page_contains_element(self, locator, timeout=None, error=None):
        """Waits until element specified with `locator` appears on current page.

        Fails if `timeout` expires before the element appears. See
        `introduction` for more information about `timeout` and its
        default value.

        `error` can be used to override the default error message.

        See also `Wait Until Page Contains`, `Wait For Condition`,
        `Wait Until Element Is Visible` and BuiltIn keyword `Wait Until
        Keyword Succeeds`.
        """
        def is_element_present(locator):
            return self.find_element(locator, required=False) is not None
        if is_falsy(error):
            error = "Element '%s' did not appear in <TIMEOUT>" % locator
        self._wait_until(timeout, error, is_element_present, locator)
    def element_should_contain(self, locator, expected, message=''):
        """Verifies element identified by `locator` contains text `expected`.

        If you wish to assert an exact (not a substring) match on the text
        of the element, use `Element Text Should Be`.

        `message` can be used to override the default error message.

        Key attributes for arbitrary elements are `id` and `name`. See
        `introduction` for details about locating elements.
        """
        self.info("Verifying element '%s' contains "
                  "text '%s'." % (locator, expected))
        actual = self._get_text(locator)
        if expected not in actual:
            if is_falsy(message):
                message = "Element '%s' should have contained text '%s' but "\
                          "its text was '%s'." % (locator, expected, actual)
            raise AssertionError(message)
    def locator_should_match_x_times(self, locator, expected_locator_count, message='', loglevel='INFO'):
        """Verifies that the page contains the given number of elements located by the given `locator`.

        See `introduction` for details about locating elements.

        See `Page Should Contain Element` for explanation about `message` and
        `loglevel` arguments.
        """
        actual_locator_count = len(self.find_element(
            locator, first_only=False, required=False)
        )
        if int(actual_locator_count) != int(expected_locator_count):
            if is_falsy(message):
                message = "Locator %s should have matched %s times but matched %s times"\
                            %(locator, expected_locator_count, actual_locator_count)
            self.ctx.log_source(loglevel)
            raise AssertionError(message)
        self.info("Current page contains %s elements matching '%s'."
                  % (actual_locator_count, locator))
    def element_should_be_visible(self, locator, message=''):
        """Verifies that the element identified by `locator` is visible.

        Herein, visible means that the element is logically visible, not optically
        visible in the current browser viewport. For example, an element that carries
        display:none is not logically visible, so using this keyword on that element
        would fail.

        `message` can be used to override the default error message.

        Key attributes for arbitrary elements are `id` and `name`. See
        `introduction` for details about locating elements.
        """
        self.info("Verifying element '%s' is visible." % locator)
        visible = self.is_visible(locator)
        if not visible:
            if is_falsy(message):
                message = ("The element '%s' should be visible, but it "
                           "is not." % locator)
            raise AssertionError(message)
    def click_button(self, locator, modifier=False):
        """Clicks button identified by ``locator``.

        See the `Locating elements` section for details about the locator
        syntax. When using the default locator strategy, buttons are
        searched using ``id``, ``name`` and ``value``.

        See the `Click Element` keyword for details about the
        ``modifier`` argument.

        The ``modifier`` argument is new in SeleniumLibrary 3.3
        """
        if is_falsy(modifier):
            self.info("Clicking button '%s'." % locator)
            element = self.find_element(locator, tag='input', required=False)
            if not element:
                element = self.find_element(locator, tag='button')
            element.click()
        else:
            self._click_with_modifier(locator, ['button', 'input'], modifier)
    def click_image(self, locator, modifier=False):
        """Clicks an image identified by ``locator``.

        See the `Locating elements` section for details about the locator
        syntax. When using the default locator strategy, images are searched
        using ``id``, ``name``, ``src`` and ``alt``.

        See the `Click Element` keyword for details about the
        ``modifier`` argument.

        The ``modifier`` argument is new in SeleniumLibrary 3.3
        """
        if is_falsy(modifier):
            self.info("Clicking image '%s'." % locator)
            element = self.find_element(locator, tag='image', required=False)
            if not element:
                # A form may have an image as it's submit trigger.
                element = self.find_element(locator, tag='input')
            element.click()
        else:
            self._click_with_modifier(locator, ['image', 'input'], modifier)
    def element_text_should_be(self, locator, expected, message=''):
        """Verifies element identified by `locator` exactly contains text `expected`.

        In contrast to `Element Should Contain`, this keyword does not try
        a substring match but an exact match on the element identified by `locator`.

        `message` can be used to override the default error message.

        Key attributes for arbitrary elements are `id` and `name`. See
        `introduction` for details about locating elements.
        """
        self.info("Verifying element '%s' contains exactly text '%s'."
                  % (locator, expected))
        element = self.find_element(locator)
        actual = element.text
        if expected != actual:
            if is_falsy(message):
                message = ("The text of element '%s' should have been '%s' "
                           "but in fact it was '%s'."
                           % (locator, expected, actual))
            raise AssertionError(message)
    def set_window_size(self, width, height, inner=False):
        """Sets current windows size to given ``width`` and ``height``.

        Values can be given using strings containing numbers or by using
        actual numbers. See also `Get Window Size`.

        Browsers have a limit how small they can be set. Trying to set them
        smaller will cause the actual size to be bigger than the requested
        size.

        If ``inner`` parameter is set to True, keyword sets the necessary
        window width and height to have the desired HTML DOM window.innerWidth
        and window.innerHeight The ``inner`` is new in SeleniumLibrary 4.0.
        See `Boolean arguments` for more details how to set boolean
        arguments.

        This ``inner`` argument does not support Frames. If a frame is selected,
        switch to default before running this.

        Example:
        | `Set Window Size` | 800 | 600 |      |
        | `Set Window Size` | 800 | 600 | True |
        """
        width, height = int(width), int(height)
        if is_falsy(inner):
            return self.driver.set_window_size(width, height)
        self.driver.set_window_size(width, height)
        inner_width = int(self.driver.execute_script("return window.innerWidth;"))
        inner_height = int(self.driver.execute_script("return window.innerHeight;"))
        self.info('window.innerWidth is %s and window.innerHeight is %s' % (inner_width, inner_height))
        width_offset = width - inner_width
        height_offset = height - inner_height
        window_width = width + width_offset
        window_height = height + height_offset
        self.info('Setting window size to %s %s' % (window_width, window_height))
        self.driver.set_window_size(window_width, window_height)
        result_width = int(self.driver.execute_script("return window.innerWidth;"))
        result_height = int(self.driver.execute_script("return window.innerHeight;"))
        if result_width != width or result_height != height:
            raise AssertionError("Keyword failed setting correct window size.")
    def xpath_should_match_x_times(self, xpath, expected_xpath_count, message='', loglevel='INFO'):
        """Verifies that the page contains the given number of elements located by the given `xpath`.

        One should not use the xpath= prefix for 'xpath'. XPath is assumed.

        Correct:
        | Xpath Should Match X Times | //div[@id='sales-pop'] | 1
        Incorrect:
        | Xpath Should Match X Times | xpath=//div[@id='sales-pop'] | 1

        See `Page Should Contain Element` for explanation about `message` and
        `loglevel` arguments.
        """
        actual_xpath_count = len(self.find_element(
            "xpath=" + xpath, first_only=False, required=False))
        if int(actual_xpath_count) != int(expected_xpath_count):
            if is_falsy(message):
                message = ("Xpath %s should have matched %s times but "
                           "matched %s times"
                           % (xpath, expected_xpath_count, actual_xpath_count))
            self.ctx.log_source(loglevel)
            raise AssertionError(message)
        self.info("Current page contains %s elements matching '%s'."
                  % (actual_xpath_count, xpath))
    def wait_for_condition(self, condition, timeout=None, error=None):
        """Waits until the given ``condition`` is true or ``timeout`` expires.

        The ``condition`` can be arbitrary JavaScript expression but it
        must return a value to be evaluated. See `Execute JavaScript` for
        information about accessing content on pages.

        ``error`` can be used to override the default error message.

        See `timeouts` for more information about using timeouts and their
        default value.

        See also `Wait Until Page Contains`, `Wait Until Page Contains
        Element`, `Wait Until Element Is Visible` and BuiltIn keyword
        `Wait Until Keyword Succeeds`.
        """
        if 'return' not in condition:
            raise ValueError("Condition '%s' did not have mandatory 'return'."
                             % condition)
        if is_falsy(error):
            error = "Condition '%s' did not become true in <TIMEOUT>" % condition
        self._wait_until(
            timeout, error,
            lambda: self.browser.execute_script(condition) is True)
 def resolve_keyword(name):
     if is_falsy(name) or is_string(name) and name.upper() == 'NOTHING':
         return None
     return name
    def select_window(self, locator='MAIN', timeout=None):
        """Selects browser window matching ``locator``.

        If the window is found, all subsequent commands use the selected
        window, until this keyword is used again. If the window is not
        found, this keyword fails. The previous window handle is returned,
        and can be used to return back to it later.

        Notice that in this context _window_ means a pop-up window opened
        when doing something on an existing window. It is not possible to
        select windows opened with `Open Browser`, `Switch Browser` must
        be used instead. Notice also that alerts should be handled with
        `Handle Alert` or other alert related keywords.

        The ``locator`` can be specified using different strategies somewhat
        similarly as when `locating elements` on pages.

        - By default the ``locator`` is matched against window handle, name,
          title, and URL. Matching is done in that order and the the first
          matching window is selected.

        - The ``locator`` can specify an explicit strategy by using format
          ``strategy:value`` (recommended) or ``strategy=value``. Supported
          strategies are ``name``, ``title`` and ``url``, which match windows
          using name, title, and URL, respectively. Additionally, ``default``
          can be used to explicitly use the default strategy explained above.

        - If the ``locator`` is ``NEW`` (case-insensitive), the latest
          opened window is selected. It is an error if this is the same
          as the current window.

        - If the ``locator`` is ``MAIN`` (default, case-insensitive),
          the main window is selected.

        - If the ``locator`` is ``CURRENT`` (case-insensitive), nothing is
          done. This effectively just returns the current window handle.

        - If the ``locator`` is not a string, it is expected to be a list
          of window handles _to exclude_. Such a list of excluded windows
          can be get from `Get Window Handles` prior to doing an action that
          opens a new window.

        The ``timeout`` is used to specify how long keyword will poll to select
        the new window. The ``timeout`` is new in SeleniumLibrary 3.2.

        Example:
        | `Click Link`      | popup1      |      | # Open new window |
        | `Select Window`   | example     |      | # Select window using default strategy |
        | `Title Should Be` | Pop-up 1    |      |
        | `Click Button`    | popup2      |      | # Open another window |
        | ${handle} = | `Select Window`   | NEW  | # Select latest opened window |
        | `Title Should Be` | Pop-up 2    |      |
        | `Select Window`   | ${handle}   |      | # Select window using handle |
        | `Title Should Be` | Pop-up 1    |      |
        | `Select Window`   | MAIN        |      | # Select the main window |
        | `Title Should Be` | Main        |      |
        | ${excludes} = | `Get Window Handles` | | # Get list of current windows |
        | `Click Link`      | popup3      |      | # Open one more window |
        | `Select Window`   | ${excludes} |      | # Select window using excludes |
        | `Title Should Be` | Pop-up 3    |      |

        *NOTE:*

        - The ``strategy:value`` syntax is only supported by SeleniumLibrary
          3.0 and newer.
        - Prior to SeleniumLibrary 3.0 matching windows by name, title
          and URL was case-insensitive.
        - Earlier versions supported aliases ``None``, ``null`` and the
          empty string for selecting the main window, and alias ``self``
          for selecting the current window. Support for these aliases were
          removed in SeleniumLibrary 3.2.
        """
        epoch = time.time()
        timeout = epoch if is_falsy(timeout) else timestr_to_secs(timeout) + epoch
        try:
            return self.driver.current_window_handle
        except NoSuchWindowException:
            pass
        finally:
            self._window_manager.select(locator, timeout)
 def test_is_falsy(self):
     for item in self.truthy:
         self.assertTrue(is_falsy(item) is False)
     for item in self.falsy:
         self.assertTrue(is_falsy(item) is True)
 def _get_ff_profile(self, ff_profile_dir):
     if is_falsy(ff_profile_dir):
         return webdriver.FirefoxProfile()
     return webdriver.FirefoxProfile(ff_profile_dir)