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')
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:
In one of my Projects, I have to verify the success alert text using Selenium. The UI is coded in react JS following Ant design. For verification please follow this link 'https://ant.design/components/message/' and click on Display Normal message. The message is shown above at the top of the page but I am not able to get the text from that using Selenium Webdriver coding in Core Java. Please help.
I tried this code:
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebDriverWait wait = new WebDriverWait(driver, 60);
WebElement successmessage = wait.until(ExpectedConditions.visibilityOfElementLocated(By.className("ant-message-custom-content-ant-message-success")));
successmessage.getText();
To extract the text This is a normal message you need to induce WebDriverWait for the visibilityOfElementLocated() and you can use either of the following Locator Strategies:
cssSelector:
driver.get("https://ant.design/components/message/");
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.cssSelector("button.ant-btn.ant-btn-primary"))).click();
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.cssSelector("div.ant-message"))).getText());
xpath:
driver.get("https://ant.design/components/message/");
new WebDriverWait(driver, 20).until(ExpectedConditions.elementToBeClickable(By.xpath("//button[#class='ant-btn ant-btn-primary']"))).click();
System.out.println(new WebDriverWait(driver, 20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//div[#class='ant-message']"))).getText());
Console Output:
This is a normal message
I'm going to suggest:
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebDriverWait wait = new WebDriverWait(driver, 15, 100);
String successMessage = wait.until(ExpectedConditions.presenceOfElementLocated(By.cssSelector(".ant-message-info > span"))).getText();
The main problem that you have is that the message doesn't last for very long, so you need to get the data out of it quickly before it is destroyed. As a result I have inlined the getText() call so that it's called as soon as the element is found.
I suspect part of your problem is getting an accurate locator. You can make it easier by opening up the chrome dev console, selecting the parent element where the notice message is created and then right clicking on that element and selecting break on -> subtree modifications. This will allow you to look at the intermediate state of the DOM by pausing JavaScript execution one the message is created. This makes it a lot easier to work out what is going on and find relevant locators.
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebElement alertElmt = driver.findElement(By.xpath("//*[#class='ant-message']"));
for(int i=1; i<10; i++) {
Thread.sleep(500);
String getText = alertElmt.getText();
if(!getText.equals("")) {
System.out.println(getText);
break;
}
}
//or with webdriverwait
driver.findElement(By.cssSelector(".ant-btn-primary")).click();
WebElement alert = new WebDriverWait(driver,20).until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//*[#class='ant-message']")));
System.out.println(alert.getText());
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 creating a test and having some issues. Here is the scenario. I use Selenium Web driver to fill out a form on Page1 and submit the form by clicking a button. Page2 starts loading... but the problem is, Page2 uses Google Analytics codes, and sometimes it takes forever for the page to stop loading.
Even though the expected element is already present, Selenium web driver does not proceed until the whole web page is fully loaded.
How do I make Selenium to move on to the next task or stop loading external javascript/css if the expected element is already present?
I tried tweaking the following settings but no luck.
driver.manage().timeouts().pageLoadTimeout(60, TimeUnit.SECONDS);
driver.manage().timeouts().setScriptTimeout(30, TimeUnit.SECONDS);
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
TEMPORARY SOLUTION: Scroll below for answer!
Give below approaches a shot.
driver.findElement(By.tagName("body")).sendKeys("Keys.ESCAPE");
or
((JavascriptExecutor) driver).executeScript("return window.stop");
Alternatively, you can also use WebDriverBackedSelenium as shown in the snippet below from Vincent Bouvier.
//When creating a new browser:
WebDriver driver = _initBrowser(); //Just returns firefox WebDriver
WebDriverBackedSelenium backedSelenuium =
new WebDriverBackedSelenium(driver,"about:blank");
//This code has to be put where a TimeOut is detected
//I use ExecutorService and Future<?> Object
void onTimeOut()
{
backedSelenuium.runScript("window.stop();");
}
Source: https://sqa.stackexchange.com/a/6355
Source: https://stackoverflow.com/a/13749867/330325
So, I reported to Selenium about these issues. And the temporary workaround is... messing with Firefox's timeout settings. Basically by default Firefox waits about 250 seconds for each connection before timing you out. You can check about:config for the details. Basically I cranked it down so Firefox doesn't wait too long and Selenium can continue as if the page has already finished loading :P.
Similar config might exist for other browsers. I still think Selenium should let us handle the pagetimeout exception. Make sure you add a star to the bug here: http://code.google.com/p/selenium/issues/detail?id=6867&sort=-id&colspec=ID%20Stars%20Type%20Status%20Priority%20Milestone%20Owner%20Summary, so selenium fixes these issues.
FirefoxBinary firefox = new FirefoxBinary(new File("/path/to/firefox.exe"));
FirefoxProfile customProfile = new FirefoxProfile();
customProfile.setAcceptUntrustedCertificates(true);
customProfile.setPreference("network.http.connection-timeout", 10);
customProfile.setPreference("network.http.connection-retry-timeout", 10);
driver = new FirefoxDriver(firefox, customProfile);
driver.manage().deleteAllCookies();
Once you have checked for the element and you know that it is present, you could either navigate to/load a different page (if the next tasks are on a different page) or if the tasks are on the same page (as you anyway do not need the elements that have not yet loaded), you could continue as usual - selenium will identify the elements which have already been loaded. This works for me when I work with feature rich pages.
Instead of using the webdriver click() to submit the form use jsexecutor and do a click. Jsexecutor does not wait for page load and you can with other actions.
As per the above scenario explained i feel its best to use the below wait command in the first page.
WebDriverWait wait = new WebDriverWait(driver, 10);
WebElement element = wait.until(ExpectedConditions.presenceOfElementLocated(By.id(>someid>)));
Once the required element is found in the first page next you can proceed to the second page.
As per the above scenario explained i feel its best to use the below wait command in the first page.
WebDriverWait wait = new WebDriverWait(driver, 10); WebElement element =
wait.until(ExpectedConditions.presenceOfElementLocated(By.id(>someid>)));
Once the required element is found in the first page next you can proceed to the second page.
Use explicit/webdriver wait----
WebDriverWait wt=new WebDriverWait(driver, 20);
wt.until(ExpectedConditions.elementToBeClickable(By.name("abc")));