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 コントロールの検索

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含まれています。

Android デバイス上の 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 のスクリーンショットを考えてみましょう。

次の例で使用されている 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画面に表示されますがfirstnamelastname、表示されません。 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 ビューの次のスクリーンショットが表示されます。

次の例で使用されている WebView を示すスクリーンショット

次のコード スニペットは、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");

}