Home | History | Annotate | Download | only in tests
      1 #include "config.h"
      2 
      3 #include <gtest/gtest.h>
      4 #include "FrameTestHelpers.h"
      5 #include "RuntimeEnabledFeatures.h"
      6 #include "URLTestHelpers.h"
      7 #include "WebFrame.h"
      8 #include "WebFrameClient.h"
      9 #include "WebFrameImpl.h"
     10 #include "WebHistoryItem.h"
     11 #include "WebInputEvent.h"
     12 #include "WebScriptSource.h"
     13 #include "WebSettings.h"
     14 #include "WebView.h"
     15 #include "WebViewClient.h"
     16 #include "WebViewImpl.h"
     17 #include "core/page/FrameView.h"
     18 #include "core/rendering/RenderView.h"
     19 #include "public/platform/Platform.h"
     20 #include "public/platform/WebUnitTestSupport.h"
     21 
     22 using namespace WebCore;
     23 using namespace WebKit;
     24 
     25 namespace {
     26 
     27 class MockWebFrameClient : public WebFrameClient {
     28 };
     29 
     30 class ProgrammaticScrollTest : public testing::Test {
     31 public:
     32     ProgrammaticScrollTest()
     33         : m_baseURL("http://www.test.com/")
     34     {
     35     }
     36 
     37     virtual void SetUp()
     38     {
     39         RuntimeEnabledFeatures::setProgrammaticScrollNotificationsEnabled(true);
     40     }
     41 
     42     virtual void TearDown()
     43     {
     44         Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
     45     }
     46 
     47 protected:
     48 
     49     void registerMockedHttpURLLoad(const std::string& fileName)
     50     {
     51         URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
     52     }
     53 
     54     std::string m_baseURL;
     55     MockWebFrameClient m_mockWebFrameClient;
     56 };
     57 
     58 class TestProgrammaticScrollClient : public WebViewClient {
     59 public:
     60     TestProgrammaticScrollClient()
     61     {
     62         reset();
     63     }
     64     void reset()
     65     {
     66         m_eventReceived = false;
     67     }
     68     bool eventReceived() const { return m_eventReceived; }
     69 
     70     // WebWidgetClient:
     71     virtual void didProgrammaticallyScroll(const WebPoint&) OVERRIDE
     72     {
     73         m_eventReceived = true;
     74     }
     75 
     76 private:
     77     bool m_eventReceived;
     78 };
     79 
     80 TEST_F(ProgrammaticScrollTest, UserScroll)
     81 {
     82     registerMockedHttpURLLoad("short_scroll.html");
     83     TestProgrammaticScrollClient client;
     84 
     85     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "short_scroll.html", false, 0, &client);
     86     webView->resize(WebSize(1000, 1000));
     87     webView->layout();
     88 
     89     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView);
     90     EXPECT_FALSE(client.eventReceived());
     91 
     92     // Non zero page scale and scroll.
     93     webViewImpl->applyScrollAndScale(WebSize(9, 13), 2.0f);
     94     EXPECT_FALSE(client.eventReceived());
     95 
     96     webView->close();
     97 }
     98 
     99 TEST_F(ProgrammaticScrollTest, ProgrammaticScroll)
    100 {
    101     registerMockedHttpURLLoad("long_scroll.html");
    102     TestProgrammaticScrollClient client;
    103 
    104     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "long_scroll.html", true, 0, &client);
    105     webView->resize(WebSize(1000, 1000));
    106     webView->layout();
    107 
    108     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView);
    109     WebFrameImpl* frameImpl = webViewImpl->mainFrameImpl();
    110     FrameView* frameView = frameImpl->frameView();
    111 
    112     // Slow scroll path.
    113     frameView->setCanBlitOnScroll(false);
    114     EXPECT_FALSE(client.eventReceived());
    115     frameImpl->executeScript(WebScriptSource("window.scrollTo(0, 20);"));
    116     EXPECT_TRUE(client.eventReceived());
    117     client.reset();
    118     frameImpl->executeScript(WebScriptSource("window.scrollBy(0, 0);"));
    119     EXPECT_FALSE(client.eventReceived());
    120     client.reset();
    121 
    122     // Fast scroll path.
    123     frameImpl->frameView()->setCanBlitOnScroll(true);
    124     EXPECT_FALSE(client.eventReceived());
    125     frameImpl->executeScript(WebScriptSource("window.scrollTo(0, 21);"));
    126     EXPECT_TRUE(client.eventReceived());
    127     client.reset();
    128     frameImpl->executeScript(WebScriptSource("window.scrollBy(0, 0);"));
    129     EXPECT_FALSE(client.eventReceived());
    130     client.reset();
    131 
    132     webView->close();
    133 }
    134 
    135 TEST_F(ProgrammaticScrollTest, UserScrollOnMainThread)
    136 {
    137     registerMockedHttpURLLoad("long_scroll.html");
    138     TestProgrammaticScrollClient client;
    139 
    140     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "long_scroll.html", true, 0, &client);
    141     webView->resize(WebSize(1000, 1000));
    142     webView->layout();
    143 
    144     WebGestureEvent gesture;
    145     gesture.type = WebInputEvent::GestureScrollBegin;
    146     webView->handleInputEvent(gesture);
    147     FrameTestHelpers::runPendingTasks();
    148     EXPECT_FALSE(client.eventReceived());
    149 
    150     gesture.type = WebInputEvent::GestureScrollUpdate;
    151     gesture.data.scrollUpdate.deltaY = 40;
    152     webView->handleInputEvent(gesture);
    153     FrameTestHelpers::runPendingTasks();
    154     EXPECT_FALSE(client.eventReceived());
    155 
    156     gesture.type = WebInputEvent::GestureScrollEnd;
    157     gesture.data.scrollUpdate.deltaY = 0;
    158     webView->handleInputEvent(gesture);
    159     FrameTestHelpers::runPendingTasks();
    160     EXPECT_FALSE(client.eventReceived());
    161 
    162     webView->close();
    163 }
    164 
    165 TEST_F(ProgrammaticScrollTest, RestoreScrollPositionAndViewStateWithScale)
    166 {
    167     registerMockedHttpURLLoad("long_scroll.html");
    168     TestProgrammaticScrollClient client;
    169 
    170     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "long_scroll.html", true, 0, &client);
    171     webView->resize(WebSize(1000, 1000));
    172     webView->layout();
    173 
    174     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView);
    175     FrameView* frameView = webViewImpl->mainFrameImpl()->frameView();
    176     HistoryController* history = webViewImpl->page()->mainFrame()->loader()->history();
    177 
    178     // Scale and scroll the page and save that state. Then scale and scroll again and restore.
    179     webViewImpl->setPageScaleFactor(2.0f, WebPoint(0, 200));
    180     history->saveDocumentAndScrollState();
    181     webViewImpl->setPageScaleFactor(3.0f, WebPoint(0, 300));
    182     // Flip back the wasScrolledByUser flag which was set to true by setPageScaleFactor
    183     // because otherwise HistoryController::restoreScrollPositionAndViewState does nothing.
    184     frameView->setWasScrolledByUser(false);
    185     history->restoreScrollPositionAndViewState();
    186 
    187     // Expect that both scroll and scale were restored, and that it was not a programmatic scroll.
    188     EXPECT_EQ(2.0f, webViewImpl->pageScaleFactor());
    189     EXPECT_EQ(200, webViewImpl->mainFrameImpl()->scrollOffset().height);
    190     EXPECT_TRUE(frameView->wasScrolledByUser());
    191     EXPECT_FALSE(client.eventReceived());
    192 
    193     webView->close();
    194 }
    195 
    196 TEST_F(ProgrammaticScrollTest, RestoreScrollPositionAndViewStateWithoutScale)
    197 {
    198     registerMockedHttpURLLoad("long_scroll.html");
    199     TestProgrammaticScrollClient client;
    200 
    201     WebView* webView = FrameTestHelpers::createWebViewAndLoad(m_baseURL + "long_scroll.html", true, 0, &client);
    202     webView->resize(WebSize(1000, 1000));
    203     webView->layout();
    204 
    205     WebViewImpl* webViewImpl = static_cast<WebViewImpl*>(webView);
    206     FrameView* frameView = webViewImpl->mainFrameImpl()->frameView();
    207     HistoryController* history = webViewImpl->page()->mainFrame()->loader()->history();
    208 
    209     // Scale and scroll the page and save that state, but then set scale to zero. Then scale and
    210     // scroll again and restore.
    211     webViewImpl->setPageScaleFactor(2.0f, WebPoint(0, 400));
    212     history->saveDocumentAndScrollState();
    213     webViewImpl->setPageScaleFactor(3.0f, WebPoint(0, 500));
    214     // Flip back the wasScrolledByUser flag which was set to true by setPageScaleFactor
    215     // because otherwise HistoryController::restoreScrollPositionAndViewState does nothing.
    216     frameView->setWasScrolledByUser(false);
    217     // HistoryController::restoreScrollPositionAndViewState flows differently if scale is zero.
    218     history->currentItem()->setPageScaleFactor(0.0f);
    219     history->restoreScrollPositionAndViewState();
    220 
    221     // Expect that only the scroll position was restored, and that it was not a programmatic scroll.
    222     EXPECT_EQ(3.0f, webViewImpl->pageScaleFactor());
    223     EXPECT_EQ(400, webViewImpl->mainFrameImpl()->scrollOffset().height);
    224     EXPECT_TRUE(frameView->wasScrolledByUser());
    225     EXPECT_FALSE(client.eventReceived());
    226 
    227     webView->close();
    228 }
    229 
    230 }
    231