Customer Selenium webdriver java method for validating table search results - java

I am wanting to create a custom method in a Base page object that will allow me to validate the results returned in a dynamic table after searching.
I have the below method ..
It takes as arguments the WebElement table, a column name that I want to validate against and and expected value that I expect to be returned by a row of that column.
I am trying to find the column index of the column with name that I pass in as columnName and assign it to a variable called searchedColIndex then use this to get all values returned under that column and then validate whether the expected result was in the list.
However I am not sure how to get the index of the column.
Also I never seem to get inside the if statement, even though when I print both column.getText() and columnName to console the values are correct and should match for one of columns, but that if statement is never evaluated as true.
public void validateTableData2(WebElement table,String columnName, String expectedSearchResult){
List<WebElement> tableRows = table.findElements(By.xpath(".//tr"));
List<WebElement> tableColumns = table.findElements(By.tagName("th"));
int searchedColIndex = 1;
for (WebElement column : tableColumns) {
if(column.getText().trim() == columnName.trim()){
System.out.println("We don't get in this if statement");
System.out.println("The values in column headers are available as if I print column.getText() then it does return correct column headings");
//Not sure how I can assign the index of the column I am interested in
//column.getText() does
}
}
List<String> returnedVals = new ArrayList<String>();
for (int i = 1; i < tableRows.size(); i++) {
String returnedVal = table.findElement(By.xpath("./tbody/tr["+i+"]/td["+searchedColIndex+"]")).getText();
returnedVals.add(returnedVal);
}
Assert.assertTrue(returnedVals.contains(expectedSearchResult));
}
Any help would be much appreciated.

For your second question, use equals() instead of ==, then you should get inside the if statement.

I was able to come up with the below method, which seems to work, although perhaps won't work for every table I try to use it with ..
public void validateTableData2(WebElement table,String columnName, String expectedSearchResult){
List<WebElement> tableRows = table.findElements(By.xpath(".//tr"));
System.out.println("Col name is " +columnName);
int searchedColIndex = table.findElements(By.xpath("//thead/tr/th/a[text()='"+columnName+"']/../preceding-sibling::th")).size()+1;
List<String> returnedVals = new ArrayList<String>();
for (int i = 1; i < tableRows.size(); i++) {
String returnedVal = table.findElement(By.xpath("./tbody/tr["+i+"]/td["+searchedColIndex+"]")).getText();
System.out.println("Returned val is "+returnedVal);
returnedVals.add(returnedVal);
}
Assert.assertTrue(returnedVals.contains(expectedSearchResult));
}

Related

How to iterate through data table pick values to pass through as a json request

I am writing an automation test and what I am trying to do is through each row in the dataTable, check each column and if the value does not equal "", then put the field name (coulmn name) and its value in the body to pass through as a json request.
For example:
|colour|food |
| |pizza|
|red | |
So when it iterates through the first row, it should create a json body of below for first request:
"food":"pizza"
For second row it will create json body of below for second request.
"color":"red"
At the moment what is happening is that for the first request it is not passing anything and for the second request it is passing:
"food":"pizza"
I almost have it but need assistance on what I am doing wrong.
Below is the code:
public void testMethod(final Table table) {
final RequestHeaders headers = Test.getCurrentHeaders();
final Map<String, Object> body = new HashMap<>();
table.getColumnNames().forEach(columnName -> {
final String value = table.getTableRows().get(0).getCell(columnName);
if (!value.equals("")) {
body.put(columnName, value);
}
postRequest("/test/endpoint", headers.getMap(), SerializationHelper.asString(body));
});
}
I believe the problem might be with table.getTableRows().get(0) which I think always return the first row. You would have to iterate over all rows, until you find something or complete your iteration. Then you either have a value or not.
PSEUDO:
table.getColumnNames().forEach(columnName -> {
String value = "";
//iterate over table rows until you are through
for (TableRow row in table.getTableRows()){
value = row.getCell(columnName);
//if you find a value for columnName which isn't empty save it and break
if (!value.equals("")) {
body.put(columnName, value);
break;
}
}
//we have to check whether we set a new value, before posting
if(!value.equals("")){
postRequest("/test/endpoint", headers.getMap(), SerializationHelper.asString(body));
}
});
Currently As I understand it, you are iterating over the tableHeaders from left to right.
So first run will be columnName = "colour"
The you are getting the first row (| |pizza|) and select the cell for the columnName.
The cell for columnName = colour is empty. So you skip it
Then you post the body.
Then in the second run, columnName = "food"
You still get the first row (| |pizza|) and select the cell for the columnName.
This time the cell for columnName = food is not empty, so you put the value into the body and post it.

Accessing multi dimensional ArrayList values

