首页 > 解决方案 > Selenium Python 动作链在 Firefox 上失败

问题描述

我正在使用以下库进行测试:

py==1.4.31 
pytest==2.8.5 
requests==2.9.1 
robotframework==2.8.5 
robotframework-selenium2library==1.5.0 
selenium==3.3.1

python 2.7

每当我尝试在 Firefox 上执行操作链命令时,我都会收到 WebDriverException。该代码适用于 Chrome 和 IE。我尝试了几种不同风格的动作链命令,但都因为同样的原因失败了。

                ActionChains(self.driver).key_down(Keys.SHIFT).click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[0] + "']")).click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[1] + "']")).click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[2] + "']")).key_up(Keys.SHIFT).perform()

... 和...

                ActionChains(self.driver) \
                .key_down(Keys.SHIFT) \
                .click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[0] + "']")) \
                .click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[1] + "']")) \
                .click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[2] + "']")) \
                .key_up(Keys.SHIFT) \
                .perform()

正如您从命令中看到的那样,我在选择屏幕上的对象时按住 shift 键。然后我松开 shift 键。这是我收到的失败:

firewall.py:454: in editCommon
    ActionChains(self.driver).key_down(Keys.SHIFT).click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[0] + "']")).click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[1] + "']")).click(self.driver.find_element_by_xpath("//select[@name='ctstate']/option[@value='" + stateList[2] + "']")).key_up(Keys.SHIFT).perform()
C:\Python27\lib\site-packages\selenium-3.3.1-py2.7.egg\selenium\webdriver\common\action_chains.py:80: in perform
    action()
C:\Python27\lib\site-packages\selenium-3.3.1-py2.7.egg\selenium\webdriver\common\action_chains.py:232: in <lambda>
    {"value": keys_to_typing(value)}))
C:\Python27\lib\site-packages\selenium-3.3.1-py2.7.egg\selenium\webdriver\remote\webdriver.py:238: in execute
    self.error_handler.check_response(response)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _

