Retrieving a list of WebElements and Identifying them - java

Is there a way to Identify and assign WebElement Names to a list of WebElements? For example using the following convention:W
#FindBy(xpath="")
WebElement listFirstObject;
#FindBy(xpath="")
WebElement listSecondObject;
Forgive me if this is an elementary question, but it seems like it would be a pretty common scenario for any tester as many applications have lists of objects with common names. In my case I have a control list with well over 700 objects and it would be nice to be able to write some iterative method to capture and individually create each common WebElement from the list.
** I have made Updates to my question for further clarification** Taking an entire grid of info is completely new to me so please be specific with the answers as I am trying to understand the logic behind it.
So I have elements I am looking for are Grid Data, I have successfully captured the entire Grid, for example
#FindBy(id="ctl00_SomeGridData_ucControlList_trgControlList_ctl00")
List<WebElement> someGridData;
If I were to individually capture each new addition to the grid it would look as such:
#FindBy(id="ctl00_SomeGridData_ucControlList_trgControlList_ctl00__0")
WebElement someGridObj1;
#FindBy(id="ctl00_SomeGridData_ucControlList_trgControlList_ctl00__1")
WebElement someGridObj2;
#FindBy(id="ctl00_SomeGridData_ucControlList_trgControlList_ctl00__2")
WebElement someGridObj3;
As you can see each individual grid element ends with "__#" Obviously this is an infinite list and I cannot capture every WebElement individually and assign a WebElement value to use for testing. What I am trying to ask is how do I capture this entire list and then if i need to call an individual WebElement later to test how do I do so? I hope this clarifies and thanks for reading.

Ok, now that have edited your question, it's clear what you want to know. Assuming your grid data is in td elements, you can do the following.
#FindBy(css = "td[id^=ctl00_SomeGridData_ucControlList_trgControlList_ctl00__]")
List<WebElement> allGridData;
By using the ^ (which means starts with) you collect all the td elements that have an id starting with ctl00_SomeGridData_ucControlList_trgControlList_ctl00__.

Yes you can do this like below:
List<WebElement> mylist = driver.findElements(By.xpath("ur xpath"));
System.out.println("Size of the list is : " +mylist.size());
This will give you how many webelements are inside your mylist.
Now apply for loop to print the value of the mylist on console
and also in the for loop you can assign them a value like this
for(int i = 0;i<mylist.size();i++){
System.out.println("index of webelements in increasing order is : " + i + mylist.get(i).getText());
// this will assign an index of 0 to max for the weblements in the
list like index 0 = for 1 webelement ,index 1 = for 2nd webelement ,
index 2 = for 3rd webelement and so on
}

Related

Trying to put a list of ids with a common phrase into an array/list in selenium java

I need to get the IDs present in the DOM that start with "starx-" into an array. After that hyphen, there is usually some combination of uppercase, lowercase, and digits - it depends upon the dropdown selected previously. But starx- is common to all ids, no matter what is selected in the previous dropdown (and there are a LOT of options so... no to creating a bunch of "if" statements based on the previous drop down)
To do so, I created this line here to match all of the id's in the DOM that start with starx-:
List<WebElement> allStarX = driver.findElements(By.cssSelector("[id^='starx-']"));
So it's good at finding them. A few print statements I threw in there show me that if there are 4 such IDs in the DOM, it will find them all. If there are 7, it will have 7 elements in that List. Unfortunately , this List doesn't contain the actual IDs. It contains:
[[ChromeDriver: chrome on WIN8_1 (f665490daee44e1039265763f67008cc)] -> css selector: [id^='starx-']]
for each id beginning with starx- that exists in the DOM. Ideally I'd get all the ID using the .getAttribute method, but that's for strings. For example, if I add it onto the end of this:
List<WebElement> allStarX = driver.findElements(By.cssSelector("[id^='starx-']")).getAttribute();
I have a type mismatch. And if I do this:
for (WebElement starx : allStarX)
{
starx.getAttribute("id");
System.out.println(starx);
}
It still prints out a bunch of this:
[[ChromeDriver: chrome on WIN8_1 (f665490daee44e1039265763f67008cc)] -> css selector: [id^='starx-']]
I kind of know why that last one doesn't work, but I don't understand why the first one doesn't.
Absolute xpaths don't seem to work because there are a lot of previous options add and remove things from the DOM.
Can anyone suggest something that might help?
As far as my understanding goes, you are trying to get the IDs which start with the text of 'starx-'. You have created a list of webelements (List<WebElement>) and while extracting the text, you are looping it by not extracting the attribute of the id, which is the issue.
You can handle it as mentioned below:
List<WebElement> allStarX = driver.findElements(By.cssSelector("[id^='starx-']"));
for (WebElement starx : allStarX)
{
System.out.println(starx.getAttribute("id"));
}
Hope this helps.

List of WebElements showing count as 1 using Selenium through Java

I have list of web element, when I apply listName.size() function on
list, it shows count as 1.
Where as in actual the count is not 1.
Below things I have tried -
Tried applying implicit and explicit wait in order to load the long list of web elements properly.
Tried wait.until(ExpectedConditions.visibilityOfElementLocated(listName));
java code :
List<WebElement> listName= driver.findElements(By.xpath("xpath"));
int count = listName.size();
I want the count exact as the number elements of list found by using xpath.
Note: The xpath is valid and correct. Can locate the elements manually with that xpath.
If your usecase is to print the size() of the List matching a specific Locator Strategy instead of using visibilityOfElementLocated() you need to use either of the following solutions:
visibilityOfAllElements(WebElement... elements):
System.out.println(new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfAllElements(driver.findElements(By.xpath("xpath")))).size());
visibilityOfAllElementsLocatedBy(By locator):
System.out.println(new WebDriverWait(driver, 10).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("xpath"))).size());

