WebDriver: проверить, существует ли элемент? [Дубликат]

    

На этот вопрос уже есть ответ здесь:

    

Как проверить, существует ли элемент с веб-драйвером?

Действительно ли использование метода catch является единственным возможным способом?

boolean present;
try {
   driver.findElement(By.id("logoutLink"));
   present = true;
} catch (NoSuchElementException e) {
   present = false;
}
105 голосов | спросил Ralph 29 J0000006Europe/Moscow 2011, 17:17:40

10 ответов


0

Вы могли бы альтернативно сделать:

driver.findElements( By.id("...") ).size() != 0

Что спасает от неприятной попытки /поймать

ответил Mike Kwan 29 J0000006Europe/Moscow 2011, 17:57:49
0

Я согласен с ответом Майка, но существует неявное 3-секундное ожидание, если не найдено ни одного элемента, который можно включить /выключить, что полезно, если вы часто выполняете это действие:

driver.manage().timeouts().implicitlyWait(0, TimeUnit.MILLISECONDS);
boolean exists = driver.findElements( By.id("...") ).size() != 0
driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

Использование этого в служебном методе должно повысить производительность, если вы выполняете много тестов

ответил Edd 9 Jpm1000000pmMon, 09 Jan 2012 18:57:31 +040012 2012, 18:57:31
0

Как отмечается в комментарии, это в C # не Java, но идея та же. Я тщательно исследовал эту проблему, и в конечном итоге проблема заключается в том, что FindElement всегда возвращает исключение, когда элемент не существует. Не существует перегруженной опции, которая позволяет вам получить значение null или что-то еще. Вот почему я предпочитаю это решение другим.

  1. Возврат списка элементов и проверка того, что размер списка равен 0, работает, но при этом вы теряете функциональность. Вы не можете сделать .click () для коллекции ссылок, даже если размер коллекции равен 1.
  2. Вы можете утверждать, что элемент существует, но часто это останавливает ваше тестирование. В некоторых случаях у меня есть дополнительная ссылка, чтобы щелкнуть в зависимости от того, как я попал на эту страницу, и я хочу щелкнуть по ней, если она существует, или перейти к другому.
  3. Это только медленно, если вы не установите тайм-аут driver.Manage (). Timeouts (). ImplicitlyWait (TimeSpan.FromSeconds (0));
  4. Это действительно очень простой и элегантный способ создания метода. Используя FindElementSafe вместо FindElement , я не «вижу» уродливый блок try /catch и могу использовать простой метод Exists . Это будет выглядеть примерно так:

    IWebElement myLink = driver.FindElementSafe(By.Id("myId"));
    if (myLink.Exists)
    {
       myLink.Click();
    }
    

Вот как вы расширяете IWebElement & IWebDriver

IWebDriver.FindElementSafe

    /// <summary>
    /// Same as FindElement only returns null when not found instead of an exception.
    /// </summary>
    /// <param name="driver">current browser instance</param>
    /// <param name="by">The search string for finding element</param>
    /// <returns>Returns element or null if not found</returns>
    public static IWebElement FindElementSafe(this IWebDriver driver, By by)
    {
        try
        {
            return driver.FindElement(by);
        }
        catch (NoSuchElementException)
        {
            return null;
        }
    }

IWebElement.Exists

    /// <summary>
    /// Requires finding element by FindElementSafe(By).
    /// Returns T/F depending on if element is defined or null.
    /// </summary>
    /// <param name="element">Current element</param>
    /// <returns>Returns T/F depending on if element is defined or null.</returns>
    public static bool Exists(this IWebElement element)
    {
        if (element == null)
        { return false; }
        return true;
    }

Вы можете использовать полиморфизм для изменения экземпляра класса IWebDriver класса FindElement, но это плохая идея с точки зрения обслуживания.

ответил Brantley Blanchard 5 PM00000070000001631 2013, 19:06:16
0

Это работает для меня каждый раз:

    if(!driver.findElements(By.xpath("//*[@id='submit']")).isEmpty()){
        //THEN CLICK ON THE SUBMIT BUTTON
    }else{
        //DO SOMETHING ELSE AS SUBMIT BUTTON IS NOT THERE
    }
ответил Amstel Bytes 17 J0000006Europe/Moscow 2014, 06:19:54
0

вы можете сделать утверждение.

см. пример

driver.asserts().assertElementFound("Page was not loaded",
By.xpath("//div[@id='actionsContainer']"),Constants.LOOKUP_TIMEOUT);

Вы можете использовать это, это родное:

