1273964e2a9764a2ad8383547847bae189bac301
[WebKit-https.git] / PerformanceTests / Animometer / runner / resources / benchmark-runner.js
1 function BenchmarkRunnerState(suites)
2 {
3     this._suites = suites;
4     this._suiteIndex = -1;
5     this._testIndex = 0;
6     this.next();
7 }
8
9 BenchmarkRunnerState.prototype.currentSuite = function()
10 {
11     return this._suites[this._suiteIndex];
12 }
13
14 BenchmarkRunnerState.prototype.currentTest = function()
15 {
16     var suite = this.currentSuite();
17     return suite ? suite.tests[this._testIndex] : null;
18 }
19
20 BenchmarkRunnerState.prototype.isFirstTest = function()
21 {
22     return !this._testIndex;
23 }
24
25 BenchmarkRunnerState.prototype.next = function()
26 {
27     this._testIndex++;
28
29     var suite = this._suites[this._suiteIndex];
30     if (suite && this._testIndex < suite.tests.length)
31         return this;
32
33     this._testIndex = 0;
34     do {
35         this._suiteIndex++;
36     } while (this._suiteIndex < this._suites.length && this._suites[this._suiteIndex].disabled);
37
38     return this;
39 }
40
41 BenchmarkRunnerState.prototype.prepareCurrentTest = function(runner, frame)
42 {
43     var suite = this.currentSuite();
44     var test = this.currentTest();
45     var promise = new SimplePromise;
46     frame.onload = function() {
47         suite.prepare(runner, frame.contentWindow, frame.contentDocument).then(function(result) { promise.resolve(result); });
48     }
49     frame.src = "../tests/" + test.url;
50     return promise;
51 }
52
53 function BenchmarkRunner(suites, client)
54 {
55     this._suites = suites;
56     this._client = client;
57 }
58
59 BenchmarkRunner.prototype.waitForElement = function(selector)
60 {
61     var promise = new SimplePromise;
62     var contentDocument = this._frame.contentDocument;
63
64     function resolveIfReady() {
65         var element = contentDocument.querySelector(selector);
66         if (element)
67             return promise.resolve(element);
68         setTimeout(resolveIfReady, 50);
69     }
70
71     resolveIfReady();
72     return promise;
73 }
74
75 BenchmarkRunner.prototype._appendFrame = function(src)
76 {
77     var frame = document.createElement("iframe");
78     frame.setAttribute("scrolling", "no");
79
80     var marginLeft = parseInt(getComputedStyle(document.body).marginLeft);
81     var marginTop = parseInt(getComputedStyle(document.body).marginTop);
82     if (window.innerWidth > 800 + marginLeft && window.innerHeight > 600 + marginTop) {
83         frame.style.left = marginLeft + "px";
84         frame.style.top = marginTop + "px";
85     } else {
86         frame.style.left = "0px";
87         frame.style.top = "0px";
88     }
89
90     if (this._client && this._client.willAddTestFrame)
91         this._client.willAddTestFrame(frame);
92
93     document.body.insertBefore(frame, document.body.firstChild);
94     this._frame = frame;
95     return frame;
96 }
97
98 BenchmarkRunner.prototype._removeFrame = function()
99 {
100     if (this._frame) {
101         this._frame.parentNode.removeChild(this._frame);
102         this._frame = null;
103     }
104 }
105
106 BenchmarkRunner.prototype._runTestAndRecordResults = function(state)
107 {
108     var promise = new SimplePromise;
109     var suite = state.currentSuite();
110     var test = state.currentTest();
111     
112     if (this._client && this._client.willRunTestTest)
113         this._client.willRunTest(suite, test);
114
115     var contentWindow = this._frame.contentWindow;
116     var self = this;
117
118     suite.run(contentWindow, test, this._client.options, this._client.recordTable, this._client.progressBar).then(function(sampler) {
119         var samplers = self._suitesSamplers[suite.name] || [];
120         
121         samplers[test.name] = sampler;
122         self._suitesSamplers[suite.name] = samplers;
123
124         if (self._client && self._client.didRunTest)
125             self._client.didRunTest(suite, test);
126         
127         state.next();
128         if (state.currentSuite() != suite)
129             self._removeFrame();
130         promise.resolve(state);
131     });
132     
133     return promise;
134 }
135
136 BenchmarkRunner.prototype.step = function(state)
137 {
138     if (!state) {
139         state = new BenchmarkRunnerState(this._suites);
140         this._suitesSamplers = {};
141     }
142
143     var suite = state.currentSuite();
144     if (!suite) {
145         this._finalize();
146         var promise = new SimplePromise;
147         promise.resolve();
148         return promise;
149     }
150
151     if (state.isFirstTest()) {
152         this._masuredValuesForCurrentSuite = {};
153         this._appendFrame();
154     }
155
156     return state.prepareCurrentTest(this, this._frame).then(function(prepareReturnValue) {
157         return this._runTestAndRecordResults(state);
158     }.bind(this));
159 }
160
161 BenchmarkRunner.prototype.runAllSteps = function(startingState)
162 {
163     var nextCallee = this.runAllSteps.bind(this);
164     this.step(startingState).then(function(nextState) {
165         if (nextState)
166             nextCallee(nextState);
167     });
168 }
169
170 BenchmarkRunner.prototype.runMultipleIterations = function(iterationCount)
171 {
172     var self = this;
173     var currentIteration = 0;
174
175     this._runNextIteration = function() {
176         currentIteration++;
177         if (currentIteration < iterationCount)
178             self.runAllSteps();
179         else if (this._client && this._client.didFinishLastIteration)
180             self._client.didFinishLastIteration();
181     }
182
183     if (self._client && self._client.willStartFirstIteration)
184         self._client.willStartFirstIteration(iterationCount);
185
186     self.runAllSteps();
187 }
188
189 BenchmarkRunner.prototype._finalize = function()
190 {
191     this._removeFrame();
192         
193     if (this._client && this._client.didRunSuites)
194         this._client.didRunSuites(this._suitesSamplers);
195
196     if (this._runNextIteration)
197         this._runNextIteration();
198 }