Bug 1489023 [wpt PR 12865] - Fire XHR abort event from a task, a=testonly
authorTimothy Gu <timothygu@chromium.org>
Tue, 11 Sep 2018 09:58:36 +0000
changeset 435995 6cc4109ffbd1f0f060ba1689e3906eceaa27945d
parent 435994 182c1a2dfc6e3648eec54e68241797365c752d25
child 435996 94dec1f28de05933d12350e28871c7c6760c0bd5
push id34625
push userdvarga@mozilla.com
push dateThu, 13 Sep 2018 02:31:40 +0000
treeherdermozilla-central@51e9e9660b3e [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewerstestonly
bugs1489023, 12865, 879620, 881180, 1208672, 589634
milestone64.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1489023 [wpt PR 12865] - Fire XHR abort event from a task, a=testonly Automatic update from web-platform-testsFire XHR abort event from a task A test for this new behavior is included as external/wpt/xhr/abort-after-stop.htm. This also means that XHR abort and readystatechange events from navigation is no longer fired. Because of that, external/wpt/xhr/open-url-multi-window-4.htm now times out rather than fails on an assertion, aligning with Firefox. A TestExpectations entry has been added with a bug that tracks fixing this test in spec or upstream in WPT. A few other test expectations were updated as well to account for this. http/tests/navigation/reentrant-xhr-onabort-crash-during-commit.html no longer works as intended, as abort event is no longer fired synchronously (and thus does not expose the same crash surface). It is replaced with an EventSource-based test that functions the same way as XHR before this CL. Note, currently EventSource's error event suffers from the same problem as XHR's abort event, and the class might undergo the same change as this in the future. We will look into an alternative for this test when that change is done. Bug: 879620, 881180 Change-Id: I5a91047086d06347794656f92511a53c22401b5e Reviewed-on: https://chromium-review.googlesource.com/1208672 Reviewed-by: Philip J├Ągenstedt <foolip@chromium.org> Reviewed-by: Yutaka Hirano <yhirano@chromium.org> Commit-Queue: Timothy Gu <timothygu@chromium.org> Cr-Commit-Position: refs/heads/master@{#589634} -- wpt-commits: 070b8cc14e896cb7d18e0043dbbf9e4c563d9fc0 wpt-pr: 12865
testing/web-platform/meta/MANIFEST.json
testing/web-platform/tests/xhr/abort-after-stop.htm
testing/web-platform/tests/xhr/open-after-abort.htm
testing/web-platform/tests/xhr/open-after-stop.window.js
--- a/testing/web-platform/meta/MANIFEST.json
+++ b/testing/web-platform/meta/MANIFEST.json
@@ -407218,16 +407218,22 @@
     ]
    ],
    "xhr/open-after-setrequestheader.htm": [
     [
      "/xhr/open-after-setrequestheader.htm",
      {}
     ]
    ],
