Java: Trying to get the value of an HTML element - java

I am trying to extract the value of an HTML table element from a website and compare it to a user input value but it seems that the nested loop is not being entered when I run the program. It works with no errors but I am not getting any output from Eclipse, I'm new to Selenium Java and still learning.
See my code below:
String inputString = basePrem;
try {
//Print to console the value of Base Prem
WebElement table = driver.findElement(By.xpath(".//td[text()='Base Premium']/following-sibling::*"));
List<WebElement> allrows = table.findElements(By.tagName("tr"));
List<WebElement> allcols = table.findElements(By.tagName("td"));
for (WebElement row: allrows) {
List<WebElement> Cells = row.findElements(By.tagName("td"));
for (WebElement Cell:Cells) {
if (Cell.getText().contains(basePrem)) {
System.out.print("Base Premium = "+ basePrem + " ");
}
else if (!Cell.getText().contains(basePrem))
{
System.out.print("Base Premium = " + basePrem + " ");
break;
}
}
}
}
catch (Exception e) {
errorMessage = "Value discrepancy";
System.out.println(errorMessage + " - " + e.getMessage());
driver.close();
}
Also, inputString is where I input the value I use for comparison (I use a separate excel file for testing)
Since the control is not going inside the nested loop, I probably have some logical error?

You can rewrite the code as below and then validate whether your inputstring is available in the table. It is not necessary to use nested for loops
Code:
String inputString = basePrem;
WebElement table = driver.findElement(By.xpath(".//table"));
//Extract all the Cell Data Element
List<WebElement> dataElementList=table.findElements(By.xpath(".//td"));
for(WebElement dataElement : dataElementList){
if(dataElement.getText().contains(inputString)){
System.out.print("Base Premium = "+ basePrem + " ");
break;
}
}

Related

getText from select ul

