Элемент myElement недоступен для просмотра в точке (x, y)… Другой элемент получит щелчок

#javascript #selenium #selenium-webdriver #xpath #click

#java #селен #selenium-веб-драйвер #webdriver #katalon-studio

Вопрос:

Я пытаюсь провести несколько тестов, используя selenium на основе Katalon Studio. В одном из моих тестов я должен писать внутри текстовой области. Проблема в том, что я получаю следующую ошибку:

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

На самом деле мой элемент находится внутри какой-то другой diva, которая может его скрыть, но как я могу сделать так, чтобы событие щелчка попало в мою текстовую область?

Комментарии:

1. Вы должны получить некоторые знания о неявных и явных ожиданиях в WebDriver. Это поможет вам разобраться с видимыми невидимыми элементами.

Ответ №1:

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. Элемент присутствует, но имеет временное наложение.

В этом случае индуцируйте ExplicitWait с ExpectedConditions помощью параметра set, чтобы 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);
 

Комментарии:

1. Но я не использую javascript. Я использую katalon, который использует java.

2. Я частично решил проблему, поместив Thread.sleep перед щелчком мыши.

3. @nix86 Thread.sleep() снижает производительность вашего теста. Так что избегайте Thread.sleep() . ImplicitlyWait может быть прекращено в любое время. Так что попробуйте, ExplicitWait как я упоминал в своем ответе.

4. Но как определяется переменная драйвера?

5. @nix86 Не могли бы вы показать нам свою работу, пожалуйста, вместе с соответствующим HTML DOM, чтобы мы могли правильно направлять вас? Спасибо

Ответ №2:

Я полагаю, вы уже проверили, что здесь нет никакого другого компонента, перекрывающего друг друга (прозрачные рекламные фреймы или какой-либо другой компонент DOM => довольно часто такие вещи встречаются в элементах ввода / текстового поля), и, когда вручную (медленно) вводите свой код, он работает плавно, затем ajax вызываетможет вызвать такое поведение.

Чтобы избежать thread.sleep, попробуйте использовать EventFiringWebDriver и зарегистрировать для него дескриптор. (В зависимости от techstack вашего приложения вы можете использовать его для 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, для обработки вызовов Ajax в калитке / dojo techstack

     @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:

Как сказал @DebanjanB, ваша кнопка (или другой элемент) может быть временно закрыта другим элементом, но вы можете подождать и щелкнуть по нему, даже если вы не знаете, какой элемент закрывает кнопку.
Для этого вы можете определить свое собственное ожидаемое условие с помощью действия щелчка:

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

Ответ №4:

Попробуйте Thread.Sleep()

Неявный поток.Сон()

Так что на самом деле это не особенность Selenium WebDriver, хотя это обычная функция в большинстве языков программирования. Но все это не имеет значения.

Нитки.Sleep() делает именно то, что вы думаете, он делает, он отключает поток. Поэтому, когда ваша программа запускается, в большинстве случаев эта программа будет представлять собой несколько автоматических проверок, они выполняются в потоке. Итак, когда мы вызываем Thread .Сон мы инструктируем нашу программу не делать абсолютно ничего в течение определенного периода времени, просто спать. Не имеет значения, что делает наше тестируемое приложение, нам все равно, наши чеки отдыхают!

Однако, к сожалению, довольно часто можно увидеть несколько экземпляров Thread.Sleep() в фреймворках проверки графического интерфейса Selenium WebDriver. Что имеет тенденцию происходить, так это то, что скрипт будет сбоить или периодически выходить из строя, и кто-то запускает его локально и понимает, что есть гонка, которую иногда WedDriver проигрывает. Возможно, загрузка приложения иногда занимает больше времени, возможно, когда у него больше данных, поэтому, чтобы исправить это, они просят WebDriver вздремнуть, чтобы убедиться, что приложение загружено до продолжения проверки.

Thread.sleep(5000);

Указанное значение выражено в миллисекундах, поэтому этот код приостановит проверку на 5 секунд.

Ответ №5:

У меня возникла эта проблема, потому что я нажал на пункт меню, который расширился, изменив размер области прокрутки и положение других элементов. Поэтому я просто заставил свою программу щелкнуть назад на следующем уровне меню, а затем снова перейти на уровень меню, к которому я пытался получить доступ. Он вернул меню в исходное положение, поэтому ошибка «перехвачен щелчок» больше не будет возникать.

Ошибка не возникала каждый раз, когда я нажимал на расширяемое меню, только когда опция расширяемого меню уже была полностью в нижней части его прокручиваемой области.

Комментарии:

1. Это было опубликовано как nwer, но я думаю, что это не решение вопроса.