17d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Copyright 2013 The Chromium Authors. All rights reserved.
27d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
37d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)// found in the LICENSE file.
47d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
57d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/basictypes.h"
67d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "base/files/file_path.h"
77dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "chrome/browser/chrome_notification_types.h"
87d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/browser.h"
97d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/browser_commands.h"
107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/browser_tabstrip.h"
117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/browser/ui/tabs/tab_strip_model.h"
127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/test/base/in_process_browser_test.h"
137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "chrome/test/base/ui_test_utils.h"
147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/notification_service.h"
157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/notification_source.h"
167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/render_view_host.h"
177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/browser/web_contents.h"
187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "content/public/test/browser_test_utils.h"
197d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)#include "net/base/net_util.h"
20eb525c5499e34cc9c4b825d6d9e75bb07cc06aceBen Murdoch#include "url/gurl.h"
217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)class ChromeRenderWidgetHostViewMacDelegateTest : public InProcessBrowserTest {
237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) public:
247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ChromeRenderWidgetHostViewMacDelegateTest() {
257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    const base::FilePath base_path(FILE_PATH_LITERAL("scroll"));
267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    url1_ = ui_test_utils::GetTestUrl(
277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base_path, base::FilePath(FILE_PATH_LITERAL("text.html")));
287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    url2_ = ui_test_utils::GetTestUrl(
297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        base_path, base::FilePath(FILE_PATH_LITERAL("blank.html")));
307d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
317d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
327d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) protected:
337d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Navigates back.
347d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  void GoBack() {
357d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    content::WindowedNotificationObserver observer(
367d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        content::NOTIFICATION_LOAD_STOP,
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        content::NotificationService::AllSources());
387d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    chrome::GoBack(browser(), CURRENT_TAB);
397d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    observer.Wait();
407d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
417d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
427d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the active web contents.
437d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  content::WebContents* GetWebContents() {
447d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return browser()->tab_strip_model()->GetActiveWebContents();
457d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
467d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
477d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the value of |query| from Javascript as an int.
487d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int GetScriptIntValue(const std::string& query) {
497d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    int value = 0;
507d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
517d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        GetWebContents(),
527d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        "domAutomationController.send(" + query + ")",
537d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        &value));
547d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return value;
557d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
567d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
577d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the vertical scroll offset of the current page.
587d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int GetScrollTop() {
597d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return GetScriptIntValue("document.body.scrollTop");
607d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
617d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
627d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Returns the horizontal scroll offset of the current page.
637d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  int GetScrollLeft() {
647d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    return GetScriptIntValue("document.body.scrollLeft");
657d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
667d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
677d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Simulates a mouse wheel event, forwarding it to the renderer.
68f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  void SendWheelEvent(int dx, int dy, blink::WebMouseWheelEvent::Phase phase) {
69f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    blink::WebMouseWheelEvent event;
70f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)    event.type = blink::WebInputEvent::MouseWheel;
717d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    event.phase = phase;
727d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    event.deltaX = dx;
737d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    event.deltaY = dy;
747d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    event.wheelTicksY = -2;
757d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    event.hasPreciseScrollingDeltas = 1;
767d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)    GetWebContents()->GetRenderViewHost()->ForwardWheelEvent(event);
777d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  }
787d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
797d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL url1_;
807d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GURL url2_;
817d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
827d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles) private:
837d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  DISALLOW_COPY_AND_ASSIGN(ChromeRenderWidgetHostViewMacDelegateTest);
847d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)};
857d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
867d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacDelegateTest,
877d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       GoBackScrollOffset) {
887d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), url1_);
897d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(url1_, GetWebContents()->GetURL());
907d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
91f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendWheelEvent(0, -200, blink::WebMouseWheelEvent::PhaseNone);
927d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const int scroll_offset = GetScrollTop();
937d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_NE(0, scroll_offset);
947d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
957d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), url2_);
967d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(url2_, GetWebContents()->GetURL());
977d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(0, GetScrollTop());
987d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
997d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GoBack();
1007d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(url1_, GetWebContents()->GetURL());
1017d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(scroll_offset, GetScrollTop());
1027d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
1037d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1047d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacDelegateTest,
1057d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)                       GoBackUsingGestureScrollOffset) {
1067d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), url1_);
1077d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(url1_, GetWebContents()->GetURL());
1087d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
109f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendWheelEvent(0, -200, blink::WebMouseWheelEvent::PhaseNone);
1107d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  const int scroll_offset = GetScrollTop();
1117d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_NE(0, scroll_offset);
1127d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1137d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ui_test_utils::NavigateToURL(browser(), url2_);
1147d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(url2_, GetWebContents()->GetURL());
1157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(0, GetScrollTop());
1167d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1177d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Send wheel events that shouldn't be handled by the web content since it's
1187d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // not scrollable in the horizontal direction.
119f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendWheelEvent(500, 0, blink::WebMouseWheelEvent::PhaseBegan);
120f2477e01787aa58f445919b809d89e252beef54fTorne (Richard Coles)  SendWheelEvent(500, 0, blink::WebMouseWheelEvent::PhaseEnded);
1217d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(0, GetScrollLeft());
1227d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)
1237d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // Simulate a back being triggered as a result of the unhandled wheel events.
1247d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // This doesn't invoke the code in ChromeRenderWidgetHostViewMacDelegate
1257d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  // because that expects NSEvents which are much harder to fake.
1267d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  GoBack();
1277d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(url1_, GetWebContents()->GetURL());
1287d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  ASSERT_EQ(scroll_offset, GetScrollTop());
1297d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)}
130