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) { }
}
}
Related
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;
}
});
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();
}
I am using below code:
public static void main(String[] args)
{System.setProperty("webdriver.gecko.driver","C:\\geckodriver-v0.17.0-win64\\geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://www.makemytrip.com/flights");
driver.manage().timeouts().implicitlyWait(10,TimeUnit.MILLISECONDS);
driver.manage().window().maximize();
driver.findElement(By.id("hp-widget__sfrom")).click();
driver.findElement(By.id("hp-widget__sfrom")).clear();
List<WebElement> Cities = driver.findElements(By.xpath("//div[#class='autoCompleteItem']"));
for (WebElement size1 : Cities )
{
String str = size1.getText();
System.out.println(str);
if(size1.getText().equals("LON"))
{
size1.click();
break;
}
else
{
System.out.println("match not found");
}
}
}
}
Use below code :
driver.get("https://www.makemytrip.com/flights");
driver.findElement(By.id("hp-widget__sfrom")).click();
driver.findElement(By.id("hp-widget__sfrom")).clear();
try {
Thread.sleep(2000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
driver.findElement(By.id("hp-widget__sfrom")).sendKeys("LON");
List<WebElement> Cities = driver.findElements(By.xpath("//div[#class='autoCompleteItem']//span[contains(.,'London, UK - All Airports')]"));
for (WebElement size1 : Cities )
{
String str = size1.getText();
if(size1.getText().equalsIgnoreCase("London, UK - All Airports"))
{
System.out.println(size1.getText());
size1.click();
break;
}
else
{
System.out.println("match not found");
}
}
}
}
If your value in below in dropdown then need to focus that element first.
if you only wants to check for text then you could simple form an xpath and avoid this loop.
try{
WebElement city =driver.findElement(By.xpath("//div[#class='autoCompleteItem' and text()='LON']");
city.click();
}catch (NoSuchElementException ex){
System.out.print("Element not Found");
}
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;
}
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 + "'");
}
}