EMMA Coverage Report (generated Tue Aug 20 10:07:21 PDT 2013)
[all classes][org.chromium.android_webview.test]

COVERAGE SUMMARY FOR SOURCE FILE [WebKitHitTestTest.java]

nameclass, %method, %block, %line, %
WebKitHitTestTest.java100% (6/6)98%  (52/53)93%  (754/813)92%  (160/173)

COVERAGE BREAKDOWN BY CLASS AND METHOD

nameclass, %method, %block, %line, %
     
class WebKitHitTestTest100% (1/1)98%  (42/43)90%  (547/606)92%  (146/159)
testUnfocusedNodeAndTouchRace (): void 0%   (0/1)0%   (0/59)0%   (0/13)
<static initializer> 100% (1/1)100% (5/5)100% (2/2)
WebKitHitTestTest (): void 100% (1/1)100% (3/3)100% (1/1)
access$000 (WebKitHitTestTest): AwTestContainerView 100% (1/1)100% (3/3)100% (1/1)
access$100 (WebKitHitTestTest): AwContents 100% (1/1)100% (3/3)100% (1/1)
blankHrefTestBody (boolean): void 100% (1/1)100% (27/27)100% (7/7)
editTextTypeTestBody (boolean): void 100% (1/1)100% (22/22)100% (6/6)
fullPageLink (String, String): String 100% (1/1)100% (19/19)100% (1/1)
pollForHitTestDataOnUiThread (int, String): boolean 100% (1/1)100% (9/9)100% (1/1)
pollForHrefAndImageSrcOnUiThread (String, String, String): boolean 100% (1/1)100% (10/10)100% (1/1)
setServerResponseAndLoad (String): void 100% (1/1)100% (16/16)100% (3/3)
setUp (): void 100% (1/1)100% (25/25)100% (6/6)
simulateInput (boolean): void 100% (1/1)100% (8/8)100% (4/4)
simulateTabDownUpOnUiThread (): void 100% (1/1)100% (7/7)100% (2/2)
simulateTouchCenterOfWebViewOnUiThread (): void 100% (1/1)100% (7/7)100% (2/2)
srcAnchorTypeRelativeUrlTestBody (boolean): void 100% (1/1)100% (29/29)100% (8/8)
srcAnchorTypeTestBody (boolean): void 100% (1/1)100% (22/22)100% (6/6)
srcEmailTypeTestBody (boolean): void 100% (1/1)100% (40/40)100% (8/8)
srcGeoTypeTestBody (boolean): void 100% (1/1)100% (40/40)100% (8/8)
srcImgeAnchorTypeTestBody (boolean): void 100% (1/1)100% (42/42)100% (8/8)
srcPhoneTypeTestBody (boolean): void 100% (1/1)100% (42/42)100% (9/9)
tearDown (): void 100% (1/1)100% (9/9)100% (4/4)
testEditTextType (): void 100% (1/1)100% (4/4)100% (2/2)
testEditTextTypeByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testImgeType (): void 100% (1/1)100% (37/37)100% (8/8)
testSrcAnchorType (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcAnchorTypeBlankHref (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcAnchorTypeBlankHrefByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcAnchorTypeByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcAnchorTypeRelativeUrl (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcAnchorTypeRelativeUrlByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcEmailType (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcEmailTypeByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcGeoType (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcGeoTypeByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcImgeAnchorType (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcImgeAnchorTypeByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcPhoneType (): void 100% (1/1)100% (4/4)100% (2/2)
testSrcPhoneTypeByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testUnknownTypeJavascriptScheme (): void 100% (1/1)100% (4/4)100% (2/2)
testUnknownTypeJavascriptSchemeByFocus (): void 100% (1/1)100% (4/4)100% (2/2)
testUnknownTypeUnrecognizedNode (): void 100% (1/1)100% (26/26)100% (8/8)
unknownTypeJavascriptSchemeTestBody (boolean): void 100% (1/1)100% (24/24)100% (7/7)
     
class WebKitHitTestTest$1100% (1/1)100% (2/2)100% (59/59)100% (7/7)
WebKitHitTestTest$1 (WebKitHitTestTest): void 100% (1/1)100% (6/6)100% (1/1)
run (): void 100% (1/1)100% (53/53)100% (6/6)
     
class WebKitHitTestTest$2100% (1/1)100% (2/2)100% (29/29)100% (4/4)
WebKitHitTestTest$2 (WebKitHitTestTest): void 100% (1/1)100% (6/6)100% (1/1)
run (): void 100% (1/1)100% (23/23)100% (3/3)
     
class WebKitHitTestTest$3100% (1/1)100% (2/2)100% (40/40)100% (3/3)
WebKitHitTestTest$3 (WebKitHitTestTest, int, String): void 100% (1/1)100% (12/12)100% (1/1)
call (): Boolean 100% (1/1)100% (28/28)100% (2/2)
     
class WebKitHitTestTest$4100% (1/1)100% (2/2)100% (64/64)100% (3/3)
WebKitHitTestTest$4 (WebKitHitTestTest, String, String, String): void 100% (1/1)100% (15/15)100% (1/1)
call (): Boolean 100% (1/1)100% (49/49)100% (2/2)
     
class WebKitHitTestTest$5100% (1/1)100% (2/2)100% (15/15)100% (2/2)
WebKitHitTestTest$5 (WebKitHitTestTest): void 100% (1/1)100% (6/6)100% (1/1)
call (): Boolean 100% (1/1)100% (9/9)100% (1/1)

1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4 
5package org.chromium.android_webview.test;
6 
7import android.content.res.Configuration;
8import android.os.SystemClock;
9import android.test.FlakyTest;
10import android.test.suitebuilder.annotation.LargeTest;
11import android.test.suitebuilder.annotation.SmallTest;
12import android.view.KeyEvent;
13import android.view.MotionEvent;
14import android.webkit.WebView.HitTestResult;
15 
16import org.chromium.android_webview.AwContents;
17import org.chromium.base.test.util.Feature;
18import org.chromium.android_webview.test.util.CommonResources;
19import org.chromium.net.test.util.TestWebServer;
20 
21import java.util.concurrent.Callable;
22 
23public class WebKitHitTestTest extends AwTestBase {
24    private TestAwContentsClient mContentsClient;
25    private AwTestContainerView mTestView;
26    private AwContents mAwContents;
27    private TestWebServer mWebServer;
28 
29    private static String HREF = "http://foo/";
30    private static String ANCHOR_TEXT = "anchor text";
31 
32    @Override
33    public void setUp() throws Exception {
34        super.setUp();
35        mContentsClient = new TestAwContentsClient();
36        mTestView = createAwTestContainerViewOnMainSync(mContentsClient);
37        mAwContents = mTestView.getAwContents();
38        mWebServer = new TestWebServer(false);
39    }
40 
41    @Override
42    public void tearDown() throws Exception {
43        if (mWebServer != null) {
44            mWebServer.shutdown();
45        }
46        super.tearDown();
47    }
48 
49    private void setServerResponseAndLoad(String response) throws Throwable {
50        String url = mWebServer.setResponse("/hittest.html", response, null);
51        loadUrlSync(mAwContents,
52                    mContentsClient.getOnPageFinishedHelper(),
53                    url);
54    }
55 
56    private static String fullPageLink(String href, String anchorText) {
57        return CommonResources.makeHtmlPageFrom("", "<a class=\"full_view\" href=\"" +
58                href + "\" " + "onclick=\"return false;\">" + anchorText + "</a>");
59    }
60 
61    private void simulateTouchCenterOfWebViewOnUiThread() throws Throwable {
62        runTestOnUiThread(new Runnable() {
63            @Override
64            public void run() {
65                long eventTime = SystemClock.uptimeMillis();
66                float x = (float)(mTestView.getRight() - mTestView.getLeft()) / 2;
67                float y = (float)(mTestView.getBottom() - mTestView.getTop()) / 2;
68                mAwContents.onTouchEvent(MotionEvent.obtain(
69                        eventTime, eventTime, MotionEvent.ACTION_DOWN,
70                        x, y, 0));
71                mAwContents.onTouchEvent(MotionEvent.obtain(
72                        eventTime, eventTime, MotionEvent.ACTION_UP,
73                        x, y, 0));
74            }
75        });
76    }
77 
78    private void simulateTabDownUpOnUiThread() throws Throwable {
79        runTestOnUiThread(new Runnable() {
80            @Override
81            public void run() {
82                mAwContents.getContentViewCore().dispatchKeyEvent(
83                        new KeyEvent(KeyEvent.ACTION_DOWN, KeyEvent.KEYCODE_TAB));
84                mAwContents.getContentViewCore().dispatchKeyEvent(
85                        new KeyEvent(KeyEvent.ACTION_UP, KeyEvent.KEYCODE_TAB));
86            }
87        });
88    }
89 
90    private void simulateInput(boolean byTouch) throws Throwable {
91        // Send a touch click event if byTouch is true. Otherwise, send a TAB
92        // key event to change the focused element of the page.
93        if (byTouch) {
94            simulateTouchCenterOfWebViewOnUiThread();
95        } else {
96            simulateTabDownUpOnUiThread();
97        }
98    }
99 
100    private boolean pollForHitTestDataOnUiThread(
101            final int type, final String extra) throws Throwable {
102        return pollOnUiThread(new Callable<Boolean>() {
103            @Override
104            public Boolean call() {
105                AwContents.HitTestData data = mAwContents.getLastHitTestResult();
106                return type == data.hitTestResultType &&
107                       (extra == null ? data.hitTestResultExtraData == null :
108                       extra.equals(data.hitTestResultExtraData));
109            }
110        });
111    }
112 
113    private boolean pollForHrefAndImageSrcOnUiThread(
114            final String href,
115            final String anchorText,
116            final String imageSrc) throws Throwable {
117        return pollOnUiThread(new Callable<Boolean>() {
118            @Override
119            public Boolean call() {
120                AwContents.HitTestData data = mAwContents.getLastHitTestResult();
121                return (href == null ? data.href == null :
122                        href.equals(data.href)) &&
123                       (anchorText == null ? data.anchorText == null :
124                        anchorText.equals(data.anchorText)) &&
125                       (imageSrc == null ? data.imgSrc == null :
126                        imageSrc.equals(data.imgSrc));
127            }
128        });
129    }
130 
131    private void srcAnchorTypeTestBody(boolean byTouch) throws Throwable {
132        String page = fullPageLink(HREF, ANCHOR_TEXT);
133        setServerResponseAndLoad(page);
134        simulateInput(byTouch);
135        assertTrue(pollForHitTestDataOnUiThread(HitTestResult.SRC_ANCHOR_TYPE, HREF));
136        assertTrue(pollForHrefAndImageSrcOnUiThread(HREF, ANCHOR_TEXT, null));
137    }
138 
139    @SmallTest
140    @Feature({"AndroidWebView", "WebKitHitTest"})
141    public void testSrcAnchorType() throws Throwable {
142        srcAnchorTypeTestBody(true);
143    }
144 
145    @SmallTest
146    @Feature({"AndroidWebView", "WebKitHitTest"})
147    public void testSrcAnchorTypeByFocus() throws Throwable {
148        srcAnchorTypeTestBody(false);
149    }
150 
151    private void blankHrefTestBody(boolean byTouch) throws Throwable {
152        String fullpath = mWebServer.getResponseUrl("/hittest.html");
153        String page = fullPageLink("", ANCHOR_TEXT);
154        setServerResponseAndLoad(page);
155        simulateInput(byTouch);
156        assertTrue(pollForHitTestDataOnUiThread(
157                HitTestResult.SRC_ANCHOR_TYPE, fullpath));
158        assertTrue(pollForHrefAndImageSrcOnUiThread(null, ANCHOR_TEXT, null));
159    }
160 
161    @SmallTest
162    @Feature({"AndroidWebView", "WebKitHitTest"})
163    public void testSrcAnchorTypeBlankHref() throws Throwable {
164        blankHrefTestBody(true);
165    }
166 
167    @SmallTest
168    @Feature({"AndroidWebView", "WebKitHitTest"})
169    public void testSrcAnchorTypeBlankHrefByFocus() throws Throwable {
170        blankHrefTestBody(false);
171    }
172 
173    private void srcAnchorTypeRelativeUrlTestBody(boolean byTouch) throws Throwable {
174        String relpath = "/foo.html";
175        String fullpath = mWebServer.getResponseUrl(relpath);
176        String page = fullPageLink(relpath, ANCHOR_TEXT);
177        setServerResponseAndLoad(page);
178        simulateInput(byTouch);
179        assertTrue(pollForHitTestDataOnUiThread(
180                HitTestResult.SRC_ANCHOR_TYPE, fullpath));
181        assertTrue(pollForHrefAndImageSrcOnUiThread(relpath, ANCHOR_TEXT, null));
182    }
183 
184    @SmallTest
185    @Feature({"AndroidWebView", "WebKitHitTest"})
186    public void testSrcAnchorTypeRelativeUrl() throws Throwable {
187        srcAnchorTypeRelativeUrlTestBody(true);
188    }
189 
190    @SmallTest
191    @Feature({"AndroidWebView", "WebKitHitTest"})
192    public void testSrcAnchorTypeRelativeUrlByFocus() throws Throwable {
193        srcAnchorTypeRelativeUrlTestBody(false);
194    }
195 
196    private void srcEmailTypeTestBody(boolean byTouch) throws Throwable {
197        String email = "foo@bar.com";
198        String prefix = "mailto:";
199        String page = fullPageLink(prefix + email, ANCHOR_TEXT);
200        setServerResponseAndLoad(page);
201        simulateInput(byTouch);
202        assertTrue(pollForHitTestDataOnUiThread(HitTestResult.EMAIL_TYPE, email));
203        assertTrue(pollForHrefAndImageSrcOnUiThread(prefix+ email, ANCHOR_TEXT, null));
204    }
205 
206    @SmallTest
207    @Feature({"AndroidWebView", "WebKitHitTest"})
208    public void testSrcEmailType() throws Throwable {
209        srcEmailTypeTestBody(true);
210    }
211 
212    @SmallTest
213    @Feature({"AndroidWebView", "WebKitHitTest"})
214    public void testSrcEmailTypeByFocus() throws Throwable {
215        srcEmailTypeTestBody(false);
216    }
217 
218    private void srcGeoTypeTestBody(boolean byTouch) throws Throwable {
219        String location = "Jilin";
220        String prefix = "geo:0,0?q=";
221        String page = fullPageLink(prefix + location, ANCHOR_TEXT);
222        setServerResponseAndLoad(page);
223        simulateInput(byTouch);
224        assertTrue(pollForHitTestDataOnUiThread(HitTestResult.GEO_TYPE, location));
225        assertTrue(pollForHrefAndImageSrcOnUiThread(prefix + location, ANCHOR_TEXT, null));
226    }
227 
228    @SmallTest
229    @Feature({"AndroidWebView", "WebKitHitTest"})
230    public void testSrcGeoType() throws Throwable {
231        srcGeoTypeTestBody(true);
232    }
233 
234    @SmallTest
235    @Feature({"AndroidWebView", "WebKitHitTest"})
236    public void testSrcGeoTypeByFocus() throws Throwable {
237        srcGeoTypeTestBody(false);
238    }
239 
240    private void srcPhoneTypeTestBody(boolean byTouch) throws Throwable {
241        String phone_num = "%2B1234567890";
242        String expected_phone_num = "+1234567890";
243        String prefix = "tel:";
244        String page = fullPageLink("tel:" + phone_num, ANCHOR_TEXT);
245        setServerResponseAndLoad(page);
246        simulateInput(byTouch);
247        assertTrue(pollForHitTestDataOnUiThread(HitTestResult.PHONE_TYPE, expected_phone_num));
248        assertTrue(pollForHrefAndImageSrcOnUiThread(prefix + phone_num, ANCHOR_TEXT, null));
249    }
250 
251    @SmallTest
252    @Feature({"AndroidWebView", "WebKitHitTest"})
253    public void testSrcPhoneType() throws Throwable {
254        srcPhoneTypeTestBody(true);
255    }
256 
257    @SmallTest
258    @Feature({"AndroidWebView", "WebKitHitTest"})
259    public void testSrcPhoneTypeByFocus() throws Throwable {
260        srcPhoneTypeTestBody(false);
261    }
262 
263    private void srcImgeAnchorTypeTestBody(boolean byTouch) throws Throwable {
264        String relImageSrc = "/nonexistent.jpg";
265        String fullImageSrc = mWebServer.getResponseUrl(relImageSrc);
266        String page = CommonResources.makeHtmlPageFrom("", "<a class=\"full_view\" href=\"" +
267                HREF + "\"onclick=\"return false;\"><img class=\"full_view\" src=\"" +
268                relImageSrc + "\"></a>");
269        setServerResponseAndLoad(page);
270        simulateInput(byTouch);
271        assertTrue(pollForHitTestDataOnUiThread(
272                HitTestResult.SRC_IMAGE_ANCHOR_TYPE, fullImageSrc));
273        assertTrue(pollForHrefAndImageSrcOnUiThread(HREF, null, fullImageSrc));
274    }
275 
276    @SmallTest
277    @Feature({"AndroidWebView", "WebKitHitTest"})
278    public void testSrcImgeAnchorType() throws Throwable {
279        srcImgeAnchorTypeTestBody(true);
280    }
281 
282    @SmallTest
283    @Feature({"AndroidWebView", "WebKitHitTest"})
284    public void testSrcImgeAnchorTypeByFocus() throws Throwable {
285        srcImgeAnchorTypeTestBody(false);
286    }
287 
288    @SmallTest
289    @Feature({"AndroidWebView", "WebKitHitTest"})
290    public void testImgeType() throws Throwable {
291        String relImageSrc = "/nonexistent2.jpg";
292        String fullImageSrc = mWebServer.getResponseUrl(relImageSrc);
293        String page = CommonResources.makeHtmlPageFrom("",
294                "<img class=\"full_view\" src=\"" + relImageSrc + "\">");
295        setServerResponseAndLoad(page);
296        simulateTouchCenterOfWebViewOnUiThread();
297        assertTrue(pollForHitTestDataOnUiThread(
298                HitTestResult.IMAGE_TYPE, fullImageSrc));
299        assertTrue(pollForHrefAndImageSrcOnUiThread(null, null, fullImageSrc));
300    }
301 
302    private void editTextTypeTestBody(boolean byTouch) throws Throwable {
303        String page = CommonResources.makeHtmlPageFrom("",
304                "<form><input class=\"full_view\" type=\"text\" name=\"test\"></form>");
305        setServerResponseAndLoad(page);
306        simulateInput(byTouch);
307        assertTrue(pollForHitTestDataOnUiThread(
308                HitTestResult.EDIT_TEXT_TYPE, null));
309        assertTrue(pollForHrefAndImageSrcOnUiThread(null, null, null));
310    }
311 
312    @SmallTest
313    @Feature({"AndroidWebView", "WebKitHitTest"})
314    public void testEditTextType() throws Throwable {
315        editTextTypeTestBody(true);
316    }
317 
318    @SmallTest
319    @Feature({"AndroidWebView", "WebKitHitTest"})
320    public void testEditTextTypeByFocus() throws Throwable {
321        editTextTypeTestBody(false);
322    }
323 
324    public void unknownTypeJavascriptSchemeTestBody(boolean byTouch) throws Throwable {
325        // Per documentation, javascript urls are special.
326        String javascript = "javascript:alert('foo');";
327        String page = fullPageLink(javascript, ANCHOR_TEXT);
328        setServerResponseAndLoad(page);
329        simulateInput(byTouch);
330        assertTrue(pollForHrefAndImageSrcOnUiThread(javascript, ANCHOR_TEXT, null));
331        assertTrue(pollForHitTestDataOnUiThread(HitTestResult.UNKNOWN_TYPE, null));
332    }
333 
334    @SmallTest
335    @Feature({"AndroidWebView", "WebKitHitTest"})
336    public void testUnknownTypeJavascriptScheme() throws Throwable {
337        unknownTypeJavascriptSchemeTestBody(true);
338    }
339 
340    @SmallTest
341    @Feature({"AndroidWebView", "WebKitHitTest"})
342    public void testUnknownTypeJavascriptSchemeByFocus() throws Throwable {
343        unknownTypeJavascriptSchemeTestBody(false);
344    }
345 
346    @SmallTest
347    @Feature({"AndroidWebView", "WebKitHitTest"})
348    public void testUnknownTypeUnrecognizedNode() throws Throwable {
349        // Since UNKNOWN_TYPE is the default, hit test another type first for
350        // this test to be valid.
351        testSrcAnchorType();
352 
353        final String title = "UNKNOWN_TYPE title";
354 
355        String page = CommonResources.makeHtmlPageFrom(
356                "<title>" + title + "</title>",
357                "<div class=\"full_view\">div text</div>");
358        setServerResponseAndLoad(page);
359 
360        // Wait for the new page to be loaded before trying hit test.
361        pollOnUiThread(new Callable<Boolean>() {
362            @Override
363            public Boolean call() {
364                return mAwContents.getContentViewCore().getTitle().equals(title);
365            }
366        });
367        simulateTouchCenterOfWebViewOnUiThread();
368        assertTrue(pollForHitTestDataOnUiThread(HitTestResult.UNKNOWN_TYPE, null));
369    }
370 
371    @LargeTest
372    @Feature({"AndroidWebView", "WebKitHitTest"})
373    public void testUnfocusedNodeAndTouchRace() throws Throwable {
374      // Test when the touch and focus paths racing with setting different
375      // results.
376 
377      String relImageSrc = "/nonexistent3.jpg";
378      String fullImageSrc = mWebServer.getResponseUrl(relImageSrc);
379      String html = CommonResources.makeHtmlPageFrom(
380          "<meta name=\"viewport\" content=\"width=device-width,height=device-height\" />" +
381          "<style type=\"text/css\">" +
382          ".full_width { width:100%; position:absolute; }" +
383          "</style>",
384          "<form><input class=\"full_width\" style=\"height:25%;\" " +
385          "type=\"text\" name=\"test\"></form>" +
386          "<img class=\"full_width\" style=\"height:50%;top:25%;\" " +
387          "src=\"" + relImageSrc + "\">");
388      setServerResponseAndLoad(html);
389 
390      // Focus on input element and check the hit test results.
391      simulateTabDownUpOnUiThread();
392      assertTrue(pollForHitTestDataOnUiThread(
393              HitTestResult.EDIT_TEXT_TYPE, null));
394      assertTrue(pollForHrefAndImageSrcOnUiThread(null, null, null));
395 
396      // Touch image. Now the focus based hit test path will try to null out
397      // the results and the touch based path will update with the result of
398      // the image.
399      simulateTouchCenterOfWebViewOnUiThread();
400 
401      // Make sure the result of image sticks.
402      for (int i = 0; i < 2; ++i) {
403        Thread.sleep(500);
404        assertTrue(pollForHitTestDataOnUiThread(
405                HitTestResult.IMAGE_TYPE, fullImageSrc));
406        assertTrue(pollForHrefAndImageSrcOnUiThread(null, null, fullImageSrc));
407      }
408    }
409}

[all classes][org.chromium.android_webview.test]
EMMA 2.0.5312 (C) Vladimir Roubtsov