0

親愛なるすべて私は、呼び出されたWebドライバメソッドを記録するためにSelenium EventFiringWebDriverを使用しています。 「StaleReferenceException」を取得することが多いと認識していますが、HtmlUnitDriverだけでは問題はありません。EventFiringWebDriverの使用中にSelenium StaleElementReferenceExceptionが発生する

「StaleElementReferenceException」がスローされたにもかかわらず、ブラウザで「click()」という呼び出しが実行されたことも認識しました。

HtmlUnitDriverまたはFirefoxDriverスタンドアロンを使用しているときに、EventFiringWebDriverがそのような問題にぶつかる間に誰かがアイデアを持っていますか? EventFiringWebDriverのwrapped WebElementsが実行されていない間に、WebElementsが実行時に起点ドライバによって更新されることはありますか? これをEventFiringWebDriver実装のバグとして提起する必要がありますか? 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(); 
     } 

同じコードをスローします - ちょうど私が認識し、古い例外のスタックトレースを学んだ後も問題

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

答えて

0

せずに動作しますが、直接HtmlUnitDriverを使用してこの問題は、EventFiringWebDriverから直接得られるものではありません。リスナー実装のWebDriverEventListenerによってスローされますが、クリックが行われた後に要素のタグ名を取得しようとしています。

私にとっては、WebDriverEventListenerのデザインが最適ではないようです。言い換えれば、渡されたWebElementを "afterXXX"メソッドで使用することはできません。そうしないと、古い例外が発生する可能性があります。代わりに、要素の詳細を取得するために "beforeXXX"メソッドを使用する必要があります。

この "afterClickOn" メソッドのための基礎となるHtmlUnit Implementation

public String getTagName() { 
    assertElementNotStale(); 
    return element.getNodeName(); 
} 

私の "誤りがちな" リスナーの実装の "GETTAGNAME()" の私のStaleElementReferenceException

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 

Javaコードスニペットのスタックトレース - クリックが行われた後に「getTagName()」を呼び出さないでください。

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")); 
    } 
} 
関連する問題