self = <selenium.webdriver.remote.errorhandler.ErrorHandler object at 0x05615430>
response = {'status': 500, 'value': '{"value":{"stacktrace":"org.openqa.selenium.UnsupportedCommandException: sendKeysToActiveEle...: \'10.0\', java.version: \'1.8.0_151\'\nDriver info: driver.version: unknown","error":"unknown command"},"status":9}'}

    def check_response(self, response):
        """
            Checks that a JSON response from the WebDriver does not have an error.

            :Args:
             - response - The JSON response from the WebDriver server as a dictionary
               object.

            :Raises: If the response contains an error message.
            """
        status = response.get('status', None)
        if status is None or status == ErrorCode.SUCCESS:
            return
        value = None
        message = response.get("message", "")
        screen = response.get("screen", "")
        stacktrace = None
        if isinstance(status, int):
            value_json = response.get('value', None)
            if value_json and isinstance(value_json, basestring):
                import json
                try:
                    value = json.loads(value_json)
                    if len(value.keys()) == 1:
                        value = value['value']
                    status = value.get('error', None)
                    if status is None:
                        status = value["status"]
                        message = value["value"]
                        if not isinstance(message, basestring):
                            value = message
                            try:
                                message = message['message']
                            except TypeError:
                                message = None
                    else:
                        message = value.get('message', None)
                except ValueError:
                    pass

        exception_class = ErrorInResponseException
        if status in ErrorCode.NO_SUCH_ELEMENT:
            exception_class = NoSuchElementException
        elif status in ErrorCode.NO_SUCH_FRAME:
            exception_class = NoSuchFrameException
        elif status in ErrorCode.NO_SUCH_WINDOW:
            exception_class = NoSuchWindowException
        elif status in ErrorCode.STALE_ELEMENT_REFERENCE:
            exception_class = StaleElementReferenceException
        elif status in ErrorCode.ELEMENT_NOT_VISIBLE:
            exception_class = ElementNotVisibleException
        elif status in ErrorCode.INVALID_ELEMENT_STATE:
            exception_class = InvalidElementStateException
        elif status in ErrorCode.INVALID_SELECTOR \
                or status in ErrorCode.INVALID_XPATH_SELECTOR \
                or status in ErrorCode.INVALID_XPATH_SELECTOR_RETURN_TYPER:
            exception_class = InvalidSelectorException
        elif status in ErrorCode.ELEMENT_IS_NOT_SELECTABLE:
            exception_class = ElementNotSelectableException
        elif status in ErrorCode.INVALID_COOKIE_DOMAIN:
            exception_class = WebDriverException
        elif status in ErrorCode.UNABLE_TO_SET_COOKIE:
            exception_class = WebDriverException
        elif status in ErrorCode.TIMEOUT:
            exception_class = TimeoutException
        elif status in ErrorCode.SCRIPT_TIMEOUT:
            exception_class = TimeoutException
        elif status in ErrorCode.UNKNOWN_ERROR:
            exception_class = WebDriverException
        elif status in ErrorCode.UNEXPECTED_ALERT_OPEN:
            exception_class = UnexpectedAlertPresentException
        elif status in ErrorCode.NO_ALERT_OPEN:
            exception_class = NoAlertPresentException
        elif status in ErrorCode.IME_NOT_AVAILABLE:
            exception_class = ImeNotAvailableException
        elif status in ErrorCode.IME_ENGINE_ACTIVATION_FAILED:
            exception_class = ImeActivationFailedException
        elif status in ErrorCode.MOVE_TARGET_OUT_OF_BOUNDS:
            exception_class = MoveTargetOutOfBoundsException
        else:
            exception_class = WebDriverException
        if value == '' or value is None:
            value = response['value']
        if isinstance(value, basestring):
            if exception_class == ErrorInResponseException:
                raise exception_class(response, value)
            raise exception_class(value)
        if message == "" and 'message' in value:
            message = value['message']

        screen = None
        if 'screen' in value:
            screen = value['screen']

        stacktrace = None
        if 'stackTrace' in value and value['stackTrace']:
            stacktrace = []
            try:
                for frame in value['stackTrace']:
                    line = self._value_or_default(frame, 'lineNumber', '')
                    file = self._value_or_default(frame, 'fileName', '<anonymous>')
                    if line:
                        file = "%s:%s" % (file, line)
                    meth = self._value_or_default(frame, 'methodName', '<anonymous>')
                    if 'className' in frame:
                        meth = "%s.%s" % (frame['className'], meth)
                    msg = "    at %s (%s)"
                    msg = msg % (meth, file)
                    stacktrace.append(msg)
            except TypeError:
                pass
        if exception_class == ErrorInResponseException:
            raise exception_class(response, message)
        elif exception_class == UnexpectedAlertPresentException and 'alert' in value:
            raise exception_class(message, screen, stacktrace, value['alert'].get('text'))
>       raise exception_class(message, screen, stacktrace)
E       WebDriverException: Message: sendKeysToActiveElement
E       Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T16:15:40.131Z'
E       System info: host: 'DESKTOP-NTB4PU8', ip: '172.16.190.211', os.name: 'Windows 10', os.arch: 'x86', os.version: '10.0', java.version: '1.8.0_151'
E       Driver info: driver.version: unknown
E       Stacktrace:
E           at org.openqa.selenium.remote.http.AbstractHttpCommandCodec.encode (AbstractHttpCommandCodec.java:220)
E           at org.openqa.selenium.remote.http.AbstractHttpCommandCodec.encode (AbstractHttpCommandCodec.java:118)
E           at org.openqa.selenium.remote.server.ProtocolConverter.handle (ProtocolConverter.java:84)
E           at org.openqa.selenium.remote.server.ServicedSession.execute (ServicedSession.java:97)
E           at org.openqa.selenium.remote.server.WebDriverServlet.lambda$handle$0 (WebDriverServlet.java:232)
E           at java.util.concurrent.Executors$RunnableAdapter.call (None:-1)
E           at java.util.concurrent.FutureTask.run (None:-1)
E           at java.util.concurrent.ThreadPoolExecutor.runWorker (None:-1)
E           at java.util.concurrent.ThreadPoolExecutor$Worker.run (None:-1)
E           at java.lang.Thread.run (None:-1)

C:\Python27\lib\site-packages\selenium-3.3.1-py2.7.egg\selenium\webdriver\remote\errorhandler.py:193: WebDriverException

我很困惑为什么 Firefox 不喜欢我尝试使用任何动作链命令。任何建议或见解将不胜感激。

标签: pythonseleniumfirefoxselenium-webdriverwebdriver

解决方案


如果您的 geckodriver 版本<v0.14升级到>=v0.15. 这是不支持 Actions 类的早期版本的 geckodriver 中的一个已知问题。见: 所以回答


推荐阅读