I've a page containing the path
/html/body/div[5]/div[2]/div[2]/div/div[2]/form/div/div[2]/div/div/div[6]/div
of which the bottom-most div resolves to
<div id="tab-topTabs--Lumber">
<div>
<ul>
<li>
2x4
</li>
<li>
4x4
</li>
<li>
4x6
</li>
</ul>
</div>
</div>
both of these will find the right element
WebElement divTopTabLumber_1 = m.getDriver().findElement(By.xpath("/html/body/div[5]/div[2]/div[2]/div/div[2]/form/div/div[2]/div/div/div[6]/div"));
WebElement divTopTabLumber_2 = m.getDriver().findElement(By.id("tab-topTabs--Lumber"));
Problem - calling using the full path grabs the correct three list elements under the deepest div:
List<WebElement> list_lumber_0 = m.getDriver().findElements(By.xpath("/html/body/div[5]/div[2]/div[2]/div/div[2]/form/div/div[2]/div/div/div[6]/div/div/ul/li"));
but these do not:
List<WebElement> list_lumber_1 = divTopTabLumber_1.findElements(By.xpath("//div//ul//li"));
List<WebElement> list_lumber_2 = divTopTabLumber_2.findElements(By.xpath("//div//ul//li"));
reporting 206 elements instead of the expected 3.
Any suggestions/critiques/solutions would be greatly appreciated.
TIA,
Still-learning Steve
I would believe that this id
tab-topTabs--Lumber
is unique in HTMLDOM.
Steps to check:
Press F12 in Chrome -> go to element section -> do a CTRL + F -> then paste the //div[#id='tab-topTabs--Lumber'] and see, if your desired element is getting highlighted with 1/1 matching node.
if it is then use the below code to locate all 3 li nodes:
List<WebElement> list_lumber_2 = divTopTabLumber_2.findElements(By.xpath(".//descendant::li"));
Related
HTML code:
<div id="routingPanel" class="">
<div id="routingPanelRight">
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a>
<span class="fa fa-trash"/>
<span class="type">[srl]</span>
</li>
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="queue" data-id="119">
<a class="ui-corner-all" tabindex="-1">AS-EMEA-NORTH</a>
<span class="fa fa-trash"/>
<span class="type">[queue]</span>
</li></ul></div></div>
I need to click on a button which is having the span class"fa fa-trash" but it is inside li class. And i have list on buttons on the page with li class changing.
I am giving testdata from excel file so i can't use the direct value.
i tried to use this xpath
.//*[#id='routingList']/li[5]/span[1] //testdata1
.//*[#id='routingList']/li[2]/span[1] //testdata2
where li value changes everytime from excel file.
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))).click();
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/span[1]"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.click();
Tried above code but it is deleting only one from the list ,where i have passed two more testdata that needs to be deleted.
Need suggestions Please
According to the information you gave me in comments, I think the problem is that you are trying to get a text from an element that doesn't contain text.
Let's say your testData is AS-HTTS-US-LAN-SW. In the HTML you provided and the xpath you mentioned, you are selecting an autoclosing tag <span class="fa fa-trash"/>. Once this tag is selected, you are trying to get the text inside of it, and there is none.
<ul id="routingList" class="ui-sortable">
<li class="ui-menu-item ui-draggable" style="display: list-item;" role="presentation" data-type="srl" data-id="15">
===========================
<a class="ui-corner-all" tabindex="-1">AS-HTTS-US-LAN-SW</a> ----> The text is contained here
<span class="fa fa-trash"/> ---> No text in that tag
===========================
<span class="type">[srl]</span>
</li>
</ul>
So, basically, you have to modify a little bit your xpath from : //ul[#id='routingList']/li/span[1] to : //ul[#id='routingList']/li/a to get the text, and then go back to the parent node to find your button with : ../span[contains(#class, 'fa fa-trash')]
WebDriverWait wait = new WebDriverWait(driver, 15);
wait.until(ExpectedConditions.visibilityOfElementLocated((By.xpath("//ul[#id='routingList']/li/span[1]")))) // removed the click here because you were clicking on the first element of the list
List<WebElement> options = driver.findElements(By.xpath("//ul[#id='routingList']/li/a"));
for (WebElement option : options) {
if(testData.equals(option.getText()))
option.findElement(By.xpath("../span[contains(#class, 'fa fa-trash')]")).click();
Tell me if it helped
I know you already accepted an answer but there's a more efficient way to do this. You can specify the text you are looking for as part of the XPath. So, you do a single search instead of looping through all the options which can be a performance hit if there are many options. Also, with something like this you are likely to use it more than once so put it in a function.
In this case, the function would take in the string you are looking for and then click the appropriate element.
public void selectRegion(String regionName)
{
driver.findElement(By.xpath("//a[.='" + regionName + "']/following-sibling::span[#class='fa fa-trash']")).click();
}
and you would call it like
selectRegion(testData);
The function looks for an A tag that contains the desired text and then clicks the sibling SPAN with class fa fa-trash.
I have tried to get the number of tweets(tweet count) through selenium
Here is the page source:
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="1 Tweet"
href="/saisiva14"
data-element-term="tweet_stats">
<span class="DashboardProfileCard-statLabel u-block">Tweets</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">1</span>
</a>
</li>
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="38 Following"
href="/following"
data-element-term="follower_stats">
<span class="DashboardProfileCard-statLabel u-block">Following</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">38</span>
</a>
</li>
<li class="DashboardProfileCard-stat Arrange-sizeFit">
<a class="DashboardProfileCard-statLink u-textUserColor u-linkClean u-block"
title="4 Followers"
href="/followers"
data-element-term="following_stats">
<span class="DashboardProfileCard-statLabel u-block">Followers</span>
<span class="DashboardProfileCard-statValue" data-is-compact="false">4</span>
</a>
</li>
I could not able to locate the web element for getting Tweets,Followers & following. The reason is span class names are common for all these elements.Please help me .
To get number of Tweets/ Following/ Followers, You can try the below statements:
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Tweet')]/span[2]")).getText());
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Following')]/span[2]")).getText());
System.out.println(driver.findElement(By.xpath("//a[contains(#title, 'Followers')]/span[2]")).getText());
To click on the Tweets/ Following/ Followers links, You can try the below statements:
driver.findElement(By.xpath("//a[contains(#title, 'Tweet')]")).click();
driver.findElement(By.xpath("//a[contains(#title, 'Following')]")).click();
driver.findElement(By.xpath("//a[contains(#title, 'Followers')]")).click();
or
driver.findElement(By.xpath("//a[./span[text()='Tweets']]")).click();
driver.findElement(By.xpath("//a[./span[text()='Following']]")).click();
driver.findElement(By.xpath("//a[./span[text()='Followers']]")).click();
The above statements are working fine for me.
try this
IList<IWebElement> elements = driver.FindElements(By.ClassName("DashboardProfileCard-stat"));
foreach (IWebElement element in elements)
{
IWebElement ele = element.FindElement(By.ClassName("DashboardProfileCard-statLabel"));
if (ele.Text == "Tweets")
{
return element.FindElement(By.ClassName("DashboardProfileCard-statValue")).Text;
}
}
this is using C#, you can modify accordingly if anyother language is used.
The selector .DashboardProfileCard-stat span:nth-child(2) should give you the collection of web elements pointing to the count. For example in Java:
ArrayList<WebElement> elements = driver.findElements(By.cssSelector(".DashboardProfileCard-stat span:nth-child(2)"))
Then you can use elements.get(0).getText() for tweets. elements.get(1).getText() for following. elements.get(2).getText() for followers. So:
ArrayList<WebElement> elements = driver.findElements(By.cssSelector(".DashboardProfileCard-stat span:nth-child(2)"));
int tweets = elements.get(0).getText();
int following = elements.get(1).getText();
int followers = elements.get(2).getText();
Of course, do your appropriate safety checks, etc. Check the length of the array before access.
This code is in Java :)
capture all the parents of the "SPAN" into a collection item.
Iterate on the collection to find the span elements (which are child of <a> tag) and capture text based on the class name variation statLabel / statValue".
List<WebElement> webElement = driver.findElements(By.xpath("//li[#class='DashboardProfileCard-stat Arrange-sizeFit']//a"));
for (WebElement element : webElement) {
System.out.println(element.findElement(By.xpath("//span[contains(#class,'statLabel')]")).getText());
System.out.println(element.findElement(By.xpath("//span[contains(#class,'statValue')]")).getText());
}
Note:- Here, the Listitems are not under div class
Could able to locate the element but the select function is not working.
HTML used:
<head>
<body id="data-search" class="hassidebar">
<ul id="material-result-list" style="top: 183px; left: 396.5px; width: 270px; display: block;">
<li>
<li>
<li>
<a>nitrate/0.2</a>
</li>
<li>
<li>
</ul>
CODE used:
Try 1:
List<WebElement> listItems = driver.findElements(By.xpath("//ul[contains(#id,'material-result-list')]/li"));
listItems.get(2).click();
Try 2:
List<WebElement> listItems = driver.findElement(By.id("material-result-list")).findElements(By.tagName("li"));
listItems.get(2).click();
(used more combinations, please help on this)
I could retrieve the auto-suggest texts using getText() method [so it confirms that there are no issues on locating the element]
But has trouble on select them and placing under text field for search
List<WebElement> link = driver.findElements(By.xpath("//ul[contains(#id,'material-result-list')]/li"));
String secondoption = link.get(2).getText();
System.out.println(secondoption);
The above script is trying to click on tag "li" and not on anchor tag "a";
Here, the getText() method of tag "li" will return text.
So, we need to click on specific anchor tag.
Solution:
List<WebElement> listItems = driver.findElement(By.id("material-result-list")).findElements(By.tagName("a"));
listItems.get(2).click();
I am unable to select any of the ul id / li class items. I do not see a method for handling this. Anyone able to get it done?
<ul id="game_list">
<li class="game_link" onclick="update_blurb('one');">ONE</li>
<li class="game_link" onclick="update_blurb('two');">TWO</li>
<li class="game_link" onclick="update_blurb('three');">THREE</li>
<li class="game_link" onclick="update_blurb('four');">FOUR</li>
<li class="game_link" onclick="update_blurb('five');">FIVE</li>
<li class="game_link" onclick="update_blurb('six');">SIX</li>
</ul>
I am attempting to select the li class links.
I'm still not exactly sure what is the problem. The right method to click on things is Click Element. You can select any of the <li> elements by a CSS selector or an XPath expression (documentation, see "Locating elements").
For example:
Click Element | css=#game_list > li:nth-child(3)
clicks the third <li> element.
Or by text:
Click Element | xpath=id('game_list')/li[text()='THREE']
selects the <li> element whose text is "THREE".
Figured this out.
I create my own element id and click that new id.
Example:
Assign Id To Element xpath=//li[#onclick="update_blurb('one');"] one
Click Element one
Thanks for checking it out, Slanec.
I'm new on Selenium, new here and my english is not the best.
I'm using selenium with .NET ...
I have a HTML page like this but the number of the events are different:
<div id="eventContent" style="text-align: center;">
<div class="event" id="event-8971062">
<ul>
<li ...></li>
<li ...></li>
<li ...></li>
</ul>
</div>
<div class="event odd" id="event-9224880">
<ul>
<li ...></li>
<li ...></li>
<li ...></li>
</ul>
</div>
</div>
I need to check all datas in the different divs but the count is dynamic and the (event)id is dynamic too. I'm trying to find out the count of the divs at first but this does'nt work. For that I try this:
DefaultSelenium selenium = new DefaultSelenium(...);
decimal count = selenium.GetXpathCount("//div[#id='eventContent']");
but this brings only 1 as result and not two for this example.
when I try:
Console.WriteLine(selenium.GetText("//div[#id='eventContent'][1]"));
it prints all divs, but when I do:
Console.WriteLine(selenium.GetText("//div[#id='eventContent'][1]/div"));
it prints only the first div and I do not understand why.
Could someone be so kind and give me an explaination of whats going on here and where I'm wrong?
Thanks in advance
elur
decimal count = selenium.GetXpathCount("//div[#id='eventContent']");
This will return the count of divs that have an id of eventContent - there is only one div like this, which is why you get a count of 1 (count variables are typically ints rather than decimals, incidentally).
If you want the count of the contained divs, use
int count = selenium.GetXpathCount("//div[#id='eventContent']/div");
This will count the number of div children of the div with an id of eventContent. This should return 2, as desired.
As for your GetText examples, I think GetText will only return the text of the first node that the xpath argument selects. So with
selenium.GetText("//div[#id='eventContent'][1]")
you get the entire text of the parent div, which naturally contains all the child divs, but with
selenium.GetText("//div[#id='eventContent'][1]/div")
you get the text of only the first child div. This xpath selects all the child divs, but GetText operates on a single element only, I believe. If you want to examine the text of each child div in turn, you'll need to first get a count of the child divs, then use for loop to get each one in turn:
for(int i = 1; i <= count; ++i)
{
string childXpath = "//div[#id='eventContent']/div[" + i + "]";
string eventText = selenium.GetText(childXpath);
// Processing of eventText
}
A for loop and manual xpath processing are needed here (rather than the neater foreach), as I believe Selenium doesn't have a way of taking an xpath and returning a collection of elements.
tryed this but returns with 0. I solved this with a while expression where I check with isElementPresent like this:
int a = 1;
while (selenium.IsElementPresent("//div[#id='eventContent'][1]/div[" + a + "]"))
{
// check data here
a++;
}
seems to work so. thanks a lot for your help,
best regards elur