Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/365.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 使用EventFiringWebDriver时出现Selenium StaleElementReferenceException异常_Java_Selenium_Selenium Webdriver_Htmlunit Driver_Stalestateexception - Fatal编程技术网

Java 使用EventFiringWebDriver时出现Selenium StaleElementReferenceException异常

Java 使用EventFiringWebDriver时出现Selenium StaleElementReferenceException异常,java,selenium,selenium-webdriver,htmlunit-driver,stalestateexception,Java,Selenium,Selenium Webdriver,Htmlunit Driver,Stalestateexception,亲爱的各位,我正在使用SeleniumEventFiringWebDriver记录被调用的web驱动程序方法。我意识到,当我单独使用HtmlUnitDriver时,我经常会得到一个“”而我没有这个问题 我还认识到,虽然抛出了“StaleElementReferenceException”,但调用“click()”已在浏览器中执行 当EventFiringWebDriver在使用HtmlUnitDriver或FirefoxDriver时遇到这样的问题时,有人想到了吗? 可能是源驱动程序在运行时更新

亲爱的各位,我正在使用SeleniumEventFiringWebDriver记录被调用的web驱动程序方法。我意识到,当我单独使用HtmlUnitDriver时,我经常会得到一个“”而我没有这个问题

我还认识到,虽然抛出了“StaleElementReferenceException”,但调用“click()”已在浏览器中执行

当EventFiringWebDriver在使用HtmlUnitDriver或FirefoxDriver时遇到这样的问题时,有人想到了吗? 可能是源驱动程序在运行时更新了WebElements,而EventFiringWebDriver的源驱动程序没有更新吗? 或者我们应该将其作为EventFiringWebDriver实现的一个bug提出

EventFiringWebDriver示例代码-抛出StaleElementReferenceException

        HtmlUnitDriver driver = new HtmlUnitDriver();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        ExtentReports extent = new ExtentReports ("report.html", true);
        ExtentTest logger = extent.startTest("test");

        EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver);
        eventDriver.register(new MyWebDriverEventListener(logger));

        try {
            WebElement element  = null;
            eventDriver.get("https://www.google.com");
            element = eventDriver.findElement(By.xpath("//input[@type='text']"));
            element.sendKeys("Test");
            element.submit();
            Thread.sleep(2000);
            element = eventDriver.findElement(By.xpath("//div[@id='search']//a"));
            String title = element.getText();
            // HERE the StaleElementReferenceException get thrown ALTHOUGH the "click" event get processed by the browser, it loads already the page
            try {
                element.click();
            } catch(StaleElementReferenceException ex) {
            }
            Thread.sleep(2000);
            Assert.assertEquals(title, eventDriver.getTitle());
            logger.log(LogStatus.PASS,"end","Test passed");
         } catch(AssertionError error) {
            logger.log(LogStatus.FAIL,"end","Test failed:" + error.getMessage());
            throw error;
         }
        finally {
            extent.endTest(logger);
            extent.flush();
            extent.close();
            eventDriver.quit(); 
        }
