关于谷歌浏览器:调试“元素点不可点击”错误

Debugging “Element is not clickable at point” error

我只看到这个铬。

完整的错误消息为:

"org.openqa.selenium.WebDriverException: Element is not clickable at point (411, 675). Other element would receive the click: ..."

"将接收单击"的元素位于相关元素的一侧,不在其顶部,不重叠,不在页面上移动。

我试过添加一个偏移量,但也不起作用。该项位于显示的窗口中,不需要滚动。


这是由以下3种类型引起的:

1.无法单击该元素。

使用actions或javascriptexecutor使其单击。

通过行动:

1
2
3
4
5
WebElement element = driver.findElement(By("element_path"));

Actions actions = new Actions(driver);

actions.moveToElement(element).click().perform();

由JavaScriptExecutor编写:

1
2
3
4
5
JavascriptExecutor jse = (JavascriptExecutor)driver;

jse.executeScript("scroll(250, 0)"); // if the element is on top.

jse.executeScript("scroll(0, 250)"); // if the element is on bottom.

1
2
3
JavascriptExecutor jse = (JavascriptExecutor)driver;

jse.executeScript("arguments[0].scrollIntoView()", Webelement);

然后单击元素。

2.页面在单击元素之前正在刷新。

为此,请使页面等待几秒钟。

三。元素是可点击的,但在它上面有一个旋转/覆盖

下面的代码将等待覆盖显示

1
2
3
4
5
By loadingImage = By.id("loading image ID");

WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);

wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage));

然后单击元素。


您也可以使用javascript点击,然后不需要滚动。

1
2
IJavaScriptExecutor ex = (IJavaScriptExecutor)Driver;
ex.ExecuteScript("arguments[0].click();", elementToClick);


Chromedriver似乎有一个漏洞(问题是它被标为无法修复)> GITHUB链接

(也许是对自由赞助商的赏金?)

评论27中提出了一个解决方法。也许对你有用。


我有同样的问题,尝试了所有提供的解决方案,但它们不适合我。最后我用了这个:

1
2
JavascriptExecutor js = (JavascriptExecutor) driver;
js.executeScript("var evt = document.createEvent('MouseEvents');" +"evt.initMouseEvent('click',true, true, window, 0, 0, 0, 0, 0, false, false, false, false, 0,null);" +"arguments[0].dispatchEvent(evt);", findElement(element));

希望这有帮助


我在硒驱动的铬合金窗口打开得太小的情况下看到了这一点。要单击的元素超出了视区,因此失败了。

听起来很合理…真正的用户要么调整窗口大小,要么滚动窗口,这样就可以看到元素并点击它。

在指示Selenium驱动程序适当地设置窗口大小之后,这个问题对我来说就消失了。这里描述了WebDriver API。


哇,这里有很多答案,还有很多好答案。

我希望我能从我的经验中补充一些东西。

伙计们,在我的例子中,偶尔会有一个曲奇覆盖层隐藏元素。滚动到元素也是有效的;但是在我看来(对于我来说,不是对每个人的灵丹妙药),最简单的解决方案就是全屏运行(我在屏幕窗口的3/4上运行脚本)!所以我们走到这里:

1
driver.manage().window().maximize();

希望有帮助!


我也在努力解决这个问题。代码在FF中工作正常,在Chrome上失败。我想做的是点击一个勾选框-如果它不在视图中,我会滚动到视图,然后点击。即使滚动到View浏览器中,也只能看到勾选框底部的几个像素,因此WebDriver拒绝点击它。

我的解决方法是:

1
2
3
4
5
6
7
8
9
WebElement element = _sectorPopup.findElement(...);

((Locatable) element).getCoordinates().inViewPort();
try {
    element.click();
} catch (Exception e) {
    new Actions(getWebDriver()).sendKeys(Keys.PAGE_DOWN).perform();
    element.click();
}

Chrome还存在发送键问题,有时需要使用操作。很明显,你需要知道方向和你需要走多少路,这样你的里程数可能会有所不同。但我更喜欢这个,而不是javascript黑客,所以我把它张贴在这里,以防其他人发现它有用。


Ruby/Watir网络驱动程序/Chrome

我使用了下面的技巧,看起来很有效:

