Dynamic webtable rows storing, searching and handling with java webdriver - selenium

There are several solution, but nothing with hashmap and enum.
Website table element simple tbody, tr,td. The code below, I have webelements in the rows list, or the row data as a string in the other list.
List<WebElement> rows = table.findElements(By.tagName("tr"));
List<ArrayList<String>> rowsData = new ArrayList<ArrayList<String>>();
for(WebElement row:rows){
List<WebElement> rowElements = row.findElements(By.tagName("td"));
ArrayList<String> rowData = new ArrayList<String>();
for(WebElement column:rowElements){
rowData.add(column.getText().toString());
}
rowsData.add(rowData);
}
One row can be:
12, ab, apple, red, -1000;
66, ac, grape, blue, 1000; etc.
I have to check all the rows and find the first row which is red, apple and last row is not bigger than 0 and click.
More useful option can be enum and hashmap. Hashmap keys can be enum values, like ID, NAME, FRUIT, COLOR, NUMBER. Checking hashmap has COLOR= red, name = apple etc.
Any solution for this? I think it can be very useful for everybody!
Thanks in advance!

Have you thought of creating row as an object? So something like this
public class Fruit {
private String name;
private int id;
//go horizontally with your column names;
//have getters/setters here
}
Now your code could be written slightly differently like,
List<WebElement> rows = table.findElements(By.tagName("tr"));
List<Fruit> fruits = new ArrayList<Fruit>();
for(WebElement row:rows){
List<WebElement> rowElements = row.findElements(By.tagName("td"));
Fruit fruit = new Fruit();
//you know first column is name or so on
//or store column header order and use it here
fruit.setName(rowElements.get(0).getText());
fruit.id(rowElements.get(1).getText());
fruits.add(fruit);
}
Now you can iterate over fruits

Related

Relate/combine 2 different xpath Java Selenium

This url will show the search result of a product in Amazon site.
https://www.amazon.com/s?k=yellow+puma+shoes&s=price-asc-rank&qid=1559364287&ref=sr_st_price-asc-rank
Using this xpath I can get product name
//span[#class='a-size-base-plus a-color-base a-text-normal']
Using this xpath I can get price
//span[#class='a-offscreen']
Is there a way to combine these 2 so that I can relate product name with price. 1 Way I can think of is:
//span[#class='a-size-base-plus a-color-base a-text-normal']
List<WebElements> allProductNames**** Save them in a list. Then run a for loop
for()
{
text = getText
//span[text()='PUMA Mens Basket Classic']/../../../../../..//span[#class='a-offscreen']
}
If you have an idea for easier solution kindly suggest. Thanks in advance.
I would rather get all the items and then iterate through each of them with in a loop as shown below.
// get all products
List<WebElement> products = driver.findElements(By.xpath("//span[#data-component-type='s-search-results']//div[#class='sg-row'][2]"));
// create a map (consider it as dictionary that to hold key value pair) to hold product and price
Map<String, String> map = new HashMap<String, String>();
for (WebElement product : products) {
String item = "";
String price = "";
// get product name
item = product.findElement(By.xpath(".//span[#class='a-size-base-plus a-color-base a-text-normal']")).getText();
// get product price (some products have range so we have to get the prices and display)
List<WebElement> prices = product.findElements(By.xpath(".//span[#class='a-offscreen']"));
for (WebElement pPrice : prices) {
if (price !=""){
price = price + "-" + pPrice.getAttribute("textContent");
}else {
price = pPrice.getAttribute("textContent");
}
}
// push the product and price to the map
map.put(item, price);
}
System.out.println(map);

Is there anyway to test sorting functionality of a web table in either Selenium Webdriver or Katalon Studio?

Is it possible to test the sorting functionality of a web table in Katalon Studio/Selenium Webdriver?
Does Katalon Studio/Selenium Webdriver have any default method to verify whether the datas within a single column is either in ascending or descending order?
The following is the code that I used to fetch all the values listed in the 1st column of a web table and save them in an array:
WebDriver driver = DriverFactory.getWebDriver()
'To locate table'
WebElement Table = driver.findElement(By.xpath('/html[1]/body[1]/table[1]/tbody[1]'))
'To locate rows of table it will Capture all the rows available in the table'
List<WebElement> rows_table = Table.findElements(By.tagName('tr'))
'To calculate no of rows In table'
int rows_count = rows_table.size()
String[] celltext = new String[rows_count]
for (int row = 0; row < rows_count; row++) {
'To locate columns(cells) of that specific row'
List<WebElement> Columns_row = rows_table.get(row).findElements(By.tagName('td'))
'It will retrieve text from 1st cell'
String celltext_1 = Columns_row.get(0).getText()
celltext[row] = celltext_1
}
For example, celltext = [4,3,2,1]
Now I want to verify that the values saved in celltext is in descending order.
Any help will be highly appreciated.
Neither selenium nor katalon provides sorting functionality. But you can use java Arrays utility class to sort the items and compare it as follows.
String[] celltextBefore = celltext;
Arrays.sort(celltext, Collections.reverseOrder());
if(Arrays.equals(celltextBefore, celltext))
{
System.out.println("Celltext is in descending order");
}
else{
System.out.println("Celltext is not in descending order");
}
Special thanks to Murthi for giving me the splendid idea of comparing arrays.
The following way I was able to solve my problem:
List<Integer> celltext_list = Arrays.asList(celltext);
Collections.sort(celltext_list, Collections.reverseOrder());
int[] celltext_new = celltext_list.toArray();
if(Arrays.equals(celltext_new, celltext)){
System.out.println("Celltext is in descending order")
}
else{
System.out.println("Celltext is in ascending order")
}
In Murthi's solution above, there was an error throwing which I added to his comment. Finally came up with the above solution.

