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_view_host_impl.h"
19 #include "content/browser/web_contents/web_contents_impl.h"
20 #include "content/public/browser/web_contents_observer.h"
21 #include "content/public/browser/web_contents_view.h"
22 #include "content/public/common/content_switches.h"
23 #include "content/public/test/browser_test_utils.h"
24 #include "content/public/test/test_utils.h"
25 #include "content/shell/browser/shell.h"
26 #include "content/test/content_browser_test.h"
27 #include "content/test/content_browser_test_utils.h"
28 #include "ui/aura/root_window.h"
29 #include "ui/aura/test/event_generator.h"
30 #include "ui/aura/window.h"
31 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
35 // This class keeps track of the RenderViewHost whose screenshot was captured.
36 class ScreenshotTracker : public NavigationEntryScreenshotManager {
38 explicit ScreenshotTracker(NavigationControllerImpl* controller)
39 : NavigationEntryScreenshotManager(controller),
40 screenshot_taken_for_(NULL),
41 waiting_for_screenshots_(0) {
44 virtual ~ScreenshotTracker() {
47 RenderViewHost* screenshot_taken_for() { return screenshot_taken_for_; }
50 screenshot_taken_for_ = NULL;
51 screenshot_set_.clear();
54 void SetScreenshotInterval(int interval_ms) {
55 SetMinScreenshotIntervalMS(interval_ms);
58 void WaitUntilScreenshotIsReady() {
59 if (!waiting_for_screenshots_)
61 message_loop_runner_ = new content::MessageLoopRunner;
62 message_loop_runner_->Run();
65 bool ScreenshotSetForEntry(NavigationEntryImpl* entry) const {
66 return screenshot_set_.count(entry) > 0;
70 // Overridden from NavigationEntryScreenshotManager:
71 virtual void TakeScreenshotImpl(RenderViewHost* host,
72 NavigationEntryImpl* entry) OVERRIDE {
73 ++waiting_for_screenshots_;
74 screenshot_taken_for_ = host;
75 NavigationEntryScreenshotManager::TakeScreenshotImpl(host, entry);
78 virtual void OnScreenshotSet(NavigationEntryImpl* entry) OVERRIDE {
79 --waiting_for_screenshots_;
80 screenshot_set_[entry] = true;
81 NavigationEntryScreenshotManager::OnScreenshotSet(entry);
82 if (waiting_for_screenshots_ == 0 && message_loop_runner_.get())
83 message_loop_runner_->Quit();
86 RenderViewHost* screenshot_taken_for_;
87 scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
88 int waiting_for_screenshots_;
89 std::map<NavigationEntryImpl*, bool> screenshot_set_;
91 DISALLOW_COPY_AND_ASSIGN(ScreenshotTracker);
94 class NavigationWatcher : public WebContentsObserver {
96 explicit NavigationWatcher(WebContents* contents)
97 : WebContentsObserver(contents),
99 should_quit_loop_(false) {
102 virtual ~NavigationWatcher() {}
104 void WaitUntilNavigationStarts() {
107 should_quit_loop_ = true;
108 base::MessageLoop::current()->Run();
112 // Overridden from WebContentsObserver:
113 virtual void AboutToNavigateRenderView(RenderViewHost* host) OVERRIDE {
115 if (should_quit_loop_)
116 base::MessageLoop::current()->Quit();
120 bool should_quit_loop_;
122 DISALLOW_COPY_AND_ASSIGN(NavigationWatcher);
125 class WebContentsViewAuraTest : public ContentBrowserTest {
127 WebContentsViewAuraTest()
128 : screenshot_manager_(NULL) {
131 // Executes the javascript synchronously and makes sure the returned value is
133 void ExecuteSyncJSFunction(RenderViewHost* rvh, const std::string& jscript) {
134 scoped_ptr<base::Value> value =
135 content::ExecuteScriptAndGetValue(rvh, jscript);
138 // Starts the test server and navigates to the given url. Sets a large enough
139 // size to the root window. Returns after the navigation to the url is
141 void StartTestWithPage(const std::string& url) {
142 ASSERT_TRUE(test_server()->Start());
143 GURL test_url(test_server()->GetURL(url));
144 NavigateToURL(shell(), test_url);
146 WebContentsImpl* web_contents =
147 static_cast<WebContentsImpl*>(shell()->web_contents());
148 NavigationControllerImpl* controller = &web_contents->GetController();
150 screenshot_manager_ = new ScreenshotTracker(controller);
151 controller->SetScreenshotManager(screenshot_manager_);
154 void TestOverscrollNavigation(bool touch_handler) {
155 ASSERT_NO_FATAL_FAILURE(
156 StartTestWithPage("files/overscroll_navigation.html"));
157 WebContentsImpl* web_contents =
158 static_cast<WebContentsImpl*>(shell()->web_contents());
159 NavigationController& controller = web_contents->GetController();
160 RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
161 web_contents->GetRenderViewHost());
162 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
163 web_contents->GetView());
164 view_aura->SetupOverlayWindowForTesting();
166 EXPECT_FALSE(controller.CanGoBack());
167 EXPECT_FALSE(controller.CanGoForward());
169 scoped_ptr<base::Value> value =
170 content::ExecuteScriptAndGetValue(view_host, "get_current()");
171 ASSERT_TRUE(value->GetAsInteger(&index));
175 ExecuteSyncJSFunction(view_host, "install_touch_handler()");
177 ExecuteSyncJSFunction(view_host, "navigate_next()");
178 ExecuteSyncJSFunction(view_host, "navigate_next()");
179 value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
180 ASSERT_TRUE(value->GetAsInteger(&index));
182 EXPECT_TRUE(controller.CanGoBack());
183 EXPECT_FALSE(controller.CanGoForward());
185 aura::Window* content = web_contents->GetView()->GetContentNativeView();
186 gfx::Rect bounds = content->GetBoundsInRootWindow();
187 aura::test::EventGenerator generator(content->GetRootWindow(), content);
188 const int kScrollDurationMs = 20;
189 const int kScrollSteps = 10;
192 // Do a swipe-right now. That should navigate backwards.
193 base::string16 expected_title = base::ASCIIToUTF16("Title: #1");
194 content::TitleWatcher title_watcher(web_contents, expected_title);
195 generator.GestureScrollSequence(
196 gfx::Point(bounds.x() + 2, bounds.y() + 10),
197 gfx::Point(bounds.right() - 10, bounds.y() + 10),
198 base::TimeDelta::FromMilliseconds(kScrollDurationMs),
200 base::string16 actual_title = title_watcher.WaitAndGetTitle();
201 EXPECT_EQ(expected_title, actual_title);
202 value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
203 ASSERT_TRUE(value->GetAsInteger(&index));
205 EXPECT_TRUE(controller.CanGoBack());
206 EXPECT_TRUE(controller.CanGoForward());
210 // Do a fling-right now. That should navigate backwards.
211 base::string16 expected_title = base::ASCIIToUTF16("Title:");
212 content::TitleWatcher title_watcher(web_contents, expected_title);
213 generator.GestureScrollSequence(
214 gfx::Point(bounds.x() + 2, bounds.y() + 10),
215 gfx::Point(bounds.right() - 10, bounds.y() + 10),
216 base::TimeDelta::FromMilliseconds(kScrollDurationMs),
218 base::string16 actual_title = title_watcher.WaitAndGetTitle();
219 EXPECT_EQ(expected_title, actual_title);
220 value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
221 ASSERT_TRUE(value->GetAsInteger(&index));
223 EXPECT_FALSE(controller.CanGoBack());
224 EXPECT_TRUE(controller.CanGoForward());
228 // Do a swipe-left now. That should navigate forward.
229 base::string16 expected_title = base::ASCIIToUTF16("Title: #1");
230 content::TitleWatcher title_watcher(web_contents, expected_title);
231 generator.GestureScrollSequence(
232 gfx::Point(bounds.right() - 10, bounds.y() + 10),
233 gfx::Point(bounds.x() + 2, bounds.y() + 10),
234 base::TimeDelta::FromMilliseconds(kScrollDurationMs),
236 base::string16 actual_title = title_watcher.WaitAndGetTitle();
237 EXPECT_EQ(expected_title, actual_title);
238 value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
239 ASSERT_TRUE(value->GetAsInteger(&index));
241 EXPECT_TRUE(controller.CanGoBack());
242 EXPECT_TRUE(controller.CanGoForward());
246 int GetCurrentIndex() {
247 WebContentsImpl* web_contents =
248 static_cast<WebContentsImpl*>(shell()->web_contents());
249 RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
250 web_contents->GetRenderViewHost());
252 scoped_ptr<base::Value> value;
253 value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
254 if (!value->GetAsInteger(&index))
260 ScreenshotTracker* screenshot_manager() { return screenshot_manager_; }
261 void set_min_screenshot_interval(int interval_ms) {
262 screenshot_manager_->SetScreenshotInterval(interval_ms);
266 ScreenshotTracker* screenshot_manager_;
268 DISALLOW_COPY_AND_ASSIGN(WebContentsViewAuraTest);
271 // Flaky on Windows (perhaps just Win-Aura): http://crbug.com/305722
273 #define MAYBE_OverscrollNavigation DISABLED_OverscrollNavigation
275 #define MAYBE_OverscrollNavigation OverscrollNavigation
277 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollNavigation) {
278 TestOverscrollNavigation(false);
281 // Flaky on Windows (perhaps just Win-Aura): http://crbug.com/305722
283 #define MAYBE_OverscrollNavigationWithTouchHandler \
284 DISABLED_OverscrollNavigationWithTouchHandler
286 #define MAYBE_OverscrollNavigationWithTouchHandler \
287 OverscrollNavigationWithTouchHandler
289 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
290 MAYBE_OverscrollNavigationWithTouchHandler) {
291 TestOverscrollNavigation(true);
294 // Disabled because the test always fails the first time it runs on the Win Aura
295 // bots, and usually but not always passes second-try (See crbug.com/179532).
297 #define MAYBE_QuickOverscrollDirectionChange \
298 DISABLED_QuickOverscrollDirectionChange
300 #define MAYBE_QuickOverscrollDirectionChange QuickOverscrollDirectionChange
302 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
303 MAYBE_QuickOverscrollDirectionChange) {
304 ASSERT_NO_FATAL_FAILURE(
305 StartTestWithPage("files/overscroll_navigation.html"));
306 WebContentsImpl* web_contents =
307 static_cast<WebContentsImpl*>(shell()->web_contents());
308 RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
309 web_contents->GetRenderViewHost());
311 // This test triggers a large number of animations. Speed them up to ensure
312 // the test completes within its time limit.
313 ui::ScopedAnimationDurationScaleMode fast_duration_mode(
314 ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
316 // Make sure the page has both back/forward history.
317 ExecuteSyncJSFunction(view_host, "navigate_next()");
318 EXPECT_EQ(1, GetCurrentIndex());
319 ExecuteSyncJSFunction(view_host, "navigate_next()");
320 EXPECT_EQ(2, GetCurrentIndex());
321 web_contents->GetController().GoBack();
322 EXPECT_EQ(1, GetCurrentIndex());
324 aura::Window* content = web_contents->GetView()->GetContentNativeView();
325 aura::WindowEventDispatcher* dispatcher = content->GetDispatcher();
326 gfx::Rect bounds = content->GetBoundsInRootWindow();
328 base::TimeDelta timestamp;
329 ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
330 gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
332 ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
333 ASSERT_FALSE(details.dispatcher_destroyed);
334 EXPECT_EQ(1, GetCurrentIndex());
336 timestamp += base::TimeDelta::FromMilliseconds(10);
337 ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
338 gfx::Point(bounds.right() - 10, bounds.y() + 5),
340 details = dispatcher->OnEventFromSource(&move1);
341 ASSERT_FALSE(details.dispatcher_destroyed);
342 EXPECT_EQ(1, GetCurrentIndex());
344 // Swipe back from the right edge, back to the left edge, back to the right
347 for (int x = bounds.right() - 10; x >= bounds.x() + 10; x-= 10) {
348 timestamp += base::TimeDelta::FromMilliseconds(10);
349 ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
350 gfx::Point(x, bounds.y() + 5),
352 details = dispatcher->OnEventFromSource(&inc);
353 ASSERT_FALSE(details.dispatcher_destroyed);
354 EXPECT_EQ(1, GetCurrentIndex());
357 for (int x = bounds.x() + 10; x <= bounds.width() - 10; x+= 10) {
358 timestamp += base::TimeDelta::FromMilliseconds(10);
359 ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
360 gfx::Point(x, bounds.y() + 5),
362 details = dispatcher->OnEventFromSource(&inc);
363 ASSERT_FALSE(details.dispatcher_destroyed);
364 EXPECT_EQ(1, GetCurrentIndex());
367 for (int x = bounds.width() - 10; x >= bounds.x() + 10; x-= 10) {
368 timestamp += base::TimeDelta::FromMilliseconds(10);
369 ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
370 gfx::Point(x, bounds.y() + 5),
372 details = dispatcher->OnEventFromSource(&inc);
373 ASSERT_FALSE(details.dispatcher_destroyed);
374 EXPECT_EQ(1, GetCurrentIndex());
377 // Do not end the overscroll sequence.
380 // Tests that the page has has a screenshot when navigation happens:
381 // - from within the page (from a JS function)
382 // - interactively, when user does an overscroll gesture
383 // - interactively, when user navigates in history without the overscroll
385 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, OverscrollScreenshot) {
386 // Disable the test for WinXP. See http://crbug/294116.
388 if (base::win::GetVersion() < base::win::VERSION_VISTA) {
389 LOG(WARNING) << "Test disabled due to unknown bug on WinXP.";
394 ASSERT_NO_FATAL_FAILURE(
395 StartTestWithPage("files/overscroll_navigation.html"));
396 WebContentsImpl* web_contents =
397 static_cast<WebContentsImpl*>(shell()->web_contents());
398 RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
399 web_contents->GetRenderViewHost());
401 set_min_screenshot_interval(0);
403 // Do a few navigations initiated by the page.
404 ExecuteSyncJSFunction(view_host, "navigate_next()");
405 EXPECT_EQ(1, GetCurrentIndex());
406 ExecuteSyncJSFunction(view_host, "navigate_next()");
407 EXPECT_EQ(2, GetCurrentIndex());
408 screenshot_manager()->WaitUntilScreenshotIsReady();
410 // The current entry won't have any screenshots. But the entries in the
411 // history should now have screenshots.
412 NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
413 web_contents->GetController().GetEntryAtIndex(2));
414 EXPECT_FALSE(entry->screenshot().get());
416 entry = NavigationEntryImpl::FromNavigationEntry(
417 web_contents->GetController().GetEntryAtIndex(1));
418 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
420 entry = NavigationEntryImpl::FromNavigationEntry(
421 web_contents->GetController().GetEntryAtIndex(0));
422 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
424 // Navigate again. Index 2 should now have a screenshot.
425 ExecuteSyncJSFunction(view_host, "navigate_next()");
426 EXPECT_EQ(3, GetCurrentIndex());
427 screenshot_manager()->WaitUntilScreenshotIsReady();
429 entry = NavigationEntryImpl::FromNavigationEntry(
430 web_contents->GetController().GetEntryAtIndex(2));
431 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
433 entry = NavigationEntryImpl::FromNavigationEntry(
434 web_contents->GetController().GetEntryAtIndex(3));
435 EXPECT_FALSE(entry->screenshot().get());
438 // Now, swipe right to navigate backwards. This should navigate away from
439 // index 3 to index 2, and index 3 should have a screenshot.
440 base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
441 content::TitleWatcher title_watcher(web_contents, expected_title);
442 aura::Window* content = web_contents->GetView()->GetContentNativeView();
443 gfx::Rect bounds = content->GetBoundsInRootWindow();
444 aura::test::EventGenerator generator(content->GetRootWindow(), content);
445 generator.GestureScrollSequence(
446 gfx::Point(bounds.x() + 2, bounds.y() + 10),
447 gfx::Point(bounds.right() - 10, bounds.y() + 10),
448 base::TimeDelta::FromMilliseconds(20),
450 base::string16 actual_title = title_watcher.WaitAndGetTitle();
451 EXPECT_EQ(expected_title, actual_title);
452 EXPECT_EQ(2, GetCurrentIndex());
453 screenshot_manager()->WaitUntilScreenshotIsReady();
454 entry = NavigationEntryImpl::FromNavigationEntry(
455 web_contents->GetController().GetEntryAtIndex(3));
456 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
459 // Navigate a couple more times.
460 ExecuteSyncJSFunction(view_host, "navigate_next()");
461 EXPECT_EQ(3, GetCurrentIndex());
462 ExecuteSyncJSFunction(view_host, "navigate_next()");
463 EXPECT_EQ(4, GetCurrentIndex());
464 screenshot_manager()->WaitUntilScreenshotIsReady();
465 entry = NavigationEntryImpl::FromNavigationEntry(
466 web_contents->GetController().GetEntryAtIndex(4));
467 EXPECT_FALSE(entry->screenshot().get());
470 // Navigate back in history.
471 base::string16 expected_title = base::ASCIIToUTF16("Title: #3");
472 content::TitleWatcher title_watcher(web_contents, expected_title);
473 web_contents->GetController().GoBack();
474 base::string16 actual_title = title_watcher.WaitAndGetTitle();
475 EXPECT_EQ(expected_title, actual_title);
476 EXPECT_EQ(3, GetCurrentIndex());
477 screenshot_manager()->WaitUntilScreenshotIsReady();
478 entry = NavigationEntryImpl::FromNavigationEntry(
479 web_contents->GetController().GetEntryAtIndex(4));
480 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
484 // Tests that screenshot is taken correctly when navigation causes a
485 // RenderViewHost to be swapped out.
486 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
487 ScreenshotForSwappedOutRenderViews) {
488 ASSERT_NO_FATAL_FAILURE(
489 StartTestWithPage("files/overscroll_navigation.html"));
490 // Create a new server with a different site.
491 net::SpawnedTestServer https_server(
492 net::SpawnedTestServer::TYPE_HTTPS,
493 net::SpawnedTestServer::kLocalhost,
494 base::FilePath(FILE_PATH_LITERAL("content/test/data")));
495 ASSERT_TRUE(https_server.Start());
497 WebContentsImpl* web_contents =
498 static_cast<WebContentsImpl*>(shell()->web_contents());
499 set_min_screenshot_interval(0);
505 { https_server.GetURL("files/title1.html"),
506 PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
507 { test_server()->GetURL("files/title2.html"),
508 PAGE_TRANSITION_AUTO_BOOKMARK },
509 { https_server.GetURL("files/title3.html"),
510 PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
514 screenshot_manager()->Reset();
515 for (int i = 0; !navigations[i].url.is_empty(); ++i) {
516 // Navigate via the user initiating a navigation from the UI.
517 NavigationController::LoadURLParams params(navigations[i].url);
518 params.transition_type = PageTransitionFromInt(navigations[i].transition);
520 RenderViewHost* old_host = web_contents->GetRenderViewHost();
521 web_contents->GetController().LoadURLWithParams(params);
522 WaitForLoadStop(web_contents);
523 screenshot_manager()->WaitUntilScreenshotIsReady();
525 EXPECT_NE(old_host, web_contents->GetRenderViewHost())
526 << navigations[i].url.spec();
527 EXPECT_EQ(old_host, screenshot_manager()->screenshot_taken_for());
529 NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
530 web_contents->GetController().GetEntryAtOffset(-1));
531 EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
533 entry = NavigationEntryImpl::FromNavigationEntry(
534 web_contents->GetController().GetLastCommittedEntry());
535 EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
536 EXPECT_FALSE(entry->screenshot().get());
537 screenshot_manager()->Reset();
540 // Increase the minimum interval between taking screenshots.
541 set_min_screenshot_interval(60000);
543 // Navigate again. This should not take any screenshot because of the
544 // increased screenshot interval.
545 NavigationController::LoadURLParams params(navigations[0].url);
546 params.transition_type = PageTransitionFromInt(navigations[0].transition);
547 web_contents->GetController().LoadURLWithParams(params);
548 WaitForLoadStop(web_contents);
549 screenshot_manager()->WaitUntilScreenshotIsReady();
551 EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
554 // TODO(sadrul): This test is disabled because it reparents in a way the
555 // FocusController does not support. This code would crash in
556 // a production build. It only passed prior to this revision
557 // because testing used the old FocusManager which did some
558 // different (osbolete) processing. TODO(sadrul) to figure out
559 // how this test should work that mimics production code a bit
561 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
562 DISABLED_ContentWindowReparent) {
563 ASSERT_NO_FATAL_FAILURE(
564 StartTestWithPage("files/overscroll_navigation.html"));
566 scoped_ptr<aura::Window> window(new aura::Window(NULL));
567 window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
569 WebContentsImpl* web_contents =
570 static_cast<WebContentsImpl*>(shell()->web_contents());
571 ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
572 EXPECT_EQ(1, GetCurrentIndex());
574 aura::Window* content = web_contents->GetView()->GetContentNativeView();
575 gfx::Rect bounds = content->GetBoundsInRootWindow();
576 aura::test::EventGenerator generator(content->GetRootWindow(), content);
577 generator.GestureScrollSequence(
578 gfx::Point(bounds.x() + 2, bounds.y() + 10),
579 gfx::Point(bounds.right() - 10, bounds.y() + 10),
580 base::TimeDelta::FromMilliseconds(20),
583 window->AddChild(shell()->web_contents()->GetView()->GetContentNativeView());
586 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
587 ContentWindowClose) {
588 ASSERT_NO_FATAL_FAILURE(
589 StartTestWithPage("files/overscroll_navigation.html"));
591 WebContentsImpl* web_contents =
592 static_cast<WebContentsImpl*>(shell()->web_contents());
593 ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
594 EXPECT_EQ(1, GetCurrentIndex());
596 aura::Window* content = web_contents->GetView()->GetContentNativeView();
597 gfx::Rect bounds = content->GetBoundsInRootWindow();
598 aura::test::EventGenerator generator(content->GetRootWindow(), content);
599 generator.GestureScrollSequence(
600 gfx::Point(bounds.x() + 2, bounds.y() + 10),
601 gfx::Point(bounds.right() - 10, bounds.y() + 10),
602 base::TimeDelta::FromMilliseconds(20),
605 delete web_contents->GetView()->GetContentNativeView();
608 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
609 RepeatedQuickOverscrollGestures) {
610 ASSERT_NO_FATAL_FAILURE(
611 StartTestWithPage("files/overscroll_navigation.html"));
613 WebContentsImpl* web_contents =
614 static_cast<WebContentsImpl*>(shell()->web_contents());
615 NavigationController& controller = web_contents->GetController();
616 RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
617 web_contents->GetRenderViewHost());
618 WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
619 web_contents->GetView());
620 view_aura->SetupOverlayWindowForTesting();
621 ExecuteSyncJSFunction(view_host, "install_touch_handler()");
623 // Navigate twice, then navigate back in history once.
624 ExecuteSyncJSFunction(view_host, "navigate_next()");
625 ExecuteSyncJSFunction(view_host, "navigate_next()");
626 EXPECT_EQ(2, GetCurrentIndex());
627 EXPECT_TRUE(controller.CanGoBack());
628 EXPECT_FALSE(controller.CanGoForward());
630 web_contents->GetController().GoBack();
631 WaitForLoadStop(web_contents);
632 EXPECT_EQ(1, GetCurrentIndex());
633 EXPECT_EQ(base::ASCIIToUTF16("Title: #1"), web_contents->GetTitle());
634 EXPECT_TRUE(controller.CanGoBack());
635 EXPECT_TRUE(controller.CanGoForward());
637 aura::Window* content = web_contents->GetView()->GetContentNativeView();
638 gfx::Rect bounds = content->GetBoundsInRootWindow();
639 aura::test::EventGenerator generator(content->GetRootWindow(), content);
641 // Do a swipe left to start a forward navigation. Then quickly do a swipe
643 base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
644 content::TitleWatcher title_watcher(web_contents, expected_title);
645 NavigationWatcher nav_watcher(web_contents);
647 generator.GestureScrollSequence(
648 gfx::Point(bounds.right() - 10, bounds.y() + 10),
649 gfx::Point(bounds.x() + 2, bounds.y() + 10),
650 base::TimeDelta::FromMilliseconds(2000),
652 nav_watcher.WaitUntilNavigationStarts();
654 generator.GestureScrollSequence(
655 gfx::Point(bounds.x() + 2, bounds.y() + 10),
656 gfx::Point(bounds.right() - 10, bounds.y() + 10),
657 base::TimeDelta::FromMilliseconds(2000),
659 base::string16 actual_title = title_watcher.WaitAndGetTitle();
660 EXPECT_EQ(expected_title, actual_title);
662 EXPECT_EQ(2, GetCurrentIndex());
663 EXPECT_TRUE(controller.CanGoBack());
664 EXPECT_FALSE(controller.CanGoForward());
667 } // namespace content