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 16import SysTestKit from "./module/kit/SysTestKit"; 17 18class AssertException extends Error { 19 constructor(message) { 20 super(); 21 this.name = "AssertException"; 22 this.message = message; 23 } 24} 25 26function getFuncWithArgsZero(func, timeout, isStressTest) { 27 return new Promise(async (resolve, reject) => { 28 let timer = null; 29 if (!isStressTest) { 30 timer = setTimeout(() => { 31 reject(new Error('execute timeout ' + timeout + 'ms')); 32 }, timeout); 33 } 34 try { 35 await func(); 36 } catch (err) { 37 reject(err); 38 } 39 timer !== null ? clearTimeout(timer) : null; 40 resolve(); 41 }); 42} 43 44function getFuncWithArgsOne(func, timeout, isStressTest) { 45 return new Promise(async (resolve, reject) => { 46 let timer = null; 47 if (!isStressTest) { 48 timer = setTimeout(() => { 49 reject(new Error('execute timeout ' + timeout + 'ms')); 50 }, timeout);; 51 } 52 53 function done() { 54 timer !== null ? clearTimeout(timer) : null; 55 resolve(); 56 } 57 58 try { 59 await func(done); 60 } catch (err) { 61 timer !== null ? clearTimeout(timer) : null; 62 reject(err); 63 } 64 }); 65} 66 67function getFuncWithArgsTwo(func, timeout, paramItem, isStressTest) { 68 return new Promise(async (resolve, reject) => { 69 let timer = null; 70 if (!isStressTest) { 71 timer = setTimeout(() => { 72 reject(new Error('execute timeout ' + timeout + 'ms')); 73 }, timeout); 74 } 75 76 function done() { 77 timer !== null ? clearTimeout(timer) : null; 78 resolve(); 79 } 80 81 try { 82 await func(done, paramItem); 83 } catch (err) { 84 timer !== null ? clearTimeout(timer) : null; 85 reject(err); 86 } 87 }); 88} 89 90function processFunc(coreContext, func) { 91 let argNames = ((func || '').toString() 92 .replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/))/mg, '') 93 .match(/^(function)?\s*[^\(]*\(\s*([^\)]*)\)/m) || ['', '', ''])[2] 94 .split(',') // split parameters 95 .map(item => item.replace(/^\s*(_?)(.+?)\1\s*$/, name => name.split('=')[0].trim())) 96 .filter(String); 97 let funcLen = func.length; 98 let processedFunc; 99 const config = coreContext.getDefaultService('config'); 100 config.setSupportAsync(true); 101 const timeout = + (config.timeout === undefined ? 5000 : config.timeout); 102 const isStressTest = (coreContext.getServices('dataDriver') !== undefined || config.getStress() > 1); 103 switch (funcLen) { 104 case 0: { 105 processedFunc = function () { 106 return getFuncWithArgsZero(func, timeout, isStressTest); 107 }; 108 break; 109 } 110 case 1: { 111 if (argNames[0] === 'data') { 112 processedFunc = function (paramItem) { 113 func(paramItem); 114 }; 115 } else { 116 processedFunc = function () { 117 return getFuncWithArgsOne(func, timeout, isStressTest); 118 }; 119 } 120 break; 121 } 122 default: { 123 processedFunc = function (paramItem) { 124 return getFuncWithArgsTwo(func, timeout, paramItem, isStressTest); 125 }; 126 break; 127 } 128 } 129 return processedFunc; 130} 131 132function secureRandomNumber() { 133 return crypto.randomBytes(8).readUInt32LE() / 0xffffffff; 134} 135 136class SuiteService { 137 constructor(attr) { 138 this.id = attr.id; 139 this.rootSuite = new SuiteService.Suite({}); 140 this.currentRunningSuite = this.rootSuite; 141 } 142 143 describe(desc, func) { 144 const configService = this.coreContext.getDefaultService('config'); 145 if (configService.filterSuite(desc)) { 146 console.info('filter suite :' + desc); 147 return; 148 } 149 const suite = new SuiteService.Suite({description: desc}); 150 if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') { 151 let suiteStress = this.coreContext.getServices('dataDriver').dataDriver.getSuiteStress(desc); 152 for (let i = 1; i < suiteStress; i++) { 153 this.currentRunningSuite.childSuites.push(suite); 154 } 155 } 156 const currentSuiteCache = this.currentRunningSuite; 157 this.currentRunningSuite.childSuites.push(suite); 158 this.currentRunningSuite = suite; 159 func.call(); 160 this.currentRunningSuite = currentSuiteCache; 161 } 162 163 beforeAll(func) { 164 this.currentRunningSuite.beforeAll.push(processFunc(this.coreContext, func)); 165 } 166 167 beforeEach(func) { 168 this.currentRunningSuite.beforeEach.push(processFunc(this.coreContext, func)); 169 } 170 171 afterAll(func) { 172 this.currentRunningSuite.afterAll.push(processFunc(this.coreContext, func)); 173 } 174 175 afterEach(func) { 176 this.currentRunningSuite.afterEach.push(processFunc(this.coreContext, func)); 177 } 178 179 getCurrentRunningSuite() { 180 return this.currentRunningSuite; 181 } 182 183 setCurrentRunningSuite(suite) { 184 this.currentRunningSuite = suite; 185 } 186 187 getSummary() { 188 let total = 0; 189 let error = 0; 190 let failure = 0; 191 let pass = 0; 192 let ignore = 0; 193 let duration = 0; 194 let rootSuite = this.coreContext.getDefaultService('suite').rootSuite; 195 if (rootSuite && rootSuite.childSuites) { 196 for (let i = 0; i < rootSuite.childSuites.length; i++) { 197 let testsuite = rootSuite.childSuites[i]; 198 duration += testsuite.duration; 199 let specs = testsuite['specs']; 200 for (let j = 0; j < specs.length; j++) { 201 let testcase = specs[j]; 202 total++; 203 if(!testcase.isExecuted) { 204 ignore++; 205 } 206 if (testcase.error) { 207 error++; 208 } else if (testcase.result.failExpects.length > 0) { 209 failure++; 210 } else if (testcase.result.pass === true) { 211 pass++; 212 } 213 } 214 } 215 } 216 return {total: total, failure: failure, error: error, pass: pass, ignore: ignore, duration: duration}; 217 } 218 219 init(coreContext) { 220 this.coreContext = coreContext; 221 } 222 223 async dryRun(abilityDelegator) { 224 const configService = this.coreContext.getDefaultService('config'); 225 let testSuitesObj = {}; 226 let suitesArray = []; 227 for (const suiteItem of this.rootSuite.childSuites) { 228 let itArray = []; 229 let suiteName = suiteItem['description']; 230 for (const itItem of suiteItem['specs']) { 231 let itName = itItem['description']; 232 let filter = itItem['fi']; 233 if (!configService.filterDesc(suiteName, itName, filter, this.coreContext)) { 234 itArray.push({'itName': itItem['description']}); 235 } 236 } 237 if (!configService.filterSuite(suiteName) && (itArray.length > 0)) { 238 let obj = {}; 239 obj[suiteName] = itArray; 240 suitesArray.push(obj); 241 } 242 } 243 testSuitesObj['suites'] = suitesArray; 244 245 let strJson = JSON.stringify(testSuitesObj); 246 let strLen = strJson.length; 247 let maxLen = 500; 248 let maxCount = Math.floor(strLen / maxLen); 249 250 for (let count = 0; count <= maxCount; count++) { 251 await SysTestKit.print(strJson.substring(count * maxLen, (count + 1) * maxLen)); 252 } 253 console.info('dryRun print success'); 254 abilityDelegator.finishTest('dry run finished!!!', 0, () => { }); 255 } 256 257 execute() { 258 const configService = this.coreContext.getDefaultService('config'); 259 if (configService.filterValid.length !== 0) { 260 this.coreContext.fireEvents('task', 'incorrectFormat'); 261 return; 262 } 263 264 if (configService.isRandom() && this.rootSuite.childSuites.length > 0) { 265 this.rootSuite.childSuites.sort(function () { 266 return Math.random().toFixed(1) > 0.5 ? -1 : 1; 267 }); 268 this.currentRunningSuite = this.rootSuite.childSuites[0]; 269 } 270 271 if (configService.isSupportAsync()) { 272 let asyncExecute = async () => { 273 await this.coreContext.fireEvents('task', 'taskStart'); 274 await this.rootSuite.asyncRun(this.coreContext); 275 }; 276 asyncExecute().then(async () => { 277 await this.coreContext.fireEvents('task', 'taskDone'); 278 }); 279 } else { 280 this.coreContext.fireEvents('task', 'taskStart'); 281 this.rootSuite.run(this.coreContext); 282 this.coreContext.fireEvents('task', 'taskDone'); 283 } 284 } 285 286 apis() { 287 const _this = this; 288 return { 289 describe: function (desc, func) { 290 return _this.describe(desc, func); 291 }, 292 beforeAll: function (func) { 293 return _this.beforeAll(func); 294 }, 295 beforeEach: function (func) { 296 return _this.beforeEach(func); 297 }, 298 afterAll: function (func) { 299 return _this.afterAll(func); 300 }, 301 afterEach: function (func) { 302 return _this.afterEach(func); 303 } 304 }; 305 } 306} 307 308SuiteService.Suite = class { 309 constructor(attrs) { 310 this.description = attrs.description || ''; 311 this.childSuites = []; 312 this.specs = []; 313 this.beforeAll = []; 314 this.afterAll = []; 315 this.beforeEach = []; 316 this.afterEach = []; 317 this.duration = 0; 318 } 319 320 pushSpec(spec) { 321 this.specs.push(spec); 322 } 323 324 removeSpec(desc) { 325 this.specs = this.specs.filter((item, index) => { 326 return item.description !== desc; 327 }); 328 } 329 330 getSpecsNum() { 331 return this.specs.length; 332 } 333 334 isRun(coreContext) { 335 const configService = coreContext.getDefaultService('config'); 336 const suiteService = coreContext.getDefaultService('suite'); 337 const specService = coreContext.getDefaultService('spec'); 338 let breakOnError = configService.isBreakOnError(); 339 let isError = specService.getStatus(); 340 return breakOnError && isError 341 } 342 343 run(coreContext) { 344 const suiteService = coreContext.getDefaultService('suite'); 345 suiteService.setCurrentRunningSuite(this); 346 if (this.description !== '') { 347 coreContext.fireEvents('suite', 'suiteStart', this); 348 } 349 this.runHookFunc('beforeAll'); 350 if (this.specs.length > 0) { 351 const configService = coreContext.getDefaultService('config'); 352 if (configService.isRandom()) { 353 this.specs.sort(function () { 354 return Math.random().toFixed(1) > 0.5 ? -1 : 1; 355 }); 356 } 357 for (let spec in this.specs) { 358 let isBreakOnError = this.isRun(coreContext); 359 if (isBreakOnError) { 360 break; 361 } 362 this.runHookFunc('beforeEach'); 363 spec.run(coreContext); 364 this.runHookFunc('afterEach'); 365 } 366 } 367 if (this.childSuites.length > 0) { 368 for (let suite in this.childSuites) { 369 let isBreakOnError = this.isRun(coreContext); 370 if (isBreakOnError) { 371 break; 372 } 373 suite.run(coreContext); 374 suiteService.setCurrentRunningSuite(suite); 375 } 376 } 377 this.runHookFunc('afterAll'); 378 if (this.description !== '') { 379 coreContext.fireEvents('suite', 'suiteDone'); 380 } 381 } 382 383 async asyncRun(coreContext) { 384 const suiteService = coreContext.getDefaultService('suite'); 385 suiteService.setCurrentRunningSuite(this); 386 if (this.description !== '') { 387 await coreContext.fireEvents('suite', 'suiteStart', this); 388 } 389 await this.runAsyncHookFunc('beforeAll'); 390 if (this.specs.length > 0) { 391 const configService = coreContext.getDefaultService('config'); 392 if (configService.isRandom()) { 393 this.specs.sort(function () { 394 return Math.random().toFixed(1) > 0.5 ? -1 : 1; 395 }); 396 } 397 for (let i = 0; i < this.specs.length; i++) { 398 // 遇错即停模式,发现用例有问题,直接返回,不在执行后面的it 399 let isBreakOnError = this.isRun(coreContext); 400 if (isBreakOnError) { 401 console.log("break index is," + i + "description is," + this.description); 402 break; 403 } 404 await this.runAsyncHookFunc('beforeEach'); 405 await this.specs[i].asyncRun(coreContext); 406 await this.runAsyncHookFunc('afterEach'); 407 } 408 } 409 410 if (this.childSuites.length > 0) { 411 for (let i = 0; i < this.childSuites.length; i++) { 412 // 遇错即停模式, 发现用例有问题,直接返回,不在执行后面的description 413 let isBreakOnError = this.isRun(coreContext); 414 if (isBreakOnError) { 415 console.log("childSuites break description," + this.description); 416 break; 417 } 418 suiteService.setCurrentRunningSuite(this.childSuites[i]); 419 await this.childSuites[i].asyncRun(coreContext); 420 } 421 } 422 423 await this.runAsyncHookFunc('afterAll'); 424 if (this.description !== '') { 425 await coreContext.fireEvents('suite', 'suiteDone'); 426 } 427 } 428 429 runHookFunc(hookName) { 430 if (this[hookName] && this[hookName].length > 0) { 431 this[hookName].forEach(func => { 432 try { 433 func(); 434 } catch (e) { 435 console.error(e); 436 } 437 }); 438 } 439 } 440 441 runAsyncHookFunc(hookName) { 442 if (this[hookName] && this[hookName].length > 0) { 443 return new Promise(async resolve => { 444 for (let i = 0; i < this[hookName].length; i++) { 445 try { 446 await this[hookName][i](); 447 } catch (e) { 448 console.error(e); 449 } 450 } 451 resolve(); 452 }); 453 } 454 } 455}; 456 457class SpecService { 458 constructor(attr) { 459 this.id = attr.id; 460 this.totalTest = 0; 461 this.hasError = false; 462 } 463 464 init(coreContext) { 465 this.coreContext = coreContext; 466 } 467 468 setCurrentRunningSpec(spec) { 469 this.currentRunningSpec = spec; 470 } 471 472 setStatus(obj) { 473 this.hasError = obj; 474 } 475 476 getStatus() { 477 return this.hasError; 478 } 479 480 getTestTotal() { 481 return this.totalTest; 482 } 483 484 getCurrentRunningSpec() { 485 return this.currentRunningSpec; 486 } 487 488 it(desc, filter, func) { 489 const configService = this.coreContext.getDefaultService('config'); 490 const currentSuiteName = this.coreContext.getDefaultService('suite').getCurrentRunningSuite().description; 491 if (configService.filterDesc(currentSuiteName, desc, filter, this.coreContext)) { 492 console.info('filter it :' + desc); 493 } else { 494 let processedFunc = processFunc(this.coreContext, func); 495 const spec = new SpecService.Spec({description: desc, fi: filter, fn: processedFunc}); 496 const suiteService = this.coreContext.getDefaultService('suite'); 497 if (typeof this.coreContext.getServices('dataDriver') !== 'undefined' && configService['dryRun'] !== 'true') { 498 let specStress = this.coreContext.getServices('dataDriver').dataDriver.getSpecStress(desc); 499 for (let i = 1; i < specStress; i++) { 500 this.totalTest++; 501 suiteService.getCurrentRunningSuite().pushSpec(spec); 502 } 503 } 504 // dryRun 状态下不统计压力测试重复数据 505 if(configService['dryRun'] !== 'true') { 506 let stress = configService.getStress(); // 命令配置压力测试 507 console.info('stress it is,' + stress); 508 for (let i = 1; i < stress; i++) { 509 const specItem = new SpecService.Spec({description: desc, fi: filter, fn: processedFunc}); 510 this.totalTest++; 511 suiteService.getCurrentRunningSuite().pushSpec(specItem); 512 } 513 } 514 this.totalTest++; 515 suiteService.getCurrentRunningSuite().pushSpec(spec); 516 } 517 } 518 519 apis() { 520 const _this = this; 521 return { 522 it: function (desc, filter, func) { 523 return _this.it(desc, filter, func); 524 } 525 }; 526 } 527} 528 529SpecService.Spec = class { 530 constructor(attrs) { 531 this.description = attrs.description || ''; 532 this.fi = attrs.fi; 533 this.fn = attrs.fn || function () { 534 }; 535 this.result = { 536 failExpects: [], 537 passExpects: [] 538 }; 539 this.error = undefined; 540 this.duration = 0; 541 this.startTime = 0; 542 this.isExecuted = false; // 当前用例是否执行 543 } 544 545 setResult(coreContext) { 546 const specService = coreContext.getDefaultService('spec'); 547 if (this.result.failExpects.length > 0) { 548 this.result.pass = false; 549 specService.setStatus(true); 550 } else { 551 this.result.pass = true; 552 } 553 console.info('testcase ' + this.description + ' result:' + this.result.pass); 554 } 555 556 run(coreContext) { 557 const specService = coreContext.getDefaultService('spec'); 558 specService.setCurrentRunningSpec(this); 559 this.startTime = new Date().getTime(); 560 coreContext.fireEvents('spec', 'specStart', this); 561 this.isExecuted = true; 562 try { 563 let dataDriver = coreContext.getServices('dataDriver'); 564 if (typeof dataDriver === 'undefined') { 565 this.fn(); 566 } else { 567 let suiteParams = dataDriver.dataDriver.getSuiteParams(); 568 let specParams = dataDriver.dataDriver.getSpecParams(); 569 console.info('[suite params] ' + JSON.stringify(suiteParams)); 570 console.info('[spec params] ' + JSON.stringify(specParams)); 571 if (this.fn.length === 0) { 572 this.fn(); 573 } else if (specParams.length === 0) { 574 this.fn(suiteParams); 575 } else { 576 specParams.forEach(paramItem => this.fn(Object.assign({}, paramItem, suiteParams))); 577 } 578 } 579 this.setResult(coreContext); 580 } catch (e) { 581 this.error = e; 582 specService.setStatus(true); 583 } 584 coreContext.fireEvents('spec', 'specDone', this); 585 } 586 587 async asyncRun(coreContext) { 588 const specService = coreContext.getDefaultService('spec'); 589 specService.setCurrentRunningSpec(this); 590 591 await coreContext.fireEvents('spec', 'specStart', this); 592 try { 593 let dataDriver = coreContext.getServices('dataDriver'); 594 if (typeof dataDriver === 'undefined') { 595 await this.fn(); 596 this.setResult(coreContext); 597 } else { 598 let suiteParams = dataDriver.dataDriver.getSuiteParams(); 599 let specParams = dataDriver.dataDriver.getSpecParams(); 600 console.info('[suite params] ' + JSON.stringify(suiteParams)); 601 console.info('[spec params] ' + JSON.stringify(specParams)); 602 if (this.fn.length === 0) { 603 await this.fn(); 604 this.setResult(coreContext); 605 } else if (specParams.length === 0) { 606 await this.fn(suiteParams); 607 this.setResult(coreContext); 608 } else { 609 for (const paramItem of specParams) { 610 await this.fn(Object.assign({}, paramItem, suiteParams)); 611 this.setResult(coreContext); 612 } 613 } 614 } 615 } catch (e) { 616 if (e instanceof AssertException) { 617 this.fail = e; 618 specService.setStatus(true); 619 } else { 620 this.error = e; 621 specService.setStatus(true); 622 } 623 } 624 this.isExecuted = true; 625 await coreContext.fireEvents('spec', 'specDone', this); 626 } 627 628 filterCheck(coreContext) { 629 const specService = coreContext.getDefaultService('spec'); 630 specService.setCurrentRunningSpec(this); 631 return true; 632 } 633 634 addExpectationResult(expectResult) { 635 if (this.result.failExpects.length === 0) { 636 this.result.failExpects.push(expectResult); 637 } 638 throw new AssertException(expectResult.message); 639 } 640}; 641 642class ExpectService { 643 constructor(attr) { 644 this.id = attr.id; 645 this.matchers = {}; 646 } 647 648 expect(actualValue) { 649 return this.wrapMatchers(actualValue); 650 } 651 652 init(coreContext) { 653 this.coreContext = coreContext; 654 this.addMatchers(this.basicMatchers()); 655 } 656 657 addMatchers(matchers) { 658 for (const matcherName in matchers) { 659 if (Object.prototype.hasOwnProperty.call(matchers, matcherName)) { 660 this.matchers[matcherName] = matchers[matcherName]; 661 } 662 } 663 } 664 665 basicMatchers() { 666 return { 667 assertTrue: function (actualValue) { 668 return { 669 pass: (actualValue) === true, 670 message: 'expect true, actualValue is ' + actualValue 671 }; 672 }, 673 assertEqual: function (actualValue, args) { 674 return { 675 pass: (actualValue) === args[0], 676 expectValue: args[0], 677 message: 'expect ' + actualValue + ' equals ' + args[0] 678 }; 679 }, 680 assertThrow: function (actual, args) { 681 const result = { 682 pass: false 683 }; 684 if (typeof actual !== 'function') { 685 result.message = 'toThrow\'s Actual should be a Function'; 686 } else { 687 let hasThrow = false; 688 let throwError; 689 try { 690 actual(); 691 } catch (e) { 692 hasThrow = true; 693 throwError = e; 694 } 695 if (!hasThrow) { 696 result.message = 'function did not throw an exception'; 697 } else if (throwError && throwError.message === args[0]) { 698 result.pass = true; 699 } else { 700 result.message = `expect to throw ${args[0]} , actual throw ${throwError.message}`; 701 } 702 } 703 return result; 704 } 705 }; 706 } 707 708 wrapMatchers(actualValue) { 709 const _this = this; 710 const wrappedMatchers = {}; 711 const specService = _this.coreContext.getDefaultService('spec'); 712 const currentRunningSpec = specService.getCurrentRunningSpec(); 713 for (const matcherName in this.matchers) { 714 if (Object.prototype.hasOwnProperty.call(this.matchers, matcherName)) { 715 wrappedMatchers[matcherName] = function () { 716 const result = _this.matchers[matcherName](actualValue, arguments); 717 result.actualValue = actualValue; 718 result.checkFunc = matcherName; 719 if (!result.pass) { 720 currentRunningSpec.addExpectationResult(result); 721 } 722 }; 723 } 724 } 725 return wrappedMatchers; 726 } 727 728 apis() { 729 const _this = this; 730 return { 731 expect: function (actualValue) { 732 return _this.expect(actualValue); 733 } 734 }; 735 } 736} 737 738class ReportService { 739 constructor(attr) { 740 this.id = attr.id; 741 } 742 743 init(coreContext) { 744 this.coreContext = coreContext; 745 this.specService = this.coreContext.getDefaultService('spec'); 746 this.suiteService = this.coreContext.getDefaultService('suite'); 747 this.duration = 0; 748 } 749 750 taskStart() { 751 console.info('[start] start run suites'); 752 } 753 754 async suiteStart() { 755 console.info('[suite start]' + this.suiteService.getCurrentRunningSuite().description); 756 } 757 758 async specStart() { 759 console.info('start running case \'' + this.specService.currentRunningSpec.description + '\''); 760 this.index = this.index + 1; 761 let spec = this.specService.currentRunningSpec; 762 spec.startTime = await SysTestKit.getRealTime(); 763 } 764 765 async specDone() { 766 let msg = ''; 767 let spec = this.specService.currentRunningSpec; 768 let suite = this.suiteService.currentRunningSuite; 769 spec.duration = await SysTestKit.getRealTime() - spec.startTime; 770 suite.duration += spec.duration; 771 if (spec.error) { 772 this.formatPrint('error', spec.description + ' ; consuming ' + spec.duration + 'ms'); 773 this.formatPrint('errorDetail', spec.error); 774 } else if (spec.result) { 775 if (spec.result.failExpects.length > 0) { 776 this.formatPrint('fail', spec.description + ' ; consuming ' + spec.duration + 'ms'); 777 spec.result.failExpects.forEach(failExpect => { 778 msg = failExpect.message || ('expect ' + failExpect.actualValue + ' ' 779 + failExpect.checkFunc + ' ' + (failExpect.expectValue)); 780 this.formatPrint('failDetail', msg); 781 }); 782 } else { 783 this.formatPrint('pass', spec.description + ' ; consuming ' + spec.duration + 'ms'); 784 } 785 } 786 this.formatPrint(this.specService.currentRunningSpec.error, msg); 787 } 788 789 suiteDone() { 790 let suite = this.suiteService.currentRunningSuite; 791 console.info('[suite end]' + ' consuming ' + suite.duration + 'ms'); 792 } 793 794 taskDone() { 795 let msg = ''; 796 let summary = this.suiteService.getSummary(); 797 msg = 'total cases:' + summary.total + ';failure ' + summary.failure + ',' + 'error ' + summary.error; 798 msg += ',pass ' + summary.pass + '; consuming ' + summary.duration + 'ms'; 799 console.info(msg); 800 console.info('[end] run suites end'); 801 } 802 803 incorrectFormat() { 804 if (this.coreContext.getDefaultService('config').filterValid.length !== 0) { 805 this.coreContext.getDefaultService('config').filterValid.forEach(function (item) { 806 console.info('this param ' + item + ' is invalid'); 807 }); 808 } 809 } 810 811 formatPrint(type, msg) { 812 switch (type) { 813 case 'pass': 814 console.info('[pass]' + msg); 815 break; 816 case 'fail': 817 console.info('[fail]' + msg); 818 break; 819 case 'failDetail': 820 console.info('[failDetail]' + msg); 821 break; 822 case 'error': 823 console.info('[error]' + msg); 824 break; 825 case 'errorDetail': 826 console.info('[errorDetail]' + msg); 827 break; 828 } 829 } 830 831 sleep(numberMillis) { 832 var now = new Date(); 833 var exitTime = now.getTime() + numberMillis; 834 while (true) { 835 now = new Date(); 836 if (now.getTime() > exitTime) { 837 return; 838 } 839 } 840 } 841} 842 843export { 844 SuiteService, 845 SpecService, 846 ExpectService, 847 ReportService 848}; 849