Selenium table count - selenium

I am testing a Java 7 web application developed with Vaadin 7 and I used to calculate the total number of rows in a table with the following code:
WebElement table= driver.findElement(By.xpath("//* [#id='grdEvRequestSearchView']/div[3]/table"));
List <WebElement> gridrow = table.findElements(By.tagName("tr"));
int rowNumber= gridrow.size();
Now the new version of the application put in a page a Vaadin grid component instead of table, now what I obtain from the count is the number of elements that currently visible: if I have a grid of 50 elements and only 10 are visible I obtain 10 and not 50 as I got in the past when table component.
Is there any way to get the effective count of rows and not the visible ones?
Andres

You cannot get the number of rows in Grid with Selenium. The idea of Grid component is that rows are being reused and new data is being fed to them. That makes the component lighter in DOM compared to old Table component in Vaadin.
With Vaadin 8 and TestBench 5 product you could check the real number of rows ( see API here: demo.vaadin.com/javadoc/com.vaadin/vaadin-testbench-api/8.0.2/… ), but unfortunately getRowCount is not in Vaadin 7 / TestBench 4.

Related

In selenium, how to located two elements have same span class name?

I need use selenium to located two elements. However, they both have same span class name. My code:
select_button = driver.find_elements_by_xpath("//span[#class='mat-button-wrapper']")
The issue is: I can this command 10 times, 6 times it locates my element, ( select button), but the other 4 times, it landed on the other button. How do I make sure it is 10 out of 10 times it will located my "select " button?
In case there are 2 elements with the same xpath as you mentioned you can use (//span[#class='mat-button-wrapper'])[1] xpath to access the first element and (//span[#class='mat-button-wrapper'])[2] for the second.
However I guess it's possible to locate the desired element with relation to some other element. I will do it if you present the web page link.

Is there any way to test display order sequence of web elements in Selenium?

Problem Statement: I have web page with 4 carousels (say A, B, C, D). I need to verify their correct display order on the UI (and not in HTML code).
Few points to test:
A should be on top always and will be displayed every time.
B, C D should follow order : A > B > C > D (Making A appear always on top and D always last or on bottom)
The order should be as above even if any of the carousels are not displayed. (Like if C is not displayed the order should be A > B > D).
Any one/two/all of B, C, D may not be displayed on page.
Test should be able to identify the sequence on both desktop and mobile browsers.
Solution I tried:
Find all the elements and get their Y coordinates using getLocation().getY() in Selenium. Compare the Y coordinates and identify which one is at top.
Current issue:
The above solution only works for Desktop browsers, and not for mobile browsers like chrome for iOS or Android, as getLocation() always returns (0,0) for all web elements.
Similar question: Its not much related with my issue:
Can I test on the order of elements using Selenium Webdriver?
Other Details:
- I'm using Java 1.8 with Selenium 2.53
- All tests are executing on Browser Stack
How do I achieve this using Selenium Web Driver and JAVA?

Can I count rows across multiple pages of a table with robot framework?

I am quite new to robot, and have only been working solo on it at work for a month or so.
Currently I am trying to count the total number on rows in a table within the application I am testing. (chrome based)
This is what I am using:
${count}= get element count //table[#class='options-table']/tbody/tr
Which brings back a value of 5 - this is counting the first page. However, I'm expecting it to bring back 76 as there are multiple pages.
Can anyone help on how to bring back the amount of rows across multiple pages?
${count}= get element count //table[#class='options-table']/tbody/tr
Expected result: 76
Actual result: 5 (only the first page)
To avoid a slightly complex logic (iterating through pages, summing up element counts) in a Robot Framework keyword you could write your own keyword in Python for example.
In this case you need a keyword that takes an element locator (//table[#class='options-table']/tbody/tr to be specific) and a list of page urls.
To implement such keyword, create a file like ExtendedSeleniumLib.py:
from robot.libraries.BuiltIn import BuiltIn
def get_element_count_from_pages(locator, *page_urls):
seleniumlib = BuiltIn().get_library_instance('SeleniumLibrary')
element_count = 0
for url in page_urls:
seleniumlib.go_to(url)
element_count += seleniumlib.get_element_count(locator)
return element_count
and from your test code you can use it like:
*** Settings ***
Library SeleniumLibrary
Library ExtendedSeleniumLib
*** Variables ***
${SE HEADER LOCATOR} //a[#class='site-header--link fs-headline1 fw-bold']
*** Test Cases ***
Count Elements On Multiple Pages Example
[Setup] Open Browser https://stackoverflow.com Firefox
Maximize Browser Window
Set Selenium Speed 0.1
${count}= Get Element Count From Pages ${SE HEADER LOCATOR}
... https://iot.stackexchange.com/
... https://sqa.stackexchange.com/
... https://robotics.stackexchange.com/
Should Be Equal As Integers ${count} 3
[Teardown] Close Browser
This example iterates through three Stack Exchange sites and counts the header elements. As there should be only one on each page the expected result is 3. Based on this you should be able to count the table rows on your pages.
About how to configure search path for libraries and resources, check the relevant chapter form the Robot Framework User Guide; Configuring where to search libraries and other extensions. If you place the python file into the same directory where your robot file is, then you do not need anything to do.
Please check below code, it assumes that the total number of pages will not be more than 100 since I'm not aware of the webpage, you can either take this number from webpage if available. Also, if you are sure that total number of rows per page is always 5 then you can use below formula
[ 5 * (total number of pages - 1 ) + row count of the last page]
This can give you total row count across all pages without traversing through all the pages. Also, please add any time synchronisation steps for the successful run.
Get Count of All Pages
${next_page_locator} Set Variable enter next page icon/link xpath here
${first_row_locator} Set Variable enter first row xpath here
${total_count} set variable 0
: FOR ${index} IN RANGE 1 100
\ Wait Until Element Is Visible ${first_row_locator}
\ ${count} get element count //table[#class='options-table']/tbody/tr
\ ${total_count} evaluate ${count} + ${total_count}
\ ${next_link_present} Run Keyword And Return Status Page Should Contain Element ${next_page_locator}
\ exit for loop if ${next_link_present} is ${False}
\ Click Element ${next_page_locator}

How to find the element within element in selenium

I am creating a framework for the data validation using selenium. The issue I am struggling with is I want to locate the element "td"(html tag) within element "tr"(html tag) . This is the code I have written.
Iterator<WebElement> i = rows.iterator();
While(i.hasnext()){
List<WebElement> columns = row.findElements(By.tagName("td"));
for(WebElement s:columns)
{
System.out.println("columnDetails : "+s.getText().toString());
}
if(columns.isEmpty())
{
ElementNotFoundException e = new ElementNotFoundException("No data in table");
throw e;
}
Iterator<WebElement> j = columns.iterator();// does some other work
ClusterData c = new ClusterData(); // does some other work
ClusterDataInitializer.initUI(c, j, lheaders); // does some other work
CUIData.put(c.getCN(), c); // does some other work
}
Now the issue with this is:
I am trying to fetch the data from the rows(see table data) in arraylist and use that arraylist further. Currently whats happening is the data for column header is fetched at start of which I have no use.I only want the rows's data. I am not able to determine the proper way to collect the data of table rows only.
if xPath of the table will help you understand it properly then here are the details :
Table header xPath of cluster name column:
/html/body/table/tbody/tr[2]/td[2]/div[2]/div/div/div[2]/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div[2]/div[2]/div/table/tbody/tr/td[2]/div/div[2]
Table row (Table Data) xPath of test cluster 01:
/html/body/table/tbody/tr[2]/td[2]/div[2]/div/div/div[2]/div/div/div[2]/div/div/div[2]/div/div/div/div/div/div[2]/div/div/div[2]/div/div/div[3]/div[2]/div/table/tbody/tr/td[2]/div/div/a
Please let me know if you need anything else.
I am using the following code to extract row data from table.
List<WebElement> rows = getElement(driver,sBy,"table_div_id").findElements(By.tagName("tr"));
where sBy = By.id and table_div_id = id of div in which table is present. This extracts all the rows into arraylist and then i am using code to extract the row data into another arraylist. It is where I am stuck.
Each row from the table is in its own "table" tag so following things are not working :-
List<WebElement> rows = driver.findElements(By.xpath("//div[#id = 'table_div_id']//tr"));
List<WebElement> columns = row.findElements(By.xpath("./td"));
or the approach I used for the previous release of product i.e.
List<WebElement> columns = row.findElements(By.tagName("td"));
So, I used following approach which enabled me to capture all of the visible rows from the table.
List<WebElement> columns = row.findElements(By.xpath(".//table[#class='gridxRowTable']/tbody/tr"));
But after that I faced another issue that is since this table was implemented using dojo, the scrolling was impossible and Selenium was only able to capture the visible rows , so to overcome this I zoomed out in the browser using selenium. This is how i achieved my goal of getting the data.I believe others might have provided me answer if i would have shared some more details. Still , sorry about that and hope my answer helps you all.
instead of
List<WebElement> columns = row.findElements(By.tagName("td"));
try using
List<WebElement> columns = row.findElements(By.xpath("./td"));
Check if this helps. This should give you the td elements. If I have not understood your issue, let me know.
You can use this way-
driver.findElement(By.Xpath("//table[#id=\"table1\"]/tbody/tr[2]/td[1]"));
Regards,
Anuja
Do you have selenium IDE installed? Perform storeText operation on the row you want to retrieve, then xpath will get populated in IDE. There will be multiple xpaths; the most reliable is xpath:position, use that to capture your rows.
And use firebug for better visibilty of your AUT.
Firebug and Selenium IDE are the most basic component of Selenium Framework development.
You can manipulate xpath as you want.

Set datagrid to show just 5 rows per page

I am using DOJO for data grid presentation
<div id="grid_log" dojoType="dojox.grid.DataGrid" store="log" structure="window.layout_log" queryOptions="{deep:true}" query="{}" clientSort="true" rowsPerPage="5"> </div>
but problem is that grid_log doesn't show just 5 rows per page. What is wrong with this tag ? Why ignores rowsPerPage="5" ?
It's look like the rowsPerPage value isn't pages that are "viewed" - but rather, "virtual" pages. That is, the grid only renders portions of itself at a time (in order to improve performance for very large data sets) - and the rowsPerPage value is used to determine how many rows to render at a time.
If you scroll to a position on the grid that it outside the rendered pages, it will render it on demand.
If you are displaying more than 5 rows (due to the height that you have set on your grid) - then setting rowsPerPage to 5 will just cause the viewable portion to be rendered in batches of 5 rows at a time. i.e. there will be a query called to your datastore with start=0 and count=5, and another query sent with start=5 and count=5, etc - until all the visible rows are rendered.
However you can see on this page - it is example of grid with paging. May be it helps you.
As far as new dojo is concerned dojo 1.7.2 here you have the pagination feature where in the pages can be set for the enhanced datagrid.If that is what you want that you will have to import the pagination plugin from new dojo and set it in the grid.You can set the pages in the grid