chrome/browser/extensions: Remove use of MessageLoopProxy and deprecated MessageLoop...
[chromium-blink-merge.git] / content / browser / web_contents / web_contents_view_aura_browsertest.cc
blobe9ba331d3c41620e6ff7966a68585711f1f0df7e
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/location.h"
9 #include "base/run_loop.h"
10 #include "base/single_thread_task_runner.h"
11 #include "base/strings/utf_string_conversions.h"
12 #include "base/test/test_timeouts.h"
13 #include "base/thread_task_runner_handle.h"
14 #include "base/values.h"
15 #if defined(OS_WIN)
16 #include "base/win/windows_version.h"
17 #endif
18 #include "content/browser/frame_host/navigation_controller_impl.h"
19 #include "content/browser/frame_host/navigation_entry_impl.h"
20 #include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
21 #include "content/browser/renderer_host/render_widget_host_view_aura.h"
22 #include "content/browser/web_contents/web_contents_impl.h"
23 #include "content/browser/web_contents/web_contents_view.h"
24 #include "content/common/input/synthetic_web_input_event_builders.h"
25 #include "content/common/input_messages.h"
26 #include "content/common/view_messages.h"
27 #include "content/public/browser/browser_message_filter.h"
28 #include "content/public/browser/render_frame_host.h"
29 #include "content/public/browser/web_contents_delegate.h"
30 #include "content/public/browser/web_contents_observer.h"
31 #include "content/public/common/content_switches.h"
32 #include "content/public/test/browser_test_utils.h"
33 #include "content/public/test/content_browser_test.h"
34 #include "content/public/test/content_browser_test_utils.h"
35 #include "content/public/test/test_renderer_host.h"
36 #include "content/public/test/test_utils.h"
37 #include "content/shell/browser/shell.h"
38 #include "ui/aura/window.h"
39 #include "ui/aura/window_tree_host.h"
40 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
41 #include "ui/events/event_processor.h"
42 #include "ui/events/event_switches.h"
43 #include "ui/events/event_utils.h"
44 #include "ui/events/test/event_generator.h"
46 namespace {
48 // TODO(tdresser): Find a way to avoid sleeping like this. See crbug.com/405282
49 // for details.
50 void GiveItSomeTime() {
51 base::RunLoop run_loop;
52 base::ThreadTaskRunnerHandle::Get()->PostDelayedTask(
53 FROM_HERE, run_loop.QuitClosure(),
54 base::TimeDelta::FromMillisecondsD(10));
55 run_loop.Run();
58 // WebContentsDelegate which tracks vertical overscroll updates.
59 class VerticalOverscrollTracker : public content::WebContentsDelegate {
60 public:
61 VerticalOverscrollTracker() : count_(0), completed_(false) {}
62 ~VerticalOverscrollTracker() override {}
64 int num_overscroll_updates() const {
65 return count_;
68 bool overscroll_completed() const {
69 return completed_;
72 void Reset() {
73 count_ = 0;
74 completed_ = false;
77 private:
78 bool CanOverscrollContent() const override { return true; }
80 void OverscrollUpdate(float delta_y) override { ++count_; }
82 void OverscrollComplete() override { completed_ = true; }
84 int count_;
85 bool completed_;
87 DISALLOW_COPY_AND_ASSIGN(VerticalOverscrollTracker);
90 } //namespace
93 namespace content {
95 // This class keeps track of the RenderViewHost whose screenshot was captured.
96 class ScreenshotTracker : public NavigationEntryScreenshotManager {
97 public:
98 explicit ScreenshotTracker(NavigationControllerImpl* controller)
99 : NavigationEntryScreenshotManager(controller),
100 screenshot_taken_for_(NULL),
101 waiting_for_screenshots_(0) {
104 ~ScreenshotTracker() override {}
106 RenderViewHost* screenshot_taken_for() { return screenshot_taken_for_; }
108 void Reset() {
109 screenshot_taken_for_ = NULL;
110 screenshot_set_.clear();
113 void SetScreenshotInterval(int interval_ms) {
114 SetMinScreenshotIntervalMS(interval_ms);
117 void WaitUntilScreenshotIsReady() {
118 if (!waiting_for_screenshots_)
119 return;
120 message_loop_runner_ = new content::MessageLoopRunner;
121 message_loop_runner_->Run();
124 bool ScreenshotSetForEntry(NavigationEntryImpl* entry) const {
125 return screenshot_set_.count(entry) > 0;
128 private:
129 // Overridden from NavigationEntryScreenshotManager:
130 void TakeScreenshotImpl(RenderViewHost* host,
131 NavigationEntryImpl* entry) override {
132 ++waiting_for_screenshots_;
133 screenshot_taken_for_ = host;
134 NavigationEntryScreenshotManager::TakeScreenshotImpl(host, entry);
137 void OnScreenshotSet(NavigationEntryImpl* entry) override {
138 --waiting_for_screenshots_;
139 screenshot_set_[entry] = true;
140 NavigationEntryScreenshotManager::OnScreenshotSet(entry);
141 if (waiting_for_screenshots_ == 0 && message_loop_runner_.get())
142 message_loop_runner_->Quit();
145 RenderViewHost* screenshot_taken_for_;
146 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
147 int waiting_for_screenshots_;
148 std::map<NavigationEntryImpl*, bool> screenshot_set_;
150 DISALLOW_COPY_AND_ASSIGN(ScreenshotTracker);
153 class NavigationWatcher : public WebContentsObserver {
154 public:
155 explicit NavigationWatcher(WebContents* contents)
156 : WebContentsObserver(contents),
157 navigated_(false),
158 should_quit_loop_(false) {
161 ~NavigationWatcher() override {}
163 void WaitUntilNavigationStarts() {
164 if (navigated_)
165 return;
166 should_quit_loop_ = true;
167 base::MessageLoop::current()->Run();
170 private:
171 // Overridden from WebContentsObserver:
172 void DidStartNavigationToPendingEntry(
173 const GURL& validated_url,
174 NavigationController::ReloadType reload_type) override {
175 navigated_ = true;
176 if (should_quit_loop_)
177 base::MessageLoop::current()->Quit();
180 bool navigated_;
181 bool should_quit_loop_;
183 DISALLOW_COPY_AND_ASSIGN(NavigationWatcher);
186 class InputEventMessageFilterWaitsForAcks : public BrowserMessageFilter {
187 public:
188 InputEventMessageFilterWaitsForAcks()
189 : BrowserMessageFilter(InputMsgStart),
190 type_(blink::WebInputEvent::Undefined),
191 state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
193 void WaitForAck(blink::WebInputEvent::Type type) {
194 base::RunLoop run_loop;
195 base::AutoReset<base::Closure> reset_quit(&quit_, run_loop.QuitClosure());
196 base::AutoReset<blink::WebInputEvent::Type> reset_type(&type_, type);
197 run_loop.Run();
200 InputEventAckState last_ack_state() const { return state_; }
202 protected:
203 ~InputEventMessageFilterWaitsForAcks() override {}
205 private:
206 void ReceivedEventAck(blink::WebInputEvent::Type type,
207 InputEventAckState state) {
208 if (type_ == type) {
209 state_ = state;
210 quit_.Run();
214 // BrowserMessageFilter:
215 bool OnMessageReceived(const IPC::Message& message) override {
216 if (message.type() == InputHostMsg_HandleInputEvent_ACK::ID) {
217 InputHostMsg_HandleInputEvent_ACK::Param params;
218 InputHostMsg_HandleInputEvent_ACK::Read(&message, &params);
219 blink::WebInputEvent::Type type = base::get<0>(params).type;
220 InputEventAckState ack = base::get<0>(params).state;
221 BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
222 base::Bind(&InputEventMessageFilterWaitsForAcks::ReceivedEventAck,
223 this, type, ack));
225 return false;
228 base::Closure quit_;
229 blink::WebInputEvent::Type type_;
230 InputEventAckState state_;
232 DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilterWaitsForAcks);
235 class WebContentsViewAuraTest : public ContentBrowserTest {
236 public:
237 WebContentsViewAuraTest()
238 : screenshot_manager_(NULL) {
241 // Executes the javascript synchronously and makes sure the returned value is
242 // freed properly.
243 void ExecuteSyncJSFunction(RenderFrameHost* rfh, const std::string& jscript) {
244 scoped_ptr<base::Value> value =
245 content::ExecuteScriptAndGetValue(rfh, jscript);
248 // Starts the test server and navigates to the given url. Sets a large enough
249 // size to the root window. Returns after the navigation to the url is
250 // complete.
251 void StartTestWithPage(const std::string& url) {
252 ASSERT_TRUE(test_server()->Start());
253 GURL test_url(test_server()->GetURL(url));
254 NavigateToURL(shell(), test_url);
256 WebContentsImpl* web_contents =
257 static_cast<WebContentsImpl*>(shell()->web_contents());
258 NavigationControllerImpl* controller = &web_contents->GetController();
260 screenshot_manager_ = new ScreenshotTracker(controller);
261 controller->SetScreenshotManager(screenshot_manager_);
264 void SetUpCommandLine(base::CommandLine* cmd) override {
265 cmd->AppendSwitchASCII(switches::kTouchEvents,
266 switches::kTouchEventsEnabled);
269 void TestOverscrollNavigation(bool touch_handler) {
270 ASSERT_NO_FATAL_FAILURE(
271 StartTestWithPage("files/overscroll_navigation.html"));
272 WebContentsImpl* web_contents =
273 static_cast<WebContentsImpl*>(shell()->web_contents());
274 NavigationController& controller = web_contents->GetController();
275 RenderFrameHost* main_frame = web_contents->GetMainFrame();
277 EXPECT_FALSE(controller.CanGoBack());
278 EXPECT_FALSE(controller.CanGoForward());
279 int index = -1;
280 scoped_ptr<base::Value> value =
281 content::ExecuteScriptAndGetValue(main_frame, "get_current()");
282 ASSERT_TRUE(value->GetAsInteger(&index));
283 EXPECT_EQ(0, index);
285 if (touch_handler)
286 ExecuteSyncJSFunction(main_frame, "install_touch_handler()");
288 ExecuteSyncJSFunction(main_frame, "navigate_next()");
289 ExecuteSyncJSFunction(main_frame, "navigate_next()");
290 value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
291 ASSERT_TRUE(value->GetAsInteger(&index));
292 EXPECT_EQ(2, index);
293 EXPECT_TRUE(controller.CanGoBack());
294 EXPECT_FALSE(controller.CanGoForward());
296 aura::Window* content = web_contents->GetContentNativeView();
297 gfx::Rect bounds = content->GetBoundsInRootWindow();
298 ui::test::EventGenerator generator(content->GetRootWindow(), content);
299 const int kScrollDurationMs = 20;
300 const int kScrollSteps = 10;
303 // Do a swipe-right now. That should navigate backwards.
304 base::string16 expected_title = base::ASCIIToUTF16("Title: #1");
305 content::TitleWatcher title_watcher(web_contents, expected_title);
306 generator.GestureScrollSequence(
307 gfx::Point(bounds.x() + 2, bounds.y() + 10),
308 gfx::Point(bounds.right() - 10, bounds.y() + 10),
309 base::TimeDelta::FromMilliseconds(kScrollDurationMs),
310 kScrollSteps);
311 base::string16 actual_title = title_watcher.WaitAndGetTitle();
312 EXPECT_EQ(expected_title, actual_title);
313 value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
314 ASSERT_TRUE(value->GetAsInteger(&index));
315 EXPECT_EQ(1, index);
316 EXPECT_TRUE(controller.CanGoBack());
317 EXPECT_TRUE(controller.CanGoForward());
321 // Do a fling-right now. That should navigate backwards.
322 base::string16 expected_title = base::ASCIIToUTF16("Title:");
323 content::TitleWatcher title_watcher(web_contents, expected_title);
324 generator.GestureScrollSequence(
325 gfx::Point(bounds.x() + 2, bounds.y() + 10),
326 gfx::Point(bounds.right() - 10, bounds.y() + 10),
327 base::TimeDelta::FromMilliseconds(kScrollDurationMs),
328 kScrollSteps);
329 base::string16 actual_title = title_watcher.WaitAndGetTitle();
330 EXPECT_EQ(expected_title, actual_title);
331 value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
332 ASSERT_TRUE(value->GetAsInteger(&index));
333 EXPECT_EQ(0, index);
334 EXPECT_FALSE(controller.CanGoBack());
335 EXPECT_TRUE(controller.CanGoForward());
339 // Do a swipe-left now. That should navigate forward.
340 base::string16 expected_title = base::ASCIIToUTF16("Title: #1");
341 content::TitleWatcher title_watcher(web_contents, expected_title);
342 generator.GestureScrollSequence(
343 gfx::Point(bounds.right() - 10, bounds.y() + 10),
344 gfx::Point(bounds.x() + 2, bounds.y() + 10),
345 base::TimeDelta::FromMilliseconds(kScrollDurationMs),
346 kScrollSteps);
347 base::string16 actual_title = title_watcher.WaitAndGetTitle();
348 EXPECT_EQ(expected_title, actual_title);
349 value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
350 ASSERT_TRUE(value->GetAsInteger(&index));
351 EXPECT_EQ(1, index);
352 EXPECT_TRUE(controller.CanGoBack());
353 EXPECT_TRUE(controller.CanGoForward());
357 int GetCurrentIndex() {
358 WebContentsImpl* web_contents =
359 static_cast<WebContentsImpl*>(shell()->web_contents());
360 RenderFrameHost* main_frame = web_contents->GetMainFrame();
361 int index = -1;
362 scoped_ptr<base::Value> value;
363 value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
364 if (!value->GetAsInteger(&index))
365 index = -1;
366 return index;
369 int ExecuteScriptAndExtractInt(const std::string& script) {
370 int value = 0;
371 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
372 shell()->web_contents(),
373 "domAutomationController.send(" + script + ")",
374 &value));
375 return value;
378 RenderViewHost* GetRenderViewHost() const {
379 RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
380 CHECK(rvh);
381 return rvh;
384 RenderWidgetHostImpl* GetRenderWidgetHost() const {
385 RenderWidgetHostImpl* const rwh =
386 RenderWidgetHostImpl::From(shell()
387 ->web_contents()
388 ->GetRenderWidgetHostView()
389 ->GetRenderWidgetHost());
390 CHECK(rwh);
391 return rwh;
394 RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
395 return static_cast<RenderWidgetHostViewBase*>(
396 GetRenderViewHost()->GetView());
399 InputEventMessageFilterWaitsForAcks* filter() {
400 return filter_.get();
403 void WaitAFrame() {
404 uint32 frame = GetRenderWidgetHostView()->RendererFrameNumber();
405 while (!GetRenderWidgetHost()->ScheduleComposite())
406 GiveItSomeTime();
407 while (GetRenderWidgetHostView()->RendererFrameNumber() == frame)
408 GiveItSomeTime();
411 protected:
412 ScreenshotTracker* screenshot_manager() { return screenshot_manager_; }
413 void set_min_screenshot_interval(int interval_ms) {
414 screenshot_manager_->SetScreenshotInterval(interval_ms);
417 void AddInputEventMessageFilter() {
418 filter_ = new InputEventMessageFilterWaitsForAcks();
419 GetRenderWidgetHost()->GetProcess()->AddFilter(filter_.get());
422 private:
423 ScreenshotTracker* screenshot_manager_;
424 scoped_refptr<InputEventMessageFilterWaitsForAcks> filter_;
426 DISALLOW_COPY_AND_ASSIGN(WebContentsViewAuraTest);
429 // Flaky on Windows: http://crbug.com/305722
430 // The test frequently times out on Linux, too. See crbug.com/440043.
431 #if defined(OS_WIN) || defined(OS_LINUX)
432 #define MAYBE_OverscrollNavigation DISABLED_OverscrollNavigation
433 #else
434 #define MAYBE_OverscrollNavigation OverscrollNavigation
435 #endif
437 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollNavigation) {
438 TestOverscrollNavigation(false);
441 // Flaky on Windows (might be related to the above test):
442 // http://crbug.com/305722
443 // On Linux, the test frequently times out. (See crbug.com/440043).
444 #if defined(OS_WIN) || defined(OS_LINUX)
445 #define MAYBE_OverscrollNavigationWithTouchHandler \
446 DISABLED_OverscrollNavigationWithTouchHandler
447 #else
448 #define MAYBE_OverscrollNavigationWithTouchHandler \
449 OverscrollNavigationWithTouchHandler
450 #endif
451 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
452 MAYBE_OverscrollNavigationWithTouchHandler) {
453 TestOverscrollNavigation(true);
456 // Disabled because the test always fails the first time it runs on the Win Aura
457 // bots, and usually but not always passes second-try (See crbug.com/179532).
458 // On Linux, the test frequently times out. (See crbug.com/440043).
459 #if defined(OS_WIN) || defined(OS_LINUX)
460 #define MAYBE_QuickOverscrollDirectionChange \
461 DISABLED_QuickOverscrollDirectionChange
462 #else
463 #define MAYBE_QuickOverscrollDirectionChange QuickOverscrollDirectionChange
464 #endif
465 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
466 MAYBE_QuickOverscrollDirectionChange) {
467 ASSERT_NO_FATAL_FAILURE(
468 StartTestWithPage("files/overscroll_navigation.html"));
469 WebContentsImpl* web_contents =
470 static_cast<WebContentsImpl*>(shell()->web_contents());
471 RenderFrameHost* main_frame = web_contents->GetMainFrame();
473 // This test triggers a large number of animations. Speed them up to ensure
474 // the test completes within its time limit.
475 ui::ScopedAnimationDurationScaleMode fast_duration_mode(
476 ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
478 // Make sure the page has both back/forward history.
479 ExecuteSyncJSFunction(main_frame, "navigate_next()");
480 EXPECT_EQ(1, GetCurrentIndex());
481 ExecuteSyncJSFunction(main_frame, "navigate_next()");
482 EXPECT_EQ(2, GetCurrentIndex());
483 web_contents->GetController().GoBack();
484 EXPECT_EQ(1, GetCurrentIndex());
486 aura::Window* content = web_contents->GetContentNativeView();
487 ui::EventProcessor* dispatcher = content->GetHost()->event_processor();
488 gfx::Rect bounds = content->GetBoundsInRootWindow();
490 base::TimeDelta timestamp = ui::EventTimeForNow();
491 ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
492 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
493 0, timestamp);
494 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
495 ASSERT_FALSE(details.dispatcher_destroyed);
496 EXPECT_EQ(1, GetCurrentIndex());
498 timestamp += base::TimeDelta::FromMilliseconds(10);
499 ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
500 gfx::Point(bounds.right() - 10, bounds.y() + 5),
501 0, timestamp);
502 details = dispatcher->OnEventFromSource(&move1);
503 ASSERT_FALSE(details.dispatcher_destroyed);
504 EXPECT_EQ(1, GetCurrentIndex());
506 // Swipe back from the right edge, back to the left edge, back to the right
507 // edge.
509 for (int x = bounds.right() - 10; x >= bounds.x() + 10; x-= 10) {
510 timestamp += base::TimeDelta::FromMilliseconds(10);
511 ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
512 gfx::Point(x, bounds.y() + 5),
513 0, timestamp);
514 details = dispatcher->OnEventFromSource(&inc);
515 ASSERT_FALSE(details.dispatcher_destroyed);
516 EXPECT_EQ(1, GetCurrentIndex());
519 for (int x = bounds.x() + 10; x <= bounds.width() - 10; x+= 10) {
520 timestamp += base::TimeDelta::FromMilliseconds(10);
521 ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
522 gfx::Point(x, bounds.y() + 5),
523 0, timestamp);
524 details = dispatcher->OnEventFromSource(&inc);
525 ASSERT_FALSE(details.dispatcher_destroyed);
526 EXPECT_EQ(1, GetCurrentIndex());
529 for (int x = bounds.width() - 10; x >= bounds.x() + 10; x-= 10) {
530 timestamp += base::TimeDelta::FromMilliseconds(10);
531 ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
532 gfx::Point(x, bounds.y() + 5),
533 0, timestamp);
534 details = dispatcher->OnEventFromSource(&inc);
535 ASSERT_FALSE(details.dispatcher_destroyed);
536 EXPECT_EQ(1, GetCurrentIndex());
539 // Do not end the overscroll sequence.
542 // Tests that the page has has a screenshot when navigation happens:
543 // - from within the page (from a JS function)
544 // - interactively, when user does an overscroll gesture
545 // - interactively, when user navigates in history without the overscroll
546 // gesture.
547 // Flaky on Windows (http://crbug.com/357311). Might be related to
548 // OverscrollNavigation test.
549 // Flaky on Ozone (http://crbug.com/399676).
550 // Flaky on ChromeOS (http://crbug.com/405945).
551 #if defined(OS_WIN) || defined(USE_OZONE) || defined(OS_CHROMEOS)
552 #define MAYBE_OverscrollScreenshot DISABLED_OverscrollScreenshot
553 #else
554 #define MAYBE_OverscrollScreenshot OverscrollScreenshot
555 #endif
556 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollScreenshot) {
557 // Disable the test for WinXP. See http://crbug/294116.
558 #if defined(OS_WIN)
559 if (base::win::GetVersion() < base::win::VERSION_VISTA) {
560 LOG(WARNING) << "Test disabled due to unknown bug on WinXP.";
561 return;
563 #endif
565 ASSERT_NO_FATAL_FAILURE(
566 StartTestWithPage("files/overscroll_navigation.html"));
567 WebContentsImpl* web_contents =
568 static_cast<WebContentsImpl*>(shell()->web_contents());
569 RenderFrameHost* main_frame = web_contents->GetMainFrame();
571 set_min_screenshot_interval(0);
573 // Do a few navigations initiated by the page.
574 // Screenshots should never be captured since these are all in-page
575 // navigations.
576 ExecuteSyncJSFunction(main_frame, "navigate_next()");
577 EXPECT_EQ(1, GetCurrentIndex());
578 ExecuteSyncJSFunction(main_frame, "navigate_next()");
579 EXPECT_EQ(2, GetCurrentIndex());
580 screenshot_manager()->WaitUntilScreenshotIsReady();
582 NavigationEntryImpl* entry = web_contents->GetController().GetEntryAtIndex(2);
583 EXPECT_FALSE(entry->screenshot().get());
585 entry = web_contents->GetController().GetEntryAtIndex(1);
586 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
588 entry = web_contents->GetController().GetEntryAtIndex(0);
589 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
591 ExecuteSyncJSFunction(main_frame, "navigate_next()");
592 screenshot_manager()->WaitUntilScreenshotIsReady();
594 entry = web_contents->GetController().GetEntryAtIndex(2);
595 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
597 entry = web_contents->GetController().GetEntryAtIndex(3);
598 EXPECT_FALSE(entry->screenshot().get());
600 // Now, swipe right to navigate backwards. This should navigate away from
601 // index 3 to index 2.
602 base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
603 content::TitleWatcher title_watcher(web_contents, expected_title);
604 aura::Window* content = web_contents->GetContentNativeView();
605 gfx::Rect bounds = content->GetBoundsInRootWindow();
606 ui::test::EventGenerator generator(content->GetRootWindow(), content);
607 generator.GestureScrollSequence(
608 gfx::Point(bounds.x() + 2, bounds.y() + 10),
609 gfx::Point(bounds.right() - 10, bounds.y() + 10),
610 base::TimeDelta::FromMilliseconds(20),
612 base::string16 actual_title = title_watcher.WaitAndGetTitle();
613 EXPECT_EQ(expected_title, actual_title);
614 EXPECT_EQ(2, GetCurrentIndex());
615 screenshot_manager()->WaitUntilScreenshotIsReady();
616 entry = web_contents->GetController().GetEntryAtIndex(3);
617 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
620 // Navigate a couple more times.
621 ExecuteSyncJSFunction(main_frame, "navigate_next()");
622 EXPECT_EQ(3, GetCurrentIndex());
623 ExecuteSyncJSFunction(main_frame, "navigate_next()");
624 EXPECT_EQ(4, GetCurrentIndex());
625 screenshot_manager()->WaitUntilScreenshotIsReady();
626 entry = web_contents->GetController().GetEntryAtIndex(4);
627 EXPECT_FALSE(entry->screenshot().get());
630 // Navigate back in history.
631 base::string16 expected_title = base::ASCIIToUTF16("Title: #3");
632 content::TitleWatcher title_watcher(web_contents, expected_title);
633 web_contents->GetController().GoBack();
634 base::string16 actual_title = title_watcher.WaitAndGetTitle();
635 EXPECT_EQ(expected_title, actual_title);
636 EXPECT_EQ(3, GetCurrentIndex());
637 screenshot_manager()->WaitUntilScreenshotIsReady();
638 entry = web_contents->GetController().GetEntryAtIndex(4);
639 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
643 // Crashes under ThreadSanitizer, http://crbug.com/356758.
644 #if defined(THREAD_SANITIZER)
645 #define MAYBE_ScreenshotForSwappedOutRenderViews \
646 DISABLED_ScreenshotForSwappedOutRenderViews
647 #else
648 #define MAYBE_ScreenshotForSwappedOutRenderViews \
649 ScreenshotForSwappedOutRenderViews
650 #endif
651 // Tests that screenshot is taken correctly when navigation causes a
652 // RenderViewHost to be swapped out.
653 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
654 MAYBE_ScreenshotForSwappedOutRenderViews) {
655 ASSERT_NO_FATAL_FAILURE(
656 StartTestWithPage("files/overscroll_navigation.html"));
657 // Create a new server with a different site.
658 net::SpawnedTestServer https_server(
659 net::SpawnedTestServer::TYPE_HTTPS,
660 net::SpawnedTestServer::kLocalhost,
661 base::FilePath(FILE_PATH_LITERAL("content/test/data")));
662 ASSERT_TRUE(https_server.Start());
664 WebContentsImpl* web_contents =
665 static_cast<WebContentsImpl*>(shell()->web_contents());
666 set_min_screenshot_interval(0);
668 struct {
669 GURL url;
670 int transition;
671 } navigations[] = {
672 { https_server.GetURL("files/title1.html"),
673 ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
674 { test_server()->GetURL("files/title2.html"),
675 ui::PAGE_TRANSITION_AUTO_BOOKMARK },
676 { https_server.GetURL("files/title3.html"),
677 ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
678 { GURL(), 0 }
681 screenshot_manager()->Reset();
682 for (int i = 0; !navigations[i].url.is_empty(); ++i) {
683 // Navigate via the user initiating a navigation from the UI.
684 NavigationController::LoadURLParams params(navigations[i].url);
685 params.transition_type =
686 ui::PageTransitionFromInt(navigations[i].transition);
688 RenderViewHost* old_host = web_contents->GetRenderViewHost();
689 web_contents->GetController().LoadURLWithParams(params);
690 WaitForLoadStop(web_contents);
691 screenshot_manager()->WaitUntilScreenshotIsReady();
693 EXPECT_NE(old_host, web_contents->GetRenderViewHost())
694 << navigations[i].url.spec();
695 EXPECT_EQ(old_host, screenshot_manager()->screenshot_taken_for());
697 NavigationEntryImpl* entry =
698 web_contents->GetController().GetEntryAtOffset(-1);
699 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
701 entry = web_contents->GetController().GetLastCommittedEntry();
702 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
703 EXPECT_FALSE(entry->screenshot().get());
704 screenshot_manager()->Reset();
707 // Increase the minimum interval between taking screenshots.
708 set_min_screenshot_interval(60000);
710 // Navigate again. This should not take any screenshot because of the
711 // increased screenshot interval.
712 NavigationController::LoadURLParams params(navigations[0].url);
713 params.transition_type = ui::PageTransitionFromInt(navigations[0].transition);
714 web_contents->GetController().LoadURLWithParams(params);
715 WaitForLoadStop(web_contents);
716 screenshot_manager()->WaitUntilScreenshotIsReady();
718 EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
721 // Tests that navigations resulting from reloads, history.replaceState,
722 // and history.pushState do not capture screenshots.
723 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ReplaceStateReloadPushState) {
724 ASSERT_NO_FATAL_FAILURE(
725 StartTestWithPage("files/overscroll_navigation.html"));
726 WebContentsImpl* web_contents =
727 static_cast<WebContentsImpl*>(shell()->web_contents());
728 RenderFrameHost* main_frame = web_contents->GetMainFrame();
730 set_min_screenshot_interval(0);
731 screenshot_manager()->Reset();
732 ExecuteSyncJSFunction(main_frame, "use_replace_state()");
733 screenshot_manager()->WaitUntilScreenshotIsReady();
734 // history.replaceState shouldn't capture a screenshot
735 EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
736 screenshot_manager()->Reset();
737 web_contents->GetController().Reload(true);
738 WaitForLoadStop(web_contents);
739 // reloading the page shouldn't capture a screenshot
740 // TODO (mfomitchev): currently broken. Uncomment when
741 // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
742 // is populated properly when reloading the page.
743 //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
744 screenshot_manager()->Reset();
745 ExecuteSyncJSFunction(main_frame, "use_push_state()");
746 screenshot_manager()->WaitUntilScreenshotIsReady();
747 // pushing a state shouldn't capture a screenshot
748 // TODO (mfomitchev): currently broken. Uncomment when
749 // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
750 // is populated properly when pushState is used.
751 //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
754 // TODO(sadrul): This test is disabled because it reparents in a way the
755 // FocusController does not support. This code would crash in
756 // a production build. It only passed prior to this revision
757 // because testing used the old FocusManager which did some
758 // different (osbolete) processing. TODO(sadrul) to figure out
759 // how this test should work that mimics production code a bit
760 // better.
761 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
762 DISABLED_ContentWindowReparent) {
763 ASSERT_NO_FATAL_FAILURE(
764 StartTestWithPage("files/overscroll_navigation.html"));
766 scoped_ptr<aura::Window> window(new aura::Window(NULL));
767 window->Init(ui::LAYER_NOT_DRAWN);
769 WebContentsImpl* web_contents =
770 static_cast<WebContentsImpl*>(shell()->web_contents());
771 ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
772 EXPECT_EQ(1, GetCurrentIndex());
774 aura::Window* content = web_contents->GetContentNativeView();
775 gfx::Rect bounds = content->GetBoundsInRootWindow();
776 ui::test::EventGenerator generator(content->GetRootWindow(), content);
777 generator.GestureScrollSequence(
778 gfx::Point(bounds.x() + 2, bounds.y() + 10),
779 gfx::Point(bounds.right() - 10, bounds.y() + 10),
780 base::TimeDelta::FromMilliseconds(20),
783 window->AddChild(shell()->web_contents()->GetContentNativeView());
786 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ContentWindowClose) {
787 ASSERT_NO_FATAL_FAILURE(
788 StartTestWithPage("files/overscroll_navigation.html"));
790 WebContentsImpl* web_contents =
791 static_cast<WebContentsImpl*>(shell()->web_contents());
792 ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
793 EXPECT_EQ(1, GetCurrentIndex());
795 aura::Window* content = web_contents->GetContentNativeView();
796 gfx::Rect bounds = content->GetBoundsInRootWindow();
797 ui::test::EventGenerator generator(content->GetRootWindow(), content);
798 generator.GestureScrollSequence(
799 gfx::Point(bounds.x() + 2, bounds.y() + 10),
800 gfx::Point(bounds.right() - 10, bounds.y() + 10),
801 base::TimeDelta::FromMilliseconds(20),
804 delete web_contents->GetContentNativeView();
808 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
809 // This appears to be flaky in the same was as the other overscroll
810 // tests. Enabling for non-Windows platforms.
811 // See http://crbug.com/369871.
812 // For linux, see http://crbug.com/381294
813 #define MAYBE_RepeatedQuickOverscrollGestures DISABLED_RepeatedQuickOverscrollGestures
814 #else
815 #define MAYBE_RepeatedQuickOverscrollGestures RepeatedQuickOverscrollGestures
816 #endif
818 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
819 MAYBE_RepeatedQuickOverscrollGestures) {
820 ASSERT_NO_FATAL_FAILURE(
821 StartTestWithPage("files/overscroll_navigation.html"));
823 WebContentsImpl* web_contents =
824 static_cast<WebContentsImpl*>(shell()->web_contents());
825 NavigationController& controller = web_contents->GetController();
826 RenderFrameHost* main_frame = web_contents->GetMainFrame();
827 ExecuteSyncJSFunction(main_frame, "install_touch_handler()");
829 // Navigate twice, then navigate back in history once.
830 ExecuteSyncJSFunction(main_frame, "navigate_next()");
831 ExecuteSyncJSFunction(main_frame, "navigate_next()");
832 EXPECT_EQ(2, GetCurrentIndex());
833 EXPECT_TRUE(controller.CanGoBack());
834 EXPECT_FALSE(controller.CanGoForward());
836 web_contents->GetController().GoBack();
837 WaitForLoadStop(web_contents);
838 EXPECT_EQ(1, GetCurrentIndex());
839 EXPECT_EQ(base::ASCIIToUTF16("Title: #1"), web_contents->GetTitle());
840 EXPECT_TRUE(controller.CanGoBack());
841 EXPECT_TRUE(controller.CanGoForward());
843 aura::Window* content = web_contents->GetContentNativeView();
844 gfx::Rect bounds = content->GetBoundsInRootWindow();
845 ui::test::EventGenerator generator(content->GetRootWindow(), content);
847 // Do a swipe left to start a forward navigation. Then quickly do a swipe
848 // right.
849 base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
850 content::TitleWatcher title_watcher(web_contents, expected_title);
851 NavigationWatcher nav_watcher(web_contents);
853 generator.GestureScrollSequence(
854 gfx::Point(bounds.right() - 10, bounds.y() + 10),
855 gfx::Point(bounds.x() + 2, bounds.y() + 10),
856 base::TimeDelta::FromMilliseconds(2000),
857 10);
858 nav_watcher.WaitUntilNavigationStarts();
860 generator.GestureScrollSequence(
861 gfx::Point(bounds.x() + 2, bounds.y() + 10),
862 gfx::Point(bounds.right() - 10, bounds.y() + 10),
863 base::TimeDelta::FromMilliseconds(2000),
864 10);
865 base::string16 actual_title = title_watcher.WaitAndGetTitle();
866 EXPECT_EQ(expected_title, actual_title);
868 EXPECT_EQ(2, GetCurrentIndex());
869 EXPECT_TRUE(controller.CanGoBack());
870 EXPECT_FALSE(controller.CanGoForward());
873 // Verify that hiding a parent of the renderer will hide the content too.
874 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, HideContentOnParenHide) {
875 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/title1.html"));
876 WebContentsImpl* web_contents =
877 static_cast<WebContentsImpl*>(shell()->web_contents());
878 aura::Window* content = web_contents->GetNativeView()->parent();
879 EXPECT_TRUE(web_contents->should_normally_be_visible());
880 content->Hide();
881 EXPECT_FALSE(web_contents->should_normally_be_visible());
882 content->Show();
883 EXPECT_TRUE(web_contents->should_normally_be_visible());
886 // Ensure that SnapToPhysicalPixelBoundary() is called on WebContentsView parent
887 // change. This is a regression test for http://crbug.com/388908.
888 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, WebContentsViewReparent) {
889 ASSERT_NO_FATAL_FAILURE(
890 StartTestWithPage("files/overscroll_navigation.html"));
892 scoped_ptr<aura::Window> window(new aura::Window(NULL));
893 window->Init(ui::LAYER_NOT_DRAWN);
895 RenderWidgetHostViewAura* rwhva =
896 static_cast<RenderWidgetHostViewAura*>(
897 shell()->web_contents()->GetRenderWidgetHostView());
898 rwhva->ResetHasSnappedToBoundary();
899 EXPECT_FALSE(rwhva->has_snapped_to_boundary());
900 window->AddChild(shell()->web_contents()->GetNativeView());
901 EXPECT_TRUE(rwhva->has_snapped_to_boundary());
904 // Flaky on some platforms, likely for the same reason as other flaky overscroll
905 // tests. http://crbug.com/305722
906 // TODO(tdresser): Re-enable this once eager GR is back on. See
907 // crbug.com/410280.
908 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
909 #define MAYBE_OverscrollNavigationTouchThrottling \
910 DISABLED_OverscrollNavigationTouchThrottling
911 #else
912 #define MAYBE_OverscrollNavigationTouchThrottling \
913 DISABLED_OverscrollNavigationTouchThrottling
914 #endif
916 // Tests that touch moves are not throttled when performing a scroll gesture on
917 // a non-scrollable area, except during gesture-nav.
918 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
919 MAYBE_OverscrollNavigationTouchThrottling) {
920 ASSERT_NO_FATAL_FAILURE(
921 StartTestWithPage("files/overscroll_navigation.html"));
923 AddInputEventMessageFilter();
925 WebContentsImpl* web_contents =
926 static_cast<WebContentsImpl*>(shell()->web_contents());
927 aura::Window* content = web_contents->GetContentNativeView();
928 gfx::Rect bounds = content->GetBoundsInRootWindow();
929 const int dx = 20;
931 ExecuteSyncJSFunction(web_contents->GetMainFrame(),
932 "install_touchmove_handler()");
934 WaitAFrame();
936 for (int navigated = 0; navigated <= 1; ++navigated) {
937 if (navigated) {
938 ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
939 ExecuteSyncJSFunction(web_contents->GetMainFrame(),
940 "reset_touchmove_count()");
942 // Send touch press.
943 SyntheticWebTouchEvent touch;
944 touch.PressPoint(bounds.x() + 2, bounds.y() + 10);
945 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
946 ui::LatencyInfo());
947 filter()->WaitForAck(blink::WebInputEvent::TouchStart);
948 WaitAFrame();
950 // Assert on the ack, because we'll end up waiting for acks that will never
951 // come if this is not true.
952 ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
954 // Send first touch move, and then a scroll begin.
955 touch.MovePoint(0, bounds.x() + 20 + 1 * dx, bounds.y() + 100);
956 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
957 ui::LatencyInfo());
958 filter()->WaitForAck(blink::WebInputEvent::TouchMove);
959 ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
961 blink::WebGestureEvent scroll_begin =
962 SyntheticWebGestureEventBuilder::BuildScrollBegin(1, 1);
963 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
964 scroll_begin, ui::LatencyInfo());
965 // Scroll begin ignores ack disposition, so don't wait for the ack.
966 WaitAFrame();
968 // First touchmove already sent, start at 2.
969 for (int i = 2; i <= 10; ++i) {
970 // Send a touch move, followed by a scroll update
971 touch.MovePoint(0, bounds.x() + 20 + i * dx, bounds.y() + 100);
972 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(
973 touch, ui::LatencyInfo());
974 WaitAFrame();
976 blink::WebGestureEvent scroll_update =
977 SyntheticWebGestureEventBuilder::BuildScrollUpdate(
978 dx, 5, 0, blink::WebGestureDeviceTouchscreen);
980 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
981 scroll_update, ui::LatencyInfo());
983 WaitAFrame();
986 touch.ReleasePoint(0);
987 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
988 ui::LatencyInfo());
989 WaitAFrame();
991 blink::WebGestureEvent scroll_end;
992 scroll_end.type = blink::WebInputEvent::GestureScrollEnd;
993 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
994 scroll_end, ui::LatencyInfo());
995 WaitAFrame();
997 if (!navigated)
998 EXPECT_EQ(10, ExecuteScriptAndExtractInt("touchmoveCount"));
999 else
1000 EXPECT_GT(10, ExecuteScriptAndExtractInt("touchmoveCount"));
1004 // Test that vertical overscroll updates are sent only when a user overscrolls
1005 // vertically.
1006 #if defined(OS_WIN)
1007 #define MAYBE_VerticalOverscroll DISABLED_VerticalOverscroll
1008 #else
1009 #define MAYBE_VerticalOverscroll VerticalOverscroll
1010 #endif
1012 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_VerticalOverscroll) {
1013 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1014 switches::kScrollEndEffect, "1");
1016 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("about:blank"));
1017 WebContentsImpl* web_contents =
1018 static_cast<WebContentsImpl*>(shell()->web_contents());
1019 VerticalOverscrollTracker tracker;
1020 web_contents->SetDelegate(&tracker);
1022 // This test triggers a large number of animations. Speed them up to ensure
1023 // the test completes within its time limit.
1024 ui::ScopedAnimationDurationScaleMode fast_duration_mode(
1025 ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
1027 aura::Window* content = web_contents->GetContentNativeView();
1028 ui::EventProcessor* dispatcher = content->GetHost()->event_processor();
1029 gfx::Rect bounds = content->GetBoundsInRootWindow();
1031 // Overscroll horizontally.
1033 int kXStep = bounds.width() / 10;
1034 gfx::Point location(bounds.right() - kXStep, bounds.y() + 5);
1035 base::TimeDelta timestamp = ui::EventTimeForNow();
1036 ui::TouchEvent press(
1037 ui::ET_TOUCH_PRESSED,
1038 location,
1040 timestamp);
1041 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
1042 ASSERT_FALSE(details.dispatcher_destroyed);
1043 WaitAFrame();
1044 location -= gfx::Vector2d(kXStep, 0);
1045 timestamp += base::TimeDelta::FromMilliseconds(10);
1047 while (location.x() > bounds.x() + kXStep) {
1048 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1049 details = dispatcher->OnEventFromSource(&inc);
1050 ASSERT_FALSE(details.dispatcher_destroyed);
1051 WaitAFrame();
1052 location -= gfx::Vector2d(10, 0);
1053 timestamp += base::TimeDelta::FromMilliseconds(10);
1056 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
1057 details = dispatcher->OnEventFromSource(&release);
1058 ASSERT_FALSE(details.dispatcher_destroyed);
1059 WaitAFrame();
1061 EXPECT_EQ(0, tracker.num_overscroll_updates());
1062 EXPECT_FALSE(tracker.overscroll_completed());
1065 // Overscroll vertically.
1067 tracker.Reset();
1069 int kYStep = bounds.height() / 10;
1070 gfx::Point location(bounds.x() + 10, bounds.y() + kYStep);
1071 base::TimeDelta timestamp = ui::EventTimeForNow();
1072 ui::TouchEvent press(
1073 ui::ET_TOUCH_PRESSED,
1074 location,
1076 timestamp);
1077 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
1078 ASSERT_FALSE(details.dispatcher_destroyed);
1079 WaitAFrame();
1080 location += gfx::Vector2d(0, kYStep);
1081 timestamp += base::TimeDelta::FromMilliseconds(10);
1083 while (location.y() < bounds.bottom() - kYStep) {
1084 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1085 details = dispatcher->OnEventFromSource(&inc);
1086 ASSERT_FALSE(details.dispatcher_destroyed);
1087 WaitAFrame();
1088 location += gfx::Vector2d(0, kYStep);
1089 timestamp += base::TimeDelta::FromMilliseconds(10);
1092 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
1093 details = dispatcher->OnEventFromSource(&release);
1094 ASSERT_FALSE(details.dispatcher_destroyed);
1095 WaitAFrame();
1097 EXPECT_LT(0, tracker.num_overscroll_updates());
1098 EXPECT_TRUE(tracker.overscroll_completed());
1101 // Start out overscrolling vertically, then switch directions and finish
1102 // overscrolling horizontally.
1104 tracker.Reset();
1106 int kXStep = bounds.width() / 10;
1107 int kYStep = bounds.height() / 10;
1108 gfx::Point location = bounds.origin() + gfx::Vector2d(0, kYStep);
1109 base::TimeDelta timestamp = ui::EventTimeForNow();
1110 ui::TouchEvent press(
1111 ui::ET_TOUCH_PRESSED,
1112 location,
1114 timestamp);
1115 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
1116 ASSERT_FALSE(details.dispatcher_destroyed);
1117 WaitAFrame();
1118 location += gfx::Vector2d(0, kYStep);
1119 timestamp += base::TimeDelta::FromMilliseconds(10);
1121 for (size_t i = 0; i < 3; ++i) {
1122 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1123 details = dispatcher->OnEventFromSource(&inc);
1124 ASSERT_FALSE(details.dispatcher_destroyed);
1125 WaitAFrame();
1126 location += gfx::Vector2d(0, kYStep);
1127 timestamp += base::TimeDelta::FromMilliseconds(10);
1130 while (location.x() < bounds.right() - kXStep) {
1131 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1132 details = dispatcher->OnEventFromSource(&inc);
1133 ASSERT_FALSE(details.dispatcher_destroyed);
1134 WaitAFrame();
1135 location += gfx::Vector2d(kXStep, 0);
1136 timestamp += base::TimeDelta::FromMilliseconds(10);
1139 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
1140 details = dispatcher->OnEventFromSource(&release);
1141 ASSERT_FALSE(details.dispatcher_destroyed);
1142 WaitAFrame();
1144 EXPECT_LT(0, tracker.num_overscroll_updates());
1145 EXPECT_FALSE(tracker.overscroll_completed());
1149 } // namespace content