[英]Element is clickable when ran in debug mode, but ran normally throws ElementClickInterceptedException
我正在尝试做 web 自动化。 我正在定义一个弹出菜单,其中包含一个分别用 xpath 或 css 定义的按钮
XPath:--> : //button[contains(text(), 'Open Door')
CSS:--> : div.device-item.content.view-content > div.detail > div > button.btn.btn-primary.ng-star-inserted
虽然一切都很好,但它抛出
org.openqa.selenium.ElementClickInterceptedException: element click intercepted:
当我一次调试测试时,单击按钮成功运行,没有任何问题。 但是当我运行测试时,它失败了。 我希望这不是等待问题,因为我们应用检查等待按钮的存在并验证它存在且可点击。
I believe many would advice to use JavaScriptExecutor approach, but our framework has a problem of returning any web element as a custom object called "Element" which is neither Web Element nor sub class of it, but extends Object and implements an interface called IElement,所以我们不能使用JavaScriptExecutor 方法,因为它需要 Web 我们要单击的按钮的元素形式。
如果它在调试中工作,则意味着覆盖自动消失。 你可以等它消失
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("[id^='device-card']")));
在任何情况下,您都可以等待按钮可点击
button = wait.until(ExpectedConditions.elementToBeClickable(By.xpath("//button[contains(text(), 'Open Door')")));
button.click();
它看起来像:
driver.executeScript("document.querySelector('button.btn').click()")
只需调整css
您需要注意以下几点:
//button[contains(text(), 'Open Door')
: 这个xpath可以进一步优化为以下任一格式:
//button[text()='Open Door']
//button[contains(., 'Open Door')]
div.device-item.content.view-content > div.detail > div > button.btn.btn-primary.ng-star-inserted
看起来不错,但我坚信button.btn.btn-primary.ng-star-inserted
也可以。presenceOfElementLocated()
:是检查页面的 DOM 上是否存在元素的期望。 这并不一定意味着该元素是可见的。elementToBeClickable()
:检查元素的期望是否可见并启用,以便您可以单击它。click()
,因此您需要将ExpectedConditions用作elementToBeClickable()
。例子:
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("css_element"))).click();
您可以在什么是等待页面元素(xpath)出现在 Selenium Webdriver 中的最有效方法是什么中找到详细讨论?
由于您仍然看到错误...ElementClickInterceptedException: element click intercepted... ,您可以添加一个额外的步骤来诱导WebDriverWait不可见,您可以使用以下任一选项:
invisibilityOf(WebElement element)
:
new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOf(overlapping_webelement)); new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("css_clickable_element"))).click();
invisibilityOfElementLocated(By locator)
:
new WebDriverWait(driver, 20).until(ExpectedConditions.invisibilityOfElementLocated(By.cssSelector("css_overlapping_element"))); new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("css_clickable_element"))).click();
您可以将鼠标移动到该元素然后单击它,即使我遇到了这个问题,这个解决方案也解决了它
Actions clickOnBtn = new Actions(driver); clickOnBtn.moveToElement("//button[contains(text(), 'Open Door')").click().build().perform;
即使元素在屏幕上不完全可见也会发生这种情况,在这种情况下,您可以滚动到该元素,然后使用上面的代码,如下所示
JavascriptExecutor jse2 = (JavascriptExecutor)driver; jse2.executeScript("arguments[0].scrollIntoView()", ele); Actions clickOnBtn = new Actions(driver); clickOnBtn.moveToElement("//button[contains(text(), 'Open Door')").click().build().perform;
使用 javascriptExecutor 点击元素
JavascriptExecutor executor = (JavascriptExecutor)driver; executor.executeScript("arguments[0].click();", ele);
有时我们选择元素的方式也会发生这种情况,xpath 可以更改,我们可以尝试使用父标签而不是按钮并尝试
您可以通过单击操作定义自己的 ExpectedCondition:
public class SuccessfulClick implements ExpectedCondition<Boolean> {
private WebElement element;
public SuccessfulClick(WebElement element) { //WebElement element
this.element = element;
}
@Override
public Boolean apply(WebDriver driver) {
try {
element.click();
return true;
} catch (ElementClickInterceptedException | StaleElementReferenceException | NoSuchElementException e) {
return false;
}
}
}
然后使用它:
wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.