Определить, если элемент не был найден через некоторое время с помощью Selenium Webdriver - PullRequest
0 голосов
/ 04 ноября 2019

Я подключаюсь к веб-сайту несколько раз каждые несколько секунд, и иногда веб-сайт просто вступает в ОГРОМНУЮ фазу загрузки, где для остановки загрузки требуется около 5 минут. Когда он, наконец, останавливается, он выдает ожидаемое ElementNotFoundException, которое я затем ловлю и перезапускаю процесс с последней точки. Тем не менее, я хочу быть в состоянии обнаружить эту фазу загрузки и обработать ее как можно скорее, вместо того, чтобы ждать 5 минут до ее завершения. Я попытался использовать FluentWait реализацию и WebDriverWait, но пока ничего не работает. Вот две реализации, которые я попробовал:

FluentWait:

private static WebElement fluentWait(final By locator, WebDriver driver) {
    Wait<WebDriver> wait = new FluentWait<>(driver)
            .withTimeout(10, TimeUnit.SECONDS)
            .pollingEvery(2, TimeUnit.SECONDS);
            //.ignoring(NoSuchElementException.class);

    return wait.until((Function<WebDriver, WebElement>) driver1 -> {
        assert driver1 != null;
        return driver1.findElement(locator);
    });
    }

WebDriverWait:

new WebDriverWait(driver,5).until(ExpectedConditions.presenceOfElementLocated(new By.ByCssSelector(someSelector)));

PS: я использую Selenium Webdriver и, в частности, ChromeDriver(). Вот изображение того, как выглядит сайт, когда он входит в эту огромную фазу загрузки ->

screenshot

Ответы [ 2 ]

1 голос
/ 07 ноября 2019

Не о чем беспокоиться. Вы можете проверить ссылки ниже, и я надеюсь, что это поможет.

Selenium - Как дождаться полной загрузки страницы

Дождаться загрузки страницы вСелен

0 голосов
/ 07 ноября 2019

Исходя из вашего вопроса, который я собираю, вы хотите, чтобы код ожидал определенное количество времени и времени ожидания, если выполнение не было завершено до этого момента?

Если вы хотите сделать это, ядумаю, что лучший способ - реализовать простой класс, который использует исполнителя для ожидания результата. Исполнители поддерживают тайм-ауты и могут возвращать значение ИЛИ выдавать исключение, если выполнение занимает слишком много времени.

Для этого я написал следующий простой класс:

public class TimedWait<T> {
    public T run(Callable<T> run, long timeoutMs) throws TimeoutException, ExecutionException, InterruptedException {
        ExecutorService executor = Executors.newSingleThreadExecutor();
        return executor.invokeAny(Collections.singletonList(run), timeoutMs, TimeUnit.MILLISECONDS);
    }
}

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

Ниже приведен пример того, как он может функционировать (я сделал быструю и грязную обработку исключений в качестве примера, вы могли быхочу немного убрать это, чтобы избежать попытки перехвата catch)

public void run() {
    try {
        String result = new TimedWait<String>().run(() -> {
            Thread.sleep(500);
            return "Some Result";
        }, 1000L);
        System.out.println(result);

        String timeOut = new TimedWait<String>().run(() -> {
            Thread.sleep(1500);
            return "This will time out";
        }, 1000L);
        System.out.println(timeOut);

    } catch (Exception e) {
        e.printStackTrace();
    }
}

Так как в этом примере задержка для первого вывода меньше, чем время ожидания, результат будет напечатан. Для второго выхода задержка превышает время ожидания, что приводит к исключению.

Вывод:

Some Result
java.util.concurrent.TimeoutException
...