JavaScript button can only be clicked once with selenium Webdriver - java

I am trying to use Selenium with JUnit and I am having trouble completing my tests because it seems like my button execution is only occurring once. here's some of the code:
JQueryUITab navTab = new JQueryUITab(driver.findElement(By.cssSelector("nav ul.tabs")));
try {
navTab.selectTab("Tab1");
} catch (Exception e) {
e.printStackTrace();
}
try {
navTab.selectTab("Tab2");
} catch (Exception e) {
e.printStackTrace();
}
System.out.print(navTab.getSelectedTab());
the console print out will read "Tab1". this JQueryUITab object is a custom object. here are the inner workings:
public String getSelectedTab() {
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab"));
for (WebElement tab : tabs) {
if (tab.getAttribute("class").equals("tab selected")) {
return tab.getText();
}
}
return null;
}
public void selectTab(String tabName) throws Exception {
boolean found = false;
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab"));
for (WebElement tab : tabs) {
if(tabName.equals(tab.getText().toString())) {
tab.click();
found = true;
break;
}
}
if (!found) {
throw new Exception("Could not find tab '" + tabName + "'");
}
}
There are no exceptions thrown. At least pertaining before or at this part of the code.

There were a couple problems wrong with my implementation. Firstly, it could have been improved by selecting not the li.tab object, but the a class inside of it. From there, there were 2 solutions that worked for me. First was using
webElement.sendKeys(Keys.ENTER);
and the second (imho more elegant solution) was to get the instance of the selenium driver object controlling the object and then get it to execute the command to click the tab. Here's the full corrected method.
public void selectTab(String tabName) throws Exception {
boolean found = false;
List<WebElement> tabs = jQueryUITab.findElements(By.cssSelector("li.tab a"));
for (WebElement tab : tabs) {
if(tabName.equals(tab.getText().toString())) {
// tab.sendKeys(Keys.ENTER);
WrapsDriver wrappedElement = (WrapsDriver) jQueryUITab;
JavascriptExecutor driver = (JavascriptExecutor) wrappedElement.getWrappedDriver();
driver.executeScript("$(arguments[0]).click();", tab);
found = true;
break;
}
}
if (!found) {
throw new Exception("Could not find tab '" + tabName + "'");
}
}

Related

Selenium click until the attirbute show

How can I create click method which can be click in the button until the attribute shows? Something like loop until but with timer (if it's not found attribute after 10 seconds, display an error). I have created something like that, but code give me NullPointerException when not found attribute:
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement button = driver.findElement(By.xpath("xpath"));
String attribute = button.getAttribute("disabled");
button.click();
if(attribute .equals("true"))
return true;
else
return false;
}
});
I got similar problem and my solution was to write a function that tries to click on the object and when it is not present it waits a second and tries once again. After 10 times of trying it returns null.
It works beautifully for me. Goes like this:
WebElement tryfind(WebDriver browser, By id)
{
WebElement ttwel=null;
for (int i=0;i<10;i++)
{
try
{
ttwel=browser.findElement(id);
break;
}
catch (NoSuchElementException ex)
{
sleep(1000);
}
}
return ttwel;
}
void sleep(int mills)
{
try
{
Thread.sleep(mills);
}
catch (InterruptedException ex)
{
}
}
You might add waiting for disabled attribute to this method, something like:
for (int i=0;i<10;i++)
{
try
{
ttwel=browser.findElement(id);
String attribute = button.getAttribute("disabled");
if (attribute==null) sleep(1000);
else break;
}
catch (NoSuchElementException ex)
{
sleep(1000);
}
}
Why don't you add a try catch block like this below to catch the NullPointerException and return false in that case
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(30));
wait.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
WebElement button = driver.findElement(By.xpath("xpath"));
try {
String attribute = button.getAttribute("disabled");
button.click();
if (attribute.equals("true")) {
return true;
}
} catch (NullPointerException e) {
return false;
}
return false;
}
});

Creating SQL queries from Query builder

