26

テストを実行すると、次のエラーが発生します:org.openqa.selenium.StaleElementReferenceException:要素がDOMにアタッチされなくなりました

上記の例外を解決する方法について何かアイデアはありますか?これは、動的なrefXpath式を持つグリッドで発生します

4

11 に答える 11

8

この問題は、WebdriverWrapper および WebElementWrapper と呼ばれる方法で回避できます。

これらのラッパーが行うことは、内部で StaleElementException を処理し、ロケーターを使用して再評価し、新しい WebElement オブジェクトを取得することです。このようにして、例外を処理するコードをコードベース全体に広げ、それを 1 つのクラスにローカライズする必要があります。

これらのいくつかのクラスだけをオープンソース化することをすぐに検討し、興味がある場合はここにリンクを追加します.

于 2011-02-28T16:29:10.513 に答える
4

この例外は、ページ上に存在しない WebElement のメソッドを使用しようとするとスローされます。グリッドがデータを動的にロードしているときにグリッドを更新すると、そのグリッド上の要素への参照はすべて「古く」なります。参照しようとしている要素がテストのページにあることを再確認してください。オブジェクトの再インスタンス化が必要になる場合があります。

于 2011-01-31T16:49:17.960 に答える
2

この問題も発生しました。モーダル パネルの読み込みが競合状態に陥り、タイムアウトになるまで待機し続けることは明らかです。

私は何度も試しましたが、解決策は、webDriver によって正確に検出されるまでモーダル パネルの読み込みを保持し、同時に webDriver インスタンスを更新し続け、モーダル パネル内で WebElements を見つけようとすることであることがわかりました。

したがって、解決策は次のようになります。たとえば、 MyModalPanelが ModalPanel Id の場合、次のようにします。

page.openModalPanel();
Assert.assertTrue(page.waitTillDisplay( "MyModalPanelContentDiv"), Wait.MODAL_PANEL));
page.fillInFormInModalpanel(formObj);

また、waitTillDisplay コードは WebDriver の Web サイトにあります。参照用にコードをここに貼り付けます。

public Boolean waitTillDisplay(final String id, int waitSeconds){

    WebDriverWait wait = new WebDriverWait(driver, waitSeconds);
        Boolean displayed = wait.until(new ExpectedCondition<Boolean>() {
              public Boolean apply(WebDriver driver) {
                  return driver.findElement(By.id(id)).isDisplayed();
              }

        });
        return displayed;

}

于 2011-11-07T06:55:43.913 に答える
1

FluentWaitとExpectedCondition適用オーバーライドを使用しました: https ://gist.github.com/djangofan/5112655 。これは、他の人がこれに答える方法とは異なり、完成したブロック内の例外を処理し、連続した試行をそのブロックにラップできるようにします。これはもっとエレガントだと思います。

public static void clickByLocator( final By locator ) {
  final long startTime = System.currentTimeMillis();
  driver.manage().timeouts().implicitlyWait( 5, TimeUnit.SECONDS );
  Wait<WebDriver> wait = new FluentWait<WebDriver>( driver )
        .withTimeout(90000, TimeUnit.MILLISECONDS)
        .pollingEvery(5500, TimeUnit.MILLISECONDS);
        //.ignoring( StaleElementReferenceException.class );        
  wait.until( new ExpectedCondition<Boolean>() { 
    @Override 
    public Boolean apply( WebDriver webDriver ) {
      try {
        webDriver.findElement( locator ).click();
        return true;
      } catch ( StaleElementReferenceException e ) {                      // try again
        return false;
      }     
    } 
  } );      
  driver.manage().timeouts().implicitlyWait( DEFAULT_IMPLICIT_WAIT, TimeUnit.SECONDS );
  long endTime   = System.currentTimeMillis();
  long totalTime = endTime - startTime;
  log("Finished click after waiting for " + totalTime + " milliseconds.");
}
于 2013-03-13T22:36:10.913 に答える
1

要素をクリックした後、要素のプロパティを取得しようとしている可能性があります。

私は同じ問題を抱えていました。ボタンをクリックした後、ボタンの getText() を試みていました。私の場合、ボタンをクリックすると、新しいウィンドウが表示されます。

于 2012-12-04T10:47:58.533 に答える
0

より柔軟にするためにいくつかの変更を加えました。

   delegate void StaleFunction(IWebElement elt);
        private static void StaleElementHandleByID(By by, StaleFunction func )
        {
            int count = 0;
            while (count < 4)
            {
                try
                {
                    IWebElement yourSlipperyElement = Driver.FindElement(by);
                    func(yourSlipperyElement);
                    count = count + 4;
                }
                catch (StaleElementReferenceException e)
                {
                    count = count + 1;
                }

            }
        }

 StaleElementHandleByID(By.Id("identDdl"),
                    delegate(IWebElement elt)
                {
                    SelectElement select = new SelectElement(elt);
                    select.SelectByText(tosave.ItemEquipamentoCem.CodigoCne.ToString());
                });
于 2012-06-08T12:08:09.960 に答える
0

迅速で汚い解決策:

el.click()

time.sleep(1)

次に、反復的に解析を続けます

于 2012-10-17T15:44:30.323 に答える
0

この場合、テストはまだロードされていない、または更新された要素を探しています。その結果、StaleElementException. 簡単な解決策は、fluentWait を追加することです。

于 2014-12-22T18:02:20.870 に答える