Reputation: 915
I have read a few online articles and they all point to 1 direction and that is when the page is loading the element is not found. In my setData() you can see I have tried a few things such as use of wait, implicitwait and 1st click and then send the username. However nothing seems to be working. I also thought of using "wait" inside pageProperties but later changed my mind because that would probably be a bad design.
Error :
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: invalid element state
System information: Windows 10, ChromeDriver 2.37.544315, chrome=65.0.3
Code:
public class Tour {
public static WebDriver driver;
//browser URL information
public WebDriver getBrowser(String browser, String url){
System.setProperty("webdriver.chrome.driver", "C:\\Users\\Downloads\\chromedriver.exe");
if(browser.equals("cc")){
driver= new ChromeDriver();
}
driver.get(url);
return driver;
}
// User name and continue button property from 1st page
public void pageUserNameProperty(String un){
WebElement login=driver.findElement(By.xpath("//input[@id='usernameOrEmail']"));
WebElement cont_btn=driver.findElement(By.xpath("//button[contains(@type,'submit')]"));
//WebDriverWait wait = new WebDriverWait(driver,30);
//wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@id='usernameOrEmail']")));
login.sendKeys(un);
cont_btn.click();
}
// Password and continue button property from 2nd page
public void pagePassTourProperty(String psd){
WebElement password=driver.findElement(By.xpath("//input[@id='password']"));
WebElement lgn_btn=driver.findElement(By.xpath("//button[contains(@type,'submit')]"));
//WebDriverWait wait = new WebDriverWait(driver,30);
//wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@id='usernameOrEmail']")));
password.sendKeys(psd);
lgn_btn.click();
}
// Supply Data for test from excel
public void setData(){
Tour tour= new Tour();
tour.getBrowser("cc", "https://wordpress.com/log-in");
WebDriverWait wait = new WebDriverWait(driver,30);
WebElement login_field=wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@id='usernameOrEmail']")));
login_field.click();
//driver.manage().timeouts().implicitlyWait(18, TimeUnit.SECONDS);
tour.pageUserNameProperty("JoeThomas");
//wait.until(ExpectedConditions.visibilityOfElementLocated(By.xpath("//input[@id='passTour']")));
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
tour.pagePassTourProperty("psd231");
}
public static void main(String[] args) {
Tour tour= new Tour();
tour.setData();
}
}
Error:
Starting ChromeDriver 2.37.544315 (730aa6a5fdba159ac9f4c1e8cbc59bf1b5ce12b7) on port 2644
Only local connections are allowed.
Apr 18, 2018 7:09:26 AM org.openqa.selenium.remote.ProtocolHandshake createSession
INFO: Detected dialect: OSS
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: invalid element state (Session info: chrome=65.0.3325.181)
(Driver info: chromedriver=2.37.544315 (730aa6a5fdba159ac9f4c1e8cbc59bf1b5ce12b7),platform=Windows NT 10.0.15063 x86_64) (WARNING: The server did not provide any stacktrace information) Command duration or timeout: 0 milliseconds Build info: version: '3.11.0', revision: 'e59cfb3', time: '2018-03-11T20:33:15.31Z' System info: host: 'XYZ', ip: '123', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '1.8.0_91'
Driver info: org.openqa.selenium.chrome.ChromeDriver Capabilities {acceptInsecureCerts: false, acceptSslCerts: false, applicationCacheEnabled: false, browserConnectionEnabled: false, browserName: chrome, chrome: {chromedriverVersion: 2.37.544315 (730aa6a5fdba15..., userDataDir: C:\Users\CHQ-SH~1\AppData\L...}, cssSelectorsEnabled: true, databaseEnabled: false, handlesAlerts: true, hasTouchScreen: false, javascriptEnabled: true, locationContextEnabled: true, mobileEmulationEnabled: false, nativeEvents: true, networkConnectionEnabled: false, pageLoadStrategy: normal, platform: XP, platformName: XP, rotatable: false, setWindowRect: true, takesHeapSnapshot: true, takesScreenshot: true, unexpectedAlertBehaviour: , unhandledPromptBehavior: , version: 65.0.3325.181, webStorageEnabled: true}
Session ID: 3298d88e517d756790ab6792e45257f1
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
Thank You for your time and suggestion.
Experiment:
public class Tour {
public static WebDriver driver;
//browser URL information
public WebDriver getBrowser(String browser, String url){
System.setProperty("webdriver.chrome.driver", "C:\\Users\\chq-sheikhr\\Downloads\\chromedriver.exe");
if(browser.equals("cc")){
driver= new ChromeDriver();
}
driver.get(url);
return driver;
}
// User name and continue button property from 1st page
public void pageUserNameProperty(String un){
WebElement login=driver.findElement(By.xpath("//input[@id='usernameOrEmail']"));
WebElement cont_btn=driver.findElement(By.xpath("//button[contains(@type,'submit')]"));
login.sendKeys(un);
cont_btn.click();
}
// Password and continue button property from 2nd page
public void pagePasswordProperty(String psd){
WebElement password=driver.findElement(By.xpath("//input[@id='password']"));
WebElement lgn_btn=driver.findElement(By.xpath("//button[contains(@type,'submit')]"));
password.sendKeys(psd);
lgn_btn.click();
}
// A method - isElementExists to check whether that element exists or not
public boolean isElementExists(By xpath){
return driver.findElements(By.xpath("//input[@id='usernameOrEmail']")).size() > 0;
}
/*create a method waitForElement and pass wait time in seconds to it, it is not a hard code wait as it
* will continuously check whether that element is exist or not and then it will wait for 1 seconds on
* every iteration of for loop
*/
public boolean waitForElement(int timeInSeconds, By xpath){
try{
for(int i=0;i<timeInSeconds;i++){
if(isElementExists(xpath))
return true;
Thread.sleep(1000);
}
}catch(Exception ex){
ex.printStackTrace();
}
return false;
}
public void setData(){
Tour tour= new Tour();
tour.getBrowser("cc", "https://wordpress.com/log-in");
tour.waitForElement(10, By.xpath("//input[@id='usernameOrEmail']"));
tour.pageUserNameProperty("JoeThoman");
tour.pagePasswordProperty("pasd123");
}
public static void main(String[] args) {
Tour tour= new Tour();
tour.setData();
}
}
Upvotes: 2
Views: 34447
Reputation: 11
This can be handled if your application is dealing with Jquery. This code will wait until your page is fully loaded with all the required data and will avoid invalidelementstateexception .
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: invalid element state
public static boolean waitForJSandJQueryToLoad() {
WebDriverWait wait = new WebDriverWait(getWebDriver(), 30);
// wait for jQuery to load
ExpectedCondition<Boolean> jQueryLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
System.out.println(
"Request = " + ((JavascriptExecutor) driver).executeScript("return jQuery.active"));
return ((Long) ((JavascriptExecutor) driver).executeScript("return jQuery.active") == 0);
} catch (Exception e) {
// no jQuery present
System.out.println("no jQuery present");
return true;
}
}
};
// wait for Java script to load
ExpectedCondition<Boolean> jsLoad = new ExpectedCondition<Boolean>() {
@Override
public Boolean apply(WebDriver driver) {
try {
System.out.println(
"Request = " + ((JavascriptExecutor) driver).executeScript("return document.readyState").toString());
return ((JavascriptExecutor) driver).executeScript("return document.readyState").toString().equals("complete");
} catch (Exception e) {
// no jQuery present
System.out.println("no jQuery present");
return true;
}
}
};
return wait.until(jQueryLoad) && wait.until(jsLoad);
}
Upvotes: 1
Reputation: 193108
This error message...
Exception in thread "main" org.openqa.selenium.InvalidElementStateException: invalid element state
...implies that the element with which you are trying to interact is in a state during which actions cannot be performed.
InvalidElementStateException is a type of WebDriverException which indicates that a WebElement with whom you are trying to interact is in a state in which actions cannot be performed with it. Such instances may arise when an element is being obscured by another element while clicking or the desired element perhaps is not being visible on the HTML DOM.
You have to consider a few facts as follows :
Do not mix implicit and explicit waits. Doing so can cause unpredictable wait times. For example setting an implicit wait of 10 seconds and an explicit wait of 15 seconds, could cause a timeout to occur after 20 seconds.
So you need to remove all the instances of implicitlyWait().
visibilityOfElementLocated()
you need to use elementToBeClickable()
method.A simple script to access the url https://wordpress.com/log-in
and send characters to the Email Address or Username field is as follows :
System.setProperty("webdriver.gecko.driver", "C:/path/to/geckodriver.exe");
WebDriver driver = new FirefoxDriver();
driver.get("https://wordpress.com/log-in");
new WebDriverWait(driver,30).until(ExpectedConditions.elementToBeClickable(By.xpath("//input[@id='usernameOrEmail']"))).sendKeys("JoeThomas");
Snapshot of the WebClient :
As per your counter question within your comments the WebDriverWait polls the HTML DOM at certain intervals (default 500 ms) till the configured amount of time (30 seconds in your case). The element/s is/are returned back as soon as the ExpectedConditions is met. For example, if the desired element is found within 1 second, it is returned and your next line of code executes. There is no delay involved. As per the WebDriverWait constructor you can always configure the timeOutInSeconds and sleepInMillis i.e. polling interval.
You can find a detailed discussion in:
Upvotes: 5
Reputation: 2760
To make it consistent please follow below steps :
A) create a method - isElementExists to check whether that element exists or not as follows :
public boolean isElementExists(String xpathOfElement){
return driver.findElements(By.xpath(xpathOfElement)).size() > 0;
}
B) Now create a method waitForElement and pass wait time in seconds to it, it is not a hard code wait as it will continuously check whether that element is exist or not and then it will wait for 1 seconds on every iteration of for loop as follows :
public boolean waitForElement(int timeInSeconds, String xpathOfElement){
try{
for(int i=0;i<timeInSeconds;i++){
if(isElementExists(xpathOfElement))
return true;
Thread.sleep(1000);
}
}catch(Exception ex){
ex.printStackTrace();
}
return false;
}
C) So once it return true you can perform the action on that element.
I have used xpath for locating element, you can use whichever you want.
Upvotes: 3