In Visual Studio writing the code for Selenium WebDriver, these two codes for the same button work fine only once.
Click the button By Css Selector:
driver.FindElement(By.CssSelector(".follow-text")).Click();
Click the button By XPath:
driver.FindElement(By.XPath("//button[#class='user-actions-follow-button js-follow-btn follow-button btn small small-follow-btn']")).Click();
Until this all correct...
But I want to click to all the buttons not to only the first, and because of the FindElements (in plural) get me error, how can I press click to all the buttons with that same code?
Using this get error:
List<IWebElement> textfields = new List<IWebElement>();
driver.FindElement(By.XPath("//button[#class='user-actions-follow-button js-follow-btn follow-button btn small small-follow-btn']")).Click();
driver.FindElement(By.XPath("//button[#class='user-actions-follow-button js-follow-btn follow-button btn small small-follow-btn'][3]")).Click();
See the capture:
You need to loop through FindElements result and call .Click() on each item :
var result = driver.FindElements(By.XPath("//button[#class='user-actions-follow-button js-follow-btn follow-button btn small small-follow-btn']"));
foreach (IWebElement element in result)
{
element.Click();
}
FYI, you need to wrap the XPath in brackets to make your attempted code using XPath index works :
driver.FindElement(By.XPath("(//button[#class='user-actions-follow-button js-follow-btn follow-button btn small small-follow-btn'])[3]")).Click();
You should use something like that (note the s in findElements)
List<WebElement> textfields = driver.findElements(By.XPath("//button[#class='user-actions-follow-button js-follow-btn follow-button btn small small-follow-btn']"));
and then iterate with a for loop
for(WebElement elem : textfields){
elem.click();
}
List <WebElement> list = driver.FindElements(By.XPath("//button[#class='user-actions-follow-button js-follow-btn follow-button btn small small-follow-btn']"));
And then iterate over the list of elements contained in the list:
int x = 0;
while (x < list.size()) {
WebElement element = list.get(x);
element.click();
}
Related
I want to Invoke a Click in an Element that don't have an ID. I have tried this:
webBrowser1.Document.GetElementById("element>a").InvokeMember("Click");
So i have used the selector but it is not working. If i can't Invoke a Click in an Element without ID then can i Invoke a Click in an Element just by using the Inner Text? Like this : webBrowser1.Document.GetElementByInnerText or something like this where you give the text and it find the element by looking for the text.
Thanks for helping!
You will need to loop through the anchor elements and check for parent foreach if it has the classname you want:
foreach (HtmlElement elem in webBrowser1.Document.GetElementsByTagName("a"))
{
if (elem.Parent.GetAttribute("className") == "element")
{
elem.InvokeMember("Click");
}
}
You can also check for InnerText while looping.
References:
https://msdn.microsoft.com/en-us/library/system.windows.forms.htmlelement(v=vs.110).aspx
https://msdn.microsoft.com/en-us/library/system.windows.forms.htmldocument(v=vs.110).aspx
I have a form that uses Selenium to go to a page and automate tasks for a user. The only part of the page that changes is a CheckBoxList, and I've been trying to extract the labels from it and mirror them to my form's CheckedListBox so users can make the selection there without seeing the page.
So far I have this:
IList<IWebElement> vehicleGroups = Builder.Driver.FindElements(By.ClassName("vehGrp"));
String[] vehicleText = new String[vehicleGroups.Count];
int i = 0;
foreach (IWebElement element in vehicleGroups)
{
vehicleText[i++] = element.Text;
vehicleGroupList.Items.Add(element.Text);
}
Which works as far as getting the correct number of elements and populating the form, but all of the labels in vehicleText are blank (or just a space.)
An example of the HTML for one of the labels is
<label><input type="checkbox" name="searchQuery.vehicleGroups[0].isSelected" value="on" class="vehGrp"> abcd/efgh ijkl mn (opqrst)</label>
Did I miss something or is the " " messing with the label text? The "abcd/efgh ijkl mn (opqrst)" is what I need but it and the potential number of elements can change daily.
vehicleGroups are the <input> elements, not the <label>s that surround them - and these have no text. This is expected behavior.
You need to get the surrounding <label> element, for example using a method like this:
https://stackoverflow.com/a/12194481/7866667
var vehicleGroupInputElements = driver.FindElements(By.ClassName("vehGrp"));
var vehicleGroupNames = vehicleGroupInputElements
.Select(e => e.FindElement(By.XPath("..")))
.Select(e => e.Text)
.ToArray();
I have a form that automates tasks on a page by user input but I'm having trouble interacting with an element on the page. It's a CheckBoxList with dynamic names and number of elements. The HTML looks like this:
<ol id="ratingModification_SupplierContact_content">
<label><input type="checkbox" name="searchQuery.vehicleGroups[0].isSelected" value="on" class="vehGrp"> abcd ef (ghi)</label> <br>
<label><input type="checkbox" name="searchQuery.vehicleGroups[1].isSelected" value="on" class="vehGrp"> jklm no (pqr)</label> <br>
</ol>
Where " abcd ef (ghi)" is the label of the first checkbox.
I already have a button that extracts the labels from the elements and puts them in an array designed with help from users here:
var vehicleGroupInputElements = Builder.Driver.FindElements(By.ClassName("vehGrp"));
var vehicleGroupNames = vehicleGroupInputElements.Select(f => f.FindElement(By.XPath(".."))).Select(f => f.Text).ToArray();
And I populate my form's CheckedListBox with:
vehicleGroupList.Items.AddRange(vehicleGroupNames);
But when I try to send the user selection back to the page I run into issues. I have tried selecting based on index via IndexOf() and the ClassName but can't figure out the syntax to make it work. Failed example:
foreach (int userChecks in vehicleGroupList.CheckedItems)
{
int checkIndex = vehicleGroupList.Items.IndexOf(userChecks);
var checkTarget = Builder.Driver.FindElements(By.ClassName("vehGrp"));
checkTarget.IndexOf(checkIndex).Click();
}
Which won't compile because int checkIndex cant convert to an IWebElement. I have also tried to build a string to address the index with xpath but it can't find the element or throws a no compound names exception. Failed example:
foreach (int userChecks in vehicleGroupList.CheckedItems)
{
int checkIndex = vehicleGroupList.Items.IndexOf(userChecks);
string elementTarget = "searchQuery.vehicleGroups[" + checkIndex + "].isSelected";
var checkTarget = Builder.Driver.FindElements(By.XPath(string.Format("//option[contains(text(), {0}]", elementTarget))).Click();
}
I've also tried to find the element by label via xpath similar to the above but it never finds it. What is the correct way to find the elements and check them?
When you want to click on each checkbox you can use :
var vehicleGroupInputElements = Builder.Driver.FindElements(By.ClassName("vehGrp"));
foreach (IWebElement checkbox in vehicleGroupInputElements)
{
checkbox.Click();
}
Just looked into Xpath syntax and found the answer. With the help of Chrome's 'copy Xpath' function in inspect mode, I found the path needed and successfully clicked the input element.
Example Xpath of the first input is as follows (notice the HTML for label[index] is 1 more than the way C# would count.)
//*[#id="ratingModification_SupplierContact_content"]/label[1]/input
And solution as follows
//Retrieves the checked items from the form and sends them to the page.
foreach (object checkedItem in vehicleGroupList.CheckedItems)
{
//Gets the index of the checked items.
int checkedIndex = vehicleGroupList.Items.IndexOf(checkedItem);
//Adds 1 to the index to match format of the page HTML.
checkedIndex++;
//Puts the index+1 into a string.
string indexText = checkedIndex.ToString();
//Finds the element by index+1.
var clickTarget = Builder.Driver.FindElement(By.XPath(string.Format("//*[#id='ratingModification_SupplierContact_content']/label[" +indexText+ "]/input")));
clickTarget.Click();
I am using C# selenium driver in visual studio for automating my scripts.The data in my radio button gets dynamically generated and I want to select the radio button using index . These are the ways I tried
Method 1
new SelectElement(driver.FindElement(By.Id("XX"))).SelectByIndex(2);Click();
In first method , I am not able to relate the Click to the element
Method 2
IWebElement element = driver.FindElement(By.("XX"));
System.Threading.Thread.Sleep(2000);
element.Click();
In method 2 , I am not sure how to pass the index.
This is my HTML code :
<input type="radio" name="XXXX" id="XXXX" value="5273786">.
So These radio buttons get dynamically generated. For eg, if I have 3 radio buttons, all 3 radio buttons have the same id and name but a different value.
So it would be great if you could let me know how to select the first radio button by passing its value or by selecting the radio button using index.
You should try as below :-
if you to select radio button by their value try as below using By.XPath() :-
IWebElement element = driver.FindElement(By.Xpath("//input[#value = '5273786']"));
element.Click();
Or try as below using By.Id() :-
IList<IWebElement> elements = driver.FindElements(By.TagName("select"));
var element = selectElements.Where(se => se.GetAttribute('value') == '5273786');
element.Click();
if you want to select radio button using index try as below using By.Xpath() :-
IWebElement element = driver.FindElement(By.Xpath("(//input[#id = 'XXXX'])[1]"));
element.Click();
Or try as below using By.Id() :-
IList<IWebElement> elements = driver.FindElements(By.Id("XXXX"));
elements[0].Click();
Hope it helps...:)
I'm trying to automate in a WinForm using a WebBrowser control to navigate and pull report info from a website. You can enter values in textboxes and invoke the click events for buttons and links, but I have not figured out how select a option drop-down .... in a automated way. Anybody recommend how to select a item from a drop-down, given this html example:
<SELECT id="term_id" size="1" name="p_term_in"><option value="">Select Another Term<option value="201050">Summer 2010<option value="201010">Spring 2010<option value="200980">Fall 2009</SELECT>
For others that can learn from entering values to textboxes and invoking click events here's how you do it:
webBrowser1.Document.GetElementById("<HTML ELEMENT NAME>").SetAttribute("value", "THE NAME");
Invoke button or hyperlink click:
webBrowser1.Document.GetElementById("<BUTTON>").InvokeMember("click");
So I've solved entering values and invoking click, but I have not solved selecting a drop-down value.
Assuming you have the following select in the HTML:
<select id="term_id" size="1" name="p_term_in">
<option value="">Select Another Term
<option value="201050">Summer 2010
<option value="201010">Spring 2010
<option value="200980">Fall 2009
</select>
This should allow you to preselect the third value:
webBrowser1.Document.GetElementById("term_id").SetAttribute("value", "201010");
var select = webBrowser.Document.GetElementById("ddlProyectos");
mshtml.HTMLSelectElement cbProyectos = select.DomElement as mshtml.HTMLSelectElement;
var total = cbProyectos.length;
for (var i= 0; i < total; i++)
{
cbProyectos.selectedIndex = i;
if (cbProyectos.value.Contains("13963"))
{
break;
}
}
//cbProyectos.selectedIndex = 4;
select.InvokeMember("onchange");
select.Children[4].SetAttribute("selected", "selected");
var theElementCollection = webBrowser.Document.GetElementsByTagName("select");
foreach (HtmlElement el in theElementCollection)
{
if (el.GetAttribute("value").Equals("13963"))
{
el.SetAttribute("selected", "selected");
//el.InvokeMember("click");
}
}
You will have to select the selected attribute on the option you want.
Given:
<select id="mySelect">
<option>1</option>
<option>2</option>
<option>3</option>
</select>
The following would selct the third option:
webBrowser1.Document
.GetElementById("")
.Children.GetElementsByName("option")[2]
.SetAttribute("selected", "selected");
try this:
add reference to microsoft.mshtml in project --> add reference...
Dim cboTemp As mshtml.HTMLSelectElement
cboTemp = WebBrowser1.Document.GetElementById("myselect").DomElement
cbotemp.selectedindex = 2
having the variable cbotemp set to a select element gives you greater access to the control :)
HtmlElement hField = webBrowser1.Document.GetElementById("ID");
hField.SetAttribute("selectedIndex", "2");
select by index (zero based) not the value....
I'm answering on this post after five years, for the people who are searching a solution of this problem.
If you just need to submit/post a value for the dropdown then this line is sufficient:
webBrowser1.Document.GetElementById("term_id").SetAttribute("value", "200980");
But if you really need to select an underlying OPTION, then:
HtmlElement selectDom = webBrowser1.Document.GetElementById("term_id");
foreach (HtmlElement option in selectDom.GetElementsByTagName("option"))
{
if (option.GetAttribute("value") == "200980")
{
var dom = option.DomElement as dynamic;
dom.selected = true;
// selectDom.InvokeMember("onChange"); // if you need this too
break;
}
}
You can use this:
webBrowser1.Document.GetElementById("term_id").SetAttribute("value",yourText);