#java #selenium #selenium-webdriver #automation #rpa
Вопрос:
Я написал функцию следующим образом
public static WebElement waitForElementToBeClickable(WebDriver driver, WebElement webElement, int seconds) {
WebDriverWait wait = new WebDriverWait(driver, seconds);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(webElement));
element.click();
return element;
}
Теперь я импортирую эту функцию и использую ее следующим образом
private String loginButton = "btnActive";
private String home = "//a[@id='pt1:_UIShome']";
WebElement login = driver.findElement(By.id(loginButton));
libraryUtils.waitForElements.waitForElementToBeClickable(driver, login, 20).click();
WebElement homeButton = driver.findElement(By.xpath(home));
libraryUtils.waitForElements.waitForElementToBeClickable(driver, homeButton, 20).click();
Кнопка входа в систему нажата, но затем, перейдя на следующую страницу, я получаю следующую ошибку —
org.openqa.селен.Исключение StaleElementReferenceException: устаревший элемент ссылка: элемент не прикреплен к документу страницы
Xpath прав, я это проверил. И когда я использую element.click()
, это тоже работает, но тогда мне потребуется вручную ввести время сна, что я и делаю. Я бы хотел, чтобы это было динамично. Буду признателен за любую помощь или предложения.
Комментарии:
1. Отображается ли элемент, расположенный с
//a[@id='pt1:_UIShome']
XPath, на первой странице, где представлена кнопка входа в систему?2. Можете ли вы поделиться ссылкой на веб-сайт?
3. Эй, извините, мне не разрешили поделиться ссылкой, но элемент с //a[@id=’pt1:_UIShome’] не находится на странице после того, как я войду в систему
4. Хорошо, есть ли этот элемент в представлении или вам нужно прокрутить его, чтобы вывести на видимый экран? Есть ли какое-то всплывающее окно, вертушка и т. Д. Изначально над ним?
5. Это на виду, не нужно скулить или что-то в этом роде
Ответ №1:
Иногда JS не был завершен, и если вы попытаетесь взаимодействовать с веб-элементом или веб-элементами, которые вы увидите staleElemenent exception
.
Однако приведенное ниже решение может сработать для вас :
new WebDriverWait(driver, 10).ignoring(StaleElementReferenceException.class).until(ExpectedConditions.elementToBeClickable(By.xpath("//a[@id='pt1:_UIShome']")));
driver.findElement(By.xpath("//a[@id='pt1:_UIShome']")).click();
Ответ №2:
Возможно, это будет не очень приятно, но я не вижу другого стабильного решения, кроме как добавить туда немного сна. Поэтому, пожалуйста, попробуйте это:
private String loginButton = "btnActive";
private String home = "//a[@id='pt1:_UIShome']";
WebElement login = driver.findElement(By.id(loginButton));
libraryUtils.waitForElements.waitForElementToBeClickable(driver, login, 20).click();
driver.findElement(By.xpath(home));
libraryUtils.waitForElements.waitForElementToBeClickable(driver, homeButton, 20);
try {
Thread.sleep(5000);
} catch (InterruptedException e) {
e.printStackTrace();
}
driver.findElement(By.xpath(home)).click();
Комментарии:
1. я уже добавляю режим сна, когда нужно приостановить его вручную, я хотел сделать это динамически, чтобы он работал на нескольких машинах независимо от задержки скорости Интернета. Дело в том, что я должен добавить сон в гораздо большее количество мест, а не только в это. Но спасибо тебе.
2. Я понимаю. В случае, если там есть динамический DOM, я не вижу для этого простого и стабильного решения. Это известная проблема.
3. Пожалуйста, дайте мне знать, если вы найдете какое-то четкое и стабильное решение.
4. Да, конечно, если вы тоже это сделаете, пожалуйста, дайте мне знать
Ответ №3:
Проблема здесь в том, что вы уже выполняете element.click()
waitForElementToBeClickable
функцию и вызываете click еще раз при вызове этой функции.
libraryUtils.waitForElements.waitForElementToBeClickable(driver, login, 20).click();
Поскольку вы уже нажали, ожидая, пока элемент станет доступным для клика, вам не следует нажимать на него снова. Я надеюсь, что вы получили ответ на StaleElementException
Комментарии:
1. Вход в веб-элемент = драйвер.findElement(By.id(Кнопка входа в систему)); libraryUtils.waitForElements.waitForElementToBeClickable(драйвер, логин, 20); домашняя кнопка веб-элемента = driver.findElement(По.xpath(главная страница)); библиотечные кнопки.waitForElements.waitForElementToBeClickable(драйвер, домашняя кнопка, 20); кнопка оплаты веб-элемента = driver.findElement(По.xpath(кредиторская задолженность)); библиотЕчные кнопки.waitForElements.waitForElementToBeClickable(драйвер, кнопка оплаты, 20);
2. я изменил код, и я выполняю его, как показано выше, он нажимает на элемент homeButton, но не нажимает на элемент payablesButton. Я получаю следующую ошибку — org.openqa.selenium. Исключение ElementClickInterceptedException: перехвачен щелчок элемента: Элемент <идентификатор=»groupNode_payables_1″ класс=»приложение-навигационная метка вверху-навигационная метка» роль=»меню» aria-haspopup=»true» tabindex=»-1″>… </a> не является кликабельным
3. Причина этой ошибки заключается в том, что какой-либо другой дочерний или родительский элемент перекрывает элемент, который вы пытаетесь щелкнуть. Есть несколько способов исправить это:
element = driver.find_element_by_css('div[class*="class_name"]') driver.execute_script("arguments[0].click();", element)
ИЛИelement = driver.find_element_by_css('div[class*="class_name"]') webdriver.ActionChains(driver).move_to_element(element ).click(element ).perform()