Как использовать Fluent, дождитесь кликабельности - Selenium - PullRequest
0 голосов
/ 23 октября 2019

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

public static void waitForElementSeenAndClick (String elementId)
    {

        WebDriver driver2 = WebDriverMgr.getDriver();

        Wait wait = new FluentWait(driver2)
                .withTimeout(FLUENT_WAIT_MAX, TimeUnit.SECONDS)
                .pollingEvery(FLUENT_WAIT_PULLING, TimeUnit.SECONDS)
                .ignoring(NoSuchElementException.class,
                        Exception.class);

        wait.until(new Function<WebDriver , Boolean>() {
            public Boolean apply (WebDriver driver2) {

                WebElement element = driver2.findElement(By.id(elementId));
                System.out.println("Try to click_1");
                element.click();
                if(element.isDisplayed()) {
                    System.out.println("Try to click_2");
                    element.click();
                    return true;
                }
                System.out.println("Try to click_3");
                return  false;
            }

        });
    }

Это то, что я получаю от консула (идентификатор: "header-account-выход из системы ")

ERROR: no such element: Unable to locate element: {"method":"css selector","selector":"#header\-account\-logout"}
  (Session info: chrome=77.0.3865.120)
For documentation on this error, please visit: https://www.seleniumhq.org/exceptions/no_such_element.html
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:17:03'

Попробуйте нажать 1, вообще не печатать. Попробуйте нажать 2, вообще не печатать. Попробуйте нажать 3, вообще не печатать. Не введено в цикл и не пытается тянуть

1 Ответ

0 голосов
/ 23 октября 2019

Ниже описывается, как я справляюсь с этой ситуацией в проектах. Я жду кликабельности, используя ExpectedConditions, что приятно и чисто. (FluentWait не требуется в большинстве случаев, просто требуется больше входных данных). Ожидание и щелчок находятся внутри try-catch, так что мы можем поймать WebDriverException, когда Selenium пытается щелкнуть элемент, но другой элемент мешает, как вы видите. Если это произойдет, мы просто повторим цикл и попробуем щелкнуть мышью до истечения времени ожидания. Я также добавил в StaleElementReferenceException, потому что нахожу это полезным.

public static void click(By locator, int timeOut)
{
    WebDriver driver = WebDriverMgr.getDriver();
    Instant now = Instant.now();
    while (Instant.now().isBefore(now.plusSeconds(timeOut)))
    {
        try
        {
            new WebDriverWait(driver, timeOut).until(ExpectedConditions.elementToBeClickable(locator)).click();

            return;
        }
        catch (WebDriverException e)
        {
            // do nothing, loop again
        }
    }

    throw new Exception("Not able to click element <" + locator + "> within " + timeOut + "s.");
}

Instant Документы Java

Примечание 1: Не передавайте простоидентификатор как String. Когда вы сделаете это, вы можете использовать этот метод только для локаторов с идентификаторами ... тогда вам придется написать другой метод для CSS-селекторов, один для XPath и так далее. Вместо этого просто передайте класс By, и вы сможете написать один метод, который обрабатывает ВСЕ типы локаторов. Вы бы назвали это как

click(By.id("..."));

Примечание: у меня сейчас нет IDE, так что это должно быть близко, по крайней мере, достаточно, чтобы направить вас в правильном направлении.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...