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"));
Related
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.
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
}
I am trying to identify a xpath of a textfield where the class name is "DeleteBackwardTextField" and Origin class is "UITextField". There are no label, name and text it. No other information to identify it.
There are 2 textfield with same above properties.
So my following xpath identifies two text fields.
By.xpath("//textfield[#class='DeleteBackwardTextField']")
How can I identify the xpath of 1 particular field. I assume index can be used. Can anybody provide a syntax for indexing.
Appreciate your help.
You can go with XPATH or CSS. The trick is to have a list of WebElements identified and then you can iterate over it.
List<WebElement> myList = driver.findElements(by.cssSelector(...); //or XPATH;
for (WebElement txtField : myList) {
// do what you need here, for each element at a time
}
Use this xpath.
(//textfield[#class='DeleteBackwardTextField'])[index]
EX: (//textfield[#class='DeleteBackwardTextField'])[1] -> first element when you have many elements matching //textfield[#class='DeleteBackwardTextField']
Note that this xpth - //textfield[#class='DeleteBackwardTextField'][2] has different meaning - it means second child of its parent.
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.
I want to get the links from a page in the hrefor src attributes. I can do:
Elements href = doc.select("[href]");
Elements src = doc.select("[src]");
There is a way to get links that matches the two attributes: Something like:
Elements links = doc.select("[href] OR [src]");
Elements links = doc.select("[href], [src]");
That should work.
Edit: more explanation can be found in the online cookbook, particularly in the subsection "Selector combinations"
http://jsoup.org/cookbook/extracting-data/selector-syntax