1
2
3
4
5
#scroll to myelement
@browser.execute_script"window.scrollTo(#{myelement.element.wd.location[0]},#{myelement.element.wd.location[1]})"

# click myelement
myelement.when_present.fire_event("click")


在运行带有xvfb run的无头测试时出现此错误。他们在当地完美无缺地工作。使用Chrome,WebDrop/ChromiDea/Chrome/Java等版本完全相同。

托尼·兰帕达指出,Chromedriver-Github链接中的"无法修复"漏洞可能与屏幕上可见或不可见的内容有关。

xvfb运行的帮助消息显示以下内容:

1
2
3
-s ARGS   --server-args=ARGS    arguments (other than server number and
                               "-nolisten tcp") to pass to the Xvfb server
                                (default:"-screen 0 640x480x8")

更改XVFB的分辨率使错误消失:

1
xvfb-run -s"-screen 0 1280x1024x16" ...

当使用量角器时,这有助于我:

1
2
3
var elm = element(by.css('.your-css-class'));
browser.executeScript("arguments[0].scrollIntoView();", elm.getWebElement());
elm.click();

首先,尝试获取最新的Chrome驱动程序并检查它是否解决了问题。

在我的情况下,它没有解决问题。但到目前为止,以下解决方案对我有效。下面是C代码,但您可以在特定语言中遵循相同的逻辑。我们在这里做的是,

步骤1:使用Selenium动作对象关注元素,

第二步:然后点击元素

步骤3:如果有异常,那么我们通过Selenium浏览器驱动程序的"ExecuteScript"方法执行javascript脚本,在元素上触发一个javascript"click"事件。

您也可以跳过步骤1和2,只尝试步骤3。第3步可以单独工作,但我注意到在一个场景中,有一些奇怪的行为,在这种场景中,即使第3步成功地单击了元素,但在单击了元素之后,它在代码的其他部分导致了意外的行为。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
            try
            {
                //Setup the driver and navigate to the web page...
                var driver = new ChromeDriver("folder path to the Chrome driver");
                driver.Navigate().GoToUrl("UrlToThePage");

                //Find the element...
                var element = driver.FindElement(By.Id("elementHtmlId"));

                //Step 1
                new Actions(driver).MoveToElement(element).Perform();  

                //Step 2
                element.Click();
            }
            catch (Exception)
            {
                //Step 3
                driver.ExecuteScript("document.getElementById('elementHtmlId').click();");

            }


我是根据托尼·兰帕达的回答中的一句话得出这个方法的。它工作得很好。

1
2
3
def scroll_to(element)
  page.execute_script("window.scrollTo(#{element.native.location.x}, #{element.native.location.y})")
end


在Python中运行Selenium脚本时,我也遇到了同样的问题。下面是我用来点击元素的内容:

1
2
3
4
from selenium.webdriver.common.action_chains import ActionChains


ActionChains(driver).click(element).perform()

我遇到了一个类似的问题,我不得不一个接一个地检查两个复选框。但我得到了同样的上面的错误。因此,我在检查复选框的步骤之间添加了wait。它工作得很好。下面是步骤:

1
2
3
4
5
6
7
  When I visit /administrator/user_profiles
  And I press xpath link"//*[@id='1']"
  Then I should see"Please wait for a moment..."
  When I wait for 5 seconds
  And I press xpath link"//*[@id='2']"
  Then I should see"Please wait for a moment..."
  When I visit /administrator/user_profiles_updates


显然,这是chrome驱动程序二进制文件中"无法修复"错误的结果。

一个对我有效的解决方案(我们的里程数可能会有所不同)可以在这个谷歌小组讨论中找到,评论3:

https://groups.google.com/forum/?从组=主题/硒开发人员活动/DSZ5WFN52TC

相关部分就在这里:

I've since worked around the issue by navigating directly to the href of
the parent anchor of the span.

driver.Navigate().GoToUrl(driver.FindElement(By.Id(embeddedSpanIdToClick)).FindElement(By.XPath("..")).GetAttribute("href"));

在我的例子中,我使用的是python,所以一旦我得到了所需的元素,我就简单地使用

1
driver.get(ViewElm.get_attribute('href'))

但是,如果您试图单击的元素是一个链接,那么我希望它只起作用。


