1 // Copyright 2013 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 "base/basictypes.h" 6 #include "base/files/file_path.h" 7 #include "chrome/browser/chrome_notification_types.h" 8 #include "chrome/browser/ui/browser.h" 9 #include "chrome/browser/ui/browser_commands.h" 10 #include "chrome/browser/ui/browser_tabstrip.h" 11 #include "chrome/browser/ui/tabs/tab_strip_model.h" 12 #include "chrome/test/base/in_process_browser_test.h" 13 #include "chrome/test/base/ui_test_utils.h" 14 #include "content/public/browser/notification_service.h" 15 #include "content/public/browser/notification_source.h" 16 #include "content/public/browser/render_view_host.h" 17 #include "content/public/browser/web_contents.h" 18 #include "content/public/test/browser_test_utils.h" 19 #include "net/base/net_util.h" 20 #include "url/gurl.h" 21 22 class ChromeRenderWidgetHostViewMacDelegateTest : public InProcessBrowserTest { 23 public: 24 ChromeRenderWidgetHostViewMacDelegateTest() { 25 const base::FilePath base_path(FILE_PATH_LITERAL("scroll")); 26 url1_ = ui_test_utils::GetTestUrl( 27 base_path, base::FilePath(FILE_PATH_LITERAL("text.html"))); 28 url2_ = ui_test_utils::GetTestUrl( 29 base_path, base::FilePath(FILE_PATH_LITERAL("blank.html"))); 30 } 31 32 protected: 33 // Navigates back. 34 void GoBack() { 35 content::WindowedNotificationObserver observer( 36 content::NOTIFICATION_LOAD_STOP, 37 content::NotificationService::AllSources()); 38 chrome::GoBack(browser(), CURRENT_TAB); 39 observer.Wait(); 40 } 41 42 // Returns the active web contents. 43 content::WebContents* GetWebContents() { 44 return browser()->tab_strip_model()->GetActiveWebContents(); 45 } 46 47 // Returns the value of |query| from Javascript as an int. 48 int GetScriptIntValue(const std::string& query) { 49 int value = 0; 50 EXPECT_TRUE(content::ExecuteScriptAndExtractInt( 51 GetWebContents(), 52 "domAutomationController.send(" + query + ")", 53 &value)); 54 return value; 55 } 56 57 // Returns the vertical scroll offset of the current page. 58 int GetScrollTop() { 59 return GetScriptIntValue("document.body.scrollTop"); 60 } 61 62 // Returns the horizontal scroll offset of the current page. 63 int GetScrollLeft() { 64 return GetScriptIntValue("document.body.scrollLeft"); 65 } 66 67 // Simulates a mouse wheel event, forwarding it to the renderer. 68 void SendWheelEvent(int dx, int dy, blink::WebMouseWheelEvent::Phase phase) { 69 blink::WebMouseWheelEvent event; 70 event.type = blink::WebInputEvent::MouseWheel; 71 event.phase = phase; 72 event.deltaX = dx; 73 event.deltaY = dy; 74 event.wheelTicksY = -2; 75 event.hasPreciseScrollingDeltas = 1; 76 GetWebContents()->GetRenderViewHost()->ForwardWheelEvent(event); 77 } 78 79 GURL url1_; 80 GURL url2_; 81 82 private: 83 DISALLOW_COPY_AND_ASSIGN(ChromeRenderWidgetHostViewMacDelegateTest); 84 }; 85 86 IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacDelegateTest, 87 GoBackScrollOffset) { 88 ui_test_utils::NavigateToURL(browser(), url1_); 89 ASSERT_EQ(url1_, GetWebContents()->GetURL()); 90 91 SendWheelEvent(0, -200, blink::WebMouseWheelEvent::PhaseNone); 92 const int scroll_offset = GetScrollTop(); 93 ASSERT_NE(0, scroll_offset); 94 95 ui_test_utils::NavigateToURL(browser(), url2_); 96 ASSERT_EQ(url2_, GetWebContents()->GetURL()); 97 ASSERT_EQ(0, GetScrollTop()); 98 99 GoBack(); 100 ASSERT_EQ(url1_, GetWebContents()->GetURL()); 101 ASSERT_EQ(scroll_offset, GetScrollTop()); 102 } 103 104 IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacDelegateTest, 105 GoBackUsingGestureScrollOffset) { 106 ui_test_utils::NavigateToURL(browser(), url1_); 107 ASSERT_EQ(url1_, GetWebContents()->GetURL()); 108 109 SendWheelEvent(0, -200, blink::WebMouseWheelEvent::PhaseNone); 110 const int scroll_offset = GetScrollTop(); 111 ASSERT_NE(0, scroll_offset); 112 113 ui_test_utils::NavigateToURL(browser(), url2_); 114 ASSERT_EQ(url2_, GetWebContents()->GetURL()); 115 ASSERT_EQ(0, GetScrollTop()); 116 117 // Send wheel events that shouldn't be handled by the web content since it's 118 // not scrollable in the horizontal direction. 119 SendWheelEvent(500, 0, blink::WebMouseWheelEvent::PhaseBegan); 120 SendWheelEvent(500, 0, blink::WebMouseWheelEvent::PhaseEnded); 121 ASSERT_EQ(0, GetScrollLeft()); 122 123 // Simulate a back being triggered as a result of the unhandled wheel events. 124 // This doesn't invoke the code in ChromeRenderWidgetHostViewMacDelegate 125 // because that expects NSEvents which are much harder to fake. 126 GoBack(); 127 ASSERT_EQ(url1_, GetWebContents()->GetURL()); 128 ASSERT_EQ(scroll_offset, GetScrollTop()); 129 } 130