Selenium WebDriver - hidden select and anchor [duplicate] - selenium

This question already has answers here:
Selenium WebDriver - get options from hidden select [closed]
(2 answers)
Closed 7 months ago.
I'm having a big problem with select on one page.
Code:
<select name="fw3k_ad_input_et_type_group" class=""
id="_id_fw3k_ad_input_et_type_group"
onchange=" eurotax.change_type_group( this.value ); "
style="display: none; ">
<option value="0"> --- odaberite tip --- </option>
<option value="-1" class="special">> nema mog tipa </option>
<option value="16390">CD</option>
<option value="17605">S</option>
<option value="17636">SE</option>
</select>
--- odaberite tip ---
Select is hidden and a href="" is visible part that changes its text depending on a selected option.
I don't know how to manage that. I can get all options with JavascriptExecutor and I can use a.click() to view dropdown box but I don't know how to click on some option.
I have tried to use Select class and .getOptions() method but it doesn't work with hidden select and I cannot change <a href=""> text.

A little confused with the question but have you you tried
WebElement element = driver.findElement(By.id("fw3k_ad_input_et_type_group"));
Select select = new Select(element);
Then use either
select.selectByValue(value);
select.selectByVisibleText(text);
select.selectByIndex(index);

1st way:
it is not the problem to click any element using the same js. As you know how to get any option the last actions remaning is to perform a click.
This should work for you:
WebElement hiddenWebElement =driver.findElement(By(..selector of the element....));
((JavascriptExecutor)driver).executeScript("arguments[0].click()",hiddenWebElement);
2nd way:
String cssSelector= ...//i gave them in your previous question
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\'"+cssSelector+"\');");
stringBuilder.append("x.click();");
js.executeScript(stringBuilder.toString());
3rd way:
using actions builder, advanced user actions API. You can read about it here
And code will be smth like that:
WebElement mnuElement;
WebElement submnuElement;
mnEle = driver.findElement(By.Id("mnEle")).click();
sbEle = driver.findElement(By.Id("sbEle")).click();
Actions builder = new Actions(driver);
// Move cursor to the Main Menu Element
builder.moveToElement(mnEle).Perform();
// Giving 5 Secs for submenu to be displayed
Thread.sleep(5000L);
// Clicking on the Hidden SubMenu
driver.findElement(By.Id("sbEle")).click();
You can also some additional info here
Hope this somehow helps you)

driver.findElement(By.name("_id_fw3k_ad_input_et_type_group")).sendKeys("16390");
worked for me for something very similar.

Related

How to click on a Dropdown menu through Selenium

Actions a= new Actions(driver);
WebElement mainmenu=driver.findElement(By.xpath(".//*[#id='yui-gen2']/a"));
a.moveToElement(mainmenu).build().perform();
WebElement Sub = driver.findElement(By.xpath(".//*[#id='helpAbout']"));
a.moveToElement(Sub).build().perform();
Sub.click();
Code couldn't able to click on submenu it just stops at 3rd line.
With selenium you should be able to just do the following:
Select variableName = new Select(DropDownElementLocator);
variableName.selectByVisibleText("Whatever");
// or
variableName.selectByIndex(1);
Your code is 90% correct, just replace following code:
a.moveToElement(Sub).click().perform();
build() method works for hover on element,and after hover on it we have to click element.
Once you Mouse Hover over the element identified as By.xpath(".//*[#id='yui-gen2']/a") and therefafter invoke moveToElement(mainmenu), build(), perform(), at this stage the element identified as By.xpath(".//*[#id='helpAbout']") is visible and interactable. So you need to invoke click() directly as follows :
Actions a= new Actions(driver);
WebElement mainmenu=driver.findElement(By.xpath(".//*[#id='yui-gen2']/a"));
a.moveToElement(mainmenu).build().perform();
WebElement Sub = driver.findElement(By.xpath(".//*[#id='helpAbout']"));
Sub.click();
import org.openqa.selenium.support.ui.Select;
WebElement selectElement;
selectElement= driver.findElement(By.id("yourElementId"));
or
selectElement driver.findElement(By.xpath("yourElementXpath"));
Select selectObject = new Select(selectElement);
The Select object will now give you a series of commands that allow you to interact with a element. First of all, there are different ways of selecting an option from the element.
<select>
<option value=value1>Bread</option>
<option value=value2 selected>Milk</option>
<option value=value3>Cheese</option>
</select>
// Select an <option> based upon the <select> element's internal index
selectObject.selectByIndex(1);
// Select an <option> based upon its value attribute
selectObject.selectByValue("value1");
// Select an <option> based upon its text. Example: Bread
selectObject.selectByVisibleText("Bread");

Best approach to use when values are dynamically created?

