It would be very much helpful if I could get a solution for the below problem.
I'm unable to select an item from a hidden Radcombobox. The below code just enabled the field and I could see the combobox drops down in a fraction of second but the item specified is not selected. Please assist me correcting my code.
HTML Script
<a id="cmb_40_Arrow" style="overflow: hidden;display: block;position: relative;outline: none;">select</a>
Java Code
((JavascriptExecutor)driver).executeScript("arguments[0].click();", getElement("InterPoint")); //This is the combobox field
new FluentWait<WebDriver>(driver)
.withTimeout(1000, TimeUnit.SECONDS).pollingEvery(1, TimeUnit.SECONDS)
.ignoring(NoSuchElementException.class)
.ignoring(StaleElementReferenceException.class)
.until(new Function<WebDriver, Boolean>() {
#NotNull
#Override
public Boolean apply(WebDriver webDriver) {
WebElement element = getElement("CustomerPole"); /*This is the item from the field "Interpoint"*/
return element != null && element.isDisplayed();
}
});
Tried the below code and it doesn't work either
//waitpgm.until(ExpectedConditions.visibilityOfElementLocated(By.xpath(" //*[#id='pnlHeaderInterconnectionPointInformation']"))).click();
//waitpgm.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#id='cmb_40_DropDown']/div/ul/li[2]"))).click();
//waitpgm.until(ExpectedConditions.elementToBeClickable(getElement("CustomerPole"))).click();
Related
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!
I want to get the text of li (second) element as below. Code is able to find the element but it is throwing the error while fetching the gettext. Please help.
WebElement element = driver.findElement(By.xpath("//div[contains(#id,'location_group')]/div/ul/li[2]"));
element.getText();
Error
Stale element reference: element is not attached to the page document
HTML
<div id=location_group>
<div>
<ul class="og-tooltip js-og-tooltip" style="display: none; opacity: 100;">
<li class="title_text">Organization Group</li>
<li class="value_text" style="background: rgb(204, 136, 136); border: 2px solid red;">Global / Aricent / gemsecure </li>
<li> </li>
<li class="title_text">Group ID</li>
<li class="value_text">gemsecure</li>
</ul>
</div>
</div>
May be you have to wait for the parent element to be visible then interact with it
WebElement elementUL = driver.findElement(By.xpath("//div[contains(#id,'location_group')]/div/ul"));
WebDriverWait wait=new WebDriverWait(driver, 60);
wait.until(ExpectedConditions.visibilityOf(elementUL));
WebElement element = driver.findElement(By.xpath("//div[contains(#id,'location_group')]/div/ul/li[2]"));
element.getText();
Because this element is wrapped with a ul that has display: none selenium can not interact with it.
Options to try:
element.getAttribute("innerHTML");
or you can use the JavascriptExecutor:
JavascriptExecutor executor = (JavascriptExecutor)driver;
String text= executor.executeScript("document.document.getElementsByClassName('value_text')[0].innerHTML");
Another option is to use querySelector/querySelectorAll which has broader support than getElementsByClassName
Place a explicit waitWebDriverWait and wait till element to be visible
WebElement ele = driver.findElement(By.xpath("Your locator "));
WebDriverWait wait=new WebDriverWait(driver, 25);
wait.until(ExpectedConditions.visibilityOf(ele));
and then getText()
What I recommend is one use the xPath. I think I've tried every solution in java's selenium library, thus my website had tricky selects - once user picks an option, the options are reloaded (ex. selected value sometimes disappears, sometimes different options where loaded depends on particular select).
Lot of stale element exceptions.
What I've used:
private WebElement getDesiredOptionByVisibleText(WebDriver driver, String selectId, String text) {
List<WebElement> options = driver.findElements(By.xpath("//select[#id='" + selectId
+ "']/option[contains(text(),'" + text + "')]"));
if (options == null || options.size() == 0) {
return null;
} else {
return options.get(0);
}
}
especially use this method with waits, for example my wait:
private void waitUntilDesiredOptionVisible(WebDriver driver, String selectId) {
getFluentWait(driver).until(d -> (getDesiredOptionByVisibleText(driver, selectId, value) != null));
}
public static FluentWait<WebDriver> getFluentWait(WebDriver driver) {
return new FluentWait<>(driver)
.withTimeout(Duration.ofSeconds(60))
.pollingEvery(Duration.ofMillis(100));
}
Last but not least clicking that option.
private void selectByVisibleTextRegex(WebDriver driver, String selectId) {
WebElement option = getDesiredOptionByVisibleText(driver, selectId, value);
if (option == null) {
throw new NoSuchElementException(String.format("Cannot locate element with text like: %s.", value));
}
option.click();
}
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.
we are doing automation for web application and most of the scenario getting loading icon will appear at center of the page .. we need to wait for dis appear to loading icon
<div id="loading" style="display: none; visibility: hidden;">
<div></div>
<div></div>
Example : we are having search functionality their in most of scenario we are getting this loading icon.
selenium webdriver we are using: id we are getting for loading to complete is id= "loading"..please any give the solutions for the above issues am facing.
we have different functionality like click & sendkeys
Explicit Wait should help:
public static String waitForElementNotVisible(int timeOutInSeconds, WebDriver driver, String elementXPath) {
if ((driver == null) || (elementXPath == null) || elementXPath.isEmpty()) {
return "Wrong usage of WaitforElementNotVisible()";
}
try {
(new WebDriverWait(driver, timeOutInSeconds)).until(ExpectedConditions.invisibilityOfElementLocated(By
.xpath(elementXPath)));
return null;
} catch (TimeoutException e) {
return "Build your own errormessage...";
}
}
I have recently faced this issue. My solution might sound hacky but it worked pretty well in my case:
public static void loadingWait(WebDriver driver, WebElement loader) {
WebDriverWait wait = new WebDriverWait(driver, 5000L);
wait.until(ExpectedConditions.visibilityOf(loader)); // wait for loader to appear
wait.until(ExpectedConditions.invisibilityOf(loader)); // wait for loader to disappear
}
you can call this method after clicking on submit button. You have to pass driver, and loader web element to this method.
You can also wait till the ajax calls have been completed. Loading wheel disappears when all the ajax calls have completed (in most of the scenarios):
WebDriverWait wait = new WebDriverWait(d, timeOutSeconds);
wait.until(waitForAjaxCalls());
public static ExpectedCondition<Boolean> waitForAjaxCalls() {
return new ExpectedCondition<Boolean>() {
#Override
public Boolean apply(WebDriver driver) {
return Boolean.valueOf(((JavascriptExecutor) driver).executeScript("return (window.angular !== undefined) && (angular.element(document).injector() !== undefined) && (angular.element(document).injector().get('$http').pendingRequests.length === 0)").toString());
}
};
}
I faced this issue and the solution is really simple :
WebDriverWait wait = new WebDriverWait(driver, Duration.ofSeconds(10));
wait.until( ExpectedConditions.invisibilityOfElementLocated(By.xpath("path_of_loader")));
Generally, you must have something like on your website :Image
so use path_of_loader = //div[#id='circular3dG'] .. You can also try searching using keywords like loader, spinner or use a page to inspect loader/spinner where it takes long to load the page.