execute_script と evaluate_script の違いって何だろう
Capybara でテストを実行した際、下記のようなエラーが出てテスト失敗することがある。
1) Error: TopTest#test_Post_note: JSON::NestingError: nesting of 101 is too deep test/integration/top_test.rb:65:in `block in <class:TopTest>'
テストのソースを見たら evaluate_script
で発生しているエラーらしい。
のコメントに「 evaluate_script
でエラーが出るときは execute_script
を使ったらいいよ」と書かれていたので、その通りにしたら、テストが通るようになった。
じゃあ、 execute_script
と evaluate_script
って何が違うんだろう、と疑問に思ったので、 binding.pry
で二つの違いを追っかけてみた。結果は以下の通り。
1. execute_script
の動き
capybara-webkit/lib/capybara/webkit/driver.rb
def execute_script(script) value = @browser.execute_script script value.empty? ? nil : value end
↓
capybara-webkit/lib/capybara/webkit/browser.rb
def execute_script(script) command('Execute', script) end
↓
capybara-webkit/lib/capybara/webkit/driver.rb
def execute_script(script) value = @browser.execute_script script value.empty? ? nil : value end
2. evaluate_script
の動き
capybara-webkit/lib/capybara/webkit/driver.rb
def evaluate_script(script) @browser.evaluate_script script end
↓
capybara-webkit/lib/capybara/webkit/browser.rb
def evaluate_script(script) json = command('Evaluate', script) JSON.parse("[#{json}]").first end
ここで
JSON.parse("[#{json}]").first
を実行すると
JSON::NestingError: nesting of 101 is too deep from /vendor/bundle/ruby/2.2.0/gems/json-1.8.3/lib/json/common.rb:155:in `parse'
とエラー(= この記事の冒頭で出ていたエラーと同じ)が出てしまうが、
JSON.parse("[#{json}]").first
の代わりに
JSON.parse("[#{json}]", max_nesting: 101).first
としてやると、エラーが出なくなる( 参考 )。
3. 結論
execute_script
と evaluate_script
でやってることは同じだけど、evaluate_script
の方は Command の返り値を JSON.parse
してて、そこで nest が deep になる…、ということらしい。
テストで返り値を使ってないのであれば、 evaluate_script
は使わず execute_script
に統一しておいてもいいかも。