I have written some code to parse the name from some radio buttons.
<div id="First" class="Size-Inputs">
<input rel="8" type="radio" value="13051374" name="idProduct-13051359"/> <span rel="L">L</span>
<input rel="8" type="radio" value="13051373" name="idProduct-13051359"/> <span rel="M">M</span>
<input rel="8" type="radio" value="13051372" name="idProduct-13051359"/> <span rel="S">S</span>
<input rel="8" type="radio" value="13051375"name="idProduct-13051359"/> <span rel="XL">XL</span> </div>
The problem which I am having when I try to parse the span rel to get the size names eg L,M,S,XL it is only coming up with the value L four times.
The code I am using is;
HtmlNodeCollection link = doc.DocumentNode.SelectNodes("//*[#id='First']/input");
if (link != null)
{
foreach (HtmlNode item in link)
{
string name = item.SelectSingleNode("//*[#id='First']/span").InnerText;
Console.WriteLine(name);
}
Console.ReadLine();
}
I was just wondering why the it is only picking up one value and printing it four times and how can you make it pick up the span rel for each of the variant input. Thanks for any help which you can provide
It seems that you don't need <input> element but <span> element. And <span> is not child of <input>. So assuming that it isn't typo or paste error, you can select <span> directly without selecting <input> element first :
HtmlNodeCollection link = doc.DocumentNode.SelectNodes("//*[#id='First']/span");
if (link != null)
{
foreach (HtmlNode item in link)
{
string name = item.InnerText;
Console.WriteLine(name);
}
Console.ReadLine();
}
Related
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.
I have this HTML
<div class="Radio">
<label>
<input class id="checkbox" name="category" type="radio" value="1">
<strong> TONY STARK </strong>
</label>
<label>
<input class id="checkbox" name="category" type="radio" value="2">
<strong> IRON MAN </strong>
</label>
<label>
<input class id="checkbox" name="category" type="radio" value="3">
<strong> ROBERT DOWNEY </strong>
</label>
I need to select radio buttons based on TONY STARK , IRON MAN , ROBERT DOWNEY as the user passes it as a flexible parameter
I tried this, but any other easy way would definitely help me!
driver.FindElement(By.Id("checkbox"));
for(WebElement radiobutton: radiobuttons)
{
if(radiobutton.getAttribute("value").equals("TONY STARK"))
radiobutton.click();
}
You should try using Xpath to get single radio button and avoid looping as below :-
string Xpath = ".//input[following-sibling::strong[contains(.,'TONY STARK')]]";
Or
string Xpath = ".//label[contains(.,'TONY STARK')]/input";
Use any one of these Xpath to find radio button as :
var radio = driver.FindElement(By.Xpath(Xpath));
radio.Click();
You can use xpath to do that. Try the below xpath .//label[contains(text(),'TONY STARK')]/input[#id='checbox']
Create a class to wrap up radios from now on:
public class RadioButtons
{
public RadioButtons(IWebDriver driver, ReadOnlyCollection<IWebElement> webElements)
{
Driver = driver;
WebElements = webElements;
}
protected IWebDriver Driver { get; }
protected ReadOnlyCollection<IWebElement> WebElements { get; }
public void SelectValue(String value)
{
WebElements.Single(we => we.GetAttribute("value") == value).Click();
}
}
Then you can use it like this:
RadioButtons categories = new RadioButtons(Driver, driver.FindElements(By.Name("category")));
categories.SelectValue("TONY STARK");
I have this other solution:
public void RadioButtonClickByNameAndValue(string name, string val)
{
ScreenComponent.Wait.WaitVisibleElement(By.Name(name));
ScreenComponent.Script.ExecuteJavaScriptCode($"$('[name={name}][value={val}]').click();");
}
In another class I say what value I want to click and in another class I say what is the element.
in my case the radio options value are "True" and "False".
Identify a radio button using XPath with index
IWebElement radioButton = driver.FindElement(By.XPath("//*[#type='radio'][1]");
radioButton.Click();
where:
Asterisk * means wildcard character.
[1] is the position of radio button options ("TONY STARK")
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
I have bunch of radio buttons, and would like to get the text from the labels for each of them. This is what I have tried so far:
IList<IWebElement> radioButtons = wd.FindElements(By.Name("Components[0].Entity.ComponentSubTypeId"));
foreach (IWebElement i in radioButtons)
{
Console.WriteLine(i.Text);
}
I know that they are getting stored in the List, because when I remove the .Text from above, a number of OpenQA.Selenium.Firefox.FirefoxWebElement's are written to the Output console, with it matching exactly to the number of radio buttons located on the page.
Here is the HTML of one of the radio buttons on the page:
<li class="optionListItem">
<span class="floatLeftSmallMargin componentTypeOptions">
<input class="required" id="Components_0__Entity_Entity_ComponentTypeId_PublicationGravure" name="Components[0].Entity.ComponentSubTypeId" type="radio" value="-2147380659" />
</span>
<span class="optionListItemText componentTypeOptions">
<label for="Components_0__Entity_Entity_ComponentTypeId_PublicationGravure">Publication Gravure</label>
<span class="helpButton" data-title="Publication Gravure" data-text="A printing method on a substrate that is subsequently formed into books, magazines, catalogues, brochures, directories, newspaper supplements or other types of printed materials.">
</span>
</span>
<div class="clear"></div>
</li>
But again, when I append the .Text to the index i in the foreach parameter, there is nothing being written to the output console.
The problem is your IList<IWebElement> radioButtons does not contain the label.
It only contains the input which does not have any text. So when you do .Text you will not see any text.
IList<IWebElement> labels = wd.FindElements(By.CssSelector(".optionListItem .optionListItemText label"));
Now Iterate on labels and call .Text, you will see the label names.
The reason why it's returning nothing is because the radio buttons indeed don't have text but you selected them, here is a pratical example of how .Text works:
<li >
<span id="foo">My text</span>
<input name="bar" type="radio"/>I'm not part of the radio
</li>
Now let's extract the text from above
//This will return "My text"
IWebElement spanText= wd.FindElement(By.CssSelector("#foo")).Text
//This will return empty
IWebElement spanText= wd.FindElement(By.XpathSelector("//input")).Text
In your case it should look something like this
IList<IWebElement> labels = wd.FindElements(By.CssSelector(".optionListItem .optionListItemText label"));
foreach (IWebElement i in labels)
{
Console.WriteLine(i.Text);
}
I have the following HTML with in this case 2 items in my ul. Now I want to check (click) the radiobutton where <span title = "SeleniumUpload">. In this HTML there is only one element, but it can be many more.
How do I find this element?
HTML example:
<ul id="ctl00_cpm_AlbumMain_thumbs" class="listAlbums clearfix nospace-bottom" mediastorepartnertype="extrafilm" style="height: 160px;">
<li id="ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|2ab03151-7f88-4924-9471-248786ba46c0_handle" class="folderitemhandle" pagenr="1">
<a title="Bekijk de foto's in dit album." href="/nl/myaccount/myphotos/album.aspx?albumid=2ab03151-7f88-4924-9471-248786ba46c0">
<img id="ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|2ab03151-7f88-4924-9471-248786ba46c0_handle_image" class="lazy" width="100" data-original="http://photos.myserver.com.stage/photos/nastemp1/volume1/8889361a-c9e5-4cbd-a5a3-bbf7612dd370/131016/4/8/48f1d74f-0e62-455a-ba60-2a64fc3ff2a6.thumb.jpg?upd=635175161317600000" alt="Bekijk de foto's in dit album." src="http://photos.myserver.com.stage/photos/nastemp1/volume1/8889361a-c9e5-4cbd-a5a3-bbf7612dd370/131016/4/8/48f1d74f-0e62-455a-ba60-2a64fc3ff2a6.thumb.jpg?upd=635175161317600000" style="display: inline;">
</a>
<label class="albumTitle">
<input id="ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|2ab03151-7f88-4924-9471-248786ba46c0_handle_box" type="radio" onclick="javascript:SelectFolder('ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|2ab03151-7f88-4924-9471-248786ba46c0_handle','1da02a93-76cd-46a5-8dfb-e841aedf4398|2ab03151-7f88-4924-9471-248786ba46c0');" name="ctl00$cpm$AlbumMain$1da02a93-76cd-46a5-8dfb-e841aedf4398|2ab03151-7f88-4924-9471-248786ba46c0_handle$" value="box">
<span title="Test (2)">Test (2)</span>
</label>
</li>
<li id="ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|35b9a18d-6203-4fcb-a05f-decb8672d1c7_handle" class="folderitemhandle" pagenr="1">
<a title="Bekijk de foto's in dit album." href="/nl/myaccount/myphotos/album.aspx?albumid=35b9a18d-6203-4fcb-a05f-decb8672d1c7">
<img id="ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|35b9a18d-6203-4fcb-a05f-decb8672d1c7_handle_image" class="lazy" width="100" data-original="http://photos.myserver.com.stage/photos/nastemp1/volume1/8889361a-c9e5-4cbd-a5a3-bbf7612dd370/131016/7/f/7f2efe77-7754-463e-8eb7-f2853cfa0f07.thumb.jpg?upd=635175162493870000" alt="Bekijk de foto's in dit album." src="http://photos.myserver.com.stage/photos/nastemp1/volume1/8889361a-c9e5-4cbd-a5a3-bbf7612dd370/131016/7/f/7f2efe77-7754-463e-8eb7-f2853cfa0f07.thumb.jpg?upd=635175162493870000" style="display: inline;">
</a>
<label class="albumTitle">
<input id="ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|35b9a18d-6203-4fcb-a05f-decb8672d1c7_handle_box" type="radio" onclick="javascript:SelectFolder('ctl00_cpm_AlbumMain_1da02a93-76cd-46a5-8dfb-e841aedf4398|35b9a18d-6203-4fcb-a05f-decb8672d1c7_handle','1da02a93-76cd-46a5-8dfb-e841aedf4398|35b9a18d-6203-4fcb-a05f-decb8672d1c7');" name="ctl00$cpm$AlbumMain$1da02a93-76cd-46a5-8dfb-e841aedf4398|35b9a18d-6203-4fcb-a05f-decb8672d1c7_handle$" value="box">
<span title="SeleniumUpload (3)">Selenium... (3)</span>
</label>
</li>
This I have so far, but the title attribute of the span returns an empty string. Why is this?
var albums = driver.FindElements(By.ClassName("albumTitle"));
Console.WriteLine("Found {0} photo-albums", albums.Count);
foreach (var we in albums)
{
var span = driver.FindElement(By.TagName("span"));
String title = span.GetAttribute("title"); // returns empty string, I need this title value
Console.WriteLine("we.text:'{0}' title:''{1}",we.Text, title);
// work around
if (we.Text.Contains("Seleni")) // I should be able to check on span title
{
var input = we.FindElement(By.CssSelector("input[id*='ctl00_cpm_AlbumMain_']"));
var id = input.GetAttribute("id");
Console.WriteLine(we.Text + " Id:" + id);
}
}
What you want to do is to use an xpath selector. Something like //*/span[title="SeleniumUpload"] if you want to match that exact title. If you want to just match something close to it, then you'll need to investigate using xpath with contains.