Using assertTrue() to validate the presence of text in selenium - java

I want to validate the presence of a text using assertTrue(), but I am getting a StackOverflow error. I am not sure that the code I have written is correct or not. Need your suggestions.
// Checking the posted text
WebElement postedtext= driver.findElement(By.cssSelector("css123"));
assertTrue("The text is verfied",postedtext.getText().equals(enteredText));
private static void assertTrue(String string, boolean equals) {
assertTrue(string,equals);}

You have a method called assertTrue(s, b) which calls itself. This is causing an infinite recursion.

It is a name conflicting that you happened to name you assert method the same name as the library method. Rename your assertTrue can solve the problem.
// Checking the posted text
WebElement postedtext= driver.findElement(By.cssSelector("css123"));
myAssertTrue("The text is verfied",postedtext.getText().equals(enteredText));
private static void myAssertTrue(String string, boolean equals) {
try {
assertTrue(string,equals);
} catch (AssertionError e) {
System.out.println(e.getMessage());
throw e;
}
}
Or you just delete your assertTrue and use the library method instead.

Related

Amazon login and logout scenario using selenium webdriver

I am new to selenium.
I am trying to automate amazon login and log out.
I am facing couple of problems.
1.In login page the button "continue" appears after username when I try to login for first time.
But later when I try to login for second time , its does not appear.
How to handle this.
Here is the code I have written so far:
public void logindetails()
{
Datafile d=new Datafile("C:\\Users\\kirruPC\\selenium divers\\Data.xlsx",0);
String uname= d.username(0, 0);
WebElement u=driver.findElement(useid);
u.sendKeys(uname);
u.click();
if(driver.findElement(By.xpath(".//*[#id='continue']")).isDisplayed()==true)
{
driver.findElement(By.id("continue")).click();
String psw=d.pass(0,1);
driver.findElement(password).sendKeys(psw);
}
else
{
String psw=d.pass(0,1);
driver.findElement(password).sendKeys(psw);
}
}
Unable to locate sign Out element.
Below is the code I have written to move to sign out link and click:
public void logout() throws Exception
{
Actions a= new Actions(driver);
WebElement ele=driver.findElement(By.xpath(".//*[#id='nav-link-accountList']"));
a.moveToElement(ele).build().perform();
driver.findElement(By.xpath(".//*[#id='nav-al-your-account']"));
Thread.sleep(3000);
driver.findElement(By.xpath(".//*[#id='nav-al-your-account']/a[22]")).click();
}
Please help me
Thanks in advance
First of all, there is a high change that the element you are searching for might not exist at all in the page, so first let's check if the element exist (if the element does not exist, an exception is thrown, so let's add a handle for that as well). For all that, create a function like so:
public bool ElementExists(By locator)
{
try
{
driver.findElement(locator);
//If no exception is thrown here, element exists, so return true
return true;
}
catch (NoSuchElementException ex)
{
return false;
{
}
Now that we have a function that can safely check if an element exists without getting an exception, you can use it to determine if you will run the code handling the element.
Function isDisplayed() already returns a bool, so checking equality with true is not necessary.
if(ElementExists(By.xpath(...)).isDisplayed())
{
if(driver.findElement(By.xpath(".//*[#id='continue']")).isDisplayed())
{
driver.findElement(By.id("continue")).click();
}
}
//The code below will run either way, so move it out of the if statement
String psw=d.pass(0,1);
driver.findElement(password).sendKeys(psw);
As for the second part of your question, your code can be simplified by just, searching for the element and then clicking it like so:
driver.findElement(By.xpath(".//*[#id='nav-al-your-account']/a[22]")).click();
If you will, double-check the xpath or "catch" the element by an ID.

Selenium select class does NOT throw error when it does not find item in the drop down list

I have method to select the item by visible text using Select class. The item I am passing in the parameter is not in the list. I want the test to fail and give me the error no such element found, but the selenium keeps on waiting for the item to appear and does not fail. Is there a way to forcefully fail the test and print the exception.
public static void selectAnItem(String elemetLocator, String itemToSelect){
Select select = new Select(driver.findElement(By.xpath(elemetLocator)));
try {
select.selectByVisibleText(itemToSelect);
} catch (Exception e) {
e.printStackTrace();
}
}
The problem is that you are eating the exception with the try-catch. If you remove that, it should throw the error you are expecting.
One suggestion... rather than passing in a String elementLocator, pass in a By class. That will allow you to use more than just XPaths, e.g.
public static void selectAnItem(By locator, String itemToSelect)
{
new Select(driver.findElement(locator)).selectByVisibleText(itemToSelect);
}
Now you can use By.id(), By.cssSelector(), and so on.

Can isDisplayed() return false without breaking run in Selenium?

I would like to use conditional function using .isDisplayed() method. Everything is working correct as long as this method returns true.
HTML is not required I think here, because I have only one button to be visible on the page, which is correclty found (I successfully clicked the button with the following xpath.
Now I try with:
if (driver.findElement(By.xpath("//a[#id='button1']")).isDisplayed()) {
//do stuff
}
else {
//do other stuff
}
Or even
WebElement withdrawnBtn = driver.findElement(By.xpath("//a[#id='button1']"));
boolean isVisible = withdrawnBtn.isDisplayed();
if (isVisible) {
//do stuff
}
else {
//do other stuff
}
but both conditionals fails, if in the first run there should be executed code from else, because everytime when the button is not available, there is fail pointing on the line with driver.findElement(By.xpath("//a[#id='button1']")).isDisplayed()); - fails, because the button is not displayed. I need t o do something, when the button is not displayed instead failing code...
Before checking isDisplayed conditions we need to check whether element exist on the page or not Otherwise it will throw Nosuchelementfound exception
driver.findElements("Locator").size()-- will return integer value if the element exist on the page.
Below is the fix code.
int size = driver.findElements("Locator").size();
if(size!=0){
if(driver.findElement("Locator").isDisplayed()){
// do operations
}
}
After reading comments, I got to know isEmpty is better way to use instead of size I made changes to the above code.
WebDriver driver;
List<WebElement> webElements = driver.findElements(By.xpath("test"));
if(!webElements.isEmpty()){
if(driver.findElement(By.xpath("test")).isDisplayed()){
// do operations
}
}
Try it and let me know if it works for you
you can also use following to identify if an element exists or not:
private boolean isPresent(WebElement element) {
try {
element;
} catch (NoSuchElementException e) {
return false;
}
return true;
}
OK, I was thinking about catching NoElementFound exception, but I found this issue:
Selenium Webdriver: best practice to handle a NoSuchElementException
using link above I used:
List<WebElement> withdrawnBtn = driver.findElements(By.xpath("//a[#id='button1']"));
if (withdrawnBtn.size() != 0) {
//do stuff
}
else {
//do other stuff
}
Instead of size() method you could use isEmpty() method.

Assertions in selenium with Page Object Factory

How can I use the path/location of a #FindBy variable as an argument to a method?
I have the following #FindBy value in my class...
#FindBy(xpath=".//*[#id='HasAnotherSubsidisedQual_container']")
#CacheLookup WebElement mSubsidisedQual;
I then have a method for checking whether an element exists...
public boolean isElementPresent(By element){
try {
mDriver.findElement(element);
return true;
}
catch (org.openqa.selenium.NoSuchElementException e){
return false;
}
}
I then use that method in another method which contains an assertion
public void checkSmartAndSkilled () {
Assert.assertTrue(isElementPresent(By.xpath(".//*[#id='HasAnotherSubsidisedQual_container']")));
}
This all works fine, however instead of specifying By.xpath... etc in the assertion, is there anyway to pass in as an argument the path for my #FindBy WebElement mSubsidisedQual?
Many thanks
You do not need to provide the xpath again. Once it is initialized by Page Factory, simply pass the element as an argument.
public void checkSmartAndSkilled () {
Assert.assertTrue(isElementPresent(mSubsidisedQual));
}
You just created a wrong method. And the way you check element existence is wrong. But if you want to do it this way then what you should do is to overload it so the parameter is your element.
Then call the element (for example click, or use its property like Enable, or Count or Length or whatever is available in Java) and if the element doesn't exist it will catch the same error. If it exists then return true.

Method retake in Java

I'm developing a project in which i have a method to know if a JTextField is empty or not, but i was wondering if a way to implement that method just once and send several JTextFields components to check if they are empty or not exists, if so, could you please tell me how?, here's my sample code.
public static void Vacio(JTextField txt){
if(txt.getText().trim().equals(null)==true){/*Message*/}
}
Also i would like to know if i could improve the method using some Lambda Expressions, beforehand.
Use :
if(txt.getText().trim().length()==0)
//Do something
Your code will not work because a blank string("") is not a null String. I simply check if the trimmed length() of TextField is 0.
A sample function:
public boolean isEmpty(JTextField jtf)
{
try{
jtf.getText();
}catch(NullPointerException e){return true;}
if(jtf.getText().trim().length() == 0)
return true;
return false;
}
I cannot imagine how adding Lambda expressions can improve what you're trying to do (?).
Anyway, to check for an empty String I'd probably use:
field.getText().trim().isEmpty()
You don't need to check for null but you do need to catch NullPointerException in the event that the underlying document in the JTextField is null.
For the other part of your quesiton, if you really want to check multiple JTextFields in one method you could pass them as a variable length argument list:
public static void vacio(JTextField... fields) {
for(JTextField field : fields) {
try {
if( field.getText().trim().isEmpty() ) {
// do something
}
}
catch(NullPointerException ex) {
// handle exception (maybe log it?)
}
}
}
and call it like:
vacio(field1, field2, field3);
But, generally speaking, keeping functions brief and only doing one thing is usually better than trying to make a function do too much.
One final aside, your method is named Vacio but java naming conventions suggest you should compose method names using mixed case letters, beginning with a lower case letter and starting each subsequent word with an upper case letter.
Check explicitly for null and then compare with "".
public static void Vacio(JTextField txt){
String str = null;
try {
str = txt.getText();
}
catch (NullPointerException npe) {
System.out.println("The document is null!");
return;
}
if(str.trim().equals("")==true){/*Message*/}
}

Categories

Resources