#include "content/browser/frame_host/navigation_controller_impl.h"
#include "content/browser/frame_host/navigation_entry_impl.h"
#include "content/browser/frame_host/navigation_entry_screenshot_manager.h"
-#include "content/browser/renderer_host/render_view_host_impl.h"
+#include "content/browser/renderer_host/render_widget_host_view_aura.h"
#include "content/browser/web_contents/web_contents_impl.h"
+#include "content/browser/web_contents/web_contents_view.h"
+#include "content/common/input/synthetic_web_input_event_builders.h"
+#include "content/common/input_messages.h"
+#include "content/common/view_messages.h"
+#include "content/public/browser/browser_message_filter.h"
+#include "content/public/browser/render_frame_host.h"
+#include "content/public/browser/web_contents_delegate.h"
#include "content/public/browser/web_contents_observer.h"
-#include "content/public/browser/web_contents_view.h"
#include "content/public/common/content_switches.h"
#include "content/public/test/browser_test_utils.h"
+#include "content/public/test/content_browser_test.h"
+#include "content/public/test/content_browser_test_utils.h"
+#include "content/public/test/test_renderer_host.h"
#include "content/public/test/test_utils.h"
#include "content/shell/browser/shell.h"
-#include "content/test/content_browser_test.h"
-#include "content/test/content_browser_test_utils.h"
-#include "ui/aura/root_window.h"
-#include "ui/aura/test/event_generator.h"
#include "ui/aura/window.h"
+#include "ui/aura/window_tree_host.h"
#include "ui/compositor/scoped_animation_duration_scale_mode.h"
+#include "ui/events/event_processor.h"
+#include "ui/events/event_switches.h"
+#include "ui/events/event_utils.h"
+#include "ui/events/test/event_generator.h"
+
+namespace {
+
+// TODO(tdresser): Find a way to avoid sleeping like this. See crbug.com/405282
+// for details.
+void GiveItSomeTime() {
+ base::RunLoop run_loop;
+ base::MessageLoop::current()->PostDelayedTask(
+ FROM_HERE,
+ run_loop.QuitClosure(),
+ base::TimeDelta::FromMillisecondsD(10));
+ run_loop.Run();
+}
+
+// WebContentsDelegate which tracks vertical overscroll updates.
+class VerticalOverscrollTracker : public content::WebContentsDelegate {
+ public:
+ VerticalOverscrollTracker() : count_(0), completed_(false) {}
+ virtual ~VerticalOverscrollTracker() {}
+
+ int num_overscroll_updates() const {
+ return count_;
+ }
+
+ bool overscroll_completed() const {
+ return completed_;
+ }
+
+ void Reset() {
+ count_ = 0;
+ completed_ = false;
+ }
+
+ private:
+ virtual bool CanOverscrollContent() const OVERRIDE {
+ return true;
+ }
+
+ virtual void OverscrollUpdate(int delta_y) OVERRIDE {
+ ++count_;
+ }
+
+ virtual void OverscrollComplete() OVERRIDE {
+ completed_ = true;
+ }
+
+ int count_;
+ bool completed_;
+
+ DISALLOW_COPY_AND_ASSIGN(VerticalOverscrollTracker);
+};
+
+} //namespace
+
namespace content {
DISALLOW_COPY_AND_ASSIGN(NavigationWatcher);
};
+class InputEventMessageFilterWaitsForAcks : public BrowserMessageFilter {
+ public:
+ InputEventMessageFilterWaitsForAcks()
+ : BrowserMessageFilter(InputMsgStart),
+ type_(blink::WebInputEvent::Undefined),
+ state_(INPUT_EVENT_ACK_STATE_UNKNOWN) {}
+
+ void WaitForAck(blink::WebInputEvent::Type type) {
+ base::RunLoop run_loop;
+ base::AutoReset<base::Closure> reset_quit(&quit_, run_loop.QuitClosure());
+ base::AutoReset<blink::WebInputEvent::Type> reset_type(&type_, type);
+ run_loop.Run();
+ }
+
+ InputEventAckState last_ack_state() const { return state_; }
+
+ protected:
+ virtual ~InputEventMessageFilterWaitsForAcks() {}
+
+ private:
+ void ReceivedEventAck(blink::WebInputEvent::Type type,
+ InputEventAckState state) {
+ if (type_ == type) {
+ state_ = state;
+ quit_.Run();
+ }
+ }
+
+ // BrowserMessageFilter:
+ virtual bool OnMessageReceived(const IPC::Message& message) OVERRIDE {
+ if (message.type() == InputHostMsg_HandleInputEvent_ACK::ID) {
+ InputHostMsg_HandleInputEvent_ACK::Param params;
+ InputHostMsg_HandleInputEvent_ACK::Read(&message, ¶ms);
+ blink::WebInputEvent::Type type = params.a.type;
+ InputEventAckState ack = params.a.state;
+ BrowserThread::PostTask(BrowserThread::UI, FROM_HERE,
+ base::Bind(&InputEventMessageFilterWaitsForAcks::ReceivedEventAck,
+ this, type, ack));
+ }
+ return false;
+ }
+
+ base::Closure quit_;
+ blink::WebInputEvent::Type type_;
+ InputEventAckState state_;
+
+ DISALLOW_COPY_AND_ASSIGN(InputEventMessageFilterWaitsForAcks);
+};
+
class WebContentsViewAuraTest : public ContentBrowserTest {
public:
WebContentsViewAuraTest()
// Executes the javascript synchronously and makes sure the returned value is
// freed properly.
- void ExecuteSyncJSFunction(RenderViewHost* rvh, const std::string& jscript) {
+ void ExecuteSyncJSFunction(RenderFrameHost* rfh, const std::string& jscript) {
scoped_ptr<base::Value> value =
- content::ExecuteScriptAndGetValue(rvh, jscript);
+ content::ExecuteScriptAndGetValue(rfh, jscript);
}
// Starts the test server and navigates to the given url. Sets a large enough
controller->SetScreenshotManager(screenshot_manager_);
}
+ virtual void SetUpCommandLine(CommandLine* cmd) OVERRIDE {
+ cmd->AppendSwitchASCII(switches::kTouchEvents,
+ switches::kTouchEventsEnabled);
+ }
+
void TestOverscrollNavigation(bool touch_handler) {
ASSERT_NO_FATAL_FAILURE(
StartTestWithPage("files/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
NavigationController& controller = web_contents->GetController();
- RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
- web_contents->GetRenderViewHost());
- WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
- web_contents->GetView());
- view_aura->SetupOverlayWindowForTesting();
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
EXPECT_FALSE(controller.CanGoBack());
EXPECT_FALSE(controller.CanGoForward());
int index = -1;
scoped_ptr<base::Value> value =
- content::ExecuteScriptAndGetValue(view_host, "get_current()");
+ content::ExecuteScriptAndGetValue(main_frame, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
EXPECT_EQ(0, index);
if (touch_handler)
- ExecuteSyncJSFunction(view_host, "install_touch_handler()");
+ ExecuteSyncJSFunction(main_frame, "install_touch_handler()");
- ExecuteSyncJSFunction(view_host, "navigate_next()");
- ExecuteSyncJSFunction(view_host, "navigate_next()");
- value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
+ value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
EXPECT_EQ(2, index);
EXPECT_TRUE(controller.CanGoBack());
EXPECT_FALSE(controller.CanGoForward());
- aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::Window* content = web_contents->GetContentNativeView();
gfx::Rect bounds = content->GetBoundsInRootWindow();
- aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ ui::test::EventGenerator generator(content->GetRootWindow(), content);
const int kScrollDurationMs = 20;
const int kScrollSteps = 10;
kScrollSteps);
base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
- value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
+ value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
EXPECT_EQ(1, index);
EXPECT_TRUE(controller.CanGoBack());
kScrollSteps);
base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
- value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
+ value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
EXPECT_EQ(0, index);
EXPECT_FALSE(controller.CanGoBack());
kScrollSteps);
base::string16 actual_title = title_watcher.WaitAndGetTitle();
EXPECT_EQ(expected_title, actual_title);
- value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
+ value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
ASSERT_TRUE(value->GetAsInteger(&index));
EXPECT_EQ(1, index);
EXPECT_TRUE(controller.CanGoBack());
int GetCurrentIndex() {
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
- RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
- web_contents->GetRenderViewHost());
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
int index = -1;
scoped_ptr<base::Value> value;
- value = content::ExecuteScriptAndGetValue(view_host, "get_current()");
+ value = content::ExecuteScriptAndGetValue(main_frame, "get_current()");
if (!value->GetAsInteger(&index))
index = -1;
return index;
}
+ int ExecuteScriptAndExtractInt(const std::string& script) {
+ int value = 0;
+ EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
+ shell()->web_contents(),
+ "domAutomationController.send(" + script + ")",
+ &value));
+ return value;
+ }
+
+ RenderViewHost* GetRenderViewHost() const {
+ RenderViewHost* const rvh = shell()->web_contents()->GetRenderViewHost();
+ CHECK(rvh);
+ return rvh;
+ }
+
+ RenderWidgetHostImpl* GetRenderWidgetHost() const {
+ RenderWidgetHostImpl* const rwh =
+ RenderWidgetHostImpl::From(shell()
+ ->web_contents()
+ ->GetRenderWidgetHostView()
+ ->GetRenderWidgetHost());
+ CHECK(rwh);
+ return rwh;
+ }
+
+ RenderWidgetHostViewBase* GetRenderWidgetHostView() const {
+ return static_cast<RenderWidgetHostViewBase*>(
+ GetRenderViewHost()->GetView());
+ }
+
+ InputEventMessageFilterWaitsForAcks* filter() {
+ return filter_.get();
+ }
+
+ void WaitAFrame() {
+ uint32 frame = GetRenderWidgetHostView()->RendererFrameNumber();
+ while (!GetRenderWidgetHost()->ScheduleComposite())
+ GiveItSomeTime();
+ while (GetRenderWidgetHostView()->RendererFrameNumber() == frame)
+ GiveItSomeTime();
+ }
+
protected:
ScreenshotTracker* screenshot_manager() { return screenshot_manager_; }
void set_min_screenshot_interval(int interval_ms) {
screenshot_manager_->SetScreenshotInterval(interval_ms);
}
+ void AddInputEventMessageFilter() {
+ filter_ = new InputEventMessageFilterWaitsForAcks();
+ GetRenderWidgetHost()->GetProcess()->AddFilter(filter_.get());
+ }
+
private:
ScreenshotTracker* screenshot_manager_;
+ scoped_refptr<InputEventMessageFilterWaitsForAcks> filter_;
DISALLOW_COPY_AND_ASSIGN(WebContentsViewAuraTest);
};
-// Flaky on Windows (perhaps just Win-Aura): http://crbug.com/305722
+// Flaky on Windows: http://crbug.com/305722
#if defined(OS_WIN)
#define MAYBE_OverscrollNavigation DISABLED_OverscrollNavigation
#else
#define MAYBE_OverscrollNavigation OverscrollNavigation
#endif
+
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollNavigation) {
TestOverscrollNavigation(false);
}
-// Flaky on Windows (perhaps just Win-Aura): http://crbug.com/305722
+// Flaky on Windows (might be related to the above test):
+// http://crbug.com/305722
#if defined(OS_WIN)
#define MAYBE_OverscrollNavigationWithTouchHandler \
DISABLED_OverscrollNavigationWithTouchHandler
StartTestWithPage("files/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
- RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
- web_contents->GetRenderViewHost());
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
// This test triggers a large number of animations. Speed them up to ensure
// the test completes within its time limit.
ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
// Make sure the page has both back/forward history.
- ExecuteSyncJSFunction(view_host, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
EXPECT_EQ(1, GetCurrentIndex());
- ExecuteSyncJSFunction(view_host, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
EXPECT_EQ(2, GetCurrentIndex());
web_contents->GetController().GoBack();
EXPECT_EQ(1, GetCurrentIndex());
- aura::Window* content = web_contents->GetView()->GetContentNativeView();
- aura::WindowEventDispatcher* dispatcher = content->GetDispatcher();
+ aura::Window* content = web_contents->GetContentNativeView();
+ ui::EventProcessor* dispatcher = content->GetHost()->event_processor();
gfx::Rect bounds = content->GetBoundsInRootWindow();
- base::TimeDelta timestamp;
+ base::TimeDelta timestamp = ui::EventTimeForNow();
ui::TouchEvent press(ui::ET_TOUCH_PRESSED,
gfx::Point(bounds.x() + bounds.width() / 2, bounds.y() + 5),
0, timestamp);
// - interactively, when user does an overscroll gesture
// - interactively, when user navigates in history without the overscroll
// gesture.
-IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, OverscrollScreenshot) {
+// Flaky on Windows (http://crbug.com/357311). Might be related to
+// OverscrollNavigation test.
+// Flaky on Ozone (http://crbug.com/399676).
+// Flaky on ChromeOS (http://crbug.com/405945).
+#if defined(OS_WIN) || defined(USE_OZONE) || defined(OS_CHROMEOS)
+#define MAYBE_OverscrollScreenshot DISABLED_OverscrollScreenshot
+#else
+#define MAYBE_OverscrollScreenshot OverscrollScreenshot
+#endif
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_OverscrollScreenshot) {
// Disable the test for WinXP. See http://crbug/294116.
#if defined(OS_WIN)
if (base::win::GetVersion() < base::win::VERSION_VISTA) {
StartTestWithPage("files/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
- RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
- web_contents->GetRenderViewHost());
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
set_min_screenshot_interval(0);
// Do a few navigations initiated by the page.
- ExecuteSyncJSFunction(view_host, "navigate_next()");
+ // Screenshots should never be captured since these are all in-page
+ // navigations.
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
EXPECT_EQ(1, GetCurrentIndex());
- ExecuteSyncJSFunction(view_host, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
EXPECT_EQ(2, GetCurrentIndex());
screenshot_manager()->WaitUntilScreenshotIsReady();
- // The current entry won't have any screenshots. But the entries in the
- // history should now have screenshots.
NavigationEntryImpl* entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(2));
EXPECT_FALSE(entry->screenshot().get());
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(1));
- EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
+ EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(0));
- EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
+ EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
- // Navigate again. Index 2 should now have a screenshot.
- ExecuteSyncJSFunction(view_host, "navigate_next()");
- EXPECT_EQ(3, GetCurrentIndex());
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(2));
- EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
+ EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(3));
EXPECT_FALSE(entry->screenshot().get());
-
{
// Now, swipe right to navigate backwards. This should navigate away from
- // index 3 to index 2, and index 3 should have a screenshot.
+ // index 3 to index 2.
base::string16 expected_title = base::ASCIIToUTF16("Title: #2");
content::TitleWatcher title_watcher(web_contents, expected_title);
- aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::Window* content = web_contents->GetContentNativeView();
gfx::Rect bounds = content->GetBoundsInRootWindow();
- aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ ui::test::EventGenerator generator(content->GetRootWindow(), content);
generator.GestureScrollSequence(
gfx::Point(bounds.x() + 2, bounds.y() + 10),
gfx::Point(bounds.right() - 10, bounds.y() + 10),
screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(3));
- EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
+ EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
}
// Navigate a couple more times.
- ExecuteSyncJSFunction(view_host, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
EXPECT_EQ(3, GetCurrentIndex());
- ExecuteSyncJSFunction(view_host, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
EXPECT_EQ(4, GetCurrentIndex());
screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
screenshot_manager()->WaitUntilScreenshotIsReady();
entry = NavigationEntryImpl::FromNavigationEntry(
web_contents->GetController().GetEntryAtIndex(4));
- EXPECT_TRUE(screenshot_manager()->ScreenshotSetForEntry(entry));
+ EXPECT_FALSE(screenshot_manager()->ScreenshotSetForEntry(entry));
}
}
+// Crashes under ThreadSanitizer, http://crbug.com/356758.
+#if defined(THREAD_SANITIZER)
+#define MAYBE_ScreenshotForSwappedOutRenderViews \
+ DISABLED_ScreenshotForSwappedOutRenderViews
+#else
+#define MAYBE_ScreenshotForSwappedOutRenderViews \
+ ScreenshotForSwappedOutRenderViews
+#endif
// Tests that screenshot is taken correctly when navigation causes a
// RenderViewHost to be swapped out.
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
- ScreenshotForSwappedOutRenderViews) {
+ MAYBE_ScreenshotForSwappedOutRenderViews) {
ASSERT_NO_FATAL_FAILURE(
StartTestWithPage("files/overscroll_navigation.html"));
// Create a new server with a different site.
int transition;
} navigations[] = {
{ https_server.GetURL("files/title1.html"),
- PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
+ ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
{ test_server()->GetURL("files/title2.html"),
- PAGE_TRANSITION_AUTO_BOOKMARK },
+ ui::PAGE_TRANSITION_AUTO_BOOKMARK },
{ https_server.GetURL("files/title3.html"),
- PAGE_TRANSITION_TYPED | PAGE_TRANSITION_FROM_ADDRESS_BAR },
+ ui::PAGE_TRANSITION_TYPED | ui::PAGE_TRANSITION_FROM_ADDRESS_BAR },
{ GURL(), 0 }
};
for (int i = 0; !navigations[i].url.is_empty(); ++i) {
// Navigate via the user initiating a navigation from the UI.
NavigationController::LoadURLParams params(navigations[i].url);
- params.transition_type = PageTransitionFromInt(navigations[i].transition);
+ params.transition_type =
+ ui::PageTransitionFromInt(navigations[i].transition);
RenderViewHost* old_host = web_contents->GetRenderViewHost();
web_contents->GetController().LoadURLWithParams(params);
// Navigate again. This should not take any screenshot because of the
// increased screenshot interval.
NavigationController::LoadURLParams params(navigations[0].url);
- params.transition_type = PageTransitionFromInt(navigations[0].transition);
+ params.transition_type = ui::PageTransitionFromInt(navigations[0].transition);
web_contents->GetController().LoadURLWithParams(params);
WaitForLoadStop(web_contents);
screenshot_manager()->WaitUntilScreenshotIsReady();
EXPECT_EQ(NULL, screenshot_manager()->screenshot_taken_for());
}
+// Tests that navigations resulting from reloads, history.replaceState,
+// and history.pushState do not capture screenshots.
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ReplaceStateReloadPushState) {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/overscroll_navigation.html"));
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
+
+ set_min_screenshot_interval(0);
+ screenshot_manager()->Reset();
+ ExecuteSyncJSFunction(main_frame, "use_replace_state()");
+ screenshot_manager()->WaitUntilScreenshotIsReady();
+ // history.replaceState shouldn't capture a screenshot
+ EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
+ screenshot_manager()->Reset();
+ web_contents->GetController().Reload(true);
+ WaitForLoadStop(web_contents);
+ // reloading the page shouldn't capture a screenshot
+ // TODO (mfomitchev): currently broken. Uncomment when
+ // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
+ // is populated properly when reloading the page.
+ //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
+ screenshot_manager()->Reset();
+ ExecuteSyncJSFunction(main_frame, "use_push_state()");
+ screenshot_manager()->WaitUntilScreenshotIsReady();
+ // pushing a state shouldn't capture a screenshot
+ // TODO (mfomitchev): currently broken. Uncomment when
+ // FrameHostMsg_DidCommitProvisionalLoad_Params.was_within_same_page
+ // is populated properly when pushState is used.
+ //EXPECT_FALSE(screenshot_manager()->screenshot_taken_for());
+}
+
// TODO(sadrul): This test is disabled because it reparents in a way the
// FocusController does not support. This code would crash in
// a production build. It only passed prior to this revision
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
- ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
+ ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
EXPECT_EQ(1, GetCurrentIndex());
- aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::Window* content = web_contents->GetContentNativeView();
gfx::Rect bounds = content->GetBoundsInRootWindow();
- aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ ui::test::EventGenerator generator(content->GetRootWindow(), content);
generator.GestureScrollSequence(
gfx::Point(bounds.x() + 2, bounds.y() + 10),
gfx::Point(bounds.right() - 10, bounds.y() + 10),
base::TimeDelta::FromMilliseconds(20),
1);
- window->AddChild(shell()->web_contents()->GetView()->GetContentNativeView());
+ window->AddChild(shell()->web_contents()->GetContentNativeView());
}
-IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
- ContentWindowClose) {
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, ContentWindowClose) {
ASSERT_NO_FATAL_FAILURE(
StartTestWithPage("files/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
- ExecuteSyncJSFunction(web_contents->GetRenderViewHost(), "navigate_next()");
+ ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
EXPECT_EQ(1, GetCurrentIndex());
- aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::Window* content = web_contents->GetContentNativeView();
gfx::Rect bounds = content->GetBoundsInRootWindow();
- aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ ui::test::EventGenerator generator(content->GetRootWindow(), content);
generator.GestureScrollSequence(
gfx::Point(bounds.x() + 2, bounds.y() + 10),
gfx::Point(bounds.right() - 10, bounds.y() + 10),
base::TimeDelta::FromMilliseconds(20),
1);
- delete web_contents->GetView()->GetContentNativeView();
+ delete web_contents->GetContentNativeView();
}
+
+#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+// This appears to be flaky in the same was as the other overscroll
+// tests. Enabling for non-Windows platforms.
+// See http://crbug.com/369871.
+// For linux, see http://crbug.com/381294
+#define MAYBE_RepeatedQuickOverscrollGestures DISABLED_RepeatedQuickOverscrollGestures
+#else
+#define MAYBE_RepeatedQuickOverscrollGestures RepeatedQuickOverscrollGestures
+#endif
+
IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
- RepeatedQuickOverscrollGestures) {
+ MAYBE_RepeatedQuickOverscrollGestures) {
ASSERT_NO_FATAL_FAILURE(
StartTestWithPage("files/overscroll_navigation.html"));
WebContentsImpl* web_contents =
static_cast<WebContentsImpl*>(shell()->web_contents());
NavigationController& controller = web_contents->GetController();
- RenderViewHostImpl* view_host = static_cast<RenderViewHostImpl*>(
- web_contents->GetRenderViewHost());
- WebContentsViewAura* view_aura = static_cast<WebContentsViewAura*>(
- web_contents->GetView());
- view_aura->SetupOverlayWindowForTesting();
- ExecuteSyncJSFunction(view_host, "install_touch_handler()");
+ RenderFrameHost* main_frame = web_contents->GetMainFrame();
+ ExecuteSyncJSFunction(main_frame, "install_touch_handler()");
// Navigate twice, then navigate back in history once.
- ExecuteSyncJSFunction(view_host, "navigate_next()");
- ExecuteSyncJSFunction(view_host, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
+ ExecuteSyncJSFunction(main_frame, "navigate_next()");
EXPECT_EQ(2, GetCurrentIndex());
EXPECT_TRUE(controller.CanGoBack());
EXPECT_FALSE(controller.CanGoForward());
EXPECT_TRUE(controller.CanGoBack());
EXPECT_TRUE(controller.CanGoForward());
- aura::Window* content = web_contents->GetView()->GetContentNativeView();
+ aura::Window* content = web_contents->GetContentNativeView();
gfx::Rect bounds = content->GetBoundsInRootWindow();
- aura::test::EventGenerator generator(content->GetRootWindow(), content);
+ ui::test::EventGenerator generator(content->GetRootWindow(), content);
// Do a swipe left to start a forward navigation. Then quickly do a swipe
// right.
EXPECT_FALSE(controller.CanGoForward());
}
+// Verify that hiding a parent of the renderer will hide the content too.
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, HideContentOnParenHide) {
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("files/title1.html"));
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ aura::Window* content = web_contents->GetNativeView()->parent();
+ EXPECT_TRUE(web_contents->should_normally_be_visible());
+ content->Hide();
+ EXPECT_FALSE(web_contents->should_normally_be_visible());
+ content->Show();
+ EXPECT_TRUE(web_contents->should_normally_be_visible());
+}
+
+// Ensure that SnapToPhysicalPixelBoundary() is called on WebContentsView parent
+// change. This is a regression test for http://crbug.com/388908.
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, WebContentsViewReparent) {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/overscroll_navigation.html"));
+
+ scoped_ptr<aura::Window> window(new aura::Window(NULL));
+ window->Init(aura::WINDOW_LAYER_NOT_DRAWN);
+
+ RenderWidgetHostViewAura* rwhva =
+ static_cast<RenderWidgetHostViewAura*>(
+ shell()->web_contents()->GetRenderWidgetHostView());
+ rwhva->ResetHasSnappedToBoundary();
+ EXPECT_FALSE(rwhva->has_snapped_to_boundary());
+ window->AddChild(shell()->web_contents()->GetNativeView());
+ EXPECT_TRUE(rwhva->has_snapped_to_boundary());
+}
+
+// Flaky on some platforms, likely for the same reason as other flaky overscroll
+// tests. http://crbug.com/305722
+// TODO(tdresser): Re-enable this once eager GR is back on. See
+// crbug.com/410280.
+#if defined(OS_WIN) || (defined(OS_LINUX) && !defined(OS_CHROMEOS))
+#define MAYBE_OverscrollNavigationTouchThrottling \
+ DISABLED_OverscrollNavigationTouchThrottling
+#else
+#define MAYBE_OverscrollNavigationTouchThrottling \
+ DISABLED_OverscrollNavigationTouchThrottling
+#endif
+
+// Tests that touch moves are not throttled when performing a scroll gesture on
+// a non-scrollable area, except during gesture-nav.
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest,
+ MAYBE_OverscrollNavigationTouchThrottling) {
+ ASSERT_NO_FATAL_FAILURE(
+ StartTestWithPage("files/overscroll_navigation.html"));
+
+ AddInputEventMessageFilter();
+
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ aura::Window* content = web_contents->GetContentNativeView();
+ gfx::Rect bounds = content->GetBoundsInRootWindow();
+ const int dx = 20;
+
+ ExecuteSyncJSFunction(web_contents->GetMainFrame(),
+ "install_touchmove_handler()");
+
+ WaitAFrame();
+
+ for (int navigated = 0; navigated <= 1; ++navigated) {
+ if (navigated) {
+ ExecuteSyncJSFunction(web_contents->GetMainFrame(), "navigate_next()");
+ ExecuteSyncJSFunction(web_contents->GetMainFrame(),
+ "reset_touchmove_count()");
+ }
+ // Send touch press.
+ SyntheticWebTouchEvent touch;
+ touch.PressPoint(bounds.x() + 2, bounds.y() + 10);
+ GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
+ ui::LatencyInfo());
+ filter()->WaitForAck(blink::WebInputEvent::TouchStart);
+ WaitAFrame();
+
+ // Assert on the ack, because we'll end up waiting for acks that will never
+ // come if this is not true.
+ ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
+
+ // Send first touch move, and then a scroll begin.
+ touch.MovePoint(0, bounds.x() + 20 + 1 * dx, bounds.y() + 100);
+ GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
+ ui::LatencyInfo());
+ filter()->WaitForAck(blink::WebInputEvent::TouchMove);
+ ASSERT_EQ(INPUT_EVENT_ACK_STATE_NOT_CONSUMED, filter()->last_ack_state());
+
+ blink::WebGestureEvent scroll_begin =
+ SyntheticWebGestureEventBuilder::BuildScrollBegin(1, 1);
+ GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
+ scroll_begin, ui::LatencyInfo());
+ // Scroll begin ignores ack disposition, so don't wait for the ack.
+ WaitAFrame();
+
+ // First touchmove already sent, start at 2.
+ for (int i = 2; i <= 10; ++i) {
+ // Send a touch move, followed by a scroll update
+ touch.MovePoint(0, bounds.x() + 20 + i * dx, bounds.y() + 100);
+ GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(
+ touch, ui::LatencyInfo());
+ WaitAFrame();
+
+ blink::WebGestureEvent scroll_update =
+ SyntheticWebGestureEventBuilder::BuildScrollUpdate(dx, 5, 0);
+
+ GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
+ scroll_update, ui::LatencyInfo());
+
+ WaitAFrame();
+ }
+
+ touch.ReleasePoint(0);
+ GetRenderWidgetHost()->ForwardTouchEventWithLatencyInfo(touch,
+ ui::LatencyInfo());
+ WaitAFrame();
+
+ blink::WebGestureEvent scroll_end;
+ scroll_end.type = blink::WebInputEvent::GestureScrollEnd;
+ GetRenderWidgetHost()->ForwardGestureEventWithLatencyInfo(
+ scroll_end, ui::LatencyInfo());
+ WaitAFrame();
+
+ if (!navigated)
+ EXPECT_EQ(10, ExecuteScriptAndExtractInt("touchmoveCount"));
+ else
+ EXPECT_GT(10, ExecuteScriptAndExtractInt("touchmoveCount"));
+ }
+}
+
+// Test that vertical overscroll updates are sent only when a user overscrolls
+// vertically.
+#if defined(OS_WIN)
+#define MAYBE_VerticalOverscroll DISABLED_VerticalOverscroll
+#else
+#define MAYBE_VerticalOverscroll VerticalOverscroll
+#endif
+
+IN_PROC_BROWSER_TEST_F(WebContentsViewAuraTest, MAYBE_VerticalOverscroll) {
+ base::CommandLine::ForCurrentProcess()->AppendSwitchASCII(
+ switches::kScrollEndEffect, "1");
+
+ ASSERT_NO_FATAL_FAILURE(StartTestWithPage("about:blank"));
+ WebContentsImpl* web_contents =
+ static_cast<WebContentsImpl*>(shell()->web_contents());
+ VerticalOverscrollTracker tracker;
+ web_contents->SetDelegate(&tracker);
+
+ // This test triggers a large number of animations. Speed them up to ensure
+ // the test completes within its time limit.
+ ui::ScopedAnimationDurationScaleMode fast_duration_mode(
+ ui::ScopedAnimationDurationScaleMode::FAST_DURATION);
+
+ aura::Window* content = web_contents->GetContentNativeView();
+ ui::EventProcessor* dispatcher = content->GetHost()->event_processor();
+ gfx::Rect bounds = content->GetBoundsInRootWindow();
+
+ // Overscroll horizontally.
+ {
+ int kXStep = bounds.width() / 10;
+ gfx::Point location(bounds.right() - kXStep, bounds.y() + 5);
+ base::TimeDelta timestamp = ui::EventTimeForNow();
+ ui::TouchEvent press(
+ ui::ET_TOUCH_PRESSED,
+ location,
+ 0,
+ timestamp);
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+ location -= gfx::Vector2d(kXStep, 0);
+ timestamp += base::TimeDelta::FromMilliseconds(10);
+
+ while (location.x() > bounds.x() + kXStep) {
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
+ details = dispatcher->OnEventFromSource(&inc);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+ location -= gfx::Vector2d(10, 0);
+ timestamp += base::TimeDelta::FromMilliseconds(10);
+ }
+
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
+ details = dispatcher->OnEventFromSource(&press);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+
+ EXPECT_EQ(0, tracker.num_overscroll_updates());
+ EXPECT_FALSE(tracker.overscroll_completed());
+ }
+
+ // Overscroll vertically.
+ {
+ tracker.Reset();
+
+ int kYStep = bounds.height() / 10;
+ gfx::Point location(bounds.x() + 10, bounds.y() + kYStep);
+ base::TimeDelta timestamp = ui::EventTimeForNow();
+ ui::TouchEvent press(
+ ui::ET_TOUCH_PRESSED,
+ location,
+ 0,
+ timestamp);
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+ location += gfx::Vector2d(0, kYStep);
+ timestamp += base::TimeDelta::FromMilliseconds(10);
+
+ while (location.y() < bounds.bottom() - kYStep) {
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
+ details = dispatcher->OnEventFromSource(&inc);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+ location += gfx::Vector2d(0, kYStep);
+ timestamp += base::TimeDelta::FromMilliseconds(10);
+ }
+
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
+ details = dispatcher->OnEventFromSource(&release);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+
+ EXPECT_LT(0, tracker.num_overscroll_updates());
+ EXPECT_TRUE(tracker.overscroll_completed());
+ }
+
+ // Start out overscrolling vertically, then switch directions and finish
+ // overscrolling horizontally.
+ {
+ tracker.Reset();
+
+ int kXStep = bounds.width() / 10;
+ int kYStep = bounds.height() / 10;
+ gfx::Point location = bounds.origin() + gfx::Vector2d(0, kYStep);
+ base::TimeDelta timestamp = ui::EventTimeForNow();
+ ui::TouchEvent press(
+ ui::ET_TOUCH_PRESSED,
+ location,
+ 0,
+ timestamp);
+ ui::EventDispatchDetails details = dispatcher->OnEventFromSource(&press);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+ location += gfx::Vector2d(0, kYStep);
+ timestamp += base::TimeDelta::FromMilliseconds(10);
+
+ for (size_t i = 0; i < 3; ++i) {
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
+ details = dispatcher->OnEventFromSource(&inc);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+ location += gfx::Vector2d(0, kYStep);
+ timestamp += base::TimeDelta::FromMilliseconds(10);
+ }
+
+ while (location.x() < bounds.right() - kXStep) {
+ ui::TouchEvent inc(ui::ET_TOUCH_MOVED, location, 0, timestamp);
+ details = dispatcher->OnEventFromSource(&inc);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+ location += gfx::Vector2d(kXStep, 0);
+ timestamp += base::TimeDelta::FromMilliseconds(10);
+ }
+
+ ui::TouchEvent release(ui::ET_TOUCH_RELEASED, location, 0, timestamp);
+ details = dispatcher->OnEventFromSource(&release);
+ ASSERT_FALSE(details.dispatcher_destroyed);
+ WaitAFrame();
+
+ EXPECT_LT(0, tracker.num_overscroll_updates());
+ EXPECT_FALSE(tracker.overscroll_completed());
+ }
+}
+
} // namespace content