I used below code and found that TRY block is not working for the situation when element is not present :
try
{
var actual = new WebDriverWait(m_WebDriver, TimeSpan
.FromSeconds(5))
.Until(ExpectedConditions
.ElementIsVisible(By.XPath(XpathUnderTest)))
.Displayed;
return actual;
}
catch (Exception ex)
{
return false;
}
I have a use-case where presence of Webelement is depend on other conditions so it is not present or visible all the time on webpage. If element is present then it's working and if element is not present then Try catch is not able to handle the scenario using you above code.
I also tried : bool isPresent = Driver.Findelements.(xpath).Count() > 0; // list
but it is not working as well if element is not present
As per your code block it's the right behavior as WebDriverWait with ElementIsVisible is correct.
As per the documentation, ExpectedConditions with ElementIsVisible will return the IWebElement once it is located and visible. In case the ExpectedConditions fails a Boolean value is returned back.
As in your try block you are defining :
var actual;
And trying to :
return actual;
So, irespective of the return from ExpectedConditions with ElementIsVisible your try block returns False Positive.
Solution :
WebDriverWait with ExpectedConditions must be implemented outside any Try-Catch block. Next steps can be decided with respect to the return type.
Related
I am using headless mode with ChromeDriver.
I find an element by calling
var name= Driver.FindElement(By.Id("TestLabelName"));
if (name== null)
{
}
The issue here is that if the element is not present it just exceptions and stops and doesnt do the null check.
Is there a way to return either the element or just null ?
Or return the console window data without having to wrap every FindElement around a try catch ?
Use FindElements instead of FindElement.
findElements will return an empty list if no matching elements are found instead of an exception.
Text copied from: Test if element is present using Selenium WebDriver?
Also you can write a static method that looks for an element:
public static IWebElement _FindElement(ChromeDriver inCromeDriver, string inNameElementId)
{
try
{
var name = inCromeDriver.FindElement(By.Id(inNameElementId));
return name;
}
catch (System.Exception ex)
{
System.Console.WriteLine(ex);
return null;
}
}
I've searched quite a bit on this topic on the stack and other places.
When I run driver.FindElements(By.myselector) my browser waits 60 seconds to time out. Instead of returning an empty list as described by the documentation
( https://www.selenium.dev/documentation/en/getting_started_with_webdriver/locating_elements/ ). It seems to be a great solution to work around an element possibly being in the DOM.
I need to check for the possible existence of loading icons/gifs. When the icons are present I need to wait until they are gone. When the icons are not there I need the method to fail to find MUCH faster than 60 seconds so I can let the script continue to test. The loading icon's appearance is not always predictable.
Is there a way to
Make an individual operation fail quickly?
Get FindElements() to return an empty list instead of failing after 60 seconds?
Get around unpredictable DOM blocking loading icons another way?
Examples of code I have tried:
Find if any elements are returned. Originally had a loop to keep checking if empty. If not Thread.Sleep() then reassign and check for existence again. Waits 60 seconds to fail.
public static IWebElement FindElementIfExists(ChromeDriver _driver, By by)
{
ReadOnlyCollection<IWebElement> elements = _driver.FindElements(by);
return (elements.Count >= 1) ? elements[0] : null;
}
This code works when the loading icon shows up, but Selenium waits 60 seconds and fails on
OpenQA.Selenium.WebDriverException: 'The HTTP request to the remote WebDriver server for URL timeout after 60 seconds when the icon is
not in the DOM.
public static bool isElementDisplayed(ChromeDriver _driver, By aSelector)
{
try
{
// WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(4));
wait.Until(ExpectedConditions.ElementIsVisible(aSelector));
return _driver.FindElement(aSelector).Displayed;
}
catch (Exception ex)
{
if (ex is NoSuchElementException || ex is StaleElementReferenceException || ex is TimeoutException)
{
return false;
}
else
{
throw ex;
}
}
}
public static void WaitForElementToBeGone(ChromeDriver _driver, By aSelector, int timeout)
{
if (isElementDisplayed(_driver, aSelector))
{
new WebDriverWait(_driver, TimeSpan.FromSeconds(timeout)).Until(ExpectedConditions.StalenessOf(_driver.FindElement(aSelector)));
}
}
Thanks again
I am implementing Selenium Page Object Pattern in my Automation Framework and the website which is going to test again is little unstable
So, basically I want to extend Selenium FindsBy Class and add specific attribute to this which allows a webelement to be tracked multiple times until it is actually found..
To explain it better :
[FindsBy(How = How.CssSelector, Using = "li.config-btn button[class *= 'configure icon-settings']")]
private IList<IWebElement> SettingsButton;
On the backend, there is my custom logic handling the waitandretry attribute
What is the most proper way of doing it?
Since FindsBy Class are sealed, you can not inherit it, so how could I extend the FindsBy Functionality and implement my stuffs?
So ,basically what i need is
[FindsByNew(How = How.CssSelector, Using = "li.config-btn button[class *= 'configure icon-settings']", WaitRetry = 3)]
private IList<IWebElement> SettingsButton;
Is there anything, they are already providing which am unaware of?
Thanks in Advance
I don't know how to extend the FindsBy class and I'm not sure if it's the best solution for your problem. I'm using a fluent wait method to achieve what you are looking for. Here's an example for clicking on a webelement where four type of exceptions are ignored for a certain waittime. When the element is not found after this waittime a TimeOutException is thrown.
public static void WaitAndClick(this IWebDriver driver, IWebElement webelement)
{
var fluentWait = new WebDriverWait(driver, Configuration.WaitTime);
fluentWait.Until(webDriver =>
{
try
{
webelement.Click();
}
catch (Exception ex)
{
if (ex is TargetInvocationException ||
ex is NoSuchElementException ||
ex is InvalidOperationException ||
ex is ElementNotVisibleException)
{
return false; //The function will rerun.
}
{
throw; //Throw exception if it's not a type to be ignored.
}
}
return true;
});
}
I am trying to make an if statement so I can use my code in multiple situations.
When i try to assert displayed or enable I get in some situations an exception Iwebelement could not be found.
I want to make a statement that if element exist 'x' should happen and when element does not exist 'y' should happen.
As mentioned I tried Displayed, Enabled. I also tried asserFalse but that also didnt gave me the required result.
It was asked for code but I only need a if statement that let something true if element exist otherwise should skip it. When I do
if (element.Displayed)
{
}
But in some cases I get an exception and I dont want the exception
is this in a TestNG or JUnit test?
I would usually handle this in a normal case inside the if statement:
pseudocode:
if(exists(x)){
assertTrue(....);
}
else{
assertFalse(....);
}
Search for multiple elements and even if one exists (>0), then return true, otherwise, non of the elements with a specific By exist.
bool ElementExists()
{
return driver.FindElements(By.Id("your locator")).Count > 0;
}
Then just do
bool ElementExists(By locator)
{
TimeSpan originalWait = driver.Manage().Timeouts().ImplicitWait;
driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(0);
bool exists = driver.FindElements(locator).Count > 0;
driver.Manage().Timeouts().ImplicitWait = originalWait;
return exists;
}
if(ElementExists(By.Id("your locator")))
{
//Do Stuff
}
else
{
//Do Stuff when element does not exist
}
Edit: Also reduce your implicit wait to 0 seconds so you don't wait long for your bool to return (the webdriver will wait for the element to appear as long as you told).
Your approach will work only when the element is displayed or exists , if not it will throw the exception and you are not handling that, so the script is failing for you.
You can create a method like below by handling the exception(I have written it in java , please make the required changes).
public static Boolean isElementDisplayed(WebDriver driver, By element) {
try {
driver.findElement(element).isDisplayed();
System.out.println("Element is displayed");
return true;
} catch (NoSuchElementException | ElementNotVisibleException e) {
System.out.println("Element not displayed");
return false;
}
}
And you can use the above method in you test cases 'n' number times like this.
if(isElementDisplayed(driver, By.xpath("locator")){
//do what you have to do if element is exists
}else{
//do what you have to do if element is not exists
}
Hope this will solve your problem
We have a .NET 4.5, MVC, C# project. We're using Selenium for UI tests, and the tests keep intermittently failing on lines that we have wait.Until(). One such example is:
NoSuchElementException was unhandled by user code
An exception of type 'OpenQA.Selenium.NoSuchElementException' occurred in WebDriver.dll but was not handled in user code
Additional information: Unable to locate element: {"method":"css selector","selector":"#assessment-472 .status-PushedToSEAS"}
It's thrown right here:
Thread.Sleep(600);
wait.Until(drv => drv.FindElement(By.CssSelector("#" + assessmentQueueId + " .status-PushedToSEAS")));
I can see that the browser opens, I see it get to that point, and I can inspect element to see that the element exists. Its id is exactly correct.
We have this problem A LOT and so far the solution has been to throw Thread.Sleep(600) (or some similar time) in front of it. The whole point of wait.Until() is to not have to do that, and this is making our test suites get very long. Also, as you can see in the example above, sometimes we have the problem even after putting a Thread.Sleep() in front of it and we have to extend the time.
Why is .NET Selenium's WebDriver.Until() not working, and is there a different way to do the same thing without just waiting a set period of time? Again, the problem is intermittent, meaning that it only happens sometimes, and it could happen at any number of wait.Until() statements, not just the one shown!
Edit:
This is a class variable.
private WebDriverWait wait;
It is instantiated like this:
this.wait = new WebDriverWait(driver, TimeSpan.FromSeconds(10));
I decided to just not use WebDriverWait.Until(), and use implicit waits on the main driver instead:
driver.Manage().Timeouts().ImplicitlyWait(TimeSpan.FromSeconds(10));
I give full credit to this answer on a different question for giving me the idea.
public static IWebElement FindElement(this IWebDriver driver, By by, int timeoutInSeconds)
{
try
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds));
return wait.Until(drv => drv.FindElement(by));
}
return driver.FindElement(by);
}
catch
{
throw;
}
}
or if you are having
NoSuchElementException
try this code
try
{
if (timeoutInSeconds > 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeoutInSeconds)).Until(ExpectedConditions.ElementIsVisible(by));
}
return driver.FindElement(by);
}
catch(Exception e)
{
throw;
}