• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2024 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 "component_test/core/component_test_tester_impl.h"
17 
18 #include <algorithm>
19 #include <queue>
20 
21 #include "base/geometry/ng/point_t.h"
22 #include "base/geometry/rect.h"
23 #include "base/memory/ace_type.h"
24 #include "base/utils/utils.h"
25 #include "core/common/ace_engine.h"
26 #include "core/common/container.h"
27 #include "core/components_ng/base/ui_node.h"
28 #include "core/pipeline_ng/pipeline_context.h"
29 
30 namespace OHOS::Ace::ComponentTest {
FindComponentImpl(const ComponentTestMatcherImpl & matcher,ErrInfo & errInfo) const31 ComponentTestComponentImpl* ComponentTestTesterImpl::FindComponentImpl(
32     const ComponentTestMatcherImpl& matcher, ErrInfo& errInfo) const
33 {
34     errInfo = QueryRetMsg(RET_ERR_FAILED);
35     auto container = AceEngine::Get().GetContainer(ACE_INSTANCE_ID);
36     CHECK_NULL_RETURN(container, nullptr);
37     auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
38     CHECK_NULL_RETURN(context, nullptr);
39     auto rootNode = context->GetRootElement();
40     CHECK_NULL_RETURN(rootNode, nullptr);
41     errInfo = QueryRetMsg(RET_OK);
42     std::queue<RefPtr<NG::UINode>> elements;
43     elements.push(rootNode);
44     while (!elements.empty()) {
45         auto current = elements.front();
46         elements.pop();
47         if (matcher.Match(current)) {
48             ComponentTestComponentImpl* componentTestComponentImpl = new ComponentTestComponentImpl();
49             componentTestComponentImpl->SetUiNode(current);
50             componentTestComponentImpl->SetEffective();
51             return componentTestComponentImpl;
52         }
53 
54         const auto& children = current->GetChildren();
55         for (const auto& child : children) {
56             elements.push(child);
57         }
58     }
59     return nullptr;
60 }
61 
FindComponentsImpl(const ComponentTestMatcherImpl & matcher,ErrInfo & errInfo) const62 std::unique_ptr<std::vector<ComponentTestComponentImpl*>> ComponentTestTesterImpl::FindComponentsImpl(
63     const ComponentTestMatcherImpl& matcher, ErrInfo& errInfo) const
64 {
65     auto testerElements = std::make_unique<std::vector<ComponentTestComponentImpl*>>();
66     auto container = AceEngine::Get().GetContainer(ACE_INSTANCE_ID);
67     errInfo = QueryRetMsg(RET_ERR_FAILED);
68     CHECK_NULL_RETURN(container, nullptr);
69     auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
70     CHECK_NULL_RETURN(context, nullptr);
71     auto rootNode = context->GetRootElement();
72     CHECK_NULL_RETURN(rootNode, nullptr);
73     errInfo = QueryRetMsg(RET_OK);
74 
75     std::queue<RefPtr<NG::UINode>> elements;
76     elements.push(rootNode);
77     RefPtr<NG::UINode> inspectorElement;
78     while (!elements.empty()) {
79         auto current = elements.front();
80         elements.pop();
81         if (matcher.Match(current)) {
82             ComponentTestComponentImpl* componentTestComponentImpl = new ComponentTestComponentImpl();
83             componentTestComponentImpl->SetUiNode(current);
84             componentTestComponentImpl->SetEffective();
85             testerElements->emplace_back(componentTestComponentImpl);
86         }
87 
88         const auto& children = current->GetChildren();
89         for (const auto& child : children) {
90             elements.push(child);
91         }
92     }
93     return testerElements;
94 }
95 
AssertComponentExistImpl(const ComponentTestMatcherImpl & matcher,ErrInfo & errInfo) const96 void ComponentTestTesterImpl::AssertComponentExistImpl(const ComponentTestMatcherImpl& matcher, ErrInfo& errInfo) const
97 {
98     ComponentTestComponentImpl* component = FindComponentImpl(matcher, errInfo);
99     if (component == nullptr) {
100         errInfo = QueryRetMsg(ErrCode::RET_ERR_ASSERTION_COMPONENT_EXIST);
101         return;
102     }
103     delete component;
104 }
105 
ScrollUntilExistImpl(const ComponentTestMatcherImpl & matcher,ErrInfo & errInfo) const106 ComponentTestComponentImpl* ComponentTestTesterImpl::ScrollUntilExistImpl(
107     const ComponentTestMatcherImpl& matcher, ErrInfo& errInfo) const
108 {
109     errInfo = QueryRetMsg(ErrCode::RET_ERR_FAILED);
110     auto container = AceEngine::Get().GetContainer(ACE_INSTANCE_ID);
111     CHECK_NULL_RETURN(container, nullptr);
112     auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
113     CHECK_NULL_RETURN(context, nullptr);
114     auto rootNode = context->GetRootElement();
115     CHECK_NULL_RETURN(rootNode, nullptr);
116 
117     std::queue<RefPtr<NG::UINode>> elements;
118     RefPtr<NG::UINode> target = nullptr;
119     elements.push(rootNode);
120     auto scale = context->GetViewScale();
121     NG::RectF screenRect(0.0, 0.0, context->GetRootWidth() * scale, context->GetRootHeight() * scale);
122     while (!elements.empty()) {
123         auto current = elements.front();
124         elements.pop();
125         if (matcher.Match(current)) {
126             target = current;
127             break;
128         }
129 
130         const auto& children = current->GetChildren();
131         for (const auto& child : children) {
132             elements.push(child);
133         }
134     }
135     if (target) {
136         const RefPtr<NG::FrameNode>& frameNode = AceType::DynamicCast<NG::FrameNode>(target);
137         NG::RectF rect = frameNode->GetTransformRectRelativeToWindow();
138         ScrollImpl(rect.GetX(), rect.GetY(), errInfo);
139         ComponentTestComponentImpl* componentTestComponentImpl = new ComponentTestComponentImpl();
140         componentTestComponentImpl->SetUiNode(target);
141         errInfo = QueryRetMsg(ErrCode::RET_OK);
142         return componentTestComponentImpl;
143     }
144     return nullptr;
145 }
146 
TriggerKeyImpl(OHOS::MMI::KeyCode keyCode,ErrInfo & errInfo) const147 void ComponentTestTesterImpl::TriggerKeyImpl(OHOS::MMI::KeyCode keyCode, ErrInfo& errInfo) const
148 {
149     SingleKeyAction singleKeyAction(keyCode);
150     singleKeyAction.Send();
151 }
152 
TriggerCombineKeysImpl(const std::vector<OHOS::MMI::KeyCode> & keyCodes,ErrInfo & errInfo) const153 void ComponentTestTesterImpl::TriggerCombineKeysImpl(
154     const std::vector<OHOS::MMI::KeyCode>& keyCodes, ErrInfo& errInfo) const
155 {
156     CombinedKeysAction combinedKeysAction(keyCodes);
157     combinedKeysAction.Send();
158 }
159 
TapImpl(float x,float y,ErrInfo & errInfo) const160 void ComponentTestTesterImpl::TapImpl(float x, float y, ErrInfo& errInfo) const
161 {
162     GenericClick(x, y, TouchType::TAP);
163 }
164 
DoubleTapImpl(float x,float y,ErrInfo & errInfo) const165 void ComponentTestTesterImpl::DoubleTapImpl(float x, float y, ErrInfo& errInfo) const
166 {
167     GenericClick(x, y, TouchType::DOUBLE_TAP);
168 }
169 
PressImpl(float x,float y,ErrInfo & errInfo,uint32_t duration) const170 void ComponentTestTesterImpl::PressImpl(float x, float y, ErrInfo& errInfo, uint32_t duration) const
171 {
172     GenericClick(x, y, TouchType::PRESS, duration);
173 }
174 
ScrollImpl(float deltaX,float deltaY,ErrInfo & errInfo) const175 void ComponentTestTesterImpl::ScrollImpl(float deltaX, float deltaY, ErrInfo& errInfo) const
176 {
177     ScrollAction scrollAction(deltaX, deltaY);
178     EventSequenceManager::GetInstance().Execute(&scrollAction);
179 }
180 
DragImpl(float startX,float startY,float endX,float endY,uint32_t speed,ErrInfo & errInfo) const181 void ComponentTestTesterImpl::DragImpl(
182     float startX, float startY, float endX, float endY, uint32_t speed, ErrInfo& errInfo) const
183 {
184     NG::PointF startPonit(startX, startY);
185     NG::PointF endPonit(endX, endY);
186     MoveAction moveAction(startPonit, endPonit, TouchType::DRAG);
187     EventSequenceManager::GetInstance().Execute(&moveAction);
188 }
189 
FlingImpl(const NG::PointF & from,const NG::PointF & to,uint32_t stepLen,uint32_t speed,ErrInfo & errInfo) const190 void ComponentTestTesterImpl::FlingImpl(
191     const NG::PointF& from, const NG::PointF& to, uint32_t stepLen, uint32_t speed, ErrInfo& errInfo) const
192 {
193     int32_t distanceX = to.GetX() - from.GetX();
194     int32_t distanceY = to.GetY() - from.GetY();
195     uint32_t distance = sqrt(distanceX * distanceX + distanceY * distanceY);
196     if (stepLen > 0 && stepLen <= distance) {
197         uint32_t steps = distance / stepLen;
198         if (speed < MIN_SPEED || speed > MAX_SPEED) {
199             LOGW("%{public}s", "The fling speed out of range");
200             speed = DEFAULT_SPEED;
201         }
202         MoveAction moveAction(from, to, TouchType::FLING, speed, steps);
203         EventSequenceManager::GetInstance().Execute(&moveAction);
204         errInfo = QueryRetMsg(ErrCode::RET_OK);
205     } else {
206         errInfo = QueryRetMsg(ErrCode::RET_ERROR_PARAM_INVALID);
207     }
208 }
209 
FlingImpl(UiDirection direction,uint32_t speed,ErrInfo & errInfo) const210 void ComponentTestTesterImpl::FlingImpl(UiDirection direction, uint32_t speed, ErrInfo& errInfo) const
211 {
212     auto container = AceEngine::Get().GetContainer(ACE_INSTANCE_ID);
213     if (!container) {
214         errInfo = QueryRetMsg(ErrCode::RET_ERR_FAILED);
215         return;
216     }
217     auto context = AceType::DynamicCast<NG::PipelineContext>(container->GetPipelineContext());
218     if (!context) {
219         errInfo = QueryRetMsg(ErrCode::RET_ERR_FAILED);
220         return;
221     }
222     auto scale = context->GetViewScale();
223     auto rootHeight = context->GetRootHeight();
224     auto rootWidth = context->GetRootWidth();
225     NG::RectF screenRect(0.0, 0.0, rootWidth * scale, rootHeight * scale);
226     NG::PointF to;
227     NG::PointF from(screenRect.Width() * HALF, screenRect.Height() * HALF);
228     switch (direction) {
229         case UiDirection::TO_UP:
230             to.SetX(screenRect.Width() * HALF);
231             to.SetY(screenRect.Height() * HALF - screenRect.Height() * QUARTER);
232             break;
233         case UiDirection::TO_DOWN:
234             to.SetX(screenRect.Width() * HALF);
235             to.SetY(screenRect.Height() * HALF + screenRect.Width() * QUARTER);
236             break;
237         case UiDirection::TO_LEFT:
238             to.SetX(screenRect.Width() * HALF - screenRect.Width() * QUARTER);
239             to.SetY(screenRect.Height() * HALF);
240             break;
241         case UiDirection::TO_RIGHT:
242             to.SetX(screenRect.Width() * HALF + screenRect.Width() * QUARTER);
243             to.SetY(screenRect.Height() * HALF);
244             break;
245         default:
246             errInfo = QueryRetMsg(ErrCode::RET_ERROR_PARAM_INVALID);
247             return;
248     }
249     MoveAction moveAction(from, to, TouchType::FLING, speed, MIN_STEP_CONUT);
250     EventSequenceManager::GetInstance().Execute(&moveAction);
251     errInfo = QueryRetMsg(ErrCode::RET_OK);
252 }
253 
GenericClick(float x,float y,const TouchType touchType,uint32_t duration) const254 void ComponentTestTesterImpl::GenericClick(float x, float y, const TouchType touchType, uint32_t duration) const
255 {
256     auto point = NG::PointF(x, y);
257     ClickAction clickAction(point, touchType, duration);
258     EventSequenceManager::GetInstance().Execute(&clickAction);
259 }
260 
261 } // namespace OHOS::Ace::ComponentTest
262