WebDriver is not waiting for elements to be enabled or displayed in my web application. The web application extensively uses AJAX/Javascript for loading a very large, dynamic application, specifically Bubble's web application editor (https://bubble.is). I am developing applications using bubble and want to use Selenium/WebDriver from within the Bubble editor.
When using implicit waits, explicit waits and fluent waits, attempts to click on an element always return the following error:
org.openqa.selenium.WebDriverException: unknown error: Element <div class="tab tabs-3">...</div> is not clickable at point (30, 185). Other element would receive the click: <div class="status-notification" style="display: block;">...</div>
This issue appears to be related to elements appearing in the DOM before they are fully loaded. The following Java code is what is being used here, compiled and run in Eclipse IDE on Java 9:
public static void main(String[] args) {
try {
WebDriver chrome = bubbleLogin(false); // login to application via static page. this step works
WebDriver driver = chrome;
// load app
WebDriverWait wait = new WebDriverWait(driver, DEFAULT_TIMEOUT_IN_SECONDS);
driver.get("https://bubble.is/page?type=page&name=index&id=test123456code&tab=tabs-1");
switchToWindowWithTitle("test123456", driver);
// EXPLICIT WAIT: wait for "elementToBeClickable" to be true - element must be displayed and enabled
wait.until(ExpectedConditions.elementToBeClickable(By.cssSelector("div.tab.tabs-3")));
// FLUENT WAIT: wait for element.IsEnabled to be true - element must be displayed and enabled
// instantiate an instance of this class to run the wait function I wrote
testng test = new testng();
test.waitUntilElementExistsAndIsEnabled(driver,By.cssSelector("div.tab.tabs-3"));
// only works via sleep... not implicit, explicit or fluent waits
// Thread.sleep(10000);
driver.findElement(By.cssSelector("div.tab.tabs-3")).click();
} catch (Exception e) {
System.out.println("failed run");
e.printStackTrace();
}
}
}
And the above FluentWait method:
private void waitUntilElementExistsAndIsEnabled(WebDriver driver, final By by) {
new FluentWait<WebDriver>(driver).withTimeout(DEFAULT_TIMEOUT_IN_SECONDS, TimeUnit.SECONDS)
.pollingEvery(DEFAULT_SLEEP_TIME_IN_SECONDS, TimeUnit.SECONDS).ignoring(NoSuchElementException.class)
.until(new ExpectedCondition<Boolean>() {
public Boolean apply(WebDriver wd) {
return wd.findElement(by).isEnabled();
}
});
}
Here is a complete dump of the error message from Eclipse: (Session info: chrome=61.0.3163.100)
(Driver info: chromedriver=2.32.498537 (cb2f855cbc7b82e20387eaf9a43f6b99b6105061),platform=Mac OS X 10.12.1 x86_64) (WARNING: The server did not provide any stacktrace information)
Command duration or timeout: 0 milliseconds
Build info: version: '3.6.0', revision: '6fbf3ec767', time: '2017-09-27T16:15:26.402Z'
System info: host: 'Krystals-MacBook-Air.local', ip: 'fe80:0:0:0:c33:4430:fcfd:933c%en0', os.name: 'Mac OS X', os.arch: 'x86_64', os.version: '10.12.1', java.version: '9'
Driver info: org.openqa.selenium.chrome.ChromeDriver
Capabilities [{mobileEmulationEnabled=false, hasTouchScreen=false, platform=MAC, acceptSslCerts=true, webStorageEnabled=true, browserName=chrome, takesScreenshot=true, javascriptEnabled=true, platformName=MAC, setWindowRect=true, unexpectedAlertBehaviour=, applicationCacheEnabled=false, rotatable=false, networkConnectionEnabled=false, chrome={chromedriverVersion=2.32.498537 (cb2f855cbc7b82e20387eaf9a43f6b99b6105061), userDataDir=/var/folders/gr/lggvp4hn09x2zqg6k561y4fr0000gn/T/.org.chromium.Chromium.haqAAG}, takesHeapSnapshot=true, pageLoadStrategy=normal, unhandledPromptBehavior=, databaseEnabled=false, handlesAlerts=true, version=61.0.3163.100, browserConnectionEnabled=false, nativeEvents=true, locationContextEnabled=true, cssSelectorsEnabled=true}]
Session ID: 0c9110334bb1b20a306363006f4bb868
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
at java.base/jdk.internal.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
at java.base/jdk.internal.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
at java.base/java.lang.reflect.Constructor.newInstance(Constructor.java:488)
at org.openqa.selenium.remote.ErrorHandler.createThrowable(ErrorHandler.java:214)
at org.openqa.selenium.remote.ErrorHandler.throwIfResponseFailed(ErrorHandler.java:166)
at org.openqa.selenium.remote.http.JsonHttpResponseCodec.reconstructValue(JsonHttpResponseCodec.java:40)
at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:82)
at org.openqa.selenium.remote.http.AbstractHttpResponseCodec.decode(AbstractHttpResponseCodec.java:45)
at org.openqa.selenium.remote.HttpCommandExecutor.execute(HttpCommandExecutor.java:164)
at org.openqa.selenium.remote.service.DriverCommandExecutor.execute(DriverCommandExecutor.java:83)
at org.openqa.selenium.remote.RemoteWebDriver.execute(RemoteWebDriver.java:586)
at org.openqa.selenium.remote.RemoteWebElement.execute(RemoteWebElement.java:279)
at org.openqa.selenium.remote.RemoteWebElement.click(RemoteWebElement.java:83)
at testng.main(testng.java:497)