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 "LinkHighlight.h"
     28 
     29 #include <gtest/gtest.h>
     30 #include "FrameTestHelpers.h"
     31 #include "URLTestHelpers.h"
     32 #include "WebFrame.h"
     33 #include "WebFrameClient.h"
     34 #include "WebFrameImpl.h"
     35 #include "WebInputEvent.h"
     36 #include "WebInputEventConversion.h"
     37 #include "WebViewClient.h"
     38 #include "WebViewImpl.h"
     39 #include "bindings/v8/ExceptionStatePlaceholder.h"
     40 #include "core/dom/Node.h"
     41 #include "core/frame/FrameView.h"
     42 #include "core/page/TouchDisambiguation.h"
     43 #include "platform/geometry/IntRect.h"
     44 #include "public/platform/Platform.h"
     45 #include "public/platform/WebContentLayer.h"
     46 #include "public/platform/WebFloatPoint.h"
     47 #include "public/platform/WebSize.h"
     48 #include "public/platform/WebUnitTestSupport.h"
     49 #include "wtf/PassOwnPtr.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 WebViewClient {
    134 public:
    135     virtual ~FakeCompositingWebViewClient()
    136     {
    137     }
    138 
    139     virtual void initializeLayerTreeView() OVERRIDE
    140     {
    141         m_layerTreeView = adoptPtr(Platform::current()->unitTestSupport()->createLayerTreeViewForTesting(WebUnitTestSupport::TestViewTypeUnitTest));
    142         ASSERT(m_layerTreeView);
    143     }
    144 
    145     virtual WebLayerTreeView* layerTreeView() OVERRIDE
    146     {
    147         return m_layerTreeView.get();
    148     }
    149 
    150     FakeWebFrameClient m_fakeWebFrameClient;
    151 
    152 private:
    153     OwnPtr<WebLayerTreeView> m_layerTreeView;
    154 };
    155 
    156 static WebViewClient* compositingWebViewClient()
    157 {
    158     DEFINE_STATIC_LOCAL(FakeCompositingWebViewClient, client, ());
    159     return &client;
    160 }
    161 
    162 TEST(LinkHighlightTest, resetDuringNodeRemoval)
    163 {
    164     const std::string baseURL("http://www.test.com/");
    165     const std::string fileName("test_touch_link_highlight.html");
    166 
    167     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
    168     FrameTestHelpers::WebViewHelper webViewHelper;
    169     WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(baseURL + fileName, true, 0, compositingWebViewClient());
    170 
    171     int pageWidth = 640;
    172     int pageHeight = 480;
    173     webViewImpl->resize(WebSize(pageWidth, pageHeight));
    174     webViewImpl->layout();
    175 
    176     WebGestureEvent touchEvent;
    177     touchEvent.type = WebInputEvent::GestureShowPress;
    178     touchEvent.x = 20;
    179     touchEvent.y = 20;
    180 
    181     PlatformGestureEventBuilder platformEvent(webViewImpl->mainFrameImpl()->frameView(), touchEvent);
    182     Node* touchNode = webViewImpl->bestTapNode(platformEvent);
    183     ASSERT_TRUE(touchNode);
    184 
    185     webViewImpl->enableTapHighlightAtPoint(platformEvent);
    186     ASSERT_TRUE(webViewImpl->linkHighlight(0));
    187 
    188     GraphicsLayer* highlightLayer = webViewImpl->linkHighlight(0)->currentGraphicsLayerForTesting();
    189     ASSERT_TRUE(highlightLayer);
    190     EXPECT_TRUE(highlightLayer->linkHighlight(0));
    191 
    192     touchNode->remove(IGNORE_EXCEPTION);
    193     webViewImpl->layout();
    194     ASSERT_EQ(0U, highlightLayer->numLinkHighlights());
    195 
    196     Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    197 }
    198 
    199 TEST(LinkHighlightTest, multipleHighlights)
    200 {
    201     const std::string baseURL("http://www.test.com/");
    202     const std::string fileName("test_touch_link_highlight.html");
    203 
    204     URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(baseURL.c_str()), WebString::fromUTF8("test_touch_link_highlight.html"));
    205     FrameTestHelpers::WebViewHelper webViewHelper;
    206     WebViewImpl* webViewImpl = webViewHelper.initializeAndLoad(baseURL + fileName, true, 0, compositingWebViewClient());
    207 
    208     int pageWidth = 640;
    209     int pageHeight = 480;
    210     webViewImpl->resize(WebSize(pageWidth, pageHeight));
    211     webViewImpl->layout();
    212 
    213     WebGestureEvent touchEvent;
    214     touchEvent.x = 50;
    215     touchEvent.y = 310;
    216     touchEvent.data.tap.width = 30;
    217     touchEvent.data.tap.height = 30;
    218 
    219     Vector<IntRect> goodTargets;
    220     Vector<Node*> highlightNodes;
    221     IntRect boundingBox(touchEvent.x - touchEvent.data.tap.width / 2, touchEvent.y - touchEvent.data.tap.height / 2, touchEvent.data.tap.width, touchEvent.data.tap.height);
    222     findGoodTouchTargets(boundingBox, webViewImpl->mainFrameImpl()->frame(), goodTargets, highlightNodes);
    223 
    224     webViewImpl->enableTapHighlights(highlightNodes);
    225     EXPECT_EQ(2U, webViewImpl->numLinkHighlights());
    226 
    227     Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
    228 }
    229 
    230 } // namespace
    231