diff --git a/src/core/types.ts b/src/core/types.ts
index 90d1817ea..d120fbfb5 100644
--- a/src/core/types.ts
+++ b/src/core/types.ts
@@ -2,7 +2,7 @@ export type Action = "advance" | "replace" | "restore"
export type Position = { x: number; y: number }
-export type StreamSource = {
+export type StreamSource = (EventSource | WebSocket) & {
addEventListener(
type: "message",
listener: (event: MessageEvent) => void,
diff --git a/src/elements/stream_source_element.ts b/src/elements/stream_source_element.ts
index 48f97e5fe..c12047b83 100644
--- a/src/elements/stream_source_element.ts
+++ b/src/elements/stream_source_element.ts
@@ -12,6 +12,8 @@ export class StreamSourceElement extends HTMLElement {
disconnectedCallback() {
if (this.streamSource) {
+ this.streamSource.close()
+
disconnectStreamSource(this.streamSource)
}
}
diff --git a/src/tests/functional/stream_tests.ts b/src/tests/functional/stream_tests.ts
index 3d159b2e3..0fb604726 100644
--- a/src/tests/functional/stream_tests.ts
+++ b/src/tests/functional/stream_tests.ts
@@ -1,6 +1,7 @@
-import { test } from "@playwright/test"
+import { Page, test } from "@playwright/test"
import { assert } from "chai"
import { nextBeat, nextEventNamed, readEventLogs, waitUntilNoSelector, waitUntilText } from "../helpers/page"
+import { StreamSourceElement } from "../../elements/stream_source_element"
test.beforeEach(async ({ page }) => {
await page.goto("/src/tests/fixtures/stream.html")
@@ -104,6 +105,9 @@ test("test receiving a stream message over SSE", async ({ page }) => {
``
)
})
+ await nextBeat()
+ assert.equal(await getReadyState(page, "stream-source"), await page.evaluate(() => EventSource.OPEN))
+
const messages = await page.locator("#messages .message")
assert.deepEqual(await messages.allTextContents(), ["First"])
@@ -113,11 +117,33 @@ test("test receiving a stream message over SSE", async ({ page }) => {
await waitUntilText(page, "Hello world!")
assert.deepEqual(await messages.allTextContents(), ["First", "Hello world!"])
- await page.evaluate(() => document.getElementById("stream-source")?.remove())
- await nextBeat()
+ const readyState = await page.evaluate((id) => {
+ const element = document.getElementById(id) as StreamSourceElement
+
+ if (element && element.streamSource) {
+ element.remove()
+
+ return element.streamSource.readyState
+ } else {
+ return -1
+ }
+ }, "stream-source")
+ assert.equal(readyState, await page.evaluate(() => EventSource.CLOSED))
await page.click("#async button")
await nextBeat()
assert.deepEqual(await messages.allTextContents(), ["First", "Hello world!"])
})
+
+async function getReadyState(page: Page, id: string): Promise {
+ return page.evaluate((id) => {
+ const element = document.getElementById(id) as StreamSourceElement
+
+ if (element?.streamSource) {
+ return element.streamSource.readyState
+ } else {
+ return -1
+ }
+ }, id)
+}