Merge lp:~canonical-platform-qa/qakit/initial-dashboard into lp:qakit

Proposed by Sergio Cazzolato
Status: Approved
Approved by: Sergio Cazzolato
Approved revision: 54
Proposed branch: lp:~canonical-platform-qa/qakit/initial-dashboard
Merge into: lp:qakit
Prerequisite: lp:~allanlesage/qakit/initial-dashboard
Diff against target: 572 lines (+234/-77)
11 files modified
qakit/dashboard/css/kpi.css (+4/-0)
qakit/dashboard/css/sidebar-collapse.css (+1/-1)
qakit/dashboard/index.html (+89/-57)
qakit/dashboard/js/appstartup.js (+31/-0)
qakit/dashboard/js/kpi.js (+20/-4)
qakit/dashboard/js/landing-failures.js (+7/-2)
qakit/dashboard/js/landings.js (+7/-2)
qakit/dashboard/js/main.js (+52/-0)
qakit/dashboard/js/test-execution.js (+7/-2)
qakit/dashboard/js/test-library.js (+7/-2)
qakit/dashboard/js/test-plans.js (+9/-7)
To merge this branch: bzr merge lp:~canonical-platform-qa/qakit/initial-dashboard
Reviewer Review Type Date Requested Status
Canonical Platform QA Team Pending
Review via email: mp+285805@code.launchpad.net

This proposal supersedes a proposal from 2016-02-11.

This proposal has been superseded by a proposal from 2016-02-12.

Commit message

Initial Dashboard including appstartup section.

To post a comment you must log in.
Revision history for this message
Sergio Cazzolato (sergio-j-cazzolato) wrote :

To test this branch it is required to create a the dir qakit/dashboard/data and copy some source json files inside.

To validate the appstartup part, it is required to copy all the appstartup graphs to the data dir. Appstartup json file can be generated with the branch lp:~canonical-platform-qa/qakit/app_startup_poc

52. By Sergio Cazzolato

Adding missing files

53. By Sergio Cazzolato

Adding new info to the appstartup graph

54. By Sergio Cazzolato

Merge from trunk

