便利ツール

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

2022年11月13日

はじめに

Appium を使って、モバイルアプリの試験自動化を検討されている方も多いと思います。
しかし、非常に基本的な試験コードの書き方しか Web 上に見当たらず、
諦めモードに入っているのではないでしょうか。

WebView で表示しているコンテンツの中身にアクセスできず、私も苦戦していました。

そこで今回は、WebView を扱う Android アプリの試験を対象に、
どのように WebView の中身にアクセスすればよいのかを解説します。

SANACHAN
以下、当サイトの関連記事になります。ご参考までに。

 

Androidアプリ側の変更(前準備)

Appium から WebView にアクセスするには、アプリ内で使用する WebView に対して追加設定が必要です。

SANACHAN
セキュリティ(予想)の関係で、そのままではアクセスできないようです。

 

関連記事で紹介したサンプルコードでは、以下のように1行追加する必要があります。

 

Appium 公式ドキュメントで、Hybrid Apps 向けに以下の記載があります。
WebView を使用する際は、setWebContentsDebuggingEnabled の設定が必要になります。

Appium comes with built-in hybrid support via Chromedriver, which allow the automation of any Chrome-backed Android web views.
There is an additional step necessary within your app build, unfortunately. As described in the Android remote debugging docs it is necessary to set to true the setWebContentsDebuggingEnabled property on the android.webkit.WebView element.
Once you have set your desired capabilities and started an Appium session, follow the generalized instructions above.

 

対象のコンテキストを検索・切替

Android アプリで WebView を使用する場合、実行する世界が異なります。
Android アプリそのものは Java/Kotlin の世界(NATIVE_APP)で実行され、
WebView は Chrome などと同じ HTML/JavaScript の世界(WEBVIEW_XXXX)で実行されます。

SANACHAN
WebViewを複数持つ場合は、それぞれのWebViewでも世界が異なります。

 

step
1
コンテキスト一覧の取得

先ずは、Appium の WebDriverIO を通して、これら世界のコンテキスト一覧を取得する必要があります。
具体的には、getContexts という API を使用します。

 getContexts
let contextNames = await client.getContexts();

step
2
対象のコンテキストへ切替

一覧が取得出来たら、試験したい対象のコンテキストへ切り替える必要があります。
具体的には、switchContext という API を使用します。

SANACHAN
上記例では、最初に見つかった WebView のコンテキストに切り替えます。
条件は必要に応じて変更可能です。1つ1つの WebView に、特殊な名前が付いています。

 

WebView 内部の要素にアクセス

コンテキストを切り替えた後は、Appium API ドキュメントに記載されている API が利用できます。
DOM系は「Element」、操作系は「Interactions」、JS Runtime系は「Web」あたりでしょうか。

以下、Appium 公式ページの Download ボタンの座標を取得するサンプルコードです。

Appium公式ページをAndroidエミュレータで表示した画面

 

UI試験用コード実行結果

それではさっそく実行してみましょう。
Appium サーバー(Appium Desktop)を起動し、コマンドプロンプトから以下を実行します。

 command
$ node test_webview.js

 

コンテキスト

 command
INFO webdriver: COMMAND getContexts()
INFO webdriver: [GET] http://127.0.0.1:4723/wd/hub/session/2d2063db-a44c-4b49-8530-da40bcacd962/contexts
INFO webdriver: RESULT [ 'NATIVE_APP', 'WEBVIEW_com.example.webviewapps' ]
INFO webdriver: COMMAND switchContext("WEBVIEW_com.example.webviewapps")
INFO webdriver: [POST] http://127.0.0.1:4723/wd/hub/session/2d2063db-a44c-4b49-8530-da40bcacd962/context
INFO webdriver: DATA { name: 'WEBVIEW_com.example.webviewapps' }

getContexts の実行結果から、「NATIVE_APP, WEBVIEW_com....」のコンテキストが取得できています。
また、switchContext で対象の WebView を指定できていることが分かります。

 

Webページのタイトル取得

 command
INFO webdriver: COMMAND getTitle()
INFO webdriver: [GET] http://127.0.0.1:4723/wd/hub/session/2d2063db-a44c-4b49-8530-da40bcacd962/title
INFO webdriver: RESULT Appium: Mobile App Automation Made Awesome.

getTitle の実行結果から、「Appium: Mobile App ...」のタイトルが取得できています。
これは、ブラウザでアクセスした際にタブへ表示される内容と合致していますね。

 

Element の座標取得

 command
INFO webdriver: COMMAND findElement("css selector", "#downloadLink")
INFO webdriver: [POST] http://127.0.0.1:4723/wd/hub/session/2d2063db-a44c-4b49-8530-da40bcacd962/element
INFO webdriver: DATA { using: 'css selector', value: '#downloadLink' }
INFO webdriver: RESULT {
ELEMENT: 'e0458b00-7222-46a0-b26e-c65f9ca3b311',
'element-6066-11e4-a52e-4f735466cecf': 'e0458b00-7222-46a0-b26e-c65f9ca3b311'
}

先ずは、エレメントの取得です。
xpath で指定した downloadLink という ID のエレメント情報を取得出来ていることが分かります。

 

 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 }

エレメントの elementId を指定して、getElementRect が実行されています。
WebView 上でのポジション(x, y, width, height)が数値として返されています。

SANACHAN
以降は、rect.x, rect.y のようにして各メンバへアクセスすることができます。

 

トラブルシューティング

No chromedriver found

switchContext を実行した際に、「No chromedriver found.」というようなエラーが出る場合があります。
Proxy 環境下で Appium を実行しているなど、何かしらの理由で ChromeDriver のインストールに失敗しています。

以下の場所に「chromedriver_win32_vxx.x.xxxx.xx.exe」がない場合はこれに該当します。

 Appiumインストール場所
C:\Users\whoami\AppData\Local\Programs\Appium Server GUI\resources\
app\node_modules\appium\node_modules\appium-chromedriver\chromedriver\win

WebDriver for Chrome のページから、Android エミュレータ上で実行している Chrome バージョンに合った
ChromeDriver をダウンロードし、上記場所に配置すれば解消します。

SANACHAN
エミュレータで使用しているバージョンは、Appium のログに出ています。

 

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

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

SANACHAN

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

-便利ツール
-, ,