Selenium - Error handling without throwing exception - selenium

I am trying to Delete a object on the screen and once it's gone check if it's still in the webpage to make sure it's gone.
By doing this :
WebElement objectToDelete = GetElementFromDriver("object-to-delete");
objectToDelete.delete(); //in some other way which results in it being gone.
objectToDelete = GetElementFromDriver("object-to-delete");
I've tried surrounding it with try & catch but I keep getting an exception.
Ex:
try{
objectToDelete = GetElementFromDriver("object-to-delete");
} catch(Exception e){
return null;}
What am I missing? Is it even possible to do what I want, perhaps in a different way?
Thanks!!
If needed I'll add my chrome/driver/selenium versions although I believe they're not relevant.

Did you try WebDriverWait "until" and "until_not" methods ?
Eg: http://selenium-python.readthedocs.io/waits.html.

The solution -
public static boolean isElementPresent throws Exception(String elementName, WebElement father){
try{
Utils.GetElementFromElement(By.className(elementName), 5, father);
return true;
} catch(NoSuchElementException e){
return false;
}
}

Related

WebDriverEventListener take screenshot onException()

guys. Today I have done my custom realization for WebDriverEventListener. I need only onException() method which will create screenshot. But I got problem because I am using fluent wait.
new FluentWait<>(webDriver)
.withTimeout(Duration.ofSeconds(10))
.pollingEvery(Duration.ofMillis(500))
.ignoring(NoSuchElementException.class)
.until(someCondition)
So, finally, I have got screen for each ignoring(NoSuchElementException.class) - 20 screenshots for 1 fail ))). Had somebody the such problem or had someone resolve it?
when you use .ignoring(NoSuchElementException.class) you don't avoid that the exception is raised, you are just ignoring that exception. What is happening is that the exception is being raised by your FluentWait, but it is ignored (when you declare .ignoring(NoSuchElementException.class)).
You have three options here:
Capture the screen at the end of your test if the test failed [preferred].
Have a Try-Catch wherever you are using your FluentWait or any other Selenium code.
Use reflection to avoid capture when the event is raised from the method that implements the FluentWait.
This is an idea after what we have discussed:
private void ExceptionThrown(object sender, WebDriverExceptionEventArgs e)
{
if (e.ThrownException is NoSuchElementException)
{
// Get the stack trace from the current exception
StackTrace stackTrace = new StackTrace(e.ThrownException, true);
// Get the method stack frame index.
int stackTraceIndex = stackTrace.FrameCount - 1;
// Get the method name that caused the exception
string methodName = stackTrace.GetFrame(stackTraceIndex).GetMethod().Name;
if(methodName != "MyFindElement")
{
TakeSceenshot();
}
}
else
{
TakeSceenshot();
}
}
// This is an extension method of the DriverHelper interface
public IWebElement MyFindElement(this IWebDriver driver, By by, int timeOut = 0)
{
var wait = new WebDriverWait(driver, TimeSpan.FromSeconds(timeOut));
wait.IgnoreExceptionTypes(typeof(NoSuchElementException));
// I wait until the element exist
IWebElement result = wait.Until(drv => drv.FindElement(by) != null);
// it means that the element doesn't exist, so we throw the exception
if(result == null)
{
MyPersonalException(by);
}
}
// The parameter will help up to generate more accurate log
public void MyPersonalException(By by)
{
throw new NoSuchElementException(by.ToString());
}
This probably require changes in EventFiringWebDriver, because this class is without WebDriverWait instance and events for them. If you want avoid it, create bool variable in your EventFiringWebDriver extended class and check this value in your OnException like:
protected void OnException(WebDriverExceptionEventArgs e) {
if (IsWaitHandler)
return;
Your actions...
}
but this is not perfect solution.

Selenium webdriver throwing timeout exception

