click するとどうなるのか
-
Upload
atsushi-yasuda -
Category
Engineering
-
view
268 -
download
3
description
Transcript of click するとどうなるのか
click 呼ぶとどうなるん?capybara + poltergeist ( + phantomjs ) の場合
自己紹介
• Crowdworks
• 元々はテストエンジニア
• ちょっと前まではゲーム作ってた
• 興味ある技術: prolog, Haxe, elm-lang
ネタバレ・このバグの誰か直して…
いつも RSpec 中などでこんな風に使っている click や visit と言ったメソッド群は
Capybara::Session の定数として NODE, DOCUMENt, SESSION のメソッドをまとめた
DSL_METHOD って名前で登録されていて
Capybara::DSL でこんな風にメソッド作られているので
include すると使えます。
で、やっていることは、 current_session の同名メソッド呼び出しです。
current_session は capybara.rb に実装されていますが、 app は rack アプリ current_driver は Capybara::Driver のインスタンスです。
と、いうわけで Capybara::Session のインスタンスが visit や click を持っている訳ですね。
ちなみに Session は初期化のタイミングでテスト対象のラックアプリを立ち上げます。
まぁ、こんな感じで。
さて、実際のところ、Capybara::Session は DSL_METHODS のうち SESSION_METHOD のみを実装してます。
NODE_METHODS と DOCUMENT_METHODS は
こんな風にして、インスタンス変数へ送ってやっています。 ここの current_scope と document は各ドライバのインスタンスですね。
こんな感じで、ドライバは node を実装しているので、 ここから先は driver の話となります。
いきなり Capybara::Poltergeist::Node にいきたいのですが、 その前に Poltergeist::Driver の初期化について。
Poltergeist ドライバは内部に app, server, client とかが見えるとおもいます。 app は rack アプリですが、 server や client は
Poltergeist 独自のもの。
server はこんな感じ。 Poltergeist は中で WebSocketServer を立ち上げます。
client は PhantomJS をラップした javascript アプリケーション
つまり、Capybara::Driver の実装である Poltergeist は、click とかを呼ばれると
こんな風に、Polteregesit 内部の WebSocket サーバーに click というコマンドを積んで
PhantomJS を操る javascript アプリケーションがそれを受け取り
なんやかんやで js のこの辺に行き着くと言う訳です。 で、やることは scroll して、
絶対座標をとって、ブラウザの絶対座標に click イベントを送る、と。
mouseEvent はこんな感じで、 マウスの座標を動かして、実際のイベントを送る
sendEvent はこう実装されていて、 ここの this._native が phantomJS なので、イベントが発火する訳です。
さて、先ほどみた mouseEvent 。 この 47 行目と 51 行目の間にノードがアニメーションして、
位置がずれているケースがあります。 この場合、座標に基づく click は成功しますが、ノードへの click は失敗します。 このケースは、capybara, poltergeist, phantomjs のデバッグログを見ても、 全て正常に見えますが、直接 console.log を挟んで座標を見るとわかります。
そんな訳で、昨年3月くらいからレアケースとしてこんなバグがありますが、 まだ解決していません。
crowdworks では、このバグを直せるエンジニアを募集しております。