Getting all the cell values from table using table header using Webdriver - selenium

Below is the HTML code for the tables:
I need to extract values from table preceding with header as "Opportunities".
Could someone please suggest the best way forward as I can extract values fine if they belong to the same table but I need help when they are in two different table and i need to look for table opportunities and than extract data from the preceding table.

Sure here is my best interpretation of what you need in Java. Any questions and I'll alter my solution to accommodate them. This starts with an index of 0,0 for row and column.
int row = 0, column = 1; //it's 1 to accommodate fogr the first thing you want being a 'th' tag
List<WebElement> tableRows = driver.findElements(By.className("dataRow"));//this gets all elements on your page with a class of dataRow (which are your tr's)
for(WebElement singleRow: tableRows) //this for loop increments each of these tr's
{
System.out.println(singleRow.findElement(By.xpath("th[1]/a[1]")).getText()); //I'll have to use an xpath here because I don't have time to play around with other solutions but it'll work
System.out.println("Row: " + row + ", Column: " + column);
List<WebElement> rowTDs = singleRow.findElements(By.tagName("td"));//this gets every td in the current tr and puts it into a list
for(WebElement singleTD: rowTDs) //this increments through that list of td's
{
System.out.println(singleTD.getText()); //this gives you back the text contained in that cell
System.out.println("Row: " + row + ", Column: " + column);
column++; //increment the column counter
}
column=1; //reset the column
row++; //increment the row counter
}
Edit: It seems that given that element of the request "Saykiro" has almost the right of it and you can replace in my solution tableRows = with this, there's probably a more succinct way to get the second table but this is what comes to me:
WebElement table1 = driver.findElemen(By.id("001Z000000vrLQe_RelatedOpportunityList_title"));
WebElement table2 = table1.findElement(By.xpath("../../../../following-sibling::table"))
List<WebElement> tableRows = table2.findElements(By.className("dataRow"));

For your case:
//*[table/tbody/tr/td/h3[text()='Opportunities']]/table[2]//td[#class=' dataCell ']
For C# (getting list of values in cells):
var values = driver.FindElements(By.XPath("//*[table/tbody/tr/td/h3[text()='Opportunities']]/table[2]//td[#class=' dataCell ']")).Select(a=>a.Text);
You should describe outer part of html, so we can build xpath better.

Related

Based on my previous qu-How to perform some actions on each value from a drop down using selenium java?

Now I want to select first value from a drop down then perform some actions on it, then I want to select second value from the same drop down and perform the same action on it.
Here is my code:
WebElement bldgs=Fn_GetWebElement(CreateSSIObject.getProperty("Bldgselect"));
Select Bldg_select=new Select(bldgs);
List<WebElement> dropdownvalues = Bldg_select.getOptions();
int count=dropdownvalues.size();
System.out.println("Total number of values are :"+count);
for(int i=1;i<count;i++) {
if(dropdownvalues.get(i).isEnabled()) {
Bldg_select.selectByIndex(i);
System.out.println("Not Working :"+i);
waitForWebPagetoLoad(2000);
WebElement search_BTN=Fn_GetWebElement(CreateSSIObject.getProperty("search_Btn"));
fn_Click(search_BTN);
WebElement add_VEND=Fn_GetWebElement(CreateSSIObject.getProperty("add_vendors"));
fn_Click(add_VEND);
WebElement vendorName=Fn_GetWebElement(CreateSSIObject.getProperty("vendor_Name"));
fn_Click(vendorName);
vendorName.sendKeys(vendor);
waitForWebPagetoLoad(5000);
WebElement search_BTN1=Fn_GetWebElement(CreateSSIObject.getProperty("search_Btn"));
fn_Click(search_BTN1);
WebElement selectVendor=Fn_GetWebElement(CreateSSIObject.getProperty("select_Vendor"));
fn_Click(selectVendor);
WebElement addToSite=Fn_GetWebElement(CreateSSIObject.getProperty("AddTo_Site"));
fn_Click(addToSite);
}
}
here I am seaching for an element(basically drop down id) and then selecting each value with selectbyindex with i for loop. and then I am clicking on a button and performing some more actions on it. Now it is selecting only first value and doing all above stuff. But it is not going back in for loop to select 2nd value and performs same steps.
I don't quite understand your problem butI can see 2 issues that may be adding to confusion.
Index should 0 based
Your loop is starting with i set to 1. As lists are zero based indexes, you should start at 0
Referencing stale elements??
You are extracting the dropdown values outside of the loop and then referencing these within the loop using index. However, you are performing a lot of actions and events within each iteration.
You may be better extracting the values again within each iteration to ensure all your references are up to date and have not gone stale.
Can you please try below solution? I am not sure what action you are tryig to execute based on selection but I think below code solve your problem.
Select drpCountry = new Select(driver.findElement(By.name("Locator")));
List <WebElement> elementCount = drpCountry.getOptions();
int iSize = elementCount.size();
for(int i =0; i<iSize ; i++)
{
String sValue = elementCount.get(i).getText();
System.out.println(sValue);
drpCountry.selectByIndex(i);
if(sValue.equalsIgnoreCase("Selection1")){
//code to be executed if condition1 is true
}else if(sValue.equalsIgnoreCase("Selection2")){
//code to be executed if condition2 is true
}
else if(sValue.equalsIgnoreCase("Selection3")){
//code to be executed if condition3 is true
}
else{
//code to be executed if all the conditions are false
}
}

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.

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..:)