此错误的原因是您试图单击的元素不在浏览器的视区(用户看到的区域)中。所以克服这个问题的方法是先滚动到所需的元素,然后执行单击。

Javascript:

1
2
3
4
async scrollTo (webElement) {
    await this.driver.executeScript('arguments[0].scrollIntoView(true)', webElement)
    await this.driver.executeScript('window.scrollBy(0,-150)')
}

爪哇:

1
2
3
4
5
public void scrollTo (WebElement e) {
    JavascriptExecutor js = (JavascriptExecutor) driver;
    js.executeAsyncScript('arguments[0].scrollIntoView(true)', e)
    js.executeAsyncScript('window.scrollBy(0,-150)')
}

错误信息说明:

错误消息简单地说,您要单击的元素存在,但它不可见。它可能被某些东西覆盖,或者暂时不可见。

测试时元素不可见的原因有很多。请重新分析您的页面并为您的案例找到合适的解决方案。

特殊情况下的解决方案:

在我的例子中,当我刚才单击的屏幕元素的工具提示出现在我想要单击Next的元素上时,就会发生这个错误。散焦是我需要的解决方案。

  • 如何散焦的快速解决方案是点击屏幕另一部分的其他元素,该元素对"无"响应。单击操作后不会发生任何事情。
  • 适当的解决方案是在弹出工具提示的元素上调用element.blur(),这将使工具提示不显示。

如果元素在驱动程序试图单击时改变位置,就会发生这种情况(我也在IE中看到过这种情况)。驱动程序保留初始位置,但当它实际开始点击时,该位置不再指向该元素。firefox驱动程序没有这个问题btw,显然它以编程方式"点击"元素。

无论如何,当您使用动画或只是动态地更改元素的高度(例如$("#foo").height(500))时,都可能发生这种情况。您需要确保只在元素高度"稳定"后单击元素。我最后得到的代码看起来像这样(C绑定):

1
2
3
4
5
if (!(driver is FirefoxDriver))
{
    new WebDriverWait(driver, TimeSpan.FromSeconds(10)).Until(
        d => d.FindElement(By.Id(someDynamicDiv)).Size.Height > initialSize);
}

在动画或任何其他您不容易查询的因素的情况下,您可以使用"通用"方法来等待元素静止:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
var prevLocation = new Point(Int32.MinValue, Int32.MinValue);
int stationaryCount = 0;
int desiredStationarySamples = 6; //3 seconds in total since the default interval is 500ms
return new WebDriverWait(driver, timeout).Until(d =>
{
    var e = driver.FindElement(By.Id(someId));
    if (e.Location == prevLocation)
    {
        stationaryCount++;
        return stationaryCount == desiredStationarySamples;
    }

    prevLocation = e.Location;
    stationaryCount = 0;
    return false;
});


我遇到这个是因为这个元素上有一个加载对话框封面。我简单地通过在使用这个元素之前添加一个等待来解决它。

1
2
3
4
5
6
try {
        Thread.sleep((int) (3000));
    } catch (InterruptedException e) {
        //
        e.printStackTrace();
    }

希望这有帮助!


我和CLJ WebDriver(Selenium的Clojure端口)面临同样的问题。为了方便起见,我把前面的解决方案翻译成了clojure。您可以在执行单击或其他操作之前调用此函数以避免该问题。

1
2
3
4
5
6
(defn scrollTo
 "Scrolls to the position of the given css selector if found"
  [q]
  (if (exists? q)
    (let [ loc (location-once-visible q) jscript (str"window.scrollTo(" (:x loc)"," (:y loc)")") ]
      (execute-script jscript))))

也许它不是真正干净的解决方案,但它起作用:

1
2
3
4
5
6
7
8
9
try:
    el.click()
except WebDriverException as e:
    if 'Element is not clickable at point' in e.msg:
        self.browser.execute_script(
            '$("{sel}").click()'.format(sel=el_selector)
        )
    else:
        raise

我收到这个错误是因为我测试了一个悬停,然后需要点击工具提示下面的链接。解决方案是在click_link之前添加page.find('.sp-logo').hover,以避免工具提示被挡住。


Re Tony Lampada的回答,评论27确实解决了我的问题,除了它提供Java代码和我需要Python。这里有一个python函数,它滚动到元素的位置,然后单击它。

