WebView の操作
重要
Visual Studio App Center は、2025 年 3 月 31 日に廃止される予定です。 完全に廃止されるまで Visual Studio App Center を引き続き使用できますが、移行を検討できる推奨される代替手段がいくつかあります。
Xamarin.UITest には、ネイティブ モバイル アプリケーションのビューを検索して操作するための API が用意されています。 ただし、一部のモバイル アプリは、Web ビューを使用して HTML をユーザーに表示するハイブリッド アプリです。 Android では が android.webkit.WebView
提供されますが、iOS アプリケーションでは UIWebView または WKWebView を使用できます。 UIWebView は古く、すべてのバージョンの iOS と互換性があり、WKWebView は iOS 8 以降用です。
UITest は最初に Web ビューへの参照を取得し、次に含まれる DOM 要素への参照を取得する必要があるため、Web ビューの操作はもう少し複雑になります。
UITest の WebView API
UITest で Web ビュー コントロールへの参照を取得するには、次の 2 つの API があります。
- AppQuery.WebView はコントロールに
UIWebView
使用されます。 - AppQuery.Class はコントロールに
WKWebView
使用されます。
これらのそれぞれについて、以下で詳しく説明します。
AppQuery.WebView を使用した UIWebView
コントロールの検索
UITest には、コントロールへの参照を取得するための AppQuery.WebView メソッドが UIWebView
用意されています。 次のスニペットは例です。
>>> app.Query(c=>c.WebView())
画面上に Web ビューが 1 つしかない場合、 WebView
既定ではその 1 つの Web ビューになります。 画面上に複数の Web ビューがある場合は、 を使用して、 WebView(Int32)
0 から始まるインデックスを渡すことによって 1 つを分離できます。
コントロールの WKWebView
検索
UITest には、コントロールへの参照を取得するための AppQuery.Class メソッドが WKWebView
用意されています。 次のスニペットは例です。
>>> app.Query(c=>c.Class("WKWebView"))
Web ビュー コントロールでの DOM 要素の操作
Web ビューが分離されると、DOM 要素と対話するための 2 つのメイン API があります。
- CSS – この API では、CSS セレクターを使用して、Web ビューによって表示される DOM 要素を検索します。
- XPath – UITest では、XPath 式を使用して Web ビュー内の DOM 要素を検索できます。
XPath API は、より強力ですが、使用もより複雑になります。 一般に、CSS API と、必要に応じて使用される XPath API を優先する必要があります。
CSS
AppQuery.Css メソッドを使用して HTML 要素を照合できます。 このメソッドは CSS セレクターを受け取り、一致するすべての HTML 要素の配列を返します。 機能的には、この API は Android と iOS でも同じです。
たとえば、次の Android アクティビティには が android.webkit.WebView
含まれています。
このスニペットは、Web ビュー内のすべての H1 DOM 要素を検索する方法を示しています。
>>> app.Query(c=>c.Css("H1"))
Query for Css("H1") gave 1 results.
[
[0] {
Id => "",
NodeType => "ELEMENT_NODE",
NodeName => "H1",
Class => "",
Html => "<h1>H1 Header!</h1>",
Value => null,
WebView => "webView1",
TextContent => "H1 Header!",
Rect => {
Width => 1032,
Height => 117,
CenterX => 540,
CenterY => 408,
Top => 44,
Bottom => 83,
Left => 8,
Right => 352,
X => 24,
Y => 351
}
}
]
特定の画面に複数の Web ビューがある場合、UITest は自動的に最初の Web ビューに既定で設定されます。 複数の Web ビューがある場合は、 を使用して IApp.WebView(Int32)
Web ビューを明示的に識別する必要があります。 たとえば、画面に 2 つの Web ビューがあり、2 つ目の Web ビューですべての H1 要素を検索する場合は、次のようになります。
>>> app.Query(c=>c.WebView(1).Css("H1"))
Query for WebView().Css("H1") gave 1 results.
[
[0] {
Id => "",
NodeType => "ELEMENT_NODE",
NodeName => "H1",
Class => "",
Html => "<h1>H1 Header!</h1>",
Value => null,
WebView => "webView1",
TextContent => "H1 Header!",
Rect => {
Width => 1032,
Height => 117,
CenterX => 540,
CenterY => 408,
Top => 44,
Bottom => 83,
Left => 8,
Right => 352,
X => 24,
Y => 351
}
}
]
複数の HTML 要素が CSS クエリと一致する場合は、 メソッドを Index
使用して結果セット内の個々の要素にアクセスできます。 たとえば、次のスニペットは、 スタイルを使用して HTML 要素の 3 番目の要素にアクセスする方法を .user
示しています。
>>> app.Tap(c => c.Css(".user").Index(2));
XPath
XPath は DOM を検索するための強力な API ですが、CSS API と比較して使用が少し難しい場合があります。 UITest は、 AppQuery.XPath メソッドに渡される XPath セレクターによって DOM 要素を検索できます。 この API は、Android と iOS でも同じです。
次のスニペットは、XPath を使用して前のセクションの H1 DOM 要素を照合する方法の例です。
>>> app.Query(c=>c.XPath("//h1"))
Query for XPath("//h1") gave 1 results.
[
[0] {
Id => "",
NodeType => "ELEMENT_NODE",
NodeName => "H1",
Class => "",
Html => "<h1>H1 Header!</h1>",
Value => null,
WebView => "webView1",
TextContent => "H1 Header!",
Rect => {
Width => 1032,
Height => 117,
CenterX => 540,
CenterY => 408,
Top => 44,
Bottom => 83,
Left => 8,
Right => 352,
X => 24,
Y => 351
}
}
]
JavaScript の呼び出し
メソッドを使用して AppQuery.InvokeJS
Web ビューを検索することもできます。 このメソッドは、文字列の形式でクエリを受け取り、クエリに一致するビュー要素に対して JavaScript を呼び出します。 WebViews 以外のビュー要素が見つかった場合、実行は停止し、例外がスローされます。
Android での InvokeJS
一般に Android では、JavaScript returns
の値が必要です。それ以外の場合、クエリは を返します null
。
>>> app.Query (w => w.WebView ().InvokeJS ("document.getElementById('lastname').value"))
[
[0] "null"
]
>>> app.Query (w => w.WebView ().InvokeJS ("return document.getElementById('lastname').value"))
[
[0] "Smith"
]
iOS での InvokeJS
一般に、iOS では、 return
は使用されません。
>>> app.Query (w => w.WebView ().InvokeJS ("return document.getElementById('lastname').value"))
[
[0] ""
]
>>> app.Query (w => w.WebView ().InvokeJS("document.getElementById('lastname').value"))
[
[0] "Smith"
]
例
このセクションでは、Web ビューを含む Calabash テストを記述するときに見つかる一般的なユース ケースについて説明します。
スクロール
Web ビューをスクロールして DOM 要素を画面に表示することができます。 これは、 メソッドまたは IApp.ScrollUpTo
メソッドをIApp.ScrollDownTo
使用して行います。 これらのメソッドのシグネチャは次のようになります。
IApp.ScrollDownTo(Func<AppQuery, AppWebQuery> toQuery,
string withinMarked,
ScrollStrategy strategy,
Nullable<TimeSpan> timeout)
パラメーターの簡単な説明を次に示します。
toQuery
- これは、Web ビューで DOM 要素を検索する UITest Web クエリです。withinMarked
- これは、Web ビューを画面上に配置する文字列です。 画面上に Web ビューが 1 つしかない場合、このパラメーターは省略可能です。 この文字列は、 によってIApp.Marked
使用され、画面上で Web ビューを検索します。strategy
- この省略可能なパラメーターは、Web ビュー内をスクロールする方法を UITest に指示します。ScrollStrategy.Gesture
は、ユーザーが画面をドラッグしてスクロールする方法をエミュレートしようとします。ScrollStrategy.Programatic
は UITest を解放して、可能な限り迅速にスクロールします。ScrollStrategy.Auto
は、 とProgramatic
の任意のGesture
組み合わせを使用してスクロールするように UITest にProgramatic
指示します (基本設定は )。timeout
- UITest がクエリをタイムアウトするまで待機する時間を指定する省略可能なパラメーター。
これらの API を使用する例として、Android アプリケーションに埋め込まれた Webview のスクリーンショットを考えてみましょう。
REPL でこのアクティビティのビュー階層を調べると、次のことがわかります。
>>> tree
[[object CalabashRootView] > PhoneWindow$DecorView]
[ActionBarOverlayLayout] id: "decor_content_parent"
[FrameLayout > LinearLayout] id: "content"
[WebView] id: "webView1", label: "WebView"
[dom] id: "show_secret"
[dom] id: "firstname"
[dom] id: "lastname"
[ActionBarContainer] id: "action_bar_container"
[Toolbar] id: "action_bar"
[TextView] text: "TestingWebviews.Droid"
[View] id: "statusBarBackground"
[View] id: "navigationBarBackground"
コマンドからの出力は、 tree
Web ビューに ID webView1
があり、次の 3 つの DOM 要素が含まれていることを示します。
- マークアップで 呼び出される
show_secret
HTML ボタン<button id="show_secret">Toggle the Secret</button>
- マークアップを含む HTML 入力フィールド
firstname
<input type="text" name="firstname" id='firstname'>
- マークアップを含む HTML 入力フィールド
lastname
<input type="text" name="lastname" id='lastname'>
ボタンはshow_secret
画面に表示されますがfirstname
lastname
、表示されません。 UITest がこれらの DOM 要素と対話する前に、スクロール API を使用してこれらのフィールドを表示する必要があります。 REPL の次のスニペットは、API を使用して HTML 入力要素をビューにスクロールする方法を ScrollDownTo
示しています。
>>> app.ScrollDownTo(c=>c.Css("#firstname"))
Scrolling down to Css("#firstname")
テキストの入力
HTML 入力要素にテキストを入力するには、テキストと AppWebQuery
using API を指定 AppQuery.EnterText
します。 Android アプリケーションの Web ビューの次のスクリーンショットが表示されます。
次のコード スニペットは、HTML 入力要素にテキストを firstname
入力するために表示されます。
[Test]
public void ScrollDownAndEnterName()
{
app.ScrollDownTo(c => c.Css("input#firstname"), );
app.EnterText(c => c.Css("input#firstname"), "Monkey");
// A more verbose way to enter text, explicitly identifying the webview and ScrollStrategy
app.ScrollDownTo(c => c.Css("input#lastname"), "webView1", ScrollStrategy.Gesture);
app.EnterText(c => c.Css("input#lastname"), "Chimpanzee");
}