24

我正在尝试使用基于硒的 Katalon Studio 进行一些测试。在我的一项测试中,我必须在文本区域内编写。问题是我收到以下错误:

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

事实上,我的元素被放置在其他一些可能隐藏它的女主角内,但我怎样才能让点击事件击中我的文本区域?

4

5 回答 5

43

Element ... is not clickable at point (x, y). Other element would receive the click"可能由不同的因素引起。您可以通过以下任一过程解决它们:

  1. 由于存在 JavaScript 或 AJAX 调用,元素没有被点击

尝试使用Actions类:

WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
  1. 元素没有被点击,因为它不在视口中

尝试使用JavascriptExecutor将元素带入视口:

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.

或者

WebElement myelement = driver.findElement(By.id("id1"));
JavascriptExecutor jse2 = (JavascriptExecutor)driver;
jse2.executeScript("arguments[0].scrollIntoView()", myelement); 
  1. 页面在元素可点击之前被刷新。

在这种情况下诱发一些wait

  1. 元素存在于 DOM 中但不可点击。

在这种情况下,添加一些ExplicitWait元素以使元素可点击。

WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("id1")));
  1. 元素存在但具有临时覆盖。

在这种情况下ExplicitWaitExpectedConditions设置invisibilityOfElementLocated为使覆盖不可见。

WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
  1. 元素存在但具有永久覆盖。

用于JavascriptExecutor直接在元素上发送点击。

WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
于 2017-06-23T15:08:13.267 回答
3

我假设,您已经检查过这里没有任何其他组件重叠(透明广告 iframe 或 DOM 的其他一些组件 => 在输入/文本字段元素中经常看到这样的东西),并且在手动(缓慢)步进时你的代码,它运行顺利,那么 ajax 调用可能会导致这种行为。

要避免 thread.sleep,请尝试使用 EventFiringWebDriver 并为其注册一个句柄。(根据您的应用程序的技术堆栈,您可以在处理程序中为 Angular、JQuery 或 wicket 工作,因此需要不同的实现)(顺便说一句:这种方法也让我多次摆脱“StaleElementException”的东西)

请参阅: 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 实现 WebDriverEventListener 例如 javascriptExecutor 来处理 wicket/dojo techstack 中的 Ajax 调用

    @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();
    }
}
于 2018-01-03T19:01:47.733 回答
1

正如@DebanjanB 所说,您的按钮(或另一个元素)可能会暂时被另一个元素覆盖,但是即使您不知道哪个元素覆盖了按钮,您也可以等待并单击它。
为此,您可以使用 click 操作定义自己的 ExpectedCondition:

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

然后使用这个:

WebDriverWait wait10 = new WebDriverWait(driver, 10);
wait10.until(elementToBeClickable(btn));
wait10.until(new SuccessfulClick(btn));
于 2020-02-10T20:00:19.757 回答
-1

试试 Thread.Sleep()

隐式 - Thread.Sleep()

所以这实际上不是 Selenium WebDriver 的一个特性,但它是大多数编程语言的一个共同特性。但这些都不重要。

Thread.Sleep() 完全按照您的想法执行,它使线程休眠。因此,当您的程序运行时,在大多数情况下,该程序将进行一些自动检查,它们在线程上运行。因此,当我们调用 Thread.Sleep 时,我们是在指示我们的程序在一段时间内完全不做任何事情,只是休眠。不管我们被测试的应用程序在做什么,我们不在乎,我们的检查正在打盹!

令人沮丧的是,在 Selenium WebDriver GUI 检查框架中看到一些 Thread.Sleep() 实例是相当普遍的。倾向于发生的情况是脚本会偶尔失败或失败,并且有人在本地运行它并意识到有一场比赛,有时 WedDriver 正在输掉比赛。可能是应用程序有时需要更长的时间来加载,也许是当它有更多数据时,所以为了修复它,他们告诉 WebDriver 小睡一下,以确保在检查继续之前加载应用程序。

线程.sleep(5000);

提供的值以毫秒为单位,因此此代码将使检查休眠 5 秒。

于 2019-03-26T12:32:20.253 回答
-2

我遇到了这个问题,因为我点击了一个展开的菜单选项,改变了可滚动区域的大小以及其他项目的位置。所以我只是让我的程序在菜单的上一级单击,然后再次前进,到我试图访问的菜单的级别。它把菜单放回原来的位置,这样“点击拦截”的错误就不会再发生了。

每次单击可扩展菜单时都不会发生错误,仅当可扩展菜单选项已经一直位于其可滚动区域的底部时。

于 2020-04-28T08:32:23.070 回答