1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
5 #include "content/browser/web_contents/web_contents_view_aura.h"
7 #include "base/command_line.h"
8 #include "base/run_loop.h"
9 #include "base/strings/utf_string_conversions.h"
10 #include "base/test/test_timeouts.h"
11 #include "base/values.h"
13 #include "base/win/windows_version.h"
15 #include "content/browser/frame_host/navigation_controller_impl.h"
16 #include "content/browser/frame_host/navigation_entry_impl.h"
17 #include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
18 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
19 #include "content/browser/web_contents/web_contents_impl.h"
20 #include "content/browser/web_contents/web_contents_view.h"
21 #include "content/common/input/synthetic_web_input_event_builders.h"
22 #include "content/common/input_messages.h"
23 #include "content/common/view_messages.h"
24 #include "content/public/browser/browser_message_filter.h"
25 #include "content/public/browser/render_frame_host.h"
26 #include "content/public/browser/web_contents_delegate.h"
27 #include "content/public/browser/web_contents_observer.h"
28 #include "content/public/common/content_switches.h"
29 #include "content/public/test/browser_test_utils.h"
30 #include "content/public/test/content_browser_test.h"
31 #include "content/public/test/content_browser_test_utils.h"
32 #include "content/public/test/test_renderer_host.h"
33 #include "content/public/test/test_utils.h"
34 #include "content/shell/browser/shell.h"
35 #include "ui/aura/window.h"
36 #include "ui/aura/window_tree_host.h"
37 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
38 #include "ui/events/event_processor.h"
39 #include "ui/events/event_switches.h"
40 #include "ui/events/event_utils.h"
41 #include "ui/events/test/event_generator.h"
45 // TODO(tdresser): Find a way to avoid sleeping like this. See crbug.com/405282
47 void GiveItSomeTime() {
48 base::RunLoop run_loop
;
49 base::MessageLoop::current()->PostDelayedTask(
51 run_loop
.QuitClosure(),
52 base::TimeDelta::FromMillisecondsD(10));
56 // WebContentsDelegate which tracks vertical overscroll updates.
57 class VerticalOverscrollTracker
: public content::WebContentsDelegate
{
59 VerticalOverscrollTracker() : count_(0), completed_(false) {}
60 ~VerticalOverscrollTracker() override
{}
62 int num_overscroll_updates() const {
66 bool overscroll_completed() const {
76 bool CanOverscrollContent() const override
{ return true; }
78 void OverscrollUpdate(float delta_y
) override
{ ++count_
; }
80 void OverscrollComplete() override
{ completed_
= true; }
85 DISALLOW_COPY_AND_ASSIGN(VerticalOverscrollTracker
);
93 // This class keeps track of the RenderViewHost whose screenshot was captured.
94 class ScreenshotTracker
: public NavigationEntryScreenshotManager
{
96 explicit ScreenshotTracker(NavigationControllerImpl
* controller
)
97 : NavigationEntryScreenshotManager(controller
),
98 screenshot_taken_for_(NULL
),
99 waiting_for_screenshots_(0) {
102 ~ScreenshotTracker() override
{}
104 RenderViewHost
* screenshot_taken_for() { return screenshot_taken_for_
; }
107 screenshot_taken_for_
= NULL
;
108 screenshot_set_
.clear();
111 void SetScreenshotInterval(int interval_ms
) {
112 SetMinScreenshotIntervalMS(interval_ms
);
115 void WaitUntilScreenshotIsReady() {
116 if (!waiting_for_screenshots_
)
118 message_loop_runner_
= new content::MessageLoopRunner
;
119 message_loop_runner_
->Run();
122 bool ScreenshotSetForEntry(NavigationEntryImpl
* entry
) const {
123 return screenshot_set_
.count(entry
) > 0;
127 // Overridden from NavigationEntryScreenshotManager:
128 void TakeScreenshotImpl(RenderViewHost
* host
,
129 NavigationEntryImpl
* entry
) override
{
130 ++waiting_for_screenshots_
;
131 screenshot_taken_for_
= host
;
132 NavigationEntryScreenshotManager::TakeScreenshotImpl(host
, entry
);
135 void OnScreenshotSet(NavigationEntryImpl
* entry
) override
{
136 --waiting_for_screenshots_
;
137 screenshot_set_
[entry
] = true;
138 NavigationEntryScreenshotManager::OnScreenshotSet(entry
);
139 if (waiting_for_screenshots_
== 0 && message_loop_runner_
.get())
140 message_loop_runner_
->Quit();
143 RenderViewHost
* screenshot_taken_for_
;
144 scoped_refptr
<content::MessageLoopRunner
> message_loop_runner_
;
145 int waiting_for_screenshots_
;
146 std::map
<NavigationEntryImpl
*, bool> screenshot_set_
;
148 DISALLOW_COPY_AND_ASSIGN(ScreenshotTracker
);
151 class NavigationWatcher
: public WebContentsObserver
{
153 explicit NavigationWatcher(WebContents
* contents
)
154 : WebContentsObserver(contents
),
156 should_quit_loop_(false) {
159 ~NavigationWatcher() override
{}
161 void WaitUntilNavigationStarts() {
164 should_quit_loop_
= true;
165 base::MessageLoop::current()->Run();
169 // Overridden from WebContentsObserver:
170 void DidStartNavigationToPendingEntry(
171 const GURL
& validated_url
,
172 NavigationController::ReloadType reload_type
) override
{
174 if (should_quit_loop_
)
175 base::MessageLoop::current()->Quit();
179 bool should_quit_loop_
;
181 DISALLOW_COPY_AND_ASSIGN(NavigationWatcher
);
184 class InputEventMessageFilterWaitsForAcks
: public BrowserMessageFilter
{
186 InputEventMessageFilterWaitsForAcks()
187 : BrowserMessageFilter(InputMsgStart
),
188 type_(blink::WebInputEvent::Undefined
),
189 state_(INPUT_EVENT_ACK_STATE_UNKNOWN
) {}
191 void WaitForAck(blink::WebInputEvent::Type type
) {
192 base::RunLoop run_loop
;
193 base::AutoReset
<base::Closure
> reset_quit(&quit_
, run_loop
.QuitClosure());
194 base::AutoReset
<blink::WebInputEvent::Type
> reset_type(&type_
, type
);
198 InputEventAckState
last_ack_state() const { return state_
; }
201 ~InputEventMessageFilterWaitsForAcks() override
{}
204 void ReceivedEventAck(blink::WebInputEvent::Type type
,
205 InputEventAckState state
) {
212 // BrowserMessageFilter:
213 bool OnMessageReceived(const IPC::Message
& message
) override
{
214 if (message
.type() == InputHostMsg_HandleInputEvent_ACK::ID
) {
215 InputHostMsg_HandleInputEvent_ACK::Param params
;
216 InputHostMsg_HandleInputEvent_ACK::Read(&message
, ¶ms
);
217 blink::WebInputEvent::Type type
= get
<0>(params
).type
;
218 InputEventAckState ack
= get
<0>(params
).state
;
219 BrowserThread::PostTask(BrowserThread::UI
, FROM_HERE
,
220 base::Bind(&InputEventMessageFilterWaitsForAcks::ReceivedEventAck
,
227 blink::WebInputEvent::Type type_
;
228 InputEventAckState state_
;
230 DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilterWaitsForAcks
);
233 class WebContentsViewAuraTest
: public ContentBrowserTest
{
235 WebContentsViewAuraTest()
236 : screenshot_manager_(NULL
) {
239 // Executes the javascript synchronously and makes sure the returned value is
241 void ExecuteSyncJSFunction(RenderFrameHost
* rfh
, const std::string
& jscript
) {
242 scoped_ptr
<base::Value
> value
=
243 content::ExecuteScriptAndGetValue(rfh
, jscript
);
246 // Starts the test server and navigates to the given url. Sets a large enough
247 // size to the root window. Returns after the navigation to the url is
249 void StartTestWithPage(const std::string
& url
) {
250 ASSERT_TRUE(test_server()->Start());
251 GURL
test_url(test_server()->GetURL(url
));
252 NavigateToURL(shell(), test_url
);
254 WebContentsImpl
* web_contents
=
255 static_cast<WebContentsImpl
*>(shell()->web_contents());
256 NavigationControllerImpl
* controller
= &web_contents
->GetController();
258 screenshot_manager_
= new ScreenshotTracker(controller
);
259 controller
->SetScreenshotManager(screenshot_manager_
);
262 void SetUpCommandLine(base::CommandLine
* cmd
) override
{
263 cmd
->AppendSwitchASCII(switches::kTouchEvents
,
264 switches::kTouchEventsEnabled
);
267 void TestOverscrollNavigation(bool touch_handler
) {
268 ASSERT_NO_FATAL_FAILURE(
269 StartTestWithPage("files/overscroll_navigation.html"));
270 WebContentsImpl
* web_contents
=
271 static_cast<WebContentsImpl
*>(shell()->web_contents());
272 NavigationController
& controller
= web_contents
->GetController();
273 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
275 EXPECT_FALSE(controller
.CanGoBack());
276 EXPECT_FALSE(controller
.CanGoForward());
278 scoped_ptr
<base::Value
> value
=
279 content::ExecuteScriptAndGetValue(main_frame
, "get_current()");
280 ASSERT_TRUE(value
->GetAsInteger(&index
));
284 ExecuteSyncJSFunction(main_frame
, "install_touch_handler()");
286 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
287 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
288 value
= content::ExecuteScriptAndGetValue(main_frame
, "get_current()");
289 ASSERT_TRUE(value
->GetAsInteger(&index
));
291 EXPECT_TRUE(controller
.CanGoBack());
292 EXPECT_FALSE(controller
.CanGoForward());
294 aura::Window
* content
= web_contents
->GetContentNativeView();
295 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
296 ui::test::EventGenerator
generator(content
->GetRootWindow(), content
);
297 const int kScrollDurationMs
= 20;
298 const int kScrollSteps
= 10;
301 // Do a swipe-right now. That should navigate backwards.
302 base::string16 expected_title
= base::ASCIIToUTF16("Title: #1");
303 content::TitleWatcher
title_watcher(web_contents
, expected_title
);
304 generator
.GestureScrollSequence(
305 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
306 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
307 base::TimeDelta::FromMilliseconds(kScrollDurationMs
),
309 base::string16 actual_title
= title_watcher
.WaitAndGetTitle();
310 EXPECT_EQ(expected_title
, actual_title
);
311 value
= content::ExecuteScriptAndGetValue(main_frame
, "get_current()");
312 ASSERT_TRUE(value
->GetAsInteger(&index
));
314 EXPECT_TRUE(controller
.CanGoBack());
315 EXPECT_TRUE(controller
.CanGoForward());
319 // Do a fling-right now. That should navigate backwards.
320 base::string16 expected_title
= base::ASCIIToUTF16("Title:");
321 content::TitleWatcher
title_watcher(web_contents
, expected_title
);
322 generator
.GestureScrollSequence(
323 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
324 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
325 base::TimeDelta::FromMilliseconds(kScrollDurationMs
),
327 base::string16 actual_title
= title_watcher
.WaitAndGetTitle();
328 EXPECT_EQ(expected_title
, actual_title
);
329 value
= content::ExecuteScriptAndGetValue(main_frame
, "get_current()");
330 ASSERT_TRUE(value
->GetAsInteger(&index
));
332 EXPECT_FALSE(controller
.CanGoBack());
333 EXPECT_TRUE(controller
.CanGoForward());
337 // Do a swipe-left now. That should navigate forward.
338 base::string16 expected_title
= base::ASCIIToUTF16("Title: #1");
339 content::TitleWatcher
title_watcher(web_contents
, expected_title
);
340 generator
.GestureScrollSequence(
341 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
342 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
343 base::TimeDelta::FromMilliseconds(kScrollDurationMs
),
345 base::string16 actual_title
= title_watcher
.WaitAndGetTitle();
346 EXPECT_EQ(expected_title
, actual_title
);
347 value
= content::ExecuteScriptAndGetValue(main_frame
, "get_current()");
348 ASSERT_TRUE(value
->GetAsInteger(&index
));
350 EXPECT_TRUE(controller
.CanGoBack());
351 EXPECT_TRUE(controller
.CanGoForward());
355 int GetCurrentIndex() {
356 WebContentsImpl
* web_contents
=
357 static_cast<WebContentsImpl
*>(shell()->web_contents());
358 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
360 scoped_ptr
<base::Value
> value
;
361 value
= content::ExecuteScriptAndGetValue(main_frame
, "get_current()");
362 if (!value
->GetAsInteger(&index
))
367 int ExecuteScriptAndExtractInt(const std::string
& script
) {
369 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
370 shell()->web_contents(),
371 "domAutomationController.send(" + script
+ ")",
376 RenderViewHost
* GetRenderViewHost() const {
377 RenderViewHost
* const rvh
= shell()->web_contents()->GetRenderViewHost();
382 RenderWidgetHostImpl
* GetRenderWidgetHost() const {
383 RenderWidgetHostImpl
* const rwh
=
384 RenderWidgetHostImpl::From(shell()
386 ->GetRenderWidgetHostView()
387 ->GetRenderWidgetHost());
392 RenderWidgetHostViewBase
* GetRenderWidgetHostView() const {
393 return static_cast<RenderWidgetHostViewBase
*>(
394 GetRenderViewHost()->GetView());
397 InputEventMessageFilterWaitsForAcks
* filter() {
398 return filter_
.get();
402 uint32 frame
= GetRenderWidgetHostView()->RendererFrameNumber();
403 while (!GetRenderWidgetHost()->ScheduleComposite())
405 while (GetRenderWidgetHostView()->RendererFrameNumber() == frame
)
410 ScreenshotTracker
* screenshot_manager() { return screenshot_manager_
; }
411 void set_min_screenshot_interval(int interval_ms
) {
412 screenshot_manager_
->SetScreenshotInterval(interval_ms
);
415 void AddInputEventMessageFilter() {
416 filter_
= new InputEventMessageFilterWaitsForAcks();
417 GetRenderWidgetHost()->GetProcess()->AddFilter(filter_
.get());
421 ScreenshotTracker
* screenshot_manager_
;
422 scoped_refptr
<InputEventMessageFilterWaitsForAcks
> filter_
;
424 DISALLOW_COPY_AND_ASSIGN(WebContentsViewAuraTest
);
427 // Flaky on Windows: http://crbug.com/305722
428 // The test frequently times out on Linux, too. See crbug.com/440043.
429 #if defined(OS_WIN) || defined(OS_LINUX)
430 #define MAYBE_OverscrollNavigation DISABLED_OverscrollNavigation
432 #define MAYBE_OverscrollNavigation OverscrollNavigation
435 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
, MAYBE_OverscrollNavigation
) {
436 TestOverscrollNavigation(false);
439 // Flaky on Windows (might be related to the above test):
440 // http://crbug.com/305722
441 // On Linux, the test frequently times out. (See crbug.com/440043).
442 #if defined(OS_WIN) || defined(OS_LINUX)
443 #define MAYBE_OverscrollNavigationWithTouchHandler \
444 DISABLED_OverscrollNavigationWithTouchHandler
446 #define MAYBE_OverscrollNavigationWithTouchHandler \
447 OverscrollNavigationWithTouchHandler
449 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
,
450 MAYBE_OverscrollNavigationWithTouchHandler
) {
451 TestOverscrollNavigation(true);
454 // Disabled because the test always fails the first time it runs on the Win Aura
455 // bots, and usually but not always passes second-try (See crbug.com/179532).
456 // On Linux, the test frequently times out. (See crbug.com/440043).
457 #if defined(OS_WIN) || defined(OS_LINUX)
458 #define MAYBE_QuickOverscrollDirectionChange \
459 DISABLED_QuickOverscrollDirectionChange
461 #define MAYBE_QuickOverscrollDirectionChange QuickOverscrollDirectionChange
463 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
,
464 MAYBE_QuickOverscrollDirectionChange
) {
465 ASSERT_NO_FATAL_FAILURE(
466 StartTestWithPage("files/overscroll_navigation.html"));
467 WebContentsImpl
* web_contents
=
468 static_cast<WebContentsImpl
*>(shell()->web_contents());
469 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
471 // This test triggers a large number of animations. Speed them up to ensure
472 // the test completes within its time limit.
473 ui::ScopedAnimationDurationScaleMode
fast_duration_mode(
474 ui::ScopedAnimationDurationScaleMode::FAST_DURATION
);
476 // Make sure the page has both back/forward history.
477 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
478 EXPECT_EQ(1, GetCurrentIndex());
479 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
480 EXPECT_EQ(2, GetCurrentIndex());
481 web_contents
->GetController().GoBack();
482 EXPECT_EQ(1, GetCurrentIndex());
484 aura::Window
* content
= web_contents
->GetContentNativeView();
485 ui::EventProcessor
* dispatcher
= content
->GetHost()->event_processor();
486 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
488 base::TimeDelta timestamp
= ui::EventTimeForNow();
489 ui::TouchEvent
press(ui::ET_TOUCH_PRESSED
,
490 gfx::Point(bounds
.x() + bounds
.width() / 2, bounds
.y() + 5),
492 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&press
);
493 ASSERT_FALSE(details
.dispatcher_destroyed
);
494 EXPECT_EQ(1, GetCurrentIndex());
496 timestamp
+= base::TimeDelta::FromMilliseconds(10);
497 ui::TouchEvent
move1(ui::ET_TOUCH_MOVED
,
498 gfx::Point(bounds
.right() - 10, bounds
.y() + 5),
500 details
= dispatcher
->OnEventFromSource(&move1
);
501 ASSERT_FALSE(details
.dispatcher_destroyed
);
502 EXPECT_EQ(1, GetCurrentIndex());
504 // Swipe back from the right edge, back to the left edge, back to the right
507 for (int x
= bounds
.right() - 10; x
>= bounds
.x() + 10; x
-= 10) {
508 timestamp
+= base::TimeDelta::FromMilliseconds(10);
509 ui::TouchEvent
inc(ui::ET_TOUCH_MOVED
,
510 gfx::Point(x
, bounds
.y() + 5),
512 details
= dispatcher
->OnEventFromSource(&inc
);
513 ASSERT_FALSE(details
.dispatcher_destroyed
);
514 EXPECT_EQ(1, GetCurrentIndex());
517 for (int x
= bounds
.x() + 10; x
<= bounds
.width() - 10; x
+= 10) {
518 timestamp
+= base::TimeDelta::FromMilliseconds(10);
519 ui::TouchEvent
inc(ui::ET_TOUCH_MOVED
,
520 gfx::Point(x
, bounds
.y() + 5),
522 details
= dispatcher
->OnEventFromSource(&inc
);
523 ASSERT_FALSE(details
.dispatcher_destroyed
);
524 EXPECT_EQ(1, GetCurrentIndex());
527 for (int x
= bounds
.width() - 10; x
>= bounds
.x() + 10; x
-= 10) {
528 timestamp
+= base::TimeDelta::FromMilliseconds(10);
529 ui::TouchEvent
inc(ui::ET_TOUCH_MOVED
,
530 gfx::Point(x
, bounds
.y() + 5),
532 details
= dispatcher
->OnEventFromSource(&inc
);
533 ASSERT_FALSE(details
.dispatcher_destroyed
);
534 EXPECT_EQ(1, GetCurrentIndex());
537 // Do not end the overscroll sequence.
540 // Tests that the page has has a screenshot when navigation happens:
541 // - from within the page (from a JS function)
542 // - interactively, when user does an overscroll gesture
543 // - interactively, when user navigates in history without the overscroll
545 // Flaky on Windows (http://crbug.com/357311). Might be related to
546 // OverscrollNavigation test.
547 // Flaky on Ozone (http://crbug.com/399676).
548 // Flaky on ChromeOS (http://crbug.com/405945).
549 #if defined(OS_WIN) || defined(USE_OZONE) || defined(OS_CHROMEOS)
550 #define MAYBE_OverscrollScreenshot DISABLED_OverscrollScreenshot
552 #define MAYBE_OverscrollScreenshot OverscrollScreenshot
554 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
, MAYBE_OverscrollScreenshot
) {
555 // Disable the test for WinXP. See http://crbug/294116.
557 if (base::win::GetVersion() < base::win::VERSION_VISTA
) {
558 LOG(WARNING
) << "Test disabled due to unknown bug on WinXP.";
563 ASSERT_NO_FATAL_FAILURE(
564 StartTestWithPage("files/overscroll_navigation.html"));
565 WebContentsImpl
* web_contents
=
566 static_cast<WebContentsImpl
*>(shell()->web_contents());
567 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
569 set_min_screenshot_interval(0);
571 // Do a few navigations initiated by the page.
572 // Screenshots should never be captured since these are all in-page
574 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
575 EXPECT_EQ(1, GetCurrentIndex());
576 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
577 EXPECT_EQ(2, GetCurrentIndex());
578 screenshot_manager()->WaitUntilScreenshotIsReady();
580 NavigationEntryImpl
* entry
= web_contents
->GetController().GetEntryAtIndex(2);
581 EXPECT_FALSE(entry
->screenshot().get());
583 entry
= web_contents
->GetController().GetEntryAtIndex(1);
584 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry
));
586 entry
= web_contents
->GetController().GetEntryAtIndex(0);
587 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry
));
589 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
590 screenshot_manager()->WaitUntilScreenshotIsReady();
592 entry
= web_contents
->GetController().GetEntryAtIndex(2);
593 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry
));
595 entry
= web_contents
->GetController().GetEntryAtIndex(3);
596 EXPECT_FALSE(entry
->screenshot().get());
598 // Now, swipe right to navigate backwards. This should navigate away from
599 // index 3 to index 2.
600 base::string16 expected_title
= base::ASCIIToUTF16("Title: #2");
601 content::TitleWatcher
title_watcher(web_contents
, expected_title
);
602 aura::Window
* content
= web_contents
->GetContentNativeView();
603 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
604 ui::test::EventGenerator
generator(content
->GetRootWindow(), content
);
605 generator
.GestureScrollSequence(
606 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
607 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
608 base::TimeDelta::FromMilliseconds(20),
610 base::string16 actual_title
= title_watcher
.WaitAndGetTitle();
611 EXPECT_EQ(expected_title
, actual_title
);
612 EXPECT_EQ(2, GetCurrentIndex());
613 screenshot_manager()->WaitUntilScreenshotIsReady();
614 entry
= web_contents
->GetController().GetEntryAtIndex(3);
615 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry
));
618 // Navigate a couple more times.
619 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
620 EXPECT_EQ(3, GetCurrentIndex());
621 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
622 EXPECT_EQ(4, GetCurrentIndex());
623 screenshot_manager()->WaitUntilScreenshotIsReady();
624 entry
= web_contents
->GetController().GetEntryAtIndex(4);
625 EXPECT_FALSE(entry
->screenshot().get());
628 // Navigate back in history.
629 base::string16 expected_title
= base::ASCIIToUTF16("Title: #3");
630 content::TitleWatcher
title_watcher(web_contents
, expected_title
);
631 web_contents
->GetController().GoBack();
632 base::string16 actual_title
= title_watcher
.WaitAndGetTitle();
633 EXPECT_EQ(expected_title
, actual_title
);
634 EXPECT_EQ(3, GetCurrentIndex());
635 screenshot_manager()->WaitUntilScreenshotIsReady();
636 entry
= web_contents
->GetController().GetEntryAtIndex(4);
637 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry
));
641 // Crashes under ThreadSanitizer, http://crbug.com/356758.
642 #if defined(THREAD_SANITIZER)
643 #define MAYBE_ScreenshotForSwappedOutRenderViews \
644 DISABLED_ScreenshotForSwappedOutRenderViews
646 #define MAYBE_ScreenshotForSwappedOutRenderViews \
647 ScreenshotForSwappedOutRenderViews
649 // Tests that screenshot is taken correctly when navigation causes a
650 // RenderViewHost to be swapped out.
651 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
,
652 MAYBE_ScreenshotForSwappedOutRenderViews
) {
653 ASSERT_NO_FATAL_FAILURE(
654 StartTestWithPage("files/overscroll_navigation.html"));
655 // Create a new server with a different site.
656 net::SpawnedTestServer
https_server(
657 net::SpawnedTestServer::TYPE_HTTPS
,
658 net::SpawnedTestServer::kLocalhost
,
659 base::FilePath(FILE_PATH_LITERAL("content/test/data")));
660 ASSERT_TRUE(https_server
.Start());
662 WebContentsImpl
* web_contents
=
663 static_cast<WebContentsImpl
*>(shell()->web_contents());
664 set_min_screenshot_interval(0);
670 { https_server
.GetURL("files/title1.html"),
671 ui::PAGE_TRANSITION_TYPED
| ui::PAGE_TRANSITION_FROM_ADDRESS_BAR
},
672 { test_server()->GetURL("files/title2.html"),
673 ui::PAGE_TRANSITION_AUTO_BOOKMARK
},
674 { https_server
.GetURL("files/title3.html"),
675 ui::PAGE_TRANSITION_TYPED
| ui::PAGE_TRANSITION_FROM_ADDRESS_BAR
},
679 screenshot_manager()->Reset();
680 for (int i
= 0; !navigations
[i
].url
.is_empty(); ++i
) {
681 // Navigate via the user initiating a navigation from the UI.
682 NavigationController::LoadURLParams
params(navigations
[i
].url
);
683 params
.transition_type
=
684 ui::PageTransitionFromInt(navigations
[i
].transition
);
686 RenderViewHost
* old_host
= web_contents
->GetRenderViewHost();
687 web_contents
->GetController().LoadURLWithParams(params
);
688 WaitForLoadStop(web_contents
);
689 screenshot_manager()->WaitUntilScreenshotIsReady();
691 EXPECT_NE(old_host
, web_contents
->GetRenderViewHost())
692 << navigations
[i
].url
.spec();
693 EXPECT_EQ(old_host
, screenshot_manager()->screenshot_taken_for());
695 NavigationEntryImpl
* entry
=
696 web_contents
->GetController().GetEntryAtOffset(-1);
697 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry
));
699 entry
= web_contents
->GetController().GetLastCommittedEntry();
700 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry
));
701 EXPECT_FALSE(entry
->screenshot().get());
702 screenshot_manager()->Reset();
705 // Increase the minimum interval between taking screenshots.
706 set_min_screenshot_interval(60000);
708 // Navigate again. This should not take any screenshot because of the
709 // increased screenshot interval.
710 NavigationController::LoadURLParams
params(navigations
[0].url
);
711 params
.transition_type
= ui::PageTransitionFromInt(navigations
[0].transition
);
712 web_contents
->GetController().LoadURLWithParams(params
);
713 WaitForLoadStop(web_contents
);
714 screenshot_manager()->WaitUntilScreenshotIsReady();
716 EXPECT_EQ(NULL
, screenshot_manager()->screenshot_taken_for());
719 // Tests that navigations resulting from reloads, history.replaceState,
720 // and history.pushState do not capture screenshots.
721 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
, ReplaceStateReloadPushState
) {
722 ASSERT_NO_FATAL_FAILURE(
723 StartTestWithPage("files/overscroll_navigation.html"));
724 WebContentsImpl
* web_contents
=
725 static_cast<WebContentsImpl
*>(shell()->web_contents());
726 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
728 set_min_screenshot_interval(0);
729 screenshot_manager()->Reset();
730 ExecuteSyncJSFunction(main_frame
, "use_replace_state()");
731 screenshot_manager()->WaitUntilScreenshotIsReady();
732 // history.replaceState shouldn't capture a screenshot
733 EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
734 screenshot_manager()->Reset();
735 web_contents
->GetController().Reload(true);
736 WaitForLoadStop(web_contents
);
737 // reloading the page shouldn't capture a screenshot
738 // TODO (mfomitchev): currently broken. Uncomment when
739 // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
740 // is populated properly when reloading the page.
741 //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
742 screenshot_manager()->Reset();
743 ExecuteSyncJSFunction(main_frame
, "use_push_state()");
744 screenshot_manager()->WaitUntilScreenshotIsReady();
745 // pushing a state shouldn't capture a screenshot
746 // TODO (mfomitchev): currently broken. Uncomment when
747 // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
748 // is populated properly when pushState is used.
749 //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
752 // TODO(sadrul): This test is disabled because it reparents in a way the
753 // FocusController does not support. This code would crash in
754 // a production build. It only passed prior to this revision
755 // because testing used the old FocusManager which did some
756 // different (osbolete) processing. TODO(sadrul) to figure out
757 // how this test should work that mimics production code a bit
759 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
,
760 DISABLED_ContentWindowReparent
) {
761 ASSERT_NO_FATAL_FAILURE(
762 StartTestWithPage("files/overscroll_navigation.html"));
764 scoped_ptr
<aura::Window
> window(new aura::Window(NULL
));
765 window
->Init(ui::LAYER_NOT_DRAWN
);
767 WebContentsImpl
* web_contents
=
768 static_cast<WebContentsImpl
*>(shell()->web_contents());
769 ExecuteSyncJSFunction(web_contents
->GetMainFrame(), "navigate_next()");
770 EXPECT_EQ(1, GetCurrentIndex());
772 aura::Window
* content
= web_contents
->GetContentNativeView();
773 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
774 ui::test::EventGenerator
generator(content
->GetRootWindow(), content
);
775 generator
.GestureScrollSequence(
776 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
777 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
778 base::TimeDelta::FromMilliseconds(20),
781 window
->AddChild(shell()->web_contents()->GetContentNativeView());
784 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
, ContentWindowClose
) {
785 ASSERT_NO_FATAL_FAILURE(
786 StartTestWithPage("files/overscroll_navigation.html"));
788 WebContentsImpl
* web_contents
=
789 static_cast<WebContentsImpl
*>(shell()->web_contents());
790 ExecuteSyncJSFunction(web_contents
->GetMainFrame(), "navigate_next()");
791 EXPECT_EQ(1, GetCurrentIndex());
793 aura::Window
* content
= web_contents
->GetContentNativeView();
794 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
795 ui::test::EventGenerator
generator(content
->GetRootWindow(), content
);
796 generator
.GestureScrollSequence(
797 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
798 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
799 base::TimeDelta::FromMilliseconds(20),
802 delete web_contents
->GetContentNativeView();
806 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
807 // This appears to be flaky in the same was as the other overscroll
808 // tests. Enabling for non-Windows platforms.
809 // See http://crbug.com/369871.
810 // For linux, see http://crbug.com/381294
811 #define MAYBE_RepeatedQuickOverscrollGestures DISABLED_RepeatedQuickOverscrollGestures
813 #define MAYBE_RepeatedQuickOverscrollGestures RepeatedQuickOverscrollGestures
816 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
,
817 MAYBE_RepeatedQuickOverscrollGestures
) {
818 ASSERT_NO_FATAL_FAILURE(
819 StartTestWithPage("files/overscroll_navigation.html"));
821 WebContentsImpl
* web_contents
=
822 static_cast<WebContentsImpl
*>(shell()->web_contents());
823 NavigationController
& controller
= web_contents
->GetController();
824 RenderFrameHost
* main_frame
= web_contents
->GetMainFrame();
825 ExecuteSyncJSFunction(main_frame
, "install_touch_handler()");
827 // Navigate twice, then navigate back in history once.
828 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
829 ExecuteSyncJSFunction(main_frame
, "navigate_next()");
830 EXPECT_EQ(2, GetCurrentIndex());
831 EXPECT_TRUE(controller
.CanGoBack());
832 EXPECT_FALSE(controller
.CanGoForward());
834 web_contents
->GetController().GoBack();
835 WaitForLoadStop(web_contents
);
836 EXPECT_EQ(1, GetCurrentIndex());
837 EXPECT_EQ(base::ASCIIToUTF16("Title: #1"), web_contents
->GetTitle());
838 EXPECT_TRUE(controller
.CanGoBack());
839 EXPECT_TRUE(controller
.CanGoForward());
841 aura::Window
* content
= web_contents
->GetContentNativeView();
842 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
843 ui::test::EventGenerator
generator(content
->GetRootWindow(), content
);
845 // Do a swipe left to start a forward navigation. Then quickly do a swipe
847 base::string16 expected_title
= base::ASCIIToUTF16("Title: #2");
848 content::TitleWatcher
title_watcher(web_contents
, expected_title
);
849 NavigationWatcher
nav_watcher(web_contents
);
851 generator
.GestureScrollSequence(
852 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
853 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
854 base::TimeDelta::FromMilliseconds(2000),
856 nav_watcher
.WaitUntilNavigationStarts();
858 generator
.GestureScrollSequence(
859 gfx::Point(bounds
.x() + 2, bounds
.y() + 10),
860 gfx::Point(bounds
.right() - 10, bounds
.y() + 10),
861 base::TimeDelta::FromMilliseconds(2000),
863 base::string16 actual_title
= title_watcher
.WaitAndGetTitle();
864 EXPECT_EQ(expected_title
, actual_title
);
866 EXPECT_EQ(2, GetCurrentIndex());
867 EXPECT_TRUE(controller
.CanGoBack());
868 EXPECT_FALSE(controller
.CanGoForward());
871 // Verify that hiding a parent of the renderer will hide the content too.
872 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
, HideContentOnParenHide
) {
873 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/title1.html"));
874 WebContentsImpl
* web_contents
=
875 static_cast<WebContentsImpl
*>(shell()->web_contents());
876 aura::Window
* content
= web_contents
->GetNativeView()->parent();
877 EXPECT_TRUE(web_contents
->should_normally_be_visible());
879 EXPECT_FALSE(web_contents
->should_normally_be_visible());
881 EXPECT_TRUE(web_contents
->should_normally_be_visible());
884 // Ensure that SnapToPhysicalPixelBoundary() is called on WebContentsView parent
885 // change. This is a regression test for http://crbug.com/388908.
886 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
, WebContentsViewReparent
) {
887 ASSERT_NO_FATAL_FAILURE(
888 StartTestWithPage("files/overscroll_navigation.html"));
890 scoped_ptr
<aura::Window
> window(new aura::Window(NULL
));
891 window
->Init(ui::LAYER_NOT_DRAWN
);
893 RenderWidgetHostViewAura
* rwhva
=
894 static_cast<RenderWidgetHostViewAura
*>(
895 shell()->web_contents()->GetRenderWidgetHostView());
896 rwhva
->ResetHasSnappedToBoundary();
897 EXPECT_FALSE(rwhva
->has_snapped_to_boundary());
898 window
->AddChild(shell()->web_contents()->GetNativeView());
899 EXPECT_TRUE(rwhva
->has_snapped_to_boundary());
902 // Flaky on some platforms, likely for the same reason as other flaky overscroll
903 // tests. http://crbug.com/305722
904 // TODO(tdresser): Re-enable this once eager GR is back on. See
906 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
907 #define MAYBE_OverscrollNavigationTouchThrottling \
908 DISABLED_OverscrollNavigationTouchThrottling
910 #define MAYBE_OverscrollNavigationTouchThrottling \
911 DISABLED_OverscrollNavigationTouchThrottling
914 // Tests that touch moves are not throttled when performing a scroll gesture on
915 // a non-scrollable area, except during gesture-nav.
916 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
,
917 MAYBE_OverscrollNavigationTouchThrottling
) {
918 ASSERT_NO_FATAL_FAILURE(
919 StartTestWithPage("files/overscroll_navigation.html"));
921 AddInputEventMessageFilter();
923 WebContentsImpl
* web_contents
=
924 static_cast<WebContentsImpl
*>(shell()->web_contents());
925 aura::Window
* content
= web_contents
->GetContentNativeView();
926 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
929 ExecuteSyncJSFunction(web_contents
->GetMainFrame(),
930 "install_touchmove_handler()");
934 for (int navigated
= 0; navigated
<= 1; ++navigated
) {
936 ExecuteSyncJSFunction(web_contents
->GetMainFrame(), "navigate_next()");
937 ExecuteSyncJSFunction(web_contents
->GetMainFrame(),
938 "reset_touchmove_count()");
941 SyntheticWebTouchEvent touch
;
942 touch
.PressPoint(bounds
.x() + 2, bounds
.y() + 10);
943 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch
,
945 filter()->WaitForAck(blink::WebInputEvent::TouchStart
);
948 // Assert on the ack, because we'll end up waiting for acks that will never
949 // come if this is not true.
950 ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED
, filter()->last_ack_state());
952 // Send first touch move, and then a scroll begin.
953 touch
.MovePoint(0, bounds
.x() + 20 + 1 * dx
, bounds
.y() + 100);
954 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch
,
956 filter()->WaitForAck(blink::WebInputEvent::TouchMove
);
957 ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED
, filter()->last_ack_state());
959 blink::WebGestureEvent scroll_begin
=
960 SyntheticWebGestureEventBuilder::BuildScrollBegin(1, 1);
961 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
962 scroll_begin
, ui::LatencyInfo());
963 // Scroll begin ignores ack disposition, so don't wait for the ack.
966 // First touchmove already sent, start at 2.
967 for (int i
= 2; i
<= 10; ++i
) {
968 // Send a touch move, followed by a scroll update
969 touch
.MovePoint(0, bounds
.x() + 20 + i
* dx
, bounds
.y() + 100);
970 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(
971 touch
, ui::LatencyInfo());
974 blink::WebGestureEvent scroll_update
=
975 SyntheticWebGestureEventBuilder::BuildScrollUpdate(
976 dx
, 5, 0, blink::WebGestureDeviceTouchscreen
);
978 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
979 scroll_update
, ui::LatencyInfo());
984 touch
.ReleasePoint(0);
985 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch
,
989 blink::WebGestureEvent scroll_end
;
990 scroll_end
.type
= blink::WebInputEvent::GestureScrollEnd
;
991 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
992 scroll_end
, ui::LatencyInfo());
996 EXPECT_EQ(10, ExecuteScriptAndExtractInt("touchmoveCount"));
998 EXPECT_GT(10, ExecuteScriptAndExtractInt("touchmoveCount"));
1002 // Test that vertical overscroll updates are sent only when a user overscrolls
1005 #define MAYBE_VerticalOverscroll DISABLED_VerticalOverscroll
1007 #define MAYBE_VerticalOverscroll VerticalOverscroll
1010 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest
, MAYBE_VerticalOverscroll
) {
1011 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1012 switches::kScrollEndEffect
, "1");
1014 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("about:blank"));
1015 WebContentsImpl
* web_contents
=
1016 static_cast<WebContentsImpl
*>(shell()->web_contents());
1017 VerticalOverscrollTracker tracker
;
1018 web_contents
->SetDelegate(&tracker
);
1020 // This test triggers a large number of animations. Speed them up to ensure
1021 // the test completes within its time limit.
1022 ui::ScopedAnimationDurationScaleMode
fast_duration_mode(
1023 ui::ScopedAnimationDurationScaleMode::FAST_DURATION
);
1025 aura::Window
* content
= web_contents
->GetContentNativeView();
1026 ui::EventProcessor
* dispatcher
= content
->GetHost()->event_processor();
1027 gfx::Rect bounds
= content
->GetBoundsInRootWindow();
1029 // Overscroll horizontally.
1031 int kXStep
= bounds
.width() / 10;
1032 gfx::Point
location(bounds
.right() - kXStep
, bounds
.y() + 5);
1033 base::TimeDelta timestamp
= ui::EventTimeForNow();
1034 ui::TouchEvent
press(
1035 ui::ET_TOUCH_PRESSED
,
1039 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&press
);
1040 ASSERT_FALSE(details
.dispatcher_destroyed
);
1042 location
-= gfx::Vector2d(kXStep
, 0);
1043 timestamp
+= base::TimeDelta::FromMilliseconds(10);
1045 while (location
.x() > bounds
.x() + kXStep
) {
1046 ui::TouchEvent
inc(ui::ET_TOUCH_MOVED
, location
, 0, timestamp
);
1047 details
= dispatcher
->OnEventFromSource(&inc
);
1048 ASSERT_FALSE(details
.dispatcher_destroyed
);
1050 location
-= gfx::Vector2d(10, 0);
1051 timestamp
+= base::TimeDelta::FromMilliseconds(10);
1054 ui::TouchEvent
release(ui::ET_TOUCH_RELEASED
, location
, 0, timestamp
);
1055 details
= dispatcher
->OnEventFromSource(&release
);
1056 ASSERT_FALSE(details
.dispatcher_destroyed
);
1059 EXPECT_EQ(0, tracker
.num_overscroll_updates());
1060 EXPECT_FALSE(tracker
.overscroll_completed());
1063 // Overscroll vertically.
1067 int kYStep
= bounds
.height() / 10;
1068 gfx::Point
location(bounds
.x() + 10, bounds
.y() + kYStep
);
1069 base::TimeDelta timestamp
= ui::EventTimeForNow();
1070 ui::TouchEvent
press(
1071 ui::ET_TOUCH_PRESSED
,
1075 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&press
);
1076 ASSERT_FALSE(details
.dispatcher_destroyed
);
1078 location
+= gfx::Vector2d(0, kYStep
);
1079 timestamp
+= base::TimeDelta::FromMilliseconds(10);
1081 while (location
.y() < bounds
.bottom() - kYStep
) {
1082 ui::TouchEvent
inc(ui::ET_TOUCH_MOVED
, location
, 0, timestamp
);
1083 details
= dispatcher
->OnEventFromSource(&inc
);
1084 ASSERT_FALSE(details
.dispatcher_destroyed
);
1086 location
+= gfx::Vector2d(0, kYStep
);
1087 timestamp
+= base::TimeDelta::FromMilliseconds(10);
1090 ui::TouchEvent
release(ui::ET_TOUCH_RELEASED
, location
, 0, timestamp
);
1091 details
= dispatcher
->OnEventFromSource(&release
);
1092 ASSERT_FALSE(details
.dispatcher_destroyed
);
1095 EXPECT_LT(0, tracker
.num_overscroll_updates());
1096 EXPECT_TRUE(tracker
.overscroll_completed());
1099 // Start out overscrolling vertically, then switch directions and finish
1100 // overscrolling horizontally.
1104 int kXStep
= bounds
.width() / 10;
1105 int kYStep
= bounds
.height() / 10;
1106 gfx::Point location
= bounds
.origin() + gfx::Vector2d(0, kYStep
);
1107 base::TimeDelta timestamp
= ui::EventTimeForNow();
1108 ui::TouchEvent
press(
1109 ui::ET_TOUCH_PRESSED
,
1113 ui::EventDispatchDetails details
= dispatcher
->OnEventFromSource(&press
);
1114 ASSERT_FALSE(details
.dispatcher_destroyed
);
1116 location
+= gfx::Vector2d(0, kYStep
);
1117 timestamp
+= base::TimeDelta::FromMilliseconds(10);
1119 for (size_t i
= 0; i
< 3; ++i
) {
1120 ui::TouchEvent
inc(ui::ET_TOUCH_MOVED
, location
, 0, timestamp
);
1121 details
= dispatcher
->OnEventFromSource(&inc
);
1122 ASSERT_FALSE(details
.dispatcher_destroyed
);
1124 location
+= gfx::Vector2d(0, kYStep
);
1125 timestamp
+= base::TimeDelta::FromMilliseconds(10);
1128 while (location
.x() < bounds
.right() - kXStep
) {
1129 ui::TouchEvent
inc(ui::ET_TOUCH_MOVED
, location
, 0, timestamp
);
1130 details
= dispatcher
->OnEventFromSource(&inc
);
1131 ASSERT_FALSE(details
.dispatcher_destroyed
);
1133 location
+= gfx::Vector2d(kXStep
, 0);
1134 timestamp
+= base::TimeDelta::FromMilliseconds(10);
1137 ui::TouchEvent
release(ui::ET_TOUCH_RELEASED
, location
, 0, timestamp
);
1138 details
= dispatcher
->OnEventFromSource(&release
);
1139 ASSERT_FALSE(details
.dispatcher_destroyed
);
1142 EXPECT_LT(0, tracker
.num_overscroll_updates());
1143 EXPECT_FALSE(tracker
.overscroll_completed());
1147 } // namespace content