Dear Selenium Webdriver Specialists,
I am new to this framework and needed a bit of advice on how to locate / find all the search results from a sales property listing website. Below is a working code
which has successfully found all the properties using Selenium Webdriver but I don't know how to use findElements(by...) to pick up every results returned by
this website:
WebDriver driver = new FirefoxDriver();
driver.get("http://www.domain.com.au/?mode=buy");
// Enter the query string "3000"
WebElement query = driver.findElement(By.xpath(".//*[#id='ctl00_SearchMoreCriteria_Radar_searchToBuy']"));
query.sendKeys("3000");
WebElement searchButton = driver.findElement(By.xpath(".//*[#id='ctl00_SearchMoreCriteria_Radar_Search']"));
searchButton.click();
// Sleep until the div we want is visible or 5 seconds is over
long end = System.currentTimeMillis() + 5000;
Could anyone offer some advice on this query? I also like to include a pausing mechanism before locating / finding all the returned results?
Many thanks,
Jack
Thank you Santoshsarma very much for your response but I am struggling to apply your suggestion onto the following returned web query page output snippet:
<h3>
<a id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_hypAddress" href="/Property/For-Sale/Penthouse/VIC/Melbourne/?adid=2009775619">602/73 Flinders Lane, Melbourne</a></h3>
<dl class="cN-featDetails">
<dt class="proptype">Property type</dt>
<dd id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_ddPropertyType" class="propertytype type-house" title="Property type: House">House</dd>
<dt class="bedrooms">Bedrooms</dt>
<dd id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_ddBedrooms" class="bedrooms" title="Bedrooms">3</dd>
<dt class="bathrooms">Bathrooms</dt>
<dd id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_ddBathrooms" class="bathrooms" title="Bathrooms">4</dd>
<dt class="carspaces">Car spaces</dt>
<dd id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_ddCarSpaces" class="carspaces" title="Car spaces">2</dd>
</dl>
</div>
<div class="main-wrap">
<ul class="photo cfix">
<li>
<a id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_hypMainThumb" tabindex="-1" class="contain" href="/Property/For-Sale/Penthouse/VIC/Melbourne/?adid=2009775619"><img id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_imgMainThumb" title="602/73 Flinders Lane, Melbourne" src="http://images.domain.com.au/img/2012625/18127/2009775619_1_PM.JPG?mod=120925-150000" alt="Main photo of 602/73 Flinders Lane, Melbourne - More Details" style="border-width:0px;" /></a>
</li>
<li class="last">
<a id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_hypSecondThumb" tabindex="-1" class="contain" href="/Property/For-Sale/Penthouse/VIC/Melbourne/?adid=2009775619"><img id="ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_imgSecondThumb" title="602/73 Flinders Lane, Melbourne" src="http://images.domain.com.au/img/2012625/18127/2009775619_2_PM.JPG?mod=120913-125823" alt="Photo of 602/73 Flinders Lane, Melbourne - More Details" style="border-width:0px;" /></a>
</li>
</ul>
List AllSearchResults=driver.findElements(By.id("ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_hypAddress"));
There is an index in ctl01 that needs to cycle through to get all search results which would be slow according other similar threats. Is there a better approach to use findElement() on a WebElement to search just its children but I am at a lost on where to locate the root. Are you able to confirm whether this approach would work & perhaps pin point where the root of the list of results from the following URL query result page:
http://www.domain.com.au/Search/buy/Property/Types/Apartment-Unit-Flat/Duplex/House/New-Apartments-Off-the-Plan/New-Home-Designs/New-House-Land/Penthouse/Semi-Detached/Studio/Terrace/Townhouse/Villa/State/VIC/Area/Inner-City/Region/Melbourne-Region/Suburb/Melbourne/?bedrooms=1&bathrooms=1&carspaces=1&from=450000&searchterm=3000&pois=PriSchl|1|2|2000
Your patience for my lack of experience in this area would be very much appreciated.
findElements method will return List of WebElements which has same locator.
> List<WebElement> AllSearchResults=driver.findElements(By.id("value"));
Run the above list in loop to get each individual search result.
for(WebElement eachResult:AllSearchResults)
{
eachResult.click();
}
If this is still unresolved, try the following for locating the h3 link
(new WebDriverWait(driver, 10)).until(ExpectedConditions
.visibilityOfElementLocated(
By.id("ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_hypAddress")));
This code waits for the given element for 10 seconds and then throws a TimeOutException.
Regards, Christian
May be we can solve it with the help of a custom xpath using ID property.
Code goes like this:
List AllSearchResults=driver.findElements(By.xpath("//*[contains(#id='SrchResLst_rptResult')]"));
or like this:
List AllSearchResults=driver.findElements(By.xpath("//*[contains(#id='ctl00_ctl00_Content_Content_SrchResLst_rptResult_ctl01_EliteListingTemplate_')]"));
Here we used * because some search results are having a combination of tags <a> and <dd>
The xpath searches for all the elements which is containing "SrchResLst_rptResult" string as a value of ID property.
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 a list of li's within an ul, where the li would look like:
<li class="list-group-item operator">
<div class="pull-right">
<a href="/index.php?page=excursion_transport&sub_page=operators&mode=edit&id=10" class="tooltip-hook" title="" data-original-title="Rediger operatøren">
<span class="fa fa-pencil fa-fw"></span>
</a>
<span class="text-muted tooltip-hook" title="" data-original-title="Operatøren kan ikke slettes da den har transportmidler.">
<span class="fa fa-trash fa-fw"></span>
</span>
</div>
Ice Cap Tours
</li>
How do I with Selenium IDE find the text "Ice Cap Tours" and at the same time press the pencil that are present in the "span class='fa-pencil'"?
If you're looking to interact with them you'd need the following locators
//a[contains(text(),'Ice Cap Tours')]//..
//span[contains(#class, 'fa-pencil')]
The first will just look for the span containing the text you're after, and the "//.." navigates up to the parent element (the a tag) to click on the link
The second one will look for the span whos class contains "fa-pencil", you may have had trouble with the other suggested locators as they will have been looking for an exact match of the class, rather than just a class which contains that one
Use click or clickAndWait Command and in Target you can write xpath as //a[text()='Ice Cap Tours']//preceding-sibling::div/a[#class='fa-pencil']
You can try bellow xpath :
//a[normalize-space()='Ice Cap Tours']/preceding-sibling::div/a/span[contains(#class,'fa-pencil')]
Here is explanation :
//a[normalize-space()='Ice Cap Tours']
This will locate your anchor tag which having text Ice Cap Tours
/preceding-sibling::div
Used to navigate to locate the preceding sibling node of a tag. In your case div is preceding sibling of a tag
div/a/span[contains(#class,'fa-pencil')]
Will locate your span which having class name pencil
I am new to Selenium. I am trying to click a sub menu option which has the following code:
<div class="nav-level nav-level-open">
<ul id="menu_0af0fc80e81924533d028c395adb60e8">
<li class="nav-item">
<a class="" href="?s=jobs&ss=jobs&mode=list">
<i class="icn-next" aria-hidden="true"></i>
<span> All Jobs - jobs/ internships/ campus interviews</span>
</a>
</li>
I am trying to click the button here labelled, "All Jobs - jobs/ internships/ campus interviews". Being a menu, there are multiple such links with the same class name. I would prefer locating the element with Css locator or Xpath. Can someone please help me?
Try the below xpath, i am assuming the string "All Jobs - jobs/ internships/ campus interviews" is not repeated in webpage
driver.findElement(By.xpath("//span[contains(text(),' All Jobs - jobs/ internships/ campus interviews')]"));
you can use above strategy in finding target exlements. if the element's display string is not dupicated in webpage
Intall the FirePath Plugin in firefox first and then inspect the button using the firepath. Try with the following code -
driver.findElement(By.xpath("//copy paste the xpath here")).click(); //driver is the reference of WebDriver interface.
driver.FindElement(By.XPath("//ul[#id='menu_0af0fc80e81924533d028c395adb60e8']/li/a")).Click();
Try out this:
WebDriver driver = new FirefoxDriver();
WebeElement element ;
element = driver.findElement(By.xpath("//*[ul[#id='menu_0af0fc80e81924533d028c395adb60e8']/li/a");
driver.click;
Try this :
driver.findElement(By.xpath("//span[contains(text(),' All Jobs - jobs/ internships/ campus interviews')]"));
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());
}
I want to get tooltip information enabling on JavaScript. I have tried with below code but its shown null every time.
Java Code:
Actions action = new Actions(driver);
WebElement element = driver.findElement(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a"));
action.moveToElement(element).build().perform();
System.out.println(driver.findElement(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a")).getAttribute("data-original-title"));
HTML Code is:
<tr class="single" name="Tasks_59c777d9-8d16-694a-7307-52caad36d751">
<td>
</td>
<td data-type="custom_task_name">
<span class="list" sfuuid="3840" data-original-title="">
<div class="ellipsis_inline" data-original-title="">
Task Testing
<br/>
Toney Harber
</div>
</span>
</td>
I have tried with span tag but this also shows null.
I am providing you 2 options try both.
Option 1
Please try below. It will return you a list. Loop through it. If there is only one span then you can get the element and then get the attribute value.
driver.findElements(By.xpath("//span[#data-original-title]"))
Option 2
Instead of
driver.findElement(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a"))
use findElements
driver.findElements(By.xpath("//*[#id='content']/div/div/div[1]/div/div[2]/div[2]/div/div[3]/div[1]/table/tbody/tr[1]/td[2]/span/div/a"))
It will return a list of web elements. Loop thorough it you might get more than one element.