2017-08-30 257 views
2

我知道如何通常是测试的WebElement是可点击:Java + Selenium:如何知道WebElement是否可以以isDisplayed,isEnabled和findElement之外的方式进行点击?

这样的测试的东西:

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. 
    } 

此功能有缺陷,它只是检查是否元素被点击的DOM的水平,但如果因为某些CSS烂摊子后,该元素是隐藏/重叠,可以得到例外的:

org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (781, 704). Other element would receive the click:

...

在这种情况下,我们可以仍然使用单击元素:

// 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是否被其他元素隐藏/重叠,并且是完全可点击的。

有人可以摆脱点点滴​​滴,我对这些做了几个小时的研究,并没有达到任何目的。

回答

-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; 
    } 
+1

这并没有解决这个问题。 – JeffC

+0

我修改了我的方法来验证可点击的功能,它现在应该解决验证的问题,而无需实际单击Web元素。 – amateurCoder

+0

@JeffC我也相信他的问题是他的要求是在点击元素之前验证元素是否可点击或不点击。我发现你在答案中直接点击了元素。 – amateurCoder

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。你也用你的功能刮三次页面。刮一次页面,然后使用存储的元素进行可见和启用的检查,例如,

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

您可以使用xpath包含函数,逻辑运算符和祖先选项。例如:

.//a[@behavior.id='myid']/ancestor::div[contains(@class,'typeClass')]/.//span

这条线找到孩子从'div'(@ class filter)'跨度',为了找到这个div,我开始寻找具有行为的'a'。ID

而对于能见度我总是用等待或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 

东西我以前曾经是:

  1. 获得近webelement。
  2. 发送快捷键为Keys.TAB或Keys.SHIFT + Keys.TAB。
  3. 从元素中获取任何属性以检查您是否位于正确的按钮上。
  4. 发送Keys.Enter。
+0

这不能解决问题。 – JeffC

+0

这是我的方式来知道WebElement是否可见,与FluentWait和visibilityOfElementLocated方法 –

+0

现在与ExpectedConditions.elementToBeClickable –

0

这里有一些事实和见解,你的问题:

  1. 我觉得方法isElementFoundDisplayedEnabled(WebDriver driver, String accessor)是一个开销当硒已经有内置WebDriverWait类在您的处置。我会在我回答的后半部分回复约WebDriverWait
  2. 文档中明确提到isDisplayed()只有在显示该元素时才会检查。此方法避免了必须解析元素的“样式”属性的问题。
  3. 文档提及isEnabled()仅检查元素当前是否启用。除了禁用的输入元素外,这通常会返回true。
  4. 所以如果WebElementclickable或没有,功能isElementFoundDisplayedEnabled(WebDriver driver, String accessor)是必要的不覆盖。因此,可能有些情况下您可能会面临org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (781, 704). Other element would receive the click
  5. 现在,当你看到Element is not clickable at point (781, 704)你已经提到约JavascriptExecutor点击和那个作品。
  6. 所以要检查,如果一个元素是可以点击的不是我们可以简单地采取WebDriverWait类的帮助,ExpectedConditions设置为elementToBeClickable
  7. 一个例子将是:

    WebDriverWait wait2 = new WebDriverWait(driver, 10); 
    WebElement ele = wait2.until(ExpectedConditions.elementToBeClickable(By.id("element_id"))); 
    
  8. 文档明确提到Element is Clickable - it is Displayed and Enabled

  9. elementToBeClickable()方法仔细看清楚地提到,它返回the (same) WebElement once it is clickable (visible and enabled)

因此,您的问题的解决方案是WebDriverWaitExplicitWait

+0

这并不能解决问题。问题是,即使一个元素被发现是可点击的,无论是通过OP的函数还是'ExplicitWait',它仍然可以运行到元素在X点不能点击的错误。问题是如何处理这种情况,包括不可点击的错误。 – JeffC

相关问题