• 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
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