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.
Related
<div class="bodyCells">
<div style="position:absolute;left:0;">
<div style="overflow:hidden;">
<div title="AAA" class="pivotTableCellWrap">AAA</div>
<div title="BBB" class="pivotTableCellWrap">BBB</div>
</div>
<div>
<div title="AAA-123" class="pivotTableCellWrap">AAA-123</div>
<div title="BBB-123" class="pivotTableCellWrap">BBB-123</div>
</div>
</div>
</div>
I have two bodycells div in my page and I want the count the nested div inside the second one.
Required output :- I want the count=2
Tried Approach :-
int rowCount = driver.FindElements(By.XPath("//div[#class='bodyCells[2]']//div").Count());
Console.WriteLine(rowCount);
you can use the below modified XPath inorder to get the count of second nested div
XPath: //div[#class='bodyCells']/div/div[2]/div
Code:
var rowCount = _driver.FindElements(By.XPath("//div[#class='bodyCells']/div/div[2]/div")).Count;
Console.WriteLine(rowCount);
As per the HTML you have provided to count the nested child <divs> inside the second (parent) <div> you can use either of the following solution:
CssSelector:
List<string> elements = driver.FindElements(By.CssSelector("div.bodyCells div.pivotTableCellWrap[title*='-']"));
Console.WriteLine(elements.Count);
XPath:
List<string> elements = driver.FindElements(By.XPath("//div[#class='bodyCells']//div[#class='pivotTableCellWrap' and contains(#title,'-')]"));
Console.WriteLine(elements.Count);
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"));
}
So I have been using things like this:
webBrowser1.Document.GetElementById("month").SetAttribute("value", exp1);
Which allows me to set values, but now I want to grab a value instead of replacing it.
<div class="contents">
<div class="background">stuff</div>
<div class="content">
<h2>title</h2>
<p>
Blah blah number is <b>0100000</b>
<p>
</div>
</div>
How can I grab the number inside the tag that's inside the content class? Kind of stuck!
Thanks!
It's the code you need:
string theText;
foreach (HtmlElement item in webBrowser1.Document.GetElementsByTagName("div"))
{
if (item.GetAttribute("className") == "content")
theText = item.GetElementsByTagName("b")[0].InnerText;
}
You can always get InnerText or InnerHtml of a chosen tag.
Try this answer: https://stackoverflow.com/a/2958449/1786034
As explained in stackoverflow question
document.getElementById('id').getElementsByTagName('b').firstChild.nodeValue
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')]
I have collection of div tags in the form tag, like this:
<form ...>
<div id="div1"> ... </div>
<div id="div2"> ... </div>
...
...
</form>
I want to display only div1 in the visible area than when user presses next, the next div tag i.e. div2 is displayed, and so on.
How can I achieve this?
I don't have much knowledge about different approaches available to do this, but I have some knowledge of Javascript, so any idea will be appreciated.
P.S. please provide sample code if possible, also I want client-side scripting.
Here's some javascript and html demonstration that may help. Increment a current integer. You could deincrement with -- for back as well. There are many ways to do this. This is just one I thought of.
<img src="mynextbutton.jpg" onclick="showNext()" />
<form ...>
<div id="Div0" style="display:inherit;"> ... </div>
<div id="Div1" style="display:none;"> ... </div>
<div id="Div2" style="display:none;"> ... </div>
...
...
</form>
//---------------------------------------------------
var currentDiv = 0;
function showNext()
{
document.getElementById("Div"+currentDiv).style.display = "none";
currentDiv ++;
document.getElementById("Div"+currentDiv).style.display = "ihherit";
}
If you put all of the element IDs into an array, and then use that to get the next item you can remove the dependence on the ID numbering determining the order that they rotate in, and also prevent them from needing to follow such a rigid format.
//add all element IDs to this array
var elements = ["firstElementID","div2","someConentsID","lastElementID"];
var currentIndex = 0;
//ensure that the first item is visible at the start.
function next()
{
//hide current item.
document.getElementById(elements[currentIndex]).Style = "display:none";
//move up the current index by one, wrapping so as to stay within array bounds.
currentIndex = (currentIndex + 1) % elements.length;
//show the new current item.
document.getElementById(elements[currentIndex]).Style = "display:inline";
}
You can adjust the show/hide code to use JQuery, or whatever other mechanism you want.