685097e5f0851c0190c5ab57e836623ec5bac6a8
[platform/framework/web/crosswalk.git] / src / content / browser / web_contents / web_contents_view_aura_browsertest.cc
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.
4
5 #include "content/browser/web_contents/web_contents_view_aura.h"
6
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/web_contents/web_contents_impl.h"
19 #include "content/browser/web_contents/web_contents_view.h"
20 #include "content/common/view_messages.h"
21 #include "content/public/browser/render_frame_host.h"
22 #include "content/public/browser/web_contents_observer.h"
23 #include "content/public/common/content_switches.h"
24 #include "content/public/test/browser_test_utils.h"
25 #include "content/public/test/content_browser_test.h"
26 #include "content/public/test/content_browser_test_utils.h"
27 #include "content/public/test/test_renderer_host.h"
28 #include "content/public/test/test_utils.h"
29 #include "content/shell/browser/shell.h"
30 #include "ui/aura/test/event_generator.h"
31 #include "ui/aura/window.h"
32 #include "ui/aura/window_tree_host.h"
33 #include "ui/compositor/scoped_animation_duration_scale_mode.h"
34 #include "ui/events/event_processor.h"
35 #include "ui/events/event_utils.h"
36
37 namespace content {
38
39 // This class keeps track of the RenderViewHost whose screenshot was captured.
40 class ScreenshotTracker : public NavigationEntryScreenshotManager {
41  public:
42   explicit ScreenshotTracker(NavigationControllerImpl* controller)
43       : NavigationEntryScreenshotManager(controller),
44         screenshot_taken_for_(NULL),
45         waiting_for_screenshots_(0) {
46   }
47
48   virtual ~ScreenshotTracker() {
49   }
50
51   RenderViewHost* screenshot_taken_for() { return screenshot_taken_for_; }
52
53   void Reset() {
54     screenshot_taken_for_ = NULL;
55     screenshot_set_.clear();
56   }
57
58   void SetScreenshotInterval(int interval_ms) {
59     SetMinScreenshotIntervalMS(interval_ms);
60   }
61
62   void WaitUntilScreenshotIsReady() {
63     if (!waiting_for_screenshots_)
64       return;
65     message_loop_runner_ = new content::MessageLoopRunner;
66     message_loop_runner_->Run();
67   }
68
69   bool ScreenshotSetForEntry(NavigationEntryImpl* entry) const {
70     return screenshot_set_.count(entry) > 0;
71   }
72
73  private:
74   // Overridden from NavigationEntryScreenshotManager:
75   virtual void TakeScreenshotImpl(RenderViewHost* host,
76                                   NavigationEntryImpl* entry) OVERRIDE {
77     ++waiting_for_screenshots_;
78     screenshot_taken_for_ = host;
79     NavigationEntryScreenshotManager::TakeScreenshotImpl(host, entry);
80   }
81
82   virtual void OnScreenshotSet(NavigationEntryImpl* entry) OVERRIDE {
83     --waiting_for_screenshots_;
84     screenshot_set_[entry] = true;
85     NavigationEntryScreenshotManager::OnScreenshotSet(entry);
86     if (waiting_for_screenshots_ == 0 && message_loop_runner_.get())
87       message_loop_runner_->Quit();
88   }
89
90   RenderViewHost* screenshot_taken_for_;
91   scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
92   int waiting_for_screenshots_;
93   std::map<NavigationEntryImpl*, bool> screenshot_set_;
94
95   DISALLOW_COPY_AND_ASSIGN(ScreenshotTracker);
96 };
97
98 class NavigationWatcher : public WebContentsObserver {
99  public:
100   explicit NavigationWatcher(WebContents* contents)
101       : WebContentsObserver(contents),
102         navigated_(false),
103         should_quit_loop_(false) {
104   }
105
106   virtual ~NavigationWatcher() {}
107
108   void WaitUntilNavigationStarts() {
109     if (navigated_)
110       return;
111     should_quit_loop_ = true;
112     base::MessageLoop::current()->Run();
113   }
114
115  private:
116   // Overridden from WebContentsObserver:
117   virtual void AboutToNavigateRenderView(RenderViewHost* host) OVERRIDE {
118     navigated_ = true;
119     if (should_quit_loop_)
120       base::MessageLoop::current()->Quit();
121   }
122
123   bool navigated_;
124   bool should_quit_loop_;
125
126   DISALLOW_COPY_AND_ASSIGN(NavigationWatcher);
127 };
128
129 class WebContentsViewAuraTest : public ContentBrowserTest {
130  public:
131   WebContentsViewAuraTest()
132       : screenshot_manager_(NULL) {
133   }
134
135   // Executes the javascript synchronously and makes sure the returned value is
136   // freed properly.
137   void ExecuteSyncJSFunction(RenderFrameHost* rfh, const std::string& jscript) {
138     scoped_ptr<base::Value> value =
139         content::ExecuteScriptAndGetValue(rfh, jscript);
140   }
141
142   // Starts the test server and navigates to the given url. Sets a large enough
143   // size to the root window.  Returns after the navigation to the url is
144   // complete.
145   void StartTestWithPage(const std::string& url) {
146     ASSERT_TRUE(test_server()->Start());
147     GURL test_url(test_server()->GetURL(url));
148     NavigateToURL(shell(), test_url);
149
150     WebContentsImpl* web_contents =
151         static_cast<WebContentsImpl*>(shell()->web_contents());
152     NavigationControllerImpl* controller = &web_contents->GetController();
153
154     screenshot_manager_ = new ScreenshotTracker(controller);
155     controller->SetScreenshotManager(screenshot_manager_);
156   }
157
158   void TestOverscrollNavigation(bool touch_handler) {
159     ASSERT_NO_FATAL_FAILURE(
160         StartTestWithPage("files/overscroll_navigation.html"));
161     WebContentsImpl* web_contents =
162         static_cast<WebContentsImpl*>(shell()->web_contents());
163     NavigationController& controller = web_contents->GetController();
164     RenderFrameHost* main_frame = web_contents->GetMainFrame();
165
166     EXPECT_FALSE(controller.CanGoBack());
167     EXPECT_FALSE(controller.CanGoForward());
168     int index = -1;
169     scoped_ptr<base::Value> value =
170         content::ExecuteScriptAndGetValue(main_frame, "get_current()");
171     ASSERT_TRUE(value->GetAsInteger(&index));
172     EXPECT_EQ(0, index);
173
174     if (touch_handler)
175       ExecuteSyncJSFunction(main_frame, "install_touch_handler()");
176
177     ExecuteSyncJSFunction(main_frame, "navigate_next()");
178     ExecuteSyncJSFunction(main_frame, "navigate_next()");
179     value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
180     ASSERT_TRUE(value->GetAsInteger(&index));
181     EXPECT_EQ(2, index);
182     EXPECT_TRUE(controller.CanGoBack());
183     EXPECT_FALSE(controller.CanGoForward());
184
185     aura::Window* content = web_contents->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;
190
191     {
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),
199           kScrollSteps);
200       base::string16 actual_title = title_watcher.WaitAndGetTitle();
201       EXPECT_EQ(expected_title, actual_title);
202       value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
203       ASSERT_TRUE(value->GetAsInteger(&index));
204       EXPECT_EQ(1, index);
205       EXPECT_TRUE(controller.CanGoBack());
206       EXPECT_TRUE(controller.CanGoForward());
207     }
208
209     {
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),
217           kScrollSteps);
218       base::string16 actual_title = title_watcher.WaitAndGetTitle();
219       EXPECT_EQ(expected_title, actual_title);
220       value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
221       ASSERT_TRUE(value->GetAsInteger(&index));
222       EXPECT_EQ(0, index);
223       EXPECT_FALSE(controller.CanGoBack());
224       EXPECT_TRUE(controller.CanGoForward());
225     }
226
227     {
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),
235           kScrollSteps);
236       base::string16 actual_title = title_watcher.WaitAndGetTitle();
237       EXPECT_EQ(expected_title, actual_title);
238       value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
239       ASSERT_TRUE(value->GetAsInteger(&index));
240       EXPECT_EQ(1, index);
241       EXPECT_TRUE(controller.CanGoBack());
242       EXPECT_TRUE(controller.CanGoForward());
243     }
244   }
245
246   int GetCurrentIndex() {
247     WebContentsImpl* web_contents =
248         static_cast<WebContentsImpl*>(shell()->web_contents());
249     RenderFrameHost* main_frame = web_contents->GetMainFrame();
250     int index = -1;
251     scoped_ptr<base::Value> value;
252     value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
253     if (!value->GetAsInteger(&index))
254       index = -1;
255     return index;
256   }
257
258  protected:
259   ScreenshotTracker* screenshot_manager() { return screenshot_manager_; }
260   void set_min_screenshot_interval(int interval_ms) {
261     screenshot_manager_->SetScreenshotInterval(interval_ms);
262   }
263
264  private:
265   ScreenshotTracker* screenshot_manager_;
266
267   DISALLOW_COPY_AND_ASSIGN(WebContentsViewAuraTest);
268 };
269
270 // Flaky on Windows and ChromeOS: http://crbug.com/305722
271 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
272     DISABLED_OverscrollNavigation) {
273   TestOverscrollNavigation(false);
274 }
275
276 // Flaky on Windows (might be related to the above test):
277 // http://crbug.com/305722
278 #if defined(OS_WIN)
279 #define MAYBE_OverscrollNavigationWithTouchHandler \
280         DISABLED_OverscrollNavigationWithTouchHandler
281 #else
282 #define MAYBE_OverscrollNavigationWithTouchHandler \
283         OverscrollNavigationWithTouchHandler
284 #endif
285 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
286                        MAYBE_OverscrollNavigationWithTouchHandler) {
287   TestOverscrollNavigation(true);
288 }
289
290 // Disabled because the test always fails the first time it runs on the Win Aura
291 // bots, and usually but not always passes second-try (See crbug.com/179532).
292 #if defined(OS_WIN)
293 #define MAYBE_QuickOverscrollDirectionChange \
294         DISABLED_QuickOverscrollDirectionChange
295 #else
296 #define MAYBE_QuickOverscrollDirectionChange QuickOverscrollDirectionChange
297 #endif
298 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
299                        MAYBE_QuickOverscrollDirectionChange) {
300   ASSERT_NO_FATAL_FAILURE(
301       StartTestWithPage("files/overscroll_navigation.html"));
302   WebContentsImpl* web_contents =
303       static_cast<WebContentsImpl*>(shell()->web_contents());
304   RenderFrameHost* main_frame = web_contents->GetMainFrame();
305
306   // This test triggers a large number of animations. Speed them up to ensure
307   // the test completes within its time limit.
308   ui::ScopedAnimationDurationScaleMode fast_duration_mode(
309       ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
310
311   // Make sure the page has both back/forward history.
312   ExecuteSyncJSFunction(main_frame, "navigate_next()");
313   EXPECT_EQ(1, GetCurrentIndex());
314   ExecuteSyncJSFunction(main_frame, "navigate_next()");
315   EXPECT_EQ(2, GetCurrentIndex());
316   web_contents->GetController().GoBack();
317   EXPECT_EQ(1, GetCurrentIndex());
318
319   aura::Window* content = web_contents->GetContentNativeView();
320   ui::EventProcessor* dispatcher = content->GetHost()->event_processor();
321   gfx::Rect bounds = content->GetBoundsInRootWindow();
322
323   base::TimeDelta timestamp = ui::EventTimeForNow();
324   ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
325       gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
326       0, timestamp);
327   ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
328   ASSERT_FALSE(details.dispatcher_destroyed);
329   EXPECT_EQ(1, GetCurrentIndex());
330
331   timestamp += base::TimeDelta::FromMilliseconds(10);
332   ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
333       gfx::Point(bounds.right() - 10, bounds.y() + 5),
334       0, timestamp);
335   details = dispatcher->OnEventFromSource(&move1);
336   ASSERT_FALSE(details.dispatcher_destroyed);
337   EXPECT_EQ(1, GetCurrentIndex());
338
339   // Swipe back from the right edge, back to the left edge, back to the right
340   // edge.
341
342   for (int x = bounds.right() - 10; x >= bounds.x() + 10; x-= 10) {
343     timestamp += base::TimeDelta::FromMilliseconds(10);
344     ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
345         gfx::Point(x, bounds.y() + 5),
346         0, timestamp);
347     details = dispatcher->OnEventFromSource(&inc);
348     ASSERT_FALSE(details.dispatcher_destroyed);
349     EXPECT_EQ(1, GetCurrentIndex());
350   }
351
352   for (int x = bounds.x() + 10; x <= bounds.width() - 10; x+= 10) {
353     timestamp += base::TimeDelta::FromMilliseconds(10);
354     ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
355         gfx::Point(x, bounds.y() + 5),
356         0, timestamp);
357     details = dispatcher->OnEventFromSource(&inc);
358     ASSERT_FALSE(details.dispatcher_destroyed);
359     EXPECT_EQ(1, GetCurrentIndex());
360   }
361
362   for (int x = bounds.width() - 10; x >= bounds.x() + 10; x-= 10) {
363     timestamp += base::TimeDelta::FromMilliseconds(10);
364     ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
365         gfx::Point(x, bounds.y() + 5),
366         0, timestamp);
367     details = dispatcher->OnEventFromSource(&inc);
368     ASSERT_FALSE(details.dispatcher_destroyed);
369     EXPECT_EQ(1, GetCurrentIndex());
370   }
371
372   // Do not end the overscroll sequence.
373 }
374
375 // Tests that the page has has a screenshot when navigation happens:
376 //  - from within the page (from a JS function)
377 //  - interactively, when user does an overscroll gesture
378 //  - interactively, when user navigates in history without the overscroll
379 //    gesture.
380 // Flaky on Windows and ChromeOS (http://crbug.com/357311). Might be related to
381 // OverscrollNavigation test.
382 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, DISABLED_OverscrollScreenshot) {
383   // Disable the test for WinXP.  See http://crbug/294116.
384 #if defined(OS_WIN)
385   if (base::win::GetVersion() < base::win::VERSION_VISTA) {
386     LOG(WARNING) << "Test disabled due to unknown bug on WinXP.";
387     return;
388   }
389 #endif
390
391   ASSERT_NO_FATAL_FAILURE(
392       StartTestWithPage("files/overscroll_navigation.html"));
393   WebContentsImpl* web_contents =
394       static_cast<WebContentsImpl*>(shell()->web_contents());
395   RenderFrameHost* main_frame = web_contents->GetMainFrame();
396
397   set_min_screenshot_interval(0);
398
399   // Do a few navigations initiated by the page.
400   ExecuteSyncJSFunction(main_frame, "navigate_next()");
401   EXPECT_EQ(1, GetCurrentIndex());
402   ExecuteSyncJSFunction(main_frame, "navigate_next()");
403   EXPECT_EQ(2, GetCurrentIndex());
404   screenshot_manager()->WaitUntilScreenshotIsReady();
405
406   // The current entry won't have any screenshots. But the entries in the
407   // history should now have screenshots.
408   NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
409       web_contents->GetController().GetEntryAtIndex(2));
410   EXPECT_FALSE(entry->screenshot().get());
411
412   entry = NavigationEntryImpl::FromNavigationEntry(
413       web_contents->GetController().GetEntryAtIndex(1));
414   EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
415
416   entry = NavigationEntryImpl::FromNavigationEntry(
417       web_contents->GetController().GetEntryAtIndex(0));
418   EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
419
420   // Navigate again. Index 2 should now have a screenshot.
421   ExecuteSyncJSFunction(main_frame, "navigate_next()");
422   EXPECT_EQ(3, GetCurrentIndex());
423   screenshot_manager()->WaitUntilScreenshotIsReady();
424
425   entry = NavigationEntryImpl::FromNavigationEntry(
426       web_contents->GetController().GetEntryAtIndex(2));
427   EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
428
429   entry = NavigationEntryImpl::FromNavigationEntry(
430       web_contents->GetController().GetEntryAtIndex(3));
431   EXPECT_FALSE(entry->screenshot().get());
432
433   {
434     // Now, swipe right to navigate backwards. This should navigate away from
435     // index 3 to index 2, and index 3 should have a screenshot.
436     base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
437     content::TitleWatcher title_watcher(web_contents, expected_title);
438     aura::Window* content = web_contents->GetContentNativeView();
439     gfx::Rect bounds = content->GetBoundsInRootWindow();
440     aura::test::EventGenerator generator(content->GetRootWindow(), content);
441     generator.GestureScrollSequence(
442         gfx::Point(bounds.x() + 2, bounds.y() + 10),
443         gfx::Point(bounds.right() - 10, bounds.y() + 10),
444         base::TimeDelta::FromMilliseconds(20),
445         1);
446     base::string16 actual_title = title_watcher.WaitAndGetTitle();
447     EXPECT_EQ(expected_title, actual_title);
448     EXPECT_EQ(2, GetCurrentIndex());
449     screenshot_manager()->WaitUntilScreenshotIsReady();
450     entry = NavigationEntryImpl::FromNavigationEntry(
451         web_contents->GetController().GetEntryAtIndex(3));
452     EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
453   }
454
455   // Navigate a couple more times.
456   ExecuteSyncJSFunction(main_frame, "navigate_next()");
457   EXPECT_EQ(3, GetCurrentIndex());
458   ExecuteSyncJSFunction(main_frame, "navigate_next()");
459   EXPECT_EQ(4, GetCurrentIndex());
460   screenshot_manager()->WaitUntilScreenshotIsReady();
461   entry = NavigationEntryImpl::FromNavigationEntry(
462       web_contents->GetController().GetEntryAtIndex(4));
463   EXPECT_FALSE(entry->screenshot().get());
464
465   {
466     // Navigate back in history.
467     base::string16 expected_title = base::ASCIIToUTF16("Title: #3");
468     content::TitleWatcher title_watcher(web_contents, expected_title);
469     web_contents->GetController().GoBack();
470     base::string16 actual_title = title_watcher.WaitAndGetTitle();
471     EXPECT_EQ(expected_title, actual_title);
472     EXPECT_EQ(3, GetCurrentIndex());
473     screenshot_manager()->WaitUntilScreenshotIsReady();
474     entry = NavigationEntryImpl::FromNavigationEntry(
475         web_contents->GetController().GetEntryAtIndex(4));
476     EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
477   }
478 }
479
480 // Crashes under ThreadSanitizer, http://crbug.com/356758.
481 #if defined(THREAD_SANITIZER)
482 #define MAYBE_ScreenshotForSwappedOutRenderViews \
483     DISABLED_ScreenshotForSwappedOutRenderViews
484 #else
485 #define MAYBE_ScreenshotForSwappedOutRenderViews \
486     ScreenshotForSwappedOutRenderViews
487 #endif
488 // Tests that screenshot is taken correctly when navigation causes a
489 // RenderViewHost to be swapped out.
490 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
491                        MAYBE_ScreenshotForSwappedOutRenderViews) {
492   ASSERT_NO_FATAL_FAILURE(
493       StartTestWithPage("files/overscroll_navigation.html"));
494   // Create a new server with a different site.
495   net::SpawnedTestServer https_server(
496       net::SpawnedTestServer::TYPE_HTTPS,
497       net::SpawnedTestServer::kLocalhost,
498       base::FilePath(FILE_PATH_LITERAL("content/test/data")));
499   ASSERT_TRUE(https_server.Start());
500
501   WebContentsImpl* web_contents =
502       static_cast<WebContentsImpl*>(shell()->web_contents());
503   set_min_screenshot_interval(0);
504
505   struct {
506     GURL url;
507     int transition;
508   } navigations[] = {
509     { https_server.GetURL("files/title1.html"),
510       PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
511     { test_server()->GetURL("files/title2.html"),
512       PAGE_TRANSITION_AUTO_BOOKMARK },
513     { https_server.GetURL("files/title3.html"),
514       PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
515     { GURL(), 0 }
516   };
517
518   screenshot_manager()->Reset();
519   for (int i = 0; !navigations[i].url.is_empty(); ++i) {
520     // Navigate via the user initiating a navigation from the UI.
521     NavigationController::LoadURLParams params(navigations[i].url);
522     params.transition_type = PageTransitionFromInt(navigations[i].transition);
523
524     RenderViewHost* old_host = web_contents->GetRenderViewHost();
525     web_contents->GetController().LoadURLWithParams(params);
526     WaitForLoadStop(web_contents);
527     screenshot_manager()->WaitUntilScreenshotIsReady();
528
529     EXPECT_NE(old_host, web_contents->GetRenderViewHost())
530         << navigations[i].url.spec();
531     EXPECT_EQ(old_host, screenshot_manager()->screenshot_taken_for());
532
533     NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
534         web_contents->GetController().GetEntryAtOffset(-1));
535     EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
536
537     entry = NavigationEntryImpl::FromNavigationEntry(
538         web_contents->GetController().GetLastCommittedEntry());
539     EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
540     EXPECT_FALSE(entry->screenshot().get());
541     screenshot_manager()->Reset();
542   }
543
544   // Increase the minimum interval between taking screenshots.
545   set_min_screenshot_interval(60000);
546
547   // Navigate again. This should not take any screenshot because of the
548   // increased screenshot interval.
549   NavigationController::LoadURLParams params(navigations[0].url);
550   params.transition_type = PageTransitionFromInt(navigations[0].transition);
551   web_contents->GetController().LoadURLWithParams(params);
552   WaitForLoadStop(web_contents);
553   screenshot_manager()->WaitUntilScreenshotIsReady();
554
555   EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
556 }
557
558 // Tests that navigations resulting from reloads and history.replaceState
559 // do not capture screenshots while navigations resulting from
560 // histrory.pushState do.
561 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ReplaceStateReloadPushState) {
562   ASSERT_NO_FATAL_FAILURE(
563       StartTestWithPage("files/overscroll_navigation.html"));
564   WebContentsImpl* web_contents =
565       static_cast<WebContentsImpl*>(shell()->web_contents());
566   RenderFrameHost* main_frame = web_contents->GetMainFrame();
567
568   set_min_screenshot_interval(0);
569   screenshot_manager()->Reset();
570   ExecuteSyncJSFunction(main_frame, "use_replace_state()");
571   screenshot_manager()->WaitUntilScreenshotIsReady();
572   // history.replaceState shouldn't capture a screenshot
573   EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
574   screenshot_manager()->Reset();
575   web_contents->GetController().Reload(true);
576   WaitForLoadStop(web_contents);
577   // reloading the page shouldn't capture a screenshot
578   EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
579   screenshot_manager()->Reset();
580   ExecuteSyncJSFunction(main_frame, "use_push_state()");
581   screenshot_manager()->WaitUntilScreenshotIsReady();
582   // pushing a state should capture a screenshot
583   EXPECT_TRUE(screenshot_manager()->screenshot_taken_for());
584 }
585
586 // TODO(sadrul): This test is disabled because it reparents in a way the
587 //               FocusController does not support. This code would crash in
588 //               a production build. It only passed prior to this revision
589 //               because testing used the old FocusManager which did some
590 //               different (osbolete) processing. TODO(sadrul) to figure out
591 //               how this test should work that mimics production code a bit
592 //               better.
593 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
594                        DISABLED_ContentWindowReparent) {
595   ASSERT_NO_FATAL_FAILURE(
596       StartTestWithPage("files/overscroll_navigation.html"));
597
598   scoped_ptr<aura::Window> window(new aura::Window(NULL));
599   window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
600
601   WebContentsImpl* web_contents =
602       static_cast<WebContentsImpl*>(shell()->web_contents());
603   ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
604   EXPECT_EQ(1, GetCurrentIndex());
605
606   aura::Window* content = web_contents->GetContentNativeView();
607   gfx::Rect bounds = content->GetBoundsInRootWindow();
608   aura::test::EventGenerator generator(content->GetRootWindow(), content);
609   generator.GestureScrollSequence(
610       gfx::Point(bounds.x() + 2, bounds.y() + 10),
611       gfx::Point(bounds.right() - 10, bounds.y() + 10),
612       base::TimeDelta::FromMilliseconds(20),
613       1);
614
615   window->AddChild(shell()->web_contents()->GetContentNativeView());
616 }
617
618 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ContentWindowClose) {
619   ASSERT_NO_FATAL_FAILURE(
620       StartTestWithPage("files/overscroll_navigation.html"));
621
622   WebContentsImpl* web_contents =
623       static_cast<WebContentsImpl*>(shell()->web_contents());
624   ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
625   EXPECT_EQ(1, GetCurrentIndex());
626
627   aura::Window* content = web_contents->GetContentNativeView();
628   gfx::Rect bounds = content->GetBoundsInRootWindow();
629   aura::test::EventGenerator generator(content->GetRootWindow(), content);
630   generator.GestureScrollSequence(
631       gfx::Point(bounds.x() + 2, bounds.y() + 10),
632       gfx::Point(bounds.right() - 10, bounds.y() + 10),
633       base::TimeDelta::FromMilliseconds(20),
634       1);
635
636   delete web_contents->GetContentNativeView();
637 }
638
639
640 #if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
641 // This appears to be flaky in the same was as the other overscroll
642 // tests. Enabling for non-Windows platforms.
643 // See http://crbug.com/369871.
644 // For linux, see http://crbug.com/381294
645 #define MAYBE_RepeatedQuickOverscrollGestures DISABLED_RepeatedQuickOverscrollGestures
646 #else
647 #define MAYBE_RepeatedQuickOverscrollGestures RepeatedQuickOverscrollGestures
648 #endif
649
650 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
651                        MAYBE_RepeatedQuickOverscrollGestures) {
652   ASSERT_NO_FATAL_FAILURE(
653       StartTestWithPage("files/overscroll_navigation.html"));
654
655   WebContentsImpl* web_contents =
656       static_cast<WebContentsImpl*>(shell()->web_contents());
657   NavigationController& controller = web_contents->GetController();
658   RenderFrameHost* main_frame = web_contents->GetMainFrame();
659   ExecuteSyncJSFunction(main_frame, "install_touch_handler()");
660
661   // Navigate twice, then navigate back in history once.
662   ExecuteSyncJSFunction(main_frame, "navigate_next()");
663   ExecuteSyncJSFunction(main_frame, "navigate_next()");
664   EXPECT_EQ(2, GetCurrentIndex());
665   EXPECT_TRUE(controller.CanGoBack());
666   EXPECT_FALSE(controller.CanGoForward());
667
668   web_contents->GetController().GoBack();
669   WaitForLoadStop(web_contents);
670   EXPECT_EQ(1, GetCurrentIndex());
671   EXPECT_EQ(base::ASCIIToUTF16("Title: #1"), web_contents->GetTitle());
672   EXPECT_TRUE(controller.CanGoBack());
673   EXPECT_TRUE(controller.CanGoForward());
674
675   aura::Window* content = web_contents->GetContentNativeView();
676   gfx::Rect bounds = content->GetBoundsInRootWindow();
677   aura::test::EventGenerator generator(content->GetRootWindow(), content);
678
679   // Do a swipe left to start a forward navigation. Then quickly do a swipe
680   // right.
681   base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
682   content::TitleWatcher title_watcher(web_contents, expected_title);
683   NavigationWatcher nav_watcher(web_contents);
684
685   generator.GestureScrollSequence(
686       gfx::Point(bounds.right() - 10, bounds.y() + 10),
687       gfx::Point(bounds.x() + 2, bounds.y() + 10),
688       base::TimeDelta::FromMilliseconds(2000),
689       10);
690   nav_watcher.WaitUntilNavigationStarts();
691
692   generator.GestureScrollSequence(
693       gfx::Point(bounds.x() + 2, bounds.y() + 10),
694       gfx::Point(bounds.right() - 10, bounds.y() + 10),
695       base::TimeDelta::FromMilliseconds(2000),
696       10);
697   base::string16 actual_title = title_watcher.WaitAndGetTitle();
698   EXPECT_EQ(expected_title, actual_title);
699
700   EXPECT_EQ(2, GetCurrentIndex());
701   EXPECT_TRUE(controller.CanGoBack());
702   EXPECT_FALSE(controller.CanGoForward());
703 }
704
705 // Verify that hiding a parent of the renderer will hide the content too.
706 IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, HideContentOnParenHide) {
707   ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/title1.html"));
708   WebContentsImpl* web_contents =
709       static_cast<WebContentsImpl*>(shell()->web_contents());
710   aura::Window* content = web_contents->GetNativeView()->parent();
711   EXPECT_TRUE(web_contents->should_normally_be_visible());
712   content->Hide();
713   EXPECT_FALSE(web_contents->should_normally_be_visible());
714   content->Show();
715   EXPECT_TRUE(web_contents->should_normally_be_visible());
716 }
717
718 }  // namespace content