web-dev-qa-db-fra.com

L'élément MyElement n'est pas cliquable au point (x, y) ... Un autre élément recevrait le clic

J'essaie de faire des tests en utilisant Katalon Studio basé sur Selenium. Dans l'un de mes tests, je dois écrire dans une zone de texte. Le problème est que j'obtiens l'erreur suivante:

...Element MyElement is not clickable at point (x, y)... Other element would receive the click...

En fait, mon élément est placé à l'intérieur d'une autre diva qui pourrait le cacher, mais comment puis-je faire en sorte que l'événement click atteigne ma zone de texte?

18
nix86

Element ... is not clickable at point (x, y). Other element would receive the click" peut être causée par différents facteurs. Vous pouvez les résoudre par l'une des procédures suivantes:

  1. Impossible de cliquer sur l'élément en raison de JavaScript ou de AJAX appels présents

Essayez d'utiliser Actions Classe:

WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
  1. L'élément n'est pas cliqué car il ne se trouve pas dans Viewport

Essayez d'utiliser JavascriptExecutor pour placer l'élément dans Viewport:

JavascriptExecutor jse1 = (JavascriptExecutor)driver;
jse1.executeScript("scroll(250, 0)"); // if the element is on top.
jse1.executeScript("scroll(0, 250)"); // if the element is at bottom.

Ou

WebElement myelement = driver.findElement(By.id("id1"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement); 
  1. La page est actualisée avant que l'élément ne soit cliquable.

Dans ce cas, induisez un wait.

  1. L'élément est présent dans le DOM mais n'est pas cliquable.

Dans ce cas, ajoutez un peu de ExplicitWait pour que l'élément soit cliquable.

WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("id1")));
  1. L'élément est présent mais présente une superposition temporaire.

Dans ce cas, induisez ExplicitWait avec ExpectedConditions défini sur invisibilityOfElementLocated pour que la superposition soit invisible.

WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
  1. L'élément est présent mais a une superposition permanente.

Utilisez JavascriptExecutor pour envoyer le clic directement sur l'élément.

WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
25
DebanjanB

Je suppose que vous avez déjà vérifié qu'il n'y a aucun autre composant qui se chevauche ici (des iframes publicitaires transparents ou un autre composant du DOM => vu assez souvent de telles choses dans les éléments d'entrée/champ de texte) et, lorsque vous passez manuellement (lentement) votre code fonctionne correctement, les appels ajax peuvent provoquer ce problème.

Pour éviter thread.sleep, essayez de vous en tenir à EventFiringWebDriver et inscrivez-y une poignée. (En fonction de la technologie de votre application, vous pouvez la travailler pour Angular, JQuery ou wicket dans le gestionnaire, nécessitant ainsi différentes implémentations) (Btw: Cette approche m'a également débarrassé des choses "StaleElementException" de nombreuses fois)

voir: org.openqa.Selenium.support.events.EventFiringWebDriver org.openqa.Selenium.support.events.WebDriverEventListener

driveme = new ChromeDriver();
driver = new EventFiringWebDriver(driveme);
ActivityCapture handle=new ActivityCapture();
driver.register(handle);

=> ActivityCapture implémente WebDriverEventListener par exemple javascriptExecutor pour gérer les appels Ajax dans une techstack guichet/dojo

    @Override
public void beforeClickOn(WebElement arg0, WebDriver event1) {
    try {
        System.out.println("After click "+arg0.toString());
        //System.out.println("Start afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
        JavascriptExecutor executor = (JavascriptExecutor) event1;
        StringBuffer javaScript = new StringBuffer();
        javaScript.append("for (var c in Wicket.channelManager.channels) {");
        javaScript.append(" if (Wicket.channelManager.channels[c].busy) {");
        javaScript.append(" return true;");
        javaScript.append(" }");
        ;
        ;
        ;
        javaScript.append("}");
        javaScript.append("return false;");
        //Boolean result = (Boolean) executor.executeScript(javaScript.toString());
        WebDriverWait wait = new WebDriverWait(event1, 20);
        wait.until(new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver driver) {
                return !(Boolean) executor.executeScript(javaScript.toString());
            }
        });
        //System.out.println("End afterClickOn - timestamp: System.currentTimeMillis(): " + System.currentTimeMillis());
    } catch (Exception ex) {
        //ex.printStackTrace();
    }
}
3
ulrayk

Essayez Thread.Sleep ()

Implicite - Thread.Sleep ()

Donc, ce n'est pas vraiment une fonctionnalité de Selenium WebDriver, c'est une fonctionnalité commune dans la plupart des langages de programmation. Mais rien de tout cela.

Thread.Sleep () fait exactement ce que vous pensez qu'il fait, il dort le thread. Ainsi, lorsque votre programme s'exécute, dans la majorité de vos cas, ce programme sera constitué de vérifications automatisées, ils s'exécutent sur un thread. Ainsi, lorsque nous appelons Thread.Sleep, nous demandons à notre programme de ne rien faire pendant un certain temps, juste dormir. Peu importe ce que fait notre application en cours de test, peu nous importe, nos chèques font la sieste!

Malheureusement, il est assez courant de voir quelques instances de Thread.Sleep () dans les cadres de vérification de l'interface graphique Selenium WebDriver. Ce qui a tendance à se produire, c'est qu'un script échouera ou échouera sporadiquement, et quelqu'un l'exécute localement et se rend compte qu'il y a une course, que WedDriver perd parfois. Il se peut qu'une application prenne parfois plus de temps à charger, peut-être lorsqu'elle contient plus de données, donc pour y remédier, elles demandent à WebDriver de faire une sieste, pour s'assurer que l'application est chargée avant que la vérification ne continue.

Thread.sleep (5000);

La valeur fournie est en millisecondes, donc ce code mettra la vérification en veille pendant 5 secondes.

0
Pradnya Bolli

Comme l'a dit @DebanjanB, votre bouton (ou un autre élément) peut être temporairement couvert par un autre élément, mais vous pouvez attendre et cliquer dessus même si vous ne savez pas quel élément recouvre le bouton.
Pour ce faire, vous pouvez définir votre propre condition attendue avec l'action de clic:

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

puis utilisez ceci:

WebDriverWait wait10 = new WebDriverWait(driver, 10);
wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));
0
Adam Silenko