diff --git a/app/components/StreamViewer/ConnectionStatus.test.tsx b/app/components/StreamViewer/ConnectionStatus.test.tsx
new file mode 100644
index 0000000..6a592de
--- /dev/null
+++ b/app/components/StreamViewer/ConnectionStatus.test.tsx
@@ -0,0 +1,32 @@
+import { render, screen } from "@testing-library/react"
+import { ConnectionStatus } from "./ConnectionStatus"
+
+describe("ConnectionStatus", () => {
+ it("renders the connecting status correctly", () => {
+ const { container } = render()
+ expect(screen.getByText("connecting")).toBeInTheDocument()
+ const dot = container.querySelector(".rounded-full")
+ expect(dot).toHaveClass("bg-yellow-500")
+ })
+
+ it("renders the connected status correctly", () => {
+ const { container } = render()
+ expect(screen.getByText("connected")).toBeInTheDocument()
+ const dot = container.querySelector(".rounded-full")
+ expect(dot).toHaveClass("bg-green-500")
+ })
+
+ it("renders the disconnected status correctly", () => {
+ const { container } = render()
+ expect(screen.getByText("disconnected")).toBeInTheDocument()
+ const dot = container.querySelector(".rounded-full")
+ expect(dot).toHaveClass("bg-gray-500")
+ })
+
+ it("renders the error status correctly (error state test)", () => {
+ const { container } = render()
+ expect(screen.getByText("error")).toBeInTheDocument()
+ const dot = container.querySelector(".rounded-full")
+ expect(dot).toHaveClass("bg-red-500")
+ })
+})
diff --git a/app/components/StreamViewer/StreamFeed.test.tsx b/app/components/StreamViewer/StreamFeed.test.tsx
new file mode 100644
index 0000000..c7bec75
--- /dev/null
+++ b/app/components/StreamViewer/StreamFeed.test.tsx
@@ -0,0 +1,40 @@
+import { render, screen } from "@testing-library/react"
+import { StreamFeed } from "./StreamFeed"
+
+describe("StreamFeed", () => {
+ it("renders empty state when no events are provided (empty/error state test)", () => {
+ render()
+ expect(screen.getByText("No events received yet.")).toBeInTheDocument()
+ })
+
+ it("renders a list of stream events correctly (rendering test)", () => {
+ const events = [
+ {
+ id: "1",
+ type: "info",
+ timestamp: "2026-06-18T12:00:00.000Z",
+ message: "Stream started",
+ },
+ {
+ id: "2",
+ type: "warning",
+ timestamp: "2026-06-18T12:05:00.000Z",
+ message: "High latency detected",
+ },
+ ]
+
+ render()
+
+ expect(screen.getByText("info")).toBeInTheDocument()
+ expect(screen.getByText("Stream started")).toBeInTheDocument()
+
+ expect(screen.getByText("warning")).toBeInTheDocument()
+ expect(screen.getByText("High latency detected")).toBeInTheDocument()
+
+ // Verify times are rendered
+ const time1 = new Date("2026-06-18T12:00:00.000Z").toLocaleTimeString()
+ const time2 = new Date("2026-06-18T12:05:00.000Z").toLocaleTimeString()
+ expect(screen.getByText(time1)).toBeInTheDocument()
+ expect(screen.getByText(time2)).toBeInTheDocument()
+ })
+})
diff --git a/app/components/StreamViewer/StreamViewer.test.tsx b/app/components/StreamViewer/StreamViewer.test.tsx
new file mode 100644
index 0000000..56baa92
--- /dev/null
+++ b/app/components/StreamViewer/StreamViewer.test.tsx
@@ -0,0 +1,63 @@
+import { render, screen } from "@testing-library/react"
+import { StreamViewer } from "./StreamViewer"
+import { useStreamSocket } from "../../hooks/useStreamSocket"
+
+// Mock the useStreamSocket hook
+jest.mock("../../hooks/useStreamSocket")
+
+const mockUseStreamSocket = useStreamSocket as jest.MockedFunction<
+ typeof useStreamSocket
+>
+
+describe("StreamViewer", () => {
+ beforeEach(() => {
+ jest.clearAllMocks()
+ })
+
+ it("renders connecting state and empty feed (rendering test)", () => {
+ mockUseStreamSocket.mockReturnValue({
+ status: "connecting",
+ events: [],
+ })
+
+ render()
+
+ expect(screen.getByText("Live Stream Feed")).toBeInTheDocument()
+ expect(screen.getByText("connecting")).toBeInTheDocument()
+ expect(screen.getByText("No events received yet.")).toBeInTheDocument()
+ expect(mockUseStreamSocket).toHaveBeenCalledWith("ws://localhost:3001")
+ })
+
+ it("renders connected state with events (interaction / data rendering test)", () => {
+ const mockEvents = [
+ {
+ id: "event-1",
+ type: "click",
+ timestamp: "2026-06-18T12:00:00.000Z",
+ message: "User clicked submit",
+ },
+ ]
+ mockUseStreamSocket.mockReturnValue({
+ status: "connected",
+ events: mockEvents,
+ })
+
+ render()
+
+ expect(screen.getByText("connected")).toBeInTheDocument()
+ expect(screen.getByText("click")).toBeInTheDocument()
+ expect(screen.getByText("User clicked submit")).toBeInTheDocument()
+ })
+
+ it("renders error state (error state test)", () => {
+ mockUseStreamSocket.mockReturnValue({
+ status: "error",
+ events: [],
+ })
+
+ render()
+
+ expect(screen.getByText("error")).toBeInTheDocument()
+ expect(screen.getByText("No events received yet.")).toBeInTheDocument()
+ })
+})
diff --git a/app/components/streams/embed-snippet.test.tsx b/app/components/streams/embed-snippet.test.tsx
new file mode 100644
index 0000000..9969093
--- /dev/null
+++ b/app/components/streams/embed-snippet.test.tsx
@@ -0,0 +1,184 @@
+import { render, screen, act, waitFor } from "@testing-library/react"
+import userEvent from "@testing-library/user-event"
+import { EmbedSnippet } from "./embed-snippet"
+
+type MutableNavigator = Omit & { clipboard?: unknown }
+
+describe("EmbedSnippet", () => {
+ const mockWriteText = jest.fn()
+ let originalClipboardDescriptor: PropertyDescriptor | undefined
+
+ beforeAll(() => {
+ originalClipboardDescriptor = Object.getOwnPropertyDescriptor(
+ Navigator.prototype,
+ "clipboard",
+ )
+
+ const mockClipboard = {
+ writeText: mockWriteText,
+ }
+
+ // Define on prototype
+ Object.defineProperty(Navigator.prototype, "clipboard", {
+ value: mockClipboard,
+ configurable: true,
+ writable: true,
+ })
+
+ // Define on window.navigator
+ try {
+ Object.defineProperty(window.navigator, "clipboard", {
+ value: mockClipboard,
+ configurable: true,
+ writable: true,
+ })
+ } catch (e) {}
+
+ // Define on global.navigator
+ try {
+ Object.defineProperty(navigator, "clipboard", {
+ value: mockClipboard,
+ configurable: true,
+ writable: true,
+ })
+ } catch (e) {}
+ })
+
+ afterAll(() => {
+ if (originalClipboardDescriptor) {
+ Object.defineProperty(
+ Navigator.prototype,
+ "clipboard",
+ originalClipboardDescriptor,
+ )
+ } else {
+ delete (Navigator.prototype as unknown as MutableNavigator).clipboard
+ }
+
+ try {
+ delete (window.navigator as unknown as MutableNavigator).clipboard
+ } catch (e) {}
+
+ try {
+ delete (navigator as unknown as MutableNavigator).clipboard
+ } catch (e) {}
+ })
+
+
+
+
+ beforeEach(() => {
+ jest.clearAllMocks()
+ jest.useFakeTimers()
+ mockWriteText.mockResolvedValue(undefined)
+ })
+
+ afterEach(() => {
+ jest.useRealTimers()
+ })
+
+ it("renders the iframe embed code with publicId (rendering test)", () => {
+ render()
+
+ expect(screen.getByText("Embed snippet")).toBeInTheDocument()
+ const codeContainer = screen.getByLabelText("iframe embed code")
+ expect(codeContainer).toHaveTextContent(
+ '