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?
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:
Essayez d'utiliser Actions
Classe:
WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
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);
Dans ce cas, induisez un wait
.
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")));
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")));
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);
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();
}
}
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.
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));