Merge "Add test-scheduler dir to verity"
[bottlenecks.git] / testing-scheduler / ui / src / components / testcase.vue
1 <template>\r
2   <div class="wrapper wrapper-content animated fadeIn">\r
3     <div class="row" style="margin-bottom: 20px;">\r
4       <div class="col-md-8">\r
5         <ol class="breadcrumb" style="padding-left: 20px; font-size: 17px;">\r
6           <li>\r
7             <router-link to="/" >root</router-link>\r
8           </li>\r
9           <li>\r
10             <router-link :to="{ path: '/testcase', query: { name: sname }}"><b>{{this.$route.query.name}}</b></router-link>\r
11           </li>\r
12         </ol>\r
13       </div>\r
14     </div>\r
15     <div id="page-content" style="" class="row">\r
16         <div class="col-lg-8">\r
17             <div class="ibox">\r
18                 <div class="ibox-title">\r
19                     <h5 style="font-size:26px;margin-top: -3px;">Test Case</h5>\r
20                     <div class="ibox-tools">\r
21                     <button class="btn btn-info btn-sm my-button-sm" type="button" v-on:click="runMultiTestcase()">Run</button>\r
22                     <button class="btn btn-success btn-sm my-button-sm" type="button" v-on:click="create()">Create</button>\r
23                     <button class="btn btn-danger btn-sm my-button-sm" v-on:click="deleteCases()" type="button">Delete</button>\r
24                     <a class="collapse-link">\r
25                         <i class="fa fa-chevron-up"></i>\r
26                     </a>\r
27                     <a class="fullscreen-link">\r
28                         <i class="fa fa-expand"></i>\r
29                     </a>\r
30                     </div>\r
31                 </div>\r
32                 <div class="ibox-content" style="text-align:center;">\r
33                 <table class="my-table table table-bordered" cellspacing="0" cellpadding="0" style="text-align: center;">\r
34                     <thead>\r
35                         <tr>\r
36                               <td class="checkbox1" style="width:20px"><input type="checkbox" v-model="selectAll"> All</td>\r
37                               <td class="smallbox" style="with:250px;">TestCase Name</td>\r
38                         </tr>\r
39                     </thead>\r
40                     <tbody>\r
41                         <tr v-for="testcase in testcases">\r
42                           <td><input class="checkbox1" style="width:20px" type="checkbox" v-model="selected" :value="testcase.testcase"> </td>\r
43                           <td class="smallbox" style="with:250px;"><router-link :to="{ path: '/content', query: { suiteName: sname, caseName: testcase.testcase } }">{{testcase.testcase}}</router-link></td>\r
44                         </tr>\r
45                     </tbody>\r
46                     <tfoot id="create-box" style="display: none">\r
47                         <tr>\r
48                             <td class="checkbox1" style="width:20px"><input type="checkbox"> </td>\r
49                             <td class="smallbox" style="with:250px;"><input type="text" v-model="newCase" @keydown.enter="additem" ></td>\r
50                         </tr>\r
51                     </tfoot>\r
52                   </table>\r
53                 </div>\r
54             </div>\r
55         </div>\r
56     </div>\r
57     <hr />\r
58     <div class="row">\r
59       <div class="col-lg-12">\r
60           <div class="ibox">\r
61               <div class="ibox-title">\r
62                   <h5 style="font-size:26px;margin-top: -3px;">Workflow</h5>\r
63                   <div class="ibox-tools">\r
64                       <a class="collapse-link">\r
65                           <i class="fa fa-chevron-up"></i>\r
66                       </a>\r
67                       <a class="fullscreen-link">\r
68                           <i class="fa fa-expand"></i>\r
69                       </a>\r
70                   </div>\r
71               </div>\r
72               <div class="ibox-content" style="padding-top: 30px;">\r
73                 <div id="executing" class="row" style="padding: 0 30px 60px;">\r
74                     <div class="col-md-offset-2 col-md-8">\r
75                       <div class="table-responsive">\r
76                         <table class="table text-center" style="margin-top: 30px;">\r
77                           <thead>\r
78                             <tr>\r
79                               <th class="text-center">#</th>\r
80                               <th class="text-center">testcase</th>\r
81                               <th class="text-center">status</th>\r
82                               <th class="text-center">operation</th>\r
83                             </tr>\r
84                           </thead>\r
85                           <tbody>\r
86                             <tr v-for="testcase in runTestcases">\r
87                               <td>{{ testcase.id }}</td>\r
88                               <td>{{ testcase.testcase }}</td>\r
89                               <td><span class="badge" v-bind:class="'badge-' + statusClass(testcase.status)">{{ testcase.status }}</span></td>\r
90                               <td>\r
91                                 <div style="display: inline-block;min-width: 130px;">\r
92                                   <button class="btn btn-primary btn-outline btn-xs fadeIn" v-on:click="runTestcase()" v-show="testcase.status == 'failed'">rerun</button>\r
93                                   <button class="btn btn-primary btn-outline btn-xs fadeIn" v-on:click="runNextCase($event.target)" v-show="testcase.status == 'failed'">run next one</button>\r
94                                 </div>\r
95                               </td>\r
96                             </tr>\r
97                           </tbody>\r
98                         </table>\r
99                       </div>\r
100                     </div>\r
101                 </div>\r
102                 <hr class="hr-line-solid">\r
103                 <div class="row" style="margin-top: 60px;">\r
104                   <wfresult v-bind:workflowId="workflowId" v-bind:wfloading='wfloading' v-bind:wfJson='wfJson' v-on:wfComplete="wfComplete = $event"></wfresult>\r
105                 </div>\r
106               </div>\r
107           </div>\r
108       </div>\r
109     </div>\r
110   </div>\r
111 </template>\r
112 <script>\r
113 import wfresult from './workflow_graph/wfresult.vue'\r
114 import showMessage from './message/showMessage.js'\r
115 export default {\r
116   name: 'testcase',\r
117   data () {\r
118     return {\r
119       testcases: [],\r
120       sname: this.$route.query.name,\r
121       newCase:'',\r
122       addstory:'',\r
123       workflowId: '',\r
124       wfloading: false,\r
125       wfJson: '',\r
126       selected: [],\r
127       curRunningId: 0,\r
128       runTestcases: [],\r
129       wfComplete: false\r
130     }\r
131   },\r
132   created: function() {\r
133     var self = this;\r
134     var msgTitle = "GET -- TESTCASES";\r
135     var errorInfo = "Failed to get testcase list.";\r
136     $.ajax({\r
137       url: this.global.SERVER_ADDR + "testsuite/content",\r
138       method:"GET",\r
139       data:{\r
140         suiteName:  this.$route.query.name\r
141       },\r
142       success:function (data) {\r
143         if(data['code'] == 200) {\r
144           self.testcases = data['result'];\r
145         } else {\r
146           showMessage(data['code'], msgTitle, errorInfo, data['error']);\r
147         }\r
148       },\r
149       error: function(obj, status, msg) {\r
150         showMessage(status, msgTitle, errorInfo, msg);\r
151       }\r
152     });\r
153   },\r
154   computed: {\r
155     selectAll: {\r
156       get: function () {\r
157         return this.testcases ? this.selected.length == this.testcases.length : false;\r
158       },\r
159       set: function (value) {\r
160         var selected = [];\r
161         if (value) {\r
162           this.testcases.forEach(function (testcase) {\r
163             selected.push(testcase.testcase);\r
164           });\r
165         }\r
166         this.selected = selected;\r
167       }\r
168     }\r
169   },\r
170   methods:{\r
171     create: function () {\r
172       var cbox = document.getElementById("create-box");\r
173       cbox.style.display = "table-footer-group";\r
174     },\r
175     additem: function () {\r
176       var self = this;\r
177       var msgTitle = "CREATE -- TESTCASE";\r
178       const caseName = self.newCase.trim();\r
179       if(caseName)\r
180       {\r
181         $.ajax({\r
182           url: this.global.SERVER_ADDR + "testcase/new",\r
183           method:"POST",\r
184           data:{\r
185             suiteName: self.sname,\r
186             caseName: caseName\r
187           },\r
188           success:function (data) {\r
189             if(data['code'] == 200){\r
190               self.testcases.push({\r
191                 id: self.testcases.length + 1 ,\r
192                 testcase: caseName,\r
193               });\r
194               showMessage(data['code'], msgTitle, "Create <strong>" + caseName + "</strong> succesfully!");\r
195             } else {\r
196               showMessage(data['code'], msgTitle, "Failed to create <strong>" + caseName + "</strong>!", data['error']);\r
197             }\r
198           },\r
199           error: function(obj, status, msg) {\r
200             showMessage(status, msgTitle, "Failed to create <strong>" + caseName + "</strong>!", msg);\r
201           }\r
202         });\r
203       }\r
204       var cbox = document.getElementById("create-box");\r
205       cbox.style.display = "none";\r
206       this.newCase = '';\r
207     },\r
208     deleteCases:function () {\r
209       var self = this;\r
210       var msgTitle = "DELETE -- TESTCASE";\r
211       var deleteArr = self.selected.slice(0);\r
212       self.testcases = self.testcases.filter(item => {\r
213           for(var i in deleteArr) {\r
214             if(item.testcase == deleteArr[i]) {\r
215               return false;\r
216             }\r
217           }\r
218           return true;\r
219       });\r
220       self.selected = [];\r
221       for(var i in deleteArr)\r
222       {\r
223         $.ajax({\r
224           url: this.global.SERVER_ADDR + "testcase/delete",\r
225           method: "POST",\r
226           data: {\r
227             suiteName: self.sname,\r
228             caseName: deleteArr[i]\r
229           },\r
230           success: function(data) {\r
231             if(data['code'] == 200){\r
232               showMessage(data['code'], msgTitle, "Delete <strong>" + deleteArr[i] + "</strong> succesfully!");\r
233             } else {\r
234               showMessage(data['code'], msgTitle, "Failed to delete <strong>" + deleteArr[i] + "</strong>!", data['error']);\r
235             }\r
236           },\r
237           error: function(obj, status, msg) {\r
238             showMessage(status, msgTitle, "Failed to delete <strong>" + deleteArr[i] + "</strong>!", msg);\r
239           }\r
240         });\r
241       }\r
242     },\r
243     runMultiTestcase: function() {\r
244       var self = this;\r
245       var msgTitle = "RUN -- TESTCASES";\r
246       self.runTestcases = [];\r
247       if(self.selected.length == 0) {\r
248         showMessage("warning", msgTitle, "please select one!");\r
249         return;\r
250       }\r
251       for(var i=0; i < self.selected.length; i++) {\r
252         var testcaseItem = {'id': i, 'testcase': '', 'status': "waiting"};\r
253         testcaseItem['testcase'] = self.selected[i];\r
254         self.runTestcases.push(testcaseItem);\r
255       }\r
256       self.curRunningId = 0;\r
257       showMessage("info", msgTitle, "start to run <strong>testcases</strong>");\r
258       self.runOneTestcase();\r
259     },\r
260     runOneTestcase: function() {\r
261       var self = this;\r
262       var msgTitle = "RUN -- TESTCASE";\r
263       if (self.curRunningId == self.runTestcases.length) {\r
264         self.curRunningId = 0;\r
265         return;\r
266       }\r
267       self.wfComplete = false;\r
268       var i = self.curRunningId;\r
269       self.runTestcases[i]['status'] = "running";\r
270       $.ajax({\r
271           url: self.global.SERVER_ADDR + "execute/testcase",\r
272           method: "POST",\r
273           data: {\r
274               "suiteName": self.sname,\r
275               "caseName": self.runTestcases[self.curRunningId]['testcase']\r
276           },\r
277           beforeSend: function(XHR) {\r
278               self.wfloading = true;\r
279           },\r
280           success: function(data) {\r
281               if(data['code'] == 200) {\r
282                   self.workflowId = data['result']['workflowId'];\r
283                   $.ajax({\r
284                       url: self.global.SERVER_ADDR + "story-content",\r
285                       method: "GET",\r
286                       data: {\r
287                           "service":  self.sname,\r
288                           "story": self.runTestcases[self.curRunningId]['testcase']\r
289                       },\r
290                       success: function(data) {\r
291                           if(data['code'] == 200) {\r
292                               self.wfJson = data['result']['content'];\r
293                           } else {\r
294                             showMessage(data['code'], msgTitle, "workflow.json get failed!");\r
295                           }\r
296                       },\r
297                       error: function(obj, status, msg) {\r
298                         showMessage(status, msgTitle, msg);\r
299                       }\r
300                   });\r
301               } else {\r
302                 var i = self.curRunningId;\r
303                 self.runTestcases[i]['status'] = "failed";\r
304                 self.wfloading = false;\r
305                 showMessage(data['code'], msgTitle, "Failed to run <strong>" + self.runTestcases[i]['testcase'] + "</strong>", data['error']);\r
306               }\r
307           },\r
308           error: function(obj, status, msg) {\r
309             var i = self.curRunningId;\r
310             self.runTestcases[i]['status'] = "failed";\r
311             self.wfloading = false;\r
312             showMessage(status, msgTitle, "Failed to run <strong>" + self.runTestcases[i]['testcase'] + "</strong>", msg);\r
313           }\r
314       });\r
315     },\r
316     statusClass: function(status) {\r
317       if(status == "waiting") {\r
318         return "success";\r
319       }\r
320       if(status == "running") {\r
321         return "warning";\r
322       }\r
323       if(status == "pass") {\r
324         return "primary";\r
325       }\r
326       if(status == "failed") {\r
327         return "danger";\r
328       }\r
329     },\r
330     runNextCase: function(obj) {\r
331       $(obj).parent().css({"display": "none"});\r
332       var i = this.curRunningId++;\r
333       this.runOneTestcase();\r
334     }\r
335   },\r
336   watch: {\r
337     wfComplete: function(val) {\r
338       if(val == false) return;\r
339       this.wfloading = false;\r
340       var i = this.curRunningId++;\r
341       this.runTestcases[i]['status'] = "pass";\r
342       this.runOneTestcase();\r
343     }\r
344   },\r
345   components: {\r
346     wfresult\r
347   }\r
348 }\r
349 </script>