我知道通常可以测试WebElement是否可点击:
用这样的方法测试它:
public static boolean isElementFoundDisplayedEnabled(WebDriver driver, String accessor){
return driver.findElements(By.xpath(accessor)).size() > 0 && driver.findElement(By.xpath(accessor)).isDisplayed() && driver.findElement(By.xpath(accessor)).isEnabled();
//isDisplayed(): method avoids the problem of having to parse an element's "style" attribute to check hidden/visible. False when element is not present
//isEnabled(): generally return true for everything but disabled input elements.
}
这个函数有缺陷,它只检查Element在DOM级别是否可以点击,但如果由于某些css搞乱,该元素被隐藏/重叠,可以得到Exception:
org.openqa.selenium.WebDriverException:未知错误:元素不是 点击点(781,704)。其他元素将收到点击:
...
在这种情况下,仍然可以使用以下方法单击元素:
// Assume driver is a valid WebDriver instance that
// has been properly instantiated elsewhere.
WebElement element = driver.findElement(By.id("gbqfd"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", element);
但是,我有兴趣了解这一点,我们如何在不点击executor.executeScript
的情况下进行检查,即WebElement没有被其他元素隐藏/重叠,并且完全可以点击。
有人可以稍微说清楚,我已经对这些进行了几个小时的研究并且无处可去。
答案 0 :(得分:0)
我不是创建一个处理所有点击的功能的忠实粉丝,但是如果我被迫写一个,它看起来就像这样。里面的评论解释了发生了什么。
public static void clickElement(By locator) throws InterruptedException
{
try
{
// first we try the standard wait for element to be clickable and click it
new WebDriverWait(driver, 10).until(ExpectedConditions.elementToBeClickable(locator)).click();
}
catch (TimeoutException e)
{
// element never becomes present
}
catch (WebDriverException e)
{
// click is blocked by another element, retry for 10 seconds
while (true)
{
Instant timeOut = Instant.now().plusSeconds(10);
try
{
driver.findElement(locator).click();
break;
}
catch (WebDriverException e2)
{
// ignore additional blocked click exceptions
}
if (Instant.now().isAfter(timeOut))
{
// element is still blocked after retries for 10 seconds, fallback to JSE click
((JavascriptExecutor) driver).executeScript("arguments[0].click();", driver.findElement(locator));
}
// slight pause between loops
Thread.sleep(100);
}
}
}
有关您的功能的一些反馈......
您应该传递By
个实例而不是字符串,例如
By locator = By.id("myId");
这样,您的功能可以更灵活,并且不会硬编码到XPath。此外,您正在使用您的功能将页面抓取3次。刮一次页面,然后使用存储的元素进行可见和启用的检查,例如
public static boolean isElementFoundDisplayedEnabled(WebDriver driver, By locator)
{
List<WebElement> e = driver.findElements(locator);
return !e.isEmpty() && e.get(0).isDisplayed() && e.get(0).isEnabled();
}
答案 1 :(得分:0)
以下是您的问题的一些事实和见解:
isElementFoundDisplayedEnabled(WebDriver driver, String accessor)
类时,方法WebDriverWait
是一个开销。我将在回答的后半部分回复WebDriverWait
。isDisplayed()
。这种方法避免了必须解析元素&#34;样式&#34;属性。isEnabled()
仅检查当前是否启用的元素。除了禁用的输入元素之外,这通常会返回true。isElementFoundDisplayedEnabled(WebDriver driver, String accessor)
是WebElement
,则必须覆盖函数clickable
。因此,在某些情况下,您可能会遇到org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (781, 704). Other element would receive the click
。Element is not clickable at point (781, 704)
时,您已经提到了 JavascriptExecutor
点击并且有效。WebDriverWait
设置为 ExpectedConditions
< /强> 一个例子是:
elementToBeClickable
仔细查看elementToBeClickable()
方法,明确提到它返回 WebDriverWait wait2 = new WebDriverWait(driver, 10);
WebElement ele = wait2.until(ExpectedConditions.elementToBeClickable(By.id("element_id")));
因此,您的问题的解决方案是 the (same) WebElement once it is clickable (visible and enabled)
,即 WebDriverWait
答案 2 :(得分:-1)
首先,您需要注意哪个属性具有隐藏或可见属性,并且基于此属性,您可以编写类似这样的内容。
示例:
<input id ="email" style="margin-top: 0px; visibility: visible;" >
代码:
public Boolean isVisibleAndClickable(WebElement email, WebDriver driver ){
Boolean flag = false;
try{
WebDriverWait wait = new WebDriverWait(driver, 10);
wait.until(ExpectedConditions.elementToBeClickable(email));
if(email.isDisplayed()){
String style = email.getAttribute("style");
if(style.contains("hidden")){
System.out.println("Element is hidden");
}
else if(style.contains("visible")){
System.out.println("Element is visible and clickable");
flag = true;
}else{
System.out.println("Element is not displayed");
}
}
} catch(Exception e){
System.out.println("Exception occured waiting for the element"+e.getMessage());
}
return flag;
}
答案 3 :(得分:-1)
您可以使用xpath contains函数,逻辑运算符和ancestor选项。例如:
.//一个[@ behavior.id =&#39;本身份识别码&#39;] /祖先:: DIV [含有(@class,&#39;类型类&#39)] /.//跨度
这条线找到了孩子们的跨越&#39;来自&#39;(@ class filter),为了找到这个div我开始找到&#39; a&#39;与behavior.id
为了提高可见性,我总是使用Wait或FluentWait选项:
public static WebElement xpathVisible(String xpath) {
return new FluentWait<WebDriver>(driver)
.withTimeout(IMPLICIT_TIMEOUT, TimeUnit.SECONDS)
.pollingEvery(RETRY_TIME, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class).until(ExpectedConditions
.elementToBeClickable(By.xpath(xpath)));
}
也许使用驱动程序的一些功能作为elementScrollBehavior从底部搜索元素是有用的:
capabilities.setCapability("elementScrollBehavior", 1); // 0- from Top,
// 1 - from
// bottom
我曾经使用过的东西是: