test_timer_flood.html (3517B)
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta charset="UTF-8"> 5 <title>Test Behavior During Timer Flood</title> 6 <script src="/tests/SimpleTest/SimpleTest.js"></script> 7 <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> 8 </head> 9 <body> 10 <p id="display"></p> 11 <div id="content" style="display: none"> 12 </div> 13 <pre id="test"> 14 <script type="application/javascript"> 15 SimpleTest.waitForExplicitFinish(); 16 // This test takes a long time to run and it times out on Android debug as a result. 17 SimpleTest.requestLongerTimeout(5); 18 19 function onLoad() { 20 return new Promise(resolve => { 21 addEventListener('load', resolve, { once: true }); 22 }); 23 } 24 25 // Create a frame that executes a timer flood. The frame signals 26 // that is ready once the flood has had a chance to warm up. 27 function withFloodFrame() { 28 return new Promise(resolve => { 29 let frame = document.createElement('iframe'); 30 addEventListener('message', function onMsg(evt) { 31 if (evt.data === 'STARTED') { 32 removeEventListener('message', onMsg); 33 resolve(frame); 34 } 35 }); 36 frame.src = 'file_timer_flood.html'; 37 document.body.appendChild(frame); 38 }); 39 } 40 41 // Test that we can load documents during a timer flood. 42 function testFrameLoad() { 43 return new Promise(resolve => { 44 let frame = document.createElement('iframe'); 45 frame.addEventListener('load', _ => { 46 frame.remove(); 47 resolve(); 48 }, { once: true }); 49 document.body.appendChild(frame); 50 }); 51 } 52 53 // Test that we can perform network requests while a timer flood 54 // is occuring. 55 function testFetch(url) { 56 return fetch(url).then(response => { 57 return response.text(); 58 }); 59 } 60 61 // Test that we can run animations for 5 seconds while a timer 62 // flood is occuring. 63 function testRequestAnimationFrame() { 64 return new Promise(resolve => { 65 let remainingFrames = 5 * 60; 66 function nextFrame() { 67 remainingFrames -= 1; 68 if (remainingFrames > 0) { 69 requestAnimationFrame(nextFrame); 70 } else { 71 resolve(); 72 } 73 }; 74 requestAnimationFrame(nextFrame); 75 }); 76 } 77 78 let floodFrame; 79 80 onLoad().then(_ => { 81 // Start a timer flood in a frame. 82 return withFloodFrame(); 83 }).then(frame => { 84 floodFrame = frame; 85 86 // Next we are going to start a bunch of asynchronous work that we 87 // expect to complete in spite of the timer flood. The type of work 88 // is a bit arbitrary, but is chosen to reflect the kinds of things 89 // we would like the browser to be able to do even when pages are 90 // abusing timers. Feel free to add more types of work here, but 91 // think carefully before removing anything. 92 let tests = []; 93 94 // Verify we can perform a variety of work while the timer flood 95 // is running. 96 for (let i = 0; i < 20; ++i) { 97 tests.push(testFrameLoad()); 98 tests.push(testFetch('file_timer_flood.html')); 99 } 100 // Verify that animations still work while the timer flood is running. 101 // Note that we do one long run of animations instead of parallel runs 102 // like the other activities because of the way requestAnimationFrame() 103 // is scheduled. Parallel animations would not result in any additional 104 // runnables be placed on the event queue. 105 tests.push(testRequestAnimationFrame()); 106 107 // Wait for all tests to finish. If we do not handle the timer flood 108 // well then this will likely time out. 109 return Promise.all(tests); 110 }).then(_ => { 111 ok(true, 'completed tests without timing out'); 112 floodFrame.remove(); 113 SimpleTest.finish(); 114 }); 115 </script> 116 </pre> 117 </body> 118 </html>