1 <head> 2 <script> 3 var botRoot = "http://build.chromium.org/p/chromium"; 4 var waterfallURL = botRoot + "/waterfall/bot_status.json?json=1"; 5 var botList; 6 var checkinResults; 7 var bots; 8 var failures; 9 10 function updateBotList(text) { 11 var results = (new RegExp('(.*)<\/body>', 'g')).exec(text); 12 if (!results || results.index < 0) { 13 console.log("Error: couldn't find bot JSON"); 14 console.log(text); 15 return; 16 } 17 var data; 18 try { 19 // The build bot returns invalid JSON. Namely it uses single 20 // quotes and includes commas in some invalid locations. We have to 21 // run some regexps across the text to fix it up. 22 var jsonString = results[1].replace(/'/g, '"').replace(/},]/g,'}]'); 23 data = JSON.parse(jsonString); 24 } catch (e) { 25 console.dir(e); 26 console.log(text); 27 return; 28 } 29 if (!data) { 30 throw new Error("JSON parse fail: " + results[1]); 31 } 32 botList = data[0]; 33 checkinResults = data[1]; 34 35 failures = botList.filter(function(bot) { 36 return (bot.color != "success"); 37 }); 38 displayFailures(); 39 } 40 41 function displayFailures() { 42 bots.innerText = ""; 43 44 if (failures.length == 0) { 45 var anchor = document.createElement("a"); 46 anchor.addEventListener("click", showConsole); 47 anchor.className = "open"; 48 anchor.innerText = "The tree is completely green."; 49 bots.appendChild(anchor); 50 bots.appendChild(document.createTextNode(" (no way!)")); 51 } else { 52 var anchor = document.createElement("a"); 53 anchor.addEventListener("click", showFailures); 54 anchor.innerText = "failures:"; 55 var div = document.createElement("div"); 56 div.appendChild(anchor); 57 bots.appendChild(div); 58 59 failures.forEach(function(bot, i) { 60 var div = document.createElement("div"); 61 div.className = "bot " + bot.color; 62 div.addEventListener("click", function() { 63 // Requires closure for each iteration to retain local value of |i|. 64 return function() { showBot(i); } 65 }()); 66 div.innerText = bot.title; 67 bots.appendChild(div); 68 }); 69 } 70 } 71 72 function showURL(url) { 73 window.open(url); 74 window.event.stopPropagation(); 75 } 76 77 function showBot(botIndex) { 78 var bot = failures[botIndex]; 79 var url = botRoot + "/waterfall/waterfall?builder=" + bot.name; 80 showURL(url); 81 } 82 83 function showConsole() { 84 var url = botRoot + "/waterfall/console"; 85 showURL(url); 86 } 87 88 function showTry() { 89 var url = botRoot + "/try-server/waterfall"; 90 showURL(url); 91 } 92 93 function showFyi() { 94 var url = botRoot + "/waterfall.fyi/console"; 95 showURL(url); 96 } 97 98 function showFailures() { 99 var url = botRoot + 100 "/waterfall/waterfall?show_events=true&failures_only=true"; 101 showURL(url); 102 } 103 104 function requestURL(url, callback) { 105 console.log("requestURL: " + url); 106 var xhr = new XMLHttpRequest(); 107 try { 108 xhr.onreadystatechange = function(state) { 109 if (xhr.readyState == 4) { 110 if (xhr.status == 200) { 111 var text = xhr.responseText; 112 //console.log(text); 113 callback(text); 114 } else { 115 bots.innerText = "Error."; 116 } 117 } 118 } 119 120 xhr.onerror = function(error) { 121 console.log("xhr error: " + JSON.stringify(error)); 122 console.dir(error); 123 } 124 125 xhr.open("GET", url, true); 126 xhr.send({}); 127 } catch(e) { 128 console.log("exception: " + e); 129 } 130 } 131 window.onload = function() { 132 bots = document.getElementById("bots"); 133 134 // XHR from onload winds up blocking the load, so we put it in a setTimeout. 135 window.setTimeout(requestURL, 0, waterfallURL, updateBotList); 136 } 137 138 function toggle_size() { 139 if (document.body.className == "big") { 140 document.body.className = "small"; 141 } else { 142 document.body.className = "big"; 143 } 144 } 145 146 </script> 147 <style> 148 body { 149 font-family: sans-serif; 150 font-size: 0.8em; 151 overflow: hidden; 152 } 153 154 #links { 155 background-color: #efefef; 156 border: 1px solid #cccccc; 157 border-radius: 5px; 158 margin-top: 1px; 159 padding: 3px; 160 white-space: nowrap; 161 text-align: center; 162 } 163 164 a { 165 text-decoration: underline; 166 color: #444; 167 } 168 169 a:hover { 170 color: black; 171 cursor: pointer; 172 } 173 174 body.big .bot { 175 -webkit-transition: all .5s ease-out; 176 margin: 20px; 177 } 178 179 body.small .bot { 180 -webkit-transition: all .5s ease-out; 181 } 182 183 .bot { 184 cursor: pointer; 185 border-radius: 5px; 186 margin-top: 1px; 187 padding: 3px; 188 white-space: nowrap; 189 } 190 191 .bot:hover { 192 border: 2px solid black; 193 padding: 2px; 194 } 195 196 .open { 197 color: green; 198 } 199 200 .closed { 201 color: red; 202 } 203 204 .running { 205 background-color: rgb(255, 252, 108); 206 border: 1px solid rgb(197, 197, 109); 207 } 208 209 .notstarted { 210 border: 1px solid rgb(170, 170, 170); 211 } 212 213 .failure { 214 background-color: rgb(233, 128, 128); 215 border: 1px solid rgb(167, 114, 114); 216 } 217 218 .warnings { 219 background-color: rgb(255, 195, 67); 220 border: 1px solid rgb(194, 157, 70); 221 } 222 223 .success { 224 background-color: rgb(143, 223, 95); 225 border: 1px solid rgb(79, 133, 48); 226 } 227 228 .exception { 229 background-color: rgb(224, 176, 255); 230 border: 1px solid rgb(172, 160, 179); 231 } 232 </style> 233 </head> 234 <body onclick="toggle_size()"> 235 <div id="links"> 236 <a href="" onclick='showConsole()'>console</a> - 237 <a href="" onclick='showTry()'>try</a> - 238 <a href="" onclick='showFyi()'>fyi</a> 239 </div> 240 <div id="bots">Loading....</div> 241 </body> 242