Dropdown duplicate value automation using Selenium

How to check the duplication of values in a checkbox using Selenium Webdriver
something like the below one will work if both the options have same value
public boolean isSelectOptionsRepeating(WebElement dropdown)
{
Select s = new Select(dropdown);
List<WebElement> list = s.getOptions();
Set<String> listNames = new Hashset<String>(list.size());
for (WebElement w : list) {
listNames.add(w.getText().trim());
}
if(list.size()== listNames.size())
return true;
else
return false;
}
You can store the values of drop down in String array and
traverse string array and use Hashmap for storing the values from the dropdown and if duplicate occurs increement the count by one
voila......you would know the the Values with its count, if count > 1. Duplicate
for reference : Java Beginner - Counting number of words in sentence

how to find one element from one cell of a web table without using any locator like id,xpah,name etc. of that cell in selenium

I have one dynamic table. in row=1 and column=3 the value of the cell is 2. I don't know any xpath, id, name etc.
To use td and tr how can I get that value.
Sample table
WebElement table= driver.findElement(By.id("table"));
/* List of all rows*/
List< WebElement> rows = table.findElement(By.tagName("tr"));
int row_count = rows.size();
/*Looping rows*/
for(int i=0;i< row_count;i++)
{
/* List all columns*/
List < WebElement> columns = rows.findElement(By.tagName("td"));
int column_count= columns.size();
for(int j=0;j< column_count ; j++)
{
String celltext= columns.get(j).getText();
System.out.println(celltext); ///This will print all values inside the table.
////But I want only one value from one cell, suppose from first row and third column
}
}
As you are saying if your td cell value is 2 and no other cell has value 2 then try this xpath :-
//td[text() = '2']
or
//tr[1]/td[text() = '2']
And if you want to get cell value try as below (Amusing you are using java) :-
WebElement table= driver.findElement(By.id("table"));
String cellValue = driver.findElement(By.xpath("//table/tr[1]/td[3]")).getText()
Edited :- you should try to get text from first row third column as below :-
String thirdColumnText = table.findElement(By.tagName("tr")).get(0).findElements(By.tagName(td)).get(3).getText();
Note :- For more better solution, need to share your table HTML
hope it helps..:)

String is to Substring, as ArrayList is to?

In Java, and many other languages, one can grab a subsection of a string by saying something like String.substring(begin, end). My question is, Does there exist a built-in capability to do the same with Lists in Java that returns a sublist from the original?
This method is called subList and exists for both array and linked lists. Beware that the list it returns is backed by the existing list so updating the original one will update the slice.
The answer can be found in the List API: List#subList(int, int) (can't figure out how to get the link working....)
Be warned, though, that this is a view of the underlying list, so if you change the original list, you'll change the sublist, and the semantics of the sublist is undefined if you structurally modify the original list. So I suppose it isn't strictly what you're looking for...
If you want a structurally independent subsection of the list, I believe you'll have to do something like:
ArrayList<something> copy = new ArrayList<>(oldList.subsection(begin, end));
However, this will retain references to the original objects in the sublist. You'll probably have to manually clone everything if you want a completely new list.
The method is called sublist and can be found here in the javadocs
http://docs.oracle.com/javase/7/docs/api/java/util/ArrayList.html#subList(int, int)
You can use subList(start, end)
ArrayList<String> arrl = new ArrayList<String>();
//adding elements to the end
arrl.add("First");
arrl.add("Second");
arrl.add("Third");
arrl.add("Random");
arrl.add("Click");
System.out.println("Actual ArrayList:"+arrl);
List<String> list = arrl.subList(2, 4);
System.out.println("Sub List: "+list);
Ouput :
Actual ArrayList:[First, Second, Third, Random, Click]
Sub List: [Third, Random]
You might just want to make a new method if you want it to be exactly like substring is to String.
public static List<String> sub(List<String> strs, int start, int end) {
List<String> ret = new ArrayList<>(); //Make a new empty ArrayList with String values
for (int i = start; i < end; i++) { //From start inclusive to end exclusive
ret.add(strs.get(i)); //Append the value of strs at the current index to the end of ret
}
return ret;
}
public static List<String> sub(List<String> strs, int start) {
List<String> ret = new ArrayList<>(); //Make a new empty ArrayList with String values
for (int i = start; i < strs.size(); i++) { //From start inclusive to the end of strs
ret.add(strs.get(i)); //Append the value of strs at the current index to the end of ret
}
return ret;
}
If myStrings is an ArrayList of the following Strings: {"do","you","really","think","I","am","addicted","to","coding"}, then sub(myStrings,1,6) would return {"you", "really", "think", "I", "am"} and sub(myStrings,4) would return {"I", "am", "addicted", "to", "coding"}. Also by doing sub(myStrings, 0) it would rewrite myStrings as a new ArrayList which could help with referencing problems.