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 Describe() const71 string WidgetSelector::Describe() const 72 { 73 stringstream ss; 74 ss << "{"; 75 ss << "selfMatcher=["; 76 for (auto &match : selfMatchers_) { 77 ss << match.Describe() << ","; 78 } 79 ss << "]"; 80 if (!frontLocators_.empty()) { 81 ss << "; frontMatcher="; 82 for (auto &locator : frontLocators_) { 83 ss << "[" << locator.Describe() << "]"; 84 } 85 } 86 if (!rearLocators_.empty()) { 87 ss << "; rearMatcher="; 88 for (auto &locator : rearLocators_) { 89 ss << "[" << locator.Describe() << "]"; 90 } 91 } 92 if (!parentLocators_.empty()) { 93 ss << "; parentMatcher="; 94 for (auto &locator : parentLocators_) { 95 ss << "[" << locator.Describe() << "]"; 96 } 97 } 98 ss << "}"; 99 return ss.str(); 100 } 101 SetWantMulti(bool wantMulti)102 void WidgetSelector::SetWantMulti(bool wantMulti) 103 { 104 wantMulti_ = wantMulti; 105 } 106 IsWantMulti() const107 bool WidgetSelector::IsWantMulti() const 108 { 109 return wantMulti_; 110 } 111 Select(const Window window,ElementNodeIterator & elementNodeRef,std::vector<Widget> & visitWidgets,std::vector<int> & targetWidgets) const112 void WidgetSelector::Select(const Window window, 113 ElementNodeIterator &elementNodeRef, 114 std::vector<Widget> &visitWidgets, 115 std::vector<int> &targetWidgets) const 116 { 117 if (appLocator_ != "" && window.bundleName_ != appLocator_) { 118 LOG_D("skip window(%{public}s), it is not target window %{public}s", window.bundleName_.data(), 119 appLocator_.data()); 120 return; 121 } 122 std::unique_ptr<SelectStrategy> visitStrategy = ConstructSelectStrategy(); 123 LOG_I("Do Select, select strategy is %{public}d", visitStrategy->GetStrategyType()); 124 visitStrategy->LocateNode(window, elementNodeRef, visitWidgets, targetWidgets); 125 } 126 GetSelfMatchers() const127 std::vector<WidgetMatchModel> WidgetSelector::GetSelfMatchers() const 128 { 129 return selfMatchers_; 130 } 131 ConstructSelectStrategy() const132 std::unique_ptr<SelectStrategy> WidgetSelector::ConstructSelectStrategy() const 133 { 134 StrategyBuildParam buildParam; 135 buildParam.myselfMatcher = selfMatchers_; 136 if (!frontLocators_.empty()) { 137 for (const auto &frontLocator : frontLocators_) { 138 buildParam.afterAnchorMatcherVec.emplace_back(frontLocator.GetSelfMatchers()); 139 } 140 } 141 if (!rearLocators_.empty()) { 142 for (const auto &beforeLocator : rearLocators_) { 143 buildParam.beforeAnchorMatcherVec.emplace_back(beforeLocator.GetSelfMatchers()); 144 } 145 } 146 if (!parentLocators_.empty()) { 147 for (const auto &withInLocator : parentLocators_) { 148 buildParam.withInAnchorMatcherVec.emplace_back(withInLocator.GetSelfMatchers()); 149 } 150 } 151 return SelectStrategy::BuildSelectStrategy(buildParam, wantMulti_); 152 } 153 } // namespace OHOS::uitest