diff --git a/Tests/LibWeb/TestConfig.ini b/Tests/LibWeb/TestConfig.ini
index 706176ea153..7934065a55c 100644
--- a/Tests/LibWeb/TestConfig.ini
+++ b/Tests/LibWeb/TestConfig.ini
@@ -4,6 +4,7 @@ Text/input/Crypto/SubtleCrypto-exportKey.html
Text/input/Crypto/SubtleCrypto-generateKey.html
Text/input/WebAnimations/misc/DocumentTimeline.html
Text/input/Worker/Worker-blob.html
+Text/input/Worker/Worker-close-after-postMessage.html
Text/input/Worker/Worker-crypto.html
Text/input/Worker/Worker-echo.html
Text/input/Worker/Worker-importScripts.html
diff --git a/Tests/LibWeb/Text/expected/Worker/Worker-close-after-postMessage.txt b/Tests/LibWeb/Text/expected/Worker/Worker-close-after-postMessage.txt
new file mode 100644
index 00000000000..88615149d25
--- /dev/null
+++ b/Tests/LibWeb/Text/expected/Worker/Worker-close-after-postMessage.txt
@@ -0,0 +1 @@
+PASS (didn't hang)
\ No newline at end of file
diff --git a/Tests/LibWeb/Text/input/Worker/Worker-close-after-postMessage.html b/Tests/LibWeb/Text/input/Worker/Worker-close-after-postMessage.html
new file mode 100644
index 00000000000..8f9f5565337
--- /dev/null
+++ b/Tests/LibWeb/Text/input/Worker/Worker-close-after-postMessage.html
@@ -0,0 +1,12 @@
+
+
+
diff --git a/Tests/LibWeb/Text/input/Worker/worker-close-after-postMessage.js b/Tests/LibWeb/Text/input/Worker/worker-close-after-postMessage.js
new file mode 100644
index 00000000000..be1eff4f80d
--- /dev/null
+++ b/Tests/LibWeb/Text/input/Worker/worker-close-after-postMessage.js
@@ -0,0 +1,4 @@
+self.onmessage = function () {
+ postMessage("PASS (didn't hang)");
+ self.close();
+};
diff --git a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp
index de2a8fbe1cd..0145165712d 100644
--- a/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp
+++ b/Userland/Libraries/LibWeb/HTML/WorkerGlobalScope.cpp
@@ -68,8 +68,9 @@ void WorkerGlobalScope::set_internal_port(JS::NonnullGCPtr port)
void WorkerGlobalScope::close_a_worker()
{
// 1. Discard any tasks that have been added to workerGlobal's relevant agent's event loop's task queues.
- relevant_settings_object(*this).responsible_event_loop().task_queue().remove_tasks_matching([](HTML::Task const&) {
- return true;
+ relevant_settings_object(*this).responsible_event_loop().task_queue().remove_tasks_matching([](HTML::Task const& task) {
+ // NOTE: We don't discard tasks with the PostedMessage source, as the spec expects PostMessage() to act as if it is invoked immediately
+ return task.source() != HTML::Task::Source::PostedMessage;
});
// 2. Set workerGlobal's closing flag to true. (This prevents any further tasks from being queued.)