【问题标题】:Selenium : How to solve org.openqa.selenium.InvalidElementStateException: invalid element stateSelenium:如何解决 org.openqa.selenium.InvalidElementStateException:无效元素状态
【发布时间】:2018-09-28 20:13:38
【问题描述】:

我已经阅读了一些在线文章,它们都指向一个方向,即页面加载时找不到元素。在我的 setData() 中,您可以看到我尝试了一些方法,例如使用等待、隐式等待和第一次单击,然后发送用户名。然而,似乎没有任何工作。我也想过在 pageProperties 中使用“等待”,但后来改变了主意,因为这可能是一个糟糕的设计。

错误:

Exception in thread "main" org.openqa.selenium.InvalidElementStateException: invalid element state

系统信息:Windows 10、ChromeDriver 2.37.544315、chrome=65.0.3

代码

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

    }

}

错误:

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)    

感谢您的宝贵时间和建议。

实验:

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();
    }

}

【问题讨论】:

  • 你为什么打电话给login_field.click()?它是一个文本字段。您应该点击提交按钮。
  • 这是一个文本字段,我单击该字段以确保首先光标在那里,然后我在该字段中发送用户名。
  • 请将完整的堆栈跟踪添加到问题中,以便查看实际抛出异常的位置。
  • 添加在上面。谢谢。
  • 更新:在 setData() 中进行更改后 1)单击登录文本字段,然后implicitWait 有时通过有时失败。 public void setData(){ Tour tour= new Tour(); tour.getBrowser("cc", "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("Joe");

标签: java selenium selenium-webdriver webdriver


【解决方案1】:

要使其一致,请按照以下步骤操作

A) 创建一个方法 - isElementExists 来检查该元素是否存在,如下所示:

public boolean isElementExists(String xpathOfElement){
    return driver.findElements(By.xpath(xpathOfElement)).size() > 0;
}

B) 现在创建一个方法 waitForElement 并传递 wait time in seconds 给它,这不是硬代码等待 因为它会不断检查 元素是否存在,然后在 for 循环的 每次迭代 上等待 1 秒,如下所示:

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) 因此,一旦它返回 true 您就可以对该元素执行操作

我已经使用xpath来定位元素,你可以使用任何一个你想要的。

【讨论】:

  • @Sheikh Rahman:你能试试这个,如果你遇到任何问题,请告诉我......?
  • Pritam 我试过这段代码,但我无法让它在 setData() 中工作。我认为这是因为我不确定如何使用它(我缺乏专业知识)。我将再试一次并粘贴代码,以便您可以看到我做错了什么。再次感谢您。
  • 请检查我上面在实验部分添加的代码。谢谢。
【解决方案2】:

此错误消息...

Exception in thread "main" org.openqa.selenium.InvalidElementStateException: invalid element state

...表示您尝试与之交互的元素处于无法执行操作的状态。


无效元素状态异常

InvalidElementStateExceptionWebDriverException 的一种类型,表示您尝试与之交互的WebElement 处于无法对其执行操作的状态。当一个元素在单击时被另一个元素遮挡或所需元素可能在 HTML DOM 上不可见时,可能会出现此类情况。


解决方案

您必须考虑以下几个事实:

  • 永远不要混淆 implicitlyWait()WebDriverWait(),因为 documentation 清楚地提到了以下内容:

不要混合隐式和显式等待。这样做会导致不可预测的等待时间。例如,设置 10 秒的隐式等待和 15 秒的显式等待,可能会导致 20 秒后发生超时。

所以你需要删除implicitlyWait()的所有实例。

  • 由于您需要发送字符电子邮件地址或用户名字段,因此您需要使用visibilityOfElementLocated()而不是ExpectedConditions方法987654325@方法。
  • 访问 url https://wordpress.com/log-in发送字符电子邮件地址或用户名 字段的简单脚本如下:

    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");
    
  • WebClient 的快照:


更新

根据您在 cmets 中的计数器问题,WebDriverWait 会以特定间隔(默认 500 毫秒)轮询 HTML DOM,直到配置的时间量(在您的情况下为 30 秒)。一旦满足ExpectedConditions,就会返回元素/s。例如,如果在 1 秒内找到所需的元素,则返回它并执行您的下一行代码。不涉及延迟。根据WebDriverWait 构造函数,您始终可以配置 timeOutInSecondssleepInMillis 即轮询间隔。


参考

您可以在以下位置找到详细讨论:

【讨论】:

  • 我可以使用它。我很想知道,作为开发人员,您是否将“driver,30”放在要求它等待特定时间的位置——这是否是一种不好的做法?
  • @SheikhRahman 查看我的答案更新,如果有任何疑问,请告诉我。
【解决方案3】:

如果您的应用程序正在处理 Jquery,则可以处理此问题。此代码将等待您的页面完全加载所有必需的数据,并避免 invalidelementstateexception

线程“main”org.openqa.selenium.InvalidElementStateException 中的异常:无效元素状态

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);
}

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-11-04
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多