Я написал несколько тестовых примеров в Selenium WebDriver с помощью Java и выполнил их в сетке (концентратор и несколько узлов). Я заметил, что несколько тестов из-за NoSuchElementException
не работают. Каков наилучший и надежный способ избежать NoSuchElementException
и убедиться, что элемент всегда найден?
Каков наилучший способ избежать исключения NoSuchElementException в Selenium?
Ответ 1
Вы никогда не можете быть уверены, что элемент будет найден, на самом деле это цель функциональных тестов - сообщить вам, если что-либо изменилось на вашей странице. Но одна вещь, которая определенно помогает, заключается в добавлении ожиданий элементов, которые часто вызывают NoSuchElementException
как
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.id<locator>));
Ответ 2
Я полностью согласен с Петром Менсиком выше. Вопрос, который вы никогда не можете сказать, присутствует ли элемент. Вы должны четко понимать, почему, когда это происходит. По моему опыту, я должен сказать, что это происходит по следующим причинам:
- 1) Страница все еще отображается, и вы уже закончили свой поиск элементов и исключение исключений элемента.
- 2) Вторая причина - AJAX еще не вернулась, и вы уже
получить
NoSuchElementException
- 3) Третий наиболее очевидный: элемент на самом деле не на странице всякий раз, когда.
поэтому наиболее надежный метод IMHO для обработки всех этих трех условий с использованием одного вызова функции - использовать fluentWait
, как предлагал Amith003.
поэтому код должен быть следующим:
пусть ур-элемент имеет локатор:
String elLocXpath= "..blablabla";
WebElement myButton= fluentWait(By.xpath(elLocXpath));
myButton.click();
public WebElement fluentWait(final By locator){
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(org.openqa.selenium.NoSuchElementException.class);
WebElement foo = wait.until(
new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
}
);
return foo;
};
Также, если ваша цель - надежный перенос кода fluentWait()
с блоком try{} catch{}
.
Также не забывайте о
public boolean isElementPresent(By selector)
{
return driver.findElements(selector).size()>0;
}
что также полезно.
Итак, чтобы завершить все упомянутое, если вы хотите избежать исключения NoElement
, просто обработайте его должным образом, поскольку никто не может гарантировать наличие элемента на странице.
Надеюсь, теперь вам станет понятнее. Отношения
Ответ 3
вы также можете использовать FluentWait
,
Каждый экземпляр FluentWait
определяет максимальное время ожидания условия, а также частоту проверки условия.
Кроме того, пользователь может настроить wait для игнорирования определенных типов исключений во время ожидания, например NoSuchElementExceptions
при поиске элемента на странице.
// Waiting 30 seconds for an element to be present on the page, checking
// for its presence once every 5 seconds.
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, SECONDS)
.pollingEvery(5, SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(By.id("foo"));
}
});
Ответ 4
WebDriverWait wait = new WebDriverWait(webDriver, timeoutInSeconds);
wait.until(ExpectedConditions.elementToBeClickable(By.id<locator>));
elementToBeClickable ожидает Включить и Видимый элемента
Ответ 5
public WebElement fluientWaitforElement(WebElement element, int timoutSec, int pollingSec) {
FluentWait<WebDriver> fWait = new FluentWait<WebDriver>(driver).withTimeout(timoutSec, TimeUnit.SECONDS)
.pollingEvery(pollingSec, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class, TimeoutException.class);
for (int i = 0; i < 2; i++) {
try {
//fWait.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("//*[@id='reportmanager-wrapper']/div[1]/div[2]/ul/li/span[3]/i[@data-original--title='We are processing through trillions of data events, this insight may take more than 15 minutes to complete.']")));
fWait.until(ExpectedConditions.visibilityOf(element));
fWait.until(ExpectedConditions.elementToBeClickable(element));
}
catch (Exception e) {
System.out.println("Element Not found trying again - " + element.toString().substring(70));
e.printStackTrace();
}
}
return element;
}
Ответ 6
Я обычно использую эту строку в основной функции
public static void main(String[] args) throws ParseException {
driver= new ChromeDriver();
driver.manage().window().maximize();
**driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);**
Надеюсь, что это поможет.
Ответ 7
Мы можем применить ниже коды для удаления этого условия исключения
-
Применяя WebDriverWait, объект webdriver ждет определенное время (во втором) элемента для его видимости.
WebDriverWait wait = new WebDriverWait(driver, 10); wait.until(ExpectedConditions.visibilityOf(link));
-
Мы можем обрабатывать NoSuchElementException через блок try-catch внутри Generic method
public boolean isElementPresent(By by) { boolean isPresent = true; try { driver.findElement(by); } catch (NoSuchElementException e) { isPresent = false; } return isPresent }
http://selenium-code.blogspot.in/2017/08/selenium-exception-nosuchelementexcepti.html
Ответ 8
Иногда можно дождаться загрузки нужного элемента.
driver.get("https://zzzzzzzzz.market/items/mirage_prime_set")
WebDriverWait(driver, 20)
.until(
EC.visibility_of_element_located(
(By.XPATH, ('//div[@class="orders-row__element order__price sell_color"]')
)))
Иногда вам нужно что-то сделать, чтобы среда пользовательского интерфейса загружала данные. Например, страница прокрутки
driver.execute_script("window.scrollTo(0, document.body.scrollHeight);")
А затем получить необходимые данные
responsetext=driver.page_source
from lxml import html
parsed_body = html.fromstring(responsetext)
obj1 = parsed_body.xpath('.//div[@class="orders-row__element order__price sell_color"]/span[1]')
print(len(obj1))