grunt-contrib-jasmineの Third party templates にあるCode coverage output with Istanbulを使って jasmine テストの coverage の計測をしようとしているのですが、XMLHttpRequest を実行するところで Cross Origin の制約にひっかかってエラーになってしまう。localhost で実行されるのが理由かなとは思われるのですが、普通に jasmine テストを実行した場合はひっかからない不思議…(エラーに「file://」が出ているのも不明) jasmine の coverage 用のタスクのオプションで host を localhost に指定していなかったためだった。そのため、localfile system (file://) で起動していた… 設定を追加したら CORS の設定は必要なかった。
XMLHttpRequest cannot load http://localhost:9002/foobar.js. Origin file:// is not allowed by Access-Control-Allow-Origin.
理由はさておき、Access-Control-Allow-Origin(HTTP access control (CORS)参考)を設定すれば、エラーを抑制できるはず(javascript - Origin is not allowed by Access-Control-Allow-Origin - Stack Overflowも参考)。grunt-contrib-connectでサーバーを立ち上げて PhantomJS がそこから Jasmine specs を実行するようにしているので、grunt-contrib-connect に CORS の設定をする。
grunt-contrib-connect で立ち上げたサーバーの header に Access-Control-Allow-Origin を追加するには… middleware のオプションを使うと良いらしい。middleware のオプションは、return に function の配列を渡すことで、渡した function を順繰り実行してくれるみたい。Access-Control-Allow-Origin の追加方法は、Allowing CORS (Cross-Origin Resource Sharing) requests from grunt serverを参考にしました。この Gist のだけだと、grunt-contrib-connect のタスクでデフォルトで設定されている middlewareが実行されなくなってしまうので、デフォルトで設定されている function も一緒に追加する。すると、こんな感じの設定になる。
test: {
options: {
hostname: 'localhost',
port: 9002,
keepalive: true,
middleware: function (connect, options) {
return \[
function (req, res, next) {
res.setHeader('Access-Control-Allow-Origin', '*');
res.setHeader('Access-Control-Allow-Methods', '*');
next();
},
// Serve static files.
connect.static(options.base),
// Make empty directories browsable.
connect.directory(options.base)
\];
}
}
},
これで Cross Origin のエラーが発生することなく、coverage の計測が完了するようになりました。
というメモ