public static void waitForElementToAppear(Driver driver, By selector, long timeOutInSeconds, String timeOutMessage) {
    try {
      WebDriverWait wait = new WebDriverWait(driver, timeOutInSeconds);
      wait.until(ExpectedConditions.visibilityOfElementLocated(selector));
    } catch (TimeoutException e) {
      throw new IllegalStateException(timeOutMessage);
    }
  }
ответил Ran Adler 3 J0000006Europe/Moscow 2013, 15:16:36
0

Я расширил реализацию Selenium WebDriver, в моем случае HtmlUnitDriver, чтобы предоставить метод

public boolean isElementPresent(By by){}

вот так:

  1. проверьте, загружена ли страница в течение периода ожидания.
  2. После загрузки страницы я неявно ожидаю время ожидания WebDriver до нескольких миллисекунд, в моем случае 100 мельниц, вероятно, должно работать и с 0 мельницами.
  3. call findElements (By), WebDriver, даже если не найдет элемент, будет ждать только количество времени сверху.
  4. верните обратно время неявного ожидания будущей загрузки страницы

Вот мой код:

import java.util.concurrent.TimeUnit;
import org.openqa.selenium.By;
import org.openqa.selenium.JavascriptExecutor;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.htmlunit.HtmlUnitDriver;
import org.openqa.selenium.support.ui.ExpectedCondition;
import org.openqa.selenium.support.ui.WebDriverWait;

public class CustomHtmlUnitDriver extends HtmlUnitDriver {

    public static final long DEFAULT_TIMEOUT_SECONDS = 30;
    private long timeout = DEFAULT_TIMEOUT_SECONDS;

    public long getTimeout() {
        return timeout;
    }
    public void setTimeout(long timeout) {
        this.timeout = timeout;
    }

    public boolean isElementPresent(By by) {
        boolean isPresent = true;
        waitForLoad();
        //search for elements and check if list is empty
        if (this.findElements(by).isEmpty()) {
            isPresent = false;
        }
        //rise back implicitly wait time
        this.manage().timeouts().implicitlyWait(timeout, TimeUnit.SECONDS);
        return isPresent;
    }

    public void waitForLoad() {
        ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
            public Boolean apply(WebDriver wd) {
                //this will tel if page is loaded
                return "complete".equals(((JavascriptExecutor) wd).executeScript("return document.readyState"));
            }
        };
        WebDriverWait wait = new WebDriverWait(this, timeout);
        //wait for page complete
        wait.until(pageLoadCondition);
        //lower implicitly wait time
        this.manage().timeouts().implicitlyWait(100, TimeUnit.MILLISECONDS);
    }   
}

Использование:

CustomHtmlUnitDriver wd = new CustomHtmlUnitDriver();
wd.get("http://example.org");
if (wd.isElementPresent(By.id("Accept"))) {
    wd.findElement(By.id("Accept")).click();
}
else {
    System.out.println("Accept button not found on page");
}
ответил Lotzy 29 Maypm14 2014, 19:54:03
0

Напишите следующий метод с использованием Java:

protected boolean isElementPresent(By by){
        try{
            driver.findElement(by);
            return true;
        }
        catch(NoSuchElementException e){
            return false;
        }
    }

Вызовите вышеуказанный метод во время утверждения.

ответил Ripon Al Wasim 16 MaramMon, 16 Mar 2015 10:03:05 +03002015-03-16T10:03:05+03:0010 2015, 10:03:05
0
String link = driver.findElement(By.linkText(linkText)).getAttribute("href")

Это даст вам ссылку, на которую указывает элемент.

ответил user1549161 19 WedEurope/Moscow2012-12-19T23:52:19+04:00Europe/Moscow12bEurope/MoscowWed, 19 Dec 2012 23:52:19 +0400 2012, 23:52:19
0

С версией 2.21.0 selenium-java.jar вы можете сделать это;

driver.findElement(By.id("...")).isDisplayed()
ответил nu1silva 25 AMpWed, 25 Apr 2012 11:39:17 +040039Wednesday 2012, 11:39:17
0

Насколько я понимаю, это стандартный способ использования веб-драйвера.

ответил Pål Brattberg 29 J0000006Europe/Moscow 2011, 17:21:59

Похожие вопросы

Популярные теги

security × 330linux × 316macos × 2827 × 268performance × 244command-line × 241sql-server × 235joomla-3.x × 222java × 189c++ × 186windows × 180cisco × 168bash × 158c# × 142gmail × 139arduino-uno × 139javascript × 134ssh × 133seo × 132mysql × 132