| OLD | NEW |
| 1 var actionInfo = { | 1 var actionInfo = { |
| 2 patch_start: { | 2 patch_start: { |
| 3 startAttempt: true, | 3 startAttempt: true, |
| 4 description: 'CQ started processing patch', | 4 description: 'CQ started processing patch', |
| 5 cls: 'important', | 5 cls: 'important', |
| 6 }, | 6 }, |
| 7 patch_stop: { | 7 patch_stop: { |
| 8 stopAttempt: true, | 8 stopAttempt: true, |
| 9 description: 'CQ stopped processing patch', | 9 description: 'CQ stopped processing patch', |
| 10 cls: 'important', | 10 cls: 'important', |
| (...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 65 | 65 |
| 66 tryjobStatus = [ | 66 tryjobStatus = [ |
| 67 'passed', | 67 'passed', |
| 68 'failed', | 68 'failed', |
| 69 'running', | 69 'running', |
| 70 'not started', | 70 'not started', |
| 71 ]; | 71 ]; |
| 72 | 72 |
| 73 | 73 |
| 74 function main() { | 74 function main() { |
| 75 rows.textContent = 'Loading patch data...'; | 75 container.textContent = 'Loading patch data...'; |
| 76 loadPatchsetRecords(function(records) { | 76 loadPatchsetRecords(function(records) { |
| 77 displayRecords(records); | 77 displayRecords(records); |
| 78 scrollToHash(); | 78 scrollToHash(); |
| 79 }); | 79 }); |
| 80 } | 80 } |
| 81 | 81 |
| 82 function loadPatchsetRecords(callback) { | 82 function loadPatchsetRecords(callback) { |
| 83 var url = '//chromium-cq-status.appspot.com/query/issue=' + issue + '/patchset
=' + patchset; | 83 var url = '//chromium-cq-status.appspot.com/query/issue=' + issue + '/patchset
=' + patchset; |
| 84 var records = []; | 84 var records = []; |
| 85 var moreRecords = true; | 85 var moreRecords = true; |
| (...skipping 11 matching lines...) Expand all Loading... |
| 97 callback(records); | 97 callback(records); |
| 98 } | 98 } |
| 99 } | 99 } |
| 100 } | 100 } |
| 101 xhr.send(); | 101 xhr.send(); |
| 102 } | 102 } |
| 103 queryRecords(null); | 103 queryRecords(null); |
| 104 } | 104 } |
| 105 | 105 |
| 106 function displayRecords(records) { | 106 function displayRecords(records) { |
| 107 rows.textContent = records.length ? '' : 'No records found.'; | 107 container.textContent = ''; |
| 108 var startTimestamp = null; | 108 var currentAttempt = null; |
| 109 var openAttemptHeader = null; | 109 var attempts = []; |
| 110 var attempts = 0; | |
| 111 records.forEach(function(record) { | 110 records.forEach(function(record) { |
| 112 var action = record.fields.action; | 111 var action = record.fields.action; |
| 113 var info = actionInfo[action]; | 112 var info = actionInfo[action]; |
| 114 if (typeof info === 'function') { | 113 if (typeof info === 'function') { |
| 115 info = info(record); | 114 info = info(record); |
| 116 } | 115 } |
| 117 if (!info || (info.filter && !info.filter(record))) { | 116 if (!info || (info.filter && !info.filter(record))) { |
| 118 return; | 117 return; |
| 119 } | 118 } |
| 120 if (info.startAttempt) { | 119 if (info.startAttempt) { |
| 121 startTimestamp = record.timestamp; | 120 currentAttempt = { |
| 122 openAttemptHeader = addHeader(++attempts); | 121 start: record.timestamp, |
| 122 header: newHeader(attempts.length + 1), |
| 123 rows: [], |
| 124 } |
| 125 attempts.push(currentAttempt); |
| 123 } | 126 } |
| 127 if (!currentAttempt) { |
| 128 console.warn('Unexpected record outside of start/end records:', record); |
| 129 } |
| 130 var duration = getDurationString(currentAttempt.start, record.timestamp); |
| 131 currentAttempt.rows.push(newRow(record.timestamp, duration, info.description
, record.fields.message, info.cls)); |
| 124 if (info.stopAttempt) { | 132 if (info.stopAttempt) { |
| 125 openAttemptHeader = null; | 133 currentAttempt.header.addText(' (' + duration + ')'); |
| 134 currentAttempt = null; |
| 126 } | 135 } |
| 127 addRow(startTimestamp, record.timestamp, info.description, record.fields.mes
sage, info.cls); | |
| 128 }); | 136 }); |
| 129 if (openAttemptHeader) { | 137 if (currentAttempt) { |
| 130 openAttemptHeader.textContent += ' (in progress)'; | 138 currentAttempt.header.addText(' (in progress for ' + getDurationString(curre
ntAttempt.start, Date.now() / 1000) + ')'); |
| 131 } | 139 } |
| 140 if (attempts.length === 0) { |
| 141 container.textContent = 'No attempts found.'; |
| 142 return; |
| 143 } |
| 144 attempts.reverse(); |
| 145 attempts.forEach(function(attempt) { |
| 146 container.appendChild(attempt.header); |
| 147 attempt.rows.reverse(); |
| 148 attempt.rows.forEach(function(row) { |
| 149 container.appendChild(row); |
| 150 }); |
| 151 }); |
| 132 } | 152 } |
| 133 | 153 |
| 134 function addHeader(attempt) { | 154 function newHeader(attemptNumber) { |
| 135 rows.appendChild(newElement('br')); | 155 var header = newElement('h3'); |
| 136 var anchor = newElement('a'); | 156 var anchor = newElement('a', 'Attempt #' + attemptNumber); |
| 137 anchor.name = attempt; | 157 anchor.name = attemptNumber; |
| 138 anchor.href = '#' + attempt; | 158 anchor.href = '#' + attemptNumber; |
| 139 var h3 = newElement('h3', 'Attempt #' + attempt); | 159 header.appendChild(anchor); |
| 140 anchor.appendChild(h3); | 160 header.addText = function(text) { |
| 141 rows.appendChild(anchor); | 161 anchor.textContent += text; |
| 142 return h3; | 162 }; |
| 163 return header; |
| 143 } | 164 } |
| 144 | 165 |
| 145 function addRow(startTimestamp, timestamp, description, message, cls) { | 166 function newRow(timestamp, duration, description, message, cls) { |
| 146 var row = newElement('row', '', cls); | 167 var row = newElement('row', '', cls); |
| 147 row.appendChild(newElement('timestamp', getTimestampString(timestamp))); | 168 row.appendChild(newElement('timestamp', getTimestampString(timestamp))); |
| 148 if (startTimestamp !== null) { | 169 row.appendChild(newElement('duration', '(' + duration + ')')); |
| 149 row.appendChild(newElement('later', '(' + getLaterString(startTimestamp, tim
estamp) + ')')); | |
| 150 } | |
| 151 var descriptionNode = newElement('description') | 170 var descriptionNode = newElement('description') |
| 152 if (typeof description === 'string') { | 171 if (typeof description === 'string') { |
| 153 descriptionNode.textContent = description; | 172 descriptionNode.textContent = description; |
| 154 } else { | 173 } else { |
| 155 descriptionNode.appendChild(description); | 174 descriptionNode.appendChild(description); |
| 156 } | 175 } |
| 157 row.appendChild(descriptionNode); | 176 row.appendChild(descriptionNode); |
| 158 if (message) { | 177 if (message) { |
| 159 row.appendChild(newElement('message', '(' + message + ')')); | 178 row.appendChild(newElement('message', '(' + message + ')')); |
| 160 } | 179 } |
| 161 rows.appendChild(row); | 180 return row; |
| 162 } | 181 } |
| 163 | 182 |
| 164 function newElement(tag, text, cls) { | 183 function newElement(tag, text, cls) { |
| 165 var element = document.createElement(tag); | 184 var element = document.createElement(tag); |
| 166 if (text) { | 185 if (text) { |
| 167 element.textContent = text; | 186 element.textContent = text; |
| 168 } | 187 } |
| 169 if (cls) { | 188 if (cls) { |
| 170 element.classList.add(cls); | 189 element.classList.add(cls); |
| 171 } | 190 } |
| 172 return element; | 191 return element; |
| 173 } | 192 } |
| 174 | 193 |
| 175 function getTimestampString(timestamp) { | 194 function getTimestampString(timestamp) { |
| 176 return new Date(timestamp * 1000).toISOString().replace('T', ' ').slice(0, 19)
; | 195 return new Date(timestamp * 1000).toISOString().replace('T', ' ').slice(0, 19)
; |
| 177 } | 196 } |
| 178 | 197 |
| 179 function getLaterString(startTimestamp, timestamp) { | 198 function getDurationString(startTimestamp, timestamp) { |
| 180 var seconds = parseInt(timestamp - startTimestamp); | 199 var seconds = parseInt(timestamp - startTimestamp); |
| 181 if (seconds < 60) { | 200 if (seconds < 60) { |
| 182 return seconds + ' second' + plural(seconds); | 201 return seconds + ' second' + plural(seconds); |
| 183 } | 202 } |
| 184 var minutes = parseInt(seconds / 60); | 203 var minutes = parseInt(seconds / 60); |
| 185 if (minutes < 60) { | 204 if (minutes < 60) { |
| 186 return minutes + ' minute' + plural(minutes); | 205 return minutes + ' minute' + plural(minutes); |
| 187 } | 206 } |
| 188 var hours = parseInt(minutes / 60); | 207 var hours = parseInt(minutes / 60); |
| 189 minutes -= hours * 60; | 208 minutes -= hours * 60; |
| 190 return hours + ' hour' + plural(hours) + ' ' + minutes + ' minute' + plural(mi
nutes); | 209 return hours + ' hour' + plural(hours) + (minutes ? ' ' + minutes + ' minute'
+ plural(minutes) : ''); |
| 191 } | 210 } |
| 192 | 211 |
| 193 function plural(value) { | 212 function plural(value) { |
| 194 return value === 1 ? '' : 's'; | 213 return value === 1 ? '' : 's'; |
| 195 } | 214 } |
| 196 | 215 |
| 197 function simpleTryjobVerifierCheck(record) { | 216 function simpleTryjobVerifierCheck(record) { |
| 198 return record.fields.verifier === 'simple try job'; | 217 return record.fields.verifier === 'simple try job'; |
| 199 } | 218 } |
| 200 | 219 |
| (...skipping 72 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 273 var node = document.querySelector('a[name="' + location.hash.slice(1) + '"]'); | 292 var node = document.querySelector('a[name="' + location.hash.slice(1) + '"]'); |
| 274 var scrollY = 0; | 293 var scrollY = 0; |
| 275 while (node) { | 294 while (node) { |
| 276 scrollY += node.offsetTop; | 295 scrollY += node.offsetTop; |
| 277 node = node.offsetParent; | 296 node = node.offsetParent; |
| 278 } | 297 } |
| 279 window.scrollTo(0, scrollY); | 298 window.scrollTo(0, scrollY); |
| 280 } | 299 } |
| 281 | 300 |
| 282 window.addEventListener('load', main); | 301 window.addEventListener('load', main); |
| OLD | NEW |