Bug 1688832: part 6) Hide `AccessibleCaretManager::Carets::mFirst`, `mSecond`. r...
[gecko.git] / layout / base / gtest / TestAccessibleCaretManager.cpp
blobd23558a1829445b0c84c859ec961489a10b615da
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/. */
7 #include "gtest/gtest.h"
8 #include "gmock/gmock.h"
10 #include <string>
12 #include "AccessibleCaret.h"
13 #include "AccessibleCaretManager.h"
14 #include "mozilla/Preferences.h"
16 using ::testing::_;
17 using ::testing::DefaultValue;
18 using ::testing::Eq;
19 using ::testing::InSequence;
20 using ::testing::MockFunction;
21 using ::testing::Return;
23 // -----------------------------------------------------------------------------
24 // This file tests CaretStateChanged events and the appearance of the two
25 // AccessibleCarets manipulated by AccessibleCaretManager.
27 namespace mozilla {
28 using dom::CaretChangedReason;
30 class MOZ_RAII AutoRestoreBoolPref final {
31 public:
32 AutoRestoreBoolPref(const char* aPref, bool aValue) : mPref(aPref) {
33 Preferences::GetBool(mPref, &mOldValue);
34 Preferences::SetBool(mPref, aValue);
37 ~AutoRestoreBoolPref() { Preferences::SetBool(mPref, mOldValue); }
39 private:
40 const char* mPref = nullptr;
41 bool mOldValue = false;
44 class AccessibleCaretManagerTester : public ::testing::Test {
45 public:
46 class MockAccessibleCaret : public AccessibleCaret {
47 public:
48 MockAccessibleCaret() : AccessibleCaret(nullptr) {}
50 void SetAppearance(Appearance aAppearance) override {
51 // A simplified version without touching CaretElement().
52 mAppearance = aAppearance;
55 MOCK_METHOD2(SetPosition,
56 PositionChangedResult(nsIFrame* aFrame, int32_t aOffset));
58 }; // class MockAccessibleCaret
60 class MockAccessibleCaretManager : public AccessibleCaretManager {
61 public:
62 using CaretMode = AccessibleCaretManager::CaretMode;
63 using AccessibleCaretManager::HideCaretsAndDispatchCaretStateChangedEvent;
64 using AccessibleCaretManager::UpdateCarets;
66 MockAccessibleCaretManager()
67 : AccessibleCaretManager(nullptr,
68 Carets{MakeUnique<MockAccessibleCaret>(),
69 MakeUnique<MockAccessibleCaret>()}) {}
71 MockAccessibleCaret& FirstCaret() {
72 return static_cast<MockAccessibleCaret&>(*mCarets.GetFirst());
75 MockAccessibleCaret& SecondCaret() {
76 return static_cast<MockAccessibleCaret&>(*mCarets.GetSecond());
79 bool CompareTreePosition(nsIFrame* aStartFrame,
80 nsIFrame* aEndFrame) const override {
81 return true;
84 bool IsCaretDisplayableInCursorMode(
85 nsIFrame** aOutFrame = nullptr,
86 int32_t* aOutOffset = nullptr) const override {
87 return true;
90 bool UpdateCaretsForOverlappingTilt() override { return true; }
92 void UpdateCaretsForAlwaysTilt(const nsIFrame* aStartFrame,
93 const nsIFrame* aEndFrame) override {
94 if (mCarets.GetFirst()->IsVisuallyVisible()) {
95 mCarets.GetFirst()->SetAppearance(Appearance::Left);
97 if (mCarets.GetSecond()->IsVisuallyVisible()) {
98 mCarets.GetSecond()->SetAppearance(Appearance::Right);
102 Terminated IsTerminated() const override { return Terminated::No; }
103 bool IsScrollStarted() const { return mIsScrollStarted; }
105 Terminated MaybeFlushLayout() override { return Terminated::No; }
107 MOCK_CONST_METHOD0(GetCaretMode, CaretMode());
108 MOCK_METHOD1(DispatchCaretStateChangedEvent,
109 void(CaretChangedReason aReason));
110 MOCK_CONST_METHOD1(HasNonEmptyTextContent, bool(nsINode* aNode));
112 }; // class MockAccessibleCaretManager
114 using Appearance = AccessibleCaret::Appearance;
115 using PositionChangedResult = AccessibleCaret::PositionChangedResult;
116 using CaretMode = MockAccessibleCaretManager::CaretMode;
118 AccessibleCaretManagerTester() {
119 DefaultValue<CaretMode>::Set(CaretMode::None);
120 DefaultValue<PositionChangedResult>::Set(PositionChangedResult::NotChanged);
122 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
123 .WillRepeatedly(Return(PositionChangedResult::Position));
125 EXPECT_CALL(mManager.SecondCaret(), SetPosition(_, _))
126 .WillRepeatedly(Return(PositionChangedResult::Position));
129 AccessibleCaret::Appearance FirstCaretAppearance() {
130 return mManager.FirstCaret().GetAppearance();
133 AccessibleCaret::Appearance SecondCaretAppearance() {
134 return mManager.SecondCaret().GetAppearance();
137 // Member variables
138 MockAccessibleCaretManager mManager;
140 }; // class AccessibleCaretManagerTester
142 TEST_F(AccessibleCaretManagerTester, TestUpdatesInSelectionMode)
143 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
144 // Set default preference.
145 AutoRestoreBoolPref savedPref("layout.accessiblecaret.always_tilt", false);
147 EXPECT_CALL(mManager, GetCaretMode())
148 .WillRepeatedly(Return(CaretMode::Selection));
150 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
151 CaretChangedReason::Updateposition))
152 .Times(3);
154 mManager.UpdateCarets();
155 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
156 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
158 mManager.OnReflow();
159 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
160 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
162 mManager.OnScrollPositionChanged();
163 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
164 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
167 TEST_F(AccessibleCaretManagerTester, TestSingleTapOnNonEmptyInput)
168 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
169 EXPECT_CALL(mManager, GetCaretMode())
170 .WillRepeatedly(Return(CaretMode::Cursor));
172 EXPECT_CALL(mManager, HasNonEmptyTextContent(_)).WillRepeatedly(Return(true));
174 MockFunction<void(std::string aCheckPointName)> check;
176 InSequence dummy;
178 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
179 CaretChangedReason::Updateposition))
180 .Times(1);
181 EXPECT_CALL(check, Call("update"));
183 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
184 CaretChangedReason::Visibilitychange))
185 .Times(1);
186 EXPECT_CALL(check, Call("mouse down"));
188 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(_)).Times(0);
189 EXPECT_CALL(check, Call("reflow"));
191 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(_)).Times(0);
192 EXPECT_CALL(check, Call("blur"));
194 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
195 CaretChangedReason::Updateposition))
196 .Times(1);
197 EXPECT_CALL(check, Call("mouse up"));
199 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
200 CaretChangedReason::Updateposition))
201 .Times(1);
202 EXPECT_CALL(check, Call("reflow2"));
204 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
205 CaretChangedReason::Updateposition))
206 .Times(1);
209 // Simulate a single tap on a non-empty input.
210 mManager.UpdateCarets();
211 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
212 check.Call("update");
214 mManager.OnSelectionChanged(nullptr, nullptr,
215 nsISelectionListener::DRAG_REASON |
216 nsISelectionListener::MOUSEDOWN_REASON);
217 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
218 check.Call("mouse down");
220 mManager.OnReflow();
221 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
222 check.Call("reflow");
224 mManager.OnBlur();
225 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
226 check.Call("blur");
228 mManager.OnSelectionChanged(nullptr, nullptr,
229 nsISelectionListener::MOUSEUP_REASON);
230 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
231 check.Call("mouse up");
233 mManager.OnReflow();
234 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
235 check.Call("reflow2");
237 mManager.OnScrollPositionChanged();
238 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
241 TEST_F(AccessibleCaretManagerTester, TestSingleTapOnEmptyInput)
242 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
243 // Set default preference.
244 AutoRestoreBoolPref savedPref(
245 "layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content",
246 false);
248 EXPECT_CALL(mManager, GetCaretMode())
249 .WillRepeatedly(Return(CaretMode::Cursor));
251 EXPECT_CALL(mManager, HasNonEmptyTextContent(_))
252 .WillRepeatedly(Return(false));
254 MockFunction<void(std::string aCheckPointName)> check;
256 InSequence dummy;
258 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
259 CaretChangedReason::Updateposition))
260 .Times(1);
261 EXPECT_CALL(check, Call("update"));
263 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
264 CaretChangedReason::Visibilitychange))
265 .Times(1);
266 EXPECT_CALL(check, Call("mouse down"));
268 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(_)).Times(0);
269 EXPECT_CALL(check, Call("reflow"));
271 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(_)).Times(0);
272 EXPECT_CALL(check, Call("blur"));
274 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
275 CaretChangedReason::Updateposition))
276 .Times(1);
277 EXPECT_CALL(check, Call("mouse up"));
279 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
280 CaretChangedReason::Updateposition))
281 .Times(1);
282 EXPECT_CALL(check, Call("reflow2"));
284 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
285 CaretChangedReason::Updateposition))
286 .Times(1);
289 // Simulate a single tap on an empty input.
290 mManager.UpdateCarets();
291 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
292 check.Call("update");
294 mManager.OnSelectionChanged(nullptr, nullptr,
295 nsISelectionListener::DRAG_REASON |
296 nsISelectionListener::MOUSEDOWN_REASON);
297 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
298 check.Call("mouse down");
300 mManager.OnReflow();
301 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
302 check.Call("reflow");
304 mManager.OnBlur();
305 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
306 check.Call("blur");
308 mManager.OnSelectionChanged(nullptr, nullptr,
309 nsISelectionListener::MOUSEUP_REASON);
310 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
311 check.Call("mouse up");
313 mManager.OnReflow();
314 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
315 check.Call("reflow2");
317 mManager.OnScrollPositionChanged();
318 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
321 TEST_F(AccessibleCaretManagerTester, TestTypingAtEndOfInput)
322 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
323 EXPECT_CALL(mManager, GetCaretMode())
324 .WillRepeatedly(Return(CaretMode::Cursor));
326 EXPECT_CALL(mManager, HasNonEmptyTextContent(_)).WillRepeatedly(Return(true));
328 MockFunction<void(std::string aCheckPointName)> check;
330 InSequence dummy;
332 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
333 CaretChangedReason::Updateposition))
334 .Times(1);
335 EXPECT_CALL(check, Call("update"));
337 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
338 CaretChangedReason::Visibilitychange))
339 .Times(1);
340 EXPECT_CALL(check, Call("keyboard"));
342 // No CaretStateChanged events should be dispatched since the caret has
343 // being hidden in cursor mode.
344 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(_)).Times(0);
347 // Simulate typing the end of the input.
348 mManager.UpdateCarets();
349 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
350 check.Call("update");
352 mManager.OnKeyboardEvent();
353 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
354 check.Call("keyboard");
356 mManager.OnSelectionChanged(nullptr, nullptr,
357 nsISelectionListener::NO_REASON);
358 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
360 mManager.OnScrollPositionChanged();
361 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
364 TEST_F(AccessibleCaretManagerTester, TestScrollInSelectionMode)
365 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
366 // Set default preference.
367 AutoRestoreBoolPref savedPref("layout.accessiblecaret.always_tilt", false);
369 EXPECT_CALL(mManager, GetCaretMode())
370 .WillRepeatedly(Return(CaretMode::Selection));
372 MockFunction<void(std::string aCheckPointName)> check;
374 InSequence dummy;
376 // Initially, first caret is out of scrollport, and second caret is visible.
377 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
378 .WillOnce(Return(PositionChangedResult::Invisible));
380 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
381 CaretChangedReason::Updateposition));
382 EXPECT_CALL(check, Call("updatecarets"));
384 EXPECT_CALL(mManager,
385 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
386 EXPECT_CALL(check, Call("scrollstart1"));
388 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
389 CaretChangedReason::Updateposition));
390 EXPECT_CALL(check, Call("reflow1"));
392 // After scroll ended, first caret is visible and second caret is out of
393 // scroll port.
394 EXPECT_CALL(mManager.SecondCaret(), SetPosition(_, _))
395 .WillOnce(Return(PositionChangedResult::Invisible));
397 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
398 CaretChangedReason::Updateposition));
399 EXPECT_CALL(check, Call("scrollend1"));
401 EXPECT_CALL(mManager,
402 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
403 EXPECT_CALL(check, Call("scrollstart2"));
405 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
406 CaretChangedReason::Updateposition));
407 EXPECT_CALL(check, Call("reflow2"));
409 // After the scroll ended, both carets are visible.
410 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
411 CaretChangedReason::Updateposition));
412 EXPECT_CALL(check, Call("scrollend2"));
415 mManager.UpdateCarets();
416 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
417 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
418 check.Call("updatecarets");
420 mManager.OnScrollStart();
421 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
422 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
423 check.Call("scrollstart1");
425 mManager.OnReflow();
426 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
427 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
428 check.Call("reflow1");
430 mManager.OnScrollEnd();
431 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
432 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
433 check.Call("scrollend1");
435 mManager.OnScrollStart();
436 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
437 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
438 check.Call("scrollstart2");
440 mManager.OnReflow();
441 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
442 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
443 check.Call("reflow2");
445 mManager.OnScrollEnd();
446 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
447 EXPECT_EQ(SecondCaretAppearance(), Appearance::Normal);
448 check.Call("scrollend2");
451 TEST_F(AccessibleCaretManagerTester,
452 TestScrollInSelectionModeWithAlwaysTiltPref)
453 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
454 // Simulate Firefox Android preference.
455 AutoRestoreBoolPref savedPref("layout.accessiblecaret.always_tilt", true);
457 EXPECT_CALL(mManager, GetCaretMode())
458 .WillRepeatedly(Return(CaretMode::Selection));
460 MockFunction<void(std::string aCheckPointName)> check;
462 InSequence dummy;
464 // Initially, first caret is out of scrollport, and second caret is visible.
465 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
466 .WillOnce(Return(PositionChangedResult::Invisible));
468 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
469 CaretChangedReason::Updateposition));
470 EXPECT_CALL(check, Call("updatecarets"));
472 EXPECT_CALL(mManager,
473 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
474 EXPECT_CALL(check, Call("scrollstart1"));
476 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(_)).Times(0);
477 EXPECT_CALL(check, Call("scrollPositionChanged1"));
479 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
480 CaretChangedReason::Updateposition));
481 EXPECT_CALL(check, Call("reflow1"));
483 // After scroll ended, first caret is visible and second caret is out of
484 // scroll port.
485 EXPECT_CALL(mManager.SecondCaret(), SetPosition(_, _))
486 .WillOnce(Return(PositionChangedResult::Invisible));
488 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
489 CaretChangedReason::Updateposition));
490 EXPECT_CALL(check, Call("scrollend1"));
492 EXPECT_CALL(mManager,
493 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
494 EXPECT_CALL(check, Call("scrollstart2"));
496 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(_)).Times(0);
497 EXPECT_CALL(check, Call("scrollPositionChanged2"));
499 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
500 CaretChangedReason::Updateposition));
501 EXPECT_CALL(check, Call("reflow2"));
503 // After the scroll ended, both carets are visible.
504 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
505 CaretChangedReason::Updateposition));
506 EXPECT_CALL(check, Call("scrollend2"));
509 mManager.UpdateCarets();
510 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
511 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
512 check.Call("updatecarets");
514 mManager.OnScrollStart();
515 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
516 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
517 check.Call("scrollstart1");
519 mManager.OnScrollPositionChanged();
520 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
521 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
522 check.Call("scrollPositionChanged1");
524 mManager.OnReflow();
525 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
526 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
527 check.Call("reflow1");
529 mManager.OnScrollEnd();
530 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
531 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
532 check.Call("scrollend1");
534 mManager.OnScrollStart();
535 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
536 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
537 check.Call("scrollstart2");
539 mManager.OnScrollPositionChanged();
540 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
541 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
542 check.Call("scrollPositionChanged2");
544 mManager.OnReflow();
545 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
546 EXPECT_EQ(SecondCaretAppearance(), Appearance::NormalNotShown);
547 check.Call("reflow2");
549 mManager.OnScrollEnd();
550 EXPECT_EQ(FirstCaretAppearance(), Appearance::Left);
551 EXPECT_EQ(SecondCaretAppearance(), Appearance::Right);
552 check.Call("scrollend2");
555 TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenLogicallyVisible)
556 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
557 EXPECT_CALL(mManager, GetCaretMode())
558 .WillRepeatedly(Return(CaretMode::Cursor));
560 EXPECT_CALL(mManager, HasNonEmptyTextContent(_)).WillRepeatedly(Return(true));
562 MockFunction<void(std::string aCheckPointName)> check;
564 InSequence dummy;
566 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
567 CaretChangedReason::Updateposition))
568 .Times(1);
569 EXPECT_CALL(check, Call("updatecarets"));
571 EXPECT_CALL(mManager,
572 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll))
573 .Times(1);
574 EXPECT_CALL(check, Call("scrollstart1"));
576 // After scroll ended, the caret is out of scroll port.
577 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
578 .WillRepeatedly(Return(PositionChangedResult::Invisible));
579 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
580 CaretChangedReason::Updateposition))
581 .Times(1);
582 EXPECT_CALL(check, Call("scrollend1"));
584 EXPECT_CALL(mManager,
585 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll))
586 .Times(1);
587 EXPECT_CALL(check, Call("scrollstart2"));
589 // After scroll ended, the caret is visible again.
590 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
591 .WillRepeatedly(Return(PositionChangedResult::Position));
592 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
593 CaretChangedReason::Updateposition))
594 .Times(1);
595 EXPECT_CALL(check, Call("scrollend2"));
598 mManager.UpdateCarets();
599 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
600 check.Call("updatecarets");
602 mManager.OnScrollStart();
603 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
604 check.Call("scrollstart1");
606 mManager.OnScrollEnd();
607 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
608 check.Call("scrollend1");
610 mManager.OnScrollStart();
611 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
612 check.Call("scrollstart2");
614 mManager.OnScrollEnd();
615 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
616 check.Call("scrollend2");
619 TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeWhenHidden)
620 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
621 EXPECT_CALL(mManager, GetCaretMode())
622 .WillRepeatedly(Return(CaretMode::Cursor));
624 EXPECT_CALL(mManager, HasNonEmptyTextContent(_)).WillRepeatedly(Return(true));
626 MockFunction<void(std::string aCheckPointName)> check;
628 InSequence dummy;
630 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
631 CaretChangedReason::Updateposition))
632 .Times(1);
633 EXPECT_CALL(check, Call("updatecarets"));
635 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
636 CaretChangedReason::Visibilitychange))
637 .Times(1);
638 EXPECT_CALL(check, Call("hidecarets"));
640 // After scroll ended, the caret is out of scroll port.
641 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
642 .WillRepeatedly(Return(PositionChangedResult::Invisible));
643 EXPECT_CALL(check, Call("scrollend1"));
645 // After scroll ended, the caret is visible again.
646 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
647 .WillRepeatedly(Return(PositionChangedResult::Position));
648 EXPECT_CALL(check, Call("scrollend2"));
651 mManager.UpdateCarets();
652 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
653 check.Call("updatecarets");
655 mManager.HideCaretsAndDispatchCaretStateChangedEvent();
656 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
657 check.Call("hidecarets");
659 mManager.OnScrollStart();
660 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
662 mManager.OnScrollEnd();
663 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
664 check.Call("scrollend1");
666 mManager.OnScrollStart();
667 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
669 mManager.OnScrollEnd();
670 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
671 check.Call("scrollend2");
674 TEST_F(AccessibleCaretManagerTester, TestScrollInCursorModeOnEmptyContent)
675 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
676 // Set default preference.
677 AutoRestoreBoolPref savedPref(
678 "layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content",
679 false);
681 EXPECT_CALL(mManager, GetCaretMode())
682 .WillRepeatedly(Return(CaretMode::Cursor));
684 EXPECT_CALL(mManager, HasNonEmptyTextContent(_))
685 .WillRepeatedly(Return(false));
687 MockFunction<void(std::string aCheckPointName)> check;
689 InSequence dummy;
691 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
692 CaretChangedReason::Updateposition));
693 EXPECT_CALL(check, Call("updatecarets"));
695 EXPECT_CALL(mManager,
696 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
697 EXPECT_CALL(check, Call("scrollstart1"));
699 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
700 .WillOnce(Return(PositionChangedResult::Invisible));
701 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
702 CaretChangedReason::Updateposition));
703 EXPECT_CALL(check, Call("scrollend1"));
705 EXPECT_CALL(mManager,
706 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
707 EXPECT_CALL(check, Call("scrollstart2"));
709 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
710 CaretChangedReason::Updateposition));
711 EXPECT_CALL(check, Call("scrollend2"));
713 EXPECT_CALL(mManager,
714 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
715 EXPECT_CALL(check, Call("scrollstart3"));
717 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
718 CaretChangedReason::Updateposition));
719 EXPECT_CALL(check, Call("scrollend3"));
722 // Simulate a pinch-zoom operation before tapping on an empty content.
723 mManager.OnScrollStart();
724 mManager.OnScrollEnd();
725 EXPECT_EQ(mManager.IsScrollStarted(), false);
727 // Simulate a single tap on an empty content.
728 mManager.UpdateCarets();
729 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
730 check.Call("updatecarets");
732 // Scroll the caret to be out of the viewport.
733 mManager.OnScrollStart();
734 check.Call("scrollstart1");
735 mManager.OnScrollEnd();
736 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
737 check.Call("scrollend1");
739 // Scroll the caret into the viewport.
740 mManager.OnScrollStart();
741 check.Call("scrollstart2");
742 mManager.OnScrollEnd();
743 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
744 check.Call("scrollend2");
746 // Scroll the caret within the viewport.
747 mManager.OnScrollStart();
748 check.Call("scrollstart3");
749 mManager.OnScrollEnd();
750 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
751 check.Call("scrollend3");
754 TEST_F(AccessibleCaretManagerTester,
755 TestScrollInCursorModeWithCaretShownWhenLongTappingOnEmptyContentPref)
756 MOZ_CAN_RUN_SCRIPT_FOR_DEFINITION {
757 // Simulate Firefox Android preference.
758 AutoRestoreBoolPref savedPref(
759 "layout.accessiblecaret.caret_shown_when_long_tapping_on_empty_content",
760 true);
762 EXPECT_CALL(mManager, GetCaretMode())
763 .WillRepeatedly(Return(CaretMode::Cursor));
765 EXPECT_CALL(mManager, HasNonEmptyTextContent(_))
766 .WillRepeatedly(Return(false));
768 MockFunction<void(std::string aCheckPointName)> check;
770 InSequence dummy;
772 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
773 CaretChangedReason::Updateposition));
774 EXPECT_CALL(check, Call("singletap updatecarets"));
776 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
777 CaretChangedReason::Updateposition));
778 EXPECT_CALL(check, Call("longtap updatecarets"));
780 EXPECT_CALL(mManager,
781 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
782 EXPECT_CALL(check, Call("longtap scrollstart1"));
784 EXPECT_CALL(mManager.FirstCaret(), SetPosition(_, _))
785 .WillOnce(Return(PositionChangedResult::Invisible));
786 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
787 CaretChangedReason::Updateposition));
788 EXPECT_CALL(check, Call("longtap scrollend1"));
790 EXPECT_CALL(mManager,
791 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
792 EXPECT_CALL(check, Call("longtap scrollstart2"));
794 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
795 CaretChangedReason::Updateposition));
796 EXPECT_CALL(check, Call("longtap scrollend2"));
798 EXPECT_CALL(mManager,
799 DispatchCaretStateChangedEvent(CaretChangedReason::Scroll));
800 EXPECT_CALL(check, Call("longtap scrollstart3"));
802 EXPECT_CALL(mManager, DispatchCaretStateChangedEvent(
803 CaretChangedReason::Updateposition));
804 EXPECT_CALL(check, Call("longtap scrollend3"));
807 // Simulate a single tap on an empty input.
808 mManager.FirstCaret().SetAppearance(Appearance::None);
809 mManager.UpdateCarets();
810 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
811 check.Call("singletap updatecarets");
813 // Scroll the caret within the viewport.
814 mManager.OnScrollStart();
815 mManager.OnScrollEnd();
816 EXPECT_EQ(FirstCaretAppearance(), Appearance::None);
818 // Simulate a long tap on an empty input.
819 mManager.FirstCaret().SetAppearance(Appearance::Normal);
820 mManager.UpdateCarets();
821 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
822 check.Call("longtap updatecarets");
824 // Scroll the caret to be out of the viewport.
825 mManager.OnScrollStart();
826 check.Call("longtap scrollstart1");
827 mManager.OnScrollEnd();
828 EXPECT_EQ(FirstCaretAppearance(), Appearance::NormalNotShown);
829 check.Call("longtap scrollend1");
831 // Scroll the caret into the viewport.
832 mManager.OnScrollStart();
833 check.Call("longtap scrollstart2");
834 mManager.OnScrollPositionChanged();
835 mManager.OnScrollEnd();
836 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
837 check.Call("longtap scrollend2");
839 // Scroll the caret within the viewport.
840 mManager.OnScrollStart();
841 check.Call("longtap scrollstart3");
842 mManager.OnScrollPositionChanged();
843 mManager.OnScrollEnd();
844 EXPECT_EQ(FirstCaretAppearance(), Appearance::Normal);
845 check.Call("longtap scrollend3");
848 } // namespace mozilla