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
16 #include "special_test_flow.h"
17
18 #include <string>
19
20 #include "report.h"
21 #include "string_ex.h"
22 #include "wukong_define.h"
23
24 namespace OHOS {
25 namespace WuKong {
26 namespace {
27 const std::string SPECIAL_TEST_HELP_MSG =
28 "usage: wukong special [<arguments>]\n"
29 "These are wukong special arguments list:\n"
30 " -h, --help special test help\n"
31 " -t, --touch[x,y] touch event \n"
32 " -c, --count total count of test\n"
33 " -i, --interval interval\n"
34 " -S, --swap[option] swap event\n"
35 " option is -s| -e| -b\n"
36 " -s, --start: the start point of swap\n"
37 " -e, --end: the end point of swap\n"
38 " -b, --bilateral: swap go and back\n"
39 " -k, --spec_insomnia power on/off event\n"
40 " -T, --time total time of test\n"
41 " -C, --component component event\n"
42 " -p, --screenshot get screenshot(only in componment input)\n"
43 " -r, --record record user operation\n"
44 " -R, --replay replay user operation\n"
45 " -u, --uitest uitest dumpLayout\n";
46
47 const std::string SHORT_OPTIONS = "c:hi:T:t:kSbs:e:C:pr:R:u:";
48 const struct option LONG_OPTIONS[] = {
49 {"count", required_argument, nullptr, 'c'}, // test count
50 {"help", no_argument, nullptr, 'h'}, // help information
51 {"interval", required_argument, nullptr, 'i'}, // test interval
52 {"touch", required_argument, nullptr, 't'}, // touch
53 {"spec_insomnia", no_argument, nullptr, 'k'}, // sleep and awake
54 {"time", required_argument, nullptr, 'T'}, // test time
55 {"swap", required_argument, nullptr, 'S'}, // swap
56 {"bilateral", no_argument, nullptr, 'b'}, // swap go and back
57 {"start", no_argument, nullptr, 's'}, // the start point of swap
58 {"end", no_argument, nullptr, 'e'}, // the end point of swap
59 {"component", required_argument, nullptr, 'C'}, // the end point of swap
60 {"screenshot", no_argument, nullptr, 'p'}, // get photo of screenshot
61 {"record", required_argument, nullptr, 'r'}, // record user operation
62 {"replay", required_argument, nullptr, 'R'}, // replay user operation
63 {"uitest", no_argument, nullptr, 'u'} // uitest dumpLayout
64 };
65 const int ONE_MINUTE = 60000;
66 bool g_commandSWAPENABLE = false;
67 bool g_commandHELPENABLE = false;
68 bool g_commandTIMEENABLE = false;
69 bool g_commandTOUCHENABLE = false;
70 bool g_commandPOWERENABLE = false;
71 bool g_commandGOBACKENABLE = false;
72 bool g_commandCOUNTENABLE = false;
73 bool g_commandCOMPONENTENABLE = false;
74 bool g_commandSCREENSHOTENABLE = false;
75 bool g_commandRECORDABLE = false;
76 bool g_commandREPLAYABLE = false;
77 bool g_commandUITEST = false;
78
79 const int NUMBER_TWO = 2;
80 } // namespace
81 using namespace std;
82
SpecialTestFlow(WuKongShellCommand & shellcommand)83 SpecialTestFlow::SpecialTestFlow(WuKongShellCommand &shellcommand) : TestFlow(shellcommand)
84 {
85 }
86
~SpecialTestFlow()87 SpecialTestFlow::~SpecialTestFlow()
88 {
89 if (timer_ != nullptr) {
90 timer_->Shutdown();
91 timer_->Unregister(timerId_);
92 timer_ = nullptr;
93 }
94 }
95
EnvInit()96 ErrCode SpecialTestFlow::EnvInit()
97 {
98 ErrCode result = OHOS::ERR_OK;
99 const std::string paramError = "param is incorrect";
100 if (g_commandSWAPENABLE == true) {
101 if (swapStartPoint_.size() == NUMBER_TWO && swapEndPoint_.size() == NUMBER_TWO) {
102 // set the params of touch special test
103 std::shared_ptr<SwapParam> swapParam = std::make_shared<SwapParam>();
104 swapParam->startX_ = stoi(swapStartPoint_[0]);
105 swapParam->startY_ = stoi(swapStartPoint_[1]);
106 swapParam->endX_ = stoi(swapEndPoint_[0]);
107 swapParam->endY_ = stoi(swapEndPoint_[1]);
108 swapParam->isGoBack_ = g_commandGOBACKENABLE;
109 if (specialTestObject_ == nullptr) {
110 specialTestObject_ = swapParam;
111 }
112 } else {
113 DEBUG_LOG(paramError.c_str());
114 shellcommand_.ResultReceiverAppend(paramError + "\n");
115 result = OHOS::ERR_INVALID_VALUE;
116 }
117 } else if (g_commandTOUCHENABLE == true) {
118 if (touchParam_.size() == NUMBER_TWO) {
119 // set the params of swap special test
120 std::shared_ptr<TouchParam> touchParam = std::make_shared<TouchParam>();
121 touchParam->x_ = stoi(touchParam_[0]);
122 touchParam->y_ = stoi(touchParam_[1]);
123 if (specialTestObject_ == nullptr) {
124 specialTestObject_ = touchParam;
125 }
126 } else {
127 DEBUG_LOG(paramError.c_str());
128 shellcommand_.ResultReceiverAppend(paramError + "\n");
129 result = OHOS::ERR_INVALID_VALUE;
130 }
131 } else if (g_commandCOMPONENTENABLE == true) {
132 std::shared_ptr<ComponentParam> componentParam = std::make_shared<ComponentParam>();
133 for (auto name : bundleName_) {
134 componentParam->PushBundleName(name);
135 }
136 componentParam->isAllFinished_ = false;
137 specialTestObject_ = componentParam;
138 } else if (g_commandRECORDABLE == true) {
139 std::shared_ptr<RecordParam> recordParam = std::make_shared<RecordParam>();
140 recordParam->recordName_ = specialRecordName_;
141 recordParam->recordStatus_ = true;
142 if (specialTestObject_ == nullptr) {
143 specialTestObject_ = recordParam;
144 }
145 } else if (g_commandREPLAYABLE == true) {
146 std::shared_ptr<RecordParam> replayParam = std::make_shared<RecordParam>();
147 replayParam->recordName_ = specialRecordName_;
148 replayParam->recordStatus_ = false;
149 if (specialTestObject_ == nullptr) {
150 specialTestObject_ = replayParam;
151 }
152 }
153
154 // if time test flow, register timer.
155 if (g_commandTIMEENABLE) {
156 RegisterTimer();
157 }
158 return result;
159 }
160
RunStep()161 ErrCode SpecialTestFlow::RunStep()
162 {
163 // control the count test flow
164 if (g_commandCOUNTENABLE == true) {
165 totalCount_--;
166 if (totalCount_ < 0) {
167 isFinished_ = true;
168 return OHOS::ERR_OK;
169 }
170 }
171 // order test
172 ErrCode result;
173 if (g_commandSCREENSHOTENABLE) {
174 std::string screenStorePath;
175 result = WuKongUtil::GetInstance()->WukongScreenCap(screenStorePath, g_commandUITEST);
176 if (result == OHOS::ERR_OK) {
177 Report::GetInstance()->RecordScreenPath(screenStorePath);
178 }
179 }
180 InputType inputTypeId = DistrbuteInputType();
181 std::shared_ptr<InputAction> inputaction = InputFactory::GetInputAction(inputTypeId);
182 result = inputaction->OrderInput(specialTestObject_);
183 if (result != OHOS::ERR_OK) {
184 WARN_LOG("This test failed");
185 }
186 if (g_commandCOMPONENTENABLE) {
187 if (specialTestObject_->isAllFinished_) {
188 isFinished_ = true;
189 }
190 }
191 if (g_commandRECORDABLE) {
192 isFinished_ = true;
193 }
194 if (g_commandREPLAYABLE) {
195 isFinished_ = true;
196 }
197 usleep(intervalArgs_ * oneSecond_);
198 return result;
199 }
200
DistrbuteInputType()201 InputType SpecialTestFlow::DistrbuteInputType()
202 {
203 InputType iputType = INPUTTYPE_INVALIDINPUT;
204
205 if (g_commandTOUCHENABLE == true) {
206 iputType = INPUTTYPE_TOUCHINPUT;
207 } else if (g_commandSWAPENABLE) {
208 iputType = INPUTTYPE_SWAPINPUT;
209 } else if (g_commandPOWERENABLE) {
210 iputType = INPUTTYPE_HARDKEYINPUT;
211 } else if (g_commandCOMPONENTENABLE) {
212 iputType = INPUTTYPE_ELEMENTINPUT;
213 } else if (g_commandRECORDABLE) {
214 iputType = INPUTTYPE_RECORDINPUT;
215 } else if (g_commandREPLAYABLE) {
216 iputType = INPUTTYPE_REPPLAYINPUT;
217 }
218 return iputType;
219 }
220
GetOptionArguments(std::string & shortOpts)221 const struct option *SpecialTestFlow::GetOptionArguments(std::string &shortOpts)
222 {
223 shortOpts = SHORT_OPTIONS;
224 return LONG_OPTIONS;
225 }
226
HandleUnknownOption(const char optopt)227 ErrCode SpecialTestFlow::HandleUnknownOption(const char optopt)
228 {
229 ErrCode result = OHOS::ERR_OK;
230 switch (optopt) {
231 case 'T':
232 case 'i':
233 case 'c':
234 case 's':
235 case 'e':
236 case 'C':
237 shellcommand_.ResultReceiverAppend("error: option '-");
238 shellcommand_.ResultReceiverAppend(string(1, optopt));
239 shellcommand_.ResultReceiverAppend("' requires a value.\n");
240 result = OHOS::ERR_INVALID_VALUE;
241 break;
242 case 'h': {
243 result = OHOS::ERR_INVALID_VALUE;
244 break;
245 }
246 default: {
247 // 'wukong special' with a unknown option: wukong special -x
248 shellcommand_.ResultReceiverAppend(
249 "'wukong special' with an unknown option, please reference help information:\n");
250 result = OHOS::ERR_INVALID_VALUE;
251 break;
252 }
253 }
254 shellcommand_.ResultReceiverAppend(SPECIAL_TEST_HELP_MSG);
255 return result;
256 }
257
HandleNormalOption(const int option)258 ErrCode SpecialTestFlow::HandleNormalOption(const int option)
259 {
260 ErrCode result = OHOS::ERR_OK;
261 switch (option) {
262 case 'S': {
263 g_commandSWAPENABLE = true;
264 break;
265 }
266 case 'k': {
267 g_commandPOWERENABLE = true;
268 break;
269 }
270 case 'c':
271 case 'T':
272 CheckArgument(option);
273 break;
274 case 'h': {
275 shellcommand_.ResultReceiverAppend(SPECIAL_TEST_HELP_MSG);
276 result = ERR_NO_INIT;
277 g_commandHELPENABLE = true;
278 break;
279 }
280 case 'i': {
281 intervalArgs_ = std::stoi(optarg);
282 TEST_RUN_LOG(("Interval: " + std::to_string(intervalArgs_)).c_str());
283 break;
284 }
285 case 't': {
286 SplitStr(optarg, ",", touchParam_);
287 // check if param is valid
288 result = CheckPosition(touchParam_);
289 g_commandTOUCHENABLE = true;
290 break;
291 }
292 case 'b': {
293 g_commandGOBACKENABLE = true;
294 break;
295 }
296 case 's': {
297 SplitStr(optarg, ",", swapStartPoint_);
298 // check if param is valid
299 result = CheckPosition(swapStartPoint_);
300 break;
301 }
302 case 'e': {
303 SplitStr(optarg, ",", swapEndPoint_);
304 // check if param is valid
305 result = CheckPosition(swapEndPoint_);
306 break;
307 }
308 case 'C': {
309 SplitStr(optarg, ",", bundleName_);
310 result = WuKongUtil::GetInstance()->CheckArgumentList(bundleName_, true);
311 g_commandCOMPONENTENABLE = true;
312 break;
313 }
314 case 'p': {
315 g_commandSCREENSHOTENABLE = true;
316 break;
317 }
318 case 'r': {
319 g_commandRECORDABLE = true;
320 specialRecordName_ = optarg;
321 break;
322 }
323 case 'R': {
324 g_commandREPLAYABLE = true;
325 specialRecordName_ = optarg;
326 break;
327 }
328 case 'u': {
329 g_commandUITEST = true;
330 break;
331 }
332 }
333 WuKongUtil::GetInstance()->SetOrderFlag(true);
334 return result;
335 }
336
CheckArgument(const int option)337 ErrCode SpecialTestFlow::CheckArgument(const int option)
338 {
339 ErrCode result = OHOS::ERR_OK;
340 switch (option) {
341 case 'c': {
342 // check if the '-c' and 'T' is exist at the same time
343 if (g_commandTIMEENABLE == false) {
344 g_commandCOUNTENABLE = true;
345 countArgs_ = std::stoi(optarg);
346 TEST_RUN_LOG(("Count: " + std::to_string(countArgs_)).c_str());
347 totalCount_ = countArgs_;
348 } else {
349 DEBUG_LOG(PARAM_COUNT_TIME_ERROR);
350 shellcommand_.ResultReceiverAppend(std::string(PARAM_COUNT_TIME_ERROR) + "\n");
351 result = OHOS::ERR_INVALID_VALUE;
352 }
353 break;
354 }
355 case 'T': {
356 // check if the '-c' and 'T' is exist at the same time
357 if (g_commandCOUNTENABLE == false) {
358 totalTime_ = std::stof(optarg);
359 TEST_RUN_LOG(("Time: " + std::to_string(totalTime_)).c_str());
360 g_commandTIMEENABLE = true;
361 } else {
362 DEBUG_LOG(PARAM_TIME_COUNT_ERROR);
363 shellcommand_.ResultReceiverAppend(std::string(PARAM_TIME_COUNT_ERROR) + "\n");
364 result = OHOS::ERR_INVALID_VALUE;
365 }
366 break;
367 }
368 default: {
369 result = OHOS::ERR_INVALID_VALUE;
370 break;
371 }
372 }
373 return result;
374 }
375
RegisterTimer()376 void SpecialTestFlow::RegisterTimer()
377 {
378 if (timer_ == nullptr) {
379 timer_ = std::make_shared<Utils::Timer>("wukong");
380 timerId_ = timer_->Register(std::bind(&SpecialTestFlow::TestTimeout, this), totalTime_ * ONE_MINUTE, true);
381 timer_->Setup();
382 }
383 }
384
TestTimeout()385 void SpecialTestFlow::TestTimeout()
386 {
387 g_commandTIMEENABLE = false;
388 isFinished_ = true;
389 }
390
CheckPosition(std::vector<std::string> argumentlist)391 ErrCode SpecialTestFlow::CheckPosition(std::vector<std::string> argumentlist)
392 {
393 int32_t screenWidth = -1;
394 int32_t screenHeight = -1;
395
396 // get the size of screen
397 ErrCode result = WuKongUtil::GetInstance()->GetScreenSize(screenWidth, screenHeight);
398 if (result != OHOS::ERR_OK) {
399 return result;
400 }
401 if (argumentlist.size() > 0) {
402 if (stoi(argumentlist[0]) > screenWidth || stoi(argumentlist[1]) > screenHeight || stoi(argumentlist[0]) < 0 ||
403 stoi(argumentlist[1]) < 0) {
404 std::string paramError = "the param of position is incorrect";
405 DEBUG_LOG(paramError.c_str());
406 shellcommand_.ResultReceiverAppend(paramError + "\n");
407 result = OHOS::ERR_NO_INIT;
408 }
409 }
410 return result;
411 }
412
LauncherApp()413 ErrCode SpecialTestFlow::LauncherApp()
414 {
415 std::shared_ptr<InputAction> inputaction = InputFactory::GetInputAction(INPUTTYPE_APPSWITCHINPUT);
416 ErrCode result = inputaction->OrderInput(specialTestObject_);
417 if (result != OHOS::ERR_OK) {
418 ERROR_LOG("launcher app failed");
419 }
420 return result;
421 }
422 } // namespace WuKong
423 } // namespace OHOS
424