【问题标题】:Selenium: Element not clickable ... Other Element Would Receive ClickSelenium:元素不可点击...其他元素会收到点击
【发布时间】:2016-06-08 17:59:58
【问题描述】:

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

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 窗口弹出并最大化页面时,测试通过了。但是当我让 Selenium 测试在 Firefox 浏览器未最大化的情况下运行时,它们会失败。

我没有使用任何花哨的 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>

【问题讨论】:

  • 让我知道以下是否正常 - 点赞/标记为已回答

标签: python django selenium selenium-webdriver django-testing


【解决方案1】:

您的答案就在您的问题之内。

  1. 错误提示“add_task_sidebar_link”not clickable at point - (61, 24.300003051757812) 这是另一个元素所在的位置 - Other element would receive the click: &lt;a class="navbar-brand" href="#"&gt;&lt;/a&gt; 正在尝试单击。由于您没有最大化浏览器,因此无法正确获取点坐标。
  2. 为了不中断未来的测试,请滚动到该元素。请参阅此帖子 (Selenium python unable to scroll down)。检查动作链 (http://selenium-python.readthedocs.org/api.html#module-selenium.webdriver.common.action_chains)

【讨论】:

  • 当我要调用 click() 方法时,我是否应该始终滚动到带有 Selenium 的元素?或者就在我遇到这个错误的时候?
  • 我相信最新的 selenium 会自动滚动。
【解决方案2】:

这更多地与元素“覆盖”彼此有关。如果它发生在非最大化窗口上,这是有道理的。如果有一个弹出/浮动 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)

【讨论】:

  • @ aneroid 如果以上为真 - 测试应该可能失败。 @ jejy2343 - 以上确认了您的应用程序中的代码缺陷。我猜当你不最大化你的元素时,你的元素应该自动 1. 可滚动并垂直/水平保持其跨度或 2. 重新排列自身 - 适用于跨平台 Web UI。其中任何一个都应该发生。当您使用 Javascript 使用上述答案时,您是通过潜在的健康检查并绕过该缺陷。反之亦然 - 如果您尝试点击它,您的测试用例可能不够充分。
  • 让我在上面总结一下:: Web UI 不应该在用户尝试使用它的地方覆盖它的元素。我会说它可以被视为外观缺陷
  • 感谢您的快速回答。我认为可能发生的情况是,当 Firefox 窗口未最大化时,它会向下滚动到链接位于左上角的位置。但是导航栏设置在页面的顶部,即使你在滚动,所以它也在左上角。这是一个猜测——我不确定 selenium 在选择链接时如何处理滚动。
  • 我不确定 Selenium 是否会自动滚动到该元素。尝试执行并验证。也尝试显式滚动。另一件事试试这个 - 显示您遇到错误的元素的坐标,获取两个元素并显示点坐标。这将明确地告诉你。如果我上面的答案很好,你可以给我投票吗?
  • @Makjblh 我同意此类 UI 行为应被视为缺陷,具体取决于站点的最低分辨率。是的,在做任何事情之前先关注一个元素是一种很好的做法。 Selenium 并不总是滚动到一个元素,这取决于操作是什么。
【解决方案3】:

在我当前的 Capybara 项目中,我经常收到“元素不可点击”错误。出现这种错误的原因是网页加载得不够好,无法定位元素。正如您所提到的,之前的测试已经通过并且您还没有编辑代码库的那部分,所以您可以执行以下操作来通过它:

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

【讨论】:

    【解决方案4】:

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

    解决此问题的方法是滚动屏幕中心的元素并尝试再次单击。 点击方法的猴子补丁:

    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
    

    【讨论】:

      【解决方案5】:

      聚会非常迟到,但我有一个非常简单的解决方案对我有用。而不是做 .click(),只需做

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

      选中元素后,空格键可以切换选择。为我工作!

      【讨论】:

      • 谢谢你,这让我整个早上都发疯了,这解决了它。
      • 这救了我的命,也可能救了其他人的命。
      • 太棒了!谢谢!我在链接/按钮上使用Keys.RETURN,似乎做类似的事情。
      • 甚至send_keys(' ') :-)
      • 感谢@ErichBSchulz 我使用了send_keys(' ')
      【解决方案6】:

      遇到了类似的问题(同样的错误)并尝试了上面 Major Major 的解决方案,使用 send_keys + 发送空格键来模拟点击而不是鼠标点击。

      Major 的解决方案:

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

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

      使用sn-p的最终成功代码:

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

      【讨论】:

        【解决方案7】:

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

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

        在 Python 中:

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

        【讨论】:

          猜你喜欢
          • 2017-04-16
          • 2016-12-19
          • 2018-03-16
          • 1970-01-01
          • 2019-02-20
          • 2015-01-12
          • 1970-01-01
          • 1970-01-01
          • 2021-10-08
          相关资源
          最近更新 更多