wiki:Writing Layout Tests to test iOS UI features

Version 3 (modified by Simon Fraser, 7 years ago) (diff)

--

Summary

It's now possible to write layout tests that exercise code in the UI process in iOS WebKit2. This allows testing of things like tapping, zooming, keyboard interaction, selection, text input etc.

This is done by running JavaScript in an isolated JS context in the UI process form a test. That JavaScript has access to a UIScriptController, which has properties that expose information about the state of the UI process,. and functions to make things happen, including event synthesis.

The UI script itself runs asynchronously, and many of the UIScriptController functions are asynchronous. Callbacks are used to tell the test when something completes.

A simple example

Let's say we want to write a test that reads back the zoom scale of the WKWebView's UIScrollView (e.g. to test viewport scale).

First, since we're testing viewport zooming, we need to have the test opt into iOS-style viewport behavior with an HTML comment after the doctype:

<!DOCTYPE html> <!-- webkit-test-runner [ useFlexibleViewport=true ] -->

then let's put in the viewport settings to test:

<head>
    <meta name="viewport" content="initial-scale=1.0">
...

Now we want to write some script to read the zoom scale in the UI process. TestRunner now has a runUIScript() function, which takes a string and a callback:

interface TestRunner {
    ...
    // UI Process Testing
    void runUIScript(DOMString script, object callback);

so we can use this in our test in some script that would run from the onload handler:

function runTest()
{
    testRunner.waitUntilDone();
    if (testRunner.runUIScript) {
        testRunner.runUIScript("...", function(result) {
            document.getElementById('result').innerText = result;
            testRunner.notifyDone();
        });
    }
}

The script passed in to runUIScript() is just a string. You can pass a string literal here, or, for longer scripts make script tag:

<script id="ui-script" type="text/plain">
...
</script>

<script>
    function getUIScript()
    {
        return document.getElementById('ui-script').text;
    }

    testRunner.runUIScript(getUIScript(), function(result) {
        ...
    });