summaryrefslogtreecommitdiffstats
path: root/dom/base/test/test_timer_flood.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/base/test/test_timer_flood.html')
-rw-r--r--dom/base/test/test_timer_flood.html116
1 files changed, 116 insertions, 0 deletions
diff --git a/dom/base/test/test_timer_flood.html b/dom/base/test/test_timer_flood.html
new file mode 100644
index 000000000..b74b04cf2
--- /dev/null
+++ b/dom/base/test/test_timer_flood.html
@@ -0,0 +1,116 @@
+<!DOCTYPE html>
+<html>
+<head>
+ <meta charset="UTF-8">
+ <title>Test Behavior During Timer Flood</title>
+ <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script>
+ <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
+</head>
+<body>
+<p id="display"></p>
+<div id="content" style="display: none">
+</div>
+<pre id="test">
+<script type="application/javascript">
+SimpleTest.waitForExplicitFinish();
+
+function onLoad() {
+ return new Promise(resolve => {
+ addEventListener('load', resolve, { once: true });
+ });
+}
+
+// Create a frame that executes a timer flood. The frame signals
+// that is ready once the flood has had a chance to warm up.
+function withFloodFrame() {
+ return new Promise(resolve => {
+ let frame = document.createElement('iframe');
+ addEventListener('message', function onMsg(evt) {
+ if (evt.data === 'STARTED') {
+ removeEventListener('message', onMsg);
+ resolve(frame);
+ }
+ });
+ frame.src = 'file_timer_flood.html';
+ document.body.appendChild(frame);
+ });
+}
+
+// Test that we can load documents during a timer flood.
+function testFrameLoad() {
+ return new Promise(resolve => {
+ let frame = document.createElement('iframe');
+ frame.addEventListener('load', _ => {
+ frame.remove();
+ resolve();
+ }, { once: true });
+ document.body.appendChild(frame);
+ });
+}
+
+// Test that we can perform network requests while a timer flood
+// is occuring.
+function testFetch(url) {
+ return fetch(url).then(response => {
+ return response.text();
+ });
+}
+
+// Test that we can run animations for 5 seconds while a timer
+// flood is occuring.
+function testRequestAnimationFrame() {
+ return new Promise(resolve => {
+ let remainingFrames = 5 * 60;
+ function nextFrame() {
+ remainingFrames -= 1;
+ if (remainingFrames > 0) {
+ requestAnimationFrame(nextFrame);
+ } else {
+ resolve();
+ }
+ };
+ requestAnimationFrame(nextFrame);
+ });
+}
+
+let floodFrame;
+
+onLoad().then(_ => {
+ // Start a timer flood in a frame.
+ return withFloodFrame();
+}).then(frame => {
+ floodFrame = frame;
+
+ // Next we are going to start a bunch of asynchronous work that we
+ // expect to complete in spite of the timer flood. The type of work
+ // is a bit arbitrary, but is chosen to reflect the kinds of things
+ // we would like the browser to be able to do even when pages are
+ // abusing timers. Feel free to add more types of work here, but
+ // think carefully before removing anything.
+ let tests = [];
+
+ // Verify we can perform a variety of work while the timer flood
+ // is running.
+ for (let i = 0; i < 20; ++i) {
+ tests.push(testFrameLoad());
+ tests.push(testFetch('file_timer_flood.html'));
+ }
+ // Verify that animations still work while the timer flood is running.
+ // Note that we do one long run of animations instead of parallel runs
+ // like the other activities because of the way requestAnimationFrame()
+ // is scheduled. Parallel animations would not result in any additional
+ // runnables be placed on the event queue.
+ tests.push(testRequestAnimationFrame());
+
+ // Wait for all tests to finish. If we do not handle the timer flood
+ // well then this will likely time out.
+ return Promise.all(tests);
+}).then(_ => {
+ ok(true, 'completed tests without timing out');
+ floodFrame.remove();
+ SimpleTest.finish();
+});
+</script>
+</pre>
+</body>
+</html>