1
2
3
4
def scroll_to_and_click(xpath):
    element = TestUtil.driver.find_element_by_xpath(xpath)
    TestUtil.driver.execute_script('window.scrollTo(0, ' + str(element.location['y']) + ');')
    element.click()

这在Chrome34.0中解决了我的问题。它在火狐28.0和IE11中没有造成任何伤害;这些浏览器不会受到问题的影响,但是在点击之前滚动到元素的位置仍然不是一件坏事。


我做了一种野蛮的点击力,它为我工作。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
try:
    elem.click()
except:
    print"failed to click"
    size = elem.size
    mid_of_y = int(size["height"])/2
    stepts_to_do_to_left = int(size["width"])
    while stepts_to_do_to_left > 0:
        try:
            print stepts_to_do_to_left, mid_of_y
            action = webdriver.common.action_chains.ActionChains(driver)
            action.move_to_element_with_offset(elem, mid_of_y, stepts_to_do_to_left)
            action.click()
            action.perform()
            print"DONE CLICK"
            break
        except:
            pass


在测试了所有提到的建议之后,没有任何效果。我做了这个密码。它能用,但不漂亮

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
public void click(WebElement element) {
    //https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
    while(true){
        try{
            element.click();
            break;
        }catch (Throwable e){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }
}

public void click(String css) {
    //https://code.google.com/p/selenium/issues/detail?id=2766 (fix)
    while(true){
        try{
            driver.findElement(By.cssSelector(css)).click();
            break;
        }catch (Throwable e){
            try {
                Thread.sleep(200);
            } catch (InterruptedException e1) {
                e1.printStackTrace();
            }
        }
    }
}

如果页面上加载了jQuery,则可以执行以下javascript命令:

1
"$('#" + element_id +"').click()"

使用python执行器的示例:

1
driver.execute_script("$('#%s').click()" % element_id)

有趣的是,我花了很多时间观察各种反应,没有人尝试过明显的反应,当然,我也没有。如果您的页面多次使用相同的ID,就像我的一样("newbutton",),而您想要的ID不是第一个找到的,那么您很可能会得到这个错误。最容易做的事(c):

1
var testIt = driver.FindElements(By.Id("newButton"));

注意,它是findelement s,而不是findelement。

然后测试从检索中得到多少结果。如果是第二个,则可以使用:

1
testit[1].Click();

或者让任何人重新使用ID来修复它们。


在Drupal中使用硒时:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
    // Get element.
    $element = $this->driver->getElement('xpath=//input');        
    // Get screen location.
    $location = $element->getLocation();
    // To make sure that Chrome correctly handles clicking on the elements
    // outside of the screen, we must move the cursor to the element's location.
    $this->driver->moveCursor($location['x'], $location['y']);

    // Optionally, set some sleep time (0.5 sec in the example below) if your
    // elements are visible after some animation.
    time_nanosleep(0, 500000000);

    // Click on the element.
    $element->click();

我有同样的问题,得到了"其他元素将收到点击"错误的显示,可见元素。我没有找到其他的解决方案来触发用javascript点击。

我换了:

1
2
3
4
5
WebElement el = webDriver.findElement(By.id("undo-alert"));
WebElement closeButton = el.findElement(By.className("close"));
// The following throws 'Element is not clickable at point ... Other element
// would receive the click'
closeButton.click();

用:

1
2
3
((JavascriptExecutor) webDriver).executeScript(
   "$('#undo-alert').find('.close').click();"
);

一切都很顺利


我也遇到了同样的问题,花了好几个小时寻找解决方案。我试图用量角器点击一个长的nggrid底部的单元格。以下是我的nggrid html的快照:

1
2
3
4
5
....many rows here..
<!- row in renderedRows ->
   <!- column in renderedColumns ->
    the test link 100000...
....

所有的点击功能都不起作用。解决方案是在元素的当前范围内使用evaluate:

1
2
element(by.cssContainingText("a","the test link 100000"))
    .evaluate("selectRow(row)")

我有另一个bug,chrome和poltergeist上的find_link不能点击一个带有em标签的标签和里面的一些文本,尽管它在火狐和机架测试中运行良好。解决方案是用以下材料取代click_link(link)

1
find('a em', text: link).click

我遇到了这个问题,它似乎是(在我的例子中)通过单击一个元素而引起的,该元素在单击的元素前面弹出一个DIV。我用一个大的"ol-try-catch"块包装我的点击来解决这个问题。


当我试图点击页面上的一个单选按钮时,我也有同样的例外。我在javascript下面使用,并使用ijavascriptexecutor执行。C例

1
2
3
4
5
6
7
8
9
10
11
string script=" function clickCharity() {"+
"var InputElements = document.getElementsByName('Charity');"+
 "for (i=0; i<InputElements.length; i++){"+
   "if(InputElements[i].getAttribute('value') == 'true')"+
   "{"+
       "InputElements[i].click();"+
   "}"+
"}"+
"}";
var js=WebDriver as IJavaScriptExecutor;
js.ExecuteScript(script);

而不是

1
webdriver.findElement(By.id("id1")).click();

尝试使用

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
click(By.id("id1"));

void click(final By byLocator) {
    waitFor(new ExpectedCondition<Boolean>() {
        @Override
        public Boolean apply(WebDriver driver) {
            WebElement element = driver.findElement(byLocator);
            if (element.isDisplayed()) {
                try {
                    element.click();
                    return true;
                } catch (Exception e) {
                    e.printStackTrace();
                }
            }
            return false;
        }

        @Override
        public String toString() {
            return"Element located" + byLocator +" clicked";
        }
    });
}


您可以使用JS模拟单击:

1
2
3
4
public void click(WebElement element) {
    JavascriptExecutor js =(JavascriptExecutor)driver;
    js.executeScript("document.elementFromPoint(" + element.getLocation().x +"," + element.getLocation().y +").click();");
}

我也遇到了同样的问题,它是由DIV和DIV内部的链接之间的ID冲突引起的,所以驱动程序单击的是DIV,而不是我想要的链接。我更改了DIV ID,它工作正常。

之前:

1
logout

后:

1
logout


当使用分辨率大于1024x768时,请尝试最大化浏览器。

1
driver.manage().window().maximize();

在Visual Studio 2013中,如果启用browserlink,则会在屏幕底部显示browserlink导航栏。如果你想点击的项目在导航栏后面,它会给出错误信息。禁用浏览器链接为我解决了问题。


我也面临同样的问题,我使用了延迟,它工作得很好,我的一方。页面正在刷新并获取其他定位器。

1
2
Thread.sleep(2000);
        Click(By.xpath("//*[@id='instructions_container']/a"));

我也因为同样的原因卡住了两天,实际上滚动会使它工作,因为可能是数据无法正确加载,这可能会导致同样的错误一次又一次。

我做的是,我随机向下滚动,用(0,-500),然后(0400),然后(0,-600),你可以根据你的使用给这些滚动值。只要把它滚动到你有内容要点击的地方就行了。

1
2
3
4
5
6
7
8
driver.execute_script("scrollBy(0,-500);")
sleep(5)

driver.execute_script("scrollBy(0,400);")
sleep(5)

driver.execute_script("scrollBy(0,-600);")
sleep(5)

它真的起作用了:)


如果在conf.js文件中使用下面的行,请将其注释掉,然后重试。

1
browser.ignoreSynchronization = true;

在我的例子中,它在Firefox中工作,但在Chrome中失败了。在Chrome中,它在将Chrome驱动程序版本更新到最新版本后得到了修复。


在rselenium中,当链接定位在顶部窗口边界时,代码成功地使用了多次。简单的解决方案是使用sendKeysToElement(),如下所示。

1
2
3
if (unlist(webElem$isElementDisplayed())) {
    webElem$sendKeysToElement(list(key ="up_arrow"))  # Add"up arrow"..
    webElem$clickElement()  # ... before $clickElement

1
2
WebDriverWait wait = new WebDriverWait(driver, TimeSpan.FromSeconds(15));
wait.Until(SeleniumExtras.WaitHelpers.ExpectedConditions.ElementToBeClickable(By.<Id or anything>));

希望这有帮助。


如果使用python:

1
2
3
4
5
6
from selenium import webdriver

action = webdriver.ActionChains(driver=self.driver)
action.move_to_element(to_element=self.driver.find_element_by_xpath(xpath="[xpath]"))
action.click()
action.perform()