Selenium Web Driver & Java. Das Element kann am Punkt (x, y) nicht angeklickt werden. Ein anderes Element würde den Klick erhalten

90

Ich habe explizite Wartezeiten verwendet und ich habe die Warnung:

org.openqa.selenium.WebDriverException: Das Element kann an Punkt (36, 72) nicht angeklickt werden. Ein anderes Element würde den Klick erhalten: ... Befehlsdauer oder Zeitüberschreitung: 393 Millisekunden

Wenn ich benutze Thread.sleep(2000), erhalte ich keine Warnungen.

@Test(dataProvider = "menuData")
public void Main(String btnMenu, String TitleResultPage, String Text) throws InterruptedException {
    WebDriverWait wait = new WebDriverWait(driver, 10);
    driver.findElement(By.id("navigationPageButton")).click();

    try {
       wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector(btnMenu)));
    } catch (Exception e) {
        System.out.println("Oh");
    }
    driver.findElement(By.cssSelector(btnMenu)).click();
    Assert.assertEquals(driver.findElement(By.cssSelector(TitleResultPage)).getText(), Text);
}
Maria
quelle
Verwenden Sie Chrome Version 61+?
Demouser123
@ Demouser123 Ich benutze Firefox 47.0.1 und SeleniumWebDriver 2.51.0
Maria
@Maria In welcher Zeile erhalten Sie den Fehler? Danke
DebanjanB
@DebanjanB In Zeile: driver.findElement (By.id ("navigationPageButton")). Click ();
Maria
Dieser Fehler bedeutet, dass ein anderes Element das Zielelement überlagert (fest / absolut positionierte Überlagerung) oder der Z-Index zu niedrig ist. Dies kann durch Hover-Effekte bei Übergängen verursacht werden (langsamer als das minimale Timeout, in diesem Fall 393 ms). Sie sollten warten, #navigationPageButtonbis sie sichtbar sind (oder auch elementToBeClickable()für dieses Element anklickbar sind ) oder prüfen, ob alle Voraussetzungen erfüllt sind, damit die Schaltfläche anklickbar ist.
Try-Catch-Endlich

Antworten:

191

WebDriverException: Das Element kann an Punkt (x, y) nicht angeklickt werden.

Dies ist eine typische org.openqa.selenium.WebDriverException, die die java.lang.RuntimeException erweitert .

Die Felder dieser Ausnahme sind:

  • BASE_SUPPORT_URL :protected static final java.lang.String BASE_SUPPORT_URL
  • DRIVER_INFO :public static final java.lang.String DRIVER_INFO
  • SESSION_ID :public static final java.lang.String SESSION_ID

Über Ihren individuellen Anwendungsfall sagt der Fehler alles:

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

Aus Ihrem Codeblock geht hervor, dass Sie das waitals definiert haben, WebDriverWait wait = new WebDriverWait(driver, 10);aber die click()Methode für das Element aufrufen, bevor das ExplicitWaitwie in ins Spiel kommt until(ExpectedConditions.elementToBeClickable).

Lösung

Der Fehler Element is not clickable at point (x, y)kann aus verschiedenen Faktoren resultieren. Sie können sie mit einem der folgenden Verfahren beheben:

1. Element, das aufgrund vorhandener JavaScript- oder AJAX-Aufrufe nicht angeklickt wird

Versuchen Sie, ActionsKlasse zu verwenden :

WebElement element = driver.findElement(By.id("navigationPageButton"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();

2. Das Element wird nicht angeklickt, da es sich nicht im Ansichtsfenster befindet

Versuchen Sie JavascriptExecutor, das Element in das Ansichtsfenster zu bringen:

WebElement myelement = driver.findElement(By.id("navigationPageButton"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement); 

3. Die Seite wird aktualisiert, bevor das Element angeklickt werden kann.

In diesem Fall induzieren Sie ExplicitWait, dh WebDriverWait, wie in Punkt 4 erwähnt.

4. Das Element ist im DOM vorhanden, aber nicht anklickbar.

In diesem Fall induzieren Sie ExplicitWait mit ExpectedConditionsset to, elementToBeClickabledamit das Element anklickbar ist:

WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("navigationPageButton")));

5. Element ist vorhanden, hat jedoch eine temporäre Überlagerung.

In diesem Fall induzieren Sie ExplicitWaitmit ExpectedConditionsset to, invisibilityOfElementLocateddass die Überlagerung unsichtbar ist.

WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));

