1414 * limitations under the License.
1515 */
1616
17+
18+ parseQueryString = function ( encodedString , useArrays ) {
19+ // strip a leading '?' from the encoded string
20+ var qstr = ( encodedString [ 0 ] == "?" ) ? encodedString . substring ( 1 ) :
21+ encodedString ;
22+ var pairs = qstr . replace ( / \+ / g, "%20" ) . split ( / ( \& a m p \; | \& \# 3 8 \; | \& # x 2 6 ; | \& ) / ) ;
23+ var o = { } ;
24+ var decode ;
25+ if ( typeof ( decodeURIComponent ) != "undefined" ) {
26+ decode = decodeURIComponent ;
27+ } else {
28+ decode = unescape ;
29+ }
30+ if ( useArrays ) {
31+ for ( var i = 0 ; i < pairs . length ; i ++ ) {
32+ var pair = pairs [ i ] . split ( "=" ) ;
33+ if ( pair . length !== 2 ) {
34+ continue ;
35+ }
36+ var name = decode ( pair [ 0 ] ) ;
37+ var arr = o [ name ] ;
38+ if ( ! ( arr instanceof Array ) ) {
39+ arr = [ ] ;
40+ o [ name ] = arr ;
41+ }
42+ arr . push ( decode ( pair [ 1 ] ) ) ;
43+ }
44+ } else {
45+ for ( i = 0 ; i < pairs . length ; i ++ ) {
46+ pair = pairs [ i ] . split ( "=" ) ;
47+ if ( pair . length !== 2 ) {
48+ continue ;
49+ }
50+ o [ decode ( pair [ 0 ] ) ] = decode ( pair [ 1 ] ) ;
51+ }
52+ }
53+ return o ;
54+ } ;
55+
56+ var params = parseQueryString ( location . search . substring ( 1 ) , true ) ;
57+
1758var cancelEvent = function ( e ) {
1859 e . stopPropagation ( ) ;
1960 e . preventDefault ( ) ;
@@ -34,6 +75,7 @@ var reenableInput = function() {
3475}
3576
3677var delayedTests = [ ] ;
78+ var results = { } ;
3779
3880var progressMessage = document . getElementById ( 'progressMessage' ) ;
3981
@@ -78,12 +120,14 @@ var error = function(test, text) {
78120} ;
79121var totalScore = 0 ;
80122var totalPossibleScore = 0 ;
81- var addScore = function ( value , good , bad , weight ) {
123+ var addScore = function ( value , good , bad , weight , name ) {
82124 var score = ( value - bad ) / ( good - bad ) ;
83125 if ( score > 1 ) score = 1 ;
84126 if ( score < 0 ) score = 0 ;
85127 totalScore += score * weight ;
86128 totalPossibleScore += weight ;
129+ results [ name ] = value ;
130+ results [ 'total' ] = ( ( totalScore / totalPossibleScore ) * 10 ) ;
87131}
88132
89133var checkName = function ( ) {
@@ -223,7 +267,7 @@ var inputLatency = function() {
223267 testMode = TEST_MODES . JAVASCRIPT_LATENCY ;
224268 requestServerTest ( test , function ( ) { } , function ( response ) {
225269 var frames = response . keyDownLatencyMs / ( 1000 / 60 ) ;
226- addScore ( frames , 0.5 , 3 , 1 ) ;
270+ addScore ( frames , 0.5 , 3 , 1 , 'Keydown Latency' ) ;
227271 pass ( test , frames . toFixed ( 1 ) + ' frames latency (lower is better)' ) ;
228272 } ) ;
229273} ;
@@ -233,7 +277,7 @@ var scrollLatency = function() {
233277 testMode = TEST_MODES . SCROLL_LATENCY ;
234278 requestServerTest ( test , function ( ) { } , function ( response ) {
235279 var frames = response . scrollLatencyMs / ( 1000 / 60 ) ;
236- addScore ( frames , 0.5 , 3 , 1 ) ;
280+ addScore ( frames , 0.5 , 3 , 1 , 'Scroll Latency' ) ;
237281 pass ( test , frames . toFixed ( 1 ) + ' frames latency (lower is better)' ) ;
238282 } ) ;
239283} ;
@@ -268,17 +312,17 @@ var testJank = function() {
268312 switch ( test . report [ i ] ) {
269313 case 'css' :
270314 var jank = response . maxCssPauseTimeMs / ( 1000 / 60 ) ;
271- addScore ( jank , 1 , 5 , .3 ) ;
315+ addScore ( jank , 1 , 5 , .3 , test . name + ' - CSS' ) ;
272316 reports . push ( 'CSS: ' + jank . toFixed ( 1 ) + ' frames jank' ) ;
273317 break ;
274318 case 'js' :
275319 var jank = response . maxJSPauseTimeMs / ( 1000 / 60 ) ;
276- addScore ( jank , 1 , 5 , .3 ) ;
320+ addScore ( jank , 1 , 5 , .3 , test . name + ' - Javascript' ) ;
277321 reports . push ( 'JavaScript: ' + jank . toFixed ( 1 ) + ' frames jank' ) ;
278322 break ;
279323 case 'scroll' :
280324 var jank = response . maxScrollPauseTimeMs / ( 1000 / 60 ) ;
281- addScore ( jank , 1 , 5 , .3 ) ;
325+ addScore ( jank , 1 , 5 , .3 , test . name + ' - Scrolling' ) ;
282326 reports . push ( 'Scrolling: ' + jank . toFixed ( 1 ) + ' frames jank' ) ;
283327 break ;
284328 }
@@ -292,6 +336,8 @@ var testNative = function() {
292336 var test = this ;
293337 testMode = TEST_MODES . NATIVE_REFERENCE ;
294338 requestServerTest ( test , function ( ) { } , function ( response ) {
339+ results [ 'Native Reference - frames latency' ] = ( response . keyDownLatencyMs / ( 1000 / 60 ) ) . toFixed ( 1 ) ;
340+ results [ 'Native Reference - frames jank' ] = ( response . maxCssPauseTimeMs / ( 1000 / 60 ) ) . toFixed ( 1 ) ;
295341 pass ( test , ( ( response . keyDownLatencyMs / ( 1000 / 60 ) ) . toFixed ( 1 ) ) + ' frames latency, ' + ( response . maxCssPauseTimeMs / ( 1000 / 60 ) ) . toFixed ( 1 ) + ' frames jank (lower is better)' ) ;
296342 } ) ;
297343} ;
@@ -349,7 +395,11 @@ var loadGiantImage = function() {
349395 return ;
350396 }
351397 }
352- document . body . removeChild ( giantImageContainer ) ;
398+ try {
399+ document . body . removeChild ( giantImageContainer ) ;
400+ } catch ( ex ) {
401+ // on error, we flood the console with message
402+ }
353403 }
354404} ;
355405
@@ -423,9 +473,10 @@ var tests = [
423473 { name : 'JavaScript jank' ,
424474 info : 'Tests responsiveness during JavaScript execution.' ,
425475 test : testJank , blocker : cpuLoad , report : [ 'css' , 'scroll' ] } ,
426- { name : 'Image loading jank' ,
427- info : 'Tests responsiveness during image loading.' ,
428- test : testJank , blocker : loadGiantImage , report : [ 'css' , 'js' , 'scroll' ] } ,
476+ // { name: 'Image loading jank',
477+ // info: 'Tests responsiveness during image loading.',
478+ // test: testJank, blocker: loadGiantImage, report: ['css', 'js', 'scroll'] },
479+
429480 // These tests work, but are disabled for now to focus on the latency test.
430481 // { name: 'requestAnimationFrame', test: checkName, toCheck: 'requestAnimationFrame' },
431482 // { name: 'Canvas 2D', test: checkName, toCheck: 'HTMLCanvasElement' },
@@ -524,6 +575,18 @@ var runNextTest = function(previousTest) {
524575 progressMessage . style . display = 'none' ;
525576 doneMessage . style . display = 'block' ;
526577 reenableInput ( ) ;
578+ // TODO: this is Firefox specific. Possibly use an extension for supporting other browsers?
579+ if ( params . auto == 1 ) {
580+ if ( window . dump ) {
581+ dump ( '__start_report\n' ) ;
582+ for ( item in results ) {
583+ dump ( item + ', ' + results [ item ] + '\n' ) ;
584+ }
585+ dump ( '__end_report\n' ) ;
586+ dump ( '__startTimestamp' + Date . now ( ) + '__endTimestamp\n' ) ;
587+ }
588+ quit ( ) ;
589+ }
527590 // End the test run.
528591 return ;
529592 }
@@ -545,6 +608,19 @@ var runNextTest = function(previousTest) {
545608} ;
546609setTimeout ( runNextTest , 100 ) ;
547610
611+ function quit ( ) {
612+ try {
613+ netscape . security . PrivilegeManager . enablePrivilege ( 'UniversalPreferencesRead UniversalPreferencesWrite UniversalXPConnect' ) ;
614+ var appService = Components . classes [ '@mozilla.org/toolkit/app-startup;1' ] .
615+ getService ( Components . interfaces . nsIAppStartup ) ;
616+ var forceQuit = Components . interfaces . nsIAppStartup . eForceQuit ;
617+ appService . quit ( forceQuit ) ;
618+ } catch ( ex ) {
619+ alert ( ex ) ;
620+ //TODO: is there a better route to take here
621+ }
622+ }
623+
548624var checkTimeout = function ( test ) {
549625 if ( ! test . finished ) {
550626 test . timedOut = true ;
0 commit comments