| // Copyright 2022 The Chromium Authors |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "ui/base/interaction/interaction_test_util.h" |
| |
| #include <string> |
| |
| #include "testing/gmock/include/gmock/gmock.h" |
| #include "testing/gtest/include/gtest/gtest.h" |
| #include "ui/base/interaction/element_identifier.h" |
| #include "ui/base/interaction/element_test_util.h" |
| #include "ui/events/event_constants.h" |
| |
| #if !BUILDFLAG(IS_IOS) |
| #include "ui/base/accelerators/accelerator.h" |
| #endif |
| |
| namespace ui::test { |
| |
| namespace { |
| |
| DEFINE_LOCAL_ELEMENT_IDENTIFIER_VALUE(kTestElementIdentifier); |
| constexpr ElementContext kTestElementContext = |
| ElementContext::CreateFakeContextForTesting(1); |
| |
| class MockInteractionSimulator : public InteractionTestUtil::Simulator { |
| public: |
| MockInteractionSimulator() = default; |
| ~MockInteractionSimulator() override = default; |
| |
| MOCK_METHOD2(PressButton, |
| ActionResult(TrackedElement* element, InputType input_type)); |
| MOCK_METHOD2(SelectMenuItem, |
| ActionResult(TrackedElement* element, InputType input_type)); |
| MOCK_METHOD2(DoDefaultAction, |
| ActionResult(TrackedElement* element, InputType input_type)); |
| MOCK_METHOD4( |
| SelectTab, |
| ActionResult(TrackedElement* tab_collection, |
| size_t index, |
| InputType input_type, |
| std::optional<size_t> expected_index_after_selection)); |
| MOCK_METHOD3(SelectDropdownItem, |
| ActionResult(TrackedElement* dropdown, |
| size_t index, |
| InputType input_type)); |
| MOCK_METHOD3(EnterText, |
| ActionResult(TrackedElement* element, |
| std::u16string text, |
| TextEntryMode mode)); |
| MOCK_METHOD1(ActivateSurface, ActionResult(TrackedElement* element)); |
| #if !BUILDFLAG(IS_IOS) |
| MOCK_METHOD2(SendAccelerator, |
| ActionResult(TrackedElement* element, Accelerator accelerator)); |
| #endif |
| MOCK_METHOD1(Confirm, ActionResult(TrackedElement* element)); |
| }; |
| |
| } // namespace |
| |
| TEST(InteractionTestUtilTest, PressButton) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| EXPECT_CALL(*mock, |
| PressButton(&element, InteractionTestUtil::InputType::kDontCare)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.PressButton(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, SelectMenuItem) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| EXPECT_CALL(*mock, SelectMenuItem(&element, |
| InteractionTestUtil::InputType::kDontCare)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.SelectMenuItem(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, DoDefaultAction) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| EXPECT_CALL(*mock, DoDefaultAction(&element, |
| InteractionTestUtil::InputType::kDontCare)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.DoDefaultAction(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, SelectTab) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| EXPECT_CALL(*mock, |
| SelectTab(&element, 1U, InteractionTestUtil::InputType::kDontCare, |
| std::optional<size_t>())) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.SelectTab(&element, 1U)); |
| } |
| |
| TEST(InteractionTestUtilTest, SelectDropdownItem) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| EXPECT_CALL(*mock, |
| SelectDropdownItem(&element, 1U, |
| InteractionTestUtil::InputType::kDontCare)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.SelectDropdownItem(&element, 1U)); |
| } |
| |
| TEST(InteractionTestUtilTest, EnterText) { |
| constexpr char16_t kText[] = u"Some text."; |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*mock, EnterText(&element, std::u16string(kText), |
| InteractionTestUtil::TextEntryMode::kAppend)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, |
| util.EnterText(&element, kText, |
| InteractionTestUtil::TextEntryMode::kAppend)); |
| |
| EXPECT_CALL(*mock, EnterText(&element, std::u16string(kText), |
| InteractionTestUtil::TextEntryMode::kReplaceAll)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, |
| util.EnterText(&element, kText, |
| InteractionTestUtil::TextEntryMode::kReplaceAll)); |
| } |
| |
| TEST(InteractionTestUtilTest, ActivateSurface) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*mock, ActivateSurface(&element)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.ActivateSurface(&element)); |
| } |
| |
| #if !BUILDFLAG(IS_IOS) |
| TEST(InteractionTestUtilTest, SendAccelerator) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| Accelerator accel(KeyboardCode::VKEY_F5, EF_SHIFT_DOWN); |
| EXPECT_CALL(*mock, SendAccelerator(&element, testing::Eq(accel))) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.SendAccelerator(&element, accel)); |
| } |
| #endif // !BUILDFLAG(IS_IOS) |
| |
| TEST(InteractionTestUtilTest, Confirm) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const mock = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*mock, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.Confirm(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, TwoSimulators_LastSucceeds) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| auto* const sim2 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*sim2, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_EQ(ActionResult::kSucceeded, util.Confirm(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, FirstSucceeds) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const sim1 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| auto* const sim2 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*sim1, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kSucceeded)); |
| EXPECT_CALL(*sim2, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kNotAttempted)); |
| |
| EXPECT_EQ(ActionResult::kSucceeded, util.Confirm(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, TwoSimulators_SecondFails) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| auto* const sim2 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*sim2, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kFailed)); |
| EXPECT_EQ(ActionResult::kFailed, util.Confirm(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, TwoSimulators_FirstFails) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const sim1 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| auto* const sim2 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*sim1, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kFailed)); |
| EXPECT_CALL(*sim2, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kNotAttempted)); |
| |
| EXPECT_EQ(ActionResult::kFailed, util.Confirm(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, TwoSimulators_SecondUnsupported) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| auto* const sim2 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*sim2, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kKnownIncompatible)); |
| EXPECT_EQ(ActionResult::kKnownIncompatible, util.Confirm(&element)); |
| } |
| |
| TEST(InteractionTestUtilTest, TwoSimulators_FirstUnsupported) { |
| TestElement element(kTestElementIdentifier, kTestElementContext); |
| InteractionTestUtil util; |
| auto* const sim1 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| auto* const sim2 = util.AddSimulator( |
| std::make_unique<testing::StrictMock<MockInteractionSimulator>>()); |
| |
| EXPECT_CALL(*sim1, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kKnownIncompatible)); |
| EXPECT_CALL(*sim2, Confirm(&element)) |
| .WillOnce(testing::Return(ActionResult::kNotAttempted)); |
| |
| EXPECT_EQ(ActionResult::kKnownIncompatible, util.Confirm(&element)); |
| } |
| |
| } // namespace ui::test |