click するとどうなるのか

26
click 呼ぶとどうなるん? capybara + poltergeist ( + phantomjs ) の場合 [email protected]

Upload: atsushi-yasuda

Post on 07-Jul-2015

253 views

Category:

Engineering


3 download

DESCRIPTION

capybara + poltergeist な構成で、各種ブラウザへのイベントはどのように phantom js へ送られるかをソースコードを追って見る。

TRANSCRIPT

Page 1: click するとどうなるのか

click 呼ぶとどうなるん?capybara + poltergeist ( + phantomjs ) の場合

[email protected]

Page 2: click するとどうなるのか

自己紹介

• Crowdworks

• 元々はテストエンジニア

• ちょっと前まではゲーム作ってた

• 興味ある技術: prolog, Haxe, elm-lang

Page 3: click するとどうなるのか

ネタバレ・このバグの誰か直して…

Page 4: click するとどうなるのか

いつも RSpec 中などでこんな風に使っている click や visit と言ったメソッド群は

Page 5: click するとどうなるのか

Capybara::Session の定数として NODE, DOCUMENt, SESSION のメソッドをまとめた

DSL_METHOD って名前で登録されていて

Page 6: click するとどうなるのか

Capybara::DSL でこんな風にメソッド作られているので

Page 7: click するとどうなるのか

include すると使えます。

Page 8: click するとどうなるのか

で、やっていることは、 current_session の同名メソッド呼び出しです。

Page 9: click するとどうなるのか

current_session は capybara.rb に実装されていますが、 app は rack アプリ current_driver は Capybara::Driver のインスタンスです。

と、いうわけで Capybara::Session のインスタンスが visit や click を持っている訳ですね。

Page 10: click するとどうなるのか

ちなみに Session は初期化のタイミングでテスト対象のラックアプリを立ち上げます。

Page 11: click するとどうなるのか

まぁ、こんな感じで。

Page 12: click するとどうなるのか

さて、実際のところ、Capybara::Session は DSL_METHODS のうち SESSION_METHOD のみを実装してます。

NODE_METHODS と DOCUMENT_METHODS は

Page 13: click するとどうなるのか

こんな風にして、インスタンス変数へ送ってやっています。 ここの current_scope と document は各ドライバのインスタンスですね。

Page 14: click するとどうなるのか

こんな感じで、ドライバは node を実装しているので、 ここから先は driver の話となります。

Page 15: click するとどうなるのか

いきなり Capybara::Poltergeist::Node にいきたいのですが、 その前に Poltergeist::Driver の初期化について。

Poltergeist ドライバは内部に app, server, client とかが見えるとおもいます。 app は rack アプリですが、 server や client は

Poltergeist 独自のもの。

Page 16: click するとどうなるのか

server はこんな感じ。 Poltergeist は中で WebSocketServer を立ち上げます。

Page 17: click するとどうなるのか

client は PhantomJS をラップした javascript アプリケーション

Page 18: click するとどうなるのか

つまり、Capybara::Driver の実装である Poltergeist は、click とかを呼ばれると

Page 19: click するとどうなるのか

こんな風に、Polteregesit 内部の WebSocket サーバーに click というコマンドを積んで

Page 20: click するとどうなるのか

PhantomJS を操る javascript アプリケーションがそれを受け取り

Page 21: click するとどうなるのか

なんやかんやで js のこの辺に行き着くと言う訳です。 で、やることは scroll して、

絶対座標をとって、ブラウザの絶対座標に click イベントを送る、と。

Page 22: click するとどうなるのか

mouseEvent はこんな感じで、 マウスの座標を動かして、実際のイベントを送る

Page 23: click するとどうなるのか

sendEvent はこう実装されていて、 ここの this._native が phantomJS なので、イベントが発火する訳です。

Page 24: click するとどうなるのか

さて、先ほどみた mouseEvent 。 この 47 行目と 51 行目の間にノードがアニメーションして、

位置がずれているケースがあります。 この場合、座標に基づく click は成功しますが、ノードへの click は失敗します。 このケースは、capybara, poltergeist, phantomjs のデバッグログを見ても、 全て正常に見えますが、直接 console.log を挟んで座標を見るとわかります。

Page 25: click するとどうなるのか

そんな訳で、昨年3月くらいからレアケースとしてこんなバグがありますが、 まだ解決していません。

Page 26: click するとどうなるのか

crowdworks では、このバグを直せるエンジニアを募集しております。