I am new to Selenium.
My issue is that I'm trying to click an element but Selenium is throwing a timeout exception, even if I increase the timeout value.
Do I need to use xpath instead of id?
The HTML Code is:
My code looks like this
void searchquotation() throws TimeoutException {
try {
WebDriverWait wait = new WebDriverWait(driver, 15);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.name("SearchButton")));
element.click();
}
catch(TimeoutException e) {
System.out.println("Timeout occured");
}
Am I doing anything wrong?
The input type here is submit (by looking at your HTML code) so I would strongly advise to try the submit() function of Selenium.
Instead of By.name, you should use By.id instead. Therefore, use either of these:
By.Id("SearchButton")
By.CssSelector("input#SearchButton")
By.Xpath("//input[#id='SearchButton']")
Note: syntax could be wrong, please adjust depending on your programming language
try below code, even timeout exception occurs, it will try 4 time to click on it. assuming locator is correct By.name("SearchButton")
public void searchquotation()
int count=0;
while(count<4)
{
try {
WebElement x = driver.findElement(By.name("SearchButton")));
WebDriverWait element=new WebDriverWait(driver,15);
element.until (ExpectedConditions.presenceOfElementLocated(By.name("SearchButton")));
x.click();
count=count+4;
}
catch(TimeoutException e) {
count=count+1;
System.out.println("Timeout occured");
continue;
}
}

If Xpath is not found my script not moving to other test cases and stop everything and exit. I am using selenium testng frame work

//getElementByXPath function for static xpath
public WebElement getElementByXPath(String Key){
try{
//This block will find element using Key value from web page and return It.
return driver.findElement(By.xpath(Object.getProperty(Key)));
}catch(Throwable t){
//If element not found on page then It will return null.
Add_Log.debug("Object not found for key --"+Key);
return null;
}
}
Here when some element is not found, my script stop and exit. But I want it just give me error so I can use it in test result and move to next test case.
I recommned using a webelement variable to store the result and then define return it... Sorry im not good at Java.
Some thing like this.
//getElementByXPath function for static xpath
public WebElement getElementByXPath(String Key){
try{
//This block will find element using Key value from web page and return It.
WebElement xpathElem = driver.findElement(By.xpath(Object.getProperty(Key)));
if(xpathElem != null)
{
return xpathElem;
}
else
{
Add_Log.debug("Object not found for key --"+Key);
return null;
}
}catch(Throwable t){
//If element not found on page then It will return null.
Add_Log.debug("Object not found for key --"+Key);
return null;
}
}
As you are using try/catch, when ever exception is came it is handled by catch block. if you want to throw this same exception after log statement then you can try like this
public WebElement getElementByXPath(String Key){
try{
//This block will find element using Key value from web page and return It.
return driver.findElement(By.xpath(Object.getProperty(Key)));
}catch(Throwable t){
//If element not found on page then It will return null.
Add_Log.debug("Object not found for key --"+Key);
//error message is thrown as exception which will appear in testng reports generally if you are using
throw new Exception(t.getMessage());
}
}

Check if a WebElement is stale without handling an exception

