diff --git a/test-app/app/src/main/assets/app/tests/testMessaging.js b/test-app/app/src/main/assets/app/tests/testMessaging.js index c06a46037..faa6cfe2d 100644 --- a/test-app/app/src/main/assets/app/tests/testMessaging.js +++ b/test-app/app/src/main/assets/app/tests/testMessaging.js @@ -155,10 +155,11 @@ describe("Messaging runtime edges", function () { var got = []; worker.on("message", function (value) { got.push(value); - if (got.length === 3) { + if (got.length === 4) { setTimeout(function () { - // Three messages: the once() registration fires only - // for the first, the on() one for all three. + // Three messages: the on() registration fires for all + // three, the once() one only for the first. The settle + // window catches a fifth reply. expect(got).toEqual([1, 2, 3, 4]); worker.terminate(); done(); diff --git a/test-app/app/src/main/assets/app/tests/testRuntimeImplementedAPIs.js b/test-app/app/src/main/assets/app/tests/testRuntimeImplementedAPIs.js index 27b784df2..c17807cb8 100644 --- a/test-app/app/src/main/assets/app/tests/testRuntimeImplementedAPIs.js +++ b/test-app/app/src/main/assets/app/tests/testRuntimeImplementedAPIs.js @@ -64,9 +64,12 @@ describe("DOMException canary", function () { }); it("serializes through structuredClone on this runtime", function () { - var clone = structuredClone(new DOMException("x", "AbortError")); + var original = new DOMException("x", "AbortError"); + original.stack = "DOMException stack sentinel"; + var clone = structuredClone(original); expect(clone instanceof DOMException).toBe(true); expect(clone.name).toBe("AbortError"); + expect(clone.stack).toBe("DOMException stack sentinel"); }); it("clones the isolate's first DOMException even when a getter creates it mid-clone", function (done) { diff --git a/test-app/runtime/src/main/cpp/WorkerEvents.cpp b/test-app/runtime/src/main/cpp/WorkerEvents.cpp index 978aeb014..7ed146b52 100644 --- a/test-app/runtime/src/main/cpp/WorkerEvents.cpp +++ b/test-app/runtime/src/main/cpp/WorkerEvents.cpp @@ -62,6 +62,9 @@ void WorkerEvents::Init(Local context) { void WorkerEvents::EmitMessage(Isolate* isolate, Local receiver, const std::shared_ptr& message) { + // Callers drain a whole batch under one scope; without this the handles of + // every message in the batch stay alive until the batch ends. + HandleScope handleScope(isolate); auto* state = RuntimeState::For(isolate); if (state == nullptr || state->emitMessage.IsEmpty()) { return;