Merge Chromium + Blink git repositories
[chromium-blink-merge.git] / third_party / WebKit / Source / web / tests / TopControlsTest.cpp
blobf7960edea20a0abad26a630d79e0a7987408225b
1 /*
2 * Copyright (C) 2015 Google Inc. All rights reserved.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
6 * met:
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * * Redistributions in binary form must reproduce the above
11 * copyright notice, this list of conditions and the following disclaimer
12 * in the documentation and/or other materials provided with the
13 * distribution.
14 * * Neither the name of Google Inc. nor the names of its
15 * contributors may be used to endorse or promote products derived from
16 * this software without specific prior written permission.
18 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19 * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20 * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21 * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22 * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28 * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
30 #include "config.h"
31 #include "core/frame/TopControls.h"
33 #include "core/frame/FrameHost.h"
34 #include "core/frame/LocalFrame.h"
35 #include "core/layout/LayoutView.h"
36 #include "core/page/Page.h"
37 #include "platform/testing/URLTestHelpers.h"
38 #include "public/platform/Platform.h"
39 #include "public/platform/WebUnitTestSupport.h"
40 #include "public/web/WebSettings.h"
41 #include "web/WebLocalFrameImpl.h"
42 #include "web/tests/FrameTestHelpers.h"
43 #include <gmock/gmock.h>
44 #include <gtest/gtest.h>
46 namespace blink {
48 // These tests cover top controls scrolling on main-thread.
49 // The animation for completing a partial show/hide is done in compositor so
50 // it is not covered here.
51 class TopControlsTest : public testing::Test {
52 public:
53 TopControlsTest()
54 : m_baseURL("http://www.test.com/")
56 registerMockedHttpURLLoad("large-div.html");
57 registerMockedHttpURLLoad("overflow-scrolling.html");
58 registerMockedHttpURLLoad("iframe-scrolling.html");
59 registerMockedHttpURLLoad("iframe-scrolling-inner.html");
62 ~TopControlsTest() override
64 Platform::current()->unitTestSupport()->unregisterAllMockedURLs();
67 WebViewImpl* initialize(const std::string& pageName = "large-div.html")
69 // Load a page with large body and set viewport size to 400x400 to ensure
70 // main frame is scrollable.
71 m_helper.initializeAndLoad(m_baseURL + pageName, true, 0, 0, &configureSettings);
73 webViewImpl()->resize(IntSize(400, 400));
74 return webViewImpl();
77 static void configureSettings(WebSettings* settings)
79 settings->setJavaScriptEnabled(true);
80 settings->setAcceleratedCompositingEnabled(true);
81 settings->setPreferCompositingToLCDTextEnabled(true);
82 // Android settings
83 settings->setViewportEnabled(true);
84 settings->setViewportMetaEnabled(true);
85 settings->setShrinksViewportContentToFit(true);
86 settings->setMainFrameResizesAreOrientationChanges(true);
89 void registerMockedHttpURLLoad(const std::string& fileName)
91 URLTestHelpers::registerMockedURLFromBaseURL(WebString::fromUTF8(m_baseURL.c_str()), WebString::fromUTF8(fileName.c_str()));
94 WebGestureEvent generateEvent(WebInputEvent::Type type, int deltaX = 0, int deltaY = 0)
96 WebGestureEvent event;
97 event.type = type;
98 event.x = 100;
99 event.y = 100;
100 if (type == WebInputEvent::GestureScrollUpdate) {
101 event.data.scrollUpdate.deltaX = deltaX;
102 event.data.scrollUpdate.deltaY = deltaY;
104 return event;
107 void verticalScroll(float deltaY)
109 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
110 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, deltaY));
111 webViewImpl()->handleInputEvent(generateEvent(WebInputEvent::GestureScrollEnd));
114 WebViewImpl* webViewImpl() const { return m_helper.webViewImpl(); }
115 LocalFrame* frame() const { return m_helper.webViewImpl()->mainFrameImpl()->frame(); }
116 VisualViewport& visualViewport() const { return m_helper.webViewImpl()->page()->frameHost().visualViewport(); }
118 private:
119 std::string m_baseURL;
120 FrameTestHelpers::WebViewHelper m_helper;
122 // To prevent platform differences in content layout, use mock
123 // scrollbars. This is especially needed for Mac, where the presence
124 // or absence of a mouse will change frame sizes because of different
125 // scrollbar themes.
126 FrameTestHelpers::UseMockScrollbarSettings m_useMockScrollbars;
129 #define EXPECT_POINT_EQ(expected, actual) \
130 do { \
131 EXPECT_DOUBLE_EQ((expected).x(), (actual).x()); \
132 EXPECT_DOUBLE_EQ((expected).y(), (actual).y()); \
133 } while (false)
135 // Disable these tests on Mac OSX until further investigation.
136 // Local build on Mac is OK but the bot fails. This is not an issue as
137 // Top Controls are currently only used on Android.
138 #if OS(MACOSX)
139 #define MAYBE(test) DISABLED_##test
140 #else
141 #define MAYBE(test) test
142 #endif
144 // Scrolling down should hide top controls.
145 TEST_F(TopControlsTest, MAYBE(HideOnScrollDown))
147 WebViewImpl* webView = initialize();
148 // initialize top controls to be shown.
149 webView->setTopControlsHeight(50.f, true);
150 webView->topControls().setShownRatio(1);
152 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
153 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
155 // Top controls should be scrolled partially and page should not scroll.
156 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -25.f));
157 EXPECT_FLOAT_EQ(25.f, webView->topControls().contentOffset());
158 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollPosition());
160 // Top controls should consume 30px and become hidden. Excess scroll should be consumed by the page.
161 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -40.f));
162 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
163 EXPECT_POINT_EQ(IntPoint(0, 15), frame()->view()->scrollPosition());
165 // Only page should consume scroll
166 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20.f));
167 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
168 EXPECT_POINT_EQ(IntPoint(0, 35), frame()->view()->scrollPosition());
171 // Scrolling up should show top controls.
172 TEST_F(TopControlsTest, MAYBE(ShowOnScrollUp))
174 WebViewImpl* webView = initialize();
175 // initialize top controls to be hidden.
176 webView->setTopControlsHeight(50.f, false);
177 webView->topControls().setShownRatio(0);
179 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
180 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
182 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 10.f));
183 EXPECT_FLOAT_EQ(10.f, webView->topControls().contentOffset());
184 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollPosition());
186 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 50.f));
187 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
188 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollPosition());
191 // Scrolling up after previous scroll downs should cause top controls to be
192 // shown only after all previously scrolled down amount is compensated.
193 TEST_F(TopControlsTest, MAYBE(ScrollDownThenUp))
195 WebViewImpl* webView = initialize();
196 // initialize top controls to be shown and position page at 100px.
197 webView->setTopControlsHeight(50.f, true);
198 webView->topControls().setShownRatio(1);
199 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
201 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
202 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
204 // Scroll down to completely hide top controls. Excess deltaY (100px) should be consumed by the page.
205 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -150.f));
206 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
207 EXPECT_POINT_EQ(IntPoint(0, 200), frame()->view()->scrollPosition());
209 // Scroll up and ensure the top controls does not move until we recover 100px previously scrolled.
210 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 40.f));
211 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
212 EXPECT_POINT_EQ(IntPoint(0, 160), frame()->view()->scrollPosition());
214 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 60.f));
215 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
216 EXPECT_POINT_EQ(IntPoint(0, 100), frame()->view()->scrollPosition());
218 // Now we have hit the threshold so further scroll up should be consumed by top controls.
219 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 30.f));
220 EXPECT_FLOAT_EQ(30.f, webView->topControls().contentOffset());
221 EXPECT_POINT_EQ(IntPoint(0, 100), frame()->view()->scrollPosition());
223 // Once top control is fully shown then page should consume any excess scroll.
224 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 70.f));
225 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
226 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
229 // Scrolling down should always cause visible top controls to start hiding even
230 // if we have been scrolling up previously.
231 TEST_F(TopControlsTest, MAYBE(ScrollUpThenDown))
233 WebViewImpl* webView = initialize();
234 // initialize top controls to be hidden and position page at 100px.
235 webView->setTopControlsHeight(50.f, false);
236 webView->topControls().setShownRatio(0);
237 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
239 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
240 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
242 // Scroll up to completely show top controls. Excess deltaY (50px) should be consumed by the page.
243 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 100.f));
244 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
245 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
247 // Scroll down and ensure only top controls is scrolled
248 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -40.f));
249 EXPECT_FLOAT_EQ(10.f, webView->topControls().contentOffset());
250 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
252 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -60.f));
253 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
254 EXPECT_POINT_EQ(IntPoint(0, 100), frame()->view()->scrollPosition());
257 // Top controls should not consume horizontal scroll.
258 TEST_F(TopControlsTest, MAYBE(HorizontalScroll))
260 WebViewImpl* webView = initialize();
261 // initialize top controls to be shown.
262 webView->setTopControlsHeight(50.f, true);
263 webView->topControls().setShownRatio(1);
265 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
266 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
268 // Top controls should not consume horizontal scroll.
269 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, -110.f, -100.f));
270 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
271 EXPECT_POINT_EQ(IntPoint(110, 50), frame()->view()->scrollPosition());
273 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, -40.f, 0));
274 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
275 EXPECT_POINT_EQ(IntPoint(150, 50), frame()->view()->scrollPosition());
278 // Page scale should not impact top controls scrolling
279 TEST_F(TopControlsTest, MAYBE(PageScaleHasNoImpact))
281 WebViewImpl* webView = initialize();
282 webViewImpl()->setDefaultPageScaleLimits(0.25f, 5);
283 webView->setPageScaleFactor(2.0);
285 // Initialize top controls to be shown.
286 webView->setTopControlsHeight(50.f, true);
287 webView->topControls().setShownRatio(1);
289 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
290 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
292 // Top controls should be scrolled partially and page should not scroll.
293 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -20.f));
294 EXPECT_FLOAT_EQ(30.f, webView->topControls().contentOffset());
295 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollableArea()->scrollPositionDouble());
297 // Top controls should consume 30px and become hidden. Excess scroll should be consumed by the page at 2x scale.
298 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, -70.f));
299 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
300 EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
302 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollEnd));
304 // Change page scale and test.
305 webView->setPageScaleFactor(0.5);
307 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollBegin));
308 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
309 EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
311 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 50.f));
312 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
313 EXPECT_POINT_EQ(IntPoint(0, 20), frame()->view()->scrollableArea()->scrollPositionDouble());
315 // At 0.5x scale scrolling 10px should take us to the top of the page.
316 webView->handleInputEvent(generateEvent(WebInputEvent::GestureScrollUpdate, 0, 10.f));
317 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
318 EXPECT_POINT_EQ(IntPoint(0, 0), frame()->view()->scrollableArea()->scrollPositionDouble());
321 // Some scroll deltas result in a shownRatio that can't be realized in a
322 // floating-point number. Make sure that if the top controls aren't fully
323 // scrolled, scrollBy doesn't return any excess delta. i.e. There should be no
324 // slippage between the content and top controls.
325 TEST_F(TopControlsTest, MAYBE(FloatingPointSlippage))
327 WebViewImpl* webView = initialize();
328 webViewImpl()->setDefaultPageScaleLimits(0.25f, 5);
329 webView->setPageScaleFactor(2.0);
331 // Initialize top controls to be shown.
332 webView->setTopControlsHeight(50.f, true);
333 webView->topControls().setShownRatio(1);
335 webView->topControls().scrollBegin();
336 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
338 // This will result in a 20px scroll to the top controls so the show ratio
339 // will be 30/50 == 0.6 which is not representible in a float. Make sure
340 // that scroll still consumes the whole delta.
341 FloatSize remainingDelta = webView->topControls().scrollBy(FloatSize(0, -10));
342 EXPECT_EQ(0, remainingDelta.height());
345 // Scrollable subregions should scroll before top controls
346 TEST_F(TopControlsTest, MAYBE(ScrollableSubregionScrollFirst))
348 WebViewImpl* webView = initialize("overflow-scrolling.html");
349 webView->setTopControlsHeight(50.f, true);
350 webView->topControls().setShownRatio(1);
351 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll);
353 // Test scroll down
354 // Scroll down should scroll the overflow div first but top controls and main frame should not scroll.
355 verticalScroll(-800.f);
356 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
357 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
359 // Continued scroll down should start hiding top controls but main frame should not scroll.
360 verticalScroll(-40.f);
361 EXPECT_FLOAT_EQ(10.f, webView->topControls().contentOffset());
362 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
364 // Continued scroll down should scroll down the main frame
365 verticalScroll(-40.f);
366 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
367 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
369 // Test scroll up
370 // scroll up should scroll overflow div first
371 verticalScroll(800.f);
372 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
373 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
375 // Continued scroll up should start showing top controls but main frame should not scroll.
376 verticalScroll(40.f);
377 EXPECT_FLOAT_EQ(40.f, webView->topControls().contentOffset());
378 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
380 // Continued scroll down up scroll up the main frame
381 verticalScroll(40.f);
382 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
383 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
387 // Scrollable iframes should scroll before top controls
388 TEST_F(TopControlsTest, MAYBE(ScrollableIframeScrollFirst))
390 WebViewImpl* webView = initialize("iframe-scrolling.html");
391 webView->setTopControlsHeight(50.f, true);
392 webView->topControls().setShownRatio(1);
393 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 50), ProgrammaticScroll);
395 // Test scroll down
396 // Scroll down should scroll the iframe first but top controls and main frame should not scroll.
397 verticalScroll(-800.f);
398 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
399 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
401 // Continued scroll down should start hiding top controls but main frame should not scroll.
402 verticalScroll(-40.f);
403 EXPECT_FLOAT_EQ(10.f, webView->topControls().contentOffset());
404 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
406 // Continued scroll down should scroll down the main frame
407 verticalScroll(-40.f);
408 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
409 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
411 // Test scroll up
412 // scroll up should scroll iframe first
413 verticalScroll(800.f);
414 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
415 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
417 // Continued scroll up should start showing top controls but main frame should not scroll.
418 verticalScroll(40.f);
419 EXPECT_FLOAT_EQ(40.f, webView->topControls().contentOffset());
420 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
422 // Continued scroll down up scroll up the main frame
423 verticalScroll(40.f);
424 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
425 EXPECT_POINT_EQ(IntPoint(0, 50), frame()->view()->scrollPosition());
428 // Top controls visibility should remain consistent when height is changed.
429 TEST_F(TopControlsTest, MAYBE(HeightChangeMaintainsVisibility))
431 WebViewImpl* webView = initialize();
432 webView->setTopControlsHeight(20.f, false);
433 webView->topControls().setShownRatio(0);
435 webView->setTopControlsHeight(20.f, false);
436 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
438 webView->setTopControlsHeight(40.f, false);
439 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
441 // Scroll up to show top controls.
442 verticalScroll(40.f);
443 EXPECT_FLOAT_EQ(40.f, webView->topControls().contentOffset());
445 // Changing height of a fully shown top controls should correctly adjust content offset
446 webView->setTopControlsHeight(30.f, false);
447 EXPECT_FLOAT_EQ(30.f, webView->topControls().contentOffset());
450 // Zero delta should not have any effect on top controls.
451 TEST_F(TopControlsTest, MAYBE(ZeroHeightMeansNoEffect))
453 WebViewImpl* webView = initialize();
454 webView->setTopControlsHeight(0, false);
455 webView->topControls().setShownRatio(0);
456 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
458 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
460 verticalScroll(20.f);
461 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
462 EXPECT_POINT_EQ(IntPoint(0, 80), frame()->view()->scrollPosition());
464 verticalScroll(-30.f);
465 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
466 EXPECT_POINT_EQ(IntPoint(0, 110), frame()->view()->scrollPosition());
468 webView->topControls().setShownRatio(1);
469 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
472 // Top controls should not hide when scrolling up past limit
473 TEST_F(TopControlsTest, MAYBE(ScrollUpPastLimitDoesNotHide))
475 WebViewImpl* webView = initialize();
476 // Initialize top controls to be shown
477 webView->setTopControlsHeight(50.f, true);
478 webView->topControls().setShownRatio(1);
479 // Use 2x scale so that both visual viewport and frameview are scrollable
480 webView->setPageScaleFactor(2.0);
482 // Fully scroll frameview but visualviewport remains scrollable
483 webView->mainFrame()->setScrollOffset(WebSize(0, 10000));
484 visualViewport().setLocation(FloatPoint(0, 0));
485 verticalScroll(-10.f);
486 EXPECT_FLOAT_EQ(40, webView->topControls().contentOffset());
488 webView->topControls().setShownRatio(1);
489 // Fully scroll visual veiwport but frameview remains scrollable
490 webView->mainFrame()->setScrollOffset(WebSize(0, 0));
491 visualViewport().setLocation(FloatPoint(0, 10000));
492 verticalScroll(-20.f);
493 EXPECT_FLOAT_EQ(30, webView->topControls().contentOffset());
495 webView->topControls().setShownRatio(1);
496 // Fully scroll both frameview and visual viewport
497 webView->mainFrame()->setScrollOffset(WebSize(0, 10000));
498 visualViewport().setLocation(FloatPoint(0, 10000));
499 verticalScroll(-30.f);
500 // Top controls should not move because neither frameview nor visual viewport
501 // are scrollable
502 EXPECT_FLOAT_EQ(50.f, webView->topControls().contentOffset());
505 // Top controls should honor its constraints
506 TEST_F(TopControlsTest, MAYBE(StateConstraints))
508 WebViewImpl* webView = initialize();
509 webView->setTopControlsHeight(50.f, false);
510 frame()->view()->scrollableArea()->setScrollPosition(IntPoint(0, 100), ProgrammaticScroll);
512 // Setting permitted state should not change content offset
513 webView->updateTopControlsState(WebTopControlsShown, WebTopControlsShown, false);
514 EXPECT_FLOAT_EQ(0.f, webView->topControls().contentOffset());
516 // Showing is permitted
517 webView->topControls().setShownRatio(1);
518 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset());
520 // Only shown state is permitted so controls cannot hide
521 verticalScroll(-20.f);
522 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset());
523 EXPECT_POINT_EQ(IntPoint(0, 120), frame()->view()->scrollPosition());
525 // Setting permitted state should not change content offset
526 webView->updateTopControlsState(WebTopControlsHidden, WebTopControlsHidden, false);
527 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset());
529 // Hiding is permitted
530 webView->topControls().setShownRatio(0);
531 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset());
533 // Only hidden state is permitted so controls cannot show
534 verticalScroll(30.f);
535 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset());
536 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition());
538 // Setting permitted state should not change content offset
539 webView->updateTopControlsState(WebTopControlsBoth, WebTopControlsBoth, false);
540 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset());
542 // Both states are permitted so controls can either show or hide
543 verticalScroll(50.f);
544 EXPECT_FLOAT_EQ(50, webView->topControls().contentOffset());
545 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition());
547 verticalScroll(-50.f);
548 EXPECT_FLOAT_EQ(0, webView->topControls().contentOffset());
549 EXPECT_POINT_EQ(IntPoint(0, 90), frame()->view()->scrollPosition());
552 } // namespace blink