HTML code image
I need getText from the li to validate correct option is visible.
I have try 3 different option but none of they work correctly.
I need 'boundlist-selected' class get text this will validate selected text.
Have comment out output inside the code.
public void DDList(WebDriver driver, String actualViews,String ReportName) throws InterruptedException {
waitForElementPresent(driver, 30, expand_btn1);
Thread.sleep(1000);
By ddlselect = By.xpath("//div[input[#name='"+ReportName+"']]/following-sibling::div");
waitForElementPresent(driver, 30, ddlselect,ReportName);
click(driver,ddlselect,ReportName);
Thread.sleep(2000);
waitForLoad(driver, 60);
By ddlexpand = By.xpath("//ul/li[text()='"+actualViews+"']");
waitForElementPresent(driver, 30, ddlexpand ,actualViews);
click(driver,ddlexpand,actualViews);
Thread.sleep(2000);
//try 1
WebElement textlabel = driver.findElement(By.xpath("//li[contains(#class,'boundlist-selected')]"));
value = textlabel.getAttribute("value");
System.out.println("getAttribute value" + value); // value Ouput 0
//try 2
String textlabel2 = driver.findElement(By.xpath("//li[contains(#class,'boundlist-selected')]")).getText();
System.out.println(textlabel2 + "print text"); // blank output
// try 3
List<WebElement>allProduct = driver.findElements(By.xpath("//ul[#class='x-list-plain']/li"));
for( WebElement product : allProduct){
System.out.println(product.getText());
// This print correctly all 3 value now I need to validate select text how can I do that?
}
// below code to validate select gets fail as value is blank
if (value.equals(actualViews)) {
Reporter.log(
"Successfully able to select " + actualViews + "option from dashboard" +ReportName+ "summary screen");
Add_Log.info(
"Successfully able to select " + actualViews + "option from dashboard" +ReportName+ "summary screen");
} else {
Assert.fail();
Reporter.log("Not able to select " + actualViews + "option from dashboard" +ReportName+ "summary screen");
Add_Log.info("Not able to select " + actualViews + "option from dashboard" +ReportName+ "summary screen");
}
Try code below:
//try 1
String selectedText = driver.findElement(By.cssSelector("li.x-boundlist-selected")).getText();
System.out.println(selectedText)
//try 2
selectedText = driver.findElement(By.cssSelector("li.x-boundlist-selected")).getAttribute("textContent");
System.out.println(selectedText)

Looping a list through a column in webdriver

If I'm expecting a page to display 5 offers, how would I tell webdriver to list all those 5 offers in a ul?
The Ul html code is
<ul id="more-load" class="product_list_widget pagination-centered" style="padding-top:15px;">
I think you would use
List<WebElement> allElements = driver.findElements(By.xpath("//div[#id='more-load']/ul/li"));
for (WebElement element: allElements) {
System.out.println(element.getText());
}
but I'm not sure how to print each individual offer in the Ul and match the 5 offers expected to be displayed
EDITED CODE
never mind used this and worked
WebElement allElements = driver.findElement(By.id("more-load"));
List<WebElement> liElements = allElements.findElements(By.tagName("li"));
for (int i = 0; i < liElements.size(); i++)
{
System.out.println("-------------------------------------------------------");
System.out.println(liElements.get(i).getText());
}
however if I have a column on the left side, with ul = product categories, how would I loop it to go through each individual link text and preform the same function
Let's say your 5 offers are as below:
Offer1
Offer2
Offer3
Offer4
Offer5
now your approach is correct till for loop:
then you can do something like :
String offerString = Offer1 + " " + Offer2 + " " + Offer3 + " " + Offer4 + " " + Offer5;
for (WebElement element: allElements) {
if(offerString.contains(element.getText()){
System.out.println("Offer item is: " + element.getText());
}
}
Stick with your original attempt, except change the line:
List<WebElement> allElements = driver.findElements(By.xpath("//div[#id='more-load']/ul/li"));
to
List<WebElement> allElements = driver.findElements(By.xpath("//ul[#id='more-load']/li"));
using java8:
List<String> offers = driver
.findElements(By.cssSelector("#more-load li"))
.stream()
.map(WebElement::getText)
.collect(Collectors.toList());
and you can assert offers.size() to have some expected value by any assert library
To get linked text elements in UL you can use next selector:
driver.findElements(By.cssSelector("ul a"))

Java program closing before Scanner can take input 2nd time around

I am experimenting with JSoup, and I cannot get my 2nd go-around with my Scanner to work. It skips directly to my catch statement.
Here is a description of the program:
I take a google search term as user input (String). Next, I ask for the number of query items that the user wishes to see, and enter an integer.
I loop through each element that is returned and add it to an ArrayList. The String displayed on the console consists of an index, Link Text, and a hyperlink.
I then want to ask the user which index they would like to enter to open a browser window leading to that link. This is done by cocantenating the hRef string with the Linux terminal command "xdg-open " using the Runtime class.
It works great up until it's time to ask which index will be chosen.
Here is my code:
/**
* Created by christopher on 4/26/16.
*/
import java.io.IOException;
import java.util.ArrayList;
import java.util.Scanner;
import org.jsoup.Jsoup;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
public class GoogleSearchJava {
static int index;
static String linkHref;
static Scanner input;
public static final String GOOGLE_SEARCH_URL = "https://www.google.com/search";
public static void main(String[] args) throws IOException {
//GET INPUT FOR SEARCH TERM
input = new Scanner(System.in);
System.out.print("Search: ");
String searchTerm = input.nextLine();
System.out.print("Enter number of query results: ");
int num = input.nextInt();
String searchURL = GOOGLE_SEARCH_URL + "?q=" + searchTerm + "&num=" + num;
//NEED TO DEFINE USER AGENT TO PREVENT 403 ERROR.
Document document = Jsoup.connect(searchURL).userAgent("Mozilla/5.0").get();
//OPTION TO DISPLAY HTML FILE IN BROWSWER. DON'T KNOW YET.
//System.out.println(doc.html());
//If google search results HTML change the <h3 class="r" to <h3 class ="r1"
//need to change below stuff accordingly
Elements results = document.select("h3.r > a");
index = 0;
String news = "News";
ArrayList<String> displayResults = new ArrayList<>();
for (Element result : results) {
index++;
linkHref = result.attr("href");
String linkText = result.text();
String pingResult = index + ": " + linkText + ", URL:: " + linkHref.substring(6, linkHref.indexOf("&")) + "\n";
if (pingResult.contains(news)) {
System.out.println("FOUND " + "\"" + linkText + "\"" + "NO HYPERTEXT FOR NEWS QUERY RESULTS AT THIS TIME. SKIPPED INDEX.");
System.out.println();
} else {
displayResults.add(pingResult);
}
}
for(String urlString : displayResults) {
System.out.println(urlString);
}
System.out.println();
goToURL(input, displayResults);
}
public static int goToURL(Scanner input, ArrayList<String> resultList) {
int newIndex = 0;
try {
System.out.print("Enter Index (i.e. 1, 2, etc) you wish to visit, 0 to exit: ");
newIndex = input.nextInt();
input.nextLine();
for (String string : resultList) {
if(string.startsWith(String.valueOf(newIndex))) {
Process process = Runtime.getRuntime().exec("xdg-open " + string.substring(6, string.indexOf("&")));
process.waitFor();
}
}
} catch (Exception e) {
System.out.println("ERROR while parsing URL");
}
return newIndex;
}
}
HERE IS THE OUTPUT Notice how it stops after I enter "1" No, I haven't taken care of pressing "0" yet:
Search: Oracle
Enter number of query results: 3
1: Oracle | Integrated Cloud Applications and Platform Services, URL:: =http://www.oracle.com/
2: Oracle Corporation - Wikipedia, the free encyclopedia, URL:: =https://en.wikipedia.org/wiki/Oracle_Corporation
3: Oracle on the Forbes America's Best Employers List, URL:: =http://www.forbes.com/companies/oracle/
Enter Index (i.e. 1, 2, etc) you wish to visit, 0 to exit: 1
ERROR while parsing URL
Process finished with exit code 0
ERROR while parsing URL suggests that error comes from
try {
System.out.print("Enter Index (i.e. 1, 2, etc) you wish to visit, 0 to exit: ");
newIndex = input.nextInt();
input.nextLine();
for (String string : resultList) {
if(string.startsWith(String.valueOf(newIndex))) {
Process process = Runtime.getRuntime().exec("xdg-open " + string.substring(6, string.indexOf("&")));
process.waitFor();
}
}
} catch (Exception e) {
System.out.println("ERROR while parsing URL");
}
I am not working on Linux so I can't test it but I suspect that your url shoulnd't start with = (you will notice that your console contains URL:: =... where your printing statement doesn't have this = so it is part of address you are trying to visit).
So change in .substring(6, hRef.indexOf("&")) 6 to 7.
Other problem is that hRef is set to be linkHref which will be last result from google you picked. You should probably create your own class which will store proper href and its description, or pass list of Element representing <a ...>..</a> elements which you picked (also you don't need to check elements in list based on their 1: ... format, simply use list.get(index - 1) if you want to map 1 to index 0, 2 to index 1 and so on).
Last advice for now is that you may change your code to be more OS independent with solution described here How to open the default webbrowser using java rather than trying to execute xdg-open

xPath not finding selector when using for-each loop variable, but works otherwise

I'm using Selenium to loop through an ArrayList of Strings in order to use each string in an xPath expression in order to select its appropriate checkbox on a website.
The problem is, when I use the for loop, the variable containing the string doesn't seem to create a valid xPath, yet when I simply substitute the string in myself it works fine.
For example, here is my ArrayList declaration with some values added.
ArrayList<String> fieldList = new ArrayList<String>();
fieldList.add("Street");
fieldList.add("City");
fieldList.add("Country");
If I then use the following code, it goes into the catch block
WebDriverWait waitForElement = new WebDriverWait(driver, 1);
for (String cField: fieldList) {
try {
waitForElement.until(ExpectedConditions.elementToBeClickable(By.xpath("//td[following-sibling::td[2] = " + cField + "]/input")));
WebElement checkBox = driver.findElement(By.xpath("//td[following-sibling::td[2] = " + cField + "]/input"));
checkBox.click();
} catch (Exception error) {
System.out.println("Couldn't find " + cField);
}
}
Telling me it couldn't find "Street" for example.
Yet when my try block contains the following, with the value explicitly stated, it works:
waitForElement.until(ExpectedConditions.elementToBeClickable(By.xpath("//td[following-sibling::td[2] = 'Street']/input")));
WebElement checkBox = driver.findElement(By.xpath("//td[following-sibling::td[2] = 'Street']/input"));
What am I doing wrong? Thanks a lot.
You are forgetting to quote your strings in the XPath expression. Add single quotes around cField:
waitForElement.until(ExpectedConditions.elementToBeClickable(
By.xpath("//td[following-sibling::td[2] = '" + cField + "']/input")));
// quotes added here ---^ and here ---^
WebElement checkBox =
driver.findElement(By.xpath("//td[following-sibling::td[2] = '" + cField + "']/input"));
// quotes added here ---^ and here ---^

After extracting data from html using a for loop, how do I insert one by one into a database?

I have extracted multiple data from an HTML using Jsoup and now I am trying to insert one by one into a derby db using JDBC on netbeans.
Here is my code:
public String nameOf() {
String nameStr = null;
String nameResults = "";
for(int j=100;j<=110;j++) {
refNum = j;
//System.out.println("Reference Number: " + refNum);
try {
//crawl and parse HTML from definition and causes page
Document docDandC = Jsoup.connect("http://www.abcd.edu/encylopedia/article/000" + refNum + ".htm").get();
// scrape name data
Elements name = docDandC.select("title");
nameStr = name.get(0).text();
//System.out.println(nameStr);
nameResults += nameStr + " ";
} catch (Exception e) {
//System.out.println("Reference number " + refNum + " does not exist.");
}
}
return nameResults;
So this method takes the names of diseases from 10 different HTMLs. What I am trying to do is to insert one name at a time to a derby db that I have created using JDBC. I have everything set up and all I have left to do is to insert each name in the corresponding name field of a table named DISEASE (which has fields: id, name, etc).
nameResults += nameStr + " ";
This part worries me as well since some diseases can have multiple words. Maybe I should use a list of some sort?
Please help! Thanks in advance.
Something like:
public List<String> nameOf() {
...
List<String> nameResults = new ArrayList<String>();
...
nameResults.add(nameStr);
...
return nameResults;

Categories