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...:)
Related
I need to edit a dropdownlist item value using c# and selenium.
Here is my code IWebElement objSelect = driver.FindElement(By.Name("classes")); var selectElement = new SelectElement(objSelect); selectElement.SelectByValue("class-55");
I need to edit value "calss-55" to be example "class-a11".
Thanks
Picked up on a small learning project, to find the cheapest car rental by modifying dates.
Website: Costco Travel
Flow: Select Province -> Rental Cars -> Enter Airport code, change date, times.
Issue: Cannot select Pick-up Time or Drop-off Time.
My code so far (works well) -
var rootDir = Directory.GetParent(Environment.CurrentDirectory);
var chromeDriverDir = rootDir.EnumerateDirectories("ChromeDriver", SearchOption.AllDirectories);
if ((chromeDriverDir != null) && (chromeDriverDir.Count() == 0))
Environment.Exit(-1);
var Driver = new ChromeDriver(chromeDriverDir.ToList()[0].FullName);
Driver.Manage().Timeouts().ImplicitWait = TimeSpan.FromSeconds(5);
Driver.Manage().Window.Position = new System.Drawing.Point(0, 0);
Driver.Manage().Window.Maximize();
Driver.Navigate().GoToUrl("https://www.costcotravel.ca/");
Driver.FindElementByXPath("//label[contains(text(), \"Ontario\")]").Click(); // Select Province
Driver.FindElementByXPath("//button[contains(text(), \"Continue\")]").Click(); // Click on Continue
Driver.FindElementByXPath("//li[#data-tab=\"rental-cars\"]/a").Click(); // Click on "Rental Cars" Driver.FindElementById("pickupLocationTextWidget").SendKeys("yyz");
Driver.FindElementByXPath("//li[#class=\"airport\" and #data-value=\"YYZ\"]").Click(); // Select the airport
Driver.FindElementById("pickupDateWidget").Clear(); Driver.FindElementById("pickupDateWidget").SendKeys("01/05/2018"); // Select pick-up date
Driver.FindElementByXPath("//div[#id=\"pickup_time_widget\"]/input").Click();
Now, the issue -
Approach 1
new SelectElement(Driver.FindElementById("pickupTimeWidget")).SelectByText("11:00 AM");
'element not visible: Element is not currently visible and may not be
manipulated
Approach 2
Driver.FindElementByXPath("//div[#id=\"pickup_time_widget\"]/div/ul/li[#data-value=\"07:30 AM\"]").Click();
element not visible
Approach 3 - knew it wouldn't work, but tried it anyway.
new SelectElement(Driver.FindElementByXPath("//div[#id=\"pickup_time_widget\"]/div/ul/li[#data-value=\"07:30 AM\"]")).SelectByIndex(5);
Element should have been select but was li
Any help on selecting a value from pickuptime/dropofftime drop-downs is greatly appreciated! Usually, I have seen many websites implementing just the select tag, but this website also has ul/li tags, which is making it complicated. Or maybe I am over thinking. Please help!
There are underlying select elements that power these dropdowns. But, they are invisible and changed whenever the values in the "ul->li" dropdowns change.
There are two general options here:
make the select elements visible and use the SelectElement class to control the dropdowns
let the select elements be invisible and instead control the "ul->li" dropdown
The first option would just require setting the style of the select elements to "display: block":
IWebElement element = Driver.FindElementById("pickupTimeWidget");
((IJavaScriptExecutor)Driver).ExecuteScript("arguments[0].style = 'display:block';", element);
new SelectElement(element).SelectByText("11:00 AM");
The second option would first require a click to open up a dropdown:
IWebElement dropdown = Driver.FindElementById("pickup_time_widget");
dropdown.Click();
Then, finding a dropdown item by value/text and clicking it:
IWebElement dropdownItem = dropdown.FindElementByXpath(".//li[. = '11:00 AM']");
dropdownItem.Click();
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();
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();
}
I have a GridView and in its OnRowDataBound callback I am adding a new cell and to that cell I'm adding a RadioButton. I've set the GroupName on the radio button, but I can still select more than one button at a time.
How can I make them grouped so that only one radio button can be selected within the group.
EDIT - This is my code:
// Add the radio button to select if this purchased address
// is set the the home address of the contact
e.Row.Cells.AddAt(0, new TableCell());
RadioButton rbSetAddress = new RadioButton();
rbSetAddress.ID = "rdSetAddress" + e.Row.Cells[2].Text;
rbSetAddress.GroupName = "SetAddress";
e.Row.Cells[0].Controls.Add(rbSetAddress);
So I'm setting a unique ID and the same GroupName. ASP.NET is NOT setting the name attribute of the input to the GroupName. So I can select as many radio buttons as I want. This is not what I want to happen. I want to be able to select one and only one in the group identified by the GroupName.
http://www.codeproject.com/KB/webforms/How_group_RButtons.aspx
http://www.developer.com/net/asp/article.php/3623096/ASPNET-Tip-Using-RadioButton-Controls-in-a-Repeater.htm
Basically, when in a repeater of any kind (which a GridView is), the names are no longer all the same from the group property as a result of the way asp.net names things inside a repeater (essentially each control gets a prefix to make it unique).
Are you sure you are giving different names to the radiobuttons on codebehind?
for (int i = 0; i < 10; i++)
{
RadioButton rb = new RadioButton();
rb.ID = "rb"+i;
rb.GroupName="rbGroup";
GridView1.Rows[i].Cells[3].Controls.Add(rb);
}