Java Selenium“成功”点击了一个元素,但实际上并没有点击
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33639353/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
Selenium clicks an element 'successfully', yet, it is not actually clicked
提问by Saleh Qadan
I have a method that clicks on a button, however, when it is run, selenium returns the outcome as clicked successfully, when, in reality, the button is not actually clicked. If I run the test several times, occasionally, it'll be clicked as expected. I have my test framework set as an implicit wait for about 15 seconds, I have set an explicit wait for this element, and still see the same issue. When I do <element>.isDisplayed()
, the element is always found. I placed the .click in a while loop to click it a few times which works most of the time, however, still sometimes the test fails. Is it possible to have an if statement to check if an element is actually displayed before clicking the button?
我有一个点击按钮的方法,但是,当它运行时,selenium 返回成功点击的结果,而实际上实际上并没有点击按钮。如果我多次运行测试,偶尔,它会按预期点击。我将我的测试框架设置为隐式等待大约 15 秒,我为该元素设置了显式等待,但仍然看到相同的问题。当我这样做时<element>.isDisplayed()
,总是会找到该元素。我将 .click 放在 while 循环中以单击它几次,这在大多数情况下都有效,但是,有时测试仍会失败。是否可以使用 if 语句在单击按钮之前检查元素是否实际显示?
I've tried:
我试过了:
if(!element.isDisplayed){
element.click
}
Here is the button I am having issues with:
这是我遇到问题的按钮:
<button class="notkoButton listNew">
<div class="l6e iconAdd">New List</div>
</button>
Here is my method:
这是我的方法:
public marketing_lists_page navigateToNewListPage() throws Throwable {
try {
int x = 0;
while(x < 5) {
newListBtn.click();
x++;
}
//newListPageHeader.isDisplayed();
} catch (NoSuchElementException e){
logs.errorDetails("Could not navigate to New List Page");
Assert.fail();
}
return this;
}
采纳答案by AGill
Seems like the element is not enabled or not clickable initially. And to answer your question, yes there is an explicit wait you can use and wait for the element to be clickable:
似乎该元素最初未启用或不可点击。并回答您的问题,是的,您可以使用显式等待并等待元素可点击:
WebDriverWait wait = new WebDriverWait(driver, timeOut);
wait.until(ExpectedConditions.elementToBeClickable(locator));
回答by marchocolate
You say you have tried an explicit wait, but it sounds like what you are asking for can be best accomplished by a fluentWait (which is type of explicit wait):
你说你已经尝试了显式等待,但听起来你所要求的最好通过 fluentWait (显式等待的类型)来完成:
public WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
return foo; };;
Here the WebElement would be the button you are trying to click. The cool thing about FluentWait is that the element itself is returned if it is found. From the documentation:
此处的 WebElement 将是您尝试单击的按钮。FluentWait 很酷的一点是,如果找到了元素,就会返回元素本身。从文档:
An implementation of the Wait interface that may have its timeout and polling interval configured on the fly. Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.
Wait 接口的实现,可以动态配置其超时和轮询间隔。每个 FluentWait 实例定义等待条件的最长时间,以及检查条件的频率。此外,用户可以将等待配置为在等待时忽略特定类型的异常,例如在页面上搜索元素时的 NoSuchElementExceptions。
To use it simply do:
要使用它,只需执行以下操作:
WebElement newListBtn = fluentWait(By.id("button"));
Also try:
还可以尝试:
Driver.SwitchTo().DefaultContent();
before clicking just in case it is a frame issue.
在点击之前,以防万一它是一个框架问题。
回答by Prat0567
Try scrolling to the element before clicking on it. This mostly happens when you test on chrome. You can use JavaScriptExecutor to scroll.
在单击它之前尝试滚动到该元素。这主要发生在您在 chrome 上测试时。您可以使用 JavaScriptExecutor 进行滚动。
Something like this:
像这样的东西:
JavascriptExecutor jse = (JavascriptExecutor)driver;
jse.executeScript("window.scrollTo(0," + element.getLocation().Y + ")");
回答by Shubham Jain
Try this, Click using javascript and feel free to change the locate for the element according to your convenience:-
试试这个,单击使用 javascript 并根据您的方便随意更改元素的位置:-
WebElement element= driver.findElement(By.xpath("YOUR XPATH"));
JavascriptExecutor executor = (JavascriptExecutor) driver;
executor.executeScript("arguments[0].click();", element);
Hope it will help you :)
希望它会帮助你:)
回答by e1che
Selenium suffers from lack of GUI "dynamism". By that i advice you to send a refresh to the page after your click.
Selenium 缺乏 GUI 的“活力”。我建议您在点击后刷新页面。
Tell me what's up.
告诉我怎么了。
回答by Shahzaib Salim
I was facing the exact same issue but only after I updated my selenium libraries from 2.45 to 2.48.2. "Click" method call never fails which mean the element is always found by the driver, what I thinkit fails to do is clicking the right spot may be. My test would run fine on a higher res screen and would sometimes pass (but mostly fail due to click issues) on a lower res screen. I tried many things but in the end what worked for me was ZOOM.
我面临着完全相同的问题,但只有在我将硒库从 2.45 更新到 2.48.2 之后。“单击”方法调用永远不会失败,这意味着驱动程序始终可以找到该元素,我认为它无法做到的是单击正确的位置。我的测试在高分辨率屏幕上运行良好,有时会在较低分辨率屏幕上通过(但主要是由于点击问题而失败)。我尝试了很多东西,但最终对我有用的是 ZOOM。
Before running the test I call the following method and the "click" method works as expected on that low res screen now.
在运行测试之前,我调用了以下方法,“单击”方法现在在低分辨率屏幕上按预期工作。
public void zoomOut () {
WebElement html = driver.findElement(By.tagName("html"));
html.sendKeys(Keys.chord(Keys.CONTROL, Keys.SUBTRACT));
}
回答by John Rix
I had what looked like a similar problem on the surface of it while using the JavaScript WebDriver - the click() promise resolved successfully, and yet nothing happened.
在使用 JavaScript WebDriver 时,我在表面上遇到了类似的问题 - click() 承诺成功解决,但什么也没发生。
In my case, it turned out to be related to an invalid image src attribute on the page (unrelated to the button I was clicking). For whatever reason, fixing the image link solved the problem!
就我而言,结果证明它与页面上无效的图像 src 属性有关(与我单击的按钮无关)。无论出于何种原因,修复图像链接解决了问题!
I know the OP was using Java rather than JS, but my own searches brought me here, so others using JavaScript will likely come the same way.
我知道 OP 使用的是 Java 而不是 JS,但我自己的搜索把我带到了这里,所以其他使用 JavaScript 的人可能会以同样的方式出现。
回答by HymansonWong
I've noticed clicks being inconsistent with Selenium as well, this seems to be a known issue to a certain extent:
我也注意到点击次数与 Selenium 不一致,这在一定程度上似乎是一个已知问题:
https://github.com/SeleniumHQ/selenium/issues/4075
https://github.com/SeleniumHQ/selenium/issues/4075
In my case there is practically no way for the element to not be ready. I had a wait, but more importantly my test case was filling in a very large form, the button that was to be clicked to initiate a drop-down is very simple and I can see it being loaded close to half a minute before my test interacts with it, yet every so often it would still fail. To the point where I wrote a silly while loop to click every 100 millisecond until the expected dropdown showed up.
在我的情况下,几乎没有办法让元素没有准备好。我等了一会儿,但更重要的是我的测试用例填写了一个非常大的表单,单击以启动下拉菜单的按钮非常简单,我可以看到它在测试前半分钟被加载与它交互,但时常它仍然会失败。我写了一个愚蠢的 while 循环,每 100 毫秒点击一次,直到出现预期的下拉菜单。
This is all guessing but from personal observance and some comments from others in that thread - such as one user mentioning they notice more issues like this when running parallel tests, seem to indicate it is possible for what seems to be a missed event, and perhaps this is due to the lag introduced from it's architecture. Specifically I'm comparing this to how Cypress works with native commands given to the browser directly without the intermediary server.
这都是猜测,但来自个人观察和该线程中其他人的一些评论 - 例如一位用户提到他们在运行并行测试时注意到更多类似的问题,似乎表明可能会发生似乎错过的事件,也许这是由于其架构引入的滞后。具体来说,我将其与 Cypress 如何使用直接提供给浏览器的本机命令进行比较,而无需中间服务器。