调试“元素不可点击”错误

我只在Chrome中看到这一点。

完整的错误信息如下:

“org.openqa.selenium.WebDriverException:元素在点(411,675)不可点击,其他元素将收到点击:…”

“将接受点击”的元素位于所讨论的元素的侧面,而不是在其之上,并且不重叠,而不是在页面上移动。

我曾尝试添加一个偏移量,但这也不起作用。 该项目在显示的窗口上,不需要滚动。

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

1.单击不可见。

使用操作JavascriptExecutor使其点击。

通过行动:

WebElement element = driver.findElement(By("element_path")); Actions actions = new Actions(driver); actions.moveToElement(element).click().perform(); 

通过JavascriptExecutor:

 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. 

要么

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

然后点击元素。

2.页面在点击元素之前被刷新。

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

3.元素是可点击的,但是在它上面有一个微调器/覆盖层

下面的代码将等到覆盖消失

 By loadingImage = By.id("loading image ID"); WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds); wait.until(ExpectedConditions.invisibilityOfElementLocated(loadingImage)); 

然后点击元素。

这似乎是一个在这个问题是,它被标记为不会修复) – > http://code.google.com/p/selenium/issues/detail?id=2766

(可能给FreedomSponsors一个赏金?)

在第27条评论中提出了一个解决方法。 也许它会为你工作。

你也可以使用JavaScript点击和滚动,那么就不需要了。

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

我有同样的问题,尝试所有提供的解决方案,但他们不为我工作。 最终我用这个:

 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)); 

希望这可以帮助

在硒驱动的Chrome窗口打开的情况下,我已经看到了这一点。 被点击的元素不在视口中,因此失败。

这听起来合乎逻辑…真正的用户将不得不调整窗口大小或滚动,以便有可能看到的元素,实际上点击它。

在指示硒驱动程序适当地设置窗口大小后,这个问题就离我远去了。 webdriver API 在这里描述 。

运行xvfb-run时无法运行测试时出现此错误。 他们在当地完美地工作。 使用chrome,webdriver / chromedriver / chrome / java等版本都是一样的。

托尼·兰帕达(TonyLâmpada)指出的http://code.google.com/p/selenium/issues/detail?id=2766指出,这可能与什么是不可见的有关屏幕上。;

xvfb-run的帮助信息显示如下:

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

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

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

红宝石/的Watir-的webdriver /镀铬

我使用下面的技巧,似乎是有效的:

 #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") 

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

我希望我会从我的经验中补充一些。

那么,在我的情况下,有一个cookie覆盖偶尔隐藏的元素。 滚动到元素也起作用; 但在我的愚见(对于我的情况,而不是每个人的灵丹妙药)最简单的解决方案就是全屏(我在3/4的屏幕窗口上运行我的脚本)! 所以在这里我们去:

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

希望有所帮助!

我也和这个问题搏斗了。 代码在FF中正常工作,在Chrome上失败。 我试图做的是点击一个复选框 – 如果它不在视图中,我会滚动查看,然后单击。 即使在Chrome浏览器中滚动,只有tickbox的底部几个像素是不可见的,所以webdriver拒绝点击它。

我的解决方法是这样的:

 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也有sendKeys的问题,使用操作有时是必要的。 显然,你需要知道你需要去哪个方向和多少,所以你的里程可能会有所不同。 但我更喜欢这个JavaScript的黑客,所以我张贴在这里,以防其他人会发现它有用。

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

在我的情况下,它并没有解决这个问题。 但是,到目前为止,下面的解决方案为我工作。 以下是C#代码,但您可以按照您的特定语言使用相同的逻辑。 我们在这里做的是,

第1步:使用Selenium Actions对象关注元素,

第2步:然后点击元素

第三步:如果出现异常,我们通过Selenium浏览器驱动程序的“ExecuteScript”方法执行javascript脚本,在元素上触发一个javascript“Click”事件。

您也可以跳过第1步和第2步,也只尝试第3步。 第3步将自己的工作,但我注意到一个奇怪的行为,其中第3步,即使它成功点击元素,导致单击元素后,我的代码的其他部分意外的行为。

  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();"); } 

我根据TonyLâmpada的回答发表了这个方法。 它工作得很好。

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

当使用量角器时,这帮助了我:

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

我正面临类似的问题,我必须检查两个复选框一个接一个。但我得到了上述相同的错误。我添加了等待在我的步骤之间检查复选框….其工作正常和伟大的。这里是步骤:

  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 

我正面临与clj-webdriver (Selenium的clojure端口)相同的问题。 为了方便,我只是把以前的解决方案翻译成clojure。 你可以在点击之前调用这个函数来避免这个问题。

 (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)))) 

这可能会发生,如果元素改变位置,而驾驶员正试图点击它(我也看到这与IE浏览器)。 驱动程序保留了初始位置,但实际上在点击它时,该位置不再指向该元素。 BTF驱动程序没有这个问题,显然它通过编程来“点击”元素。

