The below code is written for click function.
public void click(By element) {
try {
driver.findElement(element).click();
}
catch (AssertionError e) {
System.out.println("Element " + element + " not found on page");
return;
}
}
The below code is written for calling the click function in my test case.
#Test(priority = 1)
public void accept_cookies_dialog() throws Exception {
try {
click(By.id(propObjctRepo.getProperty("id_cookieCta")));
} catch (Exception e) {
addErrorlogs(e, "Not found accpet cookie dialog.");
}
}
My concern is, In every case either the element present or not the test case is getting pass. I am doing something wrong, Please suggest me the solution.
Instead of using try/catch block, you can directly use assertions to check if the element is present on the page or not. If the list size of the element is greater than zero then the element is present on the page else it is not. By this, if the element is not present on the page, assertion will fail and so will the test case.
You can do it like:
Assert.assertTrue(driver.findElements(By.id(propObjctRepo.getProperty("id_cookieCta"))).size()>0);
And then below this you can click the element, so if and only if the assertion passes, your code will reach the click method else your test case will fail.
Related
I write a code where I have found the result element visible or not, but I have received an exception.
org.openqa.selenium.NoSuchElementException: no such element: Unable to locate element: {"method":"xpath","selector":".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']"}
Here is my code
wd.navigate().refresh();
Thread.sleep(7000);
boolean airbnb = wd.findElement(By.xpath(".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']")).isDisplayed();
assertFalse(airbnb, "Airbnb Add will not show After clicking Add one times");
Is there any suggestion why element not found showing? if element not found then it should be false I am not sure where I mistake?
To avoid an exception, and expensive use of try - catch, you can locate the element using findElements. If the result list is not empty you can check if the existed element is displayed or not
List<WebElement> elements = wd.findElements(By.xpath(".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']"));
assertFalse(elements.size() > 0 && elements.get(0).isDisplayed(), "Airbnb Add will not show After clicking Add one times");
Either use try- catch block or use throws Exception to catch the NoSuchElementException
public void methodName() throws Exception
{
if(wd.findElement(By.xpath(".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']")).isDisplayed())
{
System.out.println("Element displayed");
}
}
or
try
{
if(wd.findElement(By.xpath(".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']")).isDisplayed())
{
System.out.println("Element displayed");
}
}
catch(NoSuchElementException e)
{
System.out.println("Element is not displayed");
}
Since you do not expect the element to be there the following code would throw an exception :
boolean airbnb = wd.findElement(By.xpath(".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']")).isDisplayed();
and your assert statement would not even be reached.
You can actually place an expected exception in your code instead of asserting as(in Junit):
#Test(expected = NoSuchElementException.class)
public void youtTest() {
// do whatever you're doing
Thread.sleep(7000);
wd.findElement(By.xpath(".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']"));
}
in TestNG the syntax is somehwat like :
#Test(expectedExceptions = { NoSuchElementException.class })
This is the issue with Selenium, you need to use try catch block something like below
try
{
if(wd.findElement(By.xpath(".//*[#class='airbnb-wide-block-search-btn js-airbnb-search-btn']")).isDisplayed())
{
//Your code
}
}
catch (Exception e)
{
//Your code
}
Let me put it this way: IsDisplayed will work on Object of Type WebElement.
here is the clarification
findElement should not be used to look for non-present elements, use findElements(By) and assert zero length response instead.
found on findElement
I'm getting NoSuchElementException when running the following code.
if (driver.findElement(By.xpath("//*[#id='gr2']")).isDisplayed()) {
Thread.sleep(5000);
driver.findElement(By.xpath("//*[#id='balInqTableStep2']/td/table/tbody/tr/td/table/tbody/tr[3]/td[4]/input[2]")).click();
}
else {
test.log(LogStatus.FAIL,"Please configure Gift Slabs for this site. Contact business.");
test.log(LogStatus.FAIL,"Second time wallet credit is not done");
}
NoSuchElementException exception means there is not element present on the page.
isDisplayed method assumes that element is already present on the page and so throws you exception when element is not present.
you can either make sure that element is present before calling webdriver method and you can write your own method to handle this for you.
following code snippet might help you
public boolean isDisplayed(By identifier){
boolean isElementDisplayed = false;
try{
WebElement element = driver.findElement(identifier);
isElementDisplayed = element.isDisplayed()
}catch (NoSuchElementException){
return false;
}
return isElementDisplayed;
}
and you can call it like this
isDisplayed(By.xpath("//*[#id='gr2']")
Always when you call driver.findElement(By.xpath("//*[#id='gr2']")) and the element is not present in the DOM, it's gonna throw a NoSuchElementException.
There is an alternative to avoid the code throwing the exception, calling the method findElements, instead of findElement.
E.g.:
List<WebElement> elements = driver.findElements(By.xpath("//*[#id='gr2']"));
if(!elements.isEmpty() && elements.get(0).isDisplayed()) {
Thread.sleep(5000);
driver.findElement(By.xpath("//*[#id='balInqTableStep2']/td/table/tbody/tr/td/table/tbody/tr[3]/td[4]/input[2]")).click();
}
else {
test.log(LogStatus.FAIL,"Please configure Gift Slabs for this site. Contact business.");
test.log(LogStatus.FAIL,"Second time wallet credit is not done");
}
Hope it works for you.
I am trying to fill up a dynamic from which is automatically generated with user info. So I want to set if else condition for field of the from. So i use if else loop in step defenition but suppose if condition true its ok the code excute but if "if condition fail the code stuck in else loop why.Please help
The code is below
#And("^Input Height in add report$")
public void Input_Height_in_add_report(DataTable newHeight) throws Throwable {
if(driver.findElement(By.xpath("//label//span[contains(text(),'Height')]")).isDisplayed()){
Thread.sleep(2000);
List<List<String>> data = newHeight.raw();
driver.findElement(By.xpath("/html/body/div[1]/div/div/div[2]/form/div[7]/div[1]/div/div/input")).sendKeys(data.get(1).get(1));
}
else{
}
}
The problem is that if findElement finds the element it goes if statement but if it doenst find the element it gives NosuchElementFound exception. To handle this yo can use try-catch block to run code in the else, check the following:
#And("^Input Height in add report$")
public void Input_Height_in_add_report(DataTable newHeight) throws Throwable {
try {
if(driver.findElement(By.xpath("//label//span[contains(text(),'Height')]")).isDisplayed()){
Thread.sleep(2000);
List<List<String>> data = newHeight.raw();
driver.findElement(By.xpath("/html/body/div[1]/div/div/div[2]/form/div[7]/div[1]/div/div/input")).sendKeys(data.get(1).get(1));
}
}
catch(Exception e) {
// your else code should be here
}
}
I'm using if/else statements as below, but the script fails in Selenium WebDriver. Here, for one test case the if statement works but, for another test case, the else one doesn't.
if (driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--top")).isDisplayed()){
driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--top")).click();
}
else
{
driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--bottom")).click();
}
Im not good at Java, so im putting the steps. Give try.
1. First Find elements seperately.
2. Now check if 'top' is not null and then check for is displayed and can continue further .Pseudo code below
IWebElement top= driver.findelement( put you locator top here )
IWebElement bottom = driver.findelement( put you bottom here)
if(top!=null)
{
if(top.IsDisplayed)
{
top.click()
}
}
else
{
if(bottom!=null)
{
bottom.click()
}
}
we need to click on element "div.Tooltip__body.Tooltip__body--top" if it is displayed. if not then need to click on "div.Tooltip__body.Tooltip__body--bottom"
If we use .isDisplayed to check element displayed or not, in any case element is not there, it will throw exception. that's why we need to handle this exception by using try/catch.
try{
//if element is displayed, then click it
if (driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--top")).isDisplayed()==true){
driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--top")).click();
}
}catch(Exception e){
//exception occurred as element (top) is not available.
//so i need to click on bottom
driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--bottom")).click();
//if required we can collect exception : e.getMessage()
}
Thanks
try
{
if (driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--top")).isDisplayed()==true)
driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--top")).click();
}
catch(Exception ex)
{
driver.findElement(By.cssSelector("div.Tooltip__body.Tooltip__body--bottom")).click();
}
i have a webpage with several element to be tested.
They are more than 100 and i could not write 100 code to test one element.
Is it possible to use switch case to test the element i want and not all.
For example here i have 3 tests to be executed, what i want is to test only Test1 and Test2, how can i do this using switch case in java, because i have more than 100 tests to be executed, i want to use only one code.
Thank you
//TEST1
try {
driver.findElement(By.xpath(CmpList._google)).isDisplayed();
System.out.println("Google Tab exists");
driver.findElement(By.xpath(CmpList._google)).click();
} catch (NoSuchElementException e) {
System.out.println("TEST FAILED--Google Tab element does not exist");
} finally {
System.out.println("Continue");
}
//TEST2
try {
driver.findElement(By.xpath(CmpList._radio)).isDisplayed();
System.out.println("Radio Tab element exists");
driver.findElement(By.xpath(CmpList._radio)).click();
} catch (NoSuchElementException e) {
System.out.println("TEST FAILED--Radio Tab element does not exist");
} finally {
System.out.println("Continue");
}
//TEST3
try {
driver.findElement(By.xpath(CmpList._yahoo)).isDisplayed();
System.out.println("Google Tab exists");
driver.findElement(By.xpath(CmpList._yahoo)).click();
} catch (NoSuchElementException e) {
System.out.println("TEST FAILED--Yahoo Tab element does not exist");
} finally {
System.out.println("Continue");
}
int[] testsToTest = {1,2, 45, ...};
int currentTest;
for(int i = 0; i < testsToTest; i++){
currentTest = testsToTest[i];
Switch (currentTest){
case 1:
//your first test
break;
case 2:
//second test
break;
...
case 100;
//100th test
break;
default: System.out.println("unknown test");
}
}
That'll at least get you off the ground. There's definitely a nicer way to write this here, I shutter to think how long your file will become. perhaps you could use a more generic method since you're basically testing element x, and either clicking x or saying "x failed". Consider having a map of test numbers and xpaths. for example:
public boolean testElement(String xpath){
try {
WebElement element = driver.findElement(By.xpath(xpath)).isDisplayed();
element.click();
} catch (NoSuchElementException e) {
System.out.println("TEST FAILED--element with xpath " + xpath + " does not exist");
} finally {
System.out.println("Continue");
}
}
And then you could have a hashmap of testNumbers and their xpath. Then it would just be a matter of iterating over the list as above, but instead of the switch, it would just be
testElement(testMap.get(testToTest[i]))
As far as I can see the only thing that changes is the XPath and the message you are printing.
It's not clear from your code, but if you're not using a test framework like JUnit or TestNG, then you should be.
JUnitParams is a good candidate for this as it offers a way to pass a collection of parameters to a test method and execute it many times. Each execution is treated as a separate test, without the need to write repetitive code. If the first test fails, it will continue to run the other tests.
One example usage (there are many options):
#Test
#Parameters({
CmpList._radio,
CmpList._yahoo,
.... })
public void shouldFindElement(String xpath) {
driver.findElement(By.xpath(xpath)).isDisplayed();
driver.findElement(By.xpath(CmpList._radio)).click();
}
Personally, I don't think you should catch the Exception as is not expected. I also think that you print statements introduce noise.