1 | "use strict";
|
2 |
|
3 | const Promise = require('bluebird');
|
4 | const _ = require('lodash');
|
5 |
|
6 | const reporter = require("../reports/reporter");
|
7 | const servicesApi = require('../commons/testimServicesApi');
|
8 | const BaseTestPlanRunner = require('./BaseTestPlanRunner');
|
9 | const { ArgError } = require('../errors');
|
10 | const Logger = require('../commons/logger');
|
11 | const logger = Logger.getLogger('test-plan-runner');
|
12 |
|
13 | class TestPlanRunner extends BaseTestPlanRunner {
|
14 | calcTestResultStatus(tests) {
|
15 | const total = Object.keys(tests).length;
|
16 | const passed = Object.keys(tests).reduce((count, resultId) => count + (tests[resultId].success === true ? 1 : 0), 0);
|
17 | return total === passed;
|
18 | }
|
19 |
|
20 | runTestPlans(options, branchToUse) {
|
21 | logger.info("start to run test plan", {
|
22 | options: Object.assign({}, options, {token: undefined, userParamsData: undefined}),
|
23 | branchToUse
|
24 | });
|
25 |
|
26 | function flattenTestListData(testPlansData) {
|
27 | return _.flattenDeep(Object.keys(testPlansData).map(tpId => testPlansData[tpId])).reduce((all, testRun) => _.concat(all, testRun.beforeTests, testRun.tests, testRun.afterTests), []);
|
28 | }
|
29 |
|
30 | const testPlansResults = {};
|
31 | const testPlansTests = {};
|
32 | const projectId = options.project;
|
33 |
|
34 | return this.prepareForTestResources(options)
|
35 | .then(() => servicesApi.getTestPlanTestList(projectId, options.testPlan, branchToUse))
|
36 | .then(data => {
|
37 | const testPlans = data.testPlans;
|
38 | const testPlansData = data.testPlansData;
|
39 | if (!testPlans || testPlans.length === 0) {
|
40 | return Promise.reject(new ArgError("no test plan to run " + options.testPlan));
|
41 | }
|
42 | if (!testPlansData || Object.keys(testPlansData).length === 0) {
|
43 | return Promise.reject(new ArgError("no test to run in test plan " + options.testPlan));
|
44 | }
|
45 | return this.validateConfig(options, flattenTestListData(testPlansData))
|
46 | .then(() => {
|
47 | return Promise.map(testPlans, testPlan => {
|
48 | let id = testPlan.testPlanId;
|
49 | testPlansResults[id] = {};
|
50 |
|
51 | const tpOptions = Object.assign({}, options);
|
52 | tpOptions.baseUrl = options.baseUrl || testPlan.startUrl;
|
53 | tpOptions.host = options.host || testPlan.host;
|
54 | tpOptions.port = options.port || testPlan.port;
|
55 | tpOptions.gridId = options.gridId || testPlan.gridId;
|
56 |
|
57 | if (options.gridId) {
|
58 | delete tpOptions.host;
|
59 | delete tpOptions.port;
|
60 | }
|
61 |
|
62 |
|
63 | if (options.grid) {
|
64 | delete tpOptions.host;
|
65 | delete tpOptions.port;
|
66 | delete tpOptions.gridId;
|
67 | }
|
68 |
|
69 | const testPlanName = tpOptions.overrideExecutionName || testPlan.name;
|
70 |
|
71 | return Promise.map(testPlansData[id], testPlanTests => {
|
72 | return this.runTestPlan(testPlanTests.beforeTests, testPlanTests.tests, testPlanTests.afterTests, tpOptions, testPlanName, branchToUse)
|
73 | .tap(res => {
|
74 | const isCodeMode = options.files.length > 0;
|
75 | reporter.onTestPlanFinished(res.results, testPlan.name, this.startTime, res.executionId, false, isCodeMode, res.childTestResults);
|
76 | testPlansResults[id][res.executionId] = res.results;
|
77 | });
|
78 | }).tap(() => {
|
79 | const executions = Object.keys(testPlansResults[id]).map(exeId => {
|
80 | return {
|
81 | executionId: exeId,
|
82 | status: this.calcTestResultStatus(testPlansResults[id][exeId])
|
83 | };
|
84 | });
|
85 | let tests = Object.keys(testPlansResults[id]).map(exeId => testPlansResults[id][exeId]).reduce((testResult, test) => Object.assign(testResult, test), {});
|
86 | let success = this.calcTestResultStatus(tests);
|
87 | Object.assign(testPlansTests, tests);
|
88 | const executionId = success ? executions[0].executionId : executions.find(exec => !exec.success).executionId;
|
89 | return servicesApi.saveTestPlanResult(projectId, id, {
|
90 | success: success,
|
91 | executions: executions,
|
92 | executionId: executionId
|
93 | });
|
94 | });
|
95 | });
|
96 | });
|
97 | }).then(async results => {
|
98 | const flattenResults = _(results).flattenDeep().value();
|
99 | await reporter.onAllTestPlansFinished(flattenResults);
|
100 | return flattenResults.map(res => res.results).reduce((total, cur) => Object.assign(total, cur), {});
|
101 | });
|
102 | }
|
103 | }
|
104 |
|
105 | module.exports = TestPlanRunner;
|