I'm looking for some advice on how to select a WebElement.
When I click a button that creates a new 'page', the given value is dynamic, in that it is totally random and not sequential. I would expect it to follow something like: page 1 = 0, page 2 = 1, page 3 = 2, etc.
By default I begin with a page, and its value is c3. Although when I trigger a button to create new pages the values appear as follows:
<select class="j-currentPage f-feature-A" name="currentPage"> <option value="c3">New Page</option> <option value="c277">New Page 2</option> <option value="c383">New Page 3</option> <option selected="" value="c461">New Page 4</option> </select>
So when I attempt to use the following:
List<WebElement> option = chrome.findElements(By.tagName("option"));
option.get(0).click();
option.get(1).click();
option.get(0).click();
It's obviously failing as the values are c277, c346 etc etc, and there is no way of knowing what the values will be in a new session as they will always be different.
The stacktrace is throwing a StaleElementReferenceException because its not in the DOM.
How can I select each page when the values are completely random?
I'm using Webdriver and JUnit4.
EDIT
Test method: to create some new pages.
#Test
public void createANewPage(){
WebDriverWait wait = new WebDriverWait(chrome, 60);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));
WebElement newPage = chrome.findElement(By.cssSelector("span.j-addViewBtn.ss-layers"));
newPage.click();
List<WebElement> option = chrome.findElements(By.tagName("option"));
option.get(1).click();
option.get(0).click();
}
Then a few tests later I want to call back the created page(s)
#Test
public void goToPage(){
new WebDriverWait(chrome, 60).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));
List<WebElement> option = chrome.findElements(By.tagName("option"));
option.get(0).click();
option.get(1).click();
option.get(0).click();
}
I receive a org.openqa.selenium.StaleElementReferenceException at the point of the third option.get(0).click();
However I feel as though I'm approaching this the wrong way as the values are dynamically created <option value="c3">New Page</option>
<option value="c207">New Page 2</option>
<option value="c288">New Page 3</option>
<option selected="" value="c366">New Page 4</option>
The StaleElementReferenceException does not mean that it is not in the DOM. It means that the DOM has changed since you found that object and therefore may be deleted or changed. The change coudld be due to the page reloading or HTML refreshed via javascript. Either way, Webdriver throws the error because it thinks it is probably good idea to refind objects as the page has changed.
If you refind the elements, then it will work. You are finding by tag name, so the fact that ids have changed, should have no impact.
The following would work but does have performance issues;
chrome.findElements(By.tagName("option")).get(0).click
chrome.findElements(By.tagName("option")).get(1).click
chrome.findElements(By.tagName("option")).get(2).click
There will a better way to approach your problem for your particular application but hopefully understanding what stale elements actually indicates, will help you solve your issue.
None of the FindElement() strategies support using regular expressions for finding elements.
Though there is another way using regex, might help you
List<WebElement> option = chrome.findElements(By.tagName("option"));
now loop on the options and getText. Then do the regex check programmetically
Below is a demo code will not run. Please transfer it to jave
foreach(WebElement link in links)
{
string text = link.Text;
if (Regex.Match("your Regex here", text))
{
matchingLinks.Add(text);
}
}
foreach(string linkText in matchingLinks) // now you have the texts even if they are dynamics
{
WebElement element = driver.findElement(By.LinkText(linkText));
element.Click();
// do stuff on the page navigated to
driver.Navigate().Back();
}
OKay, I've just managed to solve the issue with the help of the contributors to this question.
It seems as though I just needed to use xpath instead of List<WebElement> so the below code now selects the pages I want.
#Test
public void jGoToPage(){
new WebDriverWait(chrome, 60).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("select.j-currentPage.f-feature-A[name=\"currentPage\"]")));
WebElement page1 = chrome.findElementByXPath("//option[contains(.,'New Page')]");
page1.click();
WebElement page2 = chrome.findElementByXPath("//option[contains(.,'New Page 2')]");
page2.click();
WebElement selectPage1Again = chrome.findElementByXPath("//option[contains(.,'New Page')]");
selectPage1Again.click();
Perhaps not the best code, but if anyone would like to suggest a better way to refine it, please comment so others can learn.
The reason I declared New Page twice was because I was receiving a staleElementReferenceException again. So by simply attempting to perform page1.click(); immediately after page2.click(); is when that happened which is why I declared it as selectPage1Again
I also used this question to help with the solution.

Google signup page: Selenium cannot find select listbox