at org.openqa.selenium.htmlunit.HtmlUnitDriver.assertElementNotStale(HtmlUnitDriver.java:963)
at org.openqa.selenium.htmlunit.HtmlUnitWebElement.assertElementNotStale(HtmlUnitWebElement.java:734)
at org.openqa.selenium.htmlunit.HtmlUnitWebElement.getTagName(HtmlUnitWebElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement$1.invoke(EventFiringWebDriver.java:332)
at com.sun.proxy.$Proxy18.getTagName(Unknown Source)
at ch.megloff.test.SimpleExtentReportWebDriverEventListener.afterClickOn(SimpleExtentReportWebDriverEventListener.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.openqa.selenium.support.events.EventFiringWebDriver$1.invoke(EventFiringWebDriver.java:81)
at com.sun.proxy.$Proxy16.afterClickOn(Unknown Source)
at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement.click(EventFiringWebDriver.java:346)
..s
同样的代码——只需直接使用HtmlUnitDriver,就可以毫无问题地工作

        HtmlUnitDriver driver = new HtmlUnitDriver();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        ExtentReports extent = new ExtentReports ("report.html", true);
        ExtentTest logger = extent.startTest("test");

        try {
            WebElement element  = null;
            driver.get("https://www.google.com");
            element = driver.findElement(By.xpath("//input[@type='text']"));
            element.sendKeys("Test");
            element.submit();
            Thread.sleep(2000);
            element = driver.findElement(By.xpath("//div[@id='search']//a"));
            String title = element.getText();
            element.click();
            Thread.sleep(2000);
            Assert.assertEquals(title, driver.getTitle());
            logger.log(LogStatus.PASS,"end","Test passed");
         } catch(AssertionError error) {
            logger.log(LogStatus.FAIL,"end","Test failed:" + error.getMessage());
            throw error;
         }
        finally {
            extent.endTest(logger);
            extent.flush();
            extent.close();
            driver.quit(); 
        }

在研究过时异常的堆栈跟踪后,我发现问题并非直接来自EventFiringWebDriver。当我在执行单击后尝试获取元素的标记名时,它由的侦听器实现抛出

对我来说,它的设计似乎不是最优的。换言之,您可能无法在“afterXXX”方法中使用传递的WebElement,否则您可能会面临过时异常的风险。相反,您应该使用“beforeXXX”方法来检索元素的详细信息

StaleElementReferenceException的堆栈跟踪

        HtmlUnitDriver driver = new HtmlUnitDriver();
        driver.manage().timeouts().implicitlyWait(3, TimeUnit.SECONDS);

        ExtentReports extent = new ExtentReports ("report.html", true);
        ExtentTest logger = extent.startTest("test");

        EventFiringWebDriver eventDriver = new EventFiringWebDriver(driver);
        eventDriver.register(new MyWebDriverEventListener(logger));

        try {
            WebElement element  = null;
            eventDriver.get("https://www.google.com");
            element = eventDriver.findElement(By.xpath("//input[@type='text']"));
            element.sendKeys("Test");
            element.submit();
            Thread.sleep(2000);
            element = eventDriver.findElement(By.xpath("//div[@id='search']//a"));
            String title = element.getText();
            // HERE the StaleElementReferenceException get thrown ALTHOUGH the "click" event get processed by the browser, it loads already the page
            try {
                element.click();
            } catch(StaleElementReferenceException ex) {
            }
            Thread.sleep(2000);
            Assert.assertEquals(title, eventDriver.getTitle());
            logger.log(LogStatus.PASS,"end","Test passed");
         } catch(AssertionError error) {
            logger.log(LogStatus.FAIL,"end","Test failed:" + error.getMessage());
            throw error;
         }
        finally {
            extent.endTest(logger);
            extent.flush();
            extent.close();
            eventDriver.quit(); 
        }
at org.openqa.selenium.htmlunit.HtmlUnitDriver.assertElementNotStale(HtmlUnitDriver.java:963)
at org.openqa.selenium.htmlunit.HtmlUnitWebElement.assertElementNotStale(HtmlUnitWebElement.java:734)
at org.openqa.selenium.htmlunit.HtmlUnitWebElement.getTagName(HtmlUnitWebElement.java:291)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement$1.invoke(EventFiringWebDriver.java:332)
at com.sun.proxy.$Proxy18.getTagName(Unknown Source)
at ch.megloff.test.SimpleExtentReportWebDriverEventListener.afterClickOn(SimpleExtentReportWebDriverEventListener.java:111)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at java.lang.reflect.Method.invoke(Method.java:498)
at org.openqa.selenium.support.events.EventFiringWebDriver$1.invoke(EventFiringWebDriver.java:81)
at com.sun.proxy.$Proxy16.afterClickOn(Unknown Source)
at org.openqa.selenium.support.events.EventFiringWebDriver$EventFiringWebElement.click(EventFiringWebDriver.java:346)
..s
底层数据库的“getTagName()”的Java代码片段

此“afterClickOn”方法的“易出错”侦听器实现-执行单击后不应调用“GetTaName()”

 public class MyWebDriverEventListener extends AbstractWebDriverEventListener {
    ...
    @Override
    public void afterClickOn(WebElement element, WebDriver driver) {
        // bad implementation, click has been already performed 
        // so you may risk to have a stale exception in case the 
        // browser  switched already to the other page (DOM got changed)
        logEvent("Clicked on tag: " + element.getTagName() + " with href: " + element.getAttribute("href"));
    }
 }