I am writing selenium automation against an Angular 2 application. In the application, there is a field the user can type in to filter a dropdown that appears as soon as they start typing. The HTML looks like this:
<input> /* this is where the user starts typing */
<datalist>
<option>Option 1</option>
<option>Option 2</option>
...
</datalist>
I am getting the input element and entering partial text:
WebElement inputField = driver.findElement(By.xpath(".//input[#name='inputField']"));
inputField.clear();
inputField.sendKeys(partialText);
This is working as expected. The list drops down and is filtered appropriately. Next I find the element containing the option I want:
WebElement option =
driver.findElement(By.xpath(".//datalist/option[contains(text(), '" + myOption + "')]"));
That call is successful. But when I try to click() on it, I get:
org.openqa.selenium.WebDriverException: unknown error: option element is not in a select
I tried using Actions and Robot, but I ran into two problems:
1) As soon as I tried to press the down arrow, the dropdown closed, and 2) I don't know how, even if I could somehow select an option, I could get the text to see if I had the right option selected.
How can I select an option?
Thanks!
Try clicking the option element using javascriptExecutor.Look at below example.
WebElement elementToSelect =
driver.findElement(By.xpath(".//datalist/option[contains(text(), '" + myOption + "')]"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", elementToSelect);
Related
On clicking a checkbox, the checkbox is highlighted but its not clicked
and i don't get exception .
<input name="include_notice" onclick="javascript:TogglePublishDates();" type="checkbox">
I identify this checkbox with Name and tried using sendkeysReturn and sendKeysEnter.
Note: This test case was running good for quite a long time.No changes were made in Selenium Web driver or Firefox.
You can try to click using java script, as shown below:
JavascriptExecutor e = (JavascriptExecutor)wd;
e.executeScript("arguments[0].click();", driver.findElement(By.name("include_notice")));
If you still observe the inconsistent behavior, you may want to implement the retry mechanism, as shown below:
//1) Finding the check box
WebElement checkBox = driver.findElement(By.name("include_notice"));
//2) Checking whether check box is already checked
if (!checkBox.isSelected()) {
JavascriptExecutor e = (JavascriptExecutor)wd;
e.executeScript("arguments[0].click();", checkBox);
//3) Checking whether first attempt to check the check box worked
if (!checkBox.isSelected()) {
//4) Retrying
checkBox.click();
}
}
Let me know, if you have any further queries.
You can try with these below codes:
driver.findElement(By.name("include_notice")).click(); //find checkbox element and click on it.
Click checkbox using java-script executor.
WebElement checkbox = driver.findElement(By.name("include_notice"));
((JavascriptExecutor) driver).executeScript("arguments[0].click();", checkbox);
If Checkbox is already selected then use this code.
WebElement checkbox = driver.findElement(By.name("include_notice"));
if (!checkBox.isSelected()) //checkbox is not selected then only it will select the checkbox.
{
checkBox.click();
System.out.println(checkbox.isSelected());
}
Passing text through
sendKeys("dublin,south Africa");
It is unable to select the first element in autocomplete.
issue resolved.
this.checkin = function(text,index){
element( by.css('[ng-click="showMapTextBox2()"]') ).click();
// element(by.model("location")).sendKeys(text);
browser.actions()
.mouseMove(element(by.model("location"))
.sendKeys(text))
.perform().then(function(){
browser.sleep(500);
// press the down arrow for the autocomplete item we want to choose
for(i = 0; i < index ; i++){
browser.actions().sendKeys(protractor.Key.ARROW_DOWN).perform();
}
browser.sleep(500);
browser.actions().sendKeys(protractor.Key.ENTER).perform();
});
browser.sleep(3000);
};
spec_test code:
post_text.checkin("new Delhi, India",1);
Manually type what you want the test to perform and inspect the element of the autocomplete. You'll use protractor.ExpectedConditions to wait for that element then click on it after you send keys.
You need to do 2 things:
Enter text. Sometimes it is needed to press Tab to force the autocomplete to display options
Select appropriate drop down option
Example code in C#:
fieldElement.ClearAndSendKeys(partialValue);
fieldElement.SendKeys(Keys.Tab);
GetFieldDropdown(completeValue).Click();
GetFielDropdown() method details depending on your DOM. Here is a simplified example from a project I'm working on:
private IWebElement GetFieldDropdown(string dropdownValue)
{
return FindElement(By.XPath($"//span[contains(.,'{dropdownValue}')]"));
}
Note that if there is a delay in autocomplete being displayed above code won't work unchanged (The FindElement will not return an element). You'll need to wait for the dropdown option to be displayed before clicking on it.
PS - partialValue and completeValue can be the same
I have an angular-material dropdown with a set of options, and am attempting to select one of the options. I'm selecting them as follows:
html file:
<md-select name="myDropdown"
ng-model="addCompany.details.someModel"
ng-change="addCompany.swapDisplayedAreas()"
required>
<md-option value="Company A">Company A</md-option>
<md-option value="Company B">Company B</md-option>
</md-select>
python test:
input = self.browser.find_element_by_name('myDropdown')
input.click()
choice = self.browser.find_element_by_xpath("//*[contains(text(), 'Company A')]")
choice.click()
However, no matter how I try to select the option, I either get the following error:
selenium.common.exceptions.WebDriverException: Message: Element is not
clickable at point (750, 423). Other element would receive the click:
<md-backdrop style="position: fixed;" class="md-select-backdrop
md-click-catcher ng-scope"></md-backdrop>
Or I can see that the element is clicked on, but that the dropdown still stays pulled out. Attempting to click on any other element on the page while the dropdown is still pulled out gives a similar md-backdrop would receive the click error.
Any idea how I can choose a dropdown selection for an md-select element? I've tried disabling md-backdrop for my input elements without any success.
You should try using WebDriverWait to wait until options open from the dropdown and getting visible and clickable before click as below :-
from selenium import webdriver
from selenium.webdriver.common.by import By
from selenium.webdriver.support.ui import WebDriverWait
from selenium.webdriver.support import expected_conditions as EC
#find dropdown and click to open options
input = self.browser.find_element_by_name('myDropdown')
input.click()
#now wait until options getting visible and clickable
choice = WebDriverWait(driver, 10).until(EC.element_to_be_clickable((By.CSS_SELECTOR, "md-option[value = 'Company A']")))
choice.click()
I would guess the issue may be one of the following:
There is another element on the page with the text "Company A" and that element is trying to be clicked even though the dropdown option is clearly the element you want selenium to click. This is because selenium clicks the first element that satisfies the identifier. To check if this is the problem I would use the find elements and check how many elements are found. If that is the problem try using the css selectors such as value.
If you are using chrome I came across a similar problem with the chrome webdriver when testing an angular application.
This is the issue https://code.google.com/p/selenium/issues/detail?id=2766
I tried elegant workarounds but nothing worked...in the end I used the solution by Lukeis.
In java
int n=10;
String errorMessage;
for (int i=1; i<=n; i++)
{
try {
clickThis.click();
break;
} catch(WebDriverException driverException) {
Thread.sleep(1000);
errorMessage = driverException.toString();
}
if(i==n)
{
Assert.fail("Failed to click "+n+" times \n" + errorMessage);
}
}
It pretty much tries to click the element 10 times.
I am really stuck in testing an extJS web based application which contains many drop down combo boxes. and each box have the same class name and ids are dynamically changing each time the page gets loaded.
The combo boxes is not a typical drop down box. It contains a text box, followed by drop down button image and then clicking on that drop down button providese all the options in the drop down box. I want to select a particular element from the drop down box .
When inspect the drop down button element using firepath, its html code is
<div id="ext-gen1103" class="x-trigger-index-0 x-form-trigger x-form-arrow-trigger x-form-trigger-first" role="button"/>
similarly if i inpsect the drop down text box (whose id alone is constant and does not change)the html code is
<input id="NSClientCombo-inputEl" class="x-form-field x-form-text x-form-focus x-field-form-focus x-field-default-form-focus" type="text" placeholder="Select One" name="NSClientCombo" autocomplete="off" aria-invalid="false" data-errorqtip="" style="width: 100%; height: 28px;"/>
and if i inspect any of the drop down elements the html code for that is
<div id="boundlist-1048-listEl" class="x-boundlist-list-ct x-unselectable" style="overflow: auto; height: 187px;">
<ul class="x-list-plain">
<li class="x-boundlist-item" unselectable="on" role="option">****HELP NG****</li>
<li class="x-boundlist-item" unselectable="on" role="option">ABC Inc.</li>
I want to choose "HELP NG" or ""ABC Inc"" from drop down box. But i am really struck how to integrate and how to write selenium webdriver code to choose an element from drop down box since the drop down button contains only id and class (id keeps changing and class name for all the other drop down buttons are same). Have anyone crossed across such scenerios and please help me in sorting out this issue since this is taking away the time totally.:(
You need to use Ext.getCmp() function to retrieve a webElement of this combo.
see the code below.
This code will return the web Element
public static IWebElement ExtJsGetWebElementById(this IWebDriver driver, string id)
{
IJavaScriptExecutor js = (IJavaScriptExecutor)driver;
var script = "return Ext.getCmp('" + id + "').el.dom";
var Element = js.ExecuteScript(script) as IWebElement;
return Element;
}
The next function will be used to open the combo box and set a particular value to it using keyboard shortcuts.
public static void ExtJsSetComboValueWithKeyBoard(this IWebDriver driver, string comboId, string valueToSet)
{
var element = driver.ExtJsGetWebElementById(comboId);
element.SendKeys(Keys.Down);
Thread.Sleep(3000);
element.SendKeys(valueToSet);
Thread.Sleep(3000);
element.SendKeys(Keys.Enter);
Thread.Sleep(3000);
}
to Use the above method, use it like this in your test case.
_webDriver.ExtJsSetComboValueWithKeyBoard("NSClientCombo","ABC Inc.");
I am trying to click on a submneu in amazon.in
I could expand the main menu. but can't click on sub menu. I tried two methods. But its showing errors.
Mail category html code:
<li class="nav_pop_li nav_cat nav_divider_before" id="nav_cat_2">Books</li>
Subcategory html
All Books
I used the following methods
Method 1
driver.get("http://amazon.in");
driver.manage().window().maximize();
Actions actions = new Actions(driver);
WebElement moveonmenu = driver.findElement(By.xpath("//li[#id='nav_cat_2']"));
actions.moveToElement(moveonmenu).moveToElement(driver.findElement(By.xpath("//a[#class='nav_a nav_item']"))).click().perform();
Method 2
driver.get("http://amazon.in");
driver.manage().window().maximize();
//locate the menu to hover over using its xpath
WebElement menu = driver.findElement(By.xpath("//li[#id='nav_cat_2']"));
//Initiate mouse action using Actions class
Actions builder = new Actions(driver);
// move the mouse to the earlier identified menu option
builder.moveToElement(menu).build().perform();
// wait for max of 5 seconds before proceeding. This allows sub menu appears properly before trying to click on it
WebDriverWait wait = new WebDriverWait(driver, 5);
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//a[#class='nav_a nav_item']"))); // until this submenu is found
//identify menu option from the resulting menu display and click
WebElement menuOption = driver.findElement(By.xpath("//a[#class='nav_a nav_item']"));
menuOption.click();
Please tell me why its not working?
In "Method 1", there was issue with hovering, I guess. Must I say, it was just clicking on the "Main Category" element".
In Method 2", the hovering of "Main Category" is properly happening. The only problem was with the xpath you have chosen to click on the "Sub-Category". The xpath is actually associated with multiple elements. Hence, the code was failing.
Just replace the following codes in your Method 2, it will work:-
wait.until(ExpectedConditions.presenceOfElementLocated(By.xpath("//a[#class='nav_a nav_item' and .=\"All Books\"]")));
and
WebElement menuOption = driver.findElement(By.xpath("//a[#class='nav_a nav_item' and .=\"All Books\"]"));
Note:- In the above, I have used All Books as the text to be clicked.
( This text must exactly match with what is being displayed in the webpage.)
Similarly, you can replace All Books with other texts such as "Bestsellers, New Releases & Pre-orders, etc."