I am getting 3 columns for each row from mysql table by using ResultSet. I am not sure about the number of rows I will get by using query. To store those rows I am using ArrayList as given code below:
while (rs.next())
{
String[] row = new String[numcols];
for (int i = 0; i < numcols; i++)
{
row[i] = rs.getString(i + 1);
}
rowsList.add(row);
}
rs.close();
When I debugged the code I found columns values are present in the ArrayList. Now I am unable to access the columns values because rowsList.get(index) will return only value at specific index but I have further 3 more values at that index how to access those values.
List.get() in your case will return a String array: String[]. You can access the elements of an array by using the [] index operators:
String[] row = rowList.get(0);
for (int i = 0; i < row.length; i++)
System.out.println(row[i]);
// Or you can use the enhanced for to loop through the array:
for (String s : row)
System.out.println(s);
If you want to process all rows:
for (String[] row : rowList) {
// Process row
for (String s : row) {
// Do something with the string
}
}
I would like to suggest you to learn about List.
And the second would be to create a class that holds everything that comes from your query.
And finally save each object of the class to the array.
Example
Suppose you get id, name and address columns from your query
Create a class
public class YourClass{
int id;
String name, address;
//create getters and setters or use a constructor
//example of setter to set field id
public void setId(int id){
this.id = id;
}
}
And then while retrieving the records from query, create an object of your class and set the columns as field of your class as follow:
YourClass anObject = new YourClass();
anObject.setId(id);// get similar columns from query
anObject.setName(name);
And finally add the object to the ArrayList as below:
yourArrayList.add(anObject);
To take care of multiple number of records you need to keep these code inside the while loop
And define your List before while loop as follow:
List<YourClass> yourArrayList = new ArrayList<YourClass>();
And I think this is the best approach as it uses OOP that you should begin using instead of using bare array.
you would want to specify what object is in the list. to achieve this make your List to List<String[]> rowsList = new ArrayList<String[]>();
then use your while loop
while (rs.next())
{
String[] row = new String[numcols];
for (int i = 0; i < numcols; i++)
{
row[i] = rs.getString(i + 1);
}
rowsList.add(row);
}
rs.close();
when you access each item in the list it will always return a String[] which you can iterate to get the values.
for(int i = 0 ; i< rowsList.size() ; i++){
rowsList.get(i);//will return a String[]
}
OR
for(String[] rows : rowsList){
//iterate the rows
}

Can I ask an advice for the algorithm of retrieving arrayList in Java?

I have a class in Java such like this
for (....) {
tarik_id.add(id);
}
which is tarik_id is a List<String> and I want to add the (id) to be written in tarik_id arrayList. And then....
hasil = db.getDetailResult(tarik_id);
getDetailResult is a class for selecting all the (id) that I have pulled out with tarik_id.
And hasil is two dimensional table (List.List.String..)
I think that tarik_id doesn't return a value in my second line above. I have tried to Log.i my id, and the LogCat returns true values of my id. My question is how can the tarik_id in .getDetailResult returns all of the array values?
make your code as the following:
// put the first id in first
StringBuilder stringBuilder = new StringBuilder(id.get(0));
// start the loop from the 2nd
for (i=1; i < idList.size(); i++)
{
stringBuilder.append(",").append(id.toString());
}
String ids = stringBuilder.toString()
hasil = db.getDetailResult(ids);
Change the code in getDetailResult() for the query to be something like
if(ids.equals("")){
return null;
}
String sql = "SELECT * FROM...... WHERE ID IN("+ids+").....";
I think this is much faster, all records in 1 hit and no need for a second loop.

catch and store ALL mysql database data (table rows) to use them for comparison and matching

