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