Есть отличная удаленная работа для php+codeception+jenkins+allure+docker спецов. 100% remote! Присоединиться к проекту

Задержка на открытые нового окна Webdriver

webdriver
Теги: #<Tag:0x00007f7b636307a0>

(Ok Tober) #1

Привет,
С недавних пор, а именно с выходом 44 версии Хрома у меня возникла проблема, что стали криво хендлиться открытыя новых окон/алертов (а на самом деле- драйвер не ожидает, пока прогрузится страница), вылазит след. ошибка:

org.openqa.selenium.StaleElementReferenceException: stale element reference: element is not attached to the page document
(Driver info: chromedriver=2.16.333243 (0bfa1d3575fc1044244f21ddb82bf870944ef961),platform=Windows NT 6.1 SP1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 105 milliseconds

На сколько я понимаю - страница не успевает прогружаться, а вебдрайвер пытается найти елементы, которых еще нет в DOMе. Не понимаю, почему начала возникать такая проблема. Имплисит ожидания прописаны: driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);.

Подскажите как решить проблему. В крайнем случае - подскажите как можно добавить ожидание типа wait.until, которое будет проверять, что добавилось новое окно (открывается по клику на linked text), и я могу на него перейти.
п.с.я знаю какие елементы ожидать на новой странице, но мне нужно сначала перейти на неё. Провал в том, что валится метод перехода, так как он не успевает увидеть новую страницу. А добавлять просто sleep не очень хочу.

 linkedText.click();
 ArrayList<String> tabs = new ArrayList<String>(driver.getWindowHandles());
 driver.switchTo().window(tabs.get(1));

(Keiga) #2

Сделайте свой метод ожидания нового окна. В цикле опрашивайте некоторое время getWindowHandles() пока он не вернет +1, можно самому установить требуемый таймаут и прочие нюансы. После чего уже другим методом переключаетесь на окно и работаете с ним.


(Sergey Korol) #3

Можете попробовать поиграться с кастомными ExpectedConditions, по типу:

wait.until((WebDriver driver) -> driver.getWindowHandles().size() > 1);

(breakmt) #4

я сделал себе ожидание, до тех пор пока getWindowHandles() не изменит своего значения

wait.until(new ExpectedCondition<Boolean>() {

  @Override
  public Boolean apply(WebDriver webDriver) {
    return !webDriver.getWindowHandles().equals(oldWindowsHandles);
  }

});

(Женя Воронкин) #5

У меня проходит реализация метода


public ExpectedCondition<String> newWindowForm(final By locator) {
        return new ExpectedCondition<String>() {
            public String apply(WebDriver d) {
                String initialWindowHandle = d.getWindowHandle(); // Запоминаем в начале, в каком окне мы находились
                String found = null;
                Set<String> windowHandles = d.getWindowHandles(); // возвращает множ-во идентификаторов окон И далее проходим в цикле в каждое окно и проверяем
                // имеется ли необходимый элемент в новом окне, нет - тогда переключаемся в следующее, если совпадает, то true
                for (String handle : windowHandles) {
                    try {
                        d.switchTo().window(handle);
                        if (d.findElement((locator)).isDisplayed()) {
                            found = handle;
                            break;
                        }
                    } catch (WebDriverException e) { // игнорируем все исключения
                    }
                }
                d.switchTo().window(initialWindowHandle);
                return found;
            }
        };

Сам метод использую следующим образом -

clickNewPopupWindow.click(); // клик элемент для открытия нового окна
String parentWindowHandler = driver.getWindowHandle(); // Store your parent window
                driver.switchTo().window(new WebDriverWait(driver, 10).until(newWindowForm(By.cssSelector("#searchField"))));, где By.cssSelector("#searchField") - это собственно элемент в новом окне

... // тут что-то делаю в новом окне

driver.switchTo().window(parentWindowHandler);  // Switch back to parent window

и т.д…