I am working on a project that i have to compare all the tables between two huge databases and matching them. Actually this project aims to implement a kind of database fusion. For been more specific, if a row1 on table1.database1 describes the person "Michael" with id, phone, address, etc.. and the specific row2 on table2.database2 describes the person "Mike" with id, phone, address, etc... i have to decide after the comparison if "Michael" and "Mike" are the same persons or not.
I did the connection for both databases, I already catch up the tables, the columns and the row data. As i am not so familiar with java I don't know how to use the extracting data and start any comparison. Which is the best way to store and use them? arraylists? arrays? objects? vectors?
For example I have the following piece of code to catch the row data:
int j = 0;
while(resTablesData1.next()) {
ResultSetMetaData rsmd = resTablesData1.getMetaData();
int colCount = rsmd.getColumnCount();
System.out.println();
for (int k=0; k<colCount ; k++) {
String colName = rsmd.getColumnName(i);
Object o = resTablesData1.getObject(colName);
columnsArrayDB1[j][k] = o.toString();
System.out.println("|-----------------------------------------------------|");
System.out.print("| "+columnsArrayDB1[j][k]+" |"+"\t");
System.out.println("|-----------------------------------------------------|");
}
j++;
}
I have the same piece of code for both databases. I have to compare the columnsArrayDB1[0][0] with columnsArrayDB2[0][0] and so on... how to do that with an optimize way?
Is it better to use an Object which would represent the data of the row? for example:
public class RowDataObject {
public String col1;
public String col2;
// Etc
public RowDataObject(String aCol1, String aCol2 /*.....etc */ ) {
col1 = aCol1;
col2 = aCol2; //...etc
}
}
and then read data
List<RowDataObject> allRows = new ArrayList<RowDataObject>();
ResultSet rs = //Your Query
while (rs.next()) {
String c1 = rs.getString("A Column Name or Index");
String c2 = rs.getString("A Column second Name or Index");
//...etc
allRows.add(new RowDataObject(c1,c2......));
}
All of my work for this project processing dynamic values as I don't know beforehand the name of schemas/tables/columns etc. Please I am kindly requested some guidelines to start with because I am confused. My main problem is how to write the appropriate classes and create objects from them using the instances to my provided code.
Thanks in advance.
Since you're using o.toString() to get the String value of all returned rows, you could create an object to hold each column's value, e.g.:
class CellValue
{
int cellTye;
String cellValue;
CellValue(int cellType,String cellValue)
{
this.cellType=cellType;
this.cellValue=cellValue;
}
}
Create each new object using rsmd.getColumnType() and o.toString()
Add the objects to ArrayList for each row, and add each row to an ArrayList for each data source. you can then iterate through the two ArrayLists to compare the columns.
I haven't actually tested this, but something like:
ArrayList<ArrayList<CellValue>> cells = new ArrayList<>();
ResultSetMetaData rsmd = resTablesData1.getMetaData();
int colCount = rsmd.getColumnCount();
while(resTablesData1.next()) {
ArrayList<CellValue> row = new ArrayList<>();
for (int k=0; k<colCount ; k++) {
String colName = rsmd.getColumnName(i);
Object o = resTablesData1.getObject(colName);
row.add(new CellValue(rsmd.getColumnType(),o.toString());
}
cells.add(row);
}
When you compare the results of the two ArrayLists, you can compare cellType to make sure you're comparing cells of the same data type. If you want to get fancy, you can override .equals() in CellValue() to compare cellType and cellValue; you can then use cellValue1.equals(cellValue2) to see if it's a match.

Verify list elements by Selenium WebDriver

WebElement select = myD.findElement(By.xpath("//*[#id='custfoodtable']/tbody/tr[2]/td/div/select"));
List<WebElement> allOptions = select.findElements(By.tagName("option"));
for (WebElement option : allOptions) {
System.out.println(String.format("Value is: %s", option.getAttribute("value")));
option.click();
Object vaLue = "Gram";
if (option.getAttribute("value").equals(vaLue)) {
System.out.println("Pass");
} else {
System.out.println("fail");
}
}
I can verify one element in a list, but there are like 20 elements in a dropdown I need to verify and I do not want to use above logic 20 times. Is there any easier way to do it?
Don't use the for-each construct. It's only useful when iterating over a single Iterable / array. You need to iterate over the List<WebElement> and the array simultaneously.
// assert that the number of found <option> elements matches the expectations
assertEquals(exp.length, allOptions.size());
// assert that the value of every <option> element equals the expected value
for (int i = 0; i < exp.length; i++) {
assertEquals(exp[i], allOptions.get(i).getAttribute("value"));
}
EDIT after OP's changed his question a bit:
Assuming you have an array of expected values, you can do this:
String[] expected = {"GRAM", "OUNCE", "POUND", "MILLIMETER", "TSP", "TBSP", "FLUID_OUNCE"};
List<WebElement> allOptions = select.findElements(By.tagName("option"));
// make sure you found the right number of elements
if (expected.length != allOptions.size()) {
System.out.println("fail, wrong number of elements found");
}
// make sure that the value of every <option> element equals the expected value
for (int i = 0; i < expected.length; i++) {
String optionValue = allOptions.get(i).getAttribute("value");
if (optionValue.equals(expected[i])) {
System.out.println("passed on: " + optionValue);
} else {
System.out.println("failed on: " + optionValue);
}
}
This code essentially does what my first code did. The only real difference is that now you're doing the work manually and are printing the results out.
Before, I used the assertEquals() static method from the Assert class of the JUnit framework. This framework is a de-facto standard in writing Java tests and the assertEquals() method family is the standard way to verify the results of your program. They make sure the arguments passed into the method are equal and if they are not, they throw an AssertionError.
Anyway, you can do it the manual way, too, no problem.
You can do it like this:
String[] act = new String[allOptions.length];
int i = 0;
for (WebElement option : allOptions) {
act[i++] = option.getValue();
}
List<String> expected = Arrays.asList(exp);
List<String> actual = Arrays.asList(act);
Assert.assertNotNull(expected);
Assert.assertNotNull(actual);
Assert.assertTrue(expected.containsAll(actual));
Assert.assertTrue(expected.size() == actual.size());
public void verifyElementsInListEquals(List<WebElement> elementsList, String expectedValue) {
ArrayList<String> TextList =new ArrayList<>(); // new list to have Text from list of Webelement
for( WebElement x :elementsList){ //for each loop in JAVA
TextList.add(x.getText()); //add "x" times text to list above
}
if(TextList.contains(expectedValue)){ //check if value exist in list above
System.out.println("Value is there");
}
else{
System.out.println(" no value");
assertTrue(false); //will always stop the program here
}
}

Categories

Resources