Unmerged revisions

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'qakit/dashboard/css/kpi.css'
2--- qakit/dashboard/css/kpi.css 2016-02-12 17:25:40 +0000
3+++ qakit/dashboard/css/kpi.css 2016-02-12 17:25:40 +0000
4@@ -26,3 +26,7 @@
5 margin-right: 5px;
6 list-style-type: none !important;
7 }
8+
9+.app-startup-elem {
10+ text-align: center;
11+}
12
13=== modified file 'qakit/dashboard/css/sidebar-collapse.css'
14--- qakit/dashboard/css/sidebar-collapse.css 2016-02-12 17:25:40 +0000
15+++ qakit/dashboard/css/sidebar-collapse.css 2016-02-12 17:25:40 +0000
16@@ -89,7 +89,7 @@
17 }
18
19 .sidebar-links div.selected ul.sub-links {
20- max-height: 150px;
21+ max-height: 500px;
22 padding: 12px 0 12px 30px;
23 }
24
25
26=== modified file 'qakit/dashboard/index.html'
27--- qakit/dashboard/index.html 2016-02-12 17:25:40 +0000
28+++ qakit/dashboard/index.html 2016-02-12 17:25:40 +0000
29@@ -19,12 +19,15 @@
30 <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.3.5/js/bootstrap.min.js"></script>
31 <script type="text/javascript" src="https://cdn.datatables.net/s/bs/dt-1.10.10,b-1.1.0,fh-3.1.0,r-2.0.0/datatables.min.js"></script>
32 <script src="https://cdnjs.cloudflare.com/ajax/libs/mustache.js/2.2.1/mustache.min.js"></script>
33- <script src="js/kpi.js"></script>
34- <script src="js/test-library.js"></script>
35- <script src="js/test-execution.js"></script>
36- <script src="js/landings.js"></script>
37- <script src="js/test-plans.js"></script>
38- <script src="js/landing-failures.js"></script>
39+ <script src="js/main.js"></script>
40+ <script src="js/kpi.js"></script>
41+ <script src="js/landings.js"></script>
42+ <script src="js/landing-failures.js"></script>
43+ <script src="js/test-execution.js"></script>
44+ <script src="js/test-library.js"></script>
45+ <script src="js/test-plans.js"></script>
46+ <script src="js/appstartup.js"></script>
47+
48 <style type="text/css">
49 .bs-example{
50 margin: 20px;
51@@ -35,33 +38,44 @@
52 <aside class="sidebar-left-collapse">
53 <a href="#" class="company-logo">UES QA</a>
54 <div class="sidebar-links">
55- <div class="link-orange selected">
56+ <div id="dashboard-link" class="link-orange selected">
57 <a href="#">
58 <i class="fa fa-tachometer"></i>Dashboard
59 </a>
60 <ul class="sub-links">
61- <li><a href="#"></a></li>
62+ <li><a></a></li>
63 </ul>
64 </div>
65- <div id="test-execution" class="link-blue">
66- <a href="#">
67+ <div id="test-metrics-link" class="link-blue">
68+ <a>
69 <i class="fa fa-bar-chart"></i>Metrics
70 </a>
71 <ul class="sub-links">
72- <li id="test-library"><a href="#test-library">Test Library</a></li>
73- <li id="test-execution"><a href="#test-execution">Test Execution</a></li>
74- <li id="landings"><a href="#landings">Landings</a></li>
75- <li id="landing-failures"><a href="#landing-failures">Defects</a></li>
76+ <li id="test-library-link"><a href="#test-library-section">Test Library</a></li>
77+ <li id="test-execution-link"><a href="#test-execution-section">Test Execution</a></li>
78+ <li id="landings-link"><a href="#landings-section">Landings</a></li>
79+ <li id="landing-failures-link"><a href="#landing-failures-section">Defects</a></li>
80 </ul>
81 </div>
82 <div class="link-red">
83- <a href="#test-plans">
84+ <a id="test-plans-link" href="#test-plans-section">
85 <i class="fa fa-list-ol"></i>Test Plans
86 </a>
87 <ul class="sub-links">
88 </ul>
89 </div>
90- <div class="link-yellow">
91+ <div id="tests-link" class="link-yellow">
92+ <a>
93+ <i class="fa fa-keyboard-o"></i>Tests
94+ </a>
95+ <ul class="sub-links">
96+ <li id="applications-manual-link"><a href="#applications-manual-section">Manual by application</a></li>
97+ <li id="applications-automated-link"><a href="#applications-automated-section">Automated by application</a></li>
98+ <li id="domains-manual-link"><a href="#domains-manual-section">Manual by domain</a></li>
99+ <li id="domains-automated-link"><a href="#domains-automated-section">Automated by domain</a></li>
100+ </ul>
101+ </div>
102+ <div id="projects-link" class="link-yellow">
103 <a href="#">
104 <i class="fa fa-keyboard-o"></i>Projects
105 </a>
106@@ -72,7 +86,7 @@
107 <li><a href="#">Link 4</a></li>
108 </ul>
109 </div>
110- <div class="link-green">
111+ <div id="links-link" class="link-green">
112 <a href="#">
113 <i class="fa fa-book"></i>Links
114 </a>
115@@ -83,9 +97,16 @@
116 <li><a href="#">Link 4</a></li>
117 </ul>
118 </div>
119+ <div class="link-blue" id="app-startup-link">
120+ <a href="#app-startup-section">
121+ <i class="fa fa-tachometer"></i>App Startup
122+ </a>
123+ <ul id="app-startup-sublinks" class="sub-links">
124+ </ul>
125+ </div>
126 </div>
127 </aside>
128- <div class="main-content">
129+ <div id="main-content" class="main-content">
130
131 <div id="test-plan-modal" class="modal fade" role="dialog">
132 <div class="modal-dialog modal-lg">
133@@ -147,8 +168,7 @@
134 </div>
135 </div>
136 </script>
137-
138- <div id="test-library" class="content-section">
139+ <div id="test-library-section" class="content-section">
140 <div class="panel panel-default">
141 <div class="panel-heading"><h1>Test Library</h1></div>
142 <div class="panel-body">
143@@ -174,7 +194,7 @@
144 </div>
145 </div> <!-- test-library-section -->
146
147- <div id="test-execution" class="content-section">
148+ <div id="test-execution-section" class="content-section">
149 <div class="panel panel-default">
150 <div class="panel-heading"><h1>Test Execution</h1></div>
151 <div class="panel-body">
152@@ -200,7 +220,7 @@
153 </div>
154 </div> <!-- test-execution-section -->
155
156- <div id="landings" class="content-section">
157+ <div id="landings-section" class="content-section">
158 <div class="panel panel-default">
159 <div class="panel-heading"><h1>Landings</h1></div>
160 <div class="panel-body">
161@@ -215,14 +235,14 @@
162 <div id="siloPassRatePerWeekChartCanvasLegend" class="line-legend"></div>
163 <canvas id="siloPassRatePerWeekChartCanvas" height="600" width="800"></canvas>
164 </div>
165- <div class="col-md-12">
166+ <div class="col-md-12">a
167 <table id="landingsTable" class="table table-striped table-bordered"></table>
168 </div>
169 </div>
170 </div>
171 </div> <!-- landings-section -->
172
173- <div id="landing-failures" class="content-section">
174+ <div id="landing-failures-section" class="content-section">
175 <div class="panel panel-default">
176 <div class="panel-heading"><h1>Landing Failures</h1></div>
177 <div class="panel-body">
178@@ -234,7 +254,7 @@
179 </div>
180 </div> <!-- landing-failures-section -->
181
182- <div id="test-plans" class="content-section">
183+ <div id="test-plans-section" class="content-section">
184 <div class="panel panel-default">
185 <div class="panel-heading"><h1>Test Plans</h1></div>
186 <div class="panel-body">
187@@ -242,28 +262,60 @@
188 </div>
189 </div>
190 </div>
191-
192- <div id="applications" class="content-section">
193- <div class="panel panel-default">
194- <div class="panel-heading"><h1>Tests by Application</h1></div>
195+
196+ <div id="app-startup-section" class="content-section">
197+ <div class="panel panel-default">
198+ <div class="panel-heading"><h1>App Startup Report</h1></div>
199+ <div class="panel-body">
200+ <div class="well well-sm">
201+ <h3 id="app-startup-device"></h3>
202+ <h3 id="app-startup-channel"></h3>
203+ <h3 id="app-startup-build-number"></h3>
204+ <p><font color="blue">Cold</font> runs are test executions with no cache for the current app.</p>
205+ <p><font color="red">Hot</font> runs are test executions with cache for the current app stored during previous runs.</p>
206+ </div>
207+ <table id="AppStartUpTable" class="table table-striped table-bordered"></table>
208+ </div>
209+ </div>
210+ </div> <!-- app-startup-section -->
211+
212+ <div id="applications-manual-section" class="content-section">
213+ <div class="panel panel-default">
214+ <div class="panel-heading"><h1>Tests by Application Manual</h1></div>
215 <div class="panel-body">
216- <div class="col-md-6">
217+ <div id="tests-by-application-manual" class="col-md-6">
218 <canvas id="applicationsManualChartCanvas" height="400" width="400"></canvas>
219 </div>
220- <div class="col-md-6">
221+ </div>
222+ </div>
223+ </div> <!-- applications-manual-section -->
224+
225+ <div id="applications-automated-section" class="content-section">
226+ <div class="panel panel-default">
227+ <div class="panel-heading"><h1>Tests by Application Automated</h1></div>
228+ <div class="panel-body">
229+ <div id="tests-by-application-automated" class="col-md-6">
230 <canvas id="applicationsAutomatedChartCanvas" height="400" width="400"></canvas>
231 </div>
232 </div>
233 </div>
234- </div> <!-- applications-section -->
235+ </div> <!-- applications-automated-section -->
236
237- <div id="domains" class="content-section">
238+ <div id="domains-manual-section" class="content-section">
239 <div class="panel panel-default">
240- <div class="panel-heading"><h1>Tests by Domain</h1></div>
241+ <div class="panel-heading"><h1>Tests by Domain Manual</h1></div>
242 <div class="panel-body">
243 <div class="col-md-6">
244 <canvas id="domainsManualChartCanvas" height="400" width="400"></canvas>
245 </div>
246+ </div>
247+ </div>
248+ </div> <!-- domains-section -->
249+
250+ <div id="domains-automated-section" class="content-section">
251+ <div class="panel panel-default">
252+ <div class="panel-heading"><h1>Tests by Domain Automated</h1></div>
253+ <div class="panel-body">
254 <div class="col-md-6">
255 <canvas id="domainsAutomatedChartCanvas" height="400" width="400"></canvas>
256 </div>
257@@ -283,35 +335,15 @@
258 });
259 </script>
260 <script>
261+
262 // show only the content-section of id matching hash
263 $(window).on("hashchange", function (e) {
264- $(".content-section").hide();
265- // TODO: experimenting with loading-on-command
266- // var divToShow = $("div" + window.location.hash);
267- // divToShow.trigger("custom");
268- $("div" + window.location.hash).show();
269+ moveToSection();
270
271- // special treatment for test plans because of its modal
272- if (window.location.hash.match('#test-plan.*') != null) {
273- $("div#test-plans").show();
274- if (window.location.hash.match('#test-plan-modal.*') != null) {
275- var testPlanId = window.location.hash.split('-').reverse()[0];
276- drawTestPlanModal(testPlanData, testPlanId);
277- $("#test-plan-modal").modal('show');
278- }
279- }
280- // for whatever reason the modal isn't hiding properly
281- $("#test-plan-modal").hide();
282 });
283
284 window.onload = function() {
285- drawTestLibrarySection();
286- drawTestExecutionSection();
287- drawLandingsSection();
288- drawLandingFailuresSection();
289- drawTestPlansSection();
290- drawApplicationsSection();
291- drawDomainsSection();
292+ drawSections(true);
293 }
294 </script>
295 </body>
296
297=== added file 'qakit/dashboard/js/appstartup.js'
298--- qakit/dashboard/js/appstartup.js 1970-01-01 00:00:00 +0000
299+++ qakit/dashboard/js/appstartup.js 2016-02-12 17:25:40 +0000
300@@ -0,0 +1,31 @@
301+
302+
303+function drawAppStartUpSection(firstDraw) {
304+ $.getJSON("./data/app_startup_report.json", function(data) {
305+ if (firstDraw){
306+ process(data);
307+ }
308+ }).fail(function(data, status) {
309+ console.log("Hiding Appstartup section");
310+ $("#app-startup-section").hide();
311+ $("#app-startup-link").hide();
312+ });
313+}
314+
315+function process(data) {
316+ $('#app-startup-channel').text('Channel: ' + data.channel);
317+ $('#app-startup-device').text('Device: ' + data.device);
318+ $('#app-startup-build-number').text('Build Number: ' + data.build_number);
319+
320+ charts = data.charts
321+ for (var chart in charts) {
322+ title = charts[chart].title
323+ path = "./data/" + basename(charts[chart].path)
324+ id = title.toLowerCase() + "-app-startup-section"
325+ section = '<div class="app-startup-elem" id="' + id + '" parent-section="app-startup-section"><h2>' + title + '</h2><img src="' + path + '"/></div>'
326+ $( "#AppStartUpTable" ).append(section);
327+
328+ link = '<li><a href="#' + id + '">' + title + '</a></li>'
329+ $( "#app-startup-sublinks" ).append(link);
330+ }
331+}
332
333=== modified file 'qakit/dashboard/js/kpi.js'
334--- qakit/dashboard/js/kpi.js 2016-02-12 17:25:40 +0000
335+++ qakit/dashboard/js/kpi.js 2016-02-12 17:25:40 +0000
336@@ -42,19 +42,35 @@
337 }
338
339 function drawApplicationsSection() {
340- $.getJSON("./applications-manual.json", function(data) {
341+ $.getJSON("./data/applications-manual.json", function(data) {
342 pieChart(data, "applicationsManualChartCanvas");
343+ }).fail(function(data, status) {
344+ console.log("Hiding Manual Tests by Application section");
345+ $("#applications-manual-link").hide();
346+ $("#applications-manual-section").hide();
347 });
348- $.getJSON("./applications-automated.json", function(data) {
349+ $.getJSON("./data/applications-automated.json", function(data) {
350 pieChart(data, "applicationsAutomatedChartCanvas");
351+ }).fail(function(data, status) {
352+ console.log("Hiding Automated Tests by Application section");
353+ $("#applications-automated-link").hide();
354+ $("#applications-automated-section").hide();
355 });
356 }
357
358 function drawDomainsSection() {
359- $.getJSON("./domains-manual.json", function(data) {
360+ $.getJSON("./data/domains-manual.json", function(data) {
361 pieChart(data, "domainsManualChartCanvas");
362+ }).fail(function(data, status) {
363+ console.log("Hiding Manual Tests by Domain section");
364+ $("#domains-manual-link").hide();
365+ $("#domains-manual-section").hide();
366 });
367- $.getJSON("./domains-automated.json", function(data) {
368+ $.getJSON("./data/domains-automated.json", function(data) {
369 pieChart(data, "domainsAutomatedChartCanvas");
370+ }).fail(function(data, status) {
371+ console.log("Hiding Automated Tests by Domain section");
372+ $("#domains-automated-link").hide();
373+ $("#domains-automated-section").hide();
374 });
375 }
376
377=== modified file 'qakit/dashboard/js/landing-failures.js'
378--- qakit/dashboard/js/landing-failures.js 2016-02-12 17:25:40 +0000
379+++ qakit/dashboard/js/landing-failures.js 2016-02-12 17:25:40 +0000
380@@ -15,11 +15,16 @@
381 ],
382 searching: true,
383 order: [[0, 'dsc']],
384+ bDestroy: true,
385 });
386 }
387
388 function drawLandingFailuresSection() {
389- $.getJSON("./landing-failures.json", function(data) {
390- landingFailuresTable(data, "#landingFailuresTable");
391+ $.getJSON("./data/landing-failures.json", function(data) {
392+ landingFailuresTable(data, "#landingFailuresTable");
393+ }).fail(function(data, status) {
394+ console.log("Hiding Landing failures section");
395+ $("#landing-failures-section").hide();
396+ $("#landing-failures-link").hide();
397 });
398 }
399
400=== modified file 'qakit/dashboard/js/landings.js'
401--- qakit/dashboard/js/landings.js 2016-02-12 17:25:40 +0000
402+++ qakit/dashboard/js/landings.js 2016-02-12 17:25:40 +0000
403@@ -95,14 +95,19 @@
404 ],
405 searching: false,
406 order: [[0, 'dsc']],
407+ bDestroy: true,
408 });
409 }
410
411 function drawLandingsSection() {
412- $.getJSON("./landings.json", function(data) {
413- data = data.reverse()
414+ $.getJSON("./data/landings.json", function(data) {
415+ data = data.reverse()
416 siloLandingsPerWeekChart(data, "siloLandingsPerWeekChartCanvas");
417 siloPassRatePerWeekChart(data, "siloPassRatePerWeekChartCanvas");
418 landingsTable(data, "#landingsTable");
419+ }).fail(function(data, status) {
420+ console.log("Hiding Landings section");
421+ $("#landings-section").hide();
422+ $("#landings-link").hide();
423 });
424 }
425
426=== added file 'qakit/dashboard/js/main.js'
427--- qakit/dashboard/js/main.js 1970-01-01 00:00:00 +0000
428+++ qakit/dashboard/js/main.js 2016-02-12 17:25:40 +0000
429@@ -0,0 +1,52 @@
430+
431+
432+function drawSections(firstDraw) {
433+ drawTestLibrarySection();
434+ drawTestExecutionSection();
435+ drawLandingsSection();
436+ drawLandingFailuresSection();
437+ drawTestPlansSection();
438+ drawApplicationsSection();
439+ drawDomainsSection();
440+ drawAppStartUpSection(firstDraw);
441+
442+ hideUnusedLinks();
443+}
444+
445+function hideUnusedLinks() {
446+ $("#links-link").hide();
447+ $("#projects-link").hide();
448+}
449+
450+function basename(path) {
451+ return path.split('/').reverse()[0];
452+}
453+
454+function moveToSection() {
455+ $(".content-section").hide();
456+ $("div" + window.location.hash).show();
457+
458+ // special treatment for test plans because of its modal
459+ if (window.location.hash.match('#test-plan.*') != null) {
460+ $("div#test-plans").show();
461+ if (window.location.hash.match('#test-plan-modal.*') != null) {
462+ var testPlanId = window.location.hash.split('-').reverse()[0];
463+ drawTestPlanModal(testPlanData, testPlanId);
464+ $("#test-plan-modal").modal('show');
465+ }
466+ }
467+
468+ // for whatever reason the modal isn't hiding properly
469+ $("#test-plan-modal").hide();
470+
471+ // Show subsection parent when it is required
472+ newdiv = $(window.location.hash);
473+ if(newdiv.attr("parent-section")){
474+ parentId = newdiv.attr('parent-section');
475+ $("body").find('#' + parentId).show();
476+ }
477+
478+ if (!window.location.hash){
479+ drawSections(false);
480+ }
481+}
482\ No newline at end of file
483
484=== modified file 'qakit/dashboard/js/test-execution.js'
485--- qakit/dashboard/js/test-execution.js 2016-02-12 17:25:40 +0000
486+++ qakit/dashboard/js/test-execution.js 2016-02-12 17:25:40 +0000
487@@ -173,12 +173,13 @@
488 ],
489 searching: false,
490 order: [[0, 'dsc']],
491+ bDestroy: true,
492 });
493 }
494
495 function drawTestExecutionSection() {
496- $.getJSON("./test-execution.json", function(data) {
497- data = data.reverse()
498+ $.getJSON("./data/test-execution.json", function(data) {
499+ data = data.reverse()
500 manualTestsExecutedPerWeekChart(
501 data, "manualTestsExecutedPerWeekChartCanvas");
502 automatedTestsExecutedPerWeekChartCanvas(
503@@ -186,5 +187,9 @@
504 manualVsAutomatedChart(
505 data, "manualVsAutomatedChartCanvas");
506 testExecutionTable(data, '#testExecutionTable');
507+ }).fail(function(data, status) {
508+ console.log("Hiding Test Execution section");
509+ $("#test-execution-section").hide();
510+ $("#test-execution-link").hide();
511 });
512 }
513
514=== modified file 'qakit/dashboard/js/test-library.js'
515--- qakit/dashboard/js/test-library.js 2016-02-12 17:25:40 +0000
516+++ qakit/dashboard/js/test-library.js 2016-02-12 17:25:40 +0000
517@@ -125,15 +125,20 @@
518 ],
519 searching: false,
520 order: [[0, 'dsc']],
521+ bDestroy: true,
522 });
523 }
524
525 function drawTestLibrarySection() {
526- $.getJSON("./test-library.json", function(data) {
527- data = data.reverse()
528+ $.getJSON("./data/test-library.json", function(data) {
529+ data = data.reverse()
530 testsInLibraryChart(data, "testsInLibraryChartCanvas");
531 automatedVsManualChart(data, "automatedVsManualChartCanvas");
532 percentageAutomatedChart(data, "percentageAutomatedChartCanvas");
533 testLibraryTable(data, "#testLibraryTable");
534+ }).fail(function(data, status) {
535+ console.log("Hiding Test Library section");
536+ $("#test-library-section").hide();
537+ $("#test-library-link").hide();
538 });
539 }
540
541=== modified file 'qakit/dashboard/js/test-plans.js'
542--- qakit/dashboard/js/test-plans.js 2016-02-12 17:25:40 +0000
543+++ qakit/dashboard/js/test-plans.js 2016-02-12 17:25:40 +0000
544@@ -19,6 +19,7 @@
545 ],
546 searching: true,
547 order: [[0, 'dsc']],
548+ bDestroy: true,
549 });
550 }
551
552@@ -41,12 +42,13 @@
553 var testPlanData = null;
554
555 function drawTestPlansSection() {
556- $.getJSON("./test-plans.json", function(data) {
557- testPlanData = data;
558+ $.getJSON("./data/test-plans.json", function(data) {
559+ testPlanData = data;
560 testPlansTable(data, "#testPlansTable");
561- // $('#test-plan-modal').on('show.bs.modal', function(e) {
562- // // which id to show pls
563- // drawTestPlanModal(data, 561);
564- // });
565- });
566+ }).fail(function(data, status) {
567+ console.log("Hiding Test Plan section");
568+ $("#test-plans-section").hide();
569+ $("#test-plans-link").removeAttr("href");
570+ })
571+ ;
572 }

Subscribers

People subscribed via source and target branches

to all changes: