Home | History | Annotate | Download | only in tests
      1 /*
      2  * Copyright (C) 2012 Google Inc. All rights reserved.
      3  *
      4  * Redistribution and use in source and binary forms, with or without
      5  * modification, are permitted provided that the following conditions
      6  * are met:
      7  * 1.  Redistributions of source code must retain the above copyright
      8  *     notice, this list of conditions and the following disclaimer.
      9  * 2.  Redistributions in binary form must reproduce the above copyright
     10  *     notice, this list of conditions and the following disclaimer in the
     11  *     documentation and/or other materials provided with the distribution.
     12  *
     13  * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS'' AND ANY
     14  * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
     15  * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
     16  * DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY
     17  * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
     18  * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
     19  * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON
     20  * ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
     21  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
     22  * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
     23  */
     24 
     25 #include "config.h"
     26 
     27 #include "web/LinkHighlight.h"
     28 
     29 #include "bindings/v8/ExceptionStatePlaceholder.h"
     30 #include "core/dom/Node.h"
     31 #include "core/frame/FrameView.h"
     32 #include "core/page/TouchDisambiguation.h"
     33 #include "platform/geometry/IntRect.h"
     34 #include "public/platform/Platform.h"
     35 #include "public/platform/WebContentLayer.h"
     36 #include "public/platform/WebFloatPoint.h"
     37 #include "public/platform/WebSize.h"
     38 #include "public/platform/WebUnitTestSupport.h"
     39 #include "public/web/WebFrame.h"
     40 #include "public/web/WebFrameClient.h"
     41 #include "public/web/WebInputEvent.h"
     42 #include "public/web/WebViewClient.h"
     43 #include "web/WebInputEventConversion.h"
     44 #include "web/WebLocalFrameImpl.h"
     45 #include "web/WebViewImpl.h"
     46 #include "web/tests/FrameTestHelpers.h"
     47 #include "web/tests/URLTestHelpers.h"
     48 #include "wtf/PassOwnPtr.h"
     49 #include <gtest/gtest.h>
     50 
     51 
     52 using namespace blink;
     53 using namespace WebCore;
     54 
     55 namespace {
     56 
     57 TEST(LinkHighlightTest, verifyWebViewImplIntegration)
     58 {
     59     const std::string baseURL("http://www.test.com/");
     60     const std::string fileName("test_touch_link_highlight.html");
     61 
     62     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
     63     FrameTestHelpers::WebViewHelper webViewHelper;
     64     WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(baseURL + fileName, true);
     65     int pageWidth = 640;
     66     int pageHeight = 480;
     67     webViewImpl->resize(WebSize(pageWidth, pageHeight));
     68     webViewImpl->layout();
     69 
     70     WebGestureEvent touchEvent;
     71     touchEvent.type = WebInputEvent::GestureShowPress;
     72 
     73     // The coordinates below are linked to absolute positions in the referenced .html file.
     74     touchEvent.x = 20;
     75     touchEvent.y = 20;
     76 
     77     {
     78         PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
     79         Node* touchNode = webViewImpl->bestTapNode(platformEvent);
     80         ASSERT_TRUE(touchNode);
     81     }
     82 
     83     touchEvent.y = 40;
     84     {
     85         PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
     86         EXPECT_FALSE(webViewImpl->bestTapNode(platformEvent));
     87     }
     88 
     89     touchEvent.y = 20;
     90     // Shouldn't crash.
     91 
     92     {
     93         PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
     94         webViewImpl->enableTapHighlightAtPoint(platformEvent);
     95     }
     96 
     97     EXPECT_TRUE(webViewImpl->linkHighlight(0));
     98     EXPECT_TRUE(webViewImpl->linkHighlight(0)->contentLayer());
     99     EXPECT_TRUE(webViewImpl->linkHighlight(0)->clipLayer());
    100 
    101     // Find a target inside a scrollable div
    102 
    103     touchEvent.y = 100;
    104     {
    105         PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
    106         webViewImpl->enableTapHighlightAtPoint(platformEvent);
    107     }
    108 
    109     ASSERT_TRUE(webViewImpl->linkHighlight(0));
    110 
    111     // Don't highlight if no "hand cursor"
    112     touchEvent.y = 220; // An A-link with cross-hair cursor.
    113     {
    114         PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
    115         webViewImpl->enableTapHighlightAtPoint(platformEvent);
    116     }
    117     ASSERT_EQ(0U, webViewImpl->numLinkHighlights());
    118 
    119     touchEvent.y = 260; // A text input box.
    120     {
    121         PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
    122         webViewImpl->enableTapHighlightAtPoint(platformEvent);
    123     }
    124     ASSERT_EQ(0U, webViewImpl->numLinkHighlights());
    125 
    126     Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    127 }
    128 
    129 class FakeWebFrameClient : public WebFrameClient {
    130     // To make the destructor public.
    131 };
    132 
    133 class FakeCompositingWebViewClient : public FrameTestHelpers::TestWebViewClient {
    134 public:
    135     FakeWebFrameClient m_fakeWebFrameClient;
    136 };
    137 
    138 static WebViewClient* compositingWebViewClient()
    139 {
    140     DEFINE_STATIC_LOCAL(FakeCompositingWebViewClient, client, ());
    141     return &client;
    142 }
    143 
    144 TEST(LinkHighlightTest, resetDuringNodeRemoval)
    145 {
    146     const std::string baseURL("http://www.test.com/");
    147     const std::string fileName("test_touch_link_highlight.html");
    148 
    149     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
    150     FrameTestHelpers::WebViewHelper webViewHelper;
    151     WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(baseURL + fileName, true, 0, compositingWebViewClient());
    152 
    153     int pageWidth = 640;
    154     int pageHeight = 480;
    155     webViewImpl->resize(WebSize(pageWidth, pageHeight));
    156     webViewImpl->layout();
    157 
    158     WebGestureEvent touchEvent;
    159     touchEvent.type = WebInputEvent::GestureShowPress;
    160     touchEvent.x = 20;
    161     touchEvent.y = 20;
    162 
    163     PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
    164     Node* touchNode = webViewImpl->bestTapNode(platformEvent);
    165     ASSERT_TRUE(touchNode);
    166 
    167     webViewImpl->enableTapHighlightAtPoint(platformEvent);
    168     ASSERT_TRUE(webViewImpl->linkHighlight(0));
    169 
    170     GraphicsLayer* highlightLayer = webViewImpl->linkHighlight(0)->currentGraphicsLayerForTesting();
    171     ASSERT_TRUE(highlightLayer);
    172     EXPECT_TRUE(highlightLayer->linkHighlight(0));
    173 
    174     touchNode->remove(IGNORE_EXCEPTION);
    175     webViewImpl->layout();
    176     ASSERT_EQ(0U, highlightLayer->numLinkHighlights());
    177 
    178     Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    179 }
    180 
    181 TEST(LinkHighlightTest, multipleHighlights)
    182 {
    183     const std::string baseURL("http://www.test.com/");
    184     const std::string fileName("test_touch_link_highlight.html");
    185 
    186     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
    187     FrameTestHelpers::WebViewHelper webViewHelper;
    188     WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(baseURL + fileName, true, 0, compositingWebViewClient());
    189 
    190     int pageWidth = 640;
    191     int pageHeight = 480;
    192     webViewImpl->resize(WebSize(pageWidth, pageHeight));
    193     webViewImpl->layout();
    194 
    195     WebGestureEvent touchEvent;
    196     touchEvent.x = 50;
    197     touchEvent.y = 310;
    198     touchEvent.data.tap.width = 30;
    199     touchEvent.data.tap.height = 30;
    200 
    201     Vector<IntRect> goodTargets;
    202     WillBeHeapVector<RawPtrWillBeMember<Node> > highlightNodes;
    203     IntRect boundingBox(touchEvent.x - touchEvent.data.tap.width / 2, touchEvent.y - touchEvent.data.tap.height / 2, touchEvent.data.tap.width, touchEvent.data.tap.height);
    204     findGoodTouchTargets(boundingBox, webViewImpl->mainFrameImpl()->frame(), goodTargets, highlightNodes);
    205 
    206     webViewImpl->enableTapHighlights(highlightNodes);
    207     EXPECT_EQ(2U, webViewImpl->numLinkHighlights());
    208 
    209     Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    210 }
    211 
    212 } // namespace
    213