node.jsを使う機会があって、zombie.jsで、あるページにアクセスした時、404のページに飛ぶはずってテストを書く予定だった。
すごく使いやすいからみんな使うといいと思う(すてま
インストールも簡単。
zombie.jsが実行ファイルだとして、
/path/to/zombie.js
/path/to/node_modules/{いろんなライブラリ}
みたいな設定。
インストールするライブラリはzombieのみ(ほんとはvowsとか使ったけどw)
なので、nodeをインストールした時に自動的にインストールされるnpmコマンドでインストールすればよくて、
npm install zombie
でカレントディレクトリのnode_modulesディレクトリ以下にzombieがインストールされる。
オプションとして-gをつければnodeのグローバルなライブラリとしてインストールが出来る。
この状態で、
var Zombie = require("zombie"), browser = new Zombie(), url = "http://huwshimi.com/404"; browser.visit(url) .then(function(){ console.log(browser.text("title")); }) .fail(function(err){ console.dir(err); });
と書いて、
node zombie.js
と実行する。そうすると、色々出てくるんだけど、
Server returned status code 404 from http://huwshimi.com/404 Error: Server returned status code 404 from http://huwshimi.com/404 at /path/to/node_workspace/zombie_404/node_modules/zombie/lib/zombie/window.js:411:23 at /path/to/node_workspace/zombie_404/node_modules/zombie/lib/zombie/eventloop.js:234:18 at Object._onImmediate (/path/to/node_workspace/zombie_404/node_modules/zombie/lib/zombie/eventloop.js:139:11) at processImmediate [as _immediateCallback] (timers.js:330:15) [Error: Server returned status code 404 from http://huwshimi.com/404]
これは・・・ぺろ・・・青酸k・・・いや、標準エラー出力。
ちなみに利用したURLは
http://gigazine.net/news/20110629_30_creative_404/
で紹介されてた404のページw
この標準エラー出力は、困ったことにオプションとかで消すことが出来ず、ソースを見る限り、ステータスコードが400以上の時に必ずエラーが発生する。
そして、catchもできない。
browser.on("error",fn())
とかでなんとかできるかとか思ったけど無理だった。
色んな所見たんだけど解決策なかった。
こことか
あともう一個Issueのページが有ったんだけど見失った。。。
なので、とりあえず、protptypeで拡張してなんとかすることにした。
結果
var Zombie = require("zombie"), browser = new Zombie(), url = "http://huwshimi.com/404", temp_emit = browser.emit; Zombie.prototype.ERROR_404_MESSAGE_NO_URL = "Error: Server returned status code 404 from "; Zombie.prototype.is_404_error = function(event,error_message){ return (event === 'error' && error_message.toString() === this.ERROR_404_MESSAGE_NO_URL + this.url); } Zombie.prototype.emit = function(event,argv){ if(this.is_404_error(event,argv)){ return true; } return temp_emit(event,argv); } browser.visit(url) .then(function(){ console.log(browser.text("title")); }) .fail(function(err){ console.dir(err); });
これで一応標準エラー出力はでなくなった。
ちなみに、emitはEventEmitterのメソッドで、(参考)たぶん、Browserオブジェクトにprototypeで継承するような形で利用している。(たぶん,ソース見たけどあんまりわからなかった←)