48fd067ff7b3948888c84b9232b9553b84355b18
[WebKit-https.git] / PerformanceTests / Animometer / resources / debug-runner / animometer.js
1 Utilities.extendObject(window.benchmarkRunnerClient, {
2     testsCount: null,
3     progressBar: null,
4
5     didRunTest: function ()
6     {
7         this.progressBar.incRange();
8     },
9     
10     willStartFirstIteration: function ()
11     {
12         this.results = new ResultsDashboard();
13         this.progressBar = new ProgressBar(document.getElementById("progress-completed"), this.testsCount);
14     }
15 });
16
17 Utilities.extendObject(window.sectionsManager, {
18     setSectionHeader: function(sectionIdentifier, title)
19     {
20         document.querySelector("#" + sectionIdentifier + " h1").textContent = title;
21     }
22 });
23
24 window.optionsManager =
25 {
26     valueForOption: function(name)
27     {
28         var formElement = document.forms["benchmark-options"].elements[name];
29         if (formElement.type == "checkbox")
30             return formElement.checked;
31         return formElement.value;
32     },
33     
34     updateUIFromLocalStorage: function()
35     {
36         var formElements = document.forms["benchmark-options"].elements;
37
38         for (var i = 0; i < formElements.length; ++i) {
39             var formElement = formElements[i];
40             var name = formElement.id || formElement.name;
41             var type = formElement.type;
42
43             var value = localStorage.getItem(name);
44             if (value === null)
45                 continue;
46
47             if (type == "number")
48                 formElements[name].value = +value;
49             else if (type == "checkbox")
50                 formElements[name].checked = value == "true";
51             else if (type == "radio")
52                 formElements[name].value = value;
53         }
54     },
55
56     updateLocalStorageFromUI: function()
57     {
58         var formElements = document.forms["benchmark-options"].elements;
59         var options = {};        
60
61         for (var i = 0; i < formElements.length; ++i) {
62             var formElement = formElements[i];
63             var name = formElement.id || formElement.name;
64             var type = formElement.type;
65
66             if (type == "number")
67                 options[name] = formElement.value;
68             else if (type == "checkbox")
69                 options[name] = formElement.checked;
70             else if (type == "radio")
71                 options[name] = formElements[name].value;
72     
73             localStorage.setItem(name, options[name]);
74         }
75         
76         return options;
77     }
78 }
79
80 window.suitesManager =
81 {
82     _treeElement: function()
83     {
84         return document.querySelector("#suites > .tree");
85     },
86     
87     _suitesElements: function()
88     {
89         return document.querySelectorAll("#suites > ul > li");
90     },
91     
92     _checkboxElement: function(element)
93     {
94         return element.querySelector("input[type='checkbox']:not(.expand-button)");
95     },
96
97     _editElement: function(element)
98     {
99         return element.querySelector("input[type='number']");
100     },
101
102     _editsElements: function()
103     {
104         return document.querySelectorAll("#suites input[type='number']");
105     },
106         
107     _localStorageNameForTest: function(suiteName, testName)
108     {
109         return suiteName + "/" + testName;
110     },
111
112     _updateSuiteCheckboxState: function(suiteCheckbox)
113     {
114         var numberEnabledTests = 0;
115         suiteCheckbox.testsElements.forEach(function(testElement) {
116             var testCheckbox = this._checkboxElement(testElement);
117             if (testCheckbox.checked)
118                 ++numberEnabledTests;
119         }, this);
120         suiteCheckbox.checked = numberEnabledTests > 0;
121         suiteCheckbox.indeterminate = numberEnabledTests > 0 && numberEnabledTests < suiteCheckbox.testsElements.length;
122     },
123
124     _updateStartButtonState: function()
125     {
126         var suitesElements = this._suitesElements();
127         var startButton = document.querySelector("#intro button");
128         
129         for (var i = 0; i < suitesElements.length; ++i) {
130             var suiteElement = suitesElements[i];
131             var suiteCheckbox = this._checkboxElement(suiteElement);
132             
133             if (suiteCheckbox.checked) {
134                 startButton.disabled = false;
135                 return;
136             }
137         }
138     
139         startButton.disabled = true;
140     },
141
142     _onChangeSuiteCheckbox: function(event)
143     {
144         var selected = event.target.checked;
145         event.target.testsElements.forEach(function(testElement) {
146             var testCheckbox = this._checkboxElement(testElement);
147             testCheckbox.checked = selected;        
148         }, this);
149         this._updateStartButtonState();
150     },
151
152     _onChangeTestCheckbox: function(event)
153     {
154         var suiteCheckbox = event.target.suiteCheckbox;
155         this._updateSuiteCheckboxState(suiteCheckbox);
156         this._updateStartButtonState();
157     },
158
159     _createSuiteElement: function(treeElement, suite, id)
160     {
161         var suiteElement = DocumentExtension.createElement("li", {}, treeElement);
162         var expand = DocumentExtension.createElement("input", { type: "checkbox",  class: "expand-button", id: id }, suiteElement);
163         var label = DocumentExtension.createElement("label", { class: "tree-label", for: id }, suiteElement);
164
165         var suiteCheckbox = DocumentExtension.createElement("input", { type: "checkbox" }, label);
166         suiteCheckbox.suite = suite;
167         suiteCheckbox.onchange = this._onChangeSuiteCheckbox.bind(this);
168         suiteCheckbox.testsElements = [];
169
170         label.appendChild(document.createTextNode(" " + suite.name));
171         return suiteElement;
172     },
173
174     _createTestElement: function(listElement, test, suiteCheckbox)
175     {
176         var testElement = DocumentExtension.createElement("li", {}, listElement);
177         var span = DocumentExtension.createElement("label", { class: "tree-label" }, testElement);
178
179         var testCheckbox = DocumentExtension.createElement("input", { type: "checkbox" }, span);
180         testCheckbox.test = test;
181         testCheckbox.onchange = this._onChangeTestCheckbox.bind(this);
182         testCheckbox.suiteCheckbox = suiteCheckbox;
183
184         suiteCheckbox.testsElements.push(testElement);
185         span.appendChild(document.createTextNode(" " + test.name));
186         DocumentExtension.createElement("input", { type: "number" }, testElement);
187         return testElement;
188     },
189
190     createElements: function()
191     {
192         var treeElement = this._treeElement();
193
194         Suites.forEach(function(suite, index) {
195             var suiteElement = this._createSuiteElement(treeElement, suite, "suite-" + index);
196             var listElement = DocumentExtension.createElement("ul", {}, suiteElement);
197             var suiteCheckbox = this._checkboxElement(suiteElement);
198
199             suite.tests.forEach(function(test) {
200                 var testElement = this._createTestElement(listElement, test, suiteCheckbox);
201             }, this);
202         }, this);
203     },
204     
205     updateEditsElementsState: function()
206     {
207         var editsElements = this._editsElements();
208         var showComplexityInputs = optionsManager.valueForOption("adjustment") == "fixed";
209
210         for (var i = 0; i < editsElements.length; ++i) {
211             var editElement = editsElements[i];
212             if (showComplexityInputs)
213                 editElement.classList.add("selected");
214             else
215                 editElement.classList.remove("selected");
216         }
217     },
218
219     updateDisplay: function()
220     {
221         document.body.className = "display-" + optionsManager.valueForOption("display");
222     },
223
224     updateUIFromLocalStorage: function()
225     {
226         var suitesElements = this._suitesElements();
227         
228         for (var i = 0; i < suitesElements.length; ++i) {
229             var suiteElement = suitesElements[i];
230             var suiteCheckbox = this._checkboxElement(suiteElement);
231             var suite = suiteCheckbox.suite;
232             
233             suiteCheckbox.testsElements.forEach(function(testElement) {
234                 var testCheckbox = this._checkboxElement(testElement);
235                 var testEdit = this._editElement(testElement);
236                 var test = testCheckbox.test;
237                 
238                 var str = localStorage.getItem(this._localStorageNameForTest(suite.name, test.name));
239                 if (str === null)
240                     return;
241
242                 var value = JSON.parse(str);
243                 testCheckbox.checked = value.checked;
244                 testEdit.value = value.complexity;
245             }, this);
246
247             this._updateSuiteCheckboxState(suiteCheckbox);
248         }
249         
250         this._updateStartButtonState();
251     },
252
253     updateLocalStorageFromUI: function()
254     {
255         var suitesElements = this._suitesElements();
256         var suites = [];
257         
258         for (var i = 0; i < suitesElements.length; ++i) {
259             var suiteElement = suitesElements[i];
260             var suiteCheckbox = this._checkboxElement(suiteElement);
261             var suite = suiteCheckbox.suite;
262
263             var tests = [];
264             suiteCheckbox.testsElements.forEach(function(testElement) {
265                 var testCheckbox = this._checkboxElement(testElement);
266                 var testEdit = this._editElement(testElement);
267                 var test = testCheckbox.test;
268                 
269                 if (testCheckbox.checked) {
270                     test.complexity = testEdit.value;
271                     tests.push(test);
272                 }
273
274                 var value = { checked: testCheckbox.checked, complexity: testEdit.value }; 
275                 localStorage.setItem(this._localStorageNameForTest(suite.name, test.name), JSON.stringify(value));
276             }, this);
277
278             if (tests.length)
279                 suites.push(new Suite(suiteCheckbox.suite.name, tests));
280         }
281
282         return suites;
283     },
284     
285     updateLocalStorageFromJSON: function(iterationResults)
286     {
287         for (var suiteName in iterationResults[Strings.json.results.suites]) {
288             var suiteResults = iterationResults[Strings.json.results.suites][suiteName];
289
290             for (var testName in suiteResults[Strings.json.results.tests]) {
291                 var testResults = suiteResults[Strings.json.results.tests][testName];
292                 var data = testResults[Strings.json.experiments.complexity];
293                 var complexity = Math.round(data[Strings.json.measurements.average]);
294
295                 var value = { checked: true, complexity: complexity };
296                 localStorage.setItem(this._localStorageNameForTest(suiteName, testName), JSON.stringify(value));
297             }
298         }
299     }
300 }
301
302 Utilities.extendObject(window.benchmarkController, {
303     initialize: function()
304     {
305         document.forms["benchmark-options"].addEventListener("change", benchmarkController.onFormChanged, true);
306         optionsManager.updateUIFromLocalStorage();
307         suitesManager.createElements();
308         suitesManager.updateUIFromLocalStorage();
309         suitesManager.updateDisplay();
310         suitesManager.updateEditsElementsState();
311     },
312
313     onFormChanged: function(event)
314     {
315         if (event.target.name == "adjustment") {
316             suitesManager.updateEditsElementsState();
317             return;
318         }
319         if (event.target.name == "display") {
320             suitesManager.updateDisplay();
321         }
322     },
323
324     startBenchmark: function()
325     {
326         var options = optionsManager.updateLocalStorageFromUI();
327         var suites = suitesManager.updateLocalStorageFromUI();
328         this._startBenchmark(suites, options, "running-test");
329     },
330
331     showResults: function()
332     {
333         if (!this.addedKeyEvent) {
334             document.addEventListener("keypress", this.selectResults, false);
335             this.addedKeyEvent = true;
336         }
337
338         sectionsManager.setSectionScore("results", benchmarkRunnerClient.results.score.toFixed(2));
339         var data = benchmarkRunnerClient.results.data[Strings.json.results.iterations];
340         sectionsManager.populateTable("results-header", Headers.testName, data);
341         sectionsManager.populateTable("results-score", Headers.score, data);
342         sectionsManager.populateTable("results-data", Headers.details, data);
343         document.querySelector("#results-json textarea").textContent = JSON.stringify(benchmarkRunnerClient.results.data, function(key, value) {
344             if (typeof value == "number")
345                 return value.toFixed(2);
346             return value;
347         });
348         sectionsManager.showSection("results", true);
349
350         suitesManager.updateLocalStorageFromJSON(data[0]);
351     },
352
353     showTestGraph: function(testName, score, mean, axes, samples, samplingTimeOffset)
354     {
355         sectionsManager.setSectionHeader("test-graph", testName);
356         sectionsManager.setSectionScore("test-graph", score, mean);
357         sectionsManager.showSection("test-graph", true);
358         graph("#test-graph-data", new Insets(10, 20, 30, 40), axes, samples, samplingTimeOffset);
359     }
360 });
361
362 window.addEventListener("load", benchmarkController.initialize);