Call Individual Index of WebElement List - java

If anyone needs reference or background here was my first question asked
Retrieving a list of WebElements and Identifying them
At this point I have retrieved a list of WebElements
#FindBy(css = "td[id^=ctl00_SomeGridData_ucControlList_trgControlList_ctl00__]")
List<WebElement> allGridData;
At this point in my code I can use the web Element to call the index for example
allGridData.get(0).click
however the list is not strictly integers for example if I access at the row level <tr> it would be:
ctl00_SomeGridData_ucControlList_trgControlList_ctl00__0
but if I were to call a link within row they are table data <td> broken into divs that look like this:
ctl00_SomeGridData_ucControlList_trgControlList_ctl00__ctl04_lbView
ctl00_SomeGridData_ucControlList_trgControlList_ctl00__ctl04_hlTestPlan
or this
ctl00_SomeGridData_ucControlList_trgControlList_ctl00__ctl07_lbView
ctl00_SomeGridData_ucControlList_trgControlList_ctl00__ctl07_hlTestPlan
Since all the WebElements start with a common css selector
#FindBy(css = "td[id^=ctl00_SomeGridData_ucControlList_trgControlList_ctl00__]")
List<WebElement> allGridData;
how can identify a specific index that is a char value (ie ctl107) vs just an integer?

Assuming you want two lists, one for the View Details and one for the View Test Plans, you need the $ (ends with):
#FindBy(css = "a[id$=lbView]")
List<WebElement> allDetailViewLinks;
#FindBy(css = "a[id$=hlTestPlan]")
List<WebElement> allTestPlanLinks;
But my best guess is that you want to click on a link in a specific row rather than based on index in a list of Web Elements. For instance based on the text in the td in <tr id="ctl00_SoxMain_ucControlList_trgControlList_ctl00__0" class="rgRow">
<td class="rgExpandCol" valign="top"/><td valign="top">AL-01</td>.
You need a method to get the row with specific text in the td.
WebElement getRow(String specificValue) {
return driver.findElement(By.xpath("//td[text()='"+specificValue+"']"))
.findElement(By.xpath(".."));
}
Then you can make the methods for detail view and test plan view.
public void openDetailsView(String specificValue) {
getRow(specificValue)
.findElement(By.cssSelector("a[id$=lbView]"))
.click();
}
public void openTestPlanView(String specificValue) {
getRow(specificValue)
.findElement(By.cssSelector("a[id$=hlTestPlan]"))
.click();
}

Related

Grabbing all data values form a web table

I need to go through all the table values and grab those into array list (or your some suggested place)
First-row xpath list
/html[1]/body[1]/div[4]/div[1]/main[1]/div[1]/div[3]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[1]/th[1]
/html[1]/body[1]/div[4]/div[1]/main[1]/div[1]/div[3]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[1]/td[1]
/html[1]/body[1]/div[4]/div[1]/main[1]/div[1]/div[3]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[1]/td[2]
.
.
/html[1]/body[1]/div[4]/div[1]/main[1]/div[1]/div[3]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[1]/td[5]
2nd row, few xpaths
/html[1]/body[1]/div[4]/div[1]/main[1]/div[1]/div[3]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[2]/th[1]
/html[1]/body[1]/div[4]/div[1]/main[1]/div[1]/div[3]/div[2]/div[1]/div[1]/div[4]/div[2]/table[1]/tbody[1]/tr[2]/td[1]
Please provide some Custom keyword logic for capture those values in easy way.
DOM
We can start using relative xpath for table's tbodythen we can use tagName method of By class for html tag names 'tr' and 'td' to fetch the rows and column elements
then we can save to arrayList as shown below in code.
Note - Closely observe first call to get table start is findElement and remaining are findElements as we want all elements with tr and td tagname.
#Test
public void testWebTable() {
WebElement simpleTable = driver.findElement(By.xpath("//table[1]/tbody[1]"));
// Get all rows
List<WebElement> rows = simpleTable.findElements(By.tagName("tr"));
List<String> webTableData = new ArrayList<String>();
// Print/Save data from each row
for (WebElement row : rows) {
List<WebElement> cols = row.findElements(By.tagName("td"));
for (WebElement col : cols) {
webTableData.add(col.getText());
System.out.print(col.getText() + "\t");
} System.out.println();
}
}
You can use PHP Simple HTML Dom parser library to parse those table data easily. Check out https://simplehtmldom.sourceforge.io/

Difference WebElements Vs WebElement in selenium

