2017-08-30 1 views
2

Je suis conscient que la façon générale, il est testé que WebElement est cliquable:Java + Selenium: Comment savoir si WebElement est cliquable d'une autre manière que isDisplayed, isEnabled et findElement?

Le test dans quelque chose comme ceci:

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

Cette fonction a défaut, qu'il vérifie seulement si l'élément est cliquable à DOM niveau, mais si à cause d'un gâchis css, l'élément est caché/chevauché, on peut obtenir Exception:

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

...

Dans de telles situations, on peut toujours cliquer sur l'élément en utilisant:

// 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); 

Mais, je voudrais savoir, comment nous pouvons vérifier sans cliquer à travers executor.executeScript que, que WebElement n'est pas caché/chevauché par un autre élément et est PARFAITEMENT cliquable.

Quelqu'un peut-il s'il vous plaît jeter quelque chose, j'ai fait quelques heures de recherche sur ces derniers et atteint nulle part.

Répondre

-1

D'abord vous devez noter quel attribut a la propriété de caché ou visible et basé sur ce que vous pouvez écrire quelque chose comme ça.

Exemple:

<input id ="email" style="margin-top: 0px; visibility: visible;" > 

code:

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

Cela ne répond pas à la question. – JeffC

+0

J'ai modifié ma méthode pour vérifier la fonctionnalité cliquable qui devrait maintenant répondre à la question de la vérification sans réellement cliquer sur l'élément Web. – amateurCoder

+0

@JeffC Je crois aussi par sa question que son exigence n'était pas de cliquer sur l'élément avant de vérifier si l'élément est cliquable ou non. Je vois que vous avez cliqué sur l'élément tout de suite dans votre réponse. – amateurCoder

0

Je ne suis pas un grand fan de la création d'une fonction qui gère tous les clics, etc. comme ça, mais si je forcé d'écrire un , ça ressemblerait à ça. Les commentaires à l'intérieur expliquent ce qui se passe.

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); 
     } 
    } 
} 

Certains commentaires sur votre fonction ... Vous devriez passer autour By cas au lieu de chaînes, par exemple De cette façon, vos fonctions peuvent être plus flexibles et ne sont pas codées en dur dans XPath seulement. Aussi, vous grattez la page 3 fois avec votre fonction. Grattez la page une fois, puis utilisez l'élément stocké pour que vos chèques soient visibles et activés, par ex.

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

Vous pouvez utiliser la fonction xpath contains, les opérateurs logiques et l'option ancestor. Par exemple:

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

Cette ligne trouver enfants 'span' de la 'div' (@ filtre de classe), et pour trouver ce div j'ai commencé à trouver le 'a' avec le comportement.id

Et pour la visibilité que j'utilise toujours l'attente ou les options 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))); 
} 

Et peut-être qu'il est utilisé utile une certaine capacité sur le conducteur elementScrollBehavior pour rechercher les éléments du fond:

capabilities.setCapability("elementScrollBehavior", 1); // 0- from Top, 
                  // 1 - from 
                  // bottom 

Quelque chose que j'était autrefois utilisé:

  1. un proche Obtenir WebElement.
  2. Envoyez un raccourci en tant que Keys.TAB ou Keys.SHIFT + Keys.TAB.
  3. Prenez n'importe quelle propriété de l'élément pour vérifier que vous êtes sur le bon bouton.
  4. Envoyer un Keys.Enter.
+0

Cela ne répond pas à la question. – JeffC

+0

C'est ma façon de savoir si un WebElement est visible, avec FluentWait et la méthode visibilityOfElementLocated –

+0

Maintenant avec ExpectedConditions.elementToBeClickable –

0

Voici quelques faits et des idées à votre question:

  1. Je sens la méthode isElementFoundDisplayedEnabled(WebDriver driver, String accessor) est une surcharge lorsque Sélénium ont déjà la classe WebDriverWait en construction à votre disposition. Je reviendrai environ WebDriverWait dans la dernière partie de ma réponse.
  2. La documentation mentionne clairement isDisplayed() vérifie seulement si cet élément est affiché ou non. Cette méthode évite le problème d'avoir à analyser l'attribut "style" d'un élément.
  3. Les mentions de documentation isEnabled() vérifient uniquement si l'élément est actuellement activé ou non. Cela sera généralement vrai pour tout sauf pour les éléments d'entrée désactivés.
  4. Donc la fonction isElementFoundDisplayedEnabled(WebDriver driver, String accessor) ne couvre pas obligatoirement si le WebElement est clickable ou non. Par conséquent, il peut y avoir des cas où vous pouvez faire face à org.openqa.selenium.WebDriverException: unknown error: Element is not clickable at point (781, 704). Other element would receive the click.
  5. Maintenant, quand vous voyez Element is not clickable at point (781, 704) vous avez déjà mentionné environ JavascriptExecutor cliquez et cela fonctionne.
  6. Donc, pour vérifier que si un élément est cliquable ou non, nous pouvons simplement prendre l'aide de WebDriverWait classe avec ExpectedConditions ensemble à elementToBeClickable.
  7. Un exemple sera:

    WebDriverWait wait2 = new WebDriverWait(driver, 10); 
    WebElement ele = wait2.until(ExpectedConditions.elementToBeClickable(By.id("element_id"))); 
    
  8. Documentation mentionne clairement Element is Clickable - it is Displayed and Enabled

  9. Un examen plus approfondi de la méthode elementToBeClickable() mentionne clairement qu'il retourne the (same) WebElement once it is clickable (visible and enabled)

D'où la solution pour votre question est WebDriverWait à savoir ExplicitWait

+0

Cela ne résout pas le problème. Le problème est que même si un élément est cliquable, que ce soit par la fonction OP ou par "ExplicitWait", il peut toujours se retrouver dans l'erreur "L'élément n'est pas cliquable au point X". La question est de savoir comment gérer cette situation, y compris l'erreur non cliquable. – JeffC