How to extract the UI label texts using selenium webdriver - c#

HTML is as follows :
<div id="field-container" class="field-container center">
<form id="param-list" class="ui form">
<div>
<div class="field-group"><label class="input-label" data-tooltip="Australia, Hello" data-position="right center">Beta</label>
<div class="field">
<div class="ui input"><input id="11" value="123" type="text"></div>
</div>
</div>
<div class="field-group"><label class="input-label" data-tooltip="Australia, USA" data-position="right center">Carbon Reduction</label>
<div class="field">
<div class="ui input"><input id="12" value="" type="text"></div>
</div>
</div>
I have above html for my webUI, i am trying to read the all the fields inside (id="param-list") and get the Name which are Beta and Carbon Reduction and also the data for "data-tooltip". Below is what i am trying to do, but i am not able to get it back.
public static List<string> GetFieldsName()
{
List<string> expected = new List<string>();
IWebElement elament = driver.FindElement(container); //container = By.Id("param-list");
IList<IWebElement> fieldNames = elament.FindElements(FiledName); //By.ClassName("field");
foreach (IWebElement fieldname in fieldNames)
{
IList<IWebElement> names = fieldname.FindElements(Inputlable); //By.ClassName("input");
foreach (var name in names)
{
expected.Add(name.GetAttribute("tooltip"));
}
}
return expected;
}
when i do this all i get back is NULL and not sure how to select Name which is Beta and Carbon Reduction from above Html.

As per the HTML you have shared to extract the UI <label> texts you can use either of the following solutions:
public static List<string> GetFieldsName()
{
List<string> expected = new List<string>();
IList<IWebElement> labelNames = driver.FindElements(By.XPath("//div[#class='field-container center' and #id='field-container']//div[#class='field-group']/label[#class='input-label']"));
foreach (IWebElement labelName in labelNames)
{
expected.Add(labelName.GetAttribute("innerHTML"));
}
return expected;
}

Code below will return you tooltips, if you need both text and tooltip use double array or dictionary
public static List<string> GetFieldsName()
{
List<string> expected = new List<string>();
IList<IWebElement> labels = driver.FindElements(By.CssSelector("form#param-list label[data-tooltip]"));
foreach (IWebElement label in labels)
{
expected.Add(label.GetAttribute("data-tooltip"));
//To get text("Carbon Reduction",...) use label.GetText()
}
return expected;
}

Related

Selenium How to find element inside element

Is it possible find element inside another element?
If we have html like this one
<div>
<span>Some text 1 </span>
<p>Other text 1</p>
</div>
<div>
<span>Some text 2 </span>
<p>Other text 2</p>
</div>
<div>
<span>Some text 2 </span>
<p>Other text 2</p>
</div>
is it possible to do something like this
IList<IWebElement> elements=driver.FindElements(By.TagName("div"));
for (int i = 0; i < elements.Count; i++)
{
string text= elements[i].FindElement(By.TagName("span")).Text;
}
I have tried multiple times and in second iteration it is always finding me the the text from first element.
do you want to get p and span inside div ?
using Xpath() or CssSelector()
IList<IWebElement> div_childs = driver.FindElements(By.Xpath("//div/*"));
// or
//IList<IWebElement> div_childs = driver.FindElements(By.CssSelector("div *"));
foreach (var child in div_childs)
{
string text = child.Text;
string tag_name = child.TagName;
}
Use a CSS selector and let it do the work for you...
foreach (IWebElement element in Driver.FindElements(By.CssSelector("div > span")))
{
Console.WriteLine(element.Text);
}
This will find all SPANs that are children (>) of a DIV.

Selenium C# List

Hello Stackoverflow Users,
I have a internet site with 99 list elements.
The diffrence between the elements are only the names.
<li class="_6e4x5">
<div class="_npuc5">
<div class="_f5wpw">
<div class="_eryrc">
<div class="_2nunc">
<a class="_2g7d5 notranslate _o5iw8" title="Name1" href="/"Name1/">"Name1</a>
</div>
</div>
</div>
</div>
</li>
[...]
<li class="_6e4x5">
<div class="_npuc5">
<div class="_f5wpw">
<div class="_eryrc">
<div class="_2nunc">
<a class="_2g7d5 notranslate _o5iw8" title="Name99" href="/"Name99/">"Name99</a>
</div>
</div>
</div>
</div>
</li>
What I want:
I want to take the "title" of each list element and put it in a new list.
What I tried:
List<string> following = new List<string>();
By name = By.XPath("//div[#class='_2nunc']");
IJavaScriptExecutor js = driver as IJavaScriptExecutor;
IList<IWebElement> displayedOptions = driver.FindElements(name);
foreach (IWebElement option in displayedOptions)
{
string temp = displayedOptions[i].ToString();
following.Add(temp);
i++;
}
If I run the code, I only get the element ID, and not the "title" (name34 for example). I hope you have enough information to help me with my problem. Thanks in advance for every help!
To take the title of each list element and put it in a new list you can use the following code block :
List<string> following = new List<string>();
IList<IWebElement> displayedOptions = driver.FindElements(By.XPath("//li[#class='_6e4x5']//a[#class='_2g7d5 notranslate _o5iw8']"));
foreach (IWebElement option in displayedOptions)
{
string temp = option.GetAttribute("title");
following.Add(temp);
}
You're looking to get the a element's title attribute. The selenium IWebElement interface has a GetAttribute method you can use to get the title of your elements.
foreach (IWebElement option in displayedOptions)
{
following.Add(option.GetAttribute("title"));
}

