F.Ko-Jiの「一秒後は未来」

Selenium WebDriver と Chrome で StaleElementReferenceError が頻発するようになったので対処した

Chrome が更新されたせいか Selenium WebDriver を使ってるテストが大量にエラー。エラーの詳細は、

Selenium::WebDriver::Error::StaleElementReferenceError:
       stale element reference: element is not attached to the page document

というもの。「For documentation on this error, please visit: http://seleniumhq.org/exceptions/stale_element_reference.html」とエラーメッセージにあるので「Stale Element Reference Exception」を読んでみると、

– The element has been deleted entirely.
– The element is no longer attached to the DOM.

とあるのだが、エラーが出るのは例えば「ログインして次のページでリンクをクリックする」といったテスト。要素が存在しないとか DOM が消えるとかはないはず。

そこで色々とデバッグしてみたところ、ログイン後にリンクがきちんと表示されるまで待ってないことが分かった。というか、リンクが表示されるまで待機する処理を入れると StaleElementReferenceError は回避されるようになった。

# @wait は Selenium::WebDriver::Wait のインスタンス
# @driver は Selenium::WebDriver のインスタンス
@wait.until do
  @driver.find_element(:link, 'レッスン一覧').displayed?
end

どうもフォームのボタンをクリックした際のページ遷移をきちんと待ってくれない模様。なのでログインやログアウトなどの遷移のたびに Wait の until メソッドを使って画面遷移がきちんと完了するのを待つように修正した。

あと同様に alert や confirm のダイアログが表示されるところでも、ダイアログが表示されるまで待ってくれない。ついでにダイアログのボタンをクリックした後にダイアログが消えるのも待ってくれない。

これについても、

  # NoAlertPresentError エラーが出なくなるまでループ
  while true
    begin
      @driver.switch_to.alert.accept
      break
    rescue Selenium::WebDriver::Error::NoAlertPresentError
    end
  end

  # ダイアログが消えるまで待つ
  @wait.until do
    @driver.window_handles.length == 1
  end

  @driver.switch_to.window(@driver.window_handles.first)

こんな感じで待機処理を入れるようにした。

(追記 2015-08-02) Issue 1158 – chromedriver – Unable to find elements after installing Chrome 44 – WebDriver for Google Chrome – Google Project Hosting にて議論されていた模様。 ChromeDriver 2.17 で修正されたとあるけどどうだろう?

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です

著者について

fkoji

F.Ko-Ji

Webエンジニアやってます。最近は ドットインストール の開発がお仕事です。その傍ら、個人で Meity電車遅延なう梅酒.in#グラドル自画撮り部 の部室といったネットサービスを開発・運営してます。梅酒と草野球とリアル脱出ゲームが好きです。

» 詳しいプロフィールや運営サービスの一覧など