Утверждают, что WebElement отсутствует, используя Selenium WebDriver с java

В тестах, которые я пишу, если я хочу подтвердить, что WebElement присутствует на странице, я могу сделать просто:

driver.findElement(By.linkText("Test Search"));

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

EDIT Вот как я придумал свое собственное исправление, мне интересно, есть ли еще лучший выход.

public static void assertLinkNotPresent (WebDriver driver, String text) throws Exception {
List<WebElement> bob = driver.findElements(By.linkText(text));
  if (bob.isEmpty() == false) {
    throw new Exception (text + " (Link is present)");
  }
}

person True_Blue    schedule 19.07.2010    source источник


Ответы (14)


Не уверен, какую версию селена вы имеете в виду, однако некоторые команды в селене * теперь могут это делать: http://release.seleniumhq.org/selenium-core/0.8.0/reference.html

  • УтвердитьNotSomethingSelected
  • ассертекстноптресент

И т.д..

person Andre    schedule 17.02.2012
comment
Ссылка битая сейчас - person Andrejs; 16.09.2016
comment
Исходная проблема OP, по-видимому, указывает на то, что было создано исключение, когда элемент отсутствует. - person DMart; 12.06.2017

Это проще сделать:

driver.findElements(By.linkText("myLinkText")).size() < 1
person Sarhanis    schedule 30.11.2012
comment
Спасибо, это кажется лучшим подходом даже для привязок, отличных от Java. - person Dmitry Koroliov; 01.03.2013
comment
Это, безусловно, лучший ответ, чтобы избежать исключения, вызванного findElement. - person DMart; 12.06.2017
comment
Хорошее решение. Однако это пытается найти элемент в течение timeout секунд. Таким образом, вы можете установить (а затем сбросить) тайм-аут драйверов. Возможно в методе. - person DerMike; 20.04.2018

Я думаю, что вы можете просто поймать org.openqa.selenium.NoSuchElementException, который будет выброшен driver.findElement, если такого элемента нет:

import org.openqa.selenium.NoSuchElementException;

....

public static void assertLinkNotPresent(WebDriver driver, String text) {
    try {
        driver.findElement(By.linkText(text));
        fail("Link with text <" + text + "> is present");
    } catch (NoSuchElementException ex) { 
        /* do nothing, link is not present, assert is passed */ 
    }
}
person Sergii Pozharov    schedule 20.07.2010
comment
хорошая идея. Хотя это странно, в веб-драйвере нет механизма для обработки такого рода утверждений. - person DevDave; 10.07.2012
comment
чтобы сделать это более генетическим, вы можете передать By.id/cssSelector и т.д. вместо String Text. - person Dave; 10.01.2013
comment
Хотя это работает, я не думаю, что это идеально. Если у вас настроен веб-драйвер с неявным ожиданием, тест станет очень медленным. - person Hugo; 23.04.2013
comment
это действительно не рекомендуется, это замедлит ваше тестирование и может быть источником трудно обнаруживаемых ошибок: - если элемент отсутствует (наиболее распространенный), ваш тест будет каждый раз ожидать неявного ожидания - если элемент есть есть, но он исчезает, неявное ожидание не будет использоваться, и ваш тест немедленно завершится неудачно, ложное срабатывание. - person Benja; 16.07.2015
comment
Из-за неявной проблемы с ожиданием за это нужно сильно отказаться. - person Ben George; 23.12.2015

Существует класс под названием ExpectedConditions:

  By loc = ...
  Boolean notPresent = ExpectedConditions.not(ExpectedConditions.presenceOfElementLocated(loc)).apply(getDriver());
  Assert.assertTrue(notPresent);
person Fabian Barney    schedule 10.06.2013
comment
У меня это почему-то не работает (по крайней мере, в Selenium 2.53.0). Вместо этого мне пришлось использовать наличие всех таких элементов: ExpectedConditions.not(ExpectedConditions.presenceOfAllElementsLocatedBy(locator)));. - person stiemannkj1; 20.06.2017
comment
Используя некоторые последние версии Selenium, для этой проверки теперь существует метод под названием invisibilityOfElementLocated. Использование прямолинейно: webDriver.wait(ExpectedConditions.invisibilityOfElementLocated(xpath("<xpath expression>"))) - person Waize; 11.03.2019

Попробуй это -