I am fetching date webelements from facebook and I am looping it by using the below code.
public class select_facebook {
public static void main(String[] args) throws Exception {
WebDriver driver = new FirefoxDriver();
driver.get("http://www.facebook.com");
List<WebElement> days = driver.findElements(By.xpath("//select[#id='day']"));
System.out.println(days.size());
for (int i=0;i<days.size();i++) {
System.out.println(days.get(i));
}
}
}
But I get output as
1
[[FirefoxDriver: firefox on XP (58765a0e-31a0-40bc-8565-3418ae54682c)] -> xpath: //select[#id='day']]
But same code in for loop if I use System.out.println(days.get(i).gettext());
It list all the dates 1 to 31.
My question is then why should I call this as
List<WebElement> days = driver.findElements(By.xpath("//select[#id='day']"));
Because even the size of the webElements is just :1
System.out.println(days.size());
instead I could have called it as
WebElement days = driver.findElement(By.xpath("//select[#id='day']"));
You will get list of Elements in return of
List<WebElement> days = driver.findElements(By.xpath("//select[#id='day']"));
because there could be more than 1 element by same id ('day').
You should have to focus on what you exactly need. If you want more elements use FindElements() and when you are interested in only one element then use FindElement().
If there are more number of elements and if you use FindElement() it returns you very first element and rest others are get neglected. So make sure about your requirement.
This is because an id value can be given to only one HTML element. In other words, multiple elements cannot have the same id value on the same page in valid HTML DOM only.
FindElement() it returns you WebElement:
WebElement SINGLEELEMENT= driver.findElement(By.SELECTOR("//TAGNAME[#ATTRIBUTENAME='ATTRIBUTEVALUE']"));
FindElements() it returns you WebElements i.e List<WebElement> of multiple elements. It return 1 if only one element present in it or multiple if presents more:
List<WebElement> LISTOFELEMENTS= driver.findElements(By.SELECTOR("//TAGNAME[#ATTRIBUTENAME='ATTRIBUTEVALUE']"));
You can put looping on it to get each one element and work on each individually.

Return all Select web elements as List in Selenium

Not a duplicate: I am not asking for the <option> within a <select>. I would like to return the <select> web elements themselves as a List. When achieved, the list should have a size of 2.
I have only found driver.findElements() that returns a List<WebElement>.
How do I return a List<Select> by ng-model="income.frequency"?
(Note: I have ngWebDriver so I can use ByAngular.model("income.frequency") as locator.)
HTML:
In order to match elements by their attribute, you can use the CSS selector:
By.cssSelector("<tag>[<attribute>='<value>']")
And in context:
List<WebElement> elements = driver.findElements(By.cssSelector("select[ng-model='income.frequency']"));
Edit: According to Selenium documentation, you can create a Select with a very straight-forward constructor. Hence, if you want a list of Select objects, just construct a new list:
List<Select> selectList = new ArrayList<>();
List<WebElement> elements = driver.findElements(By.cssSelector("select[ng-model='income.frequency']"));
for(WebElement element : elements) {
selectList.add(new Select(element);
}

How to read all the heading tag on page and select one hading tag with a specific heading?

I am trying to read all the heading tag on a page and need to click only one heading tag named "dropdown". The sample structure of HTML is as follows
<div> <ul> <li>
<a href="submit_button_clicked.php">
<h2>Submit Button Clicked</h2>
<figure>
</a>
</li>
<li>
<a href="dropdown.php">
<h2>Dropdown</h2>
<figure>
What i did is to create a custom xpath and store it in List,then iterate through list using for loop but i am unable to /read/write the value of tag on console.
List l = ff.findElements(By.xpath("//div/ul/li/a/h2"));
To retrieve the text value of an element use:
element.getText();
In your case with your list it would look something like this:
for(WebElement element : l) {
System.out.println(element.getText());
}
Since you want to click on an element, it would be better to use an xpath such as the following:
ff.findElements(By.xpath("h2[text()='Dropdown']")).click();
To find and click the specific element you want. The above xpath selector looks for a h2 element with the exact text 'Dropdown' and then clicks on it.
Reading all <h2> tags can look something like:
List<WebElement> elements = ff.findElements(By.xpath("//h2"));
for(WebElement element : elements) {
System.out.println(element.getText()); // just to show that it prints text
}
Note that I defined list as List<WebElement> which is to avoid usage of raw types, and changed xpath to match any <h2>.
But when you need to click, usually you are required to click on parent <a> element, not on <h2> itself, i.e. the following should click on a correct link
ff.findElement(By.xpath("//a[#href='dropdown.php']")).click();
But if you want to find a link from header, in the above loop:
List<WebElement> elements = ff.findElements(By.xpath("//h2"));
for(WebElement element : elements) {
if("Download".equals(element.getText()) {
// get the parent <a> element and click on it
element.findElement(By.xpath("..")).click();
}
}
Hi please do it like below
WebDriver driver = new FirefoxDriver();
driver.get("http://www.seleniumhq.org");
driver.manage().timeouts().implicitlyWait(15, TimeUnit.SECONDS);
// Hi please do it like below ,take all H2 tag inside the list
List<WebElement> myH2Tags = driver.findElements(By.tagName("h2")); // you can put any tag name as per your requirement
for(int i=0;i<myH2Tags.size();i++){
System.out.println("Value of My H2 Tags are : " + myH2Tags.get(i).getText());
if(myH2Tags.get(i).getText().equals("Selenium News")){ // you can replace this with drop down value
myH2Tags.get(i).click();
}
// to avoid stale element exception you have to re identify the elements
myH2Tags = driver.findElements(By.tagName("h2"));
}

Getting the count of rows from a web table - Selenium WebDriver Java

I am working on selenium webdriver using java. I am facing a problem. I have a web table and I have test case for add event functionality, that successfully adds the event in the table. Now I want to assert/verify if I got the added event in my table or not (Because if the functionality is broken, then date will not add in the table, and I can fail that test deliberately). The number of events are unknown before the start of test case. My logic for this test case verification is as follows:
Add the event in the table. The code to add event is :
public void addIndividualEvent(String eventDate, String eventName) throws Exception
{
driver.findElement(individualEventDate).sendKeys(eventDate);
driver.findElement(individualEventName).sendKeys(eventName);
driver.findElement(addIndividualEventBtn).click();
}
Now, after this step, there may be multiple events already in the table. So my next step would be to.
Find the number of rows in the table.
Construct a for loop that goes through each row and get the text of the date field.
Add the result of for loop to a list.
Then Assert.assertEquals(List,eventDate); will tell me if my added event is in the table or not.
Now, below is the HTML code of the table in my website.
<table class="table table-condensed table-hover event-list">
<tbody>
<tr class="study-event-row ng-scope" ng-repeat="event in events | orderBy:'-date'">
<tr class="study-event-row ng-scope" ng-repeat="event in events | orderBy:'-date'">
<tr class="study-event-row ng-scope" ng-repeat="event in events | orderBy:'-date'">
</tbody>
</table>
I was able to construct the xpath that highlights all my rows available in the table.
xpath = //table[#class='table table-condensed table-hover event-list']/tbody/tr
Now the issue I am facing is that I dont know how to use this xpath to get the count of rows from my table. I tried to use xpath.getSize(); but this returned the dimensions of the table and not the actual count.
Can anyone tell me how can I get the no of rows? Thanks
To get the rows, do the following-
Using CSS selector:
List<WebElement> rows = driver.findElement(By.cssSelector("[class='table table-condensed table-hover event-list'] tr"));
Or if you have to use XPATH, then do:
List<WebElement> rows = driver.findElements(By.xpath("//table[#class='table table-condensed table-hover event-list']/tbody/tr"));
This is returning a list of WebElements. You can get the count here:
int count = rows.size();
System.out.println("ROW COUNT : "+count);
Then you can get text for each element and assert if it's as expected. As you are saying the text should be same for all elements, then you can do something like this:
for(WebElement e : rows) {
assertEquals("expected text", e.getText());
}
Use the following code to get the row size of the table.
WebElement webElement=project.login.driver.findElement(By.xpath("tbodyXpath"));
List<WebElement> rows=webElement.findElements(By.xpath("tablerowXpath"));
System.out.println("Size -------"+rows.size());
Assuming your XPath works, you can just do this...
List<WebElement> rows = driver.findElements(By.xpath("//table[#class='table table-condensed table-hover event-list']/tbody/tr"));
System.out.println(rows.size());
It will return you the number of rows (TRs) in that table.
You could use the XPath:
count(//table[#class='table table-condensed table-hover event-list']//tr)
This will count all the tr elements that are descendants of the table element with #class="table table-condensed table-hover event-list"
Resolve the table object through your xpath, then use that WebElement as your SearchContext and get all TR elements within. The size of the return list should tell you your visible row count.
int EXPECTED_ROW_COUNT = 3;
/**
* Test case for counting the number of visible rows in a table.
* #see "http://stackoverflow.com/questions/33233883/getting-the-count-of-rows-from-a-web-table-selenium-webdriver-java"
* #author http://stackoverflow.com/users/5407189/jeremiah
*/
#Test
public void testCountRows() {
WebDriver wd = new FirefoxDriver();
wd.get("http://www.w3schools.com/html/tryit.asp?filename=tryhtml_table");
WebDriverWait wait = new WebDriverWait(wd, 10);
wait.until(ExpectedConditions.frameToBeAvailableAndSwitchToIt("iframeResult"));//Specific to test location # w3schools!
WebElement parentTable = wd.findElement(By.xpath("html/body/table/tbody"));
//WebElement parentTable = wd.findElement(By.xpath("//table[#class='table table-condensed table-hover event-list']/tbody"));
//Now use the parentTable as the root of the search for all 'tr' children.
List<WebElement> rows = parentTable.findElements(By.xpath("./tr"));
Assert.assertTrue(EXPECTED_ROW_COUNT == rows.size());
}
/**
* Test that you can use to direct at your url and interact with rows.
*/
#Test
public void testYourRowCount() {
WebDriver wd = new FirefoxDriver();
//FIXME
wd.get("yourURLHere");
WebElement parentTable = wd.findElement(By.xpath("//table[#class='table table-condensed table-hover event-list']/tbody"));
//Now use the parentTable as the root of the search for all 'tr' children.
List<WebElement> rows = parentTable.findElements(By.xpath("./tr"));
//FIXME: Do stuff with the rows.
}

Categories