'Handling dynamically generated ids in selenium webdriver
I am trying to automate testing of a webpage that contains list of items. User input item is selected and is deleted. Here, I need to select VD2 and delete that item.
<div id="virtual_domains-content">
<div class="columns">
<div class="left-column">
<h2>Virtual Domains</h2>
<div class="search-row">
<div class="box scrolling list-editable">
<div id="virtual_domains-list" class="list-view">
<div id="virtual_domains-list-11" class="list-item-view">
<div class="content"> VD1 </div>
</div>
<div id="virtual_domains-list-35" class="list-item-view">
<div class="content"> VD2 </div>
</div>
</div>
</div>
The list that I get from the below code has only the first element - VD1. Second element is not captured. Can someone help me resolve the problem
List<WebElement> list = webdriver1.findElements(By.xpath("//*[starts-with(@id,'virtual_domains-list-')]"));
for(WebElement option : list){
System.out.println(option.getText());
if(option.getText().equals("VD1")) {
option.click();
break;
}
Solution 1:[1]
When dealing with random generated IDs I wouldn't recommend using them in your xpath definition. Try something like the following where you use classes instead and start at the top of the tree for a more reliable xpath.
String items = "//div[@id="virtual_domains-content"]/div[@class="columns"]/div[@class="search-row"]/div[@class="box scrolling list-editable"]/div[@class="list-view"]//div[@class="list-item-view"]"
List<WebElement> e = driver.findElements(By.xpath(items));
This will get you a list of all VDs then you can do something like
String item;
Int listItem = 0;
for(WebElement i : e){
item = "(//div[@id="virtual_domains-content"]/div[@class="columns"]/div[@class="search-row"]/div[@class="box scrolling list-editable"]/div[@class="list-view"]/div[@class="list-item-view"])[i]"
e.get(listItem).findElement(By.xpath(i));
...
...
}
You probably want to define i = 1 to start looping there since elements in your list will start at 1 as opposed to list elements that start at 0
Solution 2:[2]
In the above code you posted which is contains class name.So, why don't you use class name.
Here, is my sample python code which can do the trick
options=driver.find_element_by_class_name("list-item-view")
for option in options:
if(option.text=="VD2")
option.click()
Solution 3:[3]
In case of webelements with dynamic Ids, instead of going for Xpath with Ids we can go for other way of finding elements like 'by tagname', CSSlocator,.. it worked for me.
If You still want to use Xpath, You can get the dynamic name or id of the webelement from
driver.findelementsbytagname().
And use that in building Xpath.
Example:
List casereq_table = E.findElementByTagName("table");
tableid1 = tableid.getAttribute("id");
WebElement Certain = E.findElementByXPath("//*[@id='"+tableid1+"']/tbody/tr/td[10]");
certainity = Certain.getText();
Here, the dynamic table id is stored in a string variable, and it is used in the Xpath.
Solution 4:[4]
You should be able to use a fairly straightforward Xpath By locator to find this.
By.xpath("//div[@id='virtual_domains-list']//div[text()=' VD2 ']");
Then click on it like any other element.
You can even just locate the div with the text VD2 in if you aren't concerned about it being in the 'virtual_domains-list' div.
If you're specifically interested in clicking the containing div, you can use
By.xpath("//div[@id='virtual_domains-list']//div[text()=' VD2 ']/..");
With the trailing /.. meaning get that element's parent.
Sources
This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.
Source: Stack Overflow
Solution | Source |
---|---|
Solution 1 | so cal cheesehead |
Solution 2 | Mahesh Reddy Atla |
Solution 3 | Mahesh Reddy Atla |
Solution 4 |