private boolean verifyElementAbsent(String locator) throws Exception {
    try {
        driver.findElement(By.xpath(locator));
        System.out.println("Element Present");
        return false;

    } catch (NoSuchElementException e) {
        System.out.println("Element absent");
        return true;
    }
}
person some_other_guy    schedule 01.10.2012
comment
Подозреваю, что это не сработает. Я использую привязки Perl и пытался использовать этот подход, и проблема заключалась в том, что экземпляр драйвера умирал, когда элемент не был найден. Не уверен, что то же самое происходит с Java. - person Dmitry Koroliov; 01.03.2013

С Selenium Webdriver будет примерно так:

assertTrue(!isElementPresent(By.linkText("Empresas en Misión")));
person user1732136    schedule 03.10.2013
comment
Лучше просто assertFalse(...) - person DerMike; 20.09.2018

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

Чтобы сохранить хорошую скорость теста, этот пример временно сокращает неявное ожидание, пока элемент не исчезнет:

static final int TIMEOUT = 10;

public void checkGone(String id) {
    FluentWait<WebDriver> wait = new WebDriverWait(driver, TIMEOUT)
            .ignoring(StaleElementReferenceException.class);

    driver.manage().timeouts().implicitlyWait(1, TimeUnit.SECONDS);
    try {
        wait.until(ExpectedConditions.numberOfElementsToBe(By.id(id), 0));
    } finally {
        resetTimeout();
    }
}

void resetTimeout() {
    driver.manage().timeouts().implicitlyWait(TIMEOUT, TimeUnit.SECONDS);
}

Все еще ищу способ полностью избежать тайм-аута...

person df778899    schedule 04.10.2017

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

Graphene.element(By.linkText(text)).isPresent().apply(driver));

Он также предоставляет вам кучу хороших API для работы с Ajax, плавными ожиданиями, объектами страницы, фрагментами и так далее. Это определенно значительно упрощает разработку тестов на основе Selenium.

person Petr Mensik    schedule 28.06.2013

Для node.js я нашел следующий эффективный способ дождаться исчезновения элемента:

// variable to hold loop limit
    var limit = 5;
// variable to hold the loop count
    var tries = 0;
        var retry = driver.findElements(By.xpath(selector));
            while(retry.size > 0 && tries < limit){
                driver.sleep(timeout / 10)
                tries++;
                retry = driver.findElements(By.xpath(selector))
            }
person QualiT    schedule 25.05.2016
comment
Ваш код может попасть в бесконечный цикл, если элемент не исчезает - person algot; 19.06.2017
comment
Отличный момент. Исправлено. Я не собираюсь добавлять обработку ошибок. - person QualiT; 20.06.2017

Не ответ на сам вопрос, а, возможно, идея для основной задачи:

Когда логика вашего сайта не должна отображать определенный элемент, вы можете вставить невидимый элемент «флаг», который вы проверяете.

if condition
    renderElement()
else
    renderElementNotShownFlag() // used by Selenium test
person DerMike    schedule 20.09.2018

Ниже приведен пример использования Selenium «until.stalenessOf» и утверждения Jasmine. Он возвращает true, когда элемент больше не привязан к DOM.

const { Builder, By, Key, until } = require('selenium-webdriver');

it('should not find element', async () => {
   const waitTime = 10000;
   const el = await driver.wait( until.elementLocated(By.css('#my-id')), waitTime);
   const isRemoved = await driver.wait(until.stalenessOf(el), waitTime);

   expect(isRemoved).toBe(true);
});

Для справки: Selenium: до документа

person Miroslav Savovski    schedule 01.05.2019

Способ, который я нашел лучшим, а также показать в отчете Allure как неудачный, - это попытаться поймать элемент поиска и в блоке catch установить для assertTrue значение false, например:

    try {
        element = driver.findElement(By.linkText("Test Search"));
    }catch(Exception e) {
        assertTrue(false, "Test Search link was not displayed");
    }
person Amr El Massry    schedule 07.05.2020

findElement проверит источник html и вернет true, даже если элемент не отображается. Чтобы проверить, отображается ли элемент или нет, используйте -

private boolean verifyElementAbsent(String locator) throws Exception {

        boolean visible = driver.findElement(By.xpath(locator)).isDisplayed();
        boolean result = !visible;
        System.out.println(result);
        return result;
}
person some_other_guy    schedule 01.10.2012

Для appium 1.6.0 и выше

    WebElement button = (new WebDriverWait(driver, 10).until(ExpectedConditions.presenceOfElementLocated(By.xpath("//XCUIElementTypeButton[@name='your button']"))));
    button.click();

    Assert.assertTrue(!button.isDisplayed());
person DrPatience    schedule 29.11.2016
comment
лучше напрямую assertFalse(...) - person DerMike; 20.09.2018