[Mac] Implement Ambient Light API
[chromium-blink-merge.git] / content / browser / web_contents / web_contents_view_aura_browsertest.cc
blob6e8480c68ef4142487a527ebb1ab5982616b882e
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"
12 #if defined(OS_WIN)
13 #include "base/win/windows_version.h"
14 #endif
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"
43 namespace {
45 // TODO(tdresser): Find a way to avoid sleeping like this. See crbug.com/405282
46 // for details.
47 void GiveItSomeTime() {
48 base::RunLoop run_loop;
49 base::MessageLoop::current()->PostDelayedTask(
50 FROM_HERE,
51 run_loop.QuitClosure(),
52 base::TimeDelta::FromMillisecondsD(10));
53 run_loop.Run();
56 // WebContentsDelegate which tracks vertical overscroll updates.
57 class VerticalOverscrollTracker : public content::WebContentsDelegate {
58 public:
59 VerticalOverscrollTracker() : count_(0), completed_(false) {}
60 ~VerticalOverscrollTracker() override {}
62 int num_overscroll_updates() const {
63 return count_;
66 bool overscroll_completed() const {
67 return completed_;
70 void Reset() {
71 count_ = 0;
72 completed_ = false;
75 private:
76 bool CanOverscrollContent() const override { return true; }
78 void OverscrollUpdate(float delta_y) override { ++count_; }
80 void OverscrollComplete() override { completed_ = true; }
82 int count_;
83 bool completed_;
85 DISALLOW_COPY_AND_ASSIGN(VerticalOverscrollTracker);
88 } //namespace
91 namespace content {
93 // This class keeps track of the RenderViewHost whose screenshot was captured.
94 class ScreenshotTracker : public NavigationEntryScreenshotManager {
95 public:
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_; }
106 void Reset() {
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_)
117 return;
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;
126 private:
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 {
152 public:
153 explicit NavigationWatcher(WebContents* contents)
154 : WebContentsObserver(contents),
155 navigated_(false),
156 should_quit_loop_(false) {
159 ~NavigationWatcher() override {}
161 void WaitUntilNavigationStarts() {
162 if (navigated_)
163 return;
164 should_quit_loop_ = true;
165 base::MessageLoop::current()->Run();
168 private:
169 // Overridden from WebContentsObserver:
170 void DidStartNavigationToPendingEntry(
171 const GURL& validated_url,
172 NavigationController::ReloadType reload_type) override {
173 navigated_ = true;
174 if (should_quit_loop_)
175 base::MessageLoop::current()->Quit();
178 bool navigated_;
179 bool should_quit_loop_;
181 DISALLOW_COPY_AND_ASSIGN(NavigationWatcher);
184 class InputEventMessageFilterWaitsForAcks : public BrowserMessageFilter {
185 public:
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);
195 run_loop.Run();
198 InputEventAckState last_ack_state() const { return state_; }
200 protected:
201 ~InputEventMessageFilterWaitsForAcks() override {}
203 private:
204 void ReceivedEventAck(blink::WebInputEvent::Type type,
205 InputEventAckState state) {
206 if (type_ == type) {
207 state_ = state;
208 quit_.Run();
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, &params);
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,
221 this, type, ack));
223 return false;
226 base::Closure quit_;
227 blink::WebInputEvent::Type type_;
228 InputEventAckState state_;
230 DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilterWaitsForAcks);
233 class WebContentsViewAuraTest : public ContentBrowserTest {
234 public:
235 WebContentsViewAuraTest()
236 : screenshot_manager_(NULL) {
239 // Executes the javascript synchronously and makes sure the returned value is
240 // freed properly.
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
248 // complete.
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());
277 int index = -1;
278 scoped_ptr<base::Value> value =
279 content::ExecuteScriptAndGetValue(main_frame, "get_current()");
280 ASSERT_TRUE(value->GetAsInteger(&index));
281 EXPECT_EQ(0, index);
283 if (touch_handler)
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));
290 EXPECT_EQ(2, 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),
308 kScrollSteps);
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));
313 EXPECT_EQ(1, 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),
326 kScrollSteps);
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));
331 EXPECT_EQ(0, 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),
344 kScrollSteps);
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));
349 EXPECT_EQ(1, 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();
359 int index = -1;
360 scoped_ptr<base::Value> value;
361 value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
362 if (!value->GetAsInteger(&index))
363 index = -1;
364 return index;
367 int ExecuteScriptAndExtractInt(const std::string& script) {
368 int value = 0;
369 EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
370 shell()->web_contents(),
371 "domAutomationController.send(" + script + ")",
372 &value));
373 return value;
376 RenderViewHost* GetRenderViewHost() const {
377 RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
378 CHECK(rvh);
379 return rvh;
382 RenderWidgetHostImpl* GetRenderWidgetHost() const {
383 RenderWidgetHostImpl* const rwh =
384 RenderWidgetHostImpl::From(shell()
385 ->web_contents()
386 ->GetRenderWidgetHostView()
387 ->GetRenderWidgetHost());
388 CHECK(rwh);
389 return rwh;
392 RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
393 return static_cast<RenderWidgetHostViewBase*>(
394 GetRenderViewHost()->GetView());
397 InputEventMessageFilterWaitsForAcks* filter() {
398 return filter_.get();
401 void WaitAFrame() {
402 uint32 frame = GetRenderWidgetHostView()->RendererFrameNumber();
403 while (!GetRenderWidgetHost()->ScheduleComposite())
404 GiveItSomeTime();
405 while (GetRenderWidgetHostView()->RendererFrameNumber() == frame)
406 GiveItSomeTime();
409 protected:
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());
420 private:
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
431 #else
432 #define MAYBE_OverscrollNavigation OverscrollNavigation
433 #endif
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
445 #else
446 #define MAYBE_OverscrollNavigationWithTouchHandler \
447 OverscrollNavigationWithTouchHandler
448 #endif
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
460 #else
461 #define MAYBE_QuickOverscrollDirectionChange QuickOverscrollDirectionChange
462 #endif
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),
491 0, timestamp);
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),
499 0, timestamp);
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
505 // edge.
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),
511 0, timestamp);
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),
521 0, timestamp);
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),
531 0, timestamp);
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
544 // gesture.
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
551 #else
552 #define MAYBE_OverscrollScreenshot OverscrollScreenshot
553 #endif
554 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollScreenshot) {
555 // Disable the test for WinXP. See http://crbug/294116.
556 #if defined(OS_WIN)
557 if (base::win::GetVersion() < base::win::VERSION_VISTA) {
558 LOG(WARNING) << "Test disabled due to unknown bug on WinXP.";
559 return;
561 #endif
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
573 // navigations.
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 = NavigationEntryImpl::FromNavigationEntry(
581 web_contents->GetController().GetEntryAtIndex(2));
582 EXPECT_FALSE(entry->screenshot().get());
584 entry = NavigationEntryImpl::FromNavigationEntry(
585 web_contents->GetController().GetEntryAtIndex(1));
586 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
588 entry = NavigationEntryImpl::FromNavigationEntry(
589 web_contents->GetController().GetEntryAtIndex(0));
590 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
592 ExecuteSyncJSFunction(main_frame, "navigate_next()");
593 screenshot_manager()->WaitUntilScreenshotIsReady();
595 entry = NavigationEntryImpl::FromNavigationEntry(
596 web_contents->GetController().GetEntryAtIndex(2));
597 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
599 entry = NavigationEntryImpl::FromNavigationEntry(
600 web_contents->GetController().GetEntryAtIndex(3));
601 EXPECT_FALSE(entry->screenshot().get());
603 // Now, swipe right to navigate backwards. This should navigate away from
604 // index 3 to index 2.
605 base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
606 content::TitleWatcher title_watcher(web_contents, expected_title);
607 aura::Window* content = web_contents->GetContentNativeView();
608 gfx::Rect bounds = content->GetBoundsInRootWindow();
609 ui::test::EventGenerator generator(content->GetRootWindow(), content);
610 generator.GestureScrollSequence(
611 gfx::Point(bounds.x() + 2, bounds.y() + 10),
612 gfx::Point(bounds.right() - 10, bounds.y() + 10),
613 base::TimeDelta::FromMilliseconds(20),
615 base::string16 actual_title = title_watcher.WaitAndGetTitle();
616 EXPECT_EQ(expected_title, actual_title);
617 EXPECT_EQ(2, GetCurrentIndex());
618 screenshot_manager()->WaitUntilScreenshotIsReady();
619 entry = NavigationEntryImpl::FromNavigationEntry(
620 web_contents->GetController().GetEntryAtIndex(3));
621 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
624 // Navigate a couple more times.
625 ExecuteSyncJSFunction(main_frame, "navigate_next()");
626 EXPECT_EQ(3, GetCurrentIndex());
627 ExecuteSyncJSFunction(main_frame, "navigate_next()");
628 EXPECT_EQ(4, GetCurrentIndex());
629 screenshot_manager()->WaitUntilScreenshotIsReady();
630 entry = NavigationEntryImpl::FromNavigationEntry(
631 web_contents->GetController().GetEntryAtIndex(4));
632 EXPECT_FALSE(entry->screenshot().get());
635 // Navigate back in history.
636 base::string16 expected_title = base::ASCIIToUTF16("Title: #3");
637 content::TitleWatcher title_watcher(web_contents, expected_title);
638 web_contents->GetController().GoBack();
639 base::string16 actual_title = title_watcher.WaitAndGetTitle();
640 EXPECT_EQ(expected_title, actual_title);
641 EXPECT_EQ(3, GetCurrentIndex());
642 screenshot_manager()->WaitUntilScreenshotIsReady();
643 entry = NavigationEntryImpl::FromNavigationEntry(
644 web_contents->GetController().GetEntryAtIndex(4));
645 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
649 // Crashes under ThreadSanitizer, http://crbug.com/356758.
650 #if defined(THREAD_SANITIZER)
651 #define MAYBE_ScreenshotForSwappedOutRenderViews \
652 DISABLED_ScreenshotForSwappedOutRenderViews
653 #else
654 #define MAYBE_ScreenshotForSwappedOutRenderViews \
655 ScreenshotForSwappedOutRenderViews
656 #endif
657 // Tests that screenshot is taken correctly when navigation causes a
658 // RenderViewHost to be swapped out.
659 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
660 MAYBE_ScreenshotForSwappedOutRenderViews) {
661 ASSERT_NO_FATAL_FAILURE(
662 StartTestWithPage("files/overscroll_navigation.html"));
663 // Create a new server with a different site.
664 net::SpawnedTestServer https_server(
665 net::SpawnedTestServer::TYPE_HTTPS,
666 net::SpawnedTestServer::kLocalhost,
667 base::FilePath(FILE_PATH_LITERAL("content/test/data")));
668 ASSERT_TRUE(https_server.Start());
670 WebContentsImpl* web_contents =
671 static_cast<WebContentsImpl*>(shell()->web_contents());
672 set_min_screenshot_interval(0);
674 struct {
675 GURL url;
676 int transition;
677 } navigations[] = {
678 { https_server.GetURL("files/title1.html"),
679 ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
680 { test_server()->GetURL("files/title2.html"),
681 ui::PAGE_TRANSITION_AUTO_BOOKMARK },
682 { https_server.GetURL("files/title3.html"),
683 ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
684 { GURL(), 0 }
687 screenshot_manager()->Reset();
688 for (int i = 0; !navigations[i].url.is_empty(); ++i) {
689 // Navigate via the user initiating a navigation from the UI.
690 NavigationController::LoadURLParams params(navigations[i].url);
691 params.transition_type =
692 ui::PageTransitionFromInt(navigations[i].transition);
694 RenderViewHost* old_host = web_contents->GetRenderViewHost();
695 web_contents->GetController().LoadURLWithParams(params);
696 WaitForLoadStop(web_contents);
697 screenshot_manager()->WaitUntilScreenshotIsReady();
699 EXPECT_NE(old_host, web_contents->GetRenderViewHost())
700 << navigations[i].url.spec();
701 EXPECT_EQ(old_host, screenshot_manager()->screenshot_taken_for());
703 NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
704 web_contents->GetController().GetEntryAtOffset(-1));
705 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
707 entry = NavigationEntryImpl::FromNavigationEntry(
708 web_contents->GetController().GetLastCommittedEntry());
709 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
710 EXPECT_FALSE(entry->screenshot().get());
711 screenshot_manager()->Reset();
714 // Increase the minimum interval between taking screenshots.
715 set_min_screenshot_interval(60000);
717 // Navigate again. This should not take any screenshot because of the
718 // increased screenshot interval.
719 NavigationController::LoadURLParams params(navigations[0].url);
720 params.transition_type = ui::PageTransitionFromInt(navigations[0].transition);
721 web_contents->GetController().LoadURLWithParams(params);
722 WaitForLoadStop(web_contents);
723 screenshot_manager()->WaitUntilScreenshotIsReady();
725 EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
728 // Tests that navigations resulting from reloads, history.replaceState,
729 // and history.pushState do not capture screenshots.
730 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ReplaceStateReloadPushState) {
731 ASSERT_NO_FATAL_FAILURE(
732 StartTestWithPage("files/overscroll_navigation.html"));
733 WebContentsImpl* web_contents =
734 static_cast<WebContentsImpl*>(shell()->web_contents());
735 RenderFrameHost* main_frame = web_contents->GetMainFrame();
737 set_min_screenshot_interval(0);
738 screenshot_manager()->Reset();
739 ExecuteSyncJSFunction(main_frame, "use_replace_state()");
740 screenshot_manager()->WaitUntilScreenshotIsReady();
741 // history.replaceState shouldn't capture a screenshot
742 EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
743 screenshot_manager()->Reset();
744 web_contents->GetController().Reload(true);
745 WaitForLoadStop(web_contents);
746 // reloading the page shouldn't capture a screenshot
747 // TODO (mfomitchev): currently broken. Uncomment when
748 // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
749 // is populated properly when reloading the page.
750 //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
751 screenshot_manager()->Reset();
752 ExecuteSyncJSFunction(main_frame, "use_push_state()");
753 screenshot_manager()->WaitUntilScreenshotIsReady();
754 // pushing a state shouldn't capture a screenshot
755 // TODO (mfomitchev): currently broken. Uncomment when
756 // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
757 // is populated properly when pushState is used.
758 //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
761 // TODO(sadrul): This test is disabled because it reparents in a way the
762 // FocusController does not support. This code would crash in
763 // a production build. It only passed prior to this revision
764 // because testing used the old FocusManager which did some
765 // different (osbolete) processing. TODO(sadrul) to figure out
766 // how this test should work that mimics production code a bit
767 // better.
768 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
769 DISABLED_ContentWindowReparent) {
770 ASSERT_NO_FATAL_FAILURE(
771 StartTestWithPage("files/overscroll_navigation.html"));
773 scoped_ptr<aura::Window> window(new aura::Window(NULL));
774 window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
776 WebContentsImpl* web_contents =
777 static_cast<WebContentsImpl*>(shell()->web_contents());
778 ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
779 EXPECT_EQ(1, GetCurrentIndex());
781 aura::Window* content = web_contents->GetContentNativeView();
782 gfx::Rect bounds = content->GetBoundsInRootWindow();
783 ui::test::EventGenerator generator(content->GetRootWindow(), content);
784 generator.GestureScrollSequence(
785 gfx::Point(bounds.x() + 2, bounds.y() + 10),
786 gfx::Point(bounds.right() - 10, bounds.y() + 10),
787 base::TimeDelta::FromMilliseconds(20),
790 window->AddChild(shell()->web_contents()->GetContentNativeView());
793 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ContentWindowClose) {
794 ASSERT_NO_FATAL_FAILURE(
795 StartTestWithPage("files/overscroll_navigation.html"));
797 WebContentsImpl* web_contents =
798 static_cast<WebContentsImpl*>(shell()->web_contents());
799 ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
800 EXPECT_EQ(1, GetCurrentIndex());
802 aura::Window* content = web_contents->GetContentNativeView();
803 gfx::Rect bounds = content->GetBoundsInRootWindow();
804 ui::test::EventGenerator generator(content->GetRootWindow(), content);
805 generator.GestureScrollSequence(
806 gfx::Point(bounds.x() + 2, bounds.y() + 10),
807 gfx::Point(bounds.right() - 10, bounds.y() + 10),
808 base::TimeDelta::FromMilliseconds(20),
811 delete web_contents->GetContentNativeView();
815 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
816 // This appears to be flaky in the same was as the other overscroll
817 // tests. Enabling for non-Windows platforms.
818 // See http://crbug.com/369871.
819 // For linux, see http://crbug.com/381294
820 #define MAYBE_RepeatedQuickOverscrollGestures DISABLED_RepeatedQuickOverscrollGestures
821 #else
822 #define MAYBE_RepeatedQuickOverscrollGestures RepeatedQuickOverscrollGestures
823 #endif
825 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
826 MAYBE_RepeatedQuickOverscrollGestures) {
827 ASSERT_NO_FATAL_FAILURE(
828 StartTestWithPage("files/overscroll_navigation.html"));
830 WebContentsImpl* web_contents =
831 static_cast<WebContentsImpl*>(shell()->web_contents());
832 NavigationController& controller = web_contents->GetController();
833 RenderFrameHost* main_frame = web_contents->GetMainFrame();
834 ExecuteSyncJSFunction(main_frame, "install_touch_handler()");
836 // Navigate twice, then navigate back in history once.
837 ExecuteSyncJSFunction(main_frame, "navigate_next()");
838 ExecuteSyncJSFunction(main_frame, "navigate_next()");
839 EXPECT_EQ(2, GetCurrentIndex());
840 EXPECT_TRUE(controller.CanGoBack());
841 EXPECT_FALSE(controller.CanGoForward());
843 web_contents->GetController().GoBack();
844 WaitForLoadStop(web_contents);
845 EXPECT_EQ(1, GetCurrentIndex());
846 EXPECT_EQ(base::ASCIIToUTF16("Title: #1"), web_contents->GetTitle());
847 EXPECT_TRUE(controller.CanGoBack());
848 EXPECT_TRUE(controller.CanGoForward());
850 aura::Window* content = web_contents->GetContentNativeView();
851 gfx::Rect bounds = content->GetBoundsInRootWindow();
852 ui::test::EventGenerator generator(content->GetRootWindow(), content);
854 // Do a swipe left to start a forward navigation. Then quickly do a swipe
855 // right.
856 base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
857 content::TitleWatcher title_watcher(web_contents, expected_title);
858 NavigationWatcher nav_watcher(web_contents);
860 generator.GestureScrollSequence(
861 gfx::Point(bounds.right() - 10, bounds.y() + 10),
862 gfx::Point(bounds.x() + 2, bounds.y() + 10),
863 base::TimeDelta::FromMilliseconds(2000),
864 10);
865 nav_watcher.WaitUntilNavigationStarts();
867 generator.GestureScrollSequence(
868 gfx::Point(bounds.x() + 2, bounds.y() + 10),
869 gfx::Point(bounds.right() - 10, bounds.y() + 10),
870 base::TimeDelta::FromMilliseconds(2000),
871 10);
872 base::string16 actual_title = title_watcher.WaitAndGetTitle();
873 EXPECT_EQ(expected_title, actual_title);
875 EXPECT_EQ(2, GetCurrentIndex());
876 EXPECT_TRUE(controller.CanGoBack());
877 EXPECT_FALSE(controller.CanGoForward());
880 // Verify that hiding a parent of the renderer will hide the content too.
881 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, HideContentOnParenHide) {
882 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/title1.html"));
883 WebContentsImpl* web_contents =
884 static_cast<WebContentsImpl*>(shell()->web_contents());
885 aura::Window* content = web_contents->GetNativeView()->parent();
886 EXPECT_TRUE(web_contents->should_normally_be_visible());
887 content->Hide();
888 EXPECT_FALSE(web_contents->should_normally_be_visible());
889 content->Show();
890 EXPECT_TRUE(web_contents->should_normally_be_visible());
893 // Ensure that SnapToPhysicalPixelBoundary() is called on WebContentsView parent
894 // change. This is a regression test for http://crbug.com/388908.
895 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, WebContentsViewReparent) {
896 ASSERT_NO_FATAL_FAILURE(
897 StartTestWithPage("files/overscroll_navigation.html"));
899 scoped_ptr<aura::Window> window(new aura::Window(NULL));
900 window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
902 RenderWidgetHostViewAura* rwhva =
903 static_cast<RenderWidgetHostViewAura*>(
904 shell()->web_contents()->GetRenderWidgetHostView());
905 rwhva->ResetHasSnappedToBoundary();
906 EXPECT_FALSE(rwhva->has_snapped_to_boundary());
907 window->AddChild(shell()->web_contents()->GetNativeView());
908 EXPECT_TRUE(rwhva->has_snapped_to_boundary());
911 // Flaky on some platforms, likely for the same reason as other flaky overscroll
912 // tests. http://crbug.com/305722
913 // TODO(tdresser): Re-enable this once eager GR is back on. See
914 // crbug.com/410280.
915 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
916 #define MAYBE_OverscrollNavigationTouchThrottling \
917 DISABLED_OverscrollNavigationTouchThrottling
918 #else
919 #define MAYBE_OverscrollNavigationTouchThrottling \
920 DISABLED_OverscrollNavigationTouchThrottling
921 #endif
923 // Tests that touch moves are not throttled when performing a scroll gesture on
924 // a non-scrollable area, except during gesture-nav.
925 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
926 MAYBE_OverscrollNavigationTouchThrottling) {
927 ASSERT_NO_FATAL_FAILURE(
928 StartTestWithPage("files/overscroll_navigation.html"));
930 AddInputEventMessageFilter();
932 WebContentsImpl* web_contents =
933 static_cast<WebContentsImpl*>(shell()->web_contents());
934 aura::Window* content = web_contents->GetContentNativeView();
935 gfx::Rect bounds = content->GetBoundsInRootWindow();
936 const int dx = 20;
938 ExecuteSyncJSFunction(web_contents->GetMainFrame(),
939 "install_touchmove_handler()");
941 WaitAFrame();
943 for (int navigated = 0; navigated <= 1; ++navigated) {
944 if (navigated) {
945 ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
946 ExecuteSyncJSFunction(web_contents->GetMainFrame(),
947 "reset_touchmove_count()");
949 // Send touch press.
950 SyntheticWebTouchEvent touch;
951 touch.PressPoint(bounds.x() + 2, bounds.y() + 10);
952 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
953 ui::LatencyInfo());
954 filter()->WaitForAck(blink::WebInputEvent::TouchStart);
955 WaitAFrame();
957 // Assert on the ack, because we'll end up waiting for acks that will never
958 // come if this is not true.
959 ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
961 // Send first touch move, and then a scroll begin.
962 touch.MovePoint(0, bounds.x() + 20 + 1 * dx, bounds.y() + 100);
963 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
964 ui::LatencyInfo());
965 filter()->WaitForAck(blink::WebInputEvent::TouchMove);
966 ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
968 blink::WebGestureEvent scroll_begin =
969 SyntheticWebGestureEventBuilder::BuildScrollBegin(1, 1);
970 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
971 scroll_begin, ui::LatencyInfo());
972 // Scroll begin ignores ack disposition, so don't wait for the ack.
973 WaitAFrame();
975 // First touchmove already sent, start at 2.
976 for (int i = 2; i <= 10; ++i) {
977 // Send a touch move, followed by a scroll update
978 touch.MovePoint(0, bounds.x() + 20 + i * dx, bounds.y() + 100);
979 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(
980 touch, ui::LatencyInfo());
981 WaitAFrame();
983 blink::WebGestureEvent scroll_update =
984 SyntheticWebGestureEventBuilder::BuildScrollUpdate(
985 dx, 5, 0, blink::WebGestureDeviceTouchscreen);
987 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
988 scroll_update, ui::LatencyInfo());
990 WaitAFrame();
993 touch.ReleasePoint(0);
994 GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
995 ui::LatencyInfo());
996 WaitAFrame();
998 blink::WebGestureEvent scroll_end;
999 scroll_end.type = blink::WebInputEvent::GestureScrollEnd;
1000 GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
1001 scroll_end, ui::LatencyInfo());
1002 WaitAFrame();
1004 if (!navigated)
1005 EXPECT_EQ(10, ExecuteScriptAndExtractInt("touchmoveCount"));
1006 else
1007 EXPECT_GT(10, ExecuteScriptAndExtractInt("touchmoveCount"));
1011 // Test that vertical overscroll updates are sent only when a user overscrolls
1012 // vertically.
1013 #if defined(OS_WIN)
1014 #define MAYBE_VerticalOverscroll DISABLED_VerticalOverscroll
1015 #else
1016 #define MAYBE_VerticalOverscroll VerticalOverscroll
1017 #endif
1019 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_VerticalOverscroll) {
1020 base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
1021 switches::kScrollEndEffect, "1");
1023 ASSERT_NO_FATAL_FAILURE(StartTestWithPage("about:blank"));
1024 WebContentsImpl* web_contents =
1025 static_cast<WebContentsImpl*>(shell()->web_contents());
1026 VerticalOverscrollTracker tracker;
1027 web_contents->SetDelegate(&tracker);
1029 // This test triggers a large number of animations. Speed them up to ensure
1030 // the test completes within its time limit.
1031 ui::ScopedAnimationDurationScaleMode fast_duration_mode(
1032 ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
1034 aura::Window* content = web_contents->GetContentNativeView();
1035 ui::EventProcessor* dispatcher = content->GetHost()->event_processor();
1036 gfx::Rect bounds = content->GetBoundsInRootWindow();
1038 // Overscroll horizontally.
1040 int kXStep = bounds.width() / 10;
1041 gfx::Point location(bounds.right() - kXStep, bounds.y() + 5);
1042 base::TimeDelta timestamp = ui::EventTimeForNow();
1043 ui::TouchEvent press(
1044 ui::ET_TOUCH_PRESSED,
1045 location,
1047 timestamp);
1048 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
1049 ASSERT_FALSE(details.dispatcher_destroyed);
1050 WaitAFrame();
1051 location -= gfx::Vector2d(kXStep, 0);
1052 timestamp += base::TimeDelta::FromMilliseconds(10);
1054 while (location.x() > bounds.x() + kXStep) {
1055 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1056 details = dispatcher->OnEventFromSource(&inc);
1057 ASSERT_FALSE(details.dispatcher_destroyed);
1058 WaitAFrame();
1059 location -= gfx::Vector2d(10, 0);
1060 timestamp += base::TimeDelta::FromMilliseconds(10);
1063 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
1064 details = dispatcher->OnEventFromSource(&release);
1065 ASSERT_FALSE(details.dispatcher_destroyed);
1066 WaitAFrame();
1068 EXPECT_EQ(0, tracker.num_overscroll_updates());
1069 EXPECT_FALSE(tracker.overscroll_completed());
1072 // Overscroll vertically.
1074 tracker.Reset();
1076 int kYStep = bounds.height() / 10;
1077 gfx::Point location(bounds.x() + 10, bounds.y() + kYStep);
1078 base::TimeDelta timestamp = ui::EventTimeForNow();
1079 ui::TouchEvent press(
1080 ui::ET_TOUCH_PRESSED,
1081 location,
1083 timestamp);
1084 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
1085 ASSERT_FALSE(details.dispatcher_destroyed);
1086 WaitAFrame();
1087 location += gfx::Vector2d(0, kYStep);
1088 timestamp += base::TimeDelta::FromMilliseconds(10);
1090 while (location.y() < bounds.bottom() - kYStep) {
1091 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1092 details = dispatcher->OnEventFromSource(&inc);
1093 ASSERT_FALSE(details.dispatcher_destroyed);
1094 WaitAFrame();
1095 location += gfx::Vector2d(0, kYStep);
1096 timestamp += base::TimeDelta::FromMilliseconds(10);
1099 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
1100 details = dispatcher->OnEventFromSource(&release);
1101 ASSERT_FALSE(details.dispatcher_destroyed);
1102 WaitAFrame();
1104 EXPECT_LT(0, tracker.num_overscroll_updates());
1105 EXPECT_TRUE(tracker.overscroll_completed());
1108 // Start out overscrolling vertically, then switch directions and finish
1109 // overscrolling horizontally.
1111 tracker.Reset();
1113 int kXStep = bounds.width() / 10;
1114 int kYStep = bounds.height() / 10;
1115 gfx::Point location = bounds.origin() + gfx::Vector2d(0, kYStep);
1116 base::TimeDelta timestamp = ui::EventTimeForNow();
1117 ui::TouchEvent press(
1118 ui::ET_TOUCH_PRESSED,
1119 location,
1121 timestamp);
1122 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
1123 ASSERT_FALSE(details.dispatcher_destroyed);
1124 WaitAFrame();
1125 location += gfx::Vector2d(0, kYStep);
1126 timestamp += base::TimeDelta::FromMilliseconds(10);
1128 for (size_t i = 0; i < 3; ++i) {
1129 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1130 details = dispatcher->OnEventFromSource(&inc);
1131 ASSERT_FALSE(details.dispatcher_destroyed);
1132 WaitAFrame();
1133 location += gfx::Vector2d(0, kYStep);
1134 timestamp += base::TimeDelta::FromMilliseconds(10);
1137 while (location.x() < bounds.right() - kXStep) {
1138 ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
1139 details = dispatcher->OnEventFromSource(&inc);
1140 ASSERT_FALSE(details.dispatcher_destroyed);
1141 WaitAFrame();
1142 location += gfx::Vector2d(kXStep, 0);
1143 timestamp += base::TimeDelta::FromMilliseconds(10);
1146 ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
1147 details = dispatcher->OnEventFromSource(&release);
1148 ASSERT_FALSE(details.dispatcher_destroyed);
1149 WaitAFrame();
1151 EXPECT_LT(0, tracker.num_overscroll_updates());
1152 EXPECT_FALSE(tracker.overscroll_completed());
1156 } // namespace content