无论如何,当你使用动画或动态改变元素的高度(例如$("#foo").height(500) )时,就会发生这种情况。 你需要确保你只能在高度已经“稳定”之后点击元素。 我结束了看起来像这样的代码(C#绑定):

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

如果是动画或任何其他因素,您不能轻易查询,您可以使用“通用”方法等待元素静止:

 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; }); 

我遇到了这个问题,似乎是(通过点击一个在单击元素前面弹出一个div的元素)(在我的情况下)。 我通过在一个大的尝试catch块中包装我的点击来解决这个问题。

对于TonyLâmpada的回答,评论#27确实为我解决了这个问题,只是它提供了Java代码,而且我需要Python。 这是一个Python函数,滚动到元素的位置,然后单击它。

 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() 

这解决了我在Chrome 34.0中的问题。 它在Firefox 28.0和IE 11中没有造成任何伤害; 那些浏览器不会受到这个问题的影响,但是在点击之前滚动到元素的位置并不是一件坏事。

也许这不是很干净的解决方案,但它的工作原理:

 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 

我得到这个错误,因为我测试了一个悬停,然后需要点击工具提示下的链接。 解决方法是添加page.find('.sp-logo').hoverclick_link之前,即可获得工具提示。

经过测试所有提到的建议,没有工作。 我做了这个代码。 它工作,但不是美丽的

 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(); } } } } 

我遇到过这个,因为这个元素的加载对话框覆盖了。 我简单地通过在使用这个元素之前添加一个等待来解决它。

 try { Thread.sleep((int) (3000)); } catch (InterruptedException e) { // e.printStackTrace(); } 

希望这个帮助!

错误信息的解释

错误消息简单地说,你想点击的元素是存在的,但它是不可见的。 它可能被某种东西或暂时不可见的东西覆盖。

在测试的时候,元素不可见的原因可能有很多。 请重新分析您的网页,找到适合您的案例的解决方案。

特殊情况的解决方案

在我的情况下,这个错误发生,当我点击的屏幕元素的工具提示,弹出了我想单击下一步的元素。 散焦是我需要的解决方案。

  • 快速解决如何离焦将是点击屏幕的另一个部分,其中“没有”响应的其他元素。 点击后没有任何反应。
  • 正确的解决办法是调用元素弹出工具提示element.blur() ,这将使工具提示disapear。

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

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

https://groups.google.com/forum/?fromgroups=#!topic/selenium-developer-activity/DsZ5wFN52tc

相关部分就在这里:

我已经解决了这个问题,直接导航到跨度的父锚的href。

。driver.Navigate()GoToUrl(driver.FindElement(By.Id(embeddedSpanIdToClick))FindElement(By.XPath( “.. ”))的getAttribute(的“ href”));

就我而言,我正在使用Python,所以一旦我得到了所需的元素,我就简单地使用了

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

我希望这只能工作,但是,如果你试图点击的元素是一个链接…

我有同样的问题,这是由div和div内的链接之间的id冲突引起的。 所以驱动程序是点击div而不是我想要的链接。 我改变了div id,它工作正常。

之前:

 <div id="logout"><a id="logout" href="logoutLink">logout</a></div> 

后:

 <div id="differentId"><a id="logout" href="logoutLink">logout</a></div> 

在Drupal使用Selenium时 :

  // 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的点击。

我替换了:

 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(); 

有:

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

这一切都很好

我有同样的问题,并花了数小时找到解决方案。 我试图用量角器单击一个长的ngGrid底部的单元格。 下面是我的ngGrid html的快照:

 ....many rows here.. <!- row in renderedRows -> <!- column in renderedColumns -> <div ...> <a ngclick="selectRow(row)"...>the test link 100000</a>... .... 

所有的点击功能都不起作用。 解决方法是在元素的当前范围中使用评估 :

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

我有另外一个bug,Chrome和Poltergeist上的find_link无法点击带有EM标签的A标签和其中的一些文本,尽管它在Firefox和rack_test中运行良好。 解决方案是用下面的代码替换click_link(link)

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

在Visual Studio 2013中,如果启用BrowserLink,则会在屏幕底部显示一个BrowserLink导航栏。 如果要点击的项目位于该导航栏后面,则会显示错误。 禁用BrowserLink解决了我的问题。

有趣的是,我一直都在看各种回答,没有人试过这个明显的,当然我也没有。 如果你的页面有多次使用相同的id,就像我做的那样(“newButton”),而你想要的那个不是第一个找到的,那么你很可能会得到这个错误。 最简单的事情(C#):

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

注意它是FindElements,而不是FindElement。

然后测试看看检索结果有多少结果。 如果是第二个,则可以使用:

 testit[1].Click(); 

或者得到任何重复使用的ID来修复它们。