6. Element ist vorhanden, hat aber eine permanente Überlagerung.

Verwenden Sie JavascriptExecutordiese Option , um den Klick direkt auf das Element zu senden.

WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
DebanjanB
quelle
1
Zu # 6 / # 2 oben: Auf die .ExecuteScript-Methode kann jetzt über den Webtreiber selbst und nicht mehr über den JavascriptExecutor zugegriffen werden. Danke für die gut geschriebene Antwort!
Tabrock
5
Sie haben viele Möglichkeiten behandelt, bei denen nur 5 und 6 die richtige Methode sind, um den genannten Fehler zu behandeln. Die ersten vier werfen unterschiedliche Fehler aus, für die die von Ihnen angegebene Lösung nicht funktioniert. Zum Beispiel ist Punkt 3 tatsächlich ein veraltetes Elementproblem, das nicht funktionieren würde, obwohl Sie so lange mit der elementToBeClickble-Methode warten. Das muss anders gehandhabt werden.
Rajagopalan
6 ist nicht wirklich richtig, ein Hack, um das Problem zu umgehen, 5 wäre richtig, wenn die richtige erwartete Bedingung verwendet würde. 4 scheint die einzig richtige Antwort zu sein.
Ardesco
1
Du hast meinen Tag gerettet :-)
Ansal Ali
Wenn Sie die Aktionen des Benutzers emulieren, ist es möglicherweise sehr unerwünscht, Javascript zu verwenden, um auf ein Element zu klicken, auf das überhaupt nicht geklickt werden kann (Nr. 6). Der Endbenutzer würde dies niemals tun. Er würde entweder entweder zu dem Element scrollen, um es in das Ansichtsfenster zu bringen, oder eine Überlagerung (sofern die Seite dies zulässt) für die Interaktion mit dem Element schließen.
p_champ
18

Falls Sie es mit Javascript verwenden müssen

Wir können Argumente [0] .click () verwenden, um die Klickoperation zu simulieren.

var element = element(by.linkText('webdriverjs'));
browser.executeScript("arguments[0].click()",element);
Rester-Test
quelle
Funktioniert! Ich kann mir nicht vorstellen, wie es funktioniert, aber ansonsten klickt es auf die Überlagerungsebene (das Warten auf das Schließen der Überlagerung durch 'invisibilityOfElementLocated' dauert ungefähr 30 Sekunden).
Fisk
Können Sie bitte die vollständige Erklärung schreiben, da ich in Java schreibe und es kein vertrauter Krieg ist? Können Sie bitte den vollständigen Ablauf bereitstellen?
Bastian
4

Ich bin auf diesen Fehler gestoßen, als ich versucht habe, auf ein Element zu klicken (oder auf dessen Überlagerung, das war mir egal), und die anderen Antworten haben bei mir nicht funktioniert. Ich habe es mithilfe der elementFromPointDOM-API behoben , um das Element zu finden, auf das Selenium stattdessen klicken soll:

element_i_care_about = something()
loc = element_i_care_about.location
element_to_click = driver.execute_script(
    "return document.elementFromPoint(arguments[0], arguments[1]);",
    loc['x'],
    loc['y'])
element_to_click.click()

Ich hatte auch Situationen, in denen sich ein Element bewegte , zum Beispiel, weil ein Element darüber auf der Seite eine animierte Erweiterung oder Reduzierung durchführte. In diesem Fall hat diese Klasse für erwartete Bedingungen geholfen. Sie geben ihm die Elemente, die animiert sind , nicht die, auf die Sie klicken möchten. Diese Version funktioniert nur für jQuery-Animationen.

