| Index: chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm
|
| diff --git a/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..6680cf82efd401976b81e0d6dbe60995b046ae8a
|
| --- /dev/null
|
| +++ b/chrome/browser/renderer_host/chrome_render_widget_host_view_mac_history_swiper_browsertest.mm
|
| @@ -0,0 +1,681 @@
|
| +// Copyright 2014 The Chromium Authors. All rights reserved.
|
| +// Use of this source code is governed by a BSD-style license that can be
|
| +// found in the LICENSE file.
|
| +
|
| +#include <Cocoa/Cocoa.h>
|
| +
|
| +#include "base/files/file_path.h"
|
| +#include "base/logging.h"
|
| +#include "base/mac/scoped_nsobject.h"
|
| +#import "base/mac/sdk_forward_declarations.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "chrome/browser/ui/browser.h"
|
| +#include "chrome/browser/ui/tabs/tab_strip_model.h"
|
| +#include "chrome/test/base/in_process_browser_test.h"
|
| +#include "chrome/test/base/ui_test_utils.h"
|
| +#include "content/public/browser/render_view_host.h"
|
| +#include "content/public/browser/render_widget_host_view.h"
|
| +#include "content/public/browser/web_contents.h"
|
| +#include "content/public/test/browser_test_utils.h"
|
| +#import "third_party/ocmock/OCMock/OCMock.h"
|
| +#import "third_party/ocmock/ocmock_extensions.h"
|
| +#include "url/gurl.h"
|
| +
|
| +namespace {
|
| +
|
| +// Refers to how the event is going to be sent to the NSView. There are 3
|
| +// relevant sets of APIs. The current code relies on all three sets of APIs.
|
| +// There is significant information duplication between the three sets of APIs,
|
| +// but the timing of the callbacks of the three APIs differ significantly.
|
| +enum Deployment {
|
| + // -[NSView touchesBeganWithEvent:]
|
| + DEPLOYMENT_TOUCHES_BEGAN,
|
| + // -[NSView touchesMovedWithEvent:]
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + // -[NSView touchesEndedWithEvent:]
|
| + DEPLOYMENT_TOUCHES_ENDED,
|
| + // -[NSView scrollWheel:]
|
| + DEPLOYMENT_SCROLL_WHEEL,
|
| + // -[NSView beginGestureWithEvent:]
|
| + DEPLOYMENT_GESTURE_BEGIN,
|
| + // -[NSView endGestureWithEvent:]
|
| + DEPLOYMENT_GESTURE_END,
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +// A wrapper object for events queued for replay.
|
| +@interface QueuedEvent : NSObject {
|
| + BOOL _runMessageLoop;
|
| + Deployment _deployment;
|
| + NSEvent* _event;
|
| +}
|
| +// Whether the message loop should be run after this event has been replayed.
|
| +@property(nonatomic, assign) BOOL runMessageLoop;
|
| +// How this event should be replayed.
|
| +@property(nonatomic, assign) Deployment deployment;
|
| +// The event to be replayed.
|
| +@property(nonatomic, retain) NSEvent* event;
|
| +@end
|
| +
|
| +@implementation QueuedEvent
|
| +@synthesize deployment = _deployment;
|
| +@synthesize event = _event;
|
| +@synthesize runMessageLoop = _runMessageLoop;
|
| +- (void)dealloc {
|
| + [_event release];
|
| + [super dealloc];
|
| +}
|
| +@end
|
| +
|
| +class ChromeRenderWidgetHostViewMacHistorySwiperTest
|
| + : public InProcessBrowserTest {
|
| + public:
|
| + ChromeRenderWidgetHostViewMacHistorySwiperTest()
|
| + : event_queue_(), touch_(CGPointMake(0, 0)) {
|
| + const base::FilePath base_path(FILE_PATH_LITERAL("scroll"));
|
| + url1_ = ui_test_utils::GetTestUrl(
|
| + base_path, base::FilePath(FILE_PATH_LITERAL("text.html")));
|
| + url2_ = ui_test_utils::GetTestUrl(
|
| + base_path, base::FilePath(FILE_PATH_LITERAL("blank.html")));
|
| + }
|
| +
|
| + virtual void SetUpOnMainThread() OVERRIDE {
|
| + event_queue_.reset([[NSMutableArray alloc] init]);
|
| + touch_ = CGPointMake(0.5, 0.5);
|
| +
|
| + // Ensure that the navigation stack is not empty.
|
| + ui_test_utils::NavigateToURL(browser(), url1_);
|
| + ASSERT_EQ(url1_, GetWebContents()->GetURL());
|
| + ui_test_utils::NavigateToURL(browser(), url2_);
|
| + ASSERT_EQ(url2_, GetWebContents()->GetURL());
|
| + }
|
| +
|
| + virtual void TearDownOnMainThread() OVERRIDE {
|
| + event_queue_.reset();
|
| + }
|
| +
|
| + protected:
|
| + // Returns the active web contents.
|
| + content::WebContents* GetWebContents() {
|
| + return browser()->tab_strip_model()->GetActiveWebContents();
|
| + }
|
| +
|
| + // Returns the value of |query| from Javascript as an int.
|
| + int GetScriptIntValue(const std::string& query) {
|
| + int value = 0;
|
| + EXPECT_TRUE(content::ExecuteScriptAndExtractInt(
|
| + GetWebContents(),
|
| + "domAutomationController.send(" + query + ")",
|
| + &value));
|
| + return value;
|
| + }
|
| +
|
| + // Returns the vertical scroll offset of the current page.
|
| + int GetScrollTop() {
|
| + return GetScriptIntValue("document.body.scrollTop");
|
| + }
|
| +
|
| + bool IsHistorySwipingSupported() {
|
| + // These tests require 10.7+ APIs.
|
| + return [NSEvent
|
| + respondsToSelector:@selector(isSwipeTrackingFromScrollEventsEnabled)];
|
| + }
|
| +
|
| + // Create mock events --------------------------------------------------------
|
| +
|
| + // Creates a mock scroll wheel event that is backed by a real CGEvent.
|
| + id MockScrollWheelEvent(NSPoint delta, NSEventType type) {
|
| + CGEventRef cg_event =
|
| + CGEventCreateScrollWheelEvent(NULL, kCGScrollEventUnitLine, 2, 0, 0);
|
| + CGEventSetIntegerValueField(cg_event, kCGScrollWheelEventIsContinuous, 1);
|
| + CGEventSetIntegerValueField(
|
| + cg_event, kCGScrollWheelEventPointDeltaAxis2, delta.x);
|
| + CGEventSetIntegerValueField(
|
| + cg_event, kCGScrollWheelEventPointDeltaAxis1, delta.y);
|
| + NSEvent* event = [NSEvent eventWithCGEvent:cg_event];
|
| + CFRelease(cg_event);
|
| +
|
| + id mock_event = [OCMockObject partialMockForObject:event];
|
| + [[[mock_event stub] andReturnBool:NO] isDirectionInvertedFromDevice];
|
| + [(NSEvent*)[[mock_event stub] andReturnValue:OCMOCK_VALUE(type)] type];
|
| +
|
| + return mock_event;
|
| + }
|
| +
|
| + // Returns a scroll wheel event with the given parameters.
|
| + id ScrollWheelEventWithPhase(NSEventPhase phase,
|
| + NSEventPhase momentum_phase,
|
| + CGFloat scrolling_delta_x,
|
| + CGFloat scrolling_delta_y) {
|
| + id event = MockScrollWheelEvent(
|
| + NSMakePoint(scrolling_delta_x, scrolling_delta_y), NSScrollWheel);
|
| + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(phase)] phase];
|
| + [(NSEvent*)[[event stub]
|
| + andReturnValue:OCMOCK_VALUE(momentum_phase)] momentumPhase];
|
| + [(NSEvent*)[[event stub]
|
| + andReturnValue:OCMOCK_VALUE(scrolling_delta_x)] scrollingDeltaX];
|
| + [(NSEvent*)[[event stub]
|
| + andReturnValue:OCMOCK_VALUE(scrolling_delta_y)] scrollingDeltaY];
|
| + NSUInteger modifierFlags = 0;
|
| + [(NSEvent*)[[event stub]
|
| + andReturnValue:OCMOCK_VALUE(modifierFlags)] modifierFlags];
|
| + NSView* view =
|
| + GetWebContents()->GetRenderViewHost()->GetView()->GetNativeView();
|
| + NSWindow* window = [view window];
|
| + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(window)] window];
|
| +
|
| + return event;
|
| + }
|
| +
|
| + // Queue events for playback -------------------------------------------------
|
| +
|
| + void QueueEvent(id event, Deployment deployment, BOOL run_message_loop) {
|
| + QueuedEvent* queued_event = [[[QueuedEvent alloc] init] autorelease];
|
| + queued_event.event = event;
|
| + queued_event.deployment = deployment;
|
| + queued_event.runMessageLoop = run_message_loop;
|
| + [event_queue_ addObject:queued_event];
|
| + }
|
| +
|
| + // Queues a trackpad scroll event (e.g. [NSView scrollWheel:])
|
| + void QueueTrackpadScroll(int dx,
|
| + int dy,
|
| + NSEventPhase phase,
|
| + BOOL run_message_loop) {
|
| + id event = ScrollWheelEventWithPhase(phase, NSEventPhaseNone, dx, dy);
|
| + QueueEvent(event, DEPLOYMENT_SCROLL_WHEEL, run_message_loop);
|
| + }
|
| +
|
| + // Queues a gesture begin event (e.g. [NSView gestureDidBegin:])
|
| + void QueueGestureBegin() {
|
| + id event = [OCMockObject mockForClass:[NSEvent class]];
|
| + NSEventType type = NSEventTypeBeginGesture;
|
| + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
|
| + QueueEvent(event, DEPLOYMENT_GESTURE_BEGIN, NO);
|
| + }
|
| +
|
| + // Queues a gesture end event (e.g. [NSView gestureDidEnd:])
|
| + void QueueGestureEnd() {
|
| + id event = [OCMockObject mockForClass:[NSEvent class]];
|
| + NSEventType type = NSEventTypeEndGesture;
|
| + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
|
| + QueueEvent(event, DEPLOYMENT_GESTURE_END, NO);
|
| + }
|
| +
|
| + // Queues a touch event with absolute coordinates |x| and |y|.
|
| + void QueueTouch(CGFloat x,
|
| + CGFloat y,
|
| + Deployment deployment,
|
| + NSEventType type,
|
| + short subtype,
|
| + BOOL run_message_loop) {
|
| + id event = [OCMockObject mockForClass:[NSEvent class]];
|
| + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(type)] type];
|
| + [(NSEvent*)[[event stub] andReturnValue:OCMOCK_VALUE(subtype)] subtype];
|
| +
|
| + id mock_touch = [OCMockObject mockForClass:[NSTouch class]];
|
| + [[[mock_touch stub] andReturnNSPoint:NSMakePoint(x, y)] normalizedPosition];
|
| + NSArray* touches = @[ mock_touch ];
|
| + [[[event stub] andReturn:touches] touchesMatchingPhase:NSTouchPhaseAny
|
| + inView:[OCMArg any]];
|
| + [[[event stub] andReturnBool:NO] isDirectionInvertedFromDevice];
|
| + QueueEvent(event, deployment, run_message_loop);
|
| + }
|
| +
|
| + // Convenience methods for event queuing -------------------------------------
|
| +
|
| + // Trackpad scroll events are roughly related to touch events. Given a
|
| + // trackpad scroll delta, approximate the change to the touch event.
|
| + void UpdateTouchLocationFromTrackpadScroll(int dx, int dy) {
|
| + touch_.x -= dx * 0.001;
|
| + touch_.y -= dy * 0.001;
|
| + }
|
| +
|
| + // Queue the typical events at the beginning of a new swipe gesture. The
|
| + // ordering and values were determined by recording real swipe events.
|
| + void QueueBeginningEvents(int dx, int dy) {
|
| + QueueTouch(
|
| + DEPLOYMENT_TOUCHES_BEGAN, NSEventTypeGesture, NSMouseEventSubtype, NO);
|
| + QueueTrackpadScroll(0, 0, NSEventPhaseMayBegin, YES);
|
| + QueueTouch(
|
| + DEPLOYMENT_TOUCHES_MOVED, NSEventTypeGesture, NSMouseEventSubtype, NO);
|
| +
|
| + QueueTrackpadScroll(dx, dy, NSEventPhaseBegan, NO);
|
| + QueueGestureBegin();
|
| + QueueTouch(DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeBeginGesture,
|
| + NSTouchEventSubtype,
|
| + NO);
|
| + QueueTouch(
|
| + DEPLOYMENT_TOUCHES_MOVED, NSEventTypeGesture, NSTouchEventSubtype, YES);
|
| + UpdateTouchLocationFromTrackpadScroll(dx, dy);
|
| + QueueTouch(
|
| + DEPLOYMENT_TOUCHES_MOVED, NSEventTypeGesture, NSTouchEventSubtype, NO);
|
| + }
|
| +
|
| + // Queue the typical events at the end of a new swipe gesture. The ordering
|
| + // and values were determined by recording real swipe events.
|
| + void QueueEndEvents() {
|
| + QueueTouch(DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeEndGesture,
|
| + NSMouseEventSubtype,
|
| + NO);
|
| + QueueTouch(DEPLOYMENT_TOUCHES_ENDED,
|
| + NSEventTypeEndGesture,
|
| + NSMouseEventSubtype,
|
| + NO);
|
| + QueueGestureEnd();
|
| + QueueTrackpadScroll(0, 0, NSEventPhaseEnded, YES);
|
| + }
|
| +
|
| + // Queues a trackpad scroll movement and a touch movement event.
|
| + void QueueScrollAndTouchMoved(int dx, int dy) {
|
| + QueueTrackpadScroll(dx, dy, NSEventPhaseChanged, NO);
|
| + UpdateTouchLocationFromTrackpadScroll(dx, dy);
|
| + QueueTouch(
|
| + DEPLOYMENT_TOUCHES_MOVED, NSEventTypeGesture, NSTouchEventSubtype, YES);
|
| + }
|
| +
|
| + // Queues a touch event with the stored touch coordinates.
|
| + void QueueTouch(Deployment deployment,
|
| + NSEventType type,
|
| + short subtype,
|
| + BOOL run_message_loop) {
|
| + QueueTouch(touch_.x, touch_.y, deployment, type, subtype, run_message_loop);
|
| + }
|
| +
|
| + // Replays the events from the queue.
|
| + void RunQueuedEvents() {
|
| + while ([event_queue_ count] > 0) {
|
| + QueuedEvent* queued_event = [event_queue_ objectAtIndex:0];
|
| + NSEvent* event = queued_event.event;
|
| + NSView* view =
|
| + GetWebContents()->GetRenderViewHost()->GetView()->GetNativeView();
|
| + BOOL run_loop = queued_event.runMessageLoop;
|
| + switch (queued_event.deployment) {
|
| + case DEPLOYMENT_GESTURE_BEGIN:
|
| + [view beginGestureWithEvent:event];
|
| + break;
|
| + case DEPLOYMENT_GESTURE_END:
|
| + [view endGestureWithEvent:event];
|
| + break;
|
| + case DEPLOYMENT_SCROLL_WHEEL:
|
| + [view scrollWheel:event];
|
| + break;
|
| + case DEPLOYMENT_TOUCHES_BEGAN:
|
| + [view touchesBeganWithEvent:event];
|
| + break;
|
| + case DEPLOYMENT_TOUCHES_ENDED:
|
| + [view touchesEndedWithEvent:event];
|
| + break;
|
| + case DEPLOYMENT_TOUCHES_MOVED:
|
| + [view touchesMovedWithEvent:event];
|
| + break;
|
| + }
|
| +
|
| + [event_queue_ removeObjectAtIndex:0];
|
| +
|
| + if (!run_loop)
|
| + continue;
|
| + // Give time for the IPC to make it to the renderer process. If the IPC
|
| + // doesn't have time to make it to the renderer process, that's okay,
|
| + // since that simulates realistic conditions.
|
| + [[NSRunLoop currentRunLoop]
|
| + runUntilDate:[NSDate dateWithTimeIntervalSinceNow:0.001]];
|
| + // The renderer process returns an IPC, which needs to be handled.
|
| + base::MessageLoop::current()->RunUntilIdle();
|
| + }
|
| + }
|
| +
|
| + void ExpectUrlAndOffset(const GURL& url, int offset) {
|
| + content::WaitForLoadStop(GetWebContents());
|
| + EXPECT_EQ(url, GetWebContents()->GetURL());
|
| +
|
| + const int scroll_offset = GetScrollTop();
|
| + EXPECT_EQ(offset, scroll_offset);
|
| + }
|
| +
|
| + GURL url1_;
|
| + GURL url2_;
|
| + base::scoped_nsobject<NSMutableArray> event_queue_;
|
| + // The current location of the user's fingers on the track pad.
|
| + CGPoint touch_;
|
| +
|
| + private:
|
| + DISALLOW_COPY_AND_ASSIGN(ChromeRenderWidgetHostViewMacHistorySwiperTest);
|
| +};
|
| +
|
| +// The ordering, timing, and parameters of the events was determined by
|
| +// recording a real swipe.
|
| +IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacHistorySwiperTest,
|
| + TestBackwardsHistoryNavigationRealData) {
|
| + if (!IsHistorySwipingSupported())
|
| + return;
|
| +
|
| + QueueTouch(0.510681,
|
| + 0.444672,
|
| + DEPLOYMENT_TOUCHES_BEGAN,
|
| + NSEventTypeGesture,
|
| + NSMouseEventSubtype,
|
| + NO);
|
| + QueueTrackpadScroll(0, 0, NSEventPhaseMayBegin, YES);
|
| + QueueTouch(0.510681,
|
| + 0.444672,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSMouseEventSubtype,
|
| + NO);
|
| +
|
| + QueueTrackpadScroll(1, 0, NSEventPhaseBegan, NO);
|
| + QueueGestureBegin();
|
| + QueueTouch(0.510681,
|
| + 0.444672,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeBeginGesture,
|
| + NSTouchEventSubtype,
|
| + NO);
|
| + QueueTouch(0.510681,
|
| + 0.444672,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTouch(0.507019,
|
| + 0.444092,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + NO);
|
| + QueueTrackpadScroll(3, 0, NSEventPhaseChanged, YES);
|
| +
|
| + QueueTrackpadScroll(3, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.502861,
|
| + 0.443512,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(6, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.497002,
|
| + 0.44294,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(5, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.487236,
|
| + 0.44149,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(8, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.480392,
|
| + 0.440628,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + NO);
|
| + QueueTouch(0.475266,
|
| + 0.440338,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(6, -1, NSEventPhaseChanged, NO);
|
| + QueueTrackpadScroll(10, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.467934,
|
| + 0.439758,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(6, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.462807,
|
| + 0.439186,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTrackpadScroll(12, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.454018,
|
| + 0.438316,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(6, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.449623,
|
| + 0.438026,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(9, 0, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.443275,
|
| + 0.437744,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTouch(0.437164,
|
| + 0.437164,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(9, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.431305,
|
| + 0.436874,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTrackpadScroll(8, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.425926,
|
| + 0.436295,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTrackpadScroll(7, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.420311,
|
| + 0.43573,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(7, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.415184,
|
| + 0.43544,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTrackpadScroll(6, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.410057,
|
| + 0.43457,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTouch(0.40493,
|
| + 0.43399,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTrackpadScroll(7, -1, NSEventPhaseChanged, YES);
|
| + QueueTrackpadScroll(3, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.402489,
|
| + 0.433701,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTrackpadScroll(5, 0, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.398094,
|
| + 0.433418,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + QueueTrackpadScroll(4, -1, NSEventPhaseChanged, NO);
|
| + QueueTouch(0.394669,
|
| + 0.433128,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTouch(0.391006,
|
| + 0.432549,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTrackpadScroll(4, -1, NSEventPhaseChanged, NO);
|
| + QueueTrackpadScroll(5, 0, NSEventPhaseChanged, YES);
|
| + QueueTouch(0.386848,
|
| + 0.432259,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| + QueueTouch(0.38343,
|
| + 0.432259,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeGesture,
|
| + NSTouchEventSubtype,
|
| + YES);
|
| +
|
| + // Skipped a bunch of events. The data on the gesture end events are fudged.
|
| +
|
| + QueueTouch(0.38343,
|
| + 0.432259,
|
| + DEPLOYMENT_TOUCHES_MOVED,
|
| + NSEventTypeEndGesture,
|
| + NSMouseEventSubtype,
|
| + NO);
|
| + QueueTouch(0.38343,
|
| + 0.432259,
|
| + DEPLOYMENT_TOUCHES_ENDED,
|
| + NSEventTypeEndGesture,
|
| + NSMouseEventSubtype,
|
| + NO);
|
| + QueueGestureEnd();
|
| + QueueTrackpadScroll(0, 0, NSEventPhaseEnded, YES);
|
| +
|
| + RunQueuedEvents();
|
| + ExpectUrlAndOffset(url1_, 0);
|
| +}
|
| +
|
| +// Each movement event that has non-zero parameters has both horizontal and
|
| +// vertical motion. This should not trigger history navigation.
|
| +IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacHistorySwiperTest,
|
| + TestAllDiagonalSwipes) {
|
| + if (!IsHistorySwipingSupported())
|
| + return;
|
| +
|
| + QueueBeginningEvents(1, -1);
|
| + for (int i = 0; i < 150; ++i)
|
| + QueueScrollAndTouchMoved(1, -1);
|
| +
|
| + QueueEndEvents();
|
| + RunQueuedEvents();
|
| + ExpectUrlAndOffset(url2_, 150);
|
| +}
|
| +
|
| +// The movements are equal part diagonal, horizontal, and vertical. This should
|
| +// not trigger history navigation.
|
| +IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacHistorySwiperTest,
|
| + TestStaggeredDiagonalSwipe) {
|
| + if (!IsHistorySwipingSupported())
|
| + return;
|
| +
|
| + QueueBeginningEvents(1, 0);
|
| + for (int i = 0; i < 150; ++i) {
|
| + switch (i % 3) {
|
| + case 0:
|
| + QueueScrollAndTouchMoved(1, -1);
|
| + break;
|
| + case 1:
|
| + QueueScrollAndTouchMoved(0, -1);
|
| + break;
|
| + case 2:
|
| + QueueScrollAndTouchMoved(1, 0);
|
| + break;
|
| + default:
|
| + NOTREACHED();
|
| + }
|
| + }
|
| +
|
| + QueueEndEvents();
|
| + RunQueuedEvents();
|
| +
|
| + content::WaitForLoadStop(GetWebContents());
|
| + EXPECT_EQ(url2_, GetWebContents()->GetURL());
|
| +
|
| + // Depending on the timing of the IPCs, some of the initial events might be
|
| + // recognized as part of the history swipe, and not forwarded to the renderer,
|
| + // resulting in a non-deterministic scroll offset. This is bad, as some
|
| + // vertical motion is lost. Once the history swiper logic is fixed, this
|
| + // should become a direct comparison between 'scroll_offset' and 100.
|
| + // crbug.com/375514
|
| + const int scroll_offset = GetScrollTop();
|
| + EXPECT_GT(scroll_offset, 85);
|
| +}
|
| +
|
| +// The movement events are mostly in the horizontal direction, which should
|
| +// trigger a history swipe. This should trigger history navigation.
|
| +IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacHistorySwiperTest,
|
| + TestMostlyHorizontal) {
|
| + if (!IsHistorySwipingSupported())
|
| + return;
|
| +
|
| + QueueBeginningEvents(1, -1);
|
| + for (int i = 0; i < 150; ++i) {
|
| + if (i % 10 == 0) {
|
| + QueueScrollAndTouchMoved(0, -1);
|
| + } else if (i % 5 == 0) {
|
| + QueueScrollAndTouchMoved(1, -1);
|
| + } else {
|
| + QueueScrollAndTouchMoved(1, 0);
|
| + }
|
| + }
|
| +
|
| + QueueEndEvents();
|
| + RunQueuedEvents();
|
| + ExpectUrlAndOffset(url1_, 0);
|
| +}
|
| +
|
| +// Each movement event is horizontal, except the first two. This should trigger
|
| +// history navigation. This test is DISABLED because it has never worked. Once
|
| +// the flaw in the history swiper logic has been corrected, this test should be
|
| +// enabled.
|
| +// crbug.com/375512
|
| +IN_PROC_BROWSER_TEST_F(ChromeRenderWidgetHostViewMacHistorySwiperTest,
|
| + DISABLED_TestAllHorizontalButFirst) {
|
| + if (!IsHistorySwipingSupported())
|
| + return;
|
| +
|
| + QueueBeginningEvents(0, -1);
|
| + QueueScrollAndTouchMoved(0, -1);
|
| + for (int i = 0; i < 149; ++i)
|
| + QueueScrollAndTouchMoved(1, 0);
|
| +
|
| + QueueEndEvents();
|
| + RunQueuedEvents();
|
| + ExpectUrlAndOffset(url1_, 0);
|
| +}
|
|
|