Selenium:元素不可点击......其他元素将收到点击

Selenium: Element not clickable ... Other Element Would Receive Click

当 运行ning Selenium 测试我的 Django 项目时,我开始收到错误:

selenium.common.exceptions.WebDriverException: Message: Element is not clickable at point (61, 24.300003051757812). Other element would receive the click: <a class="navbar-brand" href="#"></a>

这很奇怪,原因有二:首先,之前的测试通过了,我还没有编辑那部分代码库。其次,当 Selenium 驱动的 Firefox Window 弹出并且我最大化页面时,测试通过了。但是当我让 Firefox 浏览器未最大化的 Selenium 测试 运行 时,它们失败了。

我没有使用任何花哨的 javascript(只是基本的 Bootstrap 3 模板),只是普通的 html 和 css。我在 Python 3.4 上使用 Django 1.9。我已经 运行 pip 来检查对 Selenium 的升级,我是最新的。

Here is a pastebin link 到我的视图和模板输出的 html。

失败的测试之一是:

def test_create_task_and_check_that_it_shows_up_in_the_task_manager_index_and_filter(self):
        # Create user
        self.user = User.objects.get(username=test_superuser_username)
        # Log the user in
        self.log_user_in(user_object=self.user, password=test_superuser_password)
        self.browser.implicitly_wait(10)
        # Pull up the main task manager page
        self.browser.get(str(self.live_server_url) + reverse('task_manager:index'))
        # Make sure we go to the task manager index
        task_index_url = str(self.live_server_url) + reverse('task_manager:index')
        self.browser.get(task_index_url)
        self.browser.implicitly_wait(4)
        self.assertTrue(str(task_index_url) == self.browser.current_url,
                        msg=('Assertion that current_url is %s failed. Current_url is %s' %
                             (str(reverse('task_manager:index')), self.browser.current_url)))
        # Click the 'add task' button on the sidebar
        add_task_taskbar_button = self.browser.find_element_by_name('add_task_sidebar_link')
        add_task_taskbar_button.click()

最后一行产生错误:

ERROR: test_create_task_and_check_that_it_shows_up_in_the_task_manager_index_and_filter (tasks.tests.test_functional.SeleniumTest)
----------------------------------------------------------------------
Traceback (most recent call last):
  File "/home/mint/Python_Projects/[project_name]/tasks/tests/test_functional.py", line 94, in test_create_task_and_check_that_it_shows_up_in_the_task_manager_index_and_filter
    add_task_taskbar_button.click()
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/selenium/webdriver/remote/webelement.py", line 75, in click
    self._execute(Command.CLICK_ELEMENT)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/selenium/webdriver/remote/webelement.py", line 469, in _execute
    return self._parent.execute(command, params)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/selenium/webdriver/remote/webdriver.py", line 201, in execute
    self.error_handler.check_response(response)
  File "/home/mint/Python_Projects/venv/lib/python3.4/site-packages/selenium/webdriver/remote/errorhandler.py", line 194, in check_response
    raise exception_class(message, screen, stacktrace)
selenium.common.exceptions.WebDriverException: Message: Element is not clickable at point (61, 24.300003051757812). Other element would receive the click: <a class="navbar-brand" href="#"></a>

你的答案就在你的问题中。

  1. 错误提示 'add_task_sidebar_link' not clickable at point - (61, 24.300003051757812) 这是另一个元素所在的位置 - Other element would receive the click: <a class="navbar-brand" href="#"></a> 尝试点击的位置。由于您没有最大化浏览器,您无法正确获取点坐标。
  2. 为了以后的测试不会中断,请滚动到该元素。参考这个post (). Check Action chains (http://selenium-python.readthedocs.org/api.html#module-selenium.webdriver.common.action_chains)

这更多地与元素 'covering' 彼此有关。如果它发生在非最大化 windows 上,这是有道理的。如果 popup/floating div 或其他元素覆盖了您实际尝试单击的元素,也可能会发生这种情况。

请记住,selenium 正在模仿用户,因此您通常无法执行用户无法执行的操作 - 例如单击被另一个元素覆盖的元素。

一个可能的解决方法是使用 Javascript 找到元素并单击它。 Example here:

labels = driver.find_elements_by_tag_name("label")
inputs = driver.execute_script(
    "var labels = arguments[0], inputs = []; for (var i=0; i < labels.length; i++){" +
    "inputs.push(document.getElementById(labels[i].getAttribute('for'))); } return inputs;", labels)

在我目前的 Capybara 项目中,我经常遇到 "Element not clickable" 错误。这种错误的原因是网页加载不够好,无法定位元素。正如您所提到的,之前的测试已经通过并且您没有编辑代码库的那部分,因此您可以执行以下操作来通过此测试:

  1. 在定位 "add_task_sidebar_link" 之前再等待一段时间。以便页面完全加载。
  2. 如果添加等待后测试仍然失败,则添加一些方法在单击元素之前截取屏幕截图。这将有助于调试测试。

最近 Firefox 驱动程序检查点击位置的元素是应该被点击的元素。 此错误意味着当驱动程序尝试单击该元素时,另一个元素位于它之上。 不幸的是,驱动程序不会自动滚动容器并引发此错误。

解决此问题的方法是滚动屏幕中央的元素,然后尝试再次单击。 点击方法的 Monkey 补丁:

JS_SCROLL_ELEMENT_CENTER_WINDOW = """\
  var element = arguments[0];
  element.scrollIntoView(true);
  var y = (window.innerHeight - element.offsetHeight) / 2;
  if (y > 0) {
    for (var e=element; e; e=e.parentElement) {
      if (e.scrollTop) {
        var yy = Math.min(e.scrollTop, y);
        e.scrollTop -= yy;
        if ((y -= yy) < 1)
          return;
      }
    }
    window.scrollBy(0, -y);
  }
  """

def click(self):
  try:
    self._execute(Command.CLICK_ELEMENT)
  except:
    self._parent.execute(Command.EXECUTE_SCRIPT, \
      {'script': JS_SCROLL_ELEMENT_CENTER_WINDOW, 'args': [self]})
    self._execute(Command.CLICK_ELEMENT)

from selenium.webdriver.remote.webelement import WebElement
from selenium.webdriver.remote.command import Command
WebElement.click = click

派对来得太晚了,但我有一个非常简单的解决方案对我有用。不要执行 .click(),只需执行

.send_keys(selenium.webdriver.common.keys.Keys.SPACE)

选中元素后,空格键可以切换选择。对我有用!

运行 遇到了类似的问题(同样的错误)并使用 send_keys 尝试了 Major Major 的解决方案 + 发送 space 条来模拟点击而不是鼠标点击。

Major Major 的解决方案:

.send_keys(selenium.webdriver.common.keys.Keys.SPACE)

我在尝试 运行 时遇到了一个新错误,指向 'selenium'。从代码中删除该关键字解决了问题,并允许我单击该元素。

使用的最终成功代码片段:

my_variable = driver.find_element_by_xpath('//*[@id="myId"]') #this is the checkbox
my_variable.send_keys(webdriver.common.keys.Keys.SPACE)

我遇到了同样的问题:由于弹出窗口 window,我必须单击的元素会从屏幕上移开并变得无法单击。

将页面滚动到有效的元素。

在Python中:

elem = driver.find_element_by_tag_name("html")
elem.send_keys(Keys.END)