Selenium WebDriver - Selecting webelements with findElements(By.xpath

I have a webpage from which I have to extract a bunch of names from web elements. My idea is to extract all those elements first using "findElements(By.xpath...", something like this:
List<WebElement> someElements = driver.findElements(By.xpath("XPATH???"));
All those elements have xPath pattern like this:
/html/body/div[1]/div/div/div[11]/div[1]/div[6]/div[1]/div[1]/h2/a
/html/body/div[1]/div/div/div[11]/div[1]/div[6]/div[2]/div[1]/h2/a
/html/body/div[1]/div/div/div[11]/div[1]/div[6]/div[3]/div[1]/h2/a
/html/body/div[1]/div/div/div[11]/div[1]/div[6]/div[4]/div[1]/h2/a
/html/body/div[1]/div/div/div[11]/div[1]/div[6]/div[5]/div[1]/h2/a
As you can see the only change is in this penultimate div that is changing.
MY question is how can I write this line of code for filling a webelement list, what goes into By.xPath()?
Many thanks in advance!
I am not entirely sure what is you are trying to achieve here.
If you want all the divs:
List<WebElement> someElements = driver.findElements(By.xpath("/html/body/div[1]/div/div/div/div[1]/div[6]/div[*]/div[1]/h2/a"));
If not please provide me with an example of the actual elements you are trying to get.
List<WebElement> divs = driver.findElements(By.xpath("/html/body/div[1]/div/div/div[11]/div[1]/div[6]/div"))
Change code portion as follows-
List<WebElement> someElements = driver.findElements(By.xpath("/html/body/div[1]/div/div/div[11]/div[1]/div[6]/div/div[1]/h2/a"));

How to skip first element in webpage and choose second element using selenium

I have two elements in webpage with same linktext in same table structure. I have to ignore first element and select second element everytime if present.
But problem is selenium selecting first element every time, How can I select second element instead of first element(ignore first element)?
I can't use anything other than Linktext to identify that element using selenium, That's the constraint.
when elements having same link text or having same loactors, there is one collection present in java i.e List
create a list of webelements having such kind of scenario, then by there index you can access the elements.
List<WebElement> list1 = driver.findElements(By.linkText("Services"));
for(int i=0;i<list1.size();i++)
{
System.out.println(i+" "+list1.getText());
//this can be used incase number of elements is more and no time to count there index
}
list1.get(1).click();
Here it is for getting second element via link text where I used collection class to store all same kind of elements.
List<WebElement> li = driver.findElements(By.linkText("Services"));;
li.get(1).click();

Selenium webdriver: finding all elements with similar id

I have this xpath: //*[#id="someId::button"]
Pressing it shows a dropdown list of values.
Now, I know all the elements in the list have an id like this :
//*[#id="someId--popup::popupItemINDEX"]
, where INDEX is a number from 1 to whatever the number of options are.
I also know the value which I must click.
One question would be: since I will always know the id of the button which generates the dropdown, can I get all the elements in the dropdown with a reusable method? (I need to interact with more than one dropdown)
The way I thought about it is:
get the root of the initial ID, as in:
//*[#id="someId
then add the rest : --popup::popupItem. I also need to add the index and I thought I could use a try block (in order to get though the exceptions when I give a bigger than expected index) like this:
for(int index=1;index<someBiggerThanExpectedNumber;index++){
try{
WebElement aux= driver.findElement(By.xpath(builtString+index+"\"]"));
if(aux.getText().equals(myDesiredValue))
aux.click();
}catch(Exception e){}
}
Note that I am using the webdriver api and java.
I would like to know if this would work and if there is an easier way of doing this, given the initial information I have.
EDIT: The way I suggested works, but for an easier solution, the accepted answer should be seen
As a rule of thumb, try to select more elements by one query, if possible. Searching for many elements one-by-one will get seriously slow.
If I understand your needs well, a good way to do this would be using
driver.findElement(By.id("someId::button")).click();
driver.findElement(By.xpath("//*[contains(#id, 'someId--popup::popupItem') " +
"and text()='" + myDesiredValue + "']"))
.click();
For more information about XPath, see the spec. It's surprisingly a very good read if you can skip the crap!
That finds and clicks an element with text equal to you desired value which contains "someId--popup::popupItem" in its ID.
List<WebElement> list = driver.findElements(By.xpath("//*[contains(#id, 'someId--popup::popupItem')]"));
That finds all just all elements that contain "someId--popup::popupItem" in their ID. You can then traverse the list and look for your desired element.
Did you know you can call findElement() on a WebElement to search just it's children?
- driver.findElement(By.id("someId")).findElements(By.className("clickable"))
Without a peek on the underlying HTML, I guess I can't offer the best approach, but I have some in my head.
Have you tried using JavascriptExecutor?
If you are willing to write a little JavaScript then this would be straightforward than in java (I think)
All you will need to do is have some JavaScript crawl through the DOM subtree, and return a list of DOM elements matching your criteria. WebDriver will then happily marshall this as List<WebElement> in the java world.
The Safer Method to use here is
int size=driver.findElements(By.xpath("//*[#id='someId::button']")).size();
Start using Index Now
String builtString="//*[#id='someId::button'][";
for(int index=1;index<=size();index++)
{
try
{
WebElement aux= driver.findElement(By.xpath(builtString+index+"\"]"));
if(aux.getText().equals(myDesiredValue))
aux.click();
}
catch(Exception e){}
}
Please Let me know is the above funda is working or not.

Categories