tor-browser

The Tor Browser
git clone https://git.dasho.dev/tor-browser.git
Log | Files | Refs | README | LICENSE

TestAccessibleCaretEventHub.cpp (30177B)


      1 /* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
      2 /* vim: set ts=8 sts=2 et sw=2 tw=80: */
      3 /* This Source Code Form is subject to the terms of the Mozilla Public
      4 * License, v. 2.0. If a copy of the MPL was not distributed with this
      5 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
      6 
      7 #include <iostream>
      8 #include <string>
      9 
     10 #include "AccessibleCaretManager.h"
     11 #include "gmock/gmock.h"
     12 #include "gtest/gtest.h"
     13 #include "mozilla/AccessibleCaretEventHub.h"
     14 #include "mozilla/BasicEvents.h"
     15 #include "mozilla/MouseEvents.h"
     16 #include "mozilla/TouchEvents.h"
     17 
     18 using ::testing::_;
     19 using ::testing::AtLeast;
     20 using ::testing::DefaultValue;
     21 using ::testing::Eq;
     22 using ::testing::InSequence;
     23 using ::testing::MockFunction;
     24 using ::testing::Return;
     25 
     26 // -----------------------------------------------------------------------------
     27 // This file test the state transitions of AccessibleCaretEventHub under
     28 // various combination of events and callbacks.
     29 
     30 namespace mozilla {
     31 
     32 class MockAccessibleCaretManager : public AccessibleCaretManager {
     33 public:
     34  MockAccessibleCaretManager() : AccessibleCaretManager(nullptr) {}
     35 
     36  MOCK_METHOD2(PressCaret,
     37               nsresult(const nsPoint& aPoint, EventClassID aEventClass));
     38  MOCK_METHOD1(DragCaret, nsresult(const nsPoint& aPoint));
     39  MOCK_METHOD0(ReleaseCaret, nsresult());
     40  MOCK_METHOD1(TapCaret, nsresult(const nsPoint& aPoint));
     41  MOCK_METHOD1(SelectWordOrShortcut, nsresult(const nsPoint& aPoint));
     42  MOCK_METHOD0(OnScrollStart, void());
     43  MOCK_METHOD0(OnScrollEnd, void());
     44  MOCK_METHOD0(OnScrollPositionChanged, void());
     45  MOCK_METHOD0(OnBlur, void());
     46 };
     47 
     48 class MockAccessibleCaretEventHub : public AccessibleCaretEventHub {
     49 public:
     50  using AccessibleCaretEventHub::DragCaretState;
     51  using AccessibleCaretEventHub::LongTapState;
     52  using AccessibleCaretEventHub::NoActionState;
     53  using AccessibleCaretEventHub::PressCaretState;
     54  using AccessibleCaretEventHub::PressNoCaretState;
     55  using AccessibleCaretEventHub::ScrollState;
     56 
     57  MockAccessibleCaretEventHub() : AccessibleCaretEventHub(nullptr) {
     58    mManager = MakeUnique<MockAccessibleCaretManager>();
     59    mInitialized = true;
     60  }
     61 
     62  nsPoint GetTouchEventPosition(WidgetTouchEvent* aEvent,
     63                                int32_t aIdentifier) const override {
     64    // Return the device point directly.
     65    LayoutDeviceIntPoint touchIntPoint = aEvent->mTouches[0]->mRefPoint;
     66    return nsPoint(touchIntPoint.x, touchIntPoint.y);
     67  }
     68 
     69  nsPoint GetMouseEventPosition(WidgetMouseEvent* aEvent) const override {
     70    // Return the device point directly.
     71    LayoutDeviceIntPoint mouseIntPoint = aEvent->AsGUIEvent()->mRefPoint;
     72    return nsPoint(mouseIntPoint.x, mouseIntPoint.y);
     73  }
     74 
     75  MockAccessibleCaretManager* GetMockAccessibleCaretManager() {
     76    return static_cast<MockAccessibleCaretManager*>(mManager.get());
     77  }
     78 };
     79 
     80 // Print the name of the state for debugging.
     81 static ::std::ostream& operator<<(
     82    ::std::ostream& aOstream,
     83    const MockAccessibleCaretEventHub::State* aState) {
     84  return aOstream << aState->Name();
     85 }
     86 
     87 class AccessibleCaretEventHubTester : public ::testing::Test {
     88 public:
     89  AccessibleCaretEventHubTester() {
     90    DefaultValue<nsresult>::Set(NS_OK);
     91    EXPECT_EQ(mHub->GetState(), MockAccessibleCaretEventHub::NoActionState());
     92 
     93    // AccessibleCaretEventHub requires the caller to hold a ref to it. We just
     94    // add ref here for the sake of convenience.
     95    mHub.get()->AddRef();
     96  }
     97 
     98  ~AccessibleCaretEventHubTester() override {
     99    // Release the ref added in the constructor.
    100    mHub.get()->Release();
    101  }
    102 
    103  static UniquePtr<WidgetEvent> CreateMouseEvent(EventMessage aMessage,
    104                                                 nscoord aX, nscoord aY) {
    105    auto event = MakeUnique<WidgetMouseEvent>(true, aMessage, nullptr,
    106                                              WidgetMouseEvent::eReal);
    107 
    108    event->mButton = MouseButton::ePrimary;
    109    event->mRefPoint = LayoutDeviceIntPoint(aX, aY);
    110 
    111    return std::move(event);
    112  }
    113 
    114  static UniquePtr<WidgetEvent> CreateMousePressEvent(nscoord aX, nscoord aY) {
    115    return CreateMouseEvent(eMouseDown, aX, aY);
    116  }
    117 
    118  static UniquePtr<WidgetEvent> CreateMouseMoveEvent(nscoord aX, nscoord aY) {
    119    return CreateMouseEvent(eMouseMove, aX, aY);
    120  }
    121 
    122  static UniquePtr<WidgetEvent> CreateMouseReleaseEvent(nscoord aX,
    123                                                        nscoord aY) {
    124    return CreateMouseEvent(eMouseUp, aX, aY);
    125  }
    126 
    127  static UniquePtr<WidgetEvent> CreateLongTapEvent(nscoord aX, nscoord aY) {
    128    return CreateMouseEvent(eMouseLongTap, aX, aY);
    129  }
    130 
    131  static UniquePtr<WidgetEvent> CreateTouchEvent(EventMessage aMessage,
    132                                                 nscoord aX, nscoord aY) {
    133    auto event = MakeUnique<WidgetTouchEvent>(true, aMessage, nullptr);
    134    int32_t identifier = 0;
    135    LayoutDeviceIntPoint point(aX, aY);
    136    LayoutDeviceIntPoint radius(19, 19);
    137    float rotationAngle = 0;
    138    float force = 1;
    139 
    140    RefPtr<dom::Touch> touch(
    141        new dom::Touch(identifier, point, radius, rotationAngle, force));
    142    event->mTouches.AppendElement(touch);
    143 
    144    return std::move(event);
    145  }
    146 
    147  static UniquePtr<WidgetEvent> CreateTouchStartEvent(nscoord aX, nscoord aY) {
    148    return CreateTouchEvent(eTouchStart, aX, aY);
    149  }
    150 
    151  static UniquePtr<WidgetEvent> CreateTouchMoveEvent(nscoord aX, nscoord aY) {
    152    return CreateTouchEvent(eTouchMove, aX, aY);
    153  }
    154 
    155  static UniquePtr<WidgetEvent> CreateTouchEndEvent(nscoord aX, nscoord aY) {
    156    return CreateTouchEvent(eTouchEnd, aX, aY);
    157  }
    158 
    159  static UniquePtr<WidgetEvent> CreateTouchCancelEvent(nscoord aX, nscoord aY) {
    160    return CreateTouchEvent(eTouchCancel, aX, aY);
    161  }
    162 
    163  static UniquePtr<WidgetEvent> CreateWheelEvent(EventMessage aMessage) {
    164    auto event = MakeUnique<WidgetWheelEvent>(true, aMessage, nullptr);
    165 
    166    return std::move(event);
    167  }
    168 
    169  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestAsyncPanZoomScroll();
    170 
    171  MOZ_CAN_RUN_SCRIPT_BOUNDARY
    172  void HandleEventAndCheckState(
    173      UniquePtr<WidgetEvent> aEvent,
    174      MockAccessibleCaretEventHub::State* aExpectedState,
    175      nsEventStatus aExpectedEventStatus) {
    176    RefPtr<MockAccessibleCaretEventHub> hub(mHub);
    177    nsEventStatus rv = hub->HandleEvent(aEvent.get());
    178    EXPECT_EQ(hub->GetState(), aExpectedState);
    179    EXPECT_EQ(rv, aExpectedEventStatus);
    180  }
    181 
    182  void CheckState(MockAccessibleCaretEventHub::State* aExpectedState) {
    183    EXPECT_EQ(mHub->GetState(), aExpectedState);
    184  }
    185 
    186  template <typename PressEventCreator, typename ReleaseEventCreator>
    187  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressReleaseOnNoCaret(
    188      PressEventCreator aPressEventCreator,
    189      ReleaseEventCreator aReleaseEventCreator);
    190 
    191  template <typename PressEventCreator, typename ReleaseEventCreator>
    192  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressReleaseOnCaret(
    193      PressEventCreator aPressEventCreator,
    194      ReleaseEventCreator aReleaseEventCreator);
    195 
    196  template <typename PressEventCreator, typename MoveEventCreator,
    197            typename ReleaseEventCreator>
    198  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressMoveReleaseOnNoCaret(
    199      PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator,
    200      ReleaseEventCreator aReleaseEventCreator);
    201 
    202  template <typename PressEventCreator, typename MoveEventCreator,
    203            typename ReleaseEventCreator>
    204  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestPressMoveReleaseOnCaret(
    205      PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator,
    206      ReleaseEventCreator aReleaseEventCreator);
    207 
    208  template <typename PressEventCreator, typename ReleaseEventCreator>
    209  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestLongTapWithSelectWordSuccessful(
    210      PressEventCreator aPressEventCreator,
    211      ReleaseEventCreator aReleaseEventCreator);
    212 
    213  template <typename PressEventCreator, typename ReleaseEventCreator>
    214  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestLongTapWithSelectWordFailed(
    215      PressEventCreator aPressEventCreator,
    216      ReleaseEventCreator aReleaseEventCreator);
    217 
    218  template <typename PressEventCreator, typename MoveEventCreator,
    219            typename ReleaseEventCreator>
    220  MOZ_CAN_RUN_SCRIPT_BOUNDARY void TestEventDrivenAsyncPanZoomScroll(
    221      PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator,
    222      ReleaseEventCreator aReleaseEventCreator);
    223 
    224  // Member variables
    225  RefPtr<MockAccessibleCaretEventHub> mHub{new MockAccessibleCaretEventHub()};
    226 
    227 };  // class AccessibleCaretEventHubTester
    228 
    229 TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnNoCaret)
    230 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    231  TestPressReleaseOnNoCaret(CreateMousePressEvent, CreateMouseReleaseEvent);
    232 }
    233 
    234 TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnNoCaret)
    235 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    236  TestPressReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchEndEvent);
    237 }
    238 
    239 template <typename PressEventCreator, typename ReleaseEventCreator>
    240 void AccessibleCaretEventHubTester::TestPressReleaseOnNoCaret(
    241    PressEventCreator aPressEventCreator,
    242    ReleaseEventCreator aReleaseEventCreator) {
    243  EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    244      .WillOnce(Return(NS_ERROR_FAILURE));
    245 
    246  EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret()).Times(0);
    247 
    248  EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), TapCaret(_)).Times(0);
    249 
    250  HandleEventAndCheckState(aPressEventCreator(0, 0),
    251                           MockAccessibleCaretEventHub::PressNoCaretState(),
    252                           nsEventStatus_eIgnore);
    253 
    254  HandleEventAndCheckState(aReleaseEventCreator(0, 0),
    255                           MockAccessibleCaretEventHub::NoActionState(),
    256                           nsEventStatus_eIgnore);
    257 }
    258 
    259 TEST_F(AccessibleCaretEventHubTester, TestMousePressReleaseOnCaret)
    260 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    261  TestPressReleaseOnCaret(CreateMousePressEvent, CreateMouseReleaseEvent);
    262 }
    263 
    264 TEST_F(AccessibleCaretEventHubTester, TestTouchPressReleaseOnCaret)
    265 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    266  TestPressReleaseOnCaret(CreateTouchStartEvent, CreateTouchEndEvent);
    267 }
    268 
    269 template <typename PressEventCreator, typename ReleaseEventCreator>
    270 void AccessibleCaretEventHubTester::TestPressReleaseOnCaret(
    271    PressEventCreator aPressEventCreator,
    272    ReleaseEventCreator aReleaseEventCreator) {
    273  {
    274    InSequence dummy;
    275 
    276    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    277        .WillOnce(Return(NS_OK));
    278 
    279    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_))
    280        .Times(0);
    281 
    282    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret());
    283    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), TapCaret(_));
    284  }
    285 
    286  HandleEventAndCheckState(aPressEventCreator(0, 0),
    287                           MockAccessibleCaretEventHub::PressCaretState(),
    288                           nsEventStatus_eConsumeNoDefault);
    289 
    290  HandleEventAndCheckState(CreateLongTapEvent(0, 0),
    291                           MockAccessibleCaretEventHub::PressCaretState(),
    292                           nsEventStatus_eConsumeNoDefault);
    293 
    294  HandleEventAndCheckState(aReleaseEventCreator(0, 0),
    295                           MockAccessibleCaretEventHub::NoActionState(),
    296                           nsEventStatus_eConsumeNoDefault);
    297 }
    298 
    299 TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnNoCaret)
    300 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    301  TestPressMoveReleaseOnNoCaret(CreateMousePressEvent, CreateMouseMoveEvent,
    302                                CreateMouseReleaseEvent);
    303 }
    304 
    305 TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnNoCaret)
    306 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    307  TestPressMoveReleaseOnNoCaret(CreateTouchStartEvent, CreateTouchMoveEvent,
    308                                CreateTouchEndEvent);
    309 }
    310 
    311 template <typename PressEventCreator, typename MoveEventCreator,
    312          typename ReleaseEventCreator>
    313 void AccessibleCaretEventHubTester::TestPressMoveReleaseOnNoCaret(
    314    PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator,
    315    ReleaseEventCreator aReleaseEventCreator) {
    316  nscoord x0 = 0, y0 = 0;
    317  nscoord x1 = 100, y1 = 100;
    318  nscoord x2 = 300, y2 = 300;
    319  nscoord x3 = 400, y3 = 400;
    320 
    321  {
    322    InSequence dummy;
    323 
    324    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    325        .WillOnce(Return(NS_ERROR_FAILURE));
    326 
    327    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0);
    328  }
    329 
    330  HandleEventAndCheckState(aPressEventCreator(x0, y0),
    331                           MockAccessibleCaretEventHub::PressNoCaretState(),
    332                           nsEventStatus_eIgnore);
    333 
    334  // A small move with the distance between (x0, y0) and (x1, y1) below the
    335  // tolerance value.
    336  HandleEventAndCheckState(aMoveEventCreator(x1, y1),
    337                           MockAccessibleCaretEventHub::PressNoCaretState(),
    338                           nsEventStatus_eIgnore);
    339 
    340  // A large move to simulate a dragging to select text since the distance
    341  // between (x0, y0) and (x2, y2) is above the tolerance value.
    342  HandleEventAndCheckState(aMoveEventCreator(x2, y2),
    343                           MockAccessibleCaretEventHub::NoActionState(),
    344                           nsEventStatus_eIgnore);
    345 
    346  HandleEventAndCheckState(aReleaseEventCreator(x3, y3),
    347                           MockAccessibleCaretEventHub::NoActionState(),
    348                           nsEventStatus_eIgnore);
    349 }
    350 
    351 TEST_F(AccessibleCaretEventHubTester, TestMousePressMoveReleaseOnCaret)
    352 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    353  TestPressMoveReleaseOnCaret(CreateMousePressEvent, CreateMouseMoveEvent,
    354                              CreateMouseReleaseEvent);
    355 }
    356 
    357 TEST_F(AccessibleCaretEventHubTester, TestTouchPressMoveReleaseOnCaret)
    358 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    359  TestPressMoveReleaseOnCaret(CreateTouchStartEvent, CreateTouchMoveEvent,
    360                              CreateTouchEndEvent);
    361 }
    362 
    363 template <typename PressEventCreator, typename MoveEventCreator,
    364          typename ReleaseEventCreator>
    365 void AccessibleCaretEventHubTester::TestPressMoveReleaseOnCaret(
    366    PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator,
    367    ReleaseEventCreator aReleaseEventCreator) {
    368  nscoord x0 = 0, y0 = 0;
    369  nscoord x1 = 100, y1 = 100;
    370  nscoord x2 = 300, y2 = 300;
    371  nscoord x3 = 400, y3 = 400;
    372 
    373  {
    374    InSequence dummy;
    375 
    376    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    377        .WillOnce(Return(NS_OK));
    378 
    379    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_))
    380        .Times(2)  // two valid drag operations
    381        .WillRepeatedly(Return(NS_OK));
    382 
    383    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret())
    384        .WillOnce(Return(NS_OK));
    385  }
    386 
    387  HandleEventAndCheckState(aPressEventCreator(x0, y0),
    388                           MockAccessibleCaretEventHub::PressCaretState(),
    389                           nsEventStatus_eConsumeNoDefault);
    390 
    391  // A small move with the distance between (x0, y0) and (x1, y1) below the
    392  // tolerance value.
    393  HandleEventAndCheckState(aMoveEventCreator(x1, y1),
    394                           MockAccessibleCaretEventHub::PressCaretState(),
    395                           nsEventStatus_eConsumeNoDefault);
    396 
    397  // A large move forms a valid drag since the distance between (x0, y0) and
    398  // (x2, y2) is above the tolerance value.
    399  HandleEventAndCheckState(aMoveEventCreator(x2, y2),
    400                           MockAccessibleCaretEventHub::DragCaretState(),
    401                           nsEventStatus_eConsumeNoDefault);
    402 
    403  // Also a valid drag since the distance between (x0, y0) and (x3, y3) above
    404  // the tolerance value even if the distance between (x2, y2) and (x3, y3) is
    405  // below the tolerance value.
    406  HandleEventAndCheckState(aMoveEventCreator(x3, y3),
    407                           MockAccessibleCaretEventHub::DragCaretState(),
    408                           nsEventStatus_eConsumeNoDefault);
    409 
    410  HandleEventAndCheckState(aReleaseEventCreator(x3, y3),
    411                           MockAccessibleCaretEventHub::NoActionState(),
    412                           nsEventStatus_eConsumeNoDefault);
    413 }
    414 
    415 TEST_F(AccessibleCaretEventHubTester,
    416       TestTouchStartMoveEndOnCaretWithTouchCancelIgnored)
    417 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    418  nscoord x0 = 0, y0 = 0;
    419  nscoord x1 = 100, y1 = 100;
    420  nscoord x2 = 300, y2 = 300;
    421  nscoord x3 = 400, y3 = 400;
    422 
    423  {
    424    InSequence dummy;
    425 
    426    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    427        .WillOnce(Return(NS_OK));
    428 
    429    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_))
    430        .WillOnce(Return(NS_OK));
    431 
    432    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), ReleaseCaret())
    433        .WillOnce(Return(NS_OK));
    434  }
    435 
    436  // All the eTouchCancel events should be ignored in this test.
    437 
    438  HandleEventAndCheckState(CreateTouchStartEvent(x0, y0),
    439                           MockAccessibleCaretEventHub::PressCaretState(),
    440                           nsEventStatus_eConsumeNoDefault);
    441 
    442  HandleEventAndCheckState(CreateTouchCancelEvent(x0, y0),
    443                           MockAccessibleCaretEventHub::PressCaretState(),
    444                           nsEventStatus_eIgnore);
    445 
    446  // A small move with the distance between (x0, y0) and (x1, y1) below the
    447  // tolerance value.
    448  HandleEventAndCheckState(CreateTouchMoveEvent(x1, y1),
    449                           MockAccessibleCaretEventHub::PressCaretState(),
    450                           nsEventStatus_eConsumeNoDefault);
    451 
    452  HandleEventAndCheckState(CreateTouchCancelEvent(x1, y1),
    453                           MockAccessibleCaretEventHub::PressCaretState(),
    454                           nsEventStatus_eIgnore);
    455 
    456  // A large move forms a valid drag since the distance between (x0, y0) and
    457  // (x2, y2) is above the tolerance value.
    458  HandleEventAndCheckState(CreateTouchMoveEvent(x2, y2),
    459                           MockAccessibleCaretEventHub::DragCaretState(),
    460                           nsEventStatus_eConsumeNoDefault);
    461 
    462  HandleEventAndCheckState(CreateTouchCancelEvent(x2, y2),
    463                           MockAccessibleCaretEventHub::DragCaretState(),
    464                           nsEventStatus_eIgnore);
    465 
    466  HandleEventAndCheckState(CreateTouchEndEvent(x3, y3),
    467                           MockAccessibleCaretEventHub::NoActionState(),
    468                           nsEventStatus_eConsumeNoDefault);
    469 
    470  HandleEventAndCheckState(CreateTouchCancelEvent(x3, y3),
    471                           MockAccessibleCaretEventHub::NoActionState(),
    472                           nsEventStatus_eIgnore);
    473 }
    474 
    475 TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordSuccessful)
    476 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    477  TestLongTapWithSelectWordSuccessful(CreateMousePressEvent,
    478                                      CreateMouseReleaseEvent);
    479 }
    480 
    481 TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordSuccessful)
    482 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    483  TestLongTapWithSelectWordSuccessful(CreateTouchStartEvent,
    484                                      CreateTouchEndEvent);
    485 }
    486 
    487 template <typename PressEventCreator, typename ReleaseEventCreator>
    488 void AccessibleCaretEventHubTester::TestLongTapWithSelectWordSuccessful(
    489    PressEventCreator aPressEventCreator,
    490    ReleaseEventCreator aReleaseEventCreator) {
    491  MockFunction<void(::std::string aCheckPointName)> check;
    492  {
    493    InSequence dummy;
    494 
    495    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    496        .WillOnce(Return(NS_ERROR_FAILURE));
    497 
    498    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_))
    499        .WillOnce(Return(NS_OK));
    500 
    501    EXPECT_CALL(check, Call("longtap with scrolling"));
    502 
    503    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    504        .WillOnce(Return(NS_ERROR_FAILURE));
    505 
    506    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_))
    507        .WillOnce(Return(NS_OK));
    508 
    509    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
    510    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd());
    511  }
    512 
    513  // Test long tap without scrolling.
    514  HandleEventAndCheckState(aPressEventCreator(0, 0),
    515                           MockAccessibleCaretEventHub::PressNoCaretState(),
    516                           nsEventStatus_eIgnore);
    517 
    518  HandleEventAndCheckState(CreateLongTapEvent(0, 0),
    519                           MockAccessibleCaretEventHub::LongTapState(),
    520                           nsEventStatus_eIgnore);
    521 
    522  HandleEventAndCheckState(aReleaseEventCreator(0, 0),
    523                           MockAccessibleCaretEventHub::NoActionState(),
    524                           nsEventStatus_eIgnore);
    525 
    526  // On Fennec, after long tap, the script might scroll and zoom the input field
    527  // to the center of the screen to make typing easier before the user lifts the
    528  // finger.
    529  check.Call("longtap with scrolling");
    530 
    531  HandleEventAndCheckState(aPressEventCreator(1, 1),
    532                           MockAccessibleCaretEventHub::PressNoCaretState(),
    533                           nsEventStatus_eIgnore);
    534 
    535  HandleEventAndCheckState(CreateLongTapEvent(1, 1),
    536                           MockAccessibleCaretEventHub::LongTapState(),
    537                           nsEventStatus_eIgnore);
    538 
    539  RefPtr<MockAccessibleCaretEventHub> hub(mHub);
    540  hub->AsyncPanZoomStarted();
    541  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    542 
    543  hub->ScrollPositionChanged();
    544  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    545 
    546  hub->AsyncPanZoomStopped();
    547  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    548 
    549  HandleEventAndCheckState(aReleaseEventCreator(1, 1),
    550                           MockAccessibleCaretEventHub::NoActionState(),
    551                           nsEventStatus_eIgnore);
    552 }
    553 
    554 TEST_F(AccessibleCaretEventHubTester, TestMouseLongTapWithSelectWordFailed)
    555 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    556  TestLongTapWithSelectWordFailed(CreateMousePressEvent,
    557                                  CreateMouseReleaseEvent);
    558 }
    559 
    560 TEST_F(AccessibleCaretEventHubTester, TestTouchLongTapWithSelectWordFailed)
    561 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    562  TestLongTapWithSelectWordFailed(CreateTouchStartEvent, CreateTouchEndEvent);
    563 }
    564 
    565 template <typename PressEventCreator, typename ReleaseEventCreator>
    566 void AccessibleCaretEventHubTester::TestLongTapWithSelectWordFailed(
    567    PressEventCreator aPressEventCreator,
    568    ReleaseEventCreator aReleaseEventCreator) {
    569  {
    570    InSequence dummy;
    571 
    572    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    573        .WillOnce(Return(NS_ERROR_FAILURE));
    574 
    575    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), SelectWordOrShortcut(_))
    576        .WillOnce(Return(NS_ERROR_FAILURE));
    577  }
    578 
    579  HandleEventAndCheckState(aPressEventCreator(0, 0),
    580                           MockAccessibleCaretEventHub::PressNoCaretState(),
    581                           nsEventStatus_eIgnore);
    582 
    583  HandleEventAndCheckState(CreateLongTapEvent(0, 0),
    584                           MockAccessibleCaretEventHub::LongTapState(),
    585                           nsEventStatus_eIgnore);
    586 
    587  HandleEventAndCheckState(aReleaseEventCreator(0, 0),
    588                           MockAccessibleCaretEventHub::NoActionState(),
    589                           nsEventStatus_eIgnore);
    590 }
    591 
    592 TEST_F(AccessibleCaretEventHubTester, TestTouchEventDrivenAsyncPanZoomScroll)
    593 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    594  TestEventDrivenAsyncPanZoomScroll(CreateTouchStartEvent, CreateTouchMoveEvent,
    595                                    CreateTouchEndEvent);
    596 }
    597 
    598 TEST_F(AccessibleCaretEventHubTester, TestMouseEventDrivenAsyncPanZoomScroll)
    599 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    600  TestEventDrivenAsyncPanZoomScroll(CreateMousePressEvent, CreateMouseMoveEvent,
    601                                    CreateMouseReleaseEvent);
    602 }
    603 
    604 template <typename PressEventCreator, typename MoveEventCreator,
    605          typename ReleaseEventCreator>
    606 void AccessibleCaretEventHubTester::TestEventDrivenAsyncPanZoomScroll(
    607    PressEventCreator aPressEventCreator, MoveEventCreator aMoveEventCreator,
    608    ReleaseEventCreator aReleaseEventCreator) {
    609  MockFunction<void(::std::string aCheckPointName)> check;
    610  {
    611    InSequence dummy;
    612 
    613    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    614        .WillOnce(Return(NS_ERROR_FAILURE));
    615    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0);
    616 
    617    EXPECT_CALL(check, Call("1"));
    618    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
    619    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd());
    620 
    621    EXPECT_CALL(check, Call("2"));
    622    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), PressCaret(_, _))
    623        .WillOnce(Return(NS_ERROR_FAILURE));
    624    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), DragCaret(_)).Times(0);
    625 
    626    EXPECT_CALL(check, Call("3"));
    627    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
    628    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd());
    629  }
    630 
    631  // Receive press event.
    632  HandleEventAndCheckState(aPressEventCreator(0, 0),
    633                           MockAccessibleCaretEventHub::PressNoCaretState(),
    634                           nsEventStatus_eIgnore);
    635 
    636  HandleEventAndCheckState(aMoveEventCreator(100, 100),
    637                           MockAccessibleCaretEventHub::PressNoCaretState(),
    638                           nsEventStatus_eIgnore);
    639 
    640  check.Call("1");
    641 
    642  // Event driven scroll started
    643  RefPtr<MockAccessibleCaretEventHub> hub(mHub);
    644  hub->AsyncPanZoomStarted();
    645  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    646 
    647  HandleEventAndCheckState(aMoveEventCreator(160, 160),
    648                           MockAccessibleCaretEventHub::ScrollState(),
    649                           nsEventStatus_eIgnore);
    650 
    651  hub->ScrollPositionChanged();
    652  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    653 
    654  // Event driven scroll ended
    655  hub->AsyncPanZoomStopped();
    656  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    657 
    658  HandleEventAndCheckState(aReleaseEventCreator(210, 210),
    659                           MockAccessibleCaretEventHub::NoActionState(),
    660                           nsEventStatus_eIgnore);
    661 
    662  check.Call("2");
    663 
    664  // Receive another press event.
    665  HandleEventAndCheckState(aPressEventCreator(220, 220),
    666                           MockAccessibleCaretEventHub::PressNoCaretState(),
    667                           nsEventStatus_eIgnore);
    668 
    669  HandleEventAndCheckState(aMoveEventCreator(230, 230),
    670                           MockAccessibleCaretEventHub::PressNoCaretState(),
    671                           nsEventStatus_eIgnore);
    672 
    673  check.Call("3");
    674 
    675  // Another APZ scroll started
    676  hub->AsyncPanZoomStarted();
    677  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    678 
    679  hub->ScrollPositionChanged();
    680  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    681 
    682  // Another APZ scroll ended
    683  hub->AsyncPanZoomStopped();
    684  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    685 
    686  HandleEventAndCheckState(aReleaseEventCreator(310, 310),
    687                           MockAccessibleCaretEventHub::NoActionState(),
    688                           nsEventStatus_eIgnore);
    689 }
    690 
    691 TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScroll)
    692 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION { TestAsyncPanZoomScroll(); }
    693 
    694 void AccessibleCaretEventHubTester::TestAsyncPanZoomScroll() {
    695  MockFunction<void(::std::string aCheckPointName)> check;
    696  {
    697    InSequence dummy;
    698 
    699    EXPECT_CALL(check, Call("1"));
    700    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
    701    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(),
    702                OnScrollPositionChanged());
    703    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd());
    704 
    705    EXPECT_CALL(check, Call("2"));
    706    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
    707    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(),
    708                OnScrollPositionChanged());
    709    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd());
    710  }
    711 
    712  // First APZ scrolling.
    713  check.Call("1");
    714 
    715  RefPtr<MockAccessibleCaretEventHub> hub(mHub);
    716  hub->AsyncPanZoomStarted();
    717  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    718 
    719  hub->ScrollPositionChanged();
    720  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    721 
    722  hub->AsyncPanZoomStopped();
    723  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    724 
    725  // Second APZ scrolling.
    726  check.Call("2");
    727 
    728  hub->AsyncPanZoomStarted();
    729  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    730 
    731  hub->ScrollPositionChanged();
    732  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    733 
    734  hub->AsyncPanZoomStopped();
    735  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    736 }
    737 
    738 TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollStartedThenBlur)
    739 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    740  {
    741    InSequence dummy;
    742 
    743    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
    744    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd()).Times(0);
    745    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur());
    746  }
    747 
    748  RefPtr<MockAccessibleCaretEventHub> hub(mHub);
    749  hub->AsyncPanZoomStarted();
    750  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    751 
    752  hub->ScrollPositionChanged();
    753  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    754 
    755  hub->NotifyBlur(true);
    756  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    757 }
    758 
    759 TEST_F(AccessibleCaretEventHubTester, TestAsyncPanZoomScrollEndedThenBlur)
    760 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
    761  {
    762    InSequence dummy;
    763 
    764    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollStart());
    765    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnScrollEnd());
    766    EXPECT_CALL(*mHub->GetMockAccessibleCaretManager(), OnBlur());
    767  }
    768 
    769  RefPtr<MockAccessibleCaretEventHub> hub(mHub);
    770  hub->AsyncPanZoomStarted();
    771  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    772 
    773  hub->ScrollPositionChanged();
    774  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::ScrollState());
    775 
    776  hub->AsyncPanZoomStopped();
    777  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    778 
    779  hub->NotifyBlur(true);
    780  EXPECT_EQ(hub->GetState(), MockAccessibleCaretEventHub::NoActionState());
    781 }
    782 
    783 }  // namespace mozilla