chrome_render_widget_host_view_mac_history_swiper_unit_test.mm revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
1a0d5878b7e1c54551c0445354788e4259900c03cDavid Tweed// Copyright 2013 The Chromium Authors. All rights reserved. 2994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith// Use of this source code is governed by a BSD-style license that can be 3994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith// found in the LICENSE file. 4994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith 5994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#include "testing/gtest/include/gtest/gtest.h" 6994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#import "chrome/browser/ui/cocoa/cocoa_test_helper.h" 7994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith 8994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#include "base/mac/scoped_nsobject.h" 9994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#import "base/mac/sdk_forward_declarations.h" 10994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#import "chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper.h" 11994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#import "third_party/ocmock/OCMock/OCMock.h" 12994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#import "third_party/ocmock/ocmock_extensions.h" 13994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith#include "third_party/WebKit/public/web/WebInputEvent.h" 14994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith 152d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith@interface HistorySwiper (MacHistorySwiperTest) 16994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith- (BOOL)systemSettingsAllowHistorySwiping:(NSEvent*)event; 17994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith- (BOOL)browserCanNavigateInDirection: 18994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith (history_swiper::NavigationDirection)forward 19994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith event:(NSEvent*)event; 2050dc12ad05d4a3a57e83852756498afce4307a77Kaelyn Uhrain- (void)endHistorySwipe; 21994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith- (void)beginHistorySwipeInDirection: 22994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith (history_swiper::NavigationDirection)goForward 23994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith event:(NSEvent*)event; 24994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith- (void)navigateBrowserInDirection:(history_swiper::NavigationDirection)forward; 25994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith- (void)initiateMagicMouseHistorySwipe:(BOOL)isRightScroll 2653aec2a2770afc242c70fd88975cd0ea389087c0Richard Smith event:(NSEvent*)event; 2753aec2a2770afc242c70fd88975cd0ea389087c0Richard Smith@end 28994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith 29994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smithclass MacHistorySwiperTest : public CocoaTest { 30994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith public: 31994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith virtual void SetUp() OVERRIDE { 32994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith CocoaTest::SetUp(); 3353aec2a2770afc242c70fd88975cd0ea389087c0Richard Smith 3453aec2a2770afc242c70fd88975cd0ea389087c0Richard Smith [HistorySwiper resetMagicMouseState]; 35994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith 36994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith view_ = [[NSView alloc] init]; 37994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith id mockDelegate = 38b310439121c875937d78cc49cc969bc1197fc025Richard Smith [OCMockObject mockForProtocol:@protocol(HistorySwiperDelegate)]; 39b310439121c875937d78cc49cc969bc1197fc025Richard Smith [[[mockDelegate stub] andReturn:view_] viewThatWantsHistoryOverlay]; 40b310439121c875937d78cc49cc969bc1197fc025Richard Smith [[[mockDelegate stub] andReturnBool:YES] shouldAllowHistorySwiping]; 41b310439121c875937d78cc49cc969bc1197fc025Richard Smith 42b310439121c875937d78cc49cc969bc1197fc025Richard Smith base::scoped_nsobject<HistorySwiper> historySwiper( 43b310439121c875937d78cc49cc969bc1197fc025Richard Smith [[HistorySwiper alloc] initWithDelegate:mockDelegate]); 44b310439121c875937d78cc49cc969bc1197fc025Richard Smith id mockHistorySwiper = [OCMockObject partialMockForObject:historySwiper]; 45b310439121c875937d78cc49cc969bc1197fc025Richard Smith [[[mockHistorySwiper stub] andReturnBool:YES] 46b310439121c875937d78cc49cc969bc1197fc025Richard Smith systemSettingsAllowHistorySwiping:[OCMArg any]]; 477faf81ff1dc8f8dc724e928ba90ccbfad0fdc2bcRichard Smith [[[mockHistorySwiper stub] andReturnBool:YES] 487faf81ff1dc8f8dc724e928ba90ccbfad0fdc2bcRichard Smith browserCanNavigateInDirection:history_swiper::kForwards 497faf81ff1dc8f8dc724e928ba90ccbfad0fdc2bcRichard Smith event:[OCMArg any]]; 507faf81ff1dc8f8dc724e928ba90ccbfad0fdc2bcRichard Smith [[[mockHistorySwiper stub] andReturnBool:YES] 517faf81ff1dc8f8dc724e928ba90ccbfad0fdc2bcRichard Smith browserCanNavigateInDirection:history_swiper::kBackwards 52b310439121c875937d78cc49cc969bc1197fc025Richard Smith event:[OCMArg any]]; 53b310439121c875937d78cc49cc969bc1197fc025Richard Smith [[[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 54994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith ++begin_count_; 55994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith // beginHistorySwipeInDirection: calls endHistorySwipe internally. 56994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith --end_count_; 57994d73f8473cb2cd3ce2f69c9575c95015be788aRichard Smith }] andForwardToRealObject] 582d67097ad41f4c2fe82ebce3f587e06498f1bd71Richard Smith beginHistorySwipeInDirection:history_swiper::kForwards 5950dc12ad05d4a3a57e83852756498afce4307a77Kaelyn Uhrain event:[OCMArg any]]; 6050dc12ad05d4a3a57e83852756498afce4307a77Kaelyn Uhrain [[[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 6150dc12ad05d4a3a57e83852756498afce4307a77Kaelyn Uhrain ++begin_count_; 6237ec8d589c5de34d0e260f0599395519bd7498deRichard Smith // beginHistorySwipeInDirection: calls endHistorySwipe internally. 6337ec8d589c5de34d0e260f0599395519bd7498deRichard Smith --end_count_; 6437ec8d589c5de34d0e260f0599395519bd7498deRichard Smith }] andForwardToRealObject] 6537ec8d589c5de34d0e260f0599395519bd7498deRichard Smith beginHistorySwipeInDirection:history_swiper::kBackwards 6637ec8d589c5de34d0e260f0599395519bd7498deRichard Smith event:[OCMArg any]]; 6737ec8d589c5de34d0e260f0599395519bd7498deRichard Smith [[[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 6837ec8d589c5de34d0e260f0599395519bd7498deRichard Smith ++end_count_; 69f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling }] andForwardToRealObject] endHistorySwipe]; 70f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling [[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 71f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling navigated_right_ = true; 72f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling }] navigateBrowserInDirection:history_swiper::kForwards]; 73f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling [[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 74f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling navigated_left_ = true; 75f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling }] navigateBrowserInDirection:history_swiper::kBackwards]; 76f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 77f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling [[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 78f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling magic_mouse_history_swipe_ = true; 79f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling }] initiateMagicMouseHistorySwipe:YES event:[OCMArg any]]; 80f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling [[[mockHistorySwiper stub] andDo:^(NSInvocation* invocation) { 81f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling magic_mouse_history_swipe_ = true; 82f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling }] initiateMagicMouseHistorySwipe:NO event:[OCMArg any]]; 83f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 84f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling historySwiper_ = [mockHistorySwiper retain]; 85f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 86f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling begin_count_ = 0; 87f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling end_count_ = 0; 88f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling navigated_right_ = false; 89f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling navigated_left_ = false; 90f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling magic_mouse_history_swipe_ = false; 91f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling } 92f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 93f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling virtual void TearDown() OVERRIDE { 94f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling [view_ release]; 95f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling [historySwiper_ release]; 96f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling CocoaTest::TearDown(); 97f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling } 98f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 99f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling void startGestureInMiddle(); 100f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling void moveGestureInMiddle(); 101f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling void moveGestureAtPoint(NSPoint point); 102f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling void momentumMoveGestureAtPoint(NSPoint point); 103f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling void endGestureAtPoint(NSPoint point); 104f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling void rendererACKForBeganEvent(); 105f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 106f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling HistorySwiper* historySwiper_; 107f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling NSView* view_; 108f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling int begin_count_; 109f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling int end_count_; 110f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling bool navigated_right_; 111f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling bool navigated_left_; 112f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling bool magic_mouse_history_swipe_; 113f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling}; 114f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 115f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill WendlingNSPoint makePoint(CGFloat x, CGFloat y) { 116f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling NSPoint point; 117f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling point.x = x; 118f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling point.y = y; 119f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling return point; 120f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling} 121f0cc19f43d5e05dbd22d00faca8c093b7005be3fBill Wendling 122e78e8fc27140309092fb56d77a72f31fa085f9daBill Wendlingid mockEventWithPoint(NSPoint point, NSEventType type) { 123651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines id mockEvent = [OCMockObject mockForClass:[NSEvent class]]; 124651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines id mockTouch = [OCMockObject mockForClass:[NSTouch class]]; 125651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines [[[mockTouch stub] andReturnNSPoint:point] normalizedPosition]; 126651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines NSArray* touches = @[mockTouch]; 127651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines [[[mockEvent stub] andReturn:touches] touchesMatchingPhase:NSTouchPhaseAny 128651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines inView:[OCMArg any]]; 129651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines [[[mockEvent stub] andReturnBool:NO] isDirectionInvertedFromDevice]; 130651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines [(NSEvent*)[[mockEvent stub] andReturnValue:OCMOCK_VALUE(type)] type]; 131651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines 132651f13cea278ec967336033dd032faef0e9fc2ecStephen Hines return mockEvent; 133e78e8fc27140309092fb56d77a72f31fa085f9daBill Wendling} 134e78e8fc27140309092fb56d77a72f31fa085f9daBill Wendling 135e78e8fc27140309092fb56d77a72f31fa085f9daBill Wendlingid scrollWheelEventWithPhase(NSEventPhase phase, 136e78e8fc27140309092fb56d77a72f31fa085f9daBill Wendling NSEventPhase momentumPhase, 137e78e8fc27140309092fb56d77a72f31fa085f9daBill Wendling CGFloat scrollingDeltaX, 1386bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines CGFloat scrollingDeltaY) { 1396bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // The point isn't used, so we pass in bogus data. 1406bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines id event = mockEventWithPoint(makePoint(0,0), NSScrollWheel); 1416bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(phase)] phase]; 1426bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [(NSEvent*) 1436bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [[event stub] andReturnValue:OCMOCK_VALUE(momentumPhase)] momentumPhase]; 1446bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [(NSEvent*)[[event stub] 1456bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines andReturnValue:OCMOCK_VALUE(scrollingDeltaX)] scrollingDeltaX]; 1466bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [(NSEvent*)[[event stub] 1476bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines andReturnValue:OCMOCK_VALUE(scrollingDeltaY)] scrollingDeltaY]; 1486bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return event; 1496bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1506bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1516bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesid scrollWheelEventWithPhase(NSEventPhase phase, 1526bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEventPhase momentumPhase) { 1536bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return scrollWheelEventWithPhase(phase, momentumPhase, 0, 0); 1546bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1556bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1566bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesid scrollWheelEventWithPhase(NSEventPhase phase) { 1576bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines return scrollWheelEventWithPhase(phase, NSEventPhaseNone); 1586bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1596bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1606bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid MacHistorySwiperTest::startGestureInMiddle() { 1616bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* event = mockEventWithPoint(makePoint(0.5, 0.5), NSEventTypeGesture); 1626bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ touchesBeganWithEvent:event]; 1636bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ beginGestureWithEvent:event]; 1646bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); 1656bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ handleEvent:scrollEvent]; 1666bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1676bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1686bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid MacHistorySwiperTest::moveGestureInMiddle() { 1696bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines moveGestureAtPoint(makePoint(0.5, 0.5)); 1706bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1716bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines // Callbacks from blink to set the relevant state for history swiping. 1726bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines rendererACKForBeganEvent(); 1736bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1746bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1756bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid MacHistorySwiperTest::moveGestureAtPoint(NSPoint point) { 1766bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* event = mockEventWithPoint(point, NSEventTypeGesture); 1776bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ touchesMovedWithEvent:event]; 1786bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1796bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseChanged); 1806bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ handleEvent:scrollEvent]; 1816bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1826bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1836bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid MacHistorySwiperTest::momentumMoveGestureAtPoint(NSPoint point) { 1846bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* event = mockEventWithPoint(point, NSEventTypeGesture); 1856bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ touchesMovedWithEvent:event]; 1866bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1876bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* scrollEvent = 1886bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines scrollWheelEventWithPhase(NSEventPhaseNone, NSEventPhaseChanged); 1896bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ handleEvent:scrollEvent]; 1906bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1916bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1926bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid MacHistorySwiperTest::endGestureAtPoint(NSPoint point) { 1936bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* event = mockEventWithPoint(point, NSEventTypeGesture); 1946bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ touchesEndedWithEvent:event]; 1956bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 1966bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseEnded); 1976bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ handleEvent:scrollEvent]; 1986bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 1996bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines 2006bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hinesvoid MacHistorySwiperTest::rendererACKForBeganEvent() { 2016bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines blink::WebMouseWheelEvent event; 2026bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines event.phase = blink::WebMouseWheelEvent::PhaseBegan; 2036bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines [historySwiper_ rendererHandledWheelEvent:event consumed:NO]; 2046bcf27bb9a4b5c3f79cb44c0e4654a6d7619ad89Stephen Hines} 205 206// Test that a simple left-swipe causes navigation. 207TEST_F(MacHistorySwiperTest, SwipeLeft) { 208 // These tests require 10.7+ APIs. 209 if (![NSEvent 210 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 211 return; 212 213 startGestureInMiddle(); 214 moveGestureInMiddle(); 215 216 EXPECT_EQ(begin_count_, 0); 217 EXPECT_EQ(end_count_, 0); 218 219 moveGestureAtPoint(makePoint(0.2, 0.5)); 220 EXPECT_EQ(begin_count_, 1); 221 EXPECT_EQ(end_count_, 0); 222 EXPECT_FALSE(navigated_right_); 223 EXPECT_FALSE(navigated_left_); 224 225 endGestureAtPoint(makePoint(0.2, 0.5)); 226 EXPECT_EQ(begin_count_, 1); 227 EXPECT_EQ(end_count_, 1); 228 EXPECT_FALSE(navigated_right_); 229 EXPECT_TRUE(navigated_left_); 230} 231 232// Test that a simple right-swipe causes navigation. 233TEST_F(MacHistorySwiperTest, SwipeRight) { 234 // These tests require 10.7+ APIs. 235 if (![NSEvent 236 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 237 return; 238 239 startGestureInMiddle(); 240 moveGestureInMiddle(); 241 242 EXPECT_EQ(begin_count_, 0); 243 EXPECT_EQ(end_count_, 0); 244 245 moveGestureAtPoint(makePoint(0.8, 0.5)); 246 EXPECT_EQ(begin_count_, 1); 247 EXPECT_EQ(end_count_, 0); 248 EXPECT_FALSE(navigated_right_); 249 EXPECT_FALSE(navigated_left_); 250 251 endGestureAtPoint(makePoint(0.8, 0.5)); 252 EXPECT_EQ(begin_count_, 1); 253 EXPECT_EQ(end_count_, 1); 254 EXPECT_TRUE(navigated_right_); 255 EXPECT_FALSE(navigated_left_); 256} 257 258// If the user doesn't swipe enough, the history swiper should begin, but the 259// browser should not navigate. 260TEST_F(MacHistorySwiperTest, SwipeLeftSmallAmount) { 261 // These tests require 10.7+ APIs. 262 if (![NSEvent 263 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 264 return; 265 266 startGestureInMiddle(); 267 moveGestureInMiddle(); 268 moveGestureAtPoint(makePoint(0.45, 0.5)); 269 endGestureAtPoint(makePoint(0.45, 0.5)); 270 EXPECT_EQ(begin_count_, 1); 271 EXPECT_EQ(end_count_, 1); 272 EXPECT_FALSE(navigated_right_); 273 EXPECT_FALSE(navigated_left_); 274} 275 276// Diagonal swipes with a slight horizontal bias should not start the history 277// swiper. 278TEST_F(MacHistorySwiperTest, SwipeDiagonal) { 279 // These tests require 10.7+ APIs. 280 if (![NSEvent 281 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 282 return; 283 284 startGestureInMiddle(); 285 moveGestureInMiddle(); 286 moveGestureInMiddle(); 287 moveGestureAtPoint(makePoint(0.6, 0.59)); 288 endGestureAtPoint(makePoint(0.6, 0.59)); 289 290 EXPECT_EQ(begin_count_, 1); 291 EXPECT_EQ(end_count_, 1); 292 EXPECT_FALSE(navigated_right_); 293 EXPECT_FALSE(navigated_left_); 294} 295 296// Swiping left and then down should cancel the history swiper without 297// navigating. 298TEST_F(MacHistorySwiperTest, SwipeLeftThenDown) { 299 // These tests require 10.7+ APIs. 300 if (![NSEvent 301 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 302 return; 303 304 startGestureInMiddle(); 305 moveGestureInMiddle(); 306 moveGestureAtPoint(makePoint(0.4, 0.5)); 307 moveGestureAtPoint(makePoint(0.4, 0.3)); 308 endGestureAtPoint(makePoint(0.2, 0.2)); 309 EXPECT_EQ(begin_count_, 1); 310 EXPECT_EQ(end_count_, 1); 311 EXPECT_FALSE(navigated_right_); 312 EXPECT_FALSE(navigated_left_); 313} 314 315// Sometimes Cocoa gets confused and sends us a momentum swipe event instead of 316// a swipe gesture event. Momentum events should not cause history swiping. 317TEST_F(MacHistorySwiperTest, MomentumSwipeLeft) { 318 // These tests require 10.7+ APIs. 319 if (![NSEvent 320 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 321 return; 322 323 startGestureInMiddle(); 324 325 // Send a momentum move gesture. 326 momentumMoveGestureAtPoint(makePoint(0.5, 0.5)); 327 EXPECT_EQ(begin_count_, 0); 328 EXPECT_EQ(end_count_, 0); 329 330 // Callbacks from blink to set the relevant state for history swiping. 331 rendererACKForBeganEvent(); 332 333 momentumMoveGestureAtPoint(makePoint(0.2, 0.5)); 334 EXPECT_EQ(begin_count_, 0); 335 EXPECT_EQ(end_count_, 0); 336 337 endGestureAtPoint(makePoint(0.2, 0.5)); 338 EXPECT_EQ(begin_count_, 0); 339 EXPECT_EQ(end_count_, 0); 340} 341 342// Momentum scroll events for magic mouse should not attempt to trigger the 343// `trackSwipeEventWithOptions:` api, as that throws an exception. 344TEST_F(MacHistorySwiperTest, MagicMouseMomentumSwipe) { 345 // These tests require 10.7+ APIs. 346 if (![NSEvent 347 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 348 return; 349 350 // Magic mouse events don't generate 'touches*' callbacks. 351 NSEvent* event = mockEventWithPoint(makePoint(0.5, 0.5), NSEventTypeGesture); 352 [historySwiper_ beginGestureWithEvent:event]; 353 NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); 354 [historySwiper_ handleEvent:scrollEvent]; 355 356 // Callbacks from blink to set the relevant state for history swiping. 357 rendererACKForBeganEvent(); 358 359 // Send a momentum move gesture. 360 scrollEvent = 361 scrollWheelEventWithPhase(NSEventPhaseNone, NSEventPhaseChanged, 5.0, 0); 362 [historySwiper_ handleEvent:scrollEvent]; 363 364 EXPECT_FALSE(magic_mouse_history_swipe_); 365} 366 367// User starts a swipe but doesn't move. 368TEST_F(MacHistorySwiperTest, NoSwipe) { 369 // These tests require 10.7+ APIs. 370 if (![NSEvent 371 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 372 return; 373 374 startGestureInMiddle(); 375 moveGestureInMiddle(); 376 377 // Starts the gesture. 378 moveGestureAtPoint(makePoint(0.44, 0.44)); 379 380 // No movement. 381 endGestureAtPoint(makePoint(0.44, 0.44)); 382 383 EXPECT_EQ(begin_count_, 1); 384 EXPECT_EQ(end_count_, 1); 385 EXPECT_FALSE(navigated_right_); 386 EXPECT_FALSE(navigated_left_); 387} 388 389// After a gesture is successfully recognized, momentum events should be 390// swallowed, but new events should pass through. 391TEST_F(MacHistorySwiperTest, TouchEventAfterGestureFinishes) { 392 // These tests require 10.7+ APIs. 393 if (![NSEvent 394 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 395 return; 396 397 // Successfully pass through a gesture. 398 startGestureInMiddle(); 399 moveGestureInMiddle(); 400 moveGestureAtPoint(makePoint(0.8, 0.5)); 401 endGestureAtPoint(makePoint(0.8, 0.5)); 402 EXPECT_TRUE(navigated_right_); 403 404 // Momentum events should be swallowed. 405 NSEvent* momentumEvent = scrollWheelEventWithPhase(NSEventPhaseNone, 406 NSEventPhaseChanged); 407 EXPECT_TRUE([historySwiper_ handleEvent:momentumEvent]); 408 409 // New events should not be swallowed. 410 NSEvent* beganEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); 411 EXPECT_FALSE([historySwiper_ handleEvent:beganEvent]); 412} 413 414// The history swipe logic should be resilient against the timing of the 415// different callbacks that result from scrolling. 416TEST_F(MacHistorySwiperTest, SwipeRightEventOrdering) { 417 // These tests require 10.7+ APIs. 418 if (![NSEvent 419 respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)]) 420 return; 421 422 // Touches began. 423 NSEvent* scrollEvent = scrollWheelEventWithPhase(NSEventPhaseBegan); 424 NSEvent* event = mockEventWithPoint(makePoint(0.5, 0.5), NSEventTypeGesture); 425 [historySwiper_ touchesBeganWithEvent:event]; 426 [historySwiper_ handleEvent:scrollEvent]; 427 rendererACKForBeganEvent(); 428 429 // Touches moved. 430 moveGestureAtPoint(makePoint(0.5, 0.5)); 431 EXPECT_EQ(begin_count_, 0); 432 EXPECT_EQ(end_count_, 0); 433 434 // Touches moved. 435 moveGestureAtPoint(makePoint(0.52, 0.5)); 436 437 // Begin gesture callback is delayed. 438 [historySwiper_ beginGestureWithEvent:event]; 439 440 // Touches moved. 441 moveGestureAtPoint(makePoint(0.52, 0.5)); 442 443 // Complete the rest of the gesture. 444 moveGestureAtPoint(makePoint(0.60, 0.5)); 445 scrollEvent = scrollWheelEventWithPhase(NSEventPhaseChanged); 446 [historySwiper_ handleEvent:scrollEvent]; 447 endGestureAtPoint(makePoint(0.70, 0.5)); 448 449 EXPECT_EQ(begin_count_, 1); 450 EXPECT_EQ(end_count_, 1); 451 EXPECT_TRUE(navigated_right_); 452 EXPECT_FALSE(navigated_left_); 453} 454