#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"
может быть вызвано различными факторами. Вы можете обратиться к ним с помощью любой из следующих процедур:
- Элемент не щелкает из-за присутствия вызовов JavaScript или AJAX
Попробуйте использовать Actions
класс:
WebElement element = driver.findElement(By.id("id1"));
Actions actions = new Actions(driver);
actions.moveToElement(element).click().build().perform();
- Элемент не щелкается, так как он не находится в пределах области просмотра
Попробуйте использовать 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);
- Страница обновляется до того, как элемент станет интерактивным.
В этом случае индуцируйте некоторые wait
.
- Элемент присутствует в DOM, но не доступен для просмотра.
В этом случае добавьте некоторые ExplicitWait
, чтобы элемент был кликабельным.
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.elementToBeClickable(By.id("id1")));
- Элемент присутствует, но имеет временное наложение.
В этом случае индуцируйте ExplicitWait
с ExpectedConditions
помощью параметра set, чтобы invisibilityOfElementLocated
Наложение было невидимым.
WebDriverWait wait3 = new WebDriverWait(driver, 10);
wait3.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("ele_to_inv")));
- Элемент присутствует, но имеет постоянное наложение.
Используется 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, но я думаю, что это не решение вопроса.