2017-08-30 262 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

相關問題