• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 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 #include "gtest/gtest.h"
16 #include "widget_operator.h"
17 #include "mock_element_node_iterator.h"
18 #include "mock_controller.h"
19 
20 using namespace OHOS::uitest;
21 using namespace std;
22 
23 unique_ptr<PointerMatrix> MockController::touch_event_records_ = nullptr;
24 
25 class WidgetOperatorTest : public testing::Test {
26 protected:
SetUp()27     void SetUp() override
28     {
29         auto mockController = std::make_unique<MockController>();
30         controller_ = mockController.get();
31         UiDriver::RegisterController(std::move(mockController));
32         driver_ = make_unique<UiDriver>();
33         ResetWindowAndNode(w1_, eles_);
34     }
35 
36     // Reset Window and node
ResetWindowAndNode(Window & w,std::vector<MockAccessibilityElementInfo> & eles)37     void ResetWindowAndNode(Window &w, std::vector<MockAccessibilityElementInfo> &eles)
38     {
39         std::string domJson = R"(
40             {
41                 "attributes":{
42                     "windowId":"12",
43                     "componentType":"List",
44                     "accessibilityId":"1",
45                     "content":"Text List",
46                     "rectInScreen":"0,1000,0,1200"
47                 },
48                 "children":[
49                     {
50                         "attributes":{
51                             "windowId":"12",
52                             "accessibilityId":"2",
53                             "componentType":"Scroll",
54                             "content":"Text List Scroll",
55                             "rectInScreen":"0,600,0,1000"
56                         },
57                         "children":[
58                             {
59                                 "attributes":{
60                                     "windowId":"12",
61                                     "accessibilityId":"3",
62                                     "componentType":"Image",
63                                     "content":"Button",
64                                     "rectInScreen":"30,40,10,20"
65                                 },
66                                 "children":[
67                                     {
68                                         "attributes":{
69                                             "windowId":"12",
70                                             "accessibilityId":"4",
71                                             "componentType":"Text",
72                                             "content":"Text One",
73                                             "rectInScreen":"30,40,10,20"
74                                         },
75                                         "children":[]
76                                     }
77                                 ]
78                             },
79                             {
80                                 "attributes":{
81                                     "windowId":"12",
82                                     "componentType":"List",
83                                     "accessibilityId":"5",
84                                     "content":"Text List12",
85                                     "rectInScreen":"40,60,10,20"
86                                 },
87                                 "children":[
88                                     {
89                                         "attributes":{
90                                             "windowId":"12",
91                                             "accessibilityId":"6",
92                                             "componentType":"Text",
93                                             "content":"Text One",
94                                             "rectInScreen":"40,50,10,20"
95                                         },
96                                         "children":[]
97                                     },
98                                     {
99                                         "attributes":{
100                                             "windowId":"12",
101                                             "accessibilityId":"8",
102                                             "componentType":"Text",
103                                             "content":"Text Two",
104                                             "rectInScreen":"50,60,10,20"
105                                         },
106                                         "children":[]
107                                     }
108                                 ]
109                             }
110                         ]
111                     },
112                     {
113                         "attributes":{
114                             "windowId":"12",
115                             "accessibilityId":"10",
116                             "componentType":"Image",
117                             "content":"Button",
118                             "rectInScreen":"10,20,20,100"
119                         },
120                         "children":[]
121                     },
122                     {
123                         "attributes":{
124                             "windowId":"12",
125                             "accessibilityId":"11",
126                             "componentType":"List",
127                             "content":"Button",
128                             "rectInScreen":"20,100,20,100"
129                         },
130                         "children":[
131                             {
132                                 "attributes":{
133                                     "windowId":"12",
134                                     "accessibilityId":"12",
135                                     "componentType":"Image",
136                                     "content":"",
137                                     "rectInScreen":"20,100,20,100"
138                                 },
139                                 "children":[]
140                             },
141                             {
142                                 "attributes":{
143                                     "windowId":"12",
144                                     "accessibilityId":"14",
145                                     "componentType":"Button",
146                                     "content":"Text End Button",
147                                     "rectInScreen":"20,100,20,100"
148                                 },
149                                 "children":[
150                                     {
151                                         "attributes":{
152                                             "windowId":"12",
153                                             "accessibilityId":"15",
154                                             "componentType":"Text",
155                                             "content":"Text End",
156                                             "rectInScreen":"20,100,20,100"
157                                         },
158                                         "children":[]
159                                     }
160                                 ]
161                             }
162                         ]
163                     }
164                 ]
165             }
166         )";
167         eles_ = MockElementNodeIterator::ConstructIteratorByJson(domJson)->elementInfoLists_;
168         w.windowLayer_ = 2;
169         w.bounds_ = Rect{0, 1000, 0, 1200};
170         w.bundleName_ = "test1";
171     }
TearDown()172     void TearDown() override
173     {
174         controller_ = nullptr;
175     }
176 
177     MockController *controller_ = nullptr;
178     unique_ptr<UiDriver> driver_ = nullptr;
179     UiOpArgs opt_;
180     Window w1_{12};
181     std::vector<MockAccessibilityElementInfo> eles_;
182     ~WidgetOperatorTest() override = default;
183 };
184 
TEST_F(WidgetOperatorTest,scrollSearchNoTarget)185 TEST_F(WidgetOperatorTest, scrollSearchNoTarget)
186 {
187     auto error = ApiCallErr(NO_ERROR);
188     auto scrollWidgetSelector = WidgetSelector();
189     auto matcher = WidgetMatchModel(UiAttr::TEXT, "Text List Scroll", EQ);
190     scrollWidgetSelector.AddMatcher(matcher);
191     vector<unique_ptr<Widget>> widgets;
192     controller_->AddWindowsAndNode(w1_, eles_);
193     scrollWidgetSelector.SetWantMulti(false);
194     driver_->FindWidgets(scrollWidgetSelector, widgets, error, true);
195 
196     ASSERT_EQ(1, widgets.size());
197 
198     // mock another dom on which the scroll-widget is missing, and perform scroll-search
199 
200     auto targetWidgetSelector = WidgetSelector();
201     auto wOp = WidgetOperator(*driver_, *widgets.at(0), opt_);
202     auto matcher0 = WidgetMatchModel(UiAttr::TEXT, "Text End", EQ);
203     targetWidgetSelector.AddMatcher(matcher0);
204     ASSERT_EQ(nullptr, wOp.ScrollFindWidget(targetWidgetSelector, true, error));
205 }
206 
TEST_F(WidgetOperatorTest,scrollSearchWithTarget)207 TEST_F(WidgetOperatorTest, scrollSearchWithTarget)
208 {
209     auto error = ApiCallErr(NO_ERROR);
210     auto scrollWidgetSelector = WidgetSelector();
211     auto matcher = WidgetMatchModel(UiAttr::TEXT, "Text List Scroll", EQ);
212     scrollWidgetSelector.AddMatcher(matcher);
213     vector<unique_ptr<Widget>> widgets;
214     controller_->AddWindowsAndNode(w1_, eles_);
215     scrollWidgetSelector.SetWantMulti(false);
216     driver_->FindWidgets(scrollWidgetSelector, widgets, error, true);
217 
218     ASSERT_EQ(1, widgets.size());
219     auto targetWidgetSelector = WidgetSelector();
220     auto wOp = WidgetOperator(*driver_, *widgets.at(0), opt_);
221     auto matcher0 = WidgetMatchModel(UiAttr::TEXT, "Text List12", EQ);
222     targetWidgetSelector.AddMatcher(matcher0);
223     auto rev = wOp.ScrollFindWidget(targetWidgetSelector, true, error);
224     ASSERT_FALSE(rev == nullptr);
225     ASSERT_EQ("5", rev->GetAttr(UiAttr::ACCESSIBILITY_ID));
226 }
227 
TEST_F(WidgetOperatorTest,scrollSearchCheckSubjectWidget)228 TEST_F(WidgetOperatorTest, scrollSearchCheckSubjectWidget)
229 {
230     auto error = ApiCallErr(NO_ERROR);
231     auto scrollWidgetSelector = WidgetSelector();
232     auto matcher = WidgetMatchModel(UiAttr::TEXT, "Text List Scroll", EQ);
233     scrollWidgetSelector.AddMatcher(matcher);
234     vector<unique_ptr<Widget>> images;
235     controller_->AddWindowsAndNode(w1_, eles_);
236     scrollWidgetSelector.SetWantMulti(false);
237     driver_->FindWidgets(scrollWidgetSelector, images, error, true);
238 
239     ASSERT_EQ(1, images.size());
240 
241     auto targetWidgetMatcher = WidgetMatchModel(UiAttr::TEXT, "Text End", EQ);
242     auto targetWidgetSelector = WidgetSelector();
243     targetWidgetSelector.AddMatcher(targetWidgetMatcher);
244     opt_.scrollWidgetDeadZone_ = 0; // set deadzone to 0 for easy computation
245     auto wOp = WidgetOperator(*driver_, *images.at(0), opt_);
246     ASSERT_EQ(nullptr, wOp.ScrollFindWidget(targetWidgetSelector, true, error));
247     // check the scroll action events, should be acted on the subject node specified by WidgetMatcher
248     ASSERT_TRUE(!MockController::touch_event_records_->Empty());
249     auto &firstEvent = MockController::touch_event_records_->At(0, 0);
250     auto fin = MockController::touch_event_records_->GetFingers() - 1;
251     auto ste = MockController::touch_event_records_->GetSteps() - 1;
252     auto &lastEvent = MockController::touch_event_records_->At(fin, ste);
253     // check scroll event pointer_x
254     int32_t subjectCx = (0 + 600) / 2;
255     ASSERT_NEAR(firstEvent.point_.px_, subjectCx, 5);
256     ASSERT_NEAR(lastEvent.point_.px_, subjectCx, 5);
257 
258     // check scroll event pointer_y
259     constexpr int32_t subjectWidgetHeight = 1000 - 0;
260     int32_t maxCy = 0;
261     int32_t minCy = 1E5;
262     for (uint32_t finger = 0; finger < MockController::touch_event_records_->GetFingers(); finger++) {
263         for (uint32_t step = 0; step < MockController::touch_event_records_->GetSteps(); step++) {
264             if (MockController::touch_event_records_->At(finger, step).point_.py_ > maxCy) {
265                 maxCy = MockController::touch_event_records_->At(finger, step).point_.py_;
266             }
267             if (MockController::touch_event_records_->At(finger, step).point_.py_ < minCy) {
268                 minCy = MockController::touch_event_records_->At(finger, step).point_.py_;
269             }
270         }
271     }
272 
273     int32_t scrollDistanceY = maxCy - minCy;
274     ASSERT_TRUE(abs(scrollDistanceY - subjectWidgetHeight) < 5);
275 }
276 
TEST_F(WidgetOperatorTest,scrollSearchCheckDirection)277 TEST_F(WidgetOperatorTest, scrollSearchCheckDirection)
278 {
279     auto error = ApiCallErr(NO_ERROR);
280     auto scrollWidgetSelector = WidgetSelector();
281     auto matcher = WidgetMatchModel(UiAttr::TEXT, "Text List Scroll", EQ);
282     scrollWidgetSelector.AddMatcher(matcher);
283     vector<unique_ptr<Widget>> widgets;
284     controller_->AddWindowsAndNode(w1_, eles_);
285     scrollWidgetSelector.SetWantMulti(false);
286     driver_->FindWidgets(scrollWidgetSelector, widgets, error, true);
287     ASSERT_EQ(1, widgets.size());
288 
289     error = ApiCallErr(NO_ERROR);
290     auto targetWidgetMatcher = WidgetMatchModel(UiAttr::TEXT, "Text End", EQ);
291     auto targetWidgetSelector = WidgetSelector();
292     targetWidgetSelector.AddMatcher(targetWidgetMatcher);
293     opt_.scrollWidgetDeadZone_ = 0; // set deadzone to 0 for easy computation
294     auto wOp = WidgetOperator(*driver_, *widgets.at(0), opt_);
295     ASSERT_EQ(nullptr, wOp.ScrollFindWidget(targetWidgetSelector, true, error));
296     // check the scroll action events, should be acted on the specified node
297     ASSERT_TRUE(!MockController::touch_event_records_->Empty());
298     // should scroll-search upward (cy_from<cy_to) then downward (cy_from>cy_to)
299     uint32_t maxCyEventIndex = 0;
300     uint32_t index = 0;
301     for (uint32_t event = 0; event < MockController::touch_event_records_->GetSize() - 1; event++) {
302         if (MockController::touch_event_records_->At(0, event).point_.py_ >
303             MockController::touch_event_records_->At(0, maxCyEventIndex).point_.py_) {
304             maxCyEventIndex = index;
305         }
306         index++;
307     }
308 
309     for (uint32_t idx = 0; idx < MockController::touch_event_records_->GetSize() - 1; idx++) {
310         if (idx < maxCyEventIndex) {
311             ASSERT_LT(MockController::touch_event_records_->At(0, idx).point_.py_,
312                       MockController::touch_event_records_->At(0, idx + 1).point_.py_);
313         } else if (idx > maxCyEventIndex) {
314             ASSERT_GT(MockController::touch_event_records_->At(0, idx).point_.py_,
315                       MockController::touch_event_records_->At(0, idx + 1).point_.py_);
316         }
317     }
318 }
319