Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1154)

Unified Diff: third_party/WebKit/Source/web/tests/RootScrollerTest.cpp

Issue 2290173004: Add some basic sanity tests to RootScroller for cases with remote frames. (Closed)
Patch Set: Use localFrame->frameWidget() Created 4 years, 3 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « no previous file | third_party/WebKit/Source/web/tests/data/root-scroller-child.html » ('j') | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
diff --git a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
index ed16f55e7b4c6c6c3365a18dfba853ea03330623..e23714a6a17b281711c33a87835888805aca8213 100644
--- a/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
+++ b/third_party/WebKit/Source/web/tests/RootScrollerTest.cpp
@@ -15,10 +15,12 @@
#include "public/platform/WebURLLoaderMockFactory.h"
#include "public/web/WebCache.h"
#include "public/web/WebConsoleMessage.h"
+#include "public/web/WebRemoteFrame.h"
#include "public/web/WebScriptSource.h"
#include "public/web/WebSettings.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "web/WebLocalFrameImpl.h"
+#include "web/WebRemoteFrameImpl.h"
#include "web/tests/FrameTestHelpers.h"
#include "wtf/Vector.h"
@@ -29,11 +31,6 @@ namespace blink {
namespace {
-class RootScrollerTestWebViewClient : public FrameTestHelpers::TestWebViewClient {
-public:
- MOCK_METHOD4(didOverscroll, void(const WebFloatSize&, const WebFloatSize&, const WebFloatPoint&, const WebFloatSize&));
-};
-
class RootScrollerTest : public ::testing::Test {
public:
RootScrollerTest()
@@ -52,14 +49,13 @@ public:
WebCache::clear();
}
- WebViewImpl* initialize(const std::string& pageName)
+ WebViewImpl* initialize(const std::string& pageName,
+ FrameTestHelpers::TestWebViewClient* client)
{
RuntimeEnabledFeatures::setSetRootScrollerEnabled(true);
- // Load a page with large body and set viewport size to 400x400 to
- // ensure main frame is scrollable.
m_helper.initializeAndLoad(
- m_baseURL + pageName, true, nullptr, &m_client, nullptr,
+ m_baseURL + pageName, true, nullptr, client, nullptr,
&configureSettings);
// Initialize top controls to be shown.
@@ -71,6 +67,11 @@ public:
return webViewImpl();
}
+ WebViewImpl* initialize(const std::string& pageName)
+ {
+ return initialize(pageName, &m_client);
+ }
+
static void configureSettings(WebSettings* settings)
{
settings->setJavaScriptEnabled(true);
@@ -97,31 +98,6 @@ public:
runPendingTasks();
}
- WebGestureEvent generateEvent(
- WebInputEvent::Type type, int deltaX = 0, int deltaY = 0)
- {
- WebGestureEvent event;
- event.type = type;
- event.sourceDevice = WebGestureDeviceTouchscreen;
- event.x = 100;
- event.y = 100;
- if (type == WebInputEvent::GestureScrollUpdate) {
- event.data.scrollUpdate.deltaX = deltaX;
- event.data.scrollUpdate.deltaY = deltaY;
- }
- return event;
- }
-
- void verticalScroll(float deltaY)
- {
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollBegin));
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollUpdate, 0, -deltaY));
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollEnd));
- }
-
WebViewImpl* webViewImpl() const
{
return m_helper.webView();
@@ -162,9 +138,45 @@ public:
return doc->rootScrollerController()->effectiveRootScroller();
}
+ WebGestureEvent generateTouchGestureEvent(
+ WebInputEvent::Type type,
+ int deltaX = 0,
+ int deltaY = 0)
+ {
+ return generateGestureEvent(
+ type, WebGestureDeviceTouchscreen, deltaX, deltaY);
+ }
+
+ WebGestureEvent generateWheelGestureEvent(
+ WebInputEvent::Type type,
+ int deltaX = 0,
+ int deltaY = 0)
+ {
+ return generateGestureEvent(
+ type, WebGestureDeviceTouchpad, deltaX, deltaY);
+ }
+
protected:
+ WebGestureEvent generateGestureEvent(
+ WebInputEvent::Type type,
+ WebGestureDevice device,
+ int deltaX,
+ int deltaY)
+ {
+ WebGestureEvent event;
+ event.type = type;
+ event.sourceDevice = device;
+ event.x = 100;
+ event.y = 100;
+ if (type == WebInputEvent::GestureScrollUpdate) {
+ event.data.scrollUpdate.deltaX = deltaX;
+ event.data.scrollUpdate.deltaY = deltaY;
+ }
+ return event;
+ }
+
std::string m_baseURL;
- RootScrollerTestWebViewClient m_client;
+ FrameTestHelpers::TestWebViewClient m_client;
FrameTestHelpers::WebViewHelper m_helper;
RuntimeEnabledFeatures::Backup m_featuresBackup;
};
@@ -182,11 +194,17 @@ TEST_F(RootScrollerTest, TestDefaultRootScroller)
EXPECT_EQ(htmlElement, effectiveRootScroller(mainFrame()->document()));
}
+class OverscrollTestWebViewClient : public FrameTestHelpers::TestWebViewClient {
+public:
+ MOCK_METHOD4(didOverscroll, void(const WebFloatSize&, const WebFloatSize&, const WebFloatPoint&, const WebFloatSize&));
+};
+
// Tests that setting an element as the root scroller causes it to control url
// bar hiding and overscroll.
TEST_F(RootScrollerTest, TestSetRootScroller)
{
- initialize("root-scroller.html");
+ OverscrollTestWebViewClient client;
+ initialize("root-scroller.html", &client);
Element* container = mainFrame()->document()->getElementById("container");
TrackExceptionState exceptionState;
@@ -197,21 +215,21 @@ TEST_F(RootScrollerTest, TestSetRootScroller)
double maximumScroll = 600;
webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollBegin));
+ generateTouchGestureEvent(WebInputEvent::GestureScrollBegin));
{
// Scrolling over the #container DIV should cause the top controls to
// hide.
EXPECT_FLOAT_EQ(1, topControls().shownRatio());
- webViewImpl()->handleInputEvent(generateEvent(
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
WebInputEvent::GestureScrollUpdate, 0, -topControls().height()));
EXPECT_FLOAT_EQ(0, topControls().shownRatio());
}
{
// Make sure we're actually scrolling the DIV and not the FrameView.
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollUpdate, 0, -100));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 0, -100));
EXPECT_FLOAT_EQ(100, container->scrollTop());
EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y());
}
@@ -219,72 +237,75 @@ TEST_F(RootScrollerTest, TestSetRootScroller)
{
// Scroll 50 pixels past the end. Ensure we report the 50 pixels as
// overscroll.
- EXPECT_CALL(m_client,
+ EXPECT_CALL(client,
didOverscroll(
WebFloatSize(0, 50),
WebFloatSize(0, 50),
WebFloatPoint(100, 100),
WebFloatSize()));
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollUpdate, 0, -550));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 0, -550));
EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop());
EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y());
- Mock::VerifyAndClearExpectations(&m_client);
+ Mock::VerifyAndClearExpectations(&client);
}
{
// Continue the gesture overscroll.
- EXPECT_CALL(m_client,
+ EXPECT_CALL(client,
didOverscroll(
WebFloatSize(0, 20),
WebFloatSize(0, 70),
WebFloatPoint(100, 100),
WebFloatSize()));
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 0, -20));
EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop());
EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y());
- Mock::VerifyAndClearExpectations(&m_client);
+ Mock::VerifyAndClearExpectations(&client);
}
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollEnd));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollEnd));
{
// Make sure a new gesture scroll still won't scroll the frameview and
// overscrolls.
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollBegin));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollBegin));
- EXPECT_CALL(m_client,
+ EXPECT_CALL(client,
didOverscroll(
WebFloatSize(0, 30),
WebFloatSize(0, 30),
WebFloatPoint(100, 100),
WebFloatSize()));
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollUpdate, 0, -30));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 0, -30));
EXPECT_FLOAT_EQ(maximumScroll, container->scrollTop());
EXPECT_FLOAT_EQ(0, mainFrameView()->scrollPositionDouble().y());
- Mock::VerifyAndClearExpectations(&m_client);
+ Mock::VerifyAndClearExpectations(&client);
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollEnd));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollEnd));
}
{
// Scrolling up should show the top controls.
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollBegin));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollBegin));
EXPECT_FLOAT_EQ(0, topControls().shownRatio());
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollUpdate, 0, 30));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 0, 30));
EXPECT_FLOAT_EQ(0.6, topControls().shownRatio());
- webViewImpl()->handleInputEvent(
- generateEvent(WebInputEvent::GestureScrollEnd));
+ webViewImpl()->handleInputEvent(generateTouchGestureEvent(
+ WebInputEvent::GestureScrollEnd));
}
+
+ // Reset manually to avoid lifetime issues with custom WebViewClient.
+ m_helper.reset();
}
// Tests that removing the element that is the root scroller from the DOM tree
@@ -502,6 +523,7 @@ TEST_F(RootScrollerTest, SetRootScrollerIframeBecomesEffective)
// root scroller layer and that the viewport apply scroll is set on it.
TEST_F(RootScrollerTest, SetRootScrollerIframeUsesCorrectLayerAndCallback)
{
+ // TODO(bokan): The expectation and actual in the checks here are backwards.
initialize("root-scroller-iframe.html");
ASSERT_EQ(nullptr, mainFrame()->document()->rootScroller());
@@ -633,6 +655,107 @@ TEST_F(RootScrollerTest, DISABLED_TestSetRootScrollerOnElementFromOutsideIframe)
}
}
+// Do a basic sanity check that setting as root scroller an iframe that's remote
+// doesn't crash or otherwise fail catastrophically.
+TEST_F(RootScrollerTest, RemoteIFrame)
+{
+ FrameTestHelpers::TestWebRemoteFrameClient remoteFrameClient;
+ initialize("root-scroller-iframe.html");
+
+ // Initialization: Replace the iframe with a remote frame.
+ {
+ WebRemoteFrame* remoteFrame = WebRemoteFrame::create(
+ WebTreeScopeType::Document, &remoteFrameClient);
+ WebFrame* childFrame = mainWebFrame()->firstChild();
+ childFrame->swap(remoteFrame);
+ }
+
+ // Set the root scroller in the local main frame to the iframe (which is
+ // remote).
+ {
+ Element* iframe = mainFrame()->document()->getElementById("iframe");
+ NonThrowableExceptionState nonThrow;
+ mainFrame()->document()->setRootScroller(iframe, nonThrow);
+ EXPECT_EQ(iframe, mainFrame()->document()->rootScroller());
+ }
+
+ // Reset explicitly to prevent lifetime issues with the RemoteFrameClient.
+ m_helper.reset();
+}
+
+// Do a basic sanity check that the scrolling and root scroller machinery
+// doesn't fail catastrophically in site isolation when the main frame is
+// remote. Setting a root scroller in OOPIF isn't implemented yet but we should
+// still scroll as before and not crash.
+TEST_F(RootScrollerTest, RemoteMainFrame)
+{
+ FrameTestHelpers::TestWebRemoteFrameClient remoteClient;
+ FrameTestHelpers::TestWebWidgetClient webWidgetClient;
+ WebFrameWidget* widget;
+ WebLocalFrameImpl* localFrame;
+
+ initialize("root-scroller-iframe.html");
+
+ // Initialization: Set the main frame to be a RemoteFrame and add a local
+ // child.
+ {
+ webViewImpl()->setMainFrame(remoteClient.frame());
+ WebRemoteFrame* root = webViewImpl()->mainFrame()->toWebRemoteFrame();
+ root->setReplicatedOrigin(SecurityOrigin::createUnique());
+ WebFrameOwnerProperties properties;
+ localFrame = FrameTestHelpers::createLocalChild(
+ root, "frameName", nullptr, nullptr, nullptr, properties);
+
+ FrameTestHelpers::loadFrame(
+ localFrame, m_baseURL + "root-scroller-child.html");
+ widget = localFrame->frameWidget();
+ widget->resize(WebSize(400, 400));
+ }
+
+ Document* document = localFrame->frameView()->frame().document();
+ Element* container = document->getElementById("container");
+
+ // Try scrolling in the iframe.
+ {
+ widget->handleInputEvent(generateWheelGestureEvent(
+ WebInputEvent::GestureScrollBegin));
+ widget->handleInputEvent(generateWheelGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 0, -100));
+ widget->handleInputEvent(generateWheelGestureEvent(
+ WebInputEvent::GestureScrollEnd));
+ EXPECT_EQ(100, container->scrollTop());
+ }
+
+ // Set the container Element as the root scroller.
+ {
+ NonThrowableExceptionState nonThrow;
+ document->setRootScroller(container, nonThrow);
+ EXPECT_EQ(container, document->rootScroller());
+ }
+
+ // Try scrolling in the iframe now that it has a root scroller set.
+ {
+ widget->handleInputEvent(generateWheelGestureEvent(
+ WebInputEvent::GestureScrollBegin));
+ widget->handleInputEvent(generateWheelGestureEvent(
+ WebInputEvent::GestureScrollUpdate, 0, -100));
+ widget->handleInputEvent(generateWheelGestureEvent(
+ WebInputEvent::GestureScrollEnd));
+
+ // TODO(bokan): This doesn't work right now because we notice in
+ // Element::nativeApplyScroll that the container is the
+ // effectiveRootScroller but the only way we expect to get to
+ // nativeApplyScroll is if the effective scroller had its applyScroll
+ // ViewportScrollCallback removed. Keep the scrolls to guard crashes
+ // but the expectations on when a ViewportScrollCallback have changed
+ // and should be updated.
+ // EXPECT_EQ(200, container->scrollTop());
+ }
+
+ // Reset explicitly to prevent lifetime issues with the RemoteFrameClient.
+ m_helper.reset();
+}
+
} // namespace
} // namespace blink
« no previous file with comments | « no previous file | third_party/WebKit/Source/web/tests/data/root-scroller-child.html » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698