test_performance_navigation_timing.html (4649B)
1 <!DOCTYPE HTML> 2 <html> 3 <!-- 4 https://bugzilla.mozilla.org/show_bug.cgi?id=1462891 5 --> 6 <head> 7 <title>Test for Bug 1462891</title> 8 <meta http-equiv="content-type" content="text/html; charset=UTF-8"> 9 <script src="/tests/SimpleTest/SimpleTest.js"></script> 10 </head> 11 <body> 12 <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=1462891">Mozilla Bug 1462891 - Navigation Timing API</a> 13 <div id="content"> 14 </div> 15 <pre id="test"> 16 <script class="testbody" type="text/javascript"> 17 var index = 0; 18 let isRounded = (x, shouldRound, expectedPrecision) => { 19 if (!shouldRound) 20 return true; 21 22 let rounded = (Math.floor(x / expectedPrecision) * expectedPrecision); 23 // First we do the perfectly normal check that should work just fine 24 if (rounded === x || x === 0) 25 return true; 26 27 // When we're diving by non-whole numbers, we may not get perfect 28 // multiplication/division because of floating points. 29 // When dealing with ms since epoch, a double's precision is on the order 30 // of 1/5 of a microsecond, so we use a value a little higher than that as 31 // our epsilon. 32 // To be clear, this error is introduced in our re-calculation of 'rounded' 33 // above in JavaScript. 34 if (Math.abs(rounded - x + expectedPrecision) < .0005) { 35 return true; 36 } else if (Math.abs(rounded - x) < .0005) { 37 return true; 38 } 39 40 // Then we handle the case where you're sub-millisecond and the timer is not 41 // We check that the timer is not sub-millisecond by assuming it is not if it 42 // returns an even number of milliseconds 43 if (expectedPrecision < 1 && Math.round(x) == x) { 44 if (Math.round(rounded) == x) { 45 return true; 46 } 47 } 48 49 ok(false, "Looming Test Failure, Additional Debugging Info: Expected Precision: " + expectedPrecision + " Measured Value: " + x + 50 " Rounded Vaue: " + rounded + " Fuzzy1: " + Math.abs(rounded - x + expectedPrecision) + 51 " Fuzzy 2: " + Math.abs(rounded - x)); 52 53 return false; 54 }; 55 56 var metrics = [ 57 "unloadEventStart", 58 "unloadEventEnd", 59 "domInteractive", 60 "domContentLoadedEventStart", 61 "domContentLoadedEventEnd", 62 "domComplete", 63 "loadEventStart", 64 "loadEventEnd" 65 ]; 66 67 async function runTests(resistFingerprinting, reduceTimerPrecision, expectedPrecision) { 68 await SpecialPowers.pushPrefEnv({ 69 "set": [["privacy.resistFingerprinting", resistFingerprinting], 70 ["privacy.reduceTimerPrecision", reduceTimerPrecision], 71 ["privacy.resistFingerprinting.reduceTimerPrecision.microseconds", expectedPrecision * 1000] 72 ]}); 73 var entries = performance.getEntriesByType("navigation"); 74 is(entries.length, 1, "Checking PerformanceNavigationEntry count"); 75 76 for (let i=0; i<entries.length; i++) { 77 for (let j=0; j<metrics.length; j++) { 78 ok(isRounded(entries[i][metrics[j]], reduceTimerPrecision, expectedPrecision), 79 "Testing " + metrics[j] + " with value " + entries[i][metrics[j]] + 80 " with resistFingerprinting " + resistFingerprinting + " reduceTimerPrecision " + 81 reduceTimerPrecision + " precision " + expectedPrecision); 82 } 83 } 84 } 85 86 async function startTests() { 87 await runTests(false, false, 2); 88 await runTests(true, false, 2); 89 await runTests(true, true, 2); 90 await runTests(false, true, 1000); 91 await runTests(false, true, 133); 92 await runTests(false, true, 13); 93 await runTests(false, true, 2); 94 await runTests(false, true, 1); 95 96 SimpleTest.finish(); 97 } 98 99 SimpleTest.waitForExplicitFinish(); 100 addLoadEvent(startTests); 101 </script> 102 </pre> 103 </body> 104 </html>