In this article

Working with Web Views

In this article

Xamarin.UITest provides API's for locating and interaction with views in native mobile applications. However, some mobile apps are hybrid apps that use web views to display HTML to the user. Android provides the android.webkit.WebView, while iOS applications may use either UIWebView or WKWebView. UIWebView is older and compatible with all versions of iOS, while WKWebView is for iOS 8 and higher.

Interacting with web views is a bit more involved as UITest must first obtain a reference to the web view, and then to the DOM elements it contains.

Web View APIs in UITest

There are two APIs to obtain a reference to a webview control in UITest:

Locating the UIWebView control with AppQuery.WebView

UITest provides the AppQuery.WebView method to obtain a reference to a UIWebView control. The following snippet is an example:

>>> app.Query(c=>c.WebView())

If there is only one web view on the screen, then WebView will default to that one web view. If there are multiple web views on the screen, the WebView(Int32) can be used to isolate one by passing a zero-based index.

Locating the WKWebView control

UITest provides the AppQuery.Class method to obtain a reference to a WKWebView control. The following snippet is an example:

>>> app.Query(c=>c.Class("WKWebView"))

Interacting with DOM Elements in a web view control

Once the web view has been isolated, there are two main API's for interacting with DOM elements:

XPath – UITest can use XPath expressions to locate DOM elements in the web view.

The XPath API, which more powerful is also more complicated to use. In general, preference should be given to the CSS API, and the XPath API used when necessary.

CSS

It is possible to match HTML elements using the AppQuery.Css method. This method takes a CSS selector and will return an array of all HTML elements that match. Functionally, this API is the same on Android and iOS.

If there is more than one web view on a given screen, then UITest will automatically default to the first web view. If there are multiple web views, then it is necessary to explicitly identify the web view using IApp.WebView(Int32). For example, if a screen had two web views and we want to find all the H1 elements in the second web view:

If more than one HTML element matches the CSS query, the Index method can be used to access an individual element in the result set. For example, the following snippet shows how to access the third element of HTML elements with the .user style:

>>> app.Tap(c => c.Css(".user").Index(2));

XPath

XPath is a very powerful API for searching the DOM, but can be a bit more difficult to use compared to the CSS API. UITest can locate DOM elements by an XPath selector passed to the AppQuery.XPath method. This API is the same on Android and iOS.

The following snippet is an example of how to match the H1 DOM element from the previous section using XPath:

Invoking JavaScript

It is also possible to locate webviews using the AppQuery.InvokeJS method. This method takes a query in the form of, and invokes Javascript on the view elements matched by the query. If view elements other than WebViews are encountered, the execution will halt and an Exception will be thrown.

InvokeJS on Android

Generally speaking Android requires that the Javascript returns the value; otherwise the query will return null:

Examples

This section will cover some common use cases that may be encountered when writing Calabash tests involving web views.

Scrolling

It is possible to scroll within an web view to bring DOM elements on to the screen. This is accomplished using the IApp.ScrollDownTo or IApp.ScrollUpTo methods. The signature of these methods is very similar:

toQuery – this is a UITest web query that will locate a DOM element in the web view.

withinMarked – this is a string that will located the web view on the screen. This parameter is optional if there is only one web view on the screen. This string will used by IApp.Marked to locate the web view on the screen.

strategy – this optional parameter tells UITest how to scroll within the web view. ScrollStrategy.Gesture will try to emulate how a user would scroll, by dragging the screen. ScrollStrategy.Programatic frees up UITest to scroll in the quickest way possible. ScrollStrategy.Auto tells UITest to use any combination of Gesture and Programatic to scroll (with a preference to Programatic).

timeout – an optional parameter that specifies how long UITest should wait before timing out the query.

As a example of using these API's consider the screenshots of a web view embedded in an Android application:

If we examine the view hierarchy of this Activity in the REPL, we can see the following:

The output from the tree command tells us that the web view has an the ID webView1, and contains three DOM elements:

an HTML button called show_secret with the markup <button id="show_secret">Toggle the Secret</button>

an HTML input field firstname, with the markup <input type="text" name="firstname" id='firstname'>

an HTML input field lastname, with the markup <input type="text" name="lastname" id='lastname'>

The show_secret button is visible on the screen, but firstname and lastname are not. Before a UITest may interact with those DOM elements, it is necessary to use the scrolling API's to bring those fields into view. The following snippet from the REPL shows how to can scroll the HTML input elements into view using the ScrollDownTo API:

>>> app.ScrollDownTo(c=>c.Css("#firstname"))
Scrolling down to Css("#firstname")

Entering Text

To enter text into HTML input element is accomplished by providing an AppWebQuery and the text to enter using the AppQuery.EnterText API . Given the following screenshot of a web view in an Android application:

The following code snippet will show to enter text into the firstname HTML input element: