diff options
Diffstat (limited to 'dom/base/test/test_bug338583.html')
-rw-r--r-- | dom/base/test/test_bug338583.html | 665 |
1 files changed, 665 insertions, 0 deletions
diff --git a/dom/base/test/test_bug338583.html b/dom/base/test/test_bug338583.html new file mode 100644 index 0000000000..a399dd490c --- /dev/null +++ b/dom/base/test/test_bug338583.html @@ -0,0 +1,665 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=338583 +--> +<head> + <meta http-equiv='Content-Type' content='text/html; charset=utf-8'> + <title>Test for Bug 338583</title> + <script type="text/javascript" src="/MochiKit/MochiKit.js"></script> + <script src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> + +</head> +<body bgColor=white> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=338583">Mozilla Bug 338583</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script class="testbody" type="text/javascript"> +/** Tests for Bug 338583 **/ + +// we test: +// 1) the EventSource behaviour +// 2) if the events are trusted +// 3) possible invalid eventsources +// 4) the close method when the object is just been used +// 5) access-control +// 6) the data parameter +// 7) delayed server responses + +// -- + + var gTestsHaveFinished = []; + + function setTestHasFinished(test_id) + { + if (gTestsHaveFinished[test_id]) { + return; + } + + gTestsHaveFinished[test_id] = true; + for (var i=0; i < gTestsHaveFinished.length; ++i) { + if (!gTestsHaveFinished[i]) { + return; + } + } + + SimpleTest.finish(); + } + + function runAllTests() { + // these tests run asynchronously, and they will take 8000 ms + var all_tests = [ + doTest1, doTest1_e, doTest1_f, doTest2, doTest3, doTest3_b, doTest3_c, doTest3_d, + doTest3_e, doTest3_f, doTest3_g, doTest3_h, doTest4, doTest4_b, + doTest5, doTest5_b, doTest5_c, doTest5_e, doTest6, doTest7 + ]; + + for (let test_id=0; test_id < all_tests.length; ++test_id) { + gTestsHaveFinished[test_id] = false; + var fn = all_tests[test_id]; + fn(test_id); + } + + setTimeout(function() { + for (let test_id=0; test_id < all_tests.length; ++test_id) { + if (!gTestsHaveFinished[test_id]) { + ok(false, "Test " + test_id + " took too long"); + setTestHasFinished(test_id); + } + } + }, 60000 * stress_factor); // all tests together are supposed to take less than 1 minute + } + + function fn_onmessage(e) { + if (e.currentTarget == e.target && e.target.hits != null) + e.target.hits.fn_onmessage++; + } + + function fn_event_listener_message(e) { + if (e.currentTarget == e.target && e.target.hits != null) + e.target.hits.fn_event_listener_message++; + } + + function fn_other_event_name(e) { + if (e.currentTarget == e.target && e.target.hits != null) + e.target.hits.fn_other_event_name++; + } + + var gEventSourceObj1 = null, gEventSourceObj1_e, gEventSourceObj1_f; + var gEventSourceObj2 = null; + var gEventSourceObj3_a = null, gEventSourceObj3_b = null, + gEventSourceObj3_c = null, gEventSourceObj3_d = null, + gEventSourceObj3_e = null, gEventSourceObj3_f = null, + gEventSourceObj3_g = null, gEventSourceObj3_h = null; + var gEventSourceObj4_a = null, gEventSourceObj4_b = null; + var gEventSourceObj5_a = null, gEventSourceObj5_b = null, + gEventSourceObj5_c = null, gEventSourceObj5_d = null, + gEventSourceObj5_e = null, gEventSourceObj5_f = null; + var gEventSourceObj6 = null; + var gEventSourceObj7 = null; + var stress_factor; // used in the setTimeouts in order to help + // the test when running in slow machines + + function hasBeenHitFor1And2(obj, min) { + if (obj.hits.fn_onmessage < min || + obj.hits.fn_event_listener_message < min || + obj.hits.fn_other_event_name < min) + return false; + return true; + } + +// in order to test (1): +// a) if the EventSource constructor parameter is equal to its url attribute +// b) let its fn_onmessage, fn_event_listener_message, and fn_other_event_name functions listeners be hit four times each +// c) the close method (we expect readyState == CLOSED) +// d) the close method (we expect no message events anymore) +// e) use the default for withCredentials when passing dictionary arguments that don't explicitly set it +// f) if a 204 HTTP response closes (interrupts) connections. See bug 869432. + + function doTest1(test_id) { + gEventSourceObj1 = new EventSource("eventsource.resource"); + ok(gEventSourceObj1.url == "http://mochi.test:8888/tests/dom/base/test/eventsource.resource", "Test 1.a failed."); + ok(gEventSourceObj1.readyState == 0 || gEventSourceObj1.readyState == 1, "Test 1.a failed."); + + doTest1_b(test_id); + } + + function doTest1_b(test_id) { + gEventSourceObj1.hits = []; + gEventSourceObj1.hits.fn_onmessage = 0; + gEventSourceObj1.onmessage = fn_onmessage; + gEventSourceObj1.hits.fn_event_listener_message = 0; + gEventSourceObj1.addEventListener('message', fn_event_listener_message, true); + gEventSourceObj1.hits.fn_other_event_name = 0; + gEventSourceObj1.addEventListener('other_event_name', fn_other_event_name, true); + + // the eventsources.res always use a retry of 0.5 second, so for four hits a timeout of 6 seconds is enough + setTimeout(function(){ + bhits = hasBeenHitFor1And2(gEventSourceObj1, 4); + ok(bhits, "Test 1.b failed."); + + doTest1_c(test_id); + }, parseInt(6000*stress_factor)); + } + + function doTest1_c(test_id) { + gEventSourceObj1.close(); + ok(gEventSourceObj1.readyState == 2, "Test 1.c failed."); + + doTest1_d(test_id); + } + + function doTest1_d(test_id) { + gEventSourceObj1.hits.fn_onmessage = 0; + gEventSourceObj1.hits.fn_event_listener_message = 0; + gEventSourceObj1.hits.fn_other_event_name = 0; + + setTimeout(function(){ + bhits = hasBeenHitFor1And2(gEventSourceObj1, 1); + ok(!bhits, "Test 1.d failed."); + gEventSourceObj1.close(); + setTestHasFinished(test_id); + }, parseInt(2000*stress_factor)); + } + + function doTest1_e(test_id) { + try { + for (var options of [null, undefined, {}]) { + gEventSourceObj1_e = new EventSource("eventsource.resource", options); + is(gEventSourceObj1_e.withCredentials, false, "withCredentials should default to false"); + gEventSourceObj1_e.close(); + } + } catch (e) { + ok(false, "Test 1.e failed"); + } + setTestHasFinished(test_id); + } + + function doTest1_f(test_id) { + var called_on_error = false; + + gEventSourceObj1_f = new EventSource("file_bug869432.eventsource"); + gEventSourceObj1_f.onopen = function(e) { + ok(false, "Test 1.f failed: onopen was called"); + }; + gEventSourceObj1_f.onmessage = function(e) { + ok(false, "Test 1.f failed: onmessage was called"); + }; + gEventSourceObj1_f.onerror = function(e) { + if (called_on_error) { + ok(false, "Test 1.f failed: onerror was called twice"); + } + called_on_error = true; + ok(gEventSourceObj1_f.readyState == 2, "Test 1.f failed: onerror was called with readyState = " + gEventSourceObj1_f.readyState); + }; + + setTimeout(function() { // just to clean... + ok(called_on_error, "Test 1.f failed: onerror was not called"); + setTestHasFinished(test_id); + }, parseInt(5000*stress_factor)); + } + +// in order to test (2) +// a) set a eventsource that give the dom events messages +// b) expect trusted events + + function doTest2(test_id) { + var func = function(e) { + ok(e.isTrusted, "Test 2 failed"); + gEventSourceObj2.close(); + }; + + gEventSourceObj2 = new EventSource("eventsource.resource"); + gEventSourceObj2.onmessage = func; + + setTimeout(function() { // just to clean... + gEventSourceObj2.close(); + setTestHasFinished(test_id); + }, parseInt(5000*stress_factor)); + } + +// in order to test (3) +// a) XSite domain error test +// b) protocol file:// test +// c) protocol javascript: test +// d) wrong Content-Type test +// e) bad http response code test +// f) message eventsource without a data test +// g) DNS error +// h) EventSource which last message doesn't end with an empty line. See bug 710546 + + function doTest3(test_id) { + gEventSourceObj3_a = new EventSource("http://example.org/tests/dom/base/test/eventsource.resource"); + + gEventSourceObj3_a.onmessage = fn_onmessage; + gEventSourceObj3_a.hits = []; + gEventSourceObj3_a.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_a.hits.fn_onmessage == 0, "Test 3.a failed"); + gEventSourceObj3_a.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_b(test_id) { + // currently no support yet for local files for b2g/Android mochitest, see bug 838726 + if (navigator.appVersion.includes("Android") || SpecialPowers.Services.appinfo.name == "B2G") { + setTestHasFinished(test_id); + return; + } + + var xhr = new XMLHttpRequest; + xhr.open("GET", "/dynamic/getMyDirectory.sjs", false); + xhr.send(); + var basePath = xhr.responseText; + + gEventSourceObj3_b = new EventSource("file://" + basePath + "eventsource.resource"); + + gEventSourceObj3_b.onmessage = fn_onmessage; + gEventSourceObj3_b.hits = []; + gEventSourceObj3_b.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_b.hits.fn_onmessage == 0, "Test 3.b failed"); + gEventSourceObj3_b.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function jsEvtSource() + { + return "event: message\n" + + "data: 1\n\n"; + } + + function doTest3_c(test_id) { + gEventSourceObj3_c = new EventSource("javascript: return jsEvtSource()"); + + gEventSourceObj3_c.onmessage = fn_onmessage; + gEventSourceObj3_c.hits = []; + gEventSourceObj3_c.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_c.hits.fn_onmessage == 0, "Test 3.c failed"); + gEventSourceObj3_c.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_d(test_id) { + gEventSourceObj3_d = new EventSource("badContentType.eventsource"); + + gEventSourceObj3_d.onmessage = fn_onmessage; + gEventSourceObj3_d.hits = []; + gEventSourceObj3_d.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_d.hits.fn_onmessage == 0, "Test 3.d failed"); + gEventSourceObj3_d.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_e(test_id) { + gEventSourceObj3_e = new EventSource("badHTTPResponseCode.eventsource"); + + gEventSourceObj3_e.onmessage = fn_onmessage; + gEventSourceObj3_e.hits = []; + gEventSourceObj3_e.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_e.hits.fn_onmessage == 0, "Test 3.e failed"); + gEventSourceObj3_e.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function doTest3_f(test_id) { + gEventSourceObj3_f = new EventSource("badMessageEvent.eventsource"); + + gEventSourceObj3_f.onmessage = fn_onmessage; + gEventSourceObj3_f.hits = []; + gEventSourceObj3_f.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_f.hits.fn_onmessage == 0, "Test 3.f failed"); + gEventSourceObj3_f.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function fnInvalidNCName() { + fnInvalidNCName.hits++; + } + + function doTest3_g(test_id) { + gEventSourceObj3_g = new EventSource("http://hdfskjghsbg.jtiyoejowe.example.com"); + + gEventSourceObj3_g.onmessage = fn_onmessage; + gEventSourceObj3_g.hits = []; + gEventSourceObj3_g.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_g.hits.fn_onmessage == 0, "Test 3.g failed"); + gEventSourceObj3_g.close(); + setTestHasFinished(test_id); + }, parseInt(1500*stress_factor)); + } + + function fnMessageListenerTest3h(e) { + fnMessageListenerTest3h.msg_ok = (fnMessageListenerTest3h.msg_ok && e.data == "ok"); + fnMessageListenerTest3h.id_ok = (fnMessageListenerTest3h.id_ok && e.lastEventId == ""); + } + + function doTest3_h(test_id) { + gEventSourceObj3_h = new EventSource("badMessageEvent2.eventsource"); + + gEventSourceObj3_h.addEventListener('message', fnMessageListenerTest3h, true); + fnMessageListenerTest3h.msg_ok = true; + fnMessageListenerTest3h.id_ok = true; + + gEventSourceObj3_h.onmessage = fn_onmessage; + gEventSourceObj3_h.hits = []; + gEventSourceObj3_h.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj3_h.hits.fn_onmessage > 1, "Test 3.h.1 failed"); + if (gEventSourceObj3_h.hits.fn_onmessage > 1) { + ok(fnMessageListenerTest3h.msg_ok, "Test 3.h.2 failed"); + ok(fnMessageListenerTest3h.id_ok, "Test 3.h.3 failed"); + } + gEventSourceObj3_h.close(); + setTestHasFinished(test_id); + }, parseInt(6000*stress_factor)); + } + +// in order to test (4) +// a) close the object when it is in use, which is being processed and that is expected +// to dispatch more eventlisteners +// b) remove an eventlistener in use + + function fn_onmessage4_a(e) + { + if (e.data > gEventSourceObj4_a.lastData) + gEventSourceObj4_a.lastData = e.data; + if (e.data == 2) + gEventSourceObj4_a.close(); + } + + function fn_onmessage4_b(e) + { + if (e.data > gEventSourceObj4_b.lastData) + gEventSourceObj4_b.lastData = e.data; + if (e.data == 2) + gEventSourceObj4_b.removeEventListener('message', fn_onmessage4_b, true); + } + + function doTest4(test_id) { + gEventSourceObj4_a = new EventSource("forRemoval.resource"); + gEventSourceObj4_a.lastData = 0; + gEventSourceObj4_a.onmessage = fn_onmessage4_a; + + setTimeout(function() { + ok(gEventSourceObj4_a.lastData == 2, "Test 4.a failed"); + gEventSourceObj4_a.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest4_b(test_id) + { + gEventSourceObj4_b = new EventSource("forRemoval.resource"); + gEventSourceObj4_b.lastData = 0; + gEventSourceObj4_b.addEventListener('message', fn_onmessage4_b, true); + + setTimeout(function() { + ok(gEventSourceObj4_b.lastData == 2, "Test 4.b failed"); + gEventSourceObj4_b.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + +// in order to test (5) +// a) valid access-control xsite request +// b) invalid access-control xsite request +// c) valid access-control xsite request on a restricted page with credentials +// d) valid access-control xsite request on a restricted page without credentials +// e) valid access-control xsite request on a restricted page when the parameter withCredentials is a getter +// f) valid access-control xsite request on a restricted page when the parameter withCredentials is missing + + function doTest5(test_id) + { + gEventSourceObj5_a = new EventSource("http://example.org/tests/dom/base/test/accesscontrol.resource"); + + gEventSourceObj5_a.onmessage = fn_onmessage; + gEventSourceObj5_a.hits = []; + gEventSourceObj5_a.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj5_a.hits.fn_onmessage != 0, "Test 5.a failed"); + gEventSourceObj5_a.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest5_b(test_id) + { + gEventSourceObj5_b = new EventSource("http://example.org/tests/dom/base/test/invalid_accesscontrol.resource"); + + gEventSourceObj5_b.onmessage = fn_onmessage; + gEventSourceObj5_b.hits = []; + gEventSourceObj5_b.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj5_b.hits.fn_onmessage == 0, "Test 5.b failed"); + gEventSourceObj5_b.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + } + + function doTest5_c(test_id) + { + // credentials using the auth cache + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + // also, test mixed mode UI + xhr.open("GET", "https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.c"); + + gEventSourceObj5_c = new EventSource("https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc", + { withCredentials: true } ); + ok(gEventSourceObj5_c.withCredentials, "Wrong withCredentials in test 5.c"); + + gEventSourceObj5_c.onmessage = function(e) { + ok(e.origin == "https://example.com", "Wrong Origin in test 5.c"); + fn_onmessage(e); + }; + gEventSourceObj5_c.hits = []; + gEventSourceObj5_c.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj5_c.hits.fn_onmessage > 0, "Test 5.c failed"); + gEventSourceObj5_c.close(); + doTest5_d(test_id); + }, parseInt(3000*stress_factor)); + }; + } + + function doTest5_d(test_id) + { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open("GET", "https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.d"); + + gEventSourceObj5_d = new EventSource("https://example.com/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc"); + ok(!gEventSourceObj5_d.withCredentials, "Wrong withCredentials in test 5.d"); + + gEventSourceObj5_d.onmessage = function(e) { + ok(e.origin == "https://example.com", "Wrong Origin in test 5.d"); + fn_onmessage(e); + }; + gEventSourceObj5_d.hits = []; + gEventSourceObj5_d.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj5_d.hits.fn_onmessage == 0, "Test 5.d failed"); + gEventSourceObj5_d.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + }; + } + + function doTest5_e(test_id) + { + // credentials using the auth cache + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open("GET", "http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_xhr", true, "user 1", "password 1"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.e"); + + gEventSourceObj5_e = new EventSource("http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user1_evtsrc", + { get withCredentials() { return true; } } ); + ok(gEventSourceObj5_e.withCredentials, "Wrong withCredentials in test 5.e"); + + gEventSourceObj5_e.onmessage = function(e) { + ok(e.origin == "http://example.org", "Wrong Origin in test 5.e"); + fn_onmessage(e); + }; + gEventSourceObj5_e.hits = []; + gEventSourceObj5_e.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj5_e.hits.fn_onmessage > 0, "Test 5.e failed"); + gEventSourceObj5_e.close(); + doTest5_f(test_id); + }, parseInt(5000*stress_factor)); + }; + } + + function doTest5_f(test_id) + { + var xhr = new XMLHttpRequest({mozAnon: true, mozSystem: true}); + xhr.open("GET", "http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_xhr", true, "user 2", "password 2"); + xhr.send(); + xhr.onloadend = function() { + ok(xhr.status == 200, "Failed to set credentials in test 5.f"); + + gEventSourceObj5_f = new EventSource("http://example.org/tests/dom/base/test/file_restrictedEventSource.sjs?test=user2_evtsrc", + { }); + ok(!gEventSourceObj5_f.withCredentials, "Wrong withCredentials in test 5.f"); + + gEventSourceObj5_f.onmessage = function(e) { + ok(e.origin == "http://example.org", "Wrong Origin in test 5.f"); + fn_onmessage(e); + }; + gEventSourceObj5_f.hits = []; + gEventSourceObj5_f.hits.fn_onmessage = 0; + + setTimeout(function() { + ok(gEventSourceObj5_f.hits.fn_onmessage == 0, "Test 5.f failed"); + gEventSourceObj5_f.close(); + setTestHasFinished(test_id); + }, parseInt(3000*stress_factor)); + }; + } + + function doTest6(test_id) + { + gEventSourceObj6 = new EventSource("somedatas.resource"); + var fn_somedata = function(e) { + if (fn_somedata.expected == 0) { + ok(e.data == "123456789\n123456789123456789\n123456789123456789123456789123456789\n 123456789123456789123456789123456789123456789123456789123456789123456789\nçãá\"\'@`~Ý Ḿyyyy", + "Test 6.a failed"); + } else if (fn_somedata.expected == 1) { + ok(e.data == " :xxabcdefghij\nçãá\"\'@`~Ý Ḿyyyy : zz", + "Test 6.b failed"); + gEventSourceObj6.close(); + } else { + ok(false, "Test 6 failed (unexpected message event)"); + } + fn_somedata.expected++; + } + fn_somedata.expected = 0; + gEventSourceObj6.onmessage = fn_somedata; + + setTimeout(function() { + gEventSourceObj6.close(); + setTestHasFinished(test_id); + }, parseInt(2500*stress_factor)); + } + + function doTest7(test_id) + { + gEventSourceObj7 = new EventSource("delayedServerEvents.sjs"); + gEventSourceObj7.msg_received = []; + gEventSourceObj7.onmessage = function(e) + { + e.target.msg_received.push(e.data); + } + + setTimeout(function() { + gEventSourceObj7.close(); + + ok(gEventSourceObj7.msg_received[0] == "" && + gEventSourceObj7.msg_received[1] == "delayed1" && + gEventSourceObj7.msg_received[2] == "delayed2", "Test 7 failed"); + + document.getElementById('waitSpan').innerHTML = ''; + setTestHasFinished(test_id); + }, parseInt(8000*stress_factor)); + } + + function doTest() + { + // Allow all cookies, then run the actual test + SpecialPowers.pushPrefEnv({"set": [["network.cookie.cookieBehavior", 0]]}, + function() { + SpecialPowers.pushPermissions([{'type': 'systemXHR', 'allow': true, 'context': document}], + doTestCallback); + }); + } + + function doTestCallback() + { + + // we get a good stress_factor by testing 10 setTimeouts and some float + // arithmetic taking my machine as stress_factor==1 (time=589) + + var begin_time = (new Date()).getTime(); + + var f = function() { + for (var j=0; j<f.i; ++j) + eval("Math.log(Math.atan(Math.sqrt(Math.pow(3.1415, 13.1415))/0.0007))"); + if (f.i < 10) { + f.i++; + setTimeout(f, 10 + 10*f.i); + } else { + stress_factor = ((new Date()).getTime()-begin_time)*1/589; + stress_factor *= 1.50; // also, a margin of 50% + + runAllTests(); + } + } + f.i = 0; + + setTimeout(f, 10); + } + + SimpleTest.waitForExplicitFinish(); + SimpleTest.requestFlakyTimeout("untriaged"); + addLoadEvent(doTest); + +</script> +</pre> + <span id=waitSpan>Wait please...</span> +</body> +</html> |