Bug 1348050 - Part 2: Create test for fetch and xhr to ensure we set the urgent start flag only when they are triggered by user input event. draft
authorTom Tung <shes050117@gmail.com>
Tue, 25 Apr 2017 17:37:22 +0800
changeset 569159 2b46d15e94d24a7b997aa2ed1ff022b93c7e65aa
parent 569158 cccf6766153b4c688b4425a1d4aa7ce9e6c1805d
child 626118 ff86db36e0b0fbcf692496c471148957a1ee1bba
push id56078
push userttung@mozilla.com
push dateThu, 27 Apr 2017 02:31:32 +0000
bugs1348050
milestone55.0a1
Bug 1348050 - Part 2: Create test for fetch and xhr to ensure we set the urgent start flag only when they are triggered by user input event. MozReview-Commit-ID: 1ehiD3ua5Kl MozReview-Commit-ID: H6bL8PpzijJ
dom/base/test/chrome.ini
dom/base/test/test_urgent_start.html
--- a/dom/base/test/chrome.ini
+++ b/dom/base/test/chrome.ini
@@ -25,9 +25,10 @@ subsuite = clipboard
 [test_messagemanager_principal.html]
 [test_messagemanager_send_principal.html]
 skip-if = buildapp == 'mulet'
 [test_mozbrowser_apis_allowed.html]
 [test_navigator_resolve_identity_xrays.xul]
 support-files = file_navigator_resolve_identity_xrays.xul
 [test_sandboxed_blob_uri.html]
 [test_sendQueryContentAndSelectionSetEvent.html]
+[test_urgent_start.html]
 [test_websocket_frame.html]
