No se puede hacer clic en el elemento MyElement en el punto (x, y)... Otro elemento recibiría el clic

Resuelto nix86 asked hace 7 años • 5 respuestas

Estoy intentando hacer algunas pruebas utilizando Katalon Studio basado en selenio. En una de mis pruebas tengo que escribir dentro de un área de texto. El problema es que me sale el siguiente error:

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

De hecho, mi elemento se coloca dentro de otra diva que podría ocultarlo, pero ¿cómo puedo hacer que el evento de clic llegue a mi área de texto?

nix86 avatar Jun 23 '17 21:06 nix86
Aceptado

Element ... is not clickable at point (x, y). Other element would receive the click"puede ser causado por diferentes factores. Podrás abordarlos mediante cualquiera de los siguientes procedimientos:

  1. No se hace clic en el elemento debido a llamadas JavaScript o AJAX presentes

Intenta usar ActionsClase:

WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
  1. No se hace clic en el elemento porque no está dentro de la ventana gráfica

Intente utilizar JavascriptExecutorpara traer el elemento dentro de 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.

O

WebElement myelement = driver.findElement(By.id("id1"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement); 
  1. La página se actualiza antes de que se pueda hacer clic en el elemento.

En este caso inducir algunos wait.

  1. El elemento está presente en el DOM pero no se puede hacer clic en él.

En este caso, agregue algunos ExplicitWaitpara que se pueda hacer clic en el elemento.

WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("id1")));
  1. El elemento está presente pero tiene una superposición temporal.

En este caso, induzca ExplicitWaitcon ExpectedConditionsset to invisibilityOfElementLocatedpara que la superposición sea invisible.

WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
  1. El elemento está presente pero tiene una superposición permanente.

Se utiliza JavascriptExecutorpara enviar el clic directamente sobre el elemento.

WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
undetected Selenium avatar Jun 23 '2017 15:06 undetected Selenium

Supongo que ya ha comprobado que no hay ningún otro componente superpuesto aquí (iframes publicitarios transparentes o algún otro componente del DOM => se ve con bastante frecuencia este tipo de cosas en los elementos de entrada/campo de texto) y, al realizar pasos manualmente (lentamente) su código funciona sin problemas, entonces las llamadas ajax pueden causar este comportamiento.

Para evitar thread.sleep, intente seguir con EventFiringWebDriver y registre un identificador. (Dependiendo de la pila tecnológica de su aplicación, puede trabajarla para Angular, JQuery o wicket en el controlador, por lo que requiere diferentes implementaciones) (Por cierto: este enfoque también me deshizo de cosas "StaleElementException" muchas veces)

ver: 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 implementa WebDriverEventListener, por ejemplo, javascriptExecutor para manejar llamadas Ajax en un techstack wicket/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();
    }
}
ulrayk avatar Jan 03 '2018 19:01 ulrayk

Como dijo @DebanjanB, su botón (u otro elemento) podría estar cubierto temporalmente por otro elemento, pero puede esperar y hacer clic en él incluso si no sabe qué elemento cubre el botón.
Para hacer esto, puede definir su propia condición esperada con la acción de hacer 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;
        }
    }
}

y luego usa esto:

WebDriverWait wait10 = new WebDriverWait(driver, 10);
wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));
Adam Silenko avatar Feb 10 '2020 20:02 Adam Silenko