I'm currently checking to see if a WebElement is stale by doing the following:
public static boolean isStale(WebElement element) {
try {
element.click();
return false;
} catch (StaleElementReferenceException sere) {
return true;
}
}
This is the same as the solution offered to this question:
Check for a stale element using selenium 2?
However, this seems rather messy to me. Is there a cleaner way that I can check if an element is stale, without having to throw and catch an exception?
(Also, as a side, if I have to stick with throwing and catching an exception, is there something better to do than clicking/sending keys/hovering to throw said exception? I might have a WebElement that I don't want to do any of these actions on, as it may inadvertently affect something else.)
Webdriver itself uses the try/catch-construction to check for staleness as well.
from org.openqa.selenium.support.ui.ExpectedConditions.java:
public static ExpectedCondition<Boolean> stalenessOf(final WebElement element) {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver ignored) {
try {
// Calling any method forces a staleness check
element.isEnabled();
return false;
} catch (StaleElementReferenceException expected) {
return true;
}
}
#Override
public String toString() {
return String.format("element (%s) to become stale", element);
}
};
}
The isEnabled() check is better than using a click action - clicking an element might cause unwanted side effects, and you just want to check the element's state.
I know this already has an accepted answer and I don't know the bigger context of how you use the staleness check but maybe this will help you or others. You can have ExpectedConditions.stalenessOf(WebElement) do the work for you. For example,
WebElement pageElement = driver.findElement(By.id("someId"));
WebDriverWait wait = new WebDriverWait(webDriver, 10);
// do something that changes state of pageElement
wait.until(ExpectedConditions.stalenessOf(pageElement));
In this case, you don't have to do pageElement.click(), etc. to trigger the check.
From the docs, .stalenessOf() waits until an element is no longer attached to the DOM.
References: ExpectedConditions
Classic statement for C# to check staleness of web element
protected bool IsStale
{
get { return ExpectedConditions.StalenessOf(webElement)(WebDriver); }
}
I don't fully understand what you want to do. What do you mean by 'messy' solution?
Maybe you can use an explicite wait an as expected condition stalenessOf in combination with not.
But every solution with that don't seems stable to me.
What I do is, that I have an clicking routine in a helperclass, the idea is like:
public void ClickHelper(WebDriver driver, By by){
int counter = 1;
int max = 5;
while (counter <= max) {
try {
WebElement clickableWebElement = driver.findElement(by);
clickableWebElement.click();
return;
} catch (StaleElementReferenceException e) {
System.out.print("\nTry " + counter + " with StaleElementReferenceException:\n" + e.getMessage() + "\n");
}
versuche++;
}
throw new RuntimeException("We tried " + max + " times, but there is still an Exception. Check Log!");
}
Be careful, I just entered this by simplyfying my own methode (there are some more checks and personally I use xpath and not by etc). There might be some typo-mistakes, but i guess you will understand the basic idea. Since I use this Helpermethode, I don't have to care about Staleness of webelements. You can alter the max-value, but personally I think, if the website is such unstable, that the Element is stale so much, I would talk to the developer, because this would not be a good website.
This should work without dependency of display/ enabled:
def is_element_on_page(element):
try:
element.get_attribute('')
return True
except StaleElementReferenceException:
return False

isElementPresent is very slow in case if element does not exist.

I am using below code to check for element on my web page
private boolean isElementPresent(By by) {
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
}
catch (Exception e)
{
return false;
}
}
I need to check in my program if a particular region appears in result as below
isElementPresent(By.xpath(".//*[#id='header']")));
If this is present this function completes quickly but if above is not present then it run for very long.
Could some one please help me in resolving this issue so that this check can be performed quickly?
Here you are missing somethings that is why it is waiting If there is not element. findElement will wait for an element implicitly specified time. so need to set that time to zero in that method.
isElementPresent(WebDriver driver, By by) {
driver.manage().timeouts().implicitlyWait(0, TimeUnit.SECONDS);
try {
driver.findElement(by);
return true;
} catch (NoSuchElementException e) {
return false;
} finally {
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
}
}
There are 4 important things going on here. In order:
Setting implicity_wait to 0 so that WebDriver does not implicitly wait.
Returning True when the element is found.
Catching the NoSuchElementException and returning False when we discover that the element is not present instead of stopping the test with an exception.
Setting implicitly_wait back to 30 after the action is complete so that WebDriver will implicitly wait in future.
Apparently, it's long to send the exception because your DOM is big and the xpath isn't the fastest way to get an element. But if you want to use xpath, try to put the best path and avoid that kind of function where is substring checking.
Your actual xpath : .//*[#id='header'] takes so long because you check all tags of your DOM. So if put the tag that what you're looking for, example : you want to catch an input. your xpath should start like that //input[#id='1234'] and it will be shorter than looking all tags.