Files
suaveplan/apps/testbed/src/client/pages/network-webrtc/network-webrtc-page.md
2026-05-27 23:29:53 +01:00

3.0 KiB

NetworkWebRtcPage

(no submodules)

## Purpose

The NetworkWebRtcPage demonstrates peer-to-peer WebRTC data channel communication between two browser tabs. It uses the Hono server's /api/signalling routes as a simple SDP exchange intermediary. One tab acts as the host (creates offer, initiates data channel), the other as the peer (polls for offer, creates answer). Once connected, both sides can exchange arbitrary text messages over a reliable ordered data channel.

Features

  • Role-based behaviour (?role=host or ?role=peer) driven from URL search params
  • Session ID (?session=<id>) used to namespace the SDP exchange
  • RTCPeerConnection with public STUN server (stun:stun.l.google.com:19302)
  • Host creates offer via pc.createOffer() and posts to /api/signalling/offer
  • Peer polls /api/signalling/offer, creates answer, posts to /api/signalling/answer
  • Host polls /api/signalling/answer to complete the handshake
  • data-status attribute on status indicator reflects connection state for E2E tests
  • All required data-testid attributes for Playwright E2E testing

Usage: Basic Example

import React from "react";
import { NetworkWebRtcPage } from "./network-webrtc-page.js";

// Open two browser tabs:
// Tab 1: http://localhost:3200/network-webrtc?role=host&session=abc123
// Tab 2: http://localhost:3200/network-webrtc?role=peer&session=abc123

Usage: Advanced Example

In multi-session Playwright tests, the host and peer pages are opened in separate browser contexts:

import { createMultiSession } from "@suaveplan/testing-e2e/multi-session";

const session = await createMultiSession({
  browser,
  count: 2,
  baseUrl: "http://localhost:3200/network-webrtc?session=test-123",
  roles: ["host", "peer"],
});
// session.pages[0] is host, session.pages[1] is peer
await expect(session.pages[0].locator("[data-status='connected']")).toBeVisible();

API Reference

NetworkWebRtcPage(): React.JSX.Element

No props. Role and session ID are read from window.location.search.

data-testid attributes:

  • page-title — the <h1> heading
  • demo-card — wraps the status, message input, and output
  • message-input — text input for sending messages
  • send-button — sends the current input over the data channel
  • output — displays sent and received messages
  • console-panel — bottom console section with usage hints
  • data-status on status paragraph — one of idle | connecting | connected | failed

Implementation Notes

The host creates a data channel before creating the offer, ensuring the peer receives the data channel via the ondatachannel event. Both sides poll the signalling server at 1-second intervals with setInterval/setTimeout; polling is cleared on cleanup via the useEffect return function. The peer retries up to 10 times waiting for the host's offer. The signalling server stores SDPs in a plain in-memory Map — it is not persistent across server restarts and is suitable for demos only.