How to setText in a textArea from an ArrayList?

I have an ArrayList ArrayList<String> externalDataList = new ArrayList<>(1600);and I would like to display in a textArea first 3 strings, but I can't succed:
Here is my code
textareaShowPreview.setPrefRowCount(3);
Iterator<String> it = externalDataList.iterator();
int tot = 0;
while(it.hasNext() && tot<3){
String element = it.next();
textareaShowPreview.setText(element + "\n");
System.out.println("elements are: " + element);
tot++;
}
The sout correctly print first 3 strings
element are: 23/05/2007 ,30.9455,31.2545,30.9091,30.9545,7518142
element are: 24/05/2007 ,30.6545,31.0909,30.5364,30.6909,12851606
element are: 25/05/2007 ,30.6636,30.8545,30.4818,30.8091,9392088
but in textArea I have only first one
How do I have to modify my code to show in textArea all three strings, one string per row?
Use appendText instead of setText here is a link.
The setText, delete the previous text and set the text you are giving to it. The append keep the current text in your text area.
Hope it helps!

Get value from Titanium Appcelerator db column

I've looked around everywhere, but I can't seem to find exactly what I'm trying to do. It should be fairly simple...
I have a db table set up like this:
var db = Ti.Database.open('playerInfo.db');
db.execute('CREATE TABLE IF NOT EXISTS playersTable (id INTEGER PRIMARY KEY, name TEXT NOT NULL, "50" INTEGER, "25" INTEGER )');
I have two buttons with an assigned value of 25, and 50, respectively. Each button has a "value" key, where I assign their values. I am trying to accomplish three things:
When a button is pressed, find the column of corresponding value.
increase the value of this column by 1.
Retrieve the new value and console log it.
This is what my code looks like when a button is pressed:
var rows = db.execute("SELECT '" + button.value + "' FROM playersTable WHERE name= '" + owner + "'");
var imagesString = rows.fieldByName(button.value);
Ti.API.debug(imagesString)
This is all in a click event listener where the variable "owner" is passed in as a string.
This is the error I get:
message = "Attempted to access unknown result column 25";
I don't have too much experience with sql, so I'm not sure what I'm doing right and what I'm doing wrong. Any help is appreciated!
Thanks.
I'm not sure quite exactly what the problem is, but the following works for me. Note that the "?" variable substitution syntax makes sure that the values are quoted properly for MySQL:
button = e.source;
db = Titanium.Database.open('test');
var rows = db.execute("SELECT * FROM playersTable WHERE name= ?", "foo");
// Theoretically this should be returning a single row. For other results,
// we would loop through the result set using result.next, but here just check if
// we got a valid row.
if (rows.isValidRow()) {
var imagesString = rows.fieldByName(button.value);
var id = rows.fieldByName('id');
imagesString = imagesString + 1;
Ti.API.info("id = " + id + " val = " + imagesString);
// The ? substitution syntax doesn't work for column names, so we
// still need to stick the button value into the query string.
db.execute('UPDATE playersTable set "' + button.value +'"= ? where id = ?', imagesString, id);
}
else
{
Ti.API.info("Row not found.");
}
db.close();
If you get the row not found error, it's possible your data isn't getting inserted properly in the first place. Here's how I inserted my test row for player "foo":
db.execute('insert into playersTable (name, "50", "25") values (?,?,?)', 'foo', 0, 0);
I think this should solve your problem. Let me know if this doesn't work for you.