Selenium : How to solve org.openqa.selenium.InvalidElementStateException: invalid element state

后端 未结 2 1398
独厮守ぢ
独厮守ぢ 2020-12-02 03:03

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

相关标签:
2条回答
  • 2020-12-02 03:30

    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

    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.


    Solution

    You have to consider a few facts as follows :

    • Never mixup implicitlyWait() and WebDriverWait() as the documentation clearly mentions the following :

    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().

    • As you need to send characters to the Email Address or Username field so instead of ExpectedConditions method 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 :

    WebClient


    Update

    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.


    Reference

    You can find a detailed discussion in:

    • Replace implicit wait with explicit wait (selenium webdriver & java)
    0 讨论(0)
  • 2020-12-02 03:36

    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.

    0 讨论(0)
提交回复
热议问题