4

page-object gem と Watir Webdriver を使用すると、ページで Selenium::WebDriver::Error::StaleElementReferenceError に出くわすことがあります。このエラーは、いくつかの基本的なものをロードし、ajax リクエストを作成し、より多くの情報を再入力します (速度の錯覚のため)。ページで)。

これは、そこに HTML 要素が存在するために発生し、すぐに消えて、ユーザーが実際に気付く前に再び表示されます。

ページオブジェクトの「.when_present」メソッドを使用して、オブジェクトが最初にページに表示されるまで待機してからアクセスします。ただし、コードが要素を見つけた後でも、通常、古い要素エラーが発生します。これは、元の HTML 要素がなくなり、アクセスしようとするまでに別の要素が再び表示されるためです。

これを回避するために、(ページオブジェクトではなく) ストレートな Watir を使用する方法を見つけました。基本的に、Watir::Wait.until ブロッ​​ク内で StaleElementReferenceError をキャッチします。例外が発生した場合、ブロックは false を返し、Wait.until は true になるかタイムアウトになるまで再試行します。私たちが発見したことは、これは通常、最初に Stale Element を取得し (以下の 3 行目)、レスキューから false を返し、Wait.until がブロックを再度実行し、2 回目は true であり、テストに移行して合格することです。 .

1  Watir::Wait.until {
2    begin
3      tds = page.my_element.when_present.element.tds
4      table_data_classes = tds.map{|cell| cell.attribute_value("class") }
5
6      # Should have at least one with a class of "xyz"
7      xyz = table_data_classes.select{|data| data.include?("xyz")}
8      xyz.size > 0 
9    rescue Selenium::WebDriver::Error::StaleElementReferenceError
10     false
11   end
12 }

この種のページオブジェクトラッパーがあるかどうかは本当に疑問です。何も見つかりませんでした。そうでない場合は、上記が機能するため問題ありません。ちょっと興味があるんだけど。

ありがとう

4

1 に答える 1

3

ゲイル、素晴らしい質問です。現時点では、page-object gem で StaleElementReferenceError が発生した場合の再試行の具体的な処理はありません。別の人から定期的にこのエラーが発生すると聞いたことがありますが、これは私が調べることができるものです。watir-webdriver のどのバージョンを使用していますか?

page-object を使用して上記のコードを複製する方法があります。あなたが提供した上記のコードがあなたのページの中にあるのか、それとも別の場所にあるのか (ステップ定義や他の場所など) はわかりません。page-object gem を使用して行うことは次のとおりです。

PageObject クラスの内部

def has_element_with_class(clz)
  wait_until
    begin
      cells = my_element.when_present.cell_elements
      cells.any? { |cell| cell.attribute('class').include? clz }
    rescue Selenium::WebDriver::Error::StaleElementReferenceError
      false
  end
end

ネストされたすべてのセル (tds)my_elementを配列に入れているだけです。any?ブロックのいずれかがtrueを返し、それ以外の場合はfalseを返す場合はtrueを返すその配列のメソッドを呼び出しています。これは、上記のすべてのコードと同じ効果があります。エラーが発生した場合は、もう一度続行します。

于 2013-04-13T14:37:32.717 に答える