1 /* 2 * Copyright (c) 2021-2022 Huawei Device Co., Ltd. 3 * Licensed under the Apache License, Version 2.0 (the "License"); 4 * you may not use this file except in compliance with the License. 5 * You may obtain a copy of the License at 6 * 7 * http://www.apache.org/licenses/LICENSE-2.0 8 * 9 * Unless required by applicable law or agreed to in writing, software 10 * distributed under the License is distributed on an "AS IS" BASIS, 11 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 * See the License for the specific language governing permissions and 13 * limitations under the License. 14 */ 15 16 #include "widget_selector.h" 17 #include "climits" 18 19 namespace OHOS::uitest { 20 using namespace std; 21 using namespace nlohmann; 22 23 static constexpr auto NEST_USAGE_ERROR = "Nesting By usage like 'BY.before(BY.after(...))' is not supported"; 24 WidgetSelector(bool addVisibleMatcher)25 WidgetSelector::WidgetSelector(bool addVisibleMatcher) 26 { 27 if (!addVisibleMatcher) { 28 return; 29 } 30 auto visibleMatcher = WidgetMatchModel(UiAttr::VISIBLE, "true", EQ); 31 selfMatchers_.emplace_back(visibleMatcher); 32 } 33 AddMatcher(const WidgetMatchModel & matcher)34 void WidgetSelector::AddMatcher(const WidgetMatchModel &matcher) 35 { 36 selfMatchers_.emplace_back(matcher); 37 } 38 AddFrontLocator(const WidgetSelector & selector,ApiCallErr & error)39 void WidgetSelector::AddFrontLocator(const WidgetSelector &selector, ApiCallErr &error) 40 { 41 if (!selector.rearLocators_.empty() || !selector.frontLocators_.empty() || !selector.parentLocators_.empty()) { 42 error = ApiCallErr(ERR_INVALID_INPUT, NEST_USAGE_ERROR); 43 return; 44 } 45 frontLocators_.emplace_back(selector); 46 } 47 AddRearLocator(const WidgetSelector & selector,ApiCallErr & error)48 void WidgetSelector::AddRearLocator(const WidgetSelector &selector, ApiCallErr &error) 49 { 50 if (!selector.rearLocators_.empty() || !selector.frontLocators_.empty() || !selector.parentLocators_.empty()) { 51 error = ApiCallErr(ERR_INVALID_INPUT, NEST_USAGE_ERROR); 52 return; 53 } 54 rearLocators_.emplace_back(selector); 55 } 56 AddParentLocator(const WidgetSelector & selector,ApiCallErr & error)57 void WidgetSelector::AddParentLocator(const WidgetSelector &selector, ApiCallErr &error) 58 { 59 if (!selector.rearLocators_.empty() || !selector.frontLocators_.empty() || !selector.parentLocators_.empty()) { 60 error = ApiCallErr(ERR_INVALID_INPUT, NEST_USAGE_ERROR); 61 return; 62 } 63 parentLocators_.emplace_back(selector); 64 } 65 AddAppLocator(string app)66 void WidgetSelector::AddAppLocator(string app) 67 { 68 appLocator_ = app; 69 } 70 GetAppLocator() const71 std::string WidgetSelector::GetAppLocator() const 72 { 73 return appLocator_; 74 } 75 AddDisplayLocator(int32_t displayId)76 void WidgetSelector::AddDisplayLocator(int32_t displayId) 77 { 78 displayLocator_ = displayId; 79 } 80 GetDisplayLocator() const81 std::int32_t WidgetSelector::GetDisplayLocator() const 82 { 83 return displayLocator_; 84 } 85 Describe() const86 string WidgetSelector::Describe() const 87 { 88 stringstream ss; 89 ss << "{"; 90 ss << "selfMatcher=["; 91 for (auto &match : selfMatchers_) { 92 ss << match.Describe() << ","; 93 } 94 ss << "]"; 95 if (!frontLocators_.empty()) { 96 ss << "; frontMatcher="; 97 for (auto &locator : frontLocators_) { 98 ss << "[" << locator.Describe() << "]"; 99 } 100 } 101 if (!rearLocators_.empty()) { 102 ss << "; rearMatcher="; 103 for (auto &locator : rearLocators_) { 104 ss << "[" << locator.Describe() << "]"; 105 } 106 } 107 if (!parentLocators_.empty()) { 108 ss << "; parentMatcher="; 109 for (auto &locator : parentLocators_) { 110 ss << "[" << locator.Describe() << "]"; 111 } 112 } 113 ss << "}"; 114 return ss.str(); 115 } 116 SetWantMulti(bool wantMulti)117 void WidgetSelector::SetWantMulti(bool wantMulti) 118 { 119 wantMulti_ = wantMulti; 120 } 121 IsWantMulti() const122 bool WidgetSelector::IsWantMulti() const 123 { 124 return wantMulti_; 125 } 126 Select(const Window window,ElementNodeIterator & elementNodeRef,std::vector<Widget> & visitWidgets,std::vector<int> & targetWidgets) const127 void WidgetSelector::Select(const Window window, 128 ElementNodeIterator &elementNodeRef, 129 std::vector<Widget> &visitWidgets, 130 std::vector<int> &targetWidgets) const 131 { 132 std::unique_ptr<SelectStrategy> visitStrategy = ConstructSelectStrategy(); 133 LOG_D("Do Select, select strategy is %{public}d", visitStrategy->GetStrategyType()); 134 DumpOption option; 135 visitStrategy->LocateNode(window, elementNodeRef, visitWidgets, targetWidgets, option); 136 } 137 GetSelfMatchers() const138 std::vector<WidgetMatchModel> WidgetSelector::GetSelfMatchers() const 139 { 140 return selfMatchers_; 141 } 142 ConstructSelectStrategy() const143 std::unique_ptr<SelectStrategy> WidgetSelector::ConstructSelectStrategy() const 144 { 145 StrategyBuildParam buildParam; 146 buildParam.myselfMatcher = selfMatchers_; 147 if (!frontLocators_.empty()) { 148 for (const auto &frontLocator : frontLocators_) { 149 buildParam.afterAnchorMatcherVec.emplace_back(frontLocator.GetSelfMatchers()); 150 } 151 } 152 if (!rearLocators_.empty()) { 153 for (const auto &beforeLocator : rearLocators_) { 154 buildParam.beforeAnchorMatcherVec.emplace_back(beforeLocator.GetSelfMatchers()); 155 } 156 } 157 if (!parentLocators_.empty()) { 158 for (const auto &withInLocator : parentLocators_) { 159 buildParam.withInAnchorMatcherVec.emplace_back(withInLocator.GetSelfMatchers()); 160 } 161 } 162 return SelectStrategy::BuildSelectStrategy(buildParam, wantMulti_); 163 } 164 } // namespace OHOS::uitest