• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 "gtest/gtest.h"
17 #include "widget_selector.h"
18 
19 using namespace OHOS::uitest;
20 using namespace std;
21 
22 static constexpr char DOM_TEXT[] = R"({
23 "attributes": {
24 "rotation": "0"
25 },
26 "children": [
27 {
28 "attributes": {
29 "resource-id": "id1",
30 "text": ""
31 },
32 "children": [
33 {
34 "attributes": {
35 "resource-id": "id2",
36 "text": ""
37 },
38 "children": [
39 {
40 "attributes": {
41 "resource-id": "id3",
42 "text": ""
43 },
44 "children": [
45 {
46 "attributes": {
47 "resource-id": "id4",
48 "text": "Use USB to"
49 },
50 "children": []
51 }
52 ]
53 }
54 ]
55 },
56 {
57 "attributes": {
58 "resource-id": "id5",
59 "text": "wyz"
60 },
61 "children": [
62 {
63 "attributes": {
64 "resource-id": "id6",
65 "text": ""
66 },
67 "children": [
68 {
69 "attributes": {
70 "resource-id": "id7",
71 "text": ""
72 },
73 "children": [
74 {
75 "attributes": {
76 "resource-id": "id8",
77 "text": "Transfer photos"
78 },
79 "children": []
80 }
81 ]
82 },
83 {
84 "attributes": {
85 "resource-id": "id9",
86 "text": ""
87 },
88 "children": [
89 {
90 "attributes": {
91 "resource-id": "id10",
92 "text": "Transfer files"
93 },
94 "children": []
95 }
96 ]
97 }
98 ]
99 }
100 ]
101 }
102 ]
103 }
104 ]
105 }
106 )";
107 
108 static constexpr auto ATTR_TEXT = "text";
109 
110 class WidgetSelectorTest : public testing::Test {
111 protected:
112     WidgetTree tree_ = WidgetTree("dummy_tree");
113 
SetUp()114     void SetUp() override
115     {
116         auto data = nlohmann::json::parse(DOM_TEXT);
117         tree_.ConstructFromDom(data, false);
118     }
119 };
120 
TEST_F(WidgetSelectorTest,signleMatcherWithoutLocatorAndExistsNoTarget)121 TEST_F(WidgetSelectorTest, signleMatcherWithoutLocatorAndExistsNoTarget)
122 {
123     auto selector = WidgetSelector();
124     auto matcher = WidgetAttrMatcher(ATTR_TEXT, "WLJ", EQ);
125     selector.AddMatcher(matcher);
126 
127     vector<reference_wrapper<const Widget>> receiver;
128     selector.Select(tree_, receiver);
129 
130     ASSERT_EQ(0, receiver.size());
131 }
132 
TEST_F(WidgetSelectorTest,signleMatcherWithoutLocatorAndExistsSingleTarget)133 TEST_F(WidgetSelectorTest, signleMatcherWithoutLocatorAndExistsSingleTarget)
134 {
135     auto selector = WidgetSelector();
136     auto matcher = WidgetAttrMatcher(ATTR_TEXT, "wyz", EQ);
137     selector.AddMatcher(matcher);
138 
139     vector<reference_wrapper<const Widget>> receiver;
140     selector.Select(tree_, receiver);
141 
142     ASSERT_EQ(1, receiver.size());
143     // check the result widget
144     ASSERT_EQ("id5", receiver.at(0).get().GetAttr("resource-id", ""));
145 }
146 
TEST_F(WidgetSelectorTest,multiMatcherWithoutLocatorAndExistsSingleTarget)147 TEST_F(WidgetSelectorTest, multiMatcherWithoutLocatorAndExistsSingleTarget)
148 {
149     auto selector = WidgetSelector();
150     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
151     auto matcher1 = WidgetAttrMatcher("resource-id", "8", CONTAINS);
152     selector.AddMatcher(matcher0);
153     selector.AddMatcher(matcher1);
154 
155     vector<reference_wrapper<const Widget>> receiver;
156     selector.Select(tree_, receiver);
157 
158     ASSERT_EQ(1, receiver.size());
159     // check the result widget
160     ASSERT_EQ("id8", receiver.at(0).get().GetAttr("resource-id", ""));
161 }
162 
TEST_F(WidgetSelectorTest,multiMatcherWithoutLocatorAndExistMultiTargets)163 TEST_F(WidgetSelectorTest, multiMatcherWithoutLocatorAndExistMultiTargets)
164 {
165     auto selector = WidgetSelector();
166     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
167     selector.AddMatcher(matcher0);
168 
169     vector<reference_wrapper<const Widget>> receiver;
170     selector.Select(tree_, receiver);
171 
172     ASSERT_EQ(2, receiver.size());
173     // check the result widgets and the order, should arranges in DFS order
174     ASSERT_EQ("id8", receiver.at(0).get().GetAttr("resource-id", ""));
175     ASSERT_EQ("id10", receiver.at(1).get().GetAttr("resource-id", ""));
176 }
177 
TEST_F(WidgetSelectorTest,singleFrontLocatorAndExistsNoTarget)178 TEST_F(WidgetSelectorTest, singleFrontLocatorAndExistsNoTarget)
179 {
180     ApiCallErr err(NO_ERROR);
181     auto selector = WidgetSelector();
182     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
183     selector.AddMatcher(matcher0);
184 
185     auto frontMatcher = WidgetAttrMatcher("resource-id", "id10", EQ);
186     auto frontLocator = WidgetSelector();
187     frontLocator.AddMatcher(frontMatcher);
188     selector.AddFrontLocator(frontLocator, err);
189     ASSERT_EQ(NO_ERROR, err.code_);
190 
191     vector<reference_wrapper<const Widget>> receiver;
192     selector.Select(tree_, receiver);
193     // "id10" is not in front of "*Transfer*", so no widget should be selected
194     ASSERT_EQ(0, receiver.size());
195 }
196 
TEST_F(WidgetSelectorTest,singleFrontLocatorAndExistsSingleTarget)197 TEST_F(WidgetSelectorTest, singleFrontLocatorAndExistsSingleTarget)
198 {
199     ApiCallErr err(NO_ERROR);
200     auto selector = WidgetSelector();
201     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
202     selector.AddMatcher(matcher0);
203 
204     auto frontMatcher = WidgetAttrMatcher("resource-id", "id9", EQ);
205     auto frontLocator = WidgetSelector();
206     frontLocator.AddMatcher(frontMatcher);
207     selector.AddFrontLocator(frontLocator, err);
208     ASSERT_EQ(NO_ERROR, err.code_);
209 
210     vector<reference_wrapper<const Widget>> receiver;
211     selector.Select(tree_, receiver);
212     // "id9" is not in front of "Transfer files" but not "Transfer photos", so one widget should be selected
213     ASSERT_EQ(1, receiver.size());
214     ASSERT_EQ("Transfer files", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
215 }
216 
TEST_F(WidgetSelectorTest,singleFrontLocatorAndExistMultiTargets)217 TEST_F(WidgetSelectorTest, singleFrontLocatorAndExistMultiTargets)
218 {
219     ApiCallErr err(NO_ERROR);
220     auto selector = WidgetSelector();
221     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
222     selector.AddMatcher(matcher0);
223 
224     auto frontMatcher = WidgetAttrMatcher("resource-id", "id7", EQ);
225     auto frontLocator = WidgetSelector();
226     frontLocator.AddMatcher(frontMatcher);
227     selector.AddFrontLocator(frontLocator, err);
228     ASSERT_EQ(NO_ERROR, err.code_);
229 
230     vector<reference_wrapper<const Widget>> receiver;
231     selector.Select(tree_, receiver);
232     // "id9" is not in front of "Transfer files" and "Transfer photos", so two widgets should be selected
233     ASSERT_EQ(2, receiver.size());
234     // check the result widgets and the order, should arranges in DFS order
235     ASSERT_EQ("Transfer photos", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
236     ASSERT_EQ("Transfer files", receiver.at(1).get().GetAttr(ATTR_TEXT, ""));
237 }
238 
TEST_F(WidgetSelectorTest,multiFrontLocatorAndExistsNoTarget)239 TEST_F(WidgetSelectorTest, multiFrontLocatorAndExistsNoTarget)
240 {
241     ApiCallErr err(NO_ERROR);
242     auto selector = WidgetSelector();
243     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
244     selector.AddMatcher(matcher0);
245 
246     auto frontMatcher0 = WidgetAttrMatcher("resource-id", "id1", EQ);
247     auto frontLocator0 = WidgetSelector();
248     frontLocator0.AddMatcher(frontMatcher0);
249     selector.AddFrontLocator(frontLocator0, err);
250     ASSERT_EQ(NO_ERROR, err.code_);
251     auto frontMatcher1 = WidgetAttrMatcher("resource-id", "id10", EQ);
252     auto frontLocator1 = WidgetSelector();
253     frontLocator1.AddMatcher(frontMatcher1);
254     selector.AddFrontLocator(frontLocator1, err);
255     ASSERT_EQ(NO_ERROR, err.code_);
256 
257     vector<reference_wrapper<const Widget>> receiver;
258     selector.Select(tree_, receiver);
259     // "id1" is in front of "*Transfer*" but "id10" isn't, so no widget should be selected
260     ASSERT_EQ(0, receiver.size());
261 }
262 
TEST_F(WidgetSelectorTest,multiFrontLocatorAndExistsSingleTarget)263 TEST_F(WidgetSelectorTest, multiFrontLocatorAndExistsSingleTarget)
264 {
265     ApiCallErr err(NO_ERROR);
266     auto selector = WidgetSelector();
267     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
268     selector.AddMatcher(matcher0);
269 
270     auto frontMatcher0 = WidgetAttrMatcher("resource-id", "id8", EQ);
271     auto frontLocator0 = WidgetSelector();
272     frontLocator0.AddMatcher(frontMatcher0);
273     selector.AddFrontLocator(frontLocator0, err);
274     ASSERT_EQ(NO_ERROR, err.code_);
275     auto frontMatcher1 = WidgetAttrMatcher("resource-id", "id9", EQ);
276     auto frontLocator1 = WidgetSelector();
277     frontLocator1.AddMatcher(frontMatcher1);
278     selector.AddFrontLocator(frontLocator1, err);
279     ASSERT_EQ(NO_ERROR, err.code_);
280 
281     vector<reference_wrapper<const Widget>> receiver;
282     selector.Select(tree_, receiver);
283     // both "id8" and "id9" are in front of "Transfer files" but not "Transfer photos", so one widget should be selected
284     ASSERT_EQ(1, receiver.size());
285     ASSERT_EQ("Transfer files", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
286 }
287 
TEST_F(WidgetSelectorTest,multiFrontLocatorAndExistMultiTargets)288 TEST_F(WidgetSelectorTest, multiFrontLocatorAndExistMultiTargets)
289 {
290     ApiCallErr err(NO_ERROR);
291     auto selector = WidgetSelector();
292     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
293     selector.AddMatcher(matcher0);
294 
295     auto frontMatcher0 = WidgetAttrMatcher("resource-id", "id6", EQ);
296     auto frontLocator0 = WidgetSelector();
297     frontLocator0.AddMatcher(frontMatcher0);
298     selector.AddFrontLocator(frontLocator0, err);
299     ASSERT_EQ(NO_ERROR, err.code_);
300     auto frontMatcher1 = WidgetAttrMatcher("resource-id", "id7", EQ);
301     auto frontLocator1 = WidgetSelector();
302     frontLocator1.AddMatcher(frontMatcher1);
303     selector.AddFrontLocator(frontLocator1, err);
304     ASSERT_EQ(NO_ERROR, err.code_);
305 
306     vector<reference_wrapper<const Widget>> receiver;
307     selector.Select(tree_, receiver);
308 
309     // both "id8" and "id9" are in front of "Transfer files" but not "*Transfer*", two widgets should be selected
310     ASSERT_EQ(2, receiver.size());
311     // check the result widgets and the order, should arranges in DFS order
312     ASSERT_EQ("Transfer photos", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
313     ASSERT_EQ("Transfer files", receiver.at(1).get().GetAttr(ATTR_TEXT, ""));
314 }
315 
TEST_F(WidgetSelectorTest,singleRearLocatorAndExistsNoTarget)316 TEST_F(WidgetSelectorTest, singleRearLocatorAndExistsNoTarget)
317 {
318     ApiCallErr err(NO_ERROR);
319     auto selector = WidgetSelector();
320     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
321     selector.AddMatcher(matcher0);
322 
323     auto rearMatcher = WidgetAttrMatcher("resource-id", "id7", EQ);
324     auto rearLocator = WidgetSelector();
325     rearLocator.AddMatcher(rearMatcher);
326     selector.AddRearLocator(rearLocator, err);
327     ASSERT_EQ(NO_ERROR, err.code_);
328 
329     vector<reference_wrapper<const Widget>> receiver;
330     selector.Select(tree_, receiver);
331     // "id10" is not in rear of "*Transfer*", so no widget should be selected
332     ASSERT_EQ(0, receiver.size());
333 }
334 
TEST_F(WidgetSelectorTest,singleRearLocatorAndExistsSingleTarget)335 TEST_F(WidgetSelectorTest, singleRearLocatorAndExistsSingleTarget)
336 {
337     ApiCallErr err(NO_ERROR);
338     auto selector = WidgetSelector();
339     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
340     selector.AddMatcher(matcher0);
341 
342     auto rearMatcher = WidgetAttrMatcher("resource-id", "id9", EQ);
343     auto rearLocator = WidgetSelector();
344     rearLocator.AddMatcher(rearMatcher);
345     selector.AddRearLocator(rearLocator, err);
346     ASSERT_EQ(NO_ERROR, err.code_);
347 
348     vector<reference_wrapper<const Widget>> receiver;
349     selector.Select(tree_, receiver);
350     // "id9" is not in rear of "Transfer photos" but not "Transfer files", so one widget should be selected
351     ASSERT_EQ(1, receiver.size());
352     ASSERT_EQ("Transfer photos", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
353 }
354 
TEST_F(WidgetSelectorTest,singleRearLocatorAndExistMultiTargets)355 TEST_F(WidgetSelectorTest, singleRearLocatorAndExistMultiTargets)
356 {
357     ApiCallErr err(NO_ERROR);
358     auto selector = WidgetSelector();
359     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "s", CONTAINS);
360     selector.AddMatcher(matcher0);
361 
362     auto rearMatcher = WidgetAttrMatcher("resource-id", "id10", EQ);
363     auto rearLocator = WidgetSelector();
364     rearLocator.AddMatcher(rearMatcher);
365     selector.AddRearLocator(rearLocator, err);
366     ASSERT_EQ(NO_ERROR, err.code_);
367 
368     vector<reference_wrapper<const Widget>> receiver;
369     selector.Select(tree_, receiver);
370     // "id10" is rear in front of "Use USB to" and "Transfer photos", so two widgets should be selected
371     ASSERT_EQ(2, receiver.size());
372     // check the result widgets and the order, should arranges in DFS order
373     ASSERT_EQ("Use USB to", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
374     ASSERT_EQ("Transfer photos", receiver.at(1).get().GetAttr(ATTR_TEXT, ""));
375 }
376 
TEST_F(WidgetSelectorTest,frontAndRearLocatorsAndExistsNoTarget)377 TEST_F(WidgetSelectorTest, frontAndRearLocatorsAndExistsNoTarget)
378 {
379     ApiCallErr err(NO_ERROR);
380     auto selector = WidgetSelector();
381     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
382     selector.AddMatcher(matcher0);
383 
384     auto frontMatcher = WidgetAttrMatcher("resource-id", "id8", EQ);
385     auto frontLocator = WidgetSelector();
386     frontLocator.AddMatcher(frontMatcher);
387     selector.AddFrontLocator(frontLocator, err);
388     ASSERT_EQ(NO_ERROR, err.code_);
389     auto rearMatcher = WidgetAttrMatcher("resource-id", "id10", EQ);
390     auto rearLocator = WidgetSelector();
391     rearLocator.AddMatcher(rearMatcher);
392     selector.AddRearLocator(rearLocator, err);
393     ASSERT_EQ(NO_ERROR, err.code_);
394 
395     vector<reference_wrapper<const Widget>> receiver;
396     selector.Select(tree_, receiver);
397     // no "*Transfer*" is between "id8" and "id10", so no widget should be selected
398     ASSERT_EQ(0, receiver.size());
399 }
400 
TEST_F(WidgetSelectorTest,frontAndRearLocatorsAndExistsSingleTarget)401 TEST_F(WidgetSelectorTest, frontAndRearLocatorsAndExistsSingleTarget)
402 {
403     ApiCallErr err(NO_ERROR);
404     auto selector = WidgetSelector();
405     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "Transfer", CONTAINS);
406     selector.AddMatcher(matcher0);
407 
408     auto frontMatcher = WidgetAttrMatcher("resource-id", "id7", EQ);
409     auto frontLocator = WidgetSelector();
410     frontLocator.AddMatcher(frontMatcher);
411     selector.AddFrontLocator(frontLocator, err);
412     ASSERT_EQ(NO_ERROR, err.code_);
413     auto rearMatcher = WidgetAttrMatcher("resource-id", "id10", EQ);
414     auto rearLocator = WidgetSelector();
415     rearLocator.AddMatcher(rearMatcher);
416     selector.AddRearLocator(rearLocator, err);
417     ASSERT_EQ(NO_ERROR, err.code_);
418 
419     vector<reference_wrapper<const Widget>> receiver;
420     selector.Select(tree_, receiver);
421 
422     // only "Transfer photos" is between "id7" and "id10", one widget should be selected
423     ASSERT_EQ(1, receiver.size());
424     ASSERT_EQ("Transfer photos", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
425 }
426 
TEST_F(WidgetSelectorTest,frontAndRearLocatorsAndExistMultiTargets)427 TEST_F(WidgetSelectorTest, frontAndRearLocatorsAndExistMultiTargets)
428 {
429     ApiCallErr err(NO_ERROR);
430     auto selector = WidgetSelector();
431     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "s", CONTAINS);
432     selector.AddMatcher(matcher0);
433 
434     auto frontMatcher = WidgetAttrMatcher("resource-id", "id3", EQ);
435     auto frontLocator = WidgetSelector();
436     frontLocator.AddMatcher(frontMatcher);
437     selector.AddFrontLocator(frontLocator, err);
438     ASSERT_EQ(NO_ERROR, err.code_);
439     auto rearMatcher = WidgetAttrMatcher("resource-id", "id9", EQ);
440     auto rearLocator = WidgetSelector();
441     rearLocator.AddMatcher(rearMatcher);
442     selector.AddRearLocator(rearLocator, err);
443     ASSERT_EQ(NO_ERROR, err.code_);
444 
445     vector<reference_wrapper<const Widget>> receiver;
446     selector.Select(tree_, receiver);
447 
448     // both of "Use USB to" and "Transfer photos" are between "id3" and "id9", so two widgets should be selected
449     ASSERT_EQ(2, receiver.size());
450     // check the result widgets and the order, should arranges in DFS order
451     ASSERT_EQ("Use USB to", receiver.at(0).get().GetAttr(ATTR_TEXT, ""));
452     ASSERT_EQ("Transfer photos", receiver.at(1).get().GetAttr(ATTR_TEXT, ""));
453 }
454 
TEST_F(WidgetSelectorTest,nestingUsageDetect)455 TEST_F(WidgetSelectorTest, nestingUsageDetect)
456 {
457     ApiCallErr err(NO_ERROR);
458     auto selector = WidgetSelector();
459     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "s", CONTAINS);
460     selector.AddMatcher(matcher0);
461 
462     auto frontMatcher = WidgetAttrMatcher("resource-id", "id3", EQ);
463     auto frontLocator = WidgetSelector();
464     frontLocator.AddMatcher(frontMatcher);
465     ASSERT_EQ(NO_ERROR, err.code_);
466     frontLocator.AddRearLocator(frontLocator, err);
467     ASSERT_EQ(NO_ERROR, err.code_);
468 
469     // make the front locator nesting
470     selector.AddFrontLocator(frontLocator, err);
471     ASSERT_EQ(ERR_INVALID_INPUT, err.code_);
472 }
473 
TEST_F(WidgetSelectorTest,selectorDescription)474 TEST_F(WidgetSelectorTest, selectorDescription)
475 {
476     ApiCallErr err(NO_ERROR);
477     auto selector = WidgetSelector();
478     auto matcher0 = WidgetAttrMatcher(ATTR_TEXT, "s", CONTAINS);
479     selector.AddMatcher(matcher0);
480 
481     auto frontMatcher = WidgetAttrMatcher("resource-id", "id3", EQ);
482     auto frontLocator = WidgetSelector();
483     frontLocator.AddMatcher(frontMatcher);
484     selector.AddFrontLocator(frontLocator, err);
485     ASSERT_EQ(NO_ERROR, err.code_);
486     auto rearMatcher = WidgetAttrMatcher("resource-id", "id9", EQ);
487     auto rearLocator = WidgetSelector();
488     rearLocator.AddMatcher(rearMatcher);
489     selector.AddRearLocator(rearLocator, err);
490     ASSERT_EQ(NO_ERROR, err.code_);
491 
492     auto description = selector.Describe();
493     auto pos0 = description.find("selfMatcher");
494     auto pos1 = description.find(matcher0.Describe());
495     auto pos2 = description.find("frontMatcher");
496     auto pos3 = description.find(frontMatcher.Describe());
497     auto pos4 = description.find("rearMatcher");
498     auto pos5 = description.find(rearMatcher.Describe());
499     ASSERT_TRUE(pos0 != string::npos && pos0 > 0);
500     ASSERT_TRUE(pos1 != string::npos && pos1 > pos0);
501     ASSERT_TRUE(pos2 != string::npos && pos2 > pos1);
502     ASSERT_TRUE(pos3 != string::npos && pos3 > pos2);
503     ASSERT_TRUE(pos4 != string::npos && pos4 > pos3);
504     ASSERT_TRUE(pos5 != string::npos && pos5 > pos4);
505 }