web_contents_view_aura_browsertest.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
1ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Use of this source code is governed by a BSD-style license that can be
3ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// found in the LICENSE file.
4ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
5ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/browser/web_contents/web_contents_view_aura.h"
6ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
7ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "base/command_line.h"
8ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "base/run_loop.h"
9ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "base/test/test_timeouts.h"
10ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "base/utf_string_conversions.h"
11ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "base/values.h"
12ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/browser/renderer_host/render_view_host_impl.h"
13ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/browser/web_contents/navigation_controller_impl.h"
14ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/browser/web_contents/navigation_entry_impl.h"
15ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/browser/web_contents/web_contents_impl.h"
16ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/browser/web_contents/web_contents_screenshot_manager.h"
17ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/public/browser/web_contents_view.h"
18ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/public/common/content_switches.h"
19ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/public/test/browser_test_utils.h"
20ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/public/test/test_utils.h"
21ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/shell/shell.h"
22ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/test/content_browser_test.h"
23ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "content/test/content_browser_test_utils.h"
24ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ui/aura/root_window.h"
25ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ui/aura/test/event_generator.h"
26ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ui/aura/window.h"
27ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#include "ui/compositor/scoped_animation_duration_scale_mode.h"
28ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
29ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovnamespace content {
30ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
31ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// This class keeps track of the RenderViewHost whose screenshot was captured.
32ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass ScreenshotTracker : public WebContentsScreenshotManager {
33ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov public:
34ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  explicit ScreenshotTracker(NavigationControllerImpl* controller)
35ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      : WebContentsScreenshotManager(controller),
36ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        screenshot_taken_for_(NULL),
37ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        waiting_for_screenshots_(0) {
38ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
39ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
40ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  virtual ~ScreenshotTracker() {
41ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
42ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
43ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  RenderViewHost* screenshot_taken_for() { return screenshot_taken_for_; }
44ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
45ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void Reset() {
46ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_taken_for_ = NULL;
47ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
48ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
49ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void SetScreenshotInterval(int interval_ms) {
50ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    SetMinScreenshotIntervalMS(interval_ms);
51ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
52ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
53ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void WaitUntilScreenshotIsReady() {
54ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!waiting_for_screenshots_)
55ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      return;
56ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    message_loop_runner_ = new content::MessageLoopRunner;
57ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    message_loop_runner_->Run();
58ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
59ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
60ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov private:
61ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Overridden from WebContentsScreenshotManager:
62ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  virtual void TakeScreenshotImpl(RenderViewHost* host,
63ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                                  NavigationEntryImpl* entry) OVERRIDE {
64ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ++waiting_for_screenshots_;
65ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_taken_for_ = host;
66ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WebContentsScreenshotManager::TakeScreenshotImpl(host, entry);
67ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
68ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
69ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  virtual void OnScreenshotSet(NavigationEntryImpl* entry) OVERRIDE {
70ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    --waiting_for_screenshots_;
71ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WebContentsScreenshotManager::OnScreenshotSet(entry);
72ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (waiting_for_screenshots_ == 0 && message_loop_runner_)
73ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      message_loop_runner_->Quit();
74ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
75ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
76ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  RenderViewHost* screenshot_taken_for_;
77ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  scoped_refptr<content::MessageLoopRunner> message_loop_runner_;
78ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  int waiting_for_screenshots_;
79ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
80ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  DISALLOW_COPY_AND_ASSIGN(ScreenshotTracker);
81ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
82ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
83ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganovclass WebContentsViewAuraTest : public ContentBrowserTest {
84ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov public:
85ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsViewAuraTest()
86ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      : screenshot_manager_(NULL) {
87ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
88ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
89ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Executes the javascript synchronously and makes sure the returned value is
90ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // freed properly.
91ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void ExecuteSyncJSFunction(RenderViewHost* rvh, const std::string& jscript) {
92ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    scoped_ptr<base::Value> value =
93ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        content::ExecuteScriptAndGetValue(rvh, jscript);
94ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
95ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
96ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Starts the test server and navigates to the given url. Sets a large enough
97ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // size to the root window.  Returns after the navigation to the url is
98ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // complete.
99ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void StartTestWithPage(const std::string& url) {
100ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT_TRUE(test_server()->Start());
101ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GURL test_url(test_server()->GetURL(url));
102ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NavigateToURL(shell(), test_url);
103ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aura::Window* content =
104ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        shell()->web_contents()->GetView()->GetContentNativeView();
105ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    content->GetRootWindow()->SetHostSize(gfx::Size(800, 600));
106ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
107ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WebContentsImpl* web_contents =
108ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static_cast<WebContentsImpl*>(shell()->web_contents());
109ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NavigationControllerImpl* controller = &web_contents->GetController();
110ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
111ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_manager_ = new ScreenshotTracker(controller);
112ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    controller->SetScreenshotManager(screenshot_manager_);
113ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
114ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
115ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void TestOverscrollNavigation(bool touch_handler) {
116ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT_NO_FATAL_FAILURE(
117ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        StartTestWithPage("files/overscroll_navigation.html"));
118ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WebContentsImpl* web_contents =
119ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static_cast<WebContentsImpl*>(shell()->web_contents());
120ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NavigationController& controller = web_contents->GetController();
121ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
122ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        web_contents->GetRenderViewHost());
123ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
124ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        web_contents->GetView());
125ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    view_aura->SetupOverlayWindowForTesting();
126ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
127ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_FALSE(controller.CanGoBack());
128ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_FALSE(controller.CanGoForward());
129ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = -1;
130ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    scoped_ptr<base::Value> value =
131ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        content::ExecuteScriptAndGetValue(view_host, "get_current()");
132ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT_TRUE(value->GetAsInteger(&index));
133ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(0, index);
134ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
135ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (touch_handler)
136ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      ExecuteSyncJSFunction(view_host, "install_touch_handler()");
137ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
138ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ExecuteSyncJSFunction(view_host, "navigate_next()");
139ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ExecuteSyncJSFunction(view_host, "navigate_next()");
140ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
141ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ASSERT_TRUE(value->GetAsInteger(&index));
142ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(2, index);
143ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_TRUE(controller.CanGoBack());
144ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_FALSE(controller.CanGoForward());
145ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
146ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aura::Window* content = web_contents->GetView()->GetContentNativeView();
147ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    gfx::Rect bounds = content->GetBoundsInRootWindow();
148ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aura::test::EventGenerator generator(content->GetRootWindow(), content);
149ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
150ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
151ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      // Do a swipe-right now. That should navigate backwards.
152ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      string16 expected_title = ASCIIToUTF16("Title: #1");
153ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      content::TitleWatcher title_watcher(web_contents, expected_title);
154ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      generator.GestureScrollSequence(
155ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          gfx::Point(bounds.x() + 2, bounds.y() + 10),
156ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          gfx::Point(bounds.right() - 10, bounds.y() + 10),
157ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          base::TimeDelta::FromMilliseconds(20),
158ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          1);
159ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      string16 actual_title = title_watcher.WaitAndGetTitle();
160ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_EQ(expected_title, actual_title);
161ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
162ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      ASSERT_TRUE(value->GetAsInteger(&index));
163ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_EQ(1, index);
164ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_TRUE(controller.CanGoBack());
165ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_TRUE(controller.CanGoForward());
166ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
167ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
168ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
169ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      // Do a fling-right now. That should navigate backwards.
170ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      string16 expected_title = ASCIIToUTF16("Title:");
171ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      content::TitleWatcher title_watcher(web_contents, expected_title);
172ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      generator.GestureScrollSequence(
173ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          gfx::Point(bounds.x() + 2, bounds.y() + 10),
174ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          gfx::Point(bounds.right() - 10, bounds.y() + 10),
175ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          base::TimeDelta::FromMilliseconds(20),
176ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          10);
177ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      string16 actual_title = title_watcher.WaitAndGetTitle();
178ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_EQ(expected_title, actual_title);
179ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
180ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      ASSERT_TRUE(value->GetAsInteger(&index));
181ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_EQ(0, index);
182ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_FALSE(controller.CanGoBack());
183ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_TRUE(controller.CanGoForward());
184ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
185ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
186ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    {
187ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      // Do a swipe-left now. That should navigate forward.
188ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      string16 expected_title = ASCIIToUTF16("Title: #1");
189ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      content::TitleWatcher title_watcher(web_contents, expected_title);
190ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      generator.GestureScrollSequence(
191ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          gfx::Point(bounds.right() - 10, bounds.y() + 10),
192ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          gfx::Point(bounds.x() + 2, bounds.y() + 10),
193ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          base::TimeDelta::FromMilliseconds(20),
194ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov          10);
195ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      string16 actual_title = title_watcher.WaitAndGetTitle();
196ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_EQ(expected_title, actual_title);
197ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
198ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      ASSERT_TRUE(value->GetAsInteger(&index));
199ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_EQ(1, index);
200ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_TRUE(controller.CanGoBack());
201ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      EXPECT_TRUE(controller.CanGoForward());
202ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    }
203ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
204ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
205ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  int GetCurrentIndex() {
206ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WebContentsImpl* web_contents =
207ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        static_cast<WebContentsImpl*>(shell()->web_contents());
208ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
209ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        web_contents->GetRenderViewHost());
210ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int index = -1;
211ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    scoped_ptr<base::Value> value;
212ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
213ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    if (!value->GetAsInteger(&index))
214ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      index = -1;
215ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    return index;
216ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
217ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
218ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov protected:
219ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ScreenshotTracker* screenshot_manager() { return screenshot_manager_; }
220ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  void set_min_screenshot_interval(int interval_ms) {
221ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_manager_->SetScreenshotInterval(interval_ms);
222ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
223ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
224ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov private:
225ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ScreenshotTracker* screenshot_manager_;
226ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
227ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  DISALLOW_COPY_AND_ASSIGN(WebContentsViewAuraTest);
228ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov};
229ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
230ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
231ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       OverscrollNavigation) {
232ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  TestOverscrollNavigation(false);
233ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
234ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
235ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
236ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       OverscrollNavigationWithTouchHandler) {
237ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  TestOverscrollNavigation(true);
238ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
239ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
240ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Disabled because the test always fails the first time it runs on the Win Aura
241ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// bots, and usually but not always passes second-try (See crbug.com/179532).
242ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#if defined(OS_WIN)
243ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAYBE_QuickOverscrollDirectionChange \
244ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        DISABLED_QuickOverscrollDirectionChange
245ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#else
246ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#define MAYBE_QuickOverscrollDirectionChange QuickOverscrollDirectionChange
247ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov#endif
248ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
249ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       MAYBE_QuickOverscrollDirectionChange) {
250ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ASSERT_NO_FATAL_FAILURE(
251ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      StartTestWithPage("files/overscroll_navigation.html"));
252ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsImpl* web_contents =
253ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      static_cast<WebContentsImpl*>(shell()->web_contents());
254ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
255ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetRenderViewHost());
256ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
257ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // This test triggers a large number of animations. Speed them up to ensure
258ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // the test completes within its time limit.
259ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ui::ScopedAnimationDurationScaleMode fast_duration_mode(
260ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
261ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
262ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Make sure the page has both back/forward history.
263ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
264ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
265ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
266ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(2, GetCurrentIndex());
267ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  web_contents->GetController().GoBack();
268ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
269ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
270ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::Window* content = web_contents->GetView()->GetContentNativeView();
271ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::RootWindow* root_window = content->GetRootWindow();
272ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  gfx::Rect bounds = content->GetBoundsInRootWindow();
273ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
274ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  base::TimeDelta timestamp;
275ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
276ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
277ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0, timestamp);
278ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&press);
279ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
280ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
281ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  timestamp += base::TimeDelta::FromMilliseconds(10);
282ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ui::TouchEvent move1(ui::ET_TOUCH_MOVED,
283ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.right() - 10, bounds.y() + 5),
284ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      0, timestamp);
285ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&move1);
286ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
287ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
288ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Swipe back from the right edge, back to the left edge, back to the right
289ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // edge.
290ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
291ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  for (int x = bounds.right() - 10; x >= bounds.x() + 10; x-= 10) {
292ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    timestamp += base::TimeDelta::FromMilliseconds(10);
293ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
294ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        gfx::Point(x, bounds.y() + 5),
295ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        0, timestamp);
296ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&inc);
297ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(1, GetCurrentIndex());
298ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
299ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
300ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  for (int x = bounds.x() + 10; x <= bounds.width() - 10; x+= 10) {
301ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    timestamp += base::TimeDelta::FromMilliseconds(10);
302ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
303ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        gfx::Point(x, bounds.y() + 5),
304ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        0, timestamp);
305ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&inc);
306ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(1, GetCurrentIndex());
307ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
308ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
309ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  for (int x = bounds.width() - 10; x >= bounds.x() + 10; x-= 10) {
310ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    timestamp += base::TimeDelta::FromMilliseconds(10);
311ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    ui::TouchEvent inc(ui::ET_TOUCH_MOVED,
312ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        gfx::Point(x, bounds.y() + 5),
313ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        0, timestamp);
314ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    root_window->AsRootWindowHostDelegate()->OnHostTouchEvent(&inc);
315ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(1, GetCurrentIndex());
316ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
317ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
318ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Do not end the overscroll sequence.
319ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
320ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
321ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Tests that the page has has a screenshot when navigation happens:
322ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  - from within the page (from a JS function)
323ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  - interactively, when user does an overscroll gesture
324ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//  - interactively, when user navigates in history without the overscroll
325ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov//    gesture.
326ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
327ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       OverscrollScreenshot) {
328ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ASSERT_NO_FATAL_FAILURE(
329ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      StartTestWithPage("files/overscroll_navigation.html"));
330ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsImpl* web_contents =
331ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      static_cast<WebContentsImpl*>(shell()->web_contents());
332ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
333ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetRenderViewHost());
334ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
335ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  set_min_screenshot_interval(0);
336ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
337ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Do a few navigations initiated by the page.
338ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
339ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
340ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
341ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(2, GetCurrentIndex());
342ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  screenshot_manager()->WaitUntilScreenshotIsReady();
343ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
344ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // The current entry won't have any screenshots. But the entries in the
345ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // history should now have screenshots.
346ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
347ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetController().GetEntryAtIndex(2));
348ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_FALSE(entry->screenshot().get());
349ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
350ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  entry = NavigationEntryImpl::FromNavigationEntry(
351ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetController().GetEntryAtIndex(1));
352ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_TRUE(entry->screenshot().get());
353ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
354ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  entry = NavigationEntryImpl::FromNavigationEntry(
355ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetController().GetEntryAtIndex(0));
356ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_TRUE(entry->screenshot().get());
357ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
358ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Navigate again. Index 2 should now have a screenshot.
359ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
360ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(3, GetCurrentIndex());
361ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  screenshot_manager()->WaitUntilScreenshotIsReady();
362ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
363ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  entry = NavigationEntryImpl::FromNavigationEntry(
364ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetController().GetEntryAtIndex(2));
365ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_TRUE(entry->screenshot().get());
366ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
367ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  entry = NavigationEntryImpl::FromNavigationEntry(
368ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetController().GetEntryAtIndex(3));
369ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_FALSE(entry->screenshot().get());
370ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
371ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
372ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Now, swipe right to navigate backwards. This should navigate away from
373ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // index 3 to index 2, and index 3 should have a screenshot.
374ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    string16 expected_title = ASCIIToUTF16("Title: #2");
375ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    content::TitleWatcher title_watcher(web_contents, expected_title);
376ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aura::Window* content = web_contents->GetView()->GetContentNativeView();
377ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    gfx::Rect bounds = content->GetBoundsInRootWindow();
378ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    aura::test::EventGenerator generator(content->GetRootWindow(), content);
379ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    generator.GestureScrollSequence(
380ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        gfx::Point(bounds.x() + 2, bounds.y() + 10),
381ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        gfx::Point(bounds.right() - 10, bounds.y() + 10),
382ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        base::TimeDelta::FromMilliseconds(20),
383ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        1);
384ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    string16 actual_title = title_watcher.WaitAndGetTitle();
385ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(expected_title, actual_title);
386ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(2, GetCurrentIndex());
387ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_manager()->WaitUntilScreenshotIsReady();
388ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    entry = NavigationEntryImpl::FromNavigationEntry(
389ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        web_contents->GetController().GetEntryAtIndex(3));
390ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_TRUE(entry->screenshot().get());
391ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
392ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
393ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Navigate a couple more times.
394ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
395ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(3, GetCurrentIndex());
396ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
397ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(4, GetCurrentIndex());
398ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  screenshot_manager()->WaitUntilScreenshotIsReady();
399ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  entry = NavigationEntryImpl::FromNavigationEntry(
400ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetController().GetEntryAtIndex(4));
401ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_FALSE(entry->screenshot().get());
402ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
403ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  {
404ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Navigate back in history.
405ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    string16 expected_title = ASCIIToUTF16("Title: #3");
406ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    content::TitleWatcher title_watcher(web_contents, expected_title);
407ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    web_contents->GetController().GoBack();
408ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    string16 actual_title = title_watcher.WaitAndGetTitle();
409ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(expected_title, actual_title);
410ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(3, GetCurrentIndex());
411ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_manager()->WaitUntilScreenshotIsReady();
412ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    entry = NavigationEntryImpl::FromNavigationEntry(
413ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        web_contents->GetController().GetEntryAtIndex(4));
414ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_TRUE(entry->screenshot().get());
415ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
416ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
417ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
418ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// Tests that screenshot is taken correctly when navigation causes a
419ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov// RenderViewHost to be swapped out.
420ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
421ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       ScreenshotForSwappedOutRenderViews) {
422ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ASSERT_NO_FATAL_FAILURE(
423ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      StartTestWithPage("files/overscroll_navigation.html"));
424ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Create a new server with a different site.
425ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  net::SpawnedTestServer https_server(
426ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      net::SpawnedTestServer::TYPE_HTTPS,
427ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      net::SpawnedTestServer::kLocalhost,
428ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      base::FilePath(FILE_PATH_LITERAL("content/test/data")));
429ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ASSERT_TRUE(https_server.Start());
430ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
431ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsImpl* web_contents =
432ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      static_cast<WebContentsImpl*>(shell()->web_contents());
433ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  set_min_screenshot_interval(0);
434ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
435ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  struct {
436ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    GURL url;
437ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    int transition;
438ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  } navigations[] = {
439ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { https_server.GetURL("files/title1.html"),
440ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
441ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { test_server()->GetURL("files/title2.html"),
442ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      PAGE_TRANSITION_AUTO_BOOKMARK },
443ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { https_server.GetURL("files/title3.html"),
444ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
445ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    { GURL(), 0 }
446ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  };
447ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
448ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  screenshot_manager()->Reset();
449ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  for (int i = 0; !navigations[i].url.is_empty(); ++i) {
450ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    // Navigate via the user initiating a navigation from the UI.
451ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NavigationController::LoadURLParams params(navigations[i].url);
452ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    params.transition_type = PageTransitionFromInt(navigations[i].transition);
453ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
454ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    RenderViewHost* old_host = web_contents->GetRenderViewHost();
455ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    web_contents->GetController().LoadURLWithParams(params);
456ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    WaitForLoadStop(web_contents);
457ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_manager()->WaitUntilScreenshotIsReady();
458ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
459ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_NE(old_host, web_contents->GetRenderViewHost())
460ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        << navigations[i].url.spec();
461ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_EQ(old_host, screenshot_manager()->screenshot_taken_for());
462ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    screenshot_manager()->Reset();
463ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
464ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
465ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        web_contents->GetController().GetEntryAtOffset(-1));
466ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_TRUE(entry->screenshot().get());
467ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
468ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    entry = NavigationEntryImpl::FromNavigationEntry(
469ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov        web_contents->GetController().GetActiveEntry());
470ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov    EXPECT_FALSE(entry->screenshot().get());
471ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  }
472ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
473ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Increase the minimum interval between taking screenshots.
474ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  set_min_screenshot_interval(60000);
475ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
476ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Navigate again. This should not take any screenshot because of the
477ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // increased screenshot interval.
478ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  NavigationController::LoadURLParams params(navigations[0].url);
479ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  params.transition_type = PageTransitionFromInt(navigations[0].transition);
480ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  web_contents->GetController().LoadURLWithParams(params);
481ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WaitForLoadStop(web_contents);
482ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  screenshot_manager()->WaitUntilScreenshotIsReady();
483ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
484ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
485ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
486ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
487ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
488ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       ContentWindowReparent) {
489ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ASSERT_NO_FATAL_FAILURE(
490ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      StartTestWithPage("files/overscroll_navigation.html"));
491ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
492ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  scoped_ptr<aura::Window> window(new aura::Window(NULL));
493ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  window->Init(ui::LAYER_NOT_DRAWN);
494ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
495ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsImpl* web_contents =
496ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      static_cast<WebContentsImpl*>(shell()->web_contents());
497ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
498ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
499ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
500ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::Window* content = web_contents->GetView()->GetContentNativeView();
501ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  gfx::Rect bounds = content->GetBoundsInRootWindow();
502ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::test::EventGenerator generator(content->GetRootWindow(), content);
503ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  generator.GestureScrollSequence(
504ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.x() + 2, bounds.y() + 10),
505ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.right() - 10, bounds.y() + 10),
506ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      base::TimeDelta::FromMilliseconds(20),
507ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      1);
508ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
509ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  window->AddChild(shell()->web_contents()->GetView()->GetContentNativeView());
510ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
511ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
512ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
513ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       ContentWindowClose) {
514ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ASSERT_NO_FATAL_FAILURE(
515ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      StartTestWithPage("files/overscroll_navigation.html"));
516ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
517ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsImpl* web_contents =
518ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      static_cast<WebContentsImpl*>(shell()->web_contents());
519ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
520ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
521ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
522ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::Window* content = web_contents->GetView()->GetContentNativeView();
523ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  gfx::Rect bounds = content->GetBoundsInRootWindow();
524ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::test::EventGenerator generator(content->GetRootWindow(), content);
525ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  generator.GestureScrollSequence(
526ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.x() + 2, bounds.y() + 10),
527ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.right() - 10, bounds.y() + 10),
528ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      base::TimeDelta::FromMilliseconds(20),
529ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      1);
530ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
531ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  delete web_contents->GetView()->GetContentNativeView();
532ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
533ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
534ee451cb395940862dad63c85adfe8f2fd55e864cSvet GanovIN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
535ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov                       RepeatedQuickOverscrollGestures) {
536ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ASSERT_NO_FATAL_FAILURE(
537ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      StartTestWithPage("files/overscroll_navigation.html"));
538ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
539ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsImpl* web_contents =
540ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      static_cast<WebContentsImpl*>(shell()->web_contents());
541ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  NavigationController& controller = web_contents->GetController();
542ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
543ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetRenderViewHost());
544ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
545ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      web_contents->GetView());
546ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  view_aura->SetupOverlayWindowForTesting();
547ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "install_touch_handler()");
548ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
549ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Navigate twice, then navigate back in history once.
550ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
551ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  ExecuteSyncJSFunction(view_host, "navigate_next()");
552ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(2, GetCurrentIndex());
553ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_TRUE(controller.CanGoBack());
554ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_FALSE(controller.CanGoForward());
555ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
556ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  web_contents->GetController().GoBack();
557ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  WaitForLoadStop(web_contents);
558ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(1, GetCurrentIndex());
559ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_TRUE(controller.CanGoBack());
560ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_TRUE(controller.CanGoForward());
561ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
562ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::Window* content = web_contents->GetView()->GetContentNativeView();
563ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  gfx::Rect bounds = content->GetBoundsInRootWindow();
564ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  aura::test::EventGenerator generator(content->GetRootWindow(), content);
565ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
566ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Do a swipe left to start a forward navigation. Then quickly do a swipe
567ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // right.
568ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  string16 expected_title = ASCIIToUTF16("Title: #2");
569ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  content::TitleWatcher title_watcher(web_contents, expected_title);
570ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
571ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  generator.GestureScrollSequence(
572ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.right() - 10, bounds.y() + 10),
573ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.x() + 2, bounds.y() + 10),
574ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      base::TimeDelta::FromMilliseconds(2000),
575ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      10);
576ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  // Make sure the GestureEventFilter's debouncing doesn't interfere.
577ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  base::MessageLoop::current()->PostDelayedTask(
578ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      FROM_HERE,
579ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      base::MessageLoop::QuitClosure(),
580ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      base::TimeDelta::FromMilliseconds(100));
581ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  base::MessageLoop::current()->Run();
582ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  generator.GestureScrollSequence(
583ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.x() + 2, bounds.y() + 10),
584ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      gfx::Point(bounds.right() - 10, bounds.y() + 10),
585ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      base::TimeDelta::FromMilliseconds(2000),
586ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov      10);
587ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  string16 actual_title = title_watcher.WaitAndGetTitle();
588ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(expected_title, actual_title);
589ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
590ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_EQ(2, GetCurrentIndex());
591ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_TRUE(controller.CanGoBack());
592ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov  EXPECT_FALSE(controller.CanGoForward());
593ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}
594ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov
595ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov}  // namespace content
596ee451cb395940862dad63c85adfe8f2fd55e864cSvet Ganov