こんにちは。毎日欠かさずAndroidと心で対話をおこなうHTMLファイ部の高橋です。入社4週目にしての初投稿です。 UIのタッチ操作が絡むJSのテストで、タッチイベントを生成する際のハマりどころをエントリします。
きっかけ
先日、JsTestDriverでタッチイベントの生成をした際、Androidだけイベントが生成されず何のエラーも出ないという事象が発生。
その答えは「selenium」の中にありました。
// Android's initTouchEvent method is not compliant with the W3C spec.
// Android's initTouchEvent method is not compliant with the W3C spec.
// Android's initTouchEvent method is not compliant with the W3C spec. だと?(大事なことなので)
さらに selenium のコードを追ってみると
// Native touch api supported starting in version 4.0 (Ice Cream Sandwich).
の表記があり、selenium の中では、4.0(ICS)以下の場合 initMouseEvent でイベントの初期化を行い、そのイベントオブジェクトに対して touches, targetTouches などのプロパティを追加してイベントを生成しているようです。 (ツッコみどころがありすぎる)
今回は、試しに上記 events.js 443行以下のイベント生成方法で検証を行ったところ、Android2.1以上(1系は検証していません)ではイベントが生成されたので、その結果をまとめたいと思います。
initTouchEvent 仕様
Android, iOSにおけるinitTouchEventの仕様を書き出してみました。
// iOS initTouchEvent
// via. TouchEvent Class Reference | Safari Development Library
// https://developer.apple.com/library/safari/#documentation/UserExperience/Reference/TouchEventClassReference/TouchEvent/TouchEvent.html
event.initTouchEvent(
type,
canBubble,
cancelable,
view,
detail,
screenX,
screenY,
clientX,
clientY,
ctrlKey,
altKey,
shiftKey,
metaKey,
touches,
targetTouches,
changedTouches,
scale,
rotation
);
// Android initTouchEvent
// via. events.js | selenium
// http://code.google.com/p/selenium/source/browse/trunk/javascript/atoms/events.js#443
event.initTouchEvent(
touches,
targetTouches,
changedTouches,
eventType,
view,
screenX,
screenY,
clientX,
clientY,
ctrlKey,
altKey,
shiftKey,
metaKey
);
すごく、引数多いです…。
見てのとおり、AndroidにはcanBubble, cancelable, detail, scale, rotationの5個が存在せず、順番も違うため、生成の際は切り分けてあげる必要があります。
サンプルコード
[TEST] createTouchEvent - jsdo.it - share JavaScript, HTML5 and CSS
(Android, iOSでアクセスすると動作確認ができます >> http://jsrun.it/keeeeei/p3Mf )
このように簡単なラッパーを作ってあげると、すごく便利にタッチイベントを生成することができますね!