便利ツール

AppiumでWebViewエレメントの正しい座標を取得する方法

はじめに

以前、Appium を使って WebView で表示しているコンテンツの中身にアクセスする方法をご紹介しました。

参考AppiumでWebView内部の要素にアクセスする方法

Appiumを使って、WebViewを扱うモバイルアプリの試験を行う場合、表示しているウェブページにアクセスできず苦戦している方も多いのではないでしょうか。そこで、WebViewを扱うAndroidアプリを対象に、どのようにアクセスすればよいのかを解説します。

続きを見る

 

最後のサンプルコードですが、実行結果に少し違和感を覚えた方もいらっしゃるかと思います。
取得したエレメントの座標値が、実際のスクリーン上の座標値と異なっています

なぜこのようなことが起きるのかを順番に説明し、解決方法を解説します。

 

不可解な座標値

エミュレータの画面は 幅1080ピクセル、高さ2220ピクセルの Google Pixel 3a を使用していました。

Appium 公式ページの「ダウンロード」ボタンは、画面上では以下の位置にあるように見えます。

  • X座標:幅1080ピクセルの1/4程度、270ピクセルから始まっている
  • Y座標:画面中央の1110ピクセルより下に描画されている

 

一方、getElementRect() で取得した左上の座標は、(x: 106, y: 400)になっています。

 command
INFO webdriver: COMMAND getElementRect("e0458b00-7222-46a0-b26e-c65f9ca3b311")
INFO webdriver: [GET] http://127.0.0.1:4723/wd/hub/session/2d2063db-a44c-4b49-8530-da40bcacd962/element/e0458b00-7222-46a0-b26e-c65f9ca3b3
11/rect
INFO webdriver: RESULT { height: 45, width: 180, x: 106.22159576416016, y: 399.8238830566406 }
SANACHAN
SANACHAN
見た目よりもかなり左上に表示されていることになります。

 

getElementRect が示す座標の意味

getElementRect で指定したエレメントは、WebView 内に表示されているエレメントを指定しました。
つまり、WebView 内に表示されている Webコンテンツの座標系で計算されています。

スマホの Chrome アプリで「PC版サイト」として表示した場合、文字が小さく表示されます。
実際の画面の解像度で表示されるため、7インチ程度のスマホ画面だと小さくなってしまうのです。

SANACHAN
SANACHAN
スマホは、PCのディスプレイ(1920x1080)を手のひらサイズにしたものです。

 

この問題を回避するため、ViewPort という考え方が導入されています

 

スマホのブラウザや WebView エレメントは、この ViewPort と呼ばれる領域にレンダリングします。
document.documentElement.clientWidth で確認すると、幅は480ピクセルになっています。
一般的なスマホの場合、幅480、高さ960ピクセル程度の領域に設定されています。

参考

ViewPort についての詳細は、Qiita記事 などをご覧ください。

 

重要ポイント

WebView 内の要素に対する getElementRect は、この ViewPort 上の座標を返します。

SANACHAN
SANACHAN
ViewPortにレンダリングし、拡大して画面に表示されているわけですね。

 

画面上の座標を取得する方法

では、どのように画面上の座標を取得すればよいのでしょうか?
最後にその方法を説明いたします。

Appium の API である touchAction() などは、画面上の座標を指定して利用します。
試験の自動化が目的で Appium を利用する場合が多く、人が操作する「タップ」を模擬する必要があります。

 

ViewPortとWebViewの座標関係

ViewPortとWebViewの座標関係

 

step
1
WebViewの座標を取得

先ず、Nativeアプリ側の WebView の座標を取得します。
WebView 自体は Native アプリのエレメントになるため、画面上の座標値が返ります。

 

step
2
ViewPortの座標を取得

次に、ViewPort の座標を取得します。
Appium の execute() を使用して、WebView 内の JavaScript から値を取得します。

 

step
3
比率から画面上の座標を計算

次に、スクリーン上の座標系と WebView の座標系の比率を計算します。

拡大率となるこの ratioXratioY を使って、画面上の座標を計算します。

 

step
4
WebViewが配置されている位置(オフセット)を加算

最後に、最初に取得した WebView の画面上の位置(offset)を考慮して、
取得したいWebView内のエレメントの座標を算出します。

 

サンプルプログラム

SANACHAN
SANACHAN
最後に WebView のオフセット(x, y)座標を加算しています。

 

こちらの記事もよく読まれています

  • この記事を書いた人
  • 最新記事
SANACHAN

SANACHAN

「生涯一エンジニア」を掲げ、大手グローバル企業でSE/PGとして8年勤め、キャリアアップ転職した現役のエンジニアです。世にあるメジャーな全プログラム言語(コボル除く)を自由に扱えます。一児の父。自分のため、家族のため、日々勉強してます。システムエンジニア、プログラミングに関する情報を蓄積している雑記帳です。

-便利ツール
-,