I'm trying to automate query builder, I've managed to create simple queries however unable to create complex or joint queries. The simple query is hardcoded, looking to make it dynamic.
Attaching the image of the query builder for reference. Complex or joint queries to be something like this "StateID = 5 AND STATE = "Bihar"
Below is the code for reference: (simple queries)
public static void selectbyqueries() throws InterruptedException{
String sname=null;
//data queries
//iterate through fields
List<WebElement> rowsList = driver.findElements(By.xpath("//*[contains(#class,'textcolq')]"));
Thread.sleep(1000);
for (WebElement element : rowsList) {
Thread.sleep(500);
try {
sname = element.getText();
if (sname.equalsIgnoreCase("Number")) { //change the data type
Thread.sleep(1000);
element.click();
break;
}
} catch (Exception e) { }
}
driver.findElement(By.xpath("//*[contains(text(),'GET UNIQUE VALUES')]")).click();
//query tools
List<WebElement> query = driver.findElements(By.xpath("//*[contains(#class,'inner-flex ng-star-inserted')]"));
Thread.sleep(1000);
for (WebElement element : query) {
Thread.sleep(500);
try {
sname = element.getText();
//will have to change the tool symbol (stand alone attributes)
if (sname.equalsIgnoreCase("=")) {
highlightclick(element);
Thread.sleep(1000);
element.click();
break;
}
} catch (Exception e) { }
}
//unique values
List<WebElement> unique = driver.findElements(By.xpath("//*[contains(#class,'cursor selected-option ng-star-inserted')]"));
Thread.sleep(1000);
for (WebElement element : unique) {
Thread.sleep(500);
try {
sname = element.getText();
//will
if (sname.equalsIgnoreCase("1")) {
highlightclick(element);
Thread.sleep(1000);
element.click();
break;
}
} catch (Exception e) { }
}
}

Selenium Stale Element Reference Exception

Everytime got StaleElementReferenceException exception.
Here is a method, pls help.
private void selectAndClickRow(String elementName, boolean doubleClick) {
try {
String elementXpath = "//tr//td//div[contains(text(),'" + elementName + "')]";
new WebDriverWait(Init.getWebDriver(), Init.getTimeOutInSeconds()).until(ExpectedConditions.visibilityOf(Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath(elementXpath))));
WebElement row = table.findElements(By.xpath(elementXpath)).get(0);
row.click();
if (doubleClick) {
row.click();
}
Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath("//tr//td[contains(#class,'selected')]//div[contains(text(),'" + elementName + "')]"));
} catch (StaleElementReferenceException e) {
freeze(1);
selectAndClickRow(elementName, doubleClick);
}
waitToLoad();
}
public WebElement waitUntilElementAppearsInDom(By by) {
Wait wait = new WebDriverWait(Init.getWebDriver(), (long)Init.getTimeOutInSeconds());
wait.until(ExpectedConditions.presenceOfElementLocated(by));
return Init.getWebDriver().findElement(by);
}
I already added an element research and waiting for a second. It doesn't help.
I guess, you are trying to double click on a element. You can use actions class as given below instead of clicking twice on a element.
private void selectAndClickRow(String elementName, boolean doubleClick) {
try {
String elementXpath = "//tr//td//div[contains(text(),'" + elementName + "')]";
new WebDriverWait(Init.getWebDriver(), Init.getTimeOutInSeconds()).until(ExpectedConditions.visibilityOf(Init.getDriverExtensions().waitUntilElementAppearsInDom(By.xpath(elementXpath))));
WebElement row = table.findElements(By.xpath(elementXpath)).get(0);
new Actions(driver).doubleClick(row).perform();
} catch (StaleElementReferenceException e) {
//freeze(1);
//selectAndClickRow(elementName, doubleClick);
}
waitToLoad();
}

How to click on mail using selenium webdriver?

I want to open the mail by clicking on it, after receiving the activation mail.
For that I am using keyword driven framework.
So can anyone please let me know that how can we click on element without using List<>.
Because in my coding structure I am returning the object of Webelement instead of List<> object.
Note: Please suggest the solution without using JavaMail Api or if suggest please let me know according to the keyword driven framework.
Way of code structure where I find the elements in one method and in another method after getting an element perform the operations:
private boolean operateWebDriver(String operation, String Locator,
String value, String objectName) throws Exception {
boolean testCaseStep = false;
try {
System.out.println("Operation execution in progress");
WebElement temp = getElement(Locator, objectName);
System.out.println("Get Element ::"+temp);
driver.manage().timeouts().implicitlyWait(5, TimeUnit.SECONDS);
//For performing click event on any of the button, radio button, drop-down etc.
if (operation.equalsIgnoreCase("Click")) {
temp.click();
}
/*Trying to click on subject line of "Email"*/
if (operation.equalsIgnoreCase("Click_anElement")) {
Thread.sleep(6000L);
Select select = new Select(temp);
List<WebElement> options= select.getOptions();
for(WebElement option:options){
System.out.println(option.getText());
}
/*try
{
if(temp.getText().equals(value)){
temp.click();
}
}
catch(Exception e){
System.out.println(e.getCause());
}*/
/*if (value != null) {
temp.click();
}*/
}
}
testCaseStep = true;
} catch (Exception e) {
System.out.println("Exception occurred operateWebDriver"
+ e.getMessage());
System.out.println("Taking Screen Shot");
TakesScreenshot ts=(TakesScreenshot)driver;
File source=ts.getScreenshotAs(OutputType.FILE);
FileUtils.copyFile(source, new File("./Screenshots/"+screenshotName+".png"));
System.out.println("Screenshot taken");
}
return testCaseStep;
}
public WebElement getElement(String locator, String objectName) throws Exception {
WebElement temp = null;
System.out.println("Locator-->" + locator);
if (locator.equalsIgnoreCase("id")) {
temp = driver.findElement(By.id(objectName));
} else if (locator.equalsIgnoreCase("xpath")) {
temp = driver.findElement(By.xpath(objectName));
System.out.println("xpath temp ----->" + temp);
} else if (locator.equalsIgnoreCase("name")) {
temp = driver.findElement(By.name(objectName));
}else if (locator.equalsIgnoreCase("cssSelector")) {
temp = driver.findElement(By.cssSelector(objectName));
}
return temp;
}

