We are using Selenium WebDriver and JBehave to run "integration" tests on our web-app. I have a method that will enter a value into a form input.
#When("I enter $elementId value $value")
public void enterElementText(final String elementId, final String value) {
final WebElement webElement = webdriver.findElement(By.id(elementId));
webElement.clear();
webElement.sendKeys(value);
}
But when I try to use this to select an item in a drop-down list it (unsurprisingly) fails
java.lang.UnsupportedOperationException: You may only set the value of
elements that are input elements
How do I select a value in the combo?
This is how to do it:
#When("I select $elementId value $value")
public void selectComboValue(final String elementId, final String value) {
final Select selectBox = new Select(web.findElement(By.id(elementId)));
selectBox.selectByValue(value);
}
The Support package in Selenium contains all you need:
using OpenQA.Selenium.Support.UI;
SelectElement select = new SelectElement(driver.findElement( By.id( elementId ) ));
select.SelectByText("Option3");
select.Submit();
You can import it through NuGet as a separate package: http://nuget.org/packages/Selenium.Support
By using ext js combobox typeAhead to make the values visible in UI.
var theCombo = new Ext.form.ComboBox({
...
id: combo_id,
typeAhead: true,
...
});
driver.findElement(By.id("combo_id-inputEl")).clear();
driver.findElement(By.id("combo_id-inputEl")).sendKeys("The Value you need");
driver.findElement(By.id("combo_id-inputEl")).sendKeys(Keys.ARROW_DOWN);
driver.findElement(By.id("combo_id-inputEl")).sendKeys(Keys.ENTER);
If that doesn´t work this is also worth a try
driver.findElement(By.id("combo_id-inputEl")).sendKeys("The Value you need");
driver.findElement(By.className("x-boundlist-item")).click();
The Selenium paradigm is that you are supposed to simulate what a user would do in real life. So that would be either a click or a keys for navigation.
Actions builder = new Actions( driver );
Action action = builder.click( driver.findElement( By.id( elementId ) ) ).build();
action.perform();
As long as you get a working selector to feed into findElement you should have no problem with it. I have found CSS selectors to be a better bet for things involving multiple elements. Do you have a sample page?
Related
My application have dropdown, and I have this problem:
org.openqa.selenium.support.ui.UnexpectedTagNameException: Element should have been "select" but was "span"
enter code here
#Test
public void cadastrar_serviço_completo() throws InterruptedException {
WebDriver driver = new ChromeDriver();
driver.manage().window().maximize();
driver.get("https://erpforme-hml.alterdata.com.br/");
Thread.sleep(1000);
driver.findElement(By.id("email-login")).sendKeys("*****");
driver.findElement(By.xpath("//form/div[2]/div/input")).sendKeys("*****");
driver.findElement(By.xpath("//button[#id='login-passaporte']")).click();
Thread.sleep(10000);
driver.findElement(By.xpath("//conpass[#id='conpass-tag']/div/div/div")).click();
driver.findElement(By.id("koopon-cabecalho-navbar-cadastro")).click();
driver.findElement(By.id("koopon-cabecalho-navbar-cadastro-estoque-servicos")).click();
Thread.sleep(1000);
driver.findElement(By.id("koopon-produto-servicos-btn-novo")).click();
Thread.sleep(1000);
driver.findElement(By.id("koopon-servico-input-valor-unitario")).sendKeys("10");
WebElement element = driver.findElement(By.id("select2-koopon-servico-select-lista-
codigos-servico-container"));
Select combo = new Select(element);
combo.selectByIndex(2);**
enter image description here
UnexpectedTagNameException this exception is displayed when passing the
reference of the WebElement which is not Select type underneath it
A check is made that the given element is, indeed, a SELECT tag. If it is not, then an UnexpectedTagNameException is thrown.
So instead of select2-koopon-servico-select-lista-codigos-servico-container taking this attribute which is of span if you just pass the select id which is koopon-servico-select-lista-codigos-servico so the exception will not get displayed
WebElement element = driver.findElement(By.id("koopon-servico-select- lista-codigos-servico"));
Select combo = new Select(element);
combo.selectByIndex(2);
I hope the above statements will help you
It is not a select it is a span, it should go through in a loop iterating through both spans capturing them with some common attribute, in this way select the one you need under some condition if you wish.
sorry my english.
Example:
el= driver.find_elements_by_xpath("//span[contains(#class,'select2-election')]")
for span in el :
if span.text == 'xxxxx':
span.click()
I would like to click checkbox based on link text. There are several checkbox in the page so using the link text I wanted to find value of the checkbox so that I can click on the checkbox
Note # All values are dynamically generated
Can you please help correct the code to include this logic. Thanks
driver.get(new URI(driver.getCurrentUrl()).resolve("/admin/lms/tag").toString());
String tag_name = sheet1.getRow(j).getCell(0).getStringCellValue();
driver.findElement(By.linkText(tag_name)).click();
WaituntilElementpresent.isExist();
String tag_value = sheet1.getRow(j).getCell(1).getStringCellValue();
driver.findElement(By.cssSelector("a[href*='"+tag_value+"']")).click();
WaituntilElementpresent.isExist();
String product = sheet1.getRow(j).getCell(2).getStringCellValue();
WaituntilElementpresent.isExist();
driver.findElement(By.cssSelector("input[name='products[]'][value='11']")).click();
https://i.stack.imgur.com/mOBY2.png
You could use an xpath like this:
//tr[.//*[text()='OPIOIDMORTEPID']]//input
this means to locate the td that has this exact text and find the input from it.
If you want to use partial text then:
//tr[.//*[contains(text(), 'MORTEPID')]]//input
You can do it with the following strategy:
find the link by using the link text
get the parent tr element
from there, find the input element of the checkbox
click on the checkbox
This can be done as follows:
WebElement link = driver.findElement(By.linkText("OPIOIDMORTEPID"));
WebElement trElement = link.findElement(By.xpath("../.."));
WebElement checkboxElement = trElement.findElement(By.tagName("input"));
checkboxElement.click();
Check this out:
Get a list of checkbox WebElements that have a common locator i.e. a common class name or tag name (this WebElement would have to have the text or be a parent of the element that has the text).
List<WebElement> checkBoxElements = webDriver.findElements(By.cssSelector("checkbox"));
Iterate through the list and check if the WebElement has the text you are looking for. If it does, click it!
for (WebElement e : checkBoxElements) {
if (e.getText().contains("Something dynamic")) {
e.click();
}
}
Be happy that this works.
I would write this section as a function so that it's reusable.
public static void selectByProductName(String value)
{
driver.findElement(By.xpath("//tr[//a[text()='" + value + "']]/td/input")).click();
}
and then call it like
selectByProductName("OPIOIDMORTEID");
I have couple of Drop-downs on a page; after selecting a value on the First Drop-down, Second Drop-down will get enable and the values get loaded accordingly.
When running manually, after selecting a value in First Drop-down, the page gets loaded and the Second Drop-down gets enabled and the values are listed according to the value selected in First Drop-down.
However, when do automation using Selenium Webdriver (in Java), only the value of First Drop-down gets selected and the Second Drop-down is never enabled or loaded with the values.
Even tried with WebDriverWait as below, but still no luck.
WebDriverWait wait = new WebDriverWait(wd, 50);
wait.until(ExpectedConditions.elementToBeClickable(By.id("event")));
Noticed that only we move out the page (ALT+TAB)and come again to the page the page is getting loaded and the Second Drop-down is enabled.
Below exception is also thrown,
org.openqa.selenium.TimeoutException: Timed out after 50 seconds waiting for element to be clickable: By.id: event
Please advise.
Coding with Page Object Model:
In POM Class:
//Create Object for Page 1
CreateAsset asset = PageFactory.initElements(wd,CreateAsset.class);
//Read the values of First & Second Drop-down from an excel
String list_event_type = readsheet.getRow(1).getCell(2).getStringCellValue();
String list_event = readsheet.getRow(1).getCell(3).getStringCellValue();
//Calling Drop-down methods in Page Factory POM Class
asset.selectEventType(list_event_type);
WebDriverWait wait = new WebDriverWait(wd, 50);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("event")));
asset.selectEvent(list_event);
In Page Factory Class:
//select the given value on the First Drop-down
#FindBy(how = How.ID, using = "eventType")
public WebElement eventType;
public void selectEventType(String eventType)
{
this.eventType.sendKeys(eventType);
}
//select the given value on Sescond Drop-down
#FindBy(how = How.ID, using = "event")
public WebElement event;
public void selectEvent(String event)
{
this.event.sendKeys(event);
}
You are using the same page object to select both values, the problem is that the page object only initializes one (at the very start. This means that the event property never gets initialized with values when the eventType element is changed.
Two options:
1. Re-init the page object after selecting the eventType
//Calling Drop-down methods in Page Factory POM Class
asset.selectEventType(list_event_type);
asset = PageFactory.initElements(wd,CreateAsset.class);
Change selectEventType to return a new page object, essentially this does the same thing as above
public CreateAsset selectEventType(String eventType)
{
this.eventType.sendKeys(eventType);
return new CreateAsset(_driver);
}
Then you would call this in your POM with
asset = asset.selectEventType(list_event_type);
Below workaround works well as expected!
wd.findElement(By.cssSelector("body")).sendKeys(Keys.chord(Keys.ALT, Keys.TAB));
I am using the sendKeys(key,Keys.TAB) method to navigate through a form.
Actions action = new Actions(driver);
CharSequence key = null;
for(int i=0;i<42;i++)
{
action.sendKeys(key,Keys.TAB).build().perform();
}
At the end of every action(a tab key press) I want to know which form element is selected
I want to reach to the 42nd element of the form and cross check whether its the desired element and for that i need to retrieve some of its information.
I am new to selenium and I am not able to figure out a way to achieve this.
You can use WebDriver's TargetLocator class for this purpose.
WebElement currentElement = driver.switchTo().activeElement();
This will return you with current element it focussed currently. If no element is focussed it will return you the body element, which is the case when u launch your browser.
Internally it will be returning u the element returned by document.activeElement. So to verify u can always run as:
JavascriptExecutor js = (JavascriptExecutor) driver;
WebElement currentElement = (WebElement) js.executeScript("return document.activeElement");
I am using selenium, TestNG and java with eclipse to perform an automated test. I'm having success with commands like click on a button (selenium.click ("button"), pass values to textboxes (selenium.type ("component", "value") and clicks too, but when it comes with a component type dropdown list (relating to common or asp.net MVC) I can not select the field with the command selenium.select ("field", "value").
To select the values and even the fields, I am using XPath to it, but even so, with the dropdown list can not, or can partially.
When a drop-down list accepts the value I type, I can use the selenium.click but if not, nothing I've tried so far works.
using webdriver you can do it with Select class i have posted a code which was working below please
have a look on that,Select Class had api to select the drop down values by its index as well as value,have a look on Select api for more info
public static void dropdown()
{
WebDriver driver = new FirefoxDriver();
driver.get("http://demosthenes.info/blog/166/HTML-Forms-Drop-down-Menus");
Select sele = new Select(driver.findElement(By.id("state")));
sele.selectByIndex(1);
}
There are several ways to select elements from dropdown list. Below are some of them you can keep them as common drop-down operation and call what ever method you need.
//select the dropdown using "select by visible text"
public static void dropDownSelectByText(WebElement webElement, String VisibleText){
Select selObj=new Select(webElement);
selObj.selectByVisibleText(VisibleText);
}
//select the dropdown using "select by index"
public static void dropDownSelectByIndex(WebElement webElement, int IndexValue){
Select selObj=new Select(webElement);
selObj.selectByIndex(IndexValue);
}
//select the dropdown using "select by value"
public static void dropDownSelectByValue(WebElement webElement, String Value){
Select selObj=new Select(webElement);
selObj.selectByValue(Value);
}
You can call above methods like
CommonPageOperations.dropDownSelectByValue(selectSubClientFromDropDownXpath,strSubClientName);
Drop down list appear only if mouse move to specific location, Then you have to use Actions as well
public void mouseMoveToExpandIcon(){
Actions action = new Actions(driver);
action.moveToElement(expandButtonXpath).perform();
}
WebElement select = driver.findElement(By.id("selection"));
List<WebElement> options = select.findElements(By.tagName("option"));
for (WebElement option : options) {
if("Germany".equals(option.getText()))
option.click();
}
Actions actions = new Actions(driver);
WebElement dBox1= (new WebDriverWait(driver,10)).until(ExpectedConditions.elementToBeClickable(By.id("selection""))). selectByVisibleText("");
actions.moveToElement(dBox1);
actions.click();
actions.perform();
You have to use Select in selenium to select from the drop down value.
//by ID
WebDriver driver = new FirefoxDriver();
new Select (driver.findElement(By.id("usState"))).selectByVisibleText("FL");
//by XPath
new Select (driver.findElement(By.xpath("xPath for dropdown"))).selectByVisibleText("FL");