I would like to use selenium to select a value in the Month list box for birthday on google page: https://accounts.google.com/SignUp
When I view page code, the code for the list box looks like:
<select id="BirthMonth" name="BirthMonth">
<option value="">Month</option>
<option value="01" >January</option>
<option value="02" >February</option>
......
<option value="12" >December</option>
</select>
However, when I use Selenium driver.findElements(), I cannot find this select and its option elements. It looks like every list box on this page (as well as gender one) cannot be accessed.
Can anyone give some suggestion how Selenium can access to these elements? Thanks
The code is as follows:
driver.get("https://accounts.google.com/SignUp");
List<WebElement> inputElements = driver.findElements(By.xpath("//select[#name]"));
for(WebElement input: inputElements){
if(input.getTagName().equals("select")){
Select selectinput = new Select(input);
List<WebElement> selects = selectinput.getOptions();
}
}
I did not get the select element I want.
EDIT:
I also try to use Select select1 = new Select(driver.findElement(By.tagName("select"))) but still cannot find this BirthMonth list box. It is wired. There is only one listbox which is inside Javascritpt that can be accessed.
Here's a suggestion for how access these elements in Selenium, with a Java example.
It gets a little messy with CSS Selectors (which I generally prefer) because this month field has some fancy widgets on it to help hide your choices for security reasons. So here we go with XPath as our selector mechanism.
Take notice I broke it down - 1st by selecting the month, and 2nd by selecting the month itself. Hope that helps.
public class Google Month Example {
public static void main(String[] args) throws Exception {
// Just picked Firefox for this example
FirefoxDriver driver;
driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(7, TimeUnit.SECONDS);
// Head to URL
driver.get("https://accounts.google.com/SignUp");
// Get the first click on the month field to generate the listbox pop-up
driver.findElement(By.xpath(".//*[#id='BirthMonth']/div")).click();
// This is ":a" because each item in this month list is assigned a hex value starting at an index of zero
driver.findElement(By.xpath(".//*[#id=':a']/div")).click();
// Check to see if November got selected
if (!driver.findElement(By.xpath(".//*[#id='BirthMonth']/div[1]")).getText().equals("November")) {
driver.close();
throw new RuntimeException("assertText 'November' failed");
}
// Close browser window
driver.quit();
}
}
Update: I realized you wanted to pass in the Month as an argument.
So swap out from the example above:
driver.findElement(By.xpath(".//*[#id=':a']/div")).click();
for the below code:
String month = "November";
driver.findElement(By
.xpath("//div[#class='goog-menuitem']/div[.='" + month + "']")).click();
Second Update:
So at one point you saw the HTML as:
<select id="BirthMonth" name="BirthMonth">
<option value="">Month</option>
<option value="01" >January</option>
<option value="02" >February</option>
......
<option value="12" >December</option>
</select>
But as I look at it in Chrome Dev Tools right now (pressing F12) after clicking on the Month field I see multiple small structure changes (posted what I see in the of the Gist link).Examples include select now becoming span and value="01" now shown as id=":0" (Why the counting starts at zero and not 1). Hope that explains some of why my example is different.

Selenium WebDriver - get options from hidden select [closed]

Closed. This question needs debugging details. It is not currently accepting answers.
Edit the question to include desired behavior, a specific problem or error, and the shortest code necessary to reproduce the problem. This will help others answer the question.
Closed 7 months ago.
Improve this question
I want to get all the options from a hidden select.
Select has "display: none;" part so I ran into a problem.
<select name="fw3k_ad_input_et_type_group"
class="" id="_id_fw3k_ad_input_et_type_group"
onchange=" eurotax.change_type_group( this.value ); "
style="display: none; ">
<option value="0">1</option>
<option value="-1" class="special">2</option>
<option value="16390">CD</option>
<option value="17605">S</option>
<option value="17636">SE</option>
</select>
My code:
Select tipSelect = new Select(driver.findElement(By.name("fw3k_ad_input_et_type_group")));
for (WebElement b : tipSelect.getOptions()) {
System.out.println(b.getText());
}
Please display code example if You have any.
firebug view:
http://imageshack.us/f/138/primjer.png/ LOOK THIS
It is possible to select elements in firebug with "display: none;" attribute. They will not be outlined on the page, but in the html tree structure.
Then, verify that you found element propertly with firebug
String optn=select[name="fw3k_ad_input_et_type_group"] option[value="0"]
//optn1=select[name="fw3k_ad_input_et_type_group"] option[value="-1"]
//optn2=select[name="fw3k_ad_input_et_type_group"] option[value="16390"]
//optn3=select[name="fw3k_ad_input_et_type_group"] option[value="17605"]
//optn4=select[name="fw3k_ad_input_et_type_group"] option[value="17636"]
then try to use jscript executor (should always work not taking into consideration whether element visible or not)
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\""+optn+"\");");
stringBuilder.append("return x.text().toString();") ;
String res= (String) js.executeScript(stringBuilder.toString());
Hope this work for you)
The matter is selenium unable to click invisible elements (or interact with invisible elements in other ways). So js should help. I would resolve it in the following way:
String css1="ul>li:last-child>div[id=unos_select_wrap] select[id="_id_fw3k_ad_input_et_type_group"]>option[value='0']";
String css2="ul>li:last-child>div[id=unos_select_wrap] select[id="_id_fw3k_ad_input_et_type_group"]>option[value='-1']";
String css3="ul>li:last-child>div[id=unos_select_wrap] select[id="_id_fw3k_ad_input_et_type_group"]>option[value='16390']";
String css4="ul>li:last-child>div[id=unos_select_wrap] select[id="_id_fw3k_ad_input_et_type_group"]>option[value='17605']";
String css5="ul>li:last-child>div[id=unos_select_wrap] select[id="_id_fw3k_ad_input_et_type_group"]>option[value='17636']";
public void getOptionTextAndPrintIt(String cssSelector){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\""+cssSelector+"\");");
stringBuilder.append("return x.text().toString();");
String res= (String) js.executeScript(stringBuilder.toString());
System.out.println(res);
}
public void allOptionValuesDepiction(){
getOptionTextAndPrintIt(css1);
getOptionTextAndPrintIt(css2);
getOptionTextAndPrintIt(css3);
getOptionTextAndPrintIt(css4);
getOptionTextAndPrintIt(css5);
}
Please let me know if something wrong as soon as you check.