XPath query not working(need find by text)

Hello sow i working with HtmlAgilityPack and i have this problem all elemnts that i need have the same stractior and the same class exept the text of the span like in the code i have span with text Amount and Date sow i need to build link like this
"//span(with text=Amount)[div and contains(#class,'detailsValue ')]");
I need to get data 1,700,000.00 from the div that in the span with text 'Amount' and 14.04.2014 from the div that in the span with text 'Date'
Any ideas?
This what i have now
List<string> OriginalAmount = GetListDataFromHtmlSourse(PageData, "//span[div and contains(#class,'detailsValue ')]");
private static List<string> GetListDataFromHtmlSourse(string HtmlSourse, string link)
{
List<string> data = new List<string>();
HtmlAgilityPack.HtmlDocument DocToParse = new HtmlAgilityPack.HtmlDocument();
DocToParse.LoadHtml(HtmlSourse);
foreach (HtmlNode node in DocToParse.DocumentNode.SelectNodes(link))
{
if (node.InnerText != null) data.Add(node.InnerText);
}
return data;
}
<div class=" depositDetails cellHeight float " style="height: 37px;">
<span class=" detailsName darkgray ">Amount</span>
<br>
<div class="detailsValue float" style="direction:rtl">1,700,000.00 </div>
</div>
</div>
<div class="BoxCellHeight float">
<div class="cellHeight separatorvertical float" style="height: 46px;"> </div>
<div class=" depositDetails cellHeight float " style="height: 40px;">
<span class=" detailsName darkgray ">Date</span>
<br>
<div class="detailsValue float">14.04.2014</div>
</div>
</div>
Actually, the question is not very clear. How about this :
//span[.='Amount']/following-sibling::div[contains(#class,'detailsValue')]]
Above XPath will search for <span> element with text equals "Amount", then get it's following <div> sibling having class contains "detailsValue"
UPDATE :
According to your comment, if I don't misunderstand it, you want both value (div after Amount span and div after Date span). Try this XPath :
//span[.='Amount' or .='Date']/following-sibling::div[contains(#class, 'detailsValue')]

HtmlAgilityPack issue with HTML

I want to get title, image src and other details but here is an issue
<div class="thumb-container">
<a class="featured" title="Spectacularly " href="http://www.site.com"></a>
<div rel="0" id="property_image_1181140" class="thumb">
<a title="*Want this title*" href="*http://www.wanttogetthislink.com*">
<img style="width: 190px; height: 127px; left: -11px; top: 0px;" alt="Spectacularly upgraded 5 bed Family Villa For Sale" src="http://c1369013.r13.cf3.rackcdn.com/1181140-1-mini.jpg">
</a>
</div>
<div class="description-listing">
<div class="heading">
<div class="type">
<label>*5,900* sq.ft.,</label>
<span>*Villa*</span>
<p class="bedroom"><em>*5*</em></p>
<p class="bathroom"><em>*6*</em></p>
</div>
<p class="amount">
<label>AED</label>
<strong>*5,120,000*</strong>
</p>
</div>
Here is my code
var allCarResults = rootNode.SelectNodes("//div[normalize-space(#class)='general-listing']");
foreach (var carResult in allCarResults)
{
var dataNode = carResult.SelectSingleNode(".//div[#class='thumb']");
var carNameNode = dataNode.SelectSingleNode(".//a");
}
Here i want to get everything in **
i do not know how to do that..
The principle is pretty much the same, you'll need to write an XPath for each item and select it from a common anchor:
HtmlNode thumbContainer = doc.DocumentNode.SelectSingleNode("//div[#class='thumb-container']");
HtmlNode link = thumbContainer.SelectSingleNode("./div[#class='thumb']/a");
string linkTitle = link.Attributes["title"].Value;
string linkHref = link.Attributes["href"].Value;
HtmlNode label = thumbContainer.SelectSingleNode("./div[#class='description-listing']/div[#class='heading']/div[#class='type']/label");
string labelText = label.InnerText;
// ... Similar for other items
Alternatively you could iterate through each HtmlNode and its children, then for each item match it against a list of items you're after.

Find the node that has no children. If it has any <span> children, just ignore it

I'm using HTMLAgilityPack. I have something like this:
<div class="address">
<h3>Postadress</h3>
<div class="box-address">Box 27 </div>
<div class="post-address">
16493 KISTA
</div>
</div>
The problem is there are other <div class="address">s.
So I have to find the one that has a <h3> child with the text "Postaddress".
What I need to extract is the value of <div class="post-address"> that is "16493 KISTA".
There are other records returned for <div class="post-address"> that have children and I don't want those to be returned. I'm only looking for <div class="post-address"> that has no children and only contains naked text.
My solution so far is:
var postAddressdiv = doc.DocumentNode.SelectNodes("//div[#class='address']");
if (postAddressdiv != null)
{
foreach (HtmlAgilityPack.HtmlNode node in postAddressdiv)
{
HtmlNode postAddress;
var h3 = node.Descendants("h3");
if (h3 != null)
{
if (h3.First().LastChild.InnerHtml == "Postadress")
{
MessageBox.Show("right place you are.");
postAddress = node.SelectSingleNode("//div[#class='post-address']");
var postAddressChildren = postAddress.Descendants();
if (postAddressChildren == null)
MessageBox.Show("found one!!!!");
}
}
}
}
But it's not working. What am I doing wrong? Thanks.
var nodes = doc.DocumentNode
.SelectNodes("//div[#class='address' and h3='Postadress']/div[#class='post-address']");

Categories