I am working on automation with Selenium WebDriver. I need to select a dropdown value but I get an error report.
This is the code I am using:
Select dropdown=new Select(driver.findElement(By.xpath("//*[#id=\"myModal\"]/div/div/div/fieldset/form/div[1]/div[2]/div[4]/div/div/div/div[2]")));
Thread.sleep(30000);
dropdown.selectByIndex(2);
But I get this error: Element should have been "select" but was "div"
I will provide code with pageObject design
public class PageWithSelector{
// initialise element first from element than to selector //
#FindBy(id = "selectID")
private WebElement selectorElement;
private Select selector;
public PageWithSelector(WebDriver driver) {
super(driver);
this.webDriver = driver;
//in constructor init elements and also Select control//
PageFactory.initElements(driver, this);
selector = new Select(selectorElement);
}
// selector via text //
public PageWithSelector selectFromSelectorText(String selectorItemText){
selector = new Select(selectorElement);
selector.selectByVisibleText(facility.getName());
return this;
}
// selector via index //
public PageWithSelector selectFromSelectorIndex(int index) {
selector = new Select(selectorElement);
selector.selectByIndex(index);
return this;
}
}
You have to only initialise Select (object) properly.
After click on drop down you can use this code :
List<WebElement> options = driver.findElements(by.xpath(" your locator"));
for(WebElement element : options){
if(element.getText().equals(" your value from drop down")){
element.click();
}
}
I often use a workaround on that.
type inside the combobox the value you want to select and then automate an ENTER Keypress in the combobox.
Now the value is selected in the combobox.
Optional you also can use the Arrowkeys to navigate in the combobox.
driver.findElement(By.xpath("...")).sendKeys("Something you want to choose");
driver.findElement(By.xpath("...")).sendKeys(Keys.DOWN);
driver.findElement(By.xpath("...")).sendKeys(Keys.ENTER);
Hope this helps!
Related
I have radio buttons that when either radio button is selected, it gets a checked attribute.
This is how the HTML looks:
My implementation of getting the descendant that has a checked attribute:
public TestObject getCheckedTestObjectFromParent(String parentID){
WebDriver driver = DriverFactory.getWebDriver()
WebElement parentWebElement = driver.findElement(By.id(parentID))
List<WebElement> children = parentWebElement.findElements(By.xpath(".//*"))
println(children.size())
for(int i = 0; i < children.size(); i++){
TestObject childTestObject = getTestObjectFromWebElement(children[i])
if(WebUI.verifyElementHasAttribute(childTestObject, 'checked', 10, FailureHandling.OPTIONAL)){
return childTestObject
}
}
}
This is the helper method that I use for converting a WebElement to a TestObject :
public TestObject getTestObjectFromWebElement(WebElement element) {
TestObject object = new TestObject()
object.addProperty("xpath", ConditionType.CONTAINS, getXPathFromElement(element))
return object
}
Helper for getting xpath from WebElement :
protected String getXPathFromElement(WebElement element) {
String elementDescription = element.toString();
return elementDescription.substring(elementDescription.lastIndexOf("-> xpath: ") + 10, elementDescription.lastIndexOf("]"));
}
Am I missing something here or is there something wrong with the WebElement -> TestObject conversion? Also is this possible using only TestObject or only WebElement? If I could get child TestObjects containing certain attributes from a parent TestObject then I wouldn't need to make a mess using WebElements.
Edit
Another image of the HTML, this time with the first radio button checked. As you can see the second radio button no longer has the 'checked' attribute.
To retrieve the WebElement that is currently checked you can use either of the following Locator Strategies:
cssSelector:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.a-toggle.a-toggle--anycase#config-src-laserunits div[id^='config-src-laserunits-']>input.a-toggle__radio[checked]")));
xpath:
WebElement elem = new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#class='a-toggle a-toggle--anycase' and #id='config-src-laserunits']//div[starts-with(#id, 'config-src-laserunits-')]/input[#class='a-toggle__radio' and #checked]")));
I was able to fix this by changing (".//*") to (".//*[#checked='checked']")
parentWebElement.findElement(By.xpath(".//*[#checked='checked']")
will find the element that has the attribute checked = 'checked'
Notice that a list is no longer needed as there can only be 1 checked radio button at a time.
Implementation
public TestObject getCheckedTestObjectFromParent(String parentID){
WebDriver driver = DriverFactory.getWebDriver()
WebElement parentWebElement = driver.findElement(By.id(parentID))
//there is only 1 checked child at a time, so there is no need for a list
WebElement checkedChild = parentWebElement.findElement(By.xpath(".//*[#checked='checked']"))
//convert the WebElement to a TestObject and return
return getTestObjectFromWebElement(checkedChild)
}
Try this Xpath
"//input[#id='config-src-laserunits-wavnmradio' and #checked='checked']"
Example:
List<WebElement> children = driver.findElements(By.xpath("//input[#id='config-src-laserunits-wavnmradio' and #checked='checked']"))
It should return size 1
EDIT
List<WebElement> children = driver.findElements(By.xpath("//input[#id='config-src-laserunits-wavnmradio']"));
for (int i=0;i<children.size();i++)
{
if(children.get(i).getAttribute("checked")!=null)
{
System.out.println("radio button is checked");
}
}
The Code is:
public void setRing(int index, String ringPattern) throws InterruptedException {
List<WebElement> webElementList = driver.findElements(By.xpath(an.getProperty("an_ringPattern")));
webElementList.get(index).click();
List<WebElement> options = webElementList.get(index).findElements(By.tagName("option"));
for (WebElement element : options) {
if (element.getText().equals(ringPattern)) {
element.click();
Thread.sleep(2000);
}
}
}
When I execute this code in debug mode, it is working fine. It selects whatever value I pass to the method.
But when I run this code it is not able to change the value in the drop down. It selects the value in the drop down, but it's not able to set the value.
Please let me know if I am missing something.
If the Exception .Error message display below at org.openqa.selenium.support.ui.WebDriverWait.timeoutException(WebDriverWait.java:80) is being thrown, means that somehow that element is not ready on the frame, the driver is not on that frame or the xpath is wrong.
You can try to switch to the frame where the element is located, like this: driver.switchToFrame("here goes the id of the frame"); You can inspect the ID of the frame or sometimes just passing the integer 0 works. Also, I would rather use wait1.until(ExpectedConditions.visibilityOfElementLocated(element)); instead of wait1.until(ExpectedConditions.presenceOfElementLocated(element));.
When you use presenceOfElementLocated, you cant assure that the element is visible for the driver.
You can use explicit wait in selenium - WebDriverWait
Use below modified code
public void setRing(int index, String ringPattern) throws InterruptedException {
List<WebElement> webElementList = driver.findElements(By.xpath(an.getProperty("an_ringPattern")));
WebDriverWait wait = new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.presenceOfElementLocated(webElementList.get(index)));
webElementList.get(index).click();
List<WebElement> options = webElementList.get(index).findElements(By.tagName("option"));
for (WebElement element : options) {
WebDriverWait wait1 = new WebDriverWait(driver, 60);
wait1.until(ExpectedConditions.presenceOfElementLocated(element));
if (element.getText().equals(ringPattern)) {
element.click();
Thread.sleep(2000);
}
}
}
I have written a piece of code to login into an application which is working fine. Now I have to click an add button, and I have tried it by Id, XPath, ClassName but it just gives me the exception of element not found. I thought I should apply an explicit wait, but it also did not work. Please check my code below:
public static void Login()
{
Browser.Url = "http://example.com";
_username = Browser.FindElement(By.Id("UserName"));
var password = Browser.FindElement(By.Id("Password"));
var loginbtn = Browser.FindElement(By.ClassName("btn-primary"));
_username.SendKeys("admin");
password.SendKeys("123");
loginbtn.Click();
var supplierTab = Browser.FindElement(By.Id("mainSupplier"));
supplierTab.Click();
WebDriverWait wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(20));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
try
{
return d.FindElement(By.Id("btnAddSupplier_SupplierForm"));
}
catch
{
return null;
}
});
var addbtn = Browser.FindElement(By.Id("btnAddSupplier_SupplierForm"));
addbtn.Click();
}
This always gives an exception on the second last line of code that element not found.
Here is the HTML:
Try the following
public static void Login()
{
Browser.Url = "http://example.com";
_username = Browser.FindElement(By.Id("UserName"));
var password = Browser.FindElement(By.Id("Password"));
var loginbtn = Browser.FindElement(By.ClassName("btn-primary"));
_username.SendKeys("admin");
password.SendKeys("123");
loginbtn.Click();
//I think you have mentioned the iframe exist and assuming the element is inside the iframe do the following. If not skip the SwitchTo() part
//you can use name, css to identify the iframe
Browser.SwitchTo().Frame(Browser.FindElement(By.XPath("xpath for the iframe")));
var supplierTab = Browser.FindElement(By.Id("mainSupplier"));
supplierTab.Click();
WebDriverWait wait = new WebDriverWait(Browser, TimeSpan.FromSeconds(20));
IWebElement myDynamicElement = wait.Until<IWebElement>((d) =>
{
return d.FindElement(By.Id("btnAddSupplier_SupplierForm"));
});
//if you think the id is not unique try using xpath or css
//even though you added an explicit wait you never used it
myDynamicElement.Click();
}
Sometimes the element will be existing in the source code but will not be visible for selenium to perform a click operation. Try the below code which will wait until the element is visible:
WebDriverWait wait = new WebDriverWait(_driver, TimeSpan.FromSeconds(20));
IWebElement element = wait.Until(
ExpectedConditions.ElementIsVisible(By.Id("btnAddSupplier_SupplierForm")));
element.Click();
Not sure if this would help, but try calling this function before you click on Add button:
void waitForPageLoad(WebDriver driver)
{
ExpectedCondition<Boolean> pageLoadCondition = new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
wait.until(pageLoadCondition);
}
A NoSuchElementException is thrown when the locating mechanism used is not available in the dom.
A TimeoutException is thrown when your expected condition fails to be true within the time limit. An expected condition can be anything, (exists,visibility,attribute value etc...).
First you want to figure out if the element's locating mechanism you are using is indeed not found in the dom. Here is a good way to manually find out.
Open chrome and navigate to the page.
Open chrome dev tools and click on the console tab.
In the text box type $x("//*[#id='btnAddSupplier_SupplierForm']") and hit enter. This will run an xpath query, basically you are looking for any element that has an id attribute with value "btnAddSupplier_SupplierForm".
If an element appears in the console and is the correct element then it's likely that you are trying to find an element in the dom before the dom is finished loading. If no element appears in the console then you have a bad locator.
Please report your findings.
I'm using Selenium 2 (Webdriver) for automating tests on a webpage. However I wonder if there is way to check checkbox from the list of checkboxes using webdriver framework?
I tried this code but no avail:
IWebElement box = ffDriver.FindElement(By.XPath("//*[#id='ctl00_ContentPlaceHolder1_Adde_div']"));
List<IWebElement> chkbox = box.FindElements(By.TagName("input"));
ffDriver.FindElement(By.Id("ctl00_ContentPlaceHolder1_Add_lstCategory_0"));
//chkbox.g(2).click();
If you already know the id of the checkbox, you can use this method to click select it:
string checkboxXPath = "//input[contains(#id, 'lstCategory_0')]"
IWebElement elementToClick = driver.FindElement(By.XPath(checkboxXPath));
elementToClick.Click();
Assuming that you have several checkboxes on the page with similar ids, you may need to change 'lstCategory_0' to something more specific.
This is written in C#, but it shouldn't be difficult to adapt to other languages. Also, if you edit your post with some more information, I can fine-tune this example better.
Let me know if this works!
I've visited the site and successfully interacted with the checkboxes in the dropdown widget using this code:
/** Set XPath Variables **/
string dropdownWidgetXPath = "//span[contains(#id, 'selInd')]";
string checkboxXPath = "//input[contains(#id, 'selInd')]";
/** Navigate to the page **/
driver.Navigate().GoToUrl("http://www.jobserve.com/us/en/Job-Search/");
/** Click the dropdown widget **/
IWebElement dropdownWidgetElement = driver.FindElement(By.XPath(dropdownWidgetXPath));
dropdownWidgetElement.Click();
/** Identify all checkboxes present **/
var allCheckboxes = driver.FindElements(By.XPath(checkboxXPath));
/** Click each checkbox and wait so that results are visible **/
foreach(IWebElement checkbox in allCheckboxes)
{
checkbox.Click();
System.Threading.Thread.Sleep(500);
}
In Selenium webdriver you can do it like this :
All the check-boxes must be having some unique identifier then you can simply find it out by Id If they dont have a unique id (This is what I encountered while testing a web application) then it must be having some title and name attribute (or some other attribute).
Then you can try this :
driver = new FirefoxDriver();
driver.findElement(By.xpath("//input[#name='mycheckboxgroup' and #title='movies']")).click();
driver.findElement(By.xpath("//input[#name='mycheckboxgroup' and #title='songs']")).click();
By id of the checkbox you could use following code:
IWebElement elementToClick = driver.FindElement(By.ID(ctl00_ContentPlaceHolder1_Add_lstCategory_0));
elementToClick.Click();
If you don't know id then use below code by xpath:
String checkbox = "//input[#type='checkbox']"
IWebElement elementToClick = driver.FindElement(By.XPath(checkbox ));
elementToClick.Click();
The code in selenium is simple:
new WebDriverWait(driver, TimeSpan.FromSeconds(timeToHoldOn)).Until(ExpectedConditions.ElementExists((By.ClassName("ckb"))));
IWebElement dropdownWidgetElement = driver.FindElement(By.ClassName("ckb"));
dropdownWidgetElement.Click();
Thread.Sleep(1000);
var allCheckboxes = driver.FindElements(By.ClassName("ckb"));
foreach (IWebElement checkbox in allCheckboxes) {
checkbox.Click();
System.Threading.Thread.Sleep(250);
}
This is how I check and uncheck all my boxes, it has to have an Id or class.
Id example:
driver.FindElement(By.Id("someid")).click();
ClassName examaple:
driver.FindElement(By.ClassName("someid")).click();
Its short, its sweet and more importantly it works.
Try using this piece of code written in java
String checkboxes = "//*[#type='checkbox']";
List<WebElement> elementToClick = driver.findElements(By.xpath(checkboxes));
for (WebElement AllCheck : elementToClick) {
AllCheck.click();
}
Java, Clicking on multiple checkboxes at a time using the loop.
**Sample Xpath :**
CheckBox1 Xpath : //input[#class='mycheck' and #id='1']
CheckBox2 Xpath : //input[#class='mycheck' and #id='2']
Get all the elements checkbox using findelements:
List WebElement ele =
driver.findElements(By.xpath("//input[#class='mycheck']"));
Make the Xpath as string by leaving the ID and assign the ID as i.
for(int i=1; i<=ele.size(); i++) { driver.findElement(By.xpath("//input[#class='mycheck' and #id='" + + i + "']")).click(); }
i gets the value for every loop and the xpath matches the checkbox and click's it.
You can select each of the radio buttons/checkboxes by selecting the element which contains them and iterating through each one just like an array.
For example, here a ul element contains some radio buttons. I select the ul element first, then I can select each radio by using the correct index (inside the [])
//Select the ul containing the radio buttons I want to click/select
var ul = driver.FindElement(By.Id("ul_containing_radio_buttons"));
//use forloop to click each button in turn
for (var i = 2; i <= 0; i--)
{
var button= ul.FindElements(By.TagName("input"))[i];
//i is the index of the radio button in out ul element
button.Click();
}
Am doing automation tesing using selenium, i need help in regarding how to select radio button.If possible help me with selenium java code.
Assuming you have selenium set up its just:
selenium.click('radio button locator');
You may want to look at the selenium javadoc http://release.seleniumhq.org/selenium-remote-control/0.9.2/doc/java/com/thoughtworks/selenium/Selenium.html
click > xpath=(//input[#type='checkbox'])[position()=1]
click > xpath=(//input[#type='checkbox'])[position()=2]
click > xpath=(//input[#type='checkbox'])[position()=3]
click > xpath=(//input[#type='checkbox'])[position()=4]
etc ...
use this commands to select random and any radio button
public class radioExamJavaScr {
public static void main(String[] args) throws IOException {
WebDriver driver = new FirefoxDriver();
EventFiringWebDriver dr = new EventFiringWebDriver(driver);
dr.get("http://www.makemytrip.com/");
dr.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
((JavascriptExecutor)dr).executeScript("document.getElementById('roundtrip_r').click();");
WebElement one_way = (WebElement)((JavascriptExecutor)dr).executeScript("return document.getElementById('oneway_r') ;");
System.out.println(one_way.isSelected());
WebElement round_trip = (WebElement)((JavascriptExecutor)dr).executeScript("return document.getElementById('roundtrip_r') ;");
System.out.println(round_trip.isSelected());
}
}
In the above example I am selecting radio button with "ROUND TRIP" using "JavaScript".
The last four lines are to verify and see whether the expected radio button is selected in the page or not.
NOTE: I am giving simple easy solution to solve a problem (selecting a radio) in the choosen webpage. A better code can be written. (user can write a method to accept radio ID and loop through all the existing radio button to see which one of them is selected).
I use this method:
String radioButtonId = "radioButtonId";
selenium.focus("id=" + radioButtonId);
selenium.click("id=" + radioButtonId, "concreteRadioButtonValue");
What you can do is this:
Create a method with a WebElement return type, and use the Method findElement(). Example:
WebDriver test;
test = new FirefoxDriver();
public static WebElement checkAndGet(By b) throws Exception {
return test.findElement(b);
}
Store the WebElement and use the Method click(). Example:
WebElement radiobutton = checkAndGet(By.xpath("//span[#class='label ng-binding']");
radiobutton.click();
Hope this helps!
Test Scenario : Select Gender(Female) radio button
Steps:
Launch new Browser
Open URL http://toolsqa.wpengine.com/automation-practice-form/
Select the Radio button (female) by Value ‘Female’
Code :
public static void main(String[] args) throws InterruptedException {
System.setProperty("webdriver.chrome.driver", "C:\\chromedriver_win32\\chromedriver.exe");
WebDriver driver = new ChromeDriver(); // Step 1 - Launch Browser
driver.get("http://toolsqa.com/automation-practice-form"); // Step 2 - Open Test URL
List<WebElement> rdBtn_Sex = driver.findElements(By.name("sex")); //
int size = rdBtn_Sex.size();
System.out.println("Total no of radio button :"+size);
for (int i=0; i< size; i++)
{
String sValue = rdBtn_Sex.get(i).getAttribute("value"); // Step 3 - 3. Select the Radio button (female) by Value ‘Female’
System.out.println("Radio button Name "+sValue);
if (sValue.equalsIgnoreCase("Female"))
{
rdBtn_Sex.get(i).click();
}
}
What you should do all the time is provide a locator for every object within a page and then use a method.
Like
driver.findElement(By.xpath(//CLASS[contains(., 'what you are looking for')])).click();