2013-08-27 6 views
5

Webアプリケーションをテストするために、Ruby 1.9.3でCapybara 2.1を使用しています(MinitestとTest Unitを使用)。StaleElementReferenceキャッシュ内にエラー要素が見つかりません

私はStaleElementReferenceException問題で苦労しています。私はその話題についてかなりの議論を見てきましたが、私が直面している問題の解決策を見つけることができませんでした。

だから基本的に、私はこのコードを使用して自分のページ上のすべてのページネーション要素を見つけようとしている:

pagination_elements.first.must_have_content('1') 

後:

pagination_elements = page.all('.pagination a') 

その後、私のようなこれらの要素にいくつかのアサーションをやっていますこれらのアサーションは、次のページのリンクをクリックしてテストを続行し、今後の最初のページ区切り要素が前のページになるようにします。 は、私は再びpaginationsの要素を取得していますことを実行します。

new_pagination_elements = page.all('.pagination a') 

そして私は、私はすでに達した要素に到達していますので、古いエラーは、ここで起こっています。 (Here is the error

リンクの状態hereが表示されます。

この一般的なテストが正しく動作するようにするには、実際にはわかりません。 ページ区切り要素に到達するためのヒントがありますか?

+0

はhttps://github.com/jnicklas/capybara/issues/843に私はすでにこのトピックと関連するものを読んだ –

+0

@RajarshiDasを見てください、それから、本当に古い問題ですカピバラの前のバージョン、それは私の問題を助けることはありません。 – Evers

答えて

1

私は、要旨の主なメッセージは見た:

Element not found in the cache - 
perhaps the page has changed since it was looked up 

私が前に似たようなケースがあります。解決策は2つあります:あなたはspec_helper

  • findの前のページを持っていない新しいページに特別な要素をCapybara.automatic_reload = falseを設定している場合

    1. は、新しいページで同じものをチェックする前page.reloadを追加します。この効果は待機と同じです。

    特定のセレクタを使用する方法もあります。たとえば、代わりの

    pagination_elements = page.all('.pagination a') 
    

    使用

    pagination_elements = page.all('#post_123 .pagination a') 
    

    は、セレクタにユニークID領域を追加して、あなたはこのような問題を満たしていなければなりません。

  • +0

    統合テストはユーザーのフローに従っているため、ページを再ロードすることはページの一部ではないため、page.reloadの使用を避けたいと思います。 – Evers

    +0

    @Evers、ここでは何も間違っていません。デフォルトの設定は 'true'なので、すべてのアクションがコンテンツをリロードします。気づかなかっただけです。私は頻繁に対話するために私はJavascriptを使用するので、私はいつも 'false'を設定します。 'spec_helper'にそのような設定がない場合はこの部分を忘れてください。 –

    +0

    しかし、同じことを2回チェックすると、' reload'する力が助けになるかもしれません。試してみる価値がある。 –

    3

    私は時々AJAX集中的なページといくつかの問題を抱えている、私の場合には、この回避策は、それを解決:

    begin 
        ... 
    rescue Selenium::WebDriver::Error::StaleElementReferenceError 
        sleep 1 
        retry 
    end 
    
    0

    あなたはwebdriverを使用して、直接ではなく、カピバラ経由しようとしたことがありますか?このwoudlは、潜在的にオブジェクトをキャッシュしないタイミングをいつでも制御できます。

    (Javaの構文については謝罪が、アイデアを得る必要があります)「findElement」を割り当て

    WebElement searchField = driver.findElement(By.CssSelector("input.foo")); 
    
    searchField.click(); 
    
    searchField.sendKeys("foo foo"); 
    
    System.out.println(searchField.getText()); 
    
    //Do something elsewhere on the page which causes html to change (e.g. submit form) 
    
    ..... 
    .... 
    
    //This next line would throw stale object 
    
    System.out.println(searchField.getText()); 
    
    //This line will not throw exception 
    
    searchField = driver.findElement(By.CssSelector("input.foo")); 
    
    System.out.println(searchField.getText()); 
    

    は再び「searchField」に、我々は要素を再発見することを意味します。再割り当てしないタイミングを知っている場合は、キーを使用してWeb要素をキャッシュする方法を決定します。

    私はカピバラを使用していませんが、キャッシング戦略を隠していると思いますか?このエラーとどのようにそれを修正する程度

    +1

    他のプロジェクトですでにCapybaraを使用しており、Webdriver自体にロールバックすることは考慮していません。カピバラは私たちに多くの時間を節約します。しかし、あなたが正しいです、capybaraは、他の多くの間で、キャッシュ戦略を持っています:) – Evers

    +0

    私はRubyに移動しようとしており、使用するライブラリを決定しようとしています。私はWebdriverを直接使用すると思うようなものです。私はカピバラのようなものを使うのが大変です。 –

    +0

    Downvote?厳しいビット –

    1

    どうやら、条件をレースに加えて、このエラーはまた、誤用withinブロックに表示されます。たとえば:

    within '.edit_form' do 
        click '.edit_button' 
        # The error will appear here if the 'edit_button' is not a 
        # descendant of the 'edit_form' 
    end 
    
    +1

    それは私の場合です!私は内部の古いオブジェクトに偽のエラーを引き起こしていた '内部のブロックの中に閉じ込められていた - 古いものは私が見つけたものではなく、ブロックそのものでした! – igorsantos07

    関連する問題