| <!--TODO(crbug/905380): migrate away from HTML imports.--> |
| <link rel="import" href="/bower_components/google-chart/google-chart.html"> |
| <link rel="import" href="/bower_components/iron-pages/iron-pages.html"> |
| <link rel="import" href="/bower_components/paper-button/paper-button.html"> |
| <link rel="import" href="/bower_components/paper-tabs/paper-tabs.html"> |
| <link rel="import" href="/bower_components/paper-tooltip/paper-tooltip.html"> |
| <link rel="import" href="/bower_components/polymer/polymer.html"> |
| |
| |
| <dom-module id="component-report"> |
| <template> |
| <style> |
| table { |
| border-collapse: collapse; |
| border: 1px solid gray; |
| } |
| |
| table th { |
| padding: 5px; |
| color: #FFF; |
| background-color: #4285F4; |
| white-space: nowrap; |
| } |
| table td { |
| max-width: 0; |
| padding: 2px; |
| padding-right: 10px; |
| height: 30px; |
| vertical-align: top; |
| overflow: hidden; |
| text-overflow: ellipsis; |
| text-align: center; |
| } |
| |
| tr:nth-child(odd) { |
| background-color: #E8F0FE; |
| } |
| |
| tr:nth-child(even) { |
| background-color: #FFF; |
| } |
| |
| .all-flake-font { |
| font-size: 14px; |
| font-weight: bold; |
| } |
| |
| .str-cell { |
| text-align: left; |
| } |
| |
| .num-cell { |
| text-align: right; |
| } |
| |
| #flake-report-display { |
| width: 95vw; |
| } |
| |
| .flake-report-table { |
| width: 95%; |
| margin-left: 20px; |
| margin-right: 20px; |
| } |
| |
| #flake-trend-chart { |
| margin-left: 0 auto; |
| height: 60vh; |
| max-height: calc(100vh - 310px); |
| width: 100%; |
| } |
| |
| #tabs-container { |
| background-color: #1F78B4; |
| width: 50vw; |
| height: 60px; |
| margin-left: 3vw; |
| } |
| |
| #display-tabs { |
| color: #FFF; |
| background-color: #4285F4; |
| } |
| |
| paper-tab.iron-selected { |
| background-color: #1F78B4; |
| color: #ffff8d; |
| font-size: 18px; |
| } |
| |
| .table-div { |
| width: 95vw; |
| max-height: calc(100vh - 310px); |
| overflow-y: auto; |
| } |
| |
| iron-pages { |
| border: 3px solid #1F78B4; |
| width: 92vw; |
| height: 70vh; |
| max-height: calc(100vh - 210px); |
| margin-left: 3vw; |
| margin-right: 3vw; |
| } |
| |
| #all-flake-span { |
| padding-right: 5%; |
| padding-bottom: 20px; |
| float: right; |
| } |
| |
| paper-button { |
| color: #fff; |
| background: #4285F4; |
| float: right; |
| margin: 20px; |
| } |
| </style> |
| <br> |
| <div id="tabs-container"> |
| <paper-tabs id="display-tabs" selected="{{selected}}"> |
| <paper-tab>Weekly Report</paper-tab> |
| <paper-tab>Top Flakes in {{component}}</paper-tab> |
| </paper-tabs> |
| </div> |
| <iron-pages selected="{{selected}}"> |
| <div> |
| <paper-button noink id="btn_toggle" on-tap="toggleReportDisplay"> |
| <template is="dom-if" if="[[show_graph]]">show report table</template> |
| <template is="dom-if" if="[[!show_graph]]">show report graph</template> |
| </paper-button> |
| <div id="flake-report-graph-div" hidden="[[!show_graph]]"> |
| <google-chart |
| id="flake-trend-chart" |
| type="combo" |
| options='{{_generateChartOptions(component)}}' |
| data = '{{_getChartDataFromFlake(component_reports)}}'> |
| </google-chart> |
| </div> |
| <div id="flake-report-table-div" class="table-div" hidden="[[show_graph]]"> |
| <table class="flake-report-table"> |
| <tr> |
| <th>Week of |
| <paper-tooltip position="top" offset="0" fit-to-visible-bounds="true">Each report contains one week of data, Monday to Sunday.</paper-tooltip> |
| </th> |
| <th>Flaky Test Count</th> |
| <th>Bug Count</th> |
| <th>New Bug Count</th> |
| <th>Falsely Rejected CL Count</th> |
| <th>Total Impacted CLs</th> |
| <th>Total Flake Occurrences</th> |
| </tr> |
| <template is="dom-repeat" items="[[component_reports]]" as="report"> |
| <tr> |
| <td>[[report.report_time]]</td> |
| <td>[[report.test_count]]</td> |
| <td>[[report.bug_count]]</td> |
| <td>[[_getCount(report.new_bug_count)]]</td> |
| <td>[[report.impacted_cl_counts.cq_false_rejection]]</td> |
| <td>[[report.impacted_cl_counts.total]]</td> |
| <td>[[report.occurrence_counts.total]]</td> |
| </tr> |
| </template> |
| </table> |
| </div> |
| </div> |
| <div id="top-flakes-container" class="table-div"> |
| <br><span id="all-flake-span"><a target="_blank" href$="{{_getLinkToFlakeDashboard()}}"><font class="all-flake-font">All Flakes</font></a></span><br> |
| <table class="flake-report-table"> |
| <tr> |
| <th class="num-cell">Flake Score</th> |
| <th class="str-cell">Test Name</th> |
| <th class="num-cell">Bug</th> |
| </tr> |
| <template is="dom-repeat" items="[[top_flakes]]" as="flake"> |
| <tr> |
| <td class="num-cell" width="10%">[[flake.flake_score_last_week]]</td> |
| <td class="str-cell" width="80%"><a target="_blank" href="/p/chromium/flake-portal/flakes/occurrences?key=[[flake.flake_urlsafe_key]]">[[flake.test_label_name]]</a></td> |
| <td class="num-cell" width="10%"> |
| <template is="dom-if" if="[[_hasBug(flake)]]"> |
| <a href="[[flake.flake_issue.issue_link]]">[[flake.flake_issue.issue_id]]</a> |
| </template> |
| </td> |
| </tr> |
| </template> |
| </table> |
| </div> |
| </iron-pages> |
| </template> |
| <script> |
| (function () { |
| "use strict"; |
| |
| Polymer({ |
| is: "component-report", |
| properties: { |
| component: { |
| type: String |
| }, |
| // A list of component report objects. |
| component_reports: { |
| type: Array |
| }, |
| // A list of flake objects. |
| top_flakes: { |
| type: Array |
| }, |
| total: { |
| type: String |
| }, |
| selected: { |
| type: Number, |
| value: 0 |
| }, |
| show_graph: { |
| type: Boolean, |
| value: true |
| } |
| }, |
| |
| _hasBug: function (flake) { |
| return (flake.flake_issue != null && |
| flake.flake_issue.issue_id != null); |
| }, |
| |
| _getLinkToFlakeDashboard: function () { |
| if (this.total != '') return '/p/chromium/flake-portal/flakes'; |
| return '/p/chromium/flake-portal/flakes?flake_filter=component::' + this.component; |
| }, |
| |
| _generateChartOptions: function (component) { |
| return { |
| title: 'Weekly flake trend on ' + component, |
| hAxes: { 0: { title: 'Weeks' } }, |
| vAxes: { 0: { title: 'Counts', |
| logScale: true} }, |
| chartArea: { |
| right: '20%', |
| width: '70%', |
| height: '70%' |
| }, |
| seriesType: 'line', |
| pointSize: 5, |
| series: { |
| 0: { |
| color: '#174ea6', |
| type: 'area'}, |
| 1: { |
| color: '#1a73e8', |
| type: 'area'}, |
| 2: { |
| color: '#dc3912', |
| type: 'bars' |
| }, |
| 3: { |
| color: '#e37400', |
| type: 'bars' |
| }, |
| 4: { |
| color: '#0d652d'}, |
| 5: { |
| color: '#9b42f4'} |
| } |
| } |
| }, |
| |
| _getReversedComponentReports(component_reports) { |
| let component_reports_copy = component_reports.slice(0); |
| return component_reports_copy.reverse(); |
| }, |
| |
| // Wrapper around a report count to set default value if it doesn't exist. |
| _getCount: function (count) { |
| if (typeof(count) == "undefined" || count == null || count == "") { |
| return 0; |
| } |
| return count; |
| }, |
| |
| _getChartDataFromFlake: function (component_reports) { |
| let data = []; |
| |
| // Declares columns. |
| data.push([ |
| 'Week', |
| 'False Rejected CL', |
| 'Distinct Impacted CL', |
| 'Bug', |
| 'New Bug', |
| 'Occurrences', |
| 'Flaky Test' |
| ]); |
| for (let report of this._getReversedComponentReports(component_reports)) { |
| let row = [ |
| report.report_time, |
| report.impacted_cl_counts.cq_false_rejection, |
| report.impacted_cl_counts.total, |
| report.bug_count, |
| this._getCount(report.new_bug_count), |
| report.occurrence_counts.total, |
| report.test_count |
| ]; |
| data.push(row); |
| } |
| return data; |
| }, |
| |
| // Event handlers. |
| toggleReportDisplay: function (e) { |
| this.show_graph = !this.show_graph; |
| } |
| }) |
| })(); |
| </script> |
| </dom-module> |