how to select a value from dropdown using selenium java webdriver using xpath?
depending on the option selected in the dropdown, fields appear .so that I need t enter values in it. My problem is I am not getting the fields after selecting the option in dropdown.After a long period of time it is appears, mean while error appears
You can click the drop down and wait for the options to get displayed and then you can click the option from it.
or
Select select = new Select(driver.findElement(By.id("drop_down_id")));
select.selectByIndex(`index_value_of_option`);
Jyotsna... Your script need to wait till the field appear. For this you need to use any of the wait condition.
implicit wait
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
or sleep condition
Thread.sleep(2000);
or you can use Fluent wait (the best one as per my suggestion)
public WebElement fluentWait(final By locator) {
Wait<WebDriver> wait = new FluentWait<WebDriver>(driver)
.withTimeout(30, TimeUnit.SECONDS)
.pollingEvery(5, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class);
WebElement foo = wait.until(new Function<WebDriver, WebElement>() {
public WebElement apply(WebDriver driver) {
return driver.findElement(locator);
}
});
return foo;
};
fluentWait function returns your found web element. From the documentation on fluentWait: An implementation of the Wait interface that may have its timeout and polling interval configured on the fly. Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page. Details you can get here
Usage of `fluentWait in your case be the following:
WebElement textbox = fluentWait(By.id("textbox"));
Sample statements to open browser, load URL and select value from dropdown
static WebDriver driver;
System.setProperty("webdriver.ie.driver","C:\\(Path)\\IEDriverServer.exe");
driver = new InternetExplorerDriver();
driver.manage().window().maximize();
driver.get("EnterURLHere");
driver.manage().timeouts().implicitlyWait(30,TimeUnit.SECONDS);
Select value1 = new Select(driver.findElement(By.id("LocateId")));
value1.selectByVisibleText("ValueToBeSelected"); //Select Character from dropdown list
you can add wait so that the problem of late loading would be resolve.
driver.manage().timeouts().implicitlyWait(20,TimeUnit.SECONDS);
or,
Thread.sleep(2000);
For selecting from drop down , there are multiple ways from which one can select :
Select dropdown = new Select(driver.findElement(By.id(""))); // By id
dropdown.selectByVisibleText(""); // By Visible text
dropdown.selectByIndex(1); // By index
Related
Below code is not able to identify the list of webelements if they are identified inside a wait condition. I get an exception as timeoutexception and unable to identify the element for the specified xpath.
However if I directly access the elements without wait condition , the values are assigned to the list Variable, why is this so?
WebDriverManager.chromedriver().setup();
WebDriver driver = new ChromeDriver();
driver.get("https://www.finance.yahoo.com");
driver.manage().window().maximize();
driver.findElement(By.xpath("//input[#id='yfin-usr-qry']")).sendKeys("nclh");
WebDriverWait wait = new WebDriverWait(driver,5);
List<WebElement>dd_list= wait.until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//ul[#class='modules_list__1zFHY']/li")));
System.out.println(dd_list.size());
for(WebElement ele : dd_list) {
if (ele.getText().contains("NCLH.VI")) {
System.out.println("i got the element");
}
}
why is this so?
The elements that you are targeting are never all visible simultaneously. Your xpath returns 15 elements, of which only 10 are visible. Implying that your condition will never be met (hence the timeout exception). Simply refine your xpath so as to target the elements you are interested in: the ones that have vocation to be visible, e.g. "//ul[#class='modules_list__1zFHY']/li[#data-type='quotes']"
The Yahoo Finance website contains ReactJS enabled elements. So you need to induce WebDriverWait for document.readyState to be complete and you can use the following Locator Strategies:
Code Block:
driver.get("https://www.finance.yahoo.com");
new WebDriverWait(driver, 120).until(webDriver -> ((JavascriptExecutor) webDriver).executeScript("return document.readyState").equals("complete"));
WebElement element = new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[#id='yfin-usr-qry']")));
element.click();
element.sendKeys("nclh");
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfAllElementsLocatedBy(By.xpath("//ul[#class='modules_list__1zFHY']//li[#data-type='quotes']"))).size())
Console Output:
6
Browser Snapshot:
Here I have the image of my code and the image of my error. Can anyone help me to resolve this issue?
ElementNotInteractableException
ElementNotInteractableException is the W3C exception which is thrown to indicate that although an element is present on the HTML DOM, it is not in a state that can be interacted with.
Reasons & Solutions :
The reason for ElementNotInteractableException to occur can be numerous.
Temporary Overlay of other WebElement over the WebElement of our interest :
In this case, the direct solution would have been to induce ExplicitWait i.e. WebDriverWait in combination with ExpectedCondition as invisibilityOfElementLocated as folllows:
WebDriverWait wait2 = new WebDriverWait(driver, 10);
wait2.until(ExpectedConditions.invisibilityOfElementLocated(By.xpath("xpath_of_element_to_be_invisible")));
driver.findElement(By.xpath("xpath_element_to_be_clicked")).click();
A better solution will be to get a bit more granular and instead of using ExpectedCondition as invisibilityOfElementLocated we can use ExpectedCondition as elementToBeClickable as follows:
WebDriverWait wait1 = new WebDriverWait(driver, 10);
WebElement element1 = wait1.until(ExpectedConditions.elementToBeClickable(By.xpath("xpath_of_element_to_be_clicked")));
element1.click();
Permanent Overlay of other WebElement over the WebElement of our interest :
If the overlay is a permanent one in this case we have to cast the WebDriver instance as JavascriptExecutor and perform the click operation as follows:
WebElement ele = driver.findElement(By.xpath("element_xpath"));
JavascriptExecutor executor = (JavascriptExecutor)driver;
executor.executeScript("arguments[0].click();", ele);
I got this because the element I wanted to interact with was covered by another element. In my case it was an opaque overlay to make everything r/o.
When trying to click an element UNDER another element we usualy get "... other Element would receive the click " but not always :.(
This Exception we get when the element is not in an interactable state. So we can use wait till the element is Located or become clickable.
Try using the Implicit wait:
driver.manage().timeouts().implicitlyWait(Time, TimeUnit.SECONDS);
If this is not working use Explicit wait:
WebDriverWait wait=new WebDriverWait(driver, 20);
WebElement input_userName;
input_userName = wait.until(ExpectedConditions.elementToBeClickable(By.tagName("input")));
input_userName.sendkeys("suryap");
You can use ExpectedCondition.visibilityOfElementLocated() as well.
You can increase the time, for example,
WebDriverWait wait=new WebDriverWait(driver, 90);
A solution to this for Javascript looks like this. You will have to modify the time to suit your need.
driver.manage().setTimeouts({ implicit: 30000 });
Hope this is helpful to someone.
see the docs for reference
Actually the Exception is Element Not Visible
The best practice is to use Implicit wait below driver Instantiation so it get sufficient time to find element throughout the exception
driver.get("http://www.testsite.com");
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
Still facing issue as some element require more time. Use ExplicitWait for individual element to satisfy certain condition
In your case you are facing element not visible exception then use wait condition in following way-
WebDriverWait wait = new WebDriverWait(driver, 120);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.your_Elemetnt));
In my case issue was because there is some animation, and that element is not visible for some duration. And hence exception was occurring.
For some reason I couldn't make ExpectedConditions.visibilityOfElementLocated work, so I created a code to wait for some hardcoded seconds before proceeding.
from selenium.webdriver.support.ui import WebDriverWait
def explicit_wait_predicate(abc):
return False
def explicit_wait(browser, timeout):
try:
Error = WebDriverWait(browser, timeout).until(explicit_wait_predicate)
except Exception as e:
None
And now I am calling this explicit_wait function wherever I want to wait for sometime e.g.
from selenium import webdriver
from selenium.webdriver.common.by import By
browser = webdriver.Safari()
browser.get('http://localhost')
explicit_wait(browser,5) # This will wait for 5 secs
elem_un = browser.find_element(By.ID, 'userName')
I'm using web driver wait as explicit wait in selenium web driver. But It's not consistent it seems. before mouse over operations, links It's throwing unable to locate element error. Please see the below method and suggest where am I going wrong.
public WebElement waitForElement(String xPathExpression) {
WebDriverWait wait = new WebDriverWait(driver,30);
WebElement element = wait.until(ExpectedConditions.visibilityOf(driver.findElement(By.xpath(xPathExpression))));
return element;
}
Just a guess, but I might have seen similar behavior on very dynamic pages. I.e the element on the page changes while being evalued.
I'm able to workaround these kind of problems by using FluentWait#ignoring
WebDriverWait wait = new WebDriverWait(driver,30)
.ignoring(NoSuchElementException.class);
I was just wondering if there's an elegant way to utilize ExpectedConditions or something else to have my code wait for a page's source to contain a given string until a given timeout. I know I can use something like this if I wanted to use a specific element's locator ...
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(ExpectedConditions.visibilityOfElementLocated(By.linkText("foobar")));
But I wanted to accomplish this without using a locator for a specific element, and just use the whole page source as my reference instead. Any suggestions?
You cant have the all elements as a condition for waiting. When switching page weddriver automaticly wait for the page to load. WHen it has finished loading the HTML elements it continues. But it doesnt wait for JavaScript to execute. A lot of webpages today uses JavaScript to populate the webpage after the HTML has loaded.
What you should do is wait for every element you want to use.
wait.until(ExpectedConditions.refreshed(ExpectedConditions.visibilityOfElementLocated(by)));
or
wait.until(ExpectedConditions.refreshed(ExpectedConditions.elementToBeClickable(element))h;
You can wait for document's readyState to become complete. Run the javascript return document.readyState").equals("complete") against the web page that is loading.
void waitForLoad(WebDriver driver) {
ExpectedCondition<Boolean> pageLoadCondition = new
ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver driver) {
return ((JavascriptExecutor)driver).executeScript("return document.readyState").equals("complete");
}
};
WebDriverWait wait = new WebDriverWait(driver, 30);
wait.until(pageLoadCondition);
}
And then you can get the page source:
driver.getPageSource();
And then verify that the pageSource contains what you are looking for:
driver.getPageSource().contains("your element/tag");
I hope this helps!
Without depending on visibility, you could check if an element is present in the DOM:
WebDriverWait wait = new WebDriverWait(driver,10);
wait.until(ExpectedConditions.presenceOfElementLocated(By.tagName("html")));
If you want to refer to individual text, you can implement ExpectedCondition<T> and create your own condition class. The mentioned interface has access to the WebDriver (due to super-interface com.google.common.base.Function<WebDriver,T>).
In the method apply you could use the WebDriver and call method getPageSource() to have String presenting the page source. Check the String for whatever you prefer.
I am facing a problem that i am not able to select element from drop down list to proceed further.
The URL for reference site is "http://www.rechargeitnow.com/needrecharge.jspx"
I tried the code below but didn't got success.
//WebDriverWait wait = new WebDriverWait(driver, 10);
//WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));
WebDriverWait wait= new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("opId_div")));
//driver.findElement(By.cssSelector("select[id='operatorid']")).sendKeys("Airtel");;
//driver.findElement(By.linkText("mobile")).sendKeys("Airtel");
//driver.findElement(By.xpath("//*[#id='oprauto']")).click();
//driver.findElement(By.xpath("/html/body/div[2]/div/div[6]/div/div/div/div/div[2]/div/div/div/div/div[2]/select/option[5]")).findElement(By.name("Airtel"));
//operator.selectByIndex(1);
//driver.findElement(By.xpath("//*[#id='oprauto']")).sendKeys("Airtel");
driver.findElement(By.xpath("/html/body/div[2]/div/div[6]/div/div[3]/ul/li[3]/img")).click();
//Select operator=new Select(driver.findElement(By.id("operatorid")));
//operator.getOptions();
//operator.selectByVisibleText("Airtel");
driver.findElement(By.tagName(" mobile no. ")).sendKeys("9001785845");
driver.findElement(By.id("transSubscriptionNoID")).sendKeys("9001457868");
//driver.findElement(By.cssSelector("img[id='btn']")).submit();
//driver.findElement(By.id("btn")).submit();
driver.findElement(By.xpath("//*[#id='btn']"));
I am not familiar with Java but I was able to easily accomplish this in Ruby with the following code.
$driver.find_element(:xpath, ".//*[#id='input_dropdown']/div[1]/img").click
$driver.find_element(:link, "T24").click
You can replace "T24" with any of the other options available on the dropdown.
Hopefully this answers half of your question at least and someone will be able to translate this into Java.
So the combo drop down is not a select box, its an unordered list, wrapped around an input. You would need to click on the drop down icon and then click the element you want. Here is some dirty code that WORKS :). It selects "Idea" from the drop down.
WebDriver driver = new FirefoxDriver();
WebDriverWait wait = new WebDriverWait(driver, 300);
driver.manage().timeouts().implicitlyWait(30, TimeUnit.SECONDS);
driver.get("http://www.rechargeitnow.com/needrecharge.jspx");
WebElement dropDownArrow = driver.findElement(By
.id("input_dropdown"));
dropDownArrow.click();
WebElement option = wait.until(ExpectedConditions
.elementToBeClickable(By.linkText("Idea")));
option.click();
The following code works. This is not what I wanted to provide you with as a code. But works none the less. You can replace Airtel with any other text present in the drop down.
driver.findElement(By.id("oprauto")).sendKeys("Airtel");
driver.findElement(By.xpath("//ul/li/a/strong[text() = 'Airtel']")).click();