Selenium action 'move_to_element' doesn

2020-07-23 05:39发布

问题:

The next command is failed on Safari browser during automation testing:

ActionChains(driver).move_to_element(searchInput).perform()

Exception:

InvalidArgumentException: Message: Encountered key input source with invalid 'value' in payload: {actions = ({duration = 0;type = pause;}); id = key; type = key;}

The whole refined test example:

def test_safari2(self):
    driver = webdriver.Safari()
    driver.get('https://www.wikipedia.org')
    locator = (By.ID, 'searchInput')

    # 1. the line below is passed
    searchInput = WebDriverWait(driver, timeout=30).until(expected_conditions.visibility_of_element_located(locator))

    # 2. the line below is failed in Safari, but passed in Chrome, FF
    ActionChains(driver).move_to_element(searchInput).perform()

However! If self.w3c_actions.key_action.pause() is commented inside action move_to_element(), then the whole Action chains works!

def move_to_element(self, to_element):
    """
    Moving the mouse to the middle of an element.

    :Args:
     - to_element: The WebElement to move to.
    """
    if self._driver.w3c:
        self.w3c_actions.pointer_action.move_to(to_element)
        # self.w3c_actions.key_action.pause()
    else:
        self._actions.append(lambda: self._driver.execute(
                             Command.MOVE_TO, {'element': to_element.id}))
    return self

The similar situation with other actions. My question is: Is it is known limitation of Safari? And therefore ActionChais command could not be use for Selenium + Safari? Or there is some configuration pecularity?

My test runner configuration:

  • OS: Mac HighSierra 10.13.6
  • Safari 12.0 (13606.2.11)
  • Selenium: 3.14.1
  • Python: 2.7.14
  • Safari is started with w3c capabilities and protocol (i.e. driver.w3c=True)

Issue background: I have an enough developed framework with a lot of actions and tests that work Ok for Chrome and Firefox. Now I'm trying to extend coverage for Safari browser also. So, that is why I'm searching for solution for not working ActionChains

回答1:

Workaround by wrapping ActionChains class so that key_action.pause is not used (which does not seem to serve any important purpose):

import selenium.webdriver

class ActionChains(selenium.webdriver.ActionChains):
    def __init__(self, driver):
        super(ActionChains, self).__init__(driver)
        if driver.name in ('Safari', 'Safari Technology Preview'):
            self.w3c_actions.key_action.pause = lambda *a, **k: None