<!DOCTYPE HTML> <html> <!-- https://bugzilla.mozilla.org/show_bug.cgi?id=435425 --> <head> <title>Test for Bug 435425</title> <script type="text/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css" /> </head> <body> <a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=435425">Mozilla Bug 435425</a> <p id="display"></p> <div id="content" style="display: none"> </div> <pre id="test"> <script class="testbody" type="text/javascript"> /** Test for Bug 435425 **/ var xhr = null; var upload = null; var currentEvents = null; var expectedResponseText = null; var uploadTotal = 0; var currentProgress = -1; function logEvent(evt) { var i = 0; while ((currentEvents.length != i) && currentEvents[i].optional && ((currentEvents[i].type != evt.type) || !(evt.target instanceof currentEvents[i].target))) { ++i; } if (evt.target instanceof XMLHttpRequestUpload) { if (evt.type == "loadstart") { uploadTotal = evt.total } else { if (evt.type == "progress") { is(evt.lengthComputable, evt.total != 0, "event(" + evt.type + ").lengthComputable should be " + (evt.total != 0 ? true : false) + "."); } if (evt.total != uploadTotal && evt.total != 0) { ok(false, "event(" + evt.type + ").total should not change during upload except to become 0 on error/abort/timeout."); } } } // There can be any number of repeated progress events, so special-case this. if (evt.type == "progress") { // Progress events can repeat, but their "loaded" value must increase. if (currentProgress >= 0) { ok(currentProgress < evt.loaded, "Progress should increase, got " + evt.loaded + " after " + currentProgress); currentProgress = evt.loaded; return; // stay at the currentEvent, since we got progress instead of it. } // Starting a new progress event group. currentProgress = evt.loaded; } else { // Reset the progress indicator on any other event type. currentProgress = -1; } ok(i != currentEvents.length, "Extra or wrong event?"); is(evt.type, currentEvents[i].type, "Wrong event!") ok(evt.target instanceof currentEvents[i].target, "Wrong event target [" + evt.target + "," + evt.type + "]!"); // If we handled non-optional event, remove all optional events before the // handled event and then the non-optional event from the list. if (!currentEvents[i].optional) { for (;i != -1; --i) { currentEvents.shift(); } } } function hasPendingNonOptionalEvent(ev) { var i = 0; while (i < currentEvents.length) { if (!currentEvents[i].optional && currentEvents[i].type == ev) return true; ++i; } return false; } function maybeStop(evt) { logEvent(evt); if (!hasPendingNonOptionalEvent("loadend")) nextTest(); } function openXHR(xhr, method, url, privileged) { if (privileged) SpecialPowers.wrap(xhr).open(method, url); else xhr.open(method, url); } function start(obj) { xhr = new XMLHttpRequest(); upload = xhr.upload; currentEvents = obj.expectedEvents; expectedResponseText = obj.withUpload; currentProgress = -1; xhr.onload = function(evt) { if (expectedResponseText) { is(evt.target.responseText, expectedResponseText, "Wrong responseText"); } logEvent(evt); } xhr.onerror = function(evt) { logEvent(evt); } xhr.onabort = function(evt) { logEvent(evt); } xhr.onloadend = function (evt) { maybeStop(evt); } xhr.onloadstart = function (evt) { logEvent(evt); } xhr.onprogress = function (evt) { logEvent(evt); } if ("upload" in xhr) { xhr.upload.onloadstart = function (evt) { logEvent(evt); } xhr.upload.onprogress = function (evt) { logEvent(evt); } xhr.upload.onload = function (evt) { logEvent(evt); } xhr.upload.onerror = function (evt) { logEvent(evt); } xhr.upload.onabort = function (evt) { logEvent(evt); } xhr.upload.onloadend = function (evt) { maybeStop(evt); } } try { var methodIsGet = (obj.method == "GET"); var url; var privileged = false; if (obj.testRedirectError) { url = "bug435425_redirect.sjs"; } else if (obj.testNetworkError) { url = "http://nosuchdomain.localhost"; privileged = true; } else { url = "bug435425.sjs"; if (obj.withUpload && methodIsGet) { url += "?" + obj.withUpload; } } openXHR(xhr, obj.method, url, privileged); xhr.send(!methodIsGet ? obj.withUpload : null); if (obj.testAbort) { xhr.abort(); } } catch (ex) { ok(false, ex); } } var none = null; var small = ""; var mid = ""; var large = ""; for (var smallLength = 0; smallLength < (0x00000000 + 2); ++smallLength) { small += "A"; } for (var midLength = 0; midLength < (0x00000FFF + 2); ++midLength) { mid += "A"; } for (var largeLength = 0; largeLength < (0x0000FFFF + 2); ++largeLength) { large += "A"; } const XHR = XMLHttpRequest; const UPLOAD = XMLHttpRequestUpload; var tests = [ { method: "GET", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "GET", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: none, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: none, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: none, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: false}, {target: UPLOAD, type: "load", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: small, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: true}, {target: UPLOAD, type: "abort", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: small, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: true}, {target: UPLOAD, type: "error", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: small, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "error", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: false}, {target: UPLOAD, type: "load", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: mid, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: true}, {target: UPLOAD, type: "abort", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: mid, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: true}, {target: UPLOAD, type: "error", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: mid, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "error", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: false}, {target: UPLOAD, type: "load", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "progress", optional: false}, {target: XHR, type: "load", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: large, testAbort: true, testRedirectError: false, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: true}, {target: UPLOAD, type: "abort", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "progress", optional: true}, {target: XHR, type: "abort", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: large, testAbort: false, testRedirectError: true, testNetworkError: false, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "progress", optional: true}, {target: UPLOAD, type: "error", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, { method: "POST", withUpload: large, testAbort: false, testRedirectError: false, testNetworkError: true, expectedEvents: [{target: XHR, type: "loadstart", optional: false}, {target: UPLOAD, type: "loadstart", optional: false}, {target: UPLOAD, type: "error", optional: false}, {target: UPLOAD, type: "loadend", optional: false}, {target: XHR, type: "error", optional: false}, {target: XHR, type: "loadend", optional: false}]}, ]; function runTest() { var test = tests.shift(); start(test); } function nextTest() { if (tests.length) { setTimeout("runTest()", 0); } else { SimpleTest.finish(); } } ok("upload" in (new XMLHttpRequest()), "XMLHttpRequest.upload isn't supported!"); SimpleTest.waitForExplicitFinish(); addLoadEvent(runTest); </script> </pre> </body> </html>