class elements_not_to_be_animated(object):
    def __init__(self, locator):
        self.locator = locator

    def __call__(self, driver):
        try:
            elements = EC._find_elements(driver, self.locator)
            # :animated is an artificial jQuery selector for things that are
            # currently animated by jQuery.
            return driver.execute_script(
                'return !jQuery(arguments[0]).filter(":animated").length;',
                elements)
        except StaleElementReferenceException:
            return False
residdsk
quelle
2

Du kannst es versuchen

WebElement navigationPageButton = (new WebDriverWait(driver, 10))
 .until(ExpectedConditions.presenceOfElementLocated(By.id("navigationPageButton")));
navigationPageButton.click();
fg78nc
quelle
Es hilft mir nicht.
Maria
Ja: org.openqa.selenium.WebDriverException: Das Element kann an Punkt (36, 72) nicht angeklickt werden. Ein anderes Element würde den Klick erhalten: <div tabindex = "0" class = "waiter-ui-lock"> </ div> Befehlsdauer oder Zeitüberschreitung: 70 Millisekunden
Maria
1
versuchen Sie das folgendeWebElement element = driver.findElement(By.id("navigationPageButton")); Actions actions = new Actions(driver); actions.moveToElement(element).click().perform();
fg78nc
Es ist auch keine Hilfe. Ich habe zwei Ausnahmen und einen AssertionError und als nächstes einen Fehler "Element ist an Punkt nicht anklickbar"
Maria
1
Wenn ich Thread.Sleep benutze, funktionieren alle. Aber ich benutze Wait all fail.
Maria
2

Das Scrollen der Seite zu dem in der Ausnahme erwähnten Punkt in der Nähe hat den Trick für mich getan. Unten ist ein Code-Snippet:

$wd_host = 'http://localhost:4444/wd/hub';
$capabilities =
    [
        \WebDriverCapabilityType::BROWSER_NAME => 'chrome',
        \WebDriverCapabilityType::PROXY => [
            'proxyType' => 'manual',
            'httpProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
            'sslProxy' => PROXY_DOMAIN.':'.PROXY_PORT,
            'noProxy' =>  PROXY_EXCEPTION // to run locally
        ],
    ];
$webDriver = \RemoteWebDriver::create($wd_host, $capabilities, 250000, 250000);
...........
...........
// Wait for 3 seconds
$webDriver->wait(3);
// Scrolls the page vertically by 70 pixels 
$webDriver->executeScript("window.scrollTo(0, 70);");

HINWEIS: Ich benutze Facebook PHP Webdriver

Sudheesh.MS
quelle
0

Die beste Lösung besteht darin, die Klickfunktion zu überschreiben:

public void _click(WebElement element){
    boolean flag = false;
    while(true) {
        try{
            element.click();
            flag=true;
        }
        catch (Exception e){
            flag = false;
        }
        if(flag)
        {
            try{
                element.click();
            }
            catch (Exception e){
                System.out.printf("Element: " +element+ " has beed clicked, Selenium exception triggered: " + e.getMessage());
            }
            break;
        }
    }
}
user2274204
quelle
0

In C # hatte ich Probleme mit der Überprüfung RadioButton, und dies funktionierte für mich:

driver.ExecuteJavaScript("arguments[0].checked=true", radio);
Kokabi
quelle
0

Kann es mit dem folgenden Code versuchen

 WebDriverWait wait = new WebDriverWait(driver, 30);

Ein anderes Element übergeben würde den Klick erhalten :<a class="navbar-brand" href="#"></a>

    boolean invisiable = wait.until(ExpectedConditions
            .invisibilityOfElementLocated(By.xpath("//div[@class='navbar-brand']")));

Übergeben Sie die ID der anklickbaren Schaltfläche wie unten gezeigt

    if (invisiable) {
        WebElement ele = driver.findElement(By.xpath("//div[@id='button']");
        ele.click();
    }
Nagarjuna Yalamanchili
quelle