Selenium Webdriver: Select with display none [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Selenium WebDriver - hidden select and anchor
Before I post my question I just want to tell that I am new to Selenium..
I am trying to select an option from a dropdown. The options display when clicked on the down arrow in the dropdown box. But, when checked in the Firebug, the display style was "none" and when trying to select the option using JUnit webdriver code by using click method in Eclipse, it did not work and it gave the exception - "org.openqa.selenium.ElementNotVisibleException: Element is not currently visible and so may not be interacted with".
Please refer to the attached image for the dropdown and HTML tags.
<select class="size-dropdown mediumSelect selectBox" name="skuAndSize" style="display: none;">
<option value=""></option>
<option value="2545672:S" name="skuId"> S</option>
<option value="2545673:M" name="skuId"> M</option![enter image description here][1]>
<option value="2545674:L" name="skuId"> L</option>
<option value="2545675:XL" name="skuId"> XL</option>
<option value="2545676:XXL" name="skuId"> XXL</option>
<option value="2545677:XXXL" name="skuId"> XXXL</option>
<option value="2545678:XXXXL" name="skuId"> XXXXL</option>
</select>
I looked at this link before posting this question - Selenium WebDriver - hidden select and anchor
But, since I am just starting I am not able to understand clearly.
Note: The same worked in IDE when used clickAt method. But in Webdriver the clickAt method is not present. Can anyone help me in this. Thanks!
Well the matter is Selenium is unable to interact with invisible ( disabled) elemnts. So you need to make element visible. BAsic idea: to make dropdown roll down , then wait with driver.manage.timeout(...) and then click on the appear needed element in dropdown.
Or you can use javascript to click element directly without preceeding dropdown roll down. Js is able to cope with it.
So this approach ALWAYS works:
css1=select[class="size-dropdown mediumSelect selectBox"]>option[value=""]
css2=select[class="size-dropdown mediumSelect selectBox"]>option[value="2545672:S"]
css2=select[class="size-dropdown mediumSelect selectBox"]>option[value="value="2545673:M"]
//.... and so on.....
public void jsClickOn(String cssSelector){
JavascriptExecutor js = (JavascriptExecutor) driver;
StringBuilder stringBuilder = new StringBuilder();
stringBuilder.append("var x = $(\'"+cssSelector+"\');");
stringBuilder.append("x.click();");
js.executeScript(stringBuilder.toString());
}
jsClickOn(css1);
jsClickOn(css2);
jsClickOn(css3);
Another way:
using actions builder, advanced user actions API. You can read about it here And code will be smth like that:
WebElement mnuElement;
WebElement submnuElement;
mnEle = driver.findElement(By.Id("mnEle")).click();
sbEle = driver.findElement(By.Id("sbEle")).click();
Actions builder = new Actions(driver);
// Move cursor to the Main Menu Element
builder.moveToElement(mnEle).Perform();
// Giving 5 Secs for submenu to be displayed
Thread.sleep(5000L);
// Clicking on the Hidden SubMenu
driver.findElement(By.Id("sbEle")).click();
But also pay attention on the way how you found css selectors, xpaths verifying it in e.g. firepath, addon to firebug in ffox.
Hope this helps you)
See this screen as example of locating dropdown options.