new file mode 100644
--- /dev/null
+++ b/dom/base/test/test_urgent_start.html
@@ -0,0 +1,205 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <title>Test for urgentStart(fetch and xhr)</title>
+  <script type="application/javascript"
+          src="chrome://mochikit/content/tests/SimpleTest/SimpleTest.js"></script>
+  <link rel="stylesheet"
+        type="text/css"
+        href="chrome://mochikit/content/tests/SimpleTest/test.css"?>
+  <script type="text/javascript" src="manifest.js"></script>
+</head>
+<body>
+<pre id="test">
+<script class="testbody" type="text/javascript">
+const { classes: Cc, interfaces: Ci } = Components;
+
+SimpleTest.waitForExplicitFinish();
+SimpleTest.waitForFocus(runTest);
+
+const topic = "http-on-opening-request";
+const url = "http://mochi.test:8888/chrome/dom/base/test/file_empty.html";
+
+let expectedResults = [];
+let testcases = [
+  "fetch",
+  "xhr",
+];
+let testcase;
+
+function isUrgentStart(aClassFlags) {
+  if (!aClassFlags) {
+    return false;
+  }
+
+  const urgentStartFlag = 1 << 6;
+  return !!(urgentStartFlag & aClassFlags);
+}
+
+// Test for setTimeout (task)
+function testSetTimeout() {
+  return new Promise(aResolve =>
+    setTimeout(function() {
+      testSimple().then(aResolve);
+    }, 0));
+}
+
+// Test for promise chain (micro-task)
+function testPromise() {
+  return Promise.resolve().then(testSimple);
+}
+
+function testSimple() {
+  if (testcase == "fetch") {
+    return fetch(url);
+  } else if (testcase == "xhr") {
+    return new Promise(aResolve => {
+      let xhr = new XMLHttpRequest();
+      xhr.open("GET", url, false);
+      xhr.send(null);
+      aResolve();
+    });
+  }
+
+  ok(false, "Shouldn't go here.");
+}
+
+function sendRequsetAndCheckUrgentStart() {
+  info("SendRequsetAndCheckUrgentStart");
+
+  let promise_resolve;
+  let promise = new Promise(aResolve => { promise_resolve = aResolve; });
+
+  function checkUrgentStart(aSubject) {
+    info("checkUrgentStart");
+    var channel = aSubject.QueryInterface(Ci.nsIChannel);
+    if (!channel.URI.spec.endsWith(url)) {
+      return;
+    }
+
+    let cos = channel.QueryInterface(Ci.nsIClassOfService);
+
+    let expectedResult = expectedResults.shift();
+    is(isUrgentStart(cos.classFlags), expectedResult,
+       "Expect get: " + expectedResult + ", get: " +
+       isUrgentStart(cos.classFlags) + " in the " +
+       (9 - expectedResults.length) + " test of " + testcase);
+
+    // Resolve if we've tested each three conditions
+    // (simple, promise, setTimeout).
+    if (expectedResults.length % 3 === 0) {
+      SpecialPowers.removeObserver(checkUrgentStart, topic);
+      promise_resolve();
+    }
+  }
+
+  SpecialPowers.addObserver(checkUrgentStart, topic);
+
+  return Promise.all([testSimple(), testSetTimeout(), testPromise(), promise]);
+}
+
+function userInputEventTriggerRequestCheckUrgentStart() {
+  info("UserInputEventTriggerRequestCheckUrgentStart");
+
+  let promise_resolve;
+  let promise = new Promise(aResolve => { promise_resolve = aResolve; });
+
+  info("AddUserInputEventListener");
+
+  let eventHandle = function () {
+    sendRequsetAndCheckUrgentStart().then(_ => promise_resolve());
+  }
+  // User Input Event
+  window.addEventListener("mousedown", eventHandle, {once: true});
+
+  info("SendUserInputEvent");
+
+  var utils = SpecialPowers.getDOMWindowUtils(window);
+  utils.sendMouseEvent("mousedown", 1, 1, 0, 1, 0);
+
+  return promise;
+}
+
+function nonUserInputEventTriggerRequestCheckUrgentStart() {
+  info("NonUserInputEventTriggerRequestCheckUrgentStart");
+
+  let promise_resolve;
+  let promise = new Promise(aResolve => { promise_resolve = aResolve; });
+
+  info("AddNonUserInputEventListener");
+
+  let eventHandle = function () {
+    sendRequsetAndCheckUrgentStart().then(_ => promise_resolve());
+  }
+  // Non user Input Event
+  window.addEventListener("message", eventHandle, {once: true});
+
+  info("SendNonUserInputEvent");
+
+  window.postMessage("hello", "*");
+
+  return promise;
+}
+
+function executeTest() {
+  is(expectedResults.length, 0, "expectedResults should be 0 be executeTest.");
+
+  // We will test fetch first and then xhr.
+  testcase = testcases.shift();
+  info("Verify " + testcase);
+
+  expectedResults = [
+    /* SimpleTest without any events */ false,
+    /* PromiseTest without any events */ false,
+    /* SetTimeoutTest without any events */ false,
+    /* SimpleTest with a user input event */ true,
+    /* PromiseTest with a user input event */ false,
+    /* SetTimeoutTest with user input event */ false,
+    /* SimpleTest with a non user input event */ false,
+    /* PromiseTest with a non user input event */ false,
+    /* SetTimeoutTest with a non user input event */ false,
+  ];
+
+  return Promise.resolve()
+  // Verify urgent start is not set when the request is not triggered by any
+  // events.
+    .then(sendRequsetAndCheckUrgentStart)
+
+  // Verify urgent start is set only when the request is triggered by a user
+  // input event.
+    .then(userInputEventTriggerRequestCheckUrgentStart)
+
+  // Verify urgent start is not set when the request is triggered by a non user
+  // input event.
+    .then(nonUserInputEventTriggerRequestCheckUrgentStart)
+    .then(_ => {
+      if (testcases.length !== 0) {
+        // Run the other test if we still have tests needed to be run.
+        return executeTest();
+      }
+
+      return Promise.resolve();
+    });
+}
+
+function endCheck() {
+  info("End Check: make sure we've done all the tests.");
+
+  is(testcases.length, 0, "All the tests should be executed.");
+  is(expectedResults.length, 0, "All the tests should be executed.");
+
+  return Promise.resolve();
+}
+
+function runTest() {
+  return Promise.resolve()
+    .then(executeTest)
+    .then(endCheck)
+    .catch(aError => ok(false, "Some test failed with error " + aError))
+    .then(SimpleTest.finish);
+}
+
+</script>
+</pre>
+</body>
+</html>