+   "xhr/open-after-stop.window.js": [
+    [
+     "/xhr/open-after-stop.window.html",
+     {}
+    ]
+   ],
    "xhr/open-during-abort-event.htm": [
     [
      "/xhr/open-during-abort-event.htm",
      {}
     ]
    ],
    "xhr/open-during-abort-processing.htm": [
     [
@@ -664466,17 +664472,17 @@
    "1c460c898c3c2c57857cb100b13e9cf73dc427cc",
    "testharness"
   ],
   "xhr/abort-after-send.htm": [
    "523a0d616b64bd356a51408ac3045e5e6da87561",
    "testharness"
   ],
   "xhr/abort-after-stop.htm": [
-   "7c5060fa4c60978d6ef850b99153b78176e002b6",
+   "d28d046fa9896ca50a98efc39a4b70a05ae586ff",
    "testharness"
   ],
   "xhr/abort-after-timeout.htm": [
    "924bc424d50eac23bb6d765c5a8d0a9b155b68b9",
    "testharness"
   ],
   "xhr/abort-during-done.htm": [
    "89301729abd3c32dfc9c67c3dac63d98116e83c4",
@@ -664890,23 +664896,27 @@
    "460b2bfc99085b1d6b900860f3250f0f6ac70262",
    "testharness"
   ],
   "xhr/no-utf16-json.htm": [
    "03bbc10804785a1f2219539fcdbe4a024ab395e7",
    "testharness"
   ],
   "xhr/open-after-abort.htm": [
-   "c9c6304422805fc3a137d0a05701af46e6884b5e",
+   "c9ef6e7ac94ec536d08fc021091f6facf7fb71b5",
    "testharness"
   ],
   "xhr/open-after-setrequestheader.htm": [
    "ca1ae25946f0ef00074d7884cdbe28bf753bc2a2",
    "testharness"
   ],
+  "xhr/open-after-stop.window.js": [
+   "e836a523f86e56e37fc83e5c357392581fb31d20",
+   "testharness"
+  ],
   "xhr/open-during-abort-event.htm": [
    "22c3be9bc44c59fb297581bee3cac390d9a68b3d",
    "testharness"
   ],
   "xhr/open-during-abort-processing.htm": [
    "5d80babd9d015bd527a3e8a49b0f4165fd711c81",
    "testharness"
   ],
--- a/testing/web-platform/tests/xhr/abort-after-stop.htm
+++ b/testing/web-platform/tests/xhr/abort-after-stop.htm
@@ -8,23 +8,26 @@
   </head>
   <body>
     <div id="log"></div>
     <script>
       var test = async_test();
       window.onload = test.step_func(function() {
         var client = new XMLHttpRequest();
         var abortFired = false;
+        var sync = true;
         client.onabort = test.step_func(function (e) {
+          assert_false(sync);
           assert_equals(e.type, 'abort');
           abortFired = true;
         });
         client.open("GET", "resources/delay.py?ms=3000", true);
         client.send(null);
         test.step_timeout(() => {
           assert_equals(abortFired, true);
           test.done();
         }, 200);
         window.stop();
+        sync = false;
       });
     </script>
   </body>
 </html>
--- a/testing/web-platform/tests/xhr/open-after-abort.htm
+++ b/testing/web-platform/tests/xhr/open-after-abort.htm
@@ -4,32 +4,74 @@
     <title>XMLHttpRequest: open() after abort()</title>
     <script src="/resources/testharness.js"></script>
     <script src="/resources/testharnessreport.js"></script>
     <link rel="help" href="https://xhr.spec.whatwg.org/#the-open()-method" data-tested-assertations="following::ol/li[15] following::ol/li[15]/ol/li[1] following::ol/li[15]/ol/li[2]" />
   </head>
   <body>
     <div id="log"></div>
     <script>
-      var test = async_test()
-      test.step(function() {
+      test(function(t) {
         var client = new XMLHttpRequest(),
             result = [],
-            expected = [1,  4, 1] // open() -> 1,
-                                    // abort() -> 4, open() -> 1
-        client.onreadystatechange = function() {
-          test.step(function() {
-            result.push(client.readyState)
-          })
-        }
+            expected = [
+              'readystatechange', 0, 1,  // open()
+              'readystatechange', 2, 4,  // abort()
+              'abort',            2, 4,  // abort()
+              'loadend',          2, 4,  // abort()
+              'readystatechange', 3, 1,  // open()
+            ]
+
+        var state = 0
+
+        client.onreadystatechange = t.step_func(function() {
+          result.push('readystatechange', state, client.readyState)
+        })
+        client.onabort = t.step_func(function() {
+          // abort event must be fired synchronously from abort().
+          assert_equals(state, 2)
+
+          // readystatechange should be fired before abort.
+          assert_array_equals(result, [
+            'readystatechange', 0, 1,  // open()
+            'readystatechange', 2, 4,  // abort()
+          ])
+
+          // readyState should be set to unsent (0) at the very end of abort(),
+          // after this (and onloadend) is called.
+          assert_equals(client.readyState, 4)
+
+          result.push('abort', state, client.readyState)
+        })
+        client.onloadend = t.step_func(function() {
+          // abort event must be fired synchronously from abort().
+          assert_equals(state, 2)
+
+          // readystatechange should be fired before abort.
+          assert_array_equals(result, [
+            'readystatechange', 0, 1,  // open()
+            'readystatechange', 2, 4,  // abort()
+            'abort',            2, 4,  // abort()
+          ])
+
+          // readyState should be set to unsent (0) at the very end of abort(),
+          // after this is called.
+          assert_equals(client.readyState, 4)
+
+          result.push('loadend', state, client.readyState)
+        })
+
         client.open("GET", "resources/well-formed.xml")
         assert_equals(client.readyState, 1)
+
+        state = 1
         client.send(null)
+        state = 2
         client.abort()
         assert_equals(client.readyState, 0)
+        state = 3
         client.open("GET", "resources/well-formed.xml")
         assert_equals(client.readyState, 1)
         assert_array_equals(result, expected)
       })
-      test.done()
     </script>
   </body>
 </html>
new file mode 100644
--- /dev/null
+++ b/testing/web-platform/tests/xhr/open-after-stop.window.js
@@ -0,0 +1,43 @@
+// window.stop() below prevents the load event from firing, so wait until it is
+// fired to start the test.
+setup({explicit_done: true });
+
+onload = () => {
+  async_test(function(t) {
+    const client = new XMLHttpRequest();
+
+    const result = [];
+    const expected = [
+      'readystatechange', 0, 1,  // open()
+    ];
+
+    let state = 0;
+
+    client.onreadystatechange = t.step_func(() => {
+      result.push('readystatechange', state, client.readyState);
+    });
+    client.onabort = t.unreached_func("abort should not be fired after window.stop() and open()");
+    client.onloadend = t.unreached_func("loadend should not be fired after window.stop() and open()");
+
+    client.open("GET", "resources/well-formed.xml");
+    assert_equals(client.readyState, 1);
+
+    state = 1;
+    client.send(null);
+    state = 2;
+    window.stop();
+    // Unlike client.abort(), window.stop() does not change readyState
+    // immediately, rather through a task...
+    assert_equals(client.readyState, 1);
+    state = 3;
+    // ... which is then canceled when we open a new request anyway.
+    client.open("GET", "resources/well-formed.xml");
+    assert_equals(client.readyState, 1);
+    assert_array_equals(result, expected);
+
+    // Give the abort and loadend events a chance to fire (erroneously) before
+    // calling this a success.
+    t.step_timeout(t.step_func_done(), 1000);
+  }, "open() after window.stop()");
+  done();
+};