If it can't be null, but it needs to be initialized, what do I make it?

I have a problem accessing some of my xpaths. We use a hybrid testing framework.
public class logoutMenu {
public static void run(WebDriver driver) {
Properties prop = new Properties();
InputStream selectproductsidebarobjectrepository;
try {
selectproductsidebarobjectrepository = new FileInputStream(
"C:/thisisthepath/ObjectRepositories/SignInPageObjectRepository");
prop.load(selectproductsidebarobjectrepository);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement logoutNormal = driver.findElement(By.xpath(prop.getProperty("logoutnormal")));
Actions actions = new Actions(driver);
actions.moveToElement(logoutNormal).build().perform();
WebElement logoutHover = driver.findElement(By.xpath(prop.getProperty("logouthover")));
logoutHover.click();
WebElement logoutPushed = driver.findElement(By.xpath(prop.getProperty("logoutpushed")));
logoutPushed.click();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (selectproductsidebarobjectrepository != null) {
try {
selectproductsidebarobjectrepository.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}
ORIGINAL PROBLEM:
It tells me that the xpath cannot be accessed if it is null. It's null because of this line: InputStream selectproductsidebarobjectrepository = null;. If I take away the = null; part of it, I get a different error: "The local variable selectproductsidebarobjectrepository may not have been initialized" which also makes sense.
What can I make selectproductsidebarobjectrepository equal to that isn't null?
NEW ISSUE:
Cleaned up the code. Got rid of the null. Got rid of the extra bracket. Still coming up as:
java.lang.IllegalArgumentException: Cannot find elements when the XPath expression is null.
at org.openqa.selenium.By.xpath(By.java:113)
at SelectProductSidebar.logoutMenu.run(logoutMenu.java:29)
at CommonFunctions.FunctionCheck.test(FunctionCheck.java:19)
Here is the script that calls this class:
public class FunctionCheck {
#Test
public void test() throws Exception {
WebDriver driver;
String baseUrl;
driver = new FirefoxDriver();
baseUrl = "http://www.MATTDAMON.com/";
driver.get(baseUrl + "MATT/MATT/MATT/MATT");
Thread.sleep(3000);
LoginPage.enterValidCredentials.run(driver);
SelectProductSidebar.logoutMenu.run(driver);
In case I'm screwing up a lot more than I initially though (probably true), here is the text file selectproductsidebarobjectrepository:
logoutnormal=//img[contains(#src,'log_out_normal')]
logouthover=//img[contains(#src,'log_out_hover')]
logoutpushed=//img[contains(#src,'log_out_pushed')]
I'm probably doing something really stupid but I'm absolutely blind to what it is right now.
This works fine for me after removing the extra brace.
public class logoutMenu {
public static void run(WebDriver driver) {
Properties prop = new Properties();
InputStream selectproductsidebarobjectrepository;
try {
selectproductsidebarobjectrepository = new FileInputStream(
"C:/thisisthepath/ObjectRepositories/SignInPageObjectRepository");
prop.load(selectproductsidebarobjectrepository);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
WebElement logoutNormal = driver.findElement(By.xpath(prop.getProperty("log_out_normal")));
Actions actions = new Actions(driver);
actions.moveToElement(logoutNormal).build().perform();
WebElement logoutHover = driver.findElement(By.xpath(prop.getProperty("log_out_hover")));
logoutHover.click();
WebElement logoutPushed = driver.findElement(By.xpath(prop.getProperty("log_out_pushed")));
logoutPushed.click();
} catch (IOException ex) {
ex.printStackTrace();
} finally {
if (selectproductsidebarobjectrepository != null) {
try {
selectproductsidebarobjectrepository.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
}

Categories