service worker: Drop postMessage() to redundant workers silently.

Update the WPT and fix behavior. Per spec change at
https://github.com/w3c/ServiceWorker/issues/1146.

Bug: 972461
Change-Id: Id4bac3fbe1996382952e54d46cb405de9eb951b3
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/1650685
Reviewed-by: Hayato Ito <hayato@chromium.org>
Reviewed-by: Kenichi Ishibashi <bashi@chromium.org>
Commit-Queue: Matt Falkenhagen <falken@chromium.org>
Cr-Commit-Position: refs/heads/master@{#667523}
diff --git a/service-workers/service-worker/postmessage.https.html b/service-workers/service-worker/postmessage.https.html
index b1f3342..7abb302 100644
--- a/service-workers/service-worker/postmessage.https.html
+++ b/service-workers/service-worker/postmessage.https.html
@@ -39,15 +39,6 @@
       .then(e => {
           assert_equals(e.data, 'quit');
           return registration.unregister(scope);
-        })
-      .then(() => { return wait_for_state(t, worker, 'redundant'); })
-      .then(() => {
-          assert_equals(worker.state, 'redundant');
-          assert_throws(
-            {name:'InvalidStateError'},
-            function() { worker.postMessage(''); },
-            'Calling postMessage on a redundant ServiceWorker should ' +
-                'throw InvalidStateError.');
         });
   }, 'postMessage to a ServiceWorker (and back via MessagePort)');
 
@@ -178,4 +169,34 @@
         });
   }, 'postMessage with dictionary a transferable ArrayBuffer between ServiceWorker and Client');
 
+  promise_test(async t => {
+    const firstScript = 'resources/postmessage-echo-worker.js?one';
+    const secondScript = 'resources/postmessage-echo-worker.js?two';
+    const scope = 'resources/';
+
+    const registration = await service_worker_unregister_and_register(t, firstScript, scope);
+    t.add_cleanup(() => registration.unregister());
+    const firstWorker = registration.installing;
+
+    const messagePromise = new Promise(resolve => {
+      navigator.serviceWorker.addEventListener('message', (event) => {
+        resolve(event.data);
+      }, {once: true});
+    });
+
+    await wait_for_state(t, firstWorker, 'activated');
+    await navigator.serviceWorker.register(secondScript, {scope});
+    const secondWorker = registration.installing;
+    await wait_for_state(t, firstWorker, 'redundant');
+
+    // postMessage() to a redundant worker should be dropped silently.
+    // Historically, this threw an exception.
+    firstWorker.postMessage('firstWorker');
+
+    // To test somewhat that it was not received, send a message to another
+    // worker and check that we get a reply for that one.
+    secondWorker.postMessage('secondWorker');
+    const data = await messagePromise;
+    assert_equals(data, 'secondWorker');
+  }, 'postMessage to a redundant worker');
 </script>
diff --git a/service-workers/service-worker/resources/postmessage-echo-worker.js b/service-workers/service-worker/resources/postmessage-echo-worker.js
new file mode 100644
index 0000000..f088ad1
--- /dev/null
+++ b/service-workers/service-worker/resources/postmessage-echo-worker.js
@@ -0,0 +1,3 @@
+self.addEventListener('message', event => {
+  event.source.postMessage(event.data);
+});