capybara + poltergeist でCSVダウンロードを行う際の罠と解決法
GWの中日に出社して初めてのブログ投稿を行っている山口です。
さて、今回はタイトルの通りの内容で、
管理画面におけるCSVダウンロードのE2Eテストをcapybara + poltergeistで実装した際の、罠と解決法を紹介していきます。
なお、以下のコードでは管理画面へのログイン処理は別途実行済みとします。
1. visitでCSV取得を試みる
単純にvisit(またはclick)でCSVダウロードURLにアクセスし、CSVを取得を試みます。
capybara.visit('https://example.com/sample.csv') # => {"status"=>"fail"}
結果は、failとなりました。
どうやらレスポンスとしてCSVが返ってきた場合Capybaraは失敗したとみなすようです。
さて、困りました。そして、ぐぐりました。
すると、以下の記事が見つかったので言われたとおりにexecute_scriptを使ってやってみることにします。
Downloading file to specific folder using Capybara and Poltergeist driver - Stack Overflow
2. execute_scriptを使いCSV取得を試みる
まず、execute_scriptで管理画面のコンテキストでJavaScriptの関数を定義します。
(Chromeの開発者ツールのconsoleで関数定義する感じです)
その後、evaluate_scriptで定義した関数を呼び出して、CSVのデータを受け取る流れとなります。
uri = URI.parse('https://example.com/sample.csv') js_methods = <<js_methods window.downloadCSVXHR = function() { var url = window.location.protocol + '//' + window.location.host + '/#{uri.path}?#{uri.query}'; return getFile(url); }; window.getFile = function(url) { var xhr = new XMLHttpRequest(); xhr.open('GET', url, false); xhr.send(null); return xhr.responseText; }; js_methods capybara.execute_script(js_methods) csv = capybara.evaluate_script('downloadCSVXHR()')
この修正で、大半のテストはうまくいきましたが、一部失敗するものがありました。
原因を探っていくと、下記Qiitaの記事に答えがありました。
どうやら、Content-Disposition: attachement なレスポンスは取得できないみたいです。
(正確には、該当レスポンスでも取得できるケースはありました。)
PhantomJS で Content-Disposition: attachment なレスポンスを取得する方法 - Qiita
記事ではforkされたadd_download_capabilitiesを使用することで対応されたようですが、
CSV取得テストのためだけに、本流からそれるのは避けたいなと考え。考え。考えました。
ひらめきました。単純にcookie取り出して別の方法でCSV取得すればいいじゃないか。
3. Curlを使いCSV取得を試みる
というわけで、capybaraからcookie情報を取り出し、CurlでCSV取得することにしました。
curl = Curl::Easy.new curl.headers = curl.headers.merge(capybara.driver.headers) curl.headers["Cookie"] = capybara.driver.cookies.each_with_object([]) { |(key, value), array| array.push("#{key}=#{value.value}" }.join('; ') curl.url = 'https://example.com/sample.csv' curl.http_get csv = curl.body_str
この方法で、すべてが失敗するケースはなくなり、山口に平和が訪れました。
まとめ
- Capybara + poltergiestでCSVダウンロードするなら、cookie取り出してCurlにたのめ。
- CSVダウンロードのテストに、Capybaraを使うべきかそもそもちゃんと考えよう。
それでは、残り少なくなってきましたが、よりよいGWをお過ごしください。