Protractor + WebDriver で楽天銀行と Gmail にログインして入出金明細を保存
上記のリポジトリに Pull Request を出させてもらった。それがこちら。
- (Gmail等に) IMAP でログインしてメールを監視
- 楽天銀行にログインしてワンタイムパスワードのメールを送信
- ワンタイムパスワードが書かれたメールが来るまで browser.wait() + protractor.promise.defer() *1 で待つ
- ワンタイムパスワードでログインして入出金明細を TSV ファイルとして保存 *2
みたいなことしてます。
正直 Protractor のデバッグが一番大変だった。 変な場所で expect() してて全然関係ないテストでコケたりしてた。 デバッグは正直勘で進めてしまったのでよくない。 ちゃんと詳細なログとか取れる方法があるかもっと調べればよかった。
Windows 対応
ついでに既存の npm run-scripts の Windows 対応もした。
本文終わり。以下は調べたことです。
実装中に調べたこと
参考にしたページ
- まだmechanizeで消耗してるの? WebDriverで銀行をスクレイピング(ProtractorとWebdriverIOを例に) - 詩と創作・思索のひろば
- Node.js の IMAP 用 ライブラリ inbox
iconv を Windows でビルドするための環境構築
- SE奮闘記: IMAPでGmailを監視して、新着メールがあったらPHPを実行
- node.js - NodeJS - Error installing with NPM - Stack Overflow
- Windows users are not happy. · Issue #629 · nodejs/node-gyp · GitHub
この2つのサイトがとっかかりとしてはとても助かったんだけど、一つまずい箇所がある。
それは {stream}.on('data', ...)
に来たバッファから文字列を検索してるけど、data
の時に渡されるデータは細切れなので、
iconv の変換時に不正なバイトとしてエラーになる可能性がある (なった)。
あと潜在的に検索文字列の途中で切れてたら検索に引っかからない。
なのでこのようにした。
stream.on("data", function(chunk) { body += chunk; }); stream.on("end", function() { body = converter.convert(body).toString(); // FIXME: body にはヘッダ部も含まれているため RFC822 に則ってちゃんとパースする? if (/ワンタイムキー[ ]*[::][ ]*([a-zA-Z0-9]+)/.test(body)) { var otKey = RegExp.$1; console.log('ワンタイムキーを本文から取得成功:' + otKey); deferred.fulfill(otKey); } else { console.log('ワンタイムキーを本文から取得失敗'); deferred.reject(); } });
- nodejs-guidelines/windows-environment.md at master · Microsoft/nodejs-guidelines · GitHub
- 上にリンクいっぱい書いたけど、結局公式のこのガイド通りにやったらいけた。
以下は init.cmd の Node 関連の内容。
rem # Node set PATH=C:\Program Files\nodejs;%USERPROFILE%\AppData\Roaming\npm;%PATH% rem # ================ Prerequisites for Node ================ rem # https://github.com/Microsoft/nodejs-guidelines/blob/master/windows-environment.md rem # Visual Studio rem # set PATH=C:\Program Files\Microsoft SQL Server\110\Tools\Binn\;%PATH% set PATH=C:\Program Files (x86)\Windows Kits\8.1\Windows Performance Toolkit\;%USERPROFILE%\.dnx\bin;C:\Program Files\Microsoft DNX\Dnvm\;C:\Program Files\Microsoft SQL Server\130\Tools\Binn\;%PATH% rem # Python 2.7 set PATH=C:\Python27;C:\Python27\Scripts;%PATH% rem # ================ Prerequisites for Node ================
browser.wait()
- How to use browser.wait() to wait for URL to change? · Issue #610 · angular/protractor · GitHub
- Protractor - end to end testing for AngularJS
- browser.wait() に Promise を返す関数を渡すと resolve() されるまで待ってくれる (Promise をそのまま渡してもいいのかな?)。
- Protractor blocking wait | Emmett Pickerel's
- protractor/toc.md at master · angular/protractor · GitHub
- Protractor - end to end testing for AngularJS, protractor/timeouts.md at master · angular/protractor · GitHub
- Jasmine, WebDriver, Protractor それぞれにタイムアウトがある
- Protractor - end to end testing for AngularJS
If your page does manual bootstrap Protractor will not be able to load your page using browser.get. Instead, use the base webdriver instance - browser.driver.get. This means that Protractor does not know when your page is fully loaded, and you may need to add a wait statement to make sure your tests avoid race conditions.
(2段階認証を使っている場合) アプリパスワードを生成
2段階認証を使っている場合はパスワードをそのまま入力したのではログインできない。 アプリパスワードというアプリ固有のパスワードを発行する必要がある。
node.js - Authentication issue with node imap and node mail lister - Stack Overflow
https://support.google.com/accounts/answer/6010255
この設定は、2 段階認証プロセスが有効になっているアカウントでは利用できません。こうしたアカウントで安全性の低いアプリにアクセスするには、アプリケーション固有のパスワードが必要です。 ヘルプ
発行されたパスワードをそのままアカウントのパスワードとして渡せば認証される。