- Two participants, for what only a real call can show: a device switch that
neither drops the media session nor rejoins, and a meter that keeps moving
while muted while the peer is still shown the mute rather than left to infer
it from silence.
- The component harness covers what only a host page shows: every device
reachable in a small container, the list sized against the call rather than
the window, and the menu following the call area when the host resizes it.
- Synthetic devices are patched onto the media element and the audio context
alike, so a browser with no hardware still enumerates and still routes.
Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
The widget tests cannot reach what makes a component different, because the
iframe used to guarantee it: that Element Call stays inside the space it was
given, and that two of them can exist in one page. So the development harness
gets driven by Playwright.
Three tests. Two components in one page holding a real call between two devices
of one account. The settings dialog and the reaction picker staying inside the
container the host gave, asserted by bounding box. And the host bridge
reporting in both directions, including a host-initiated mute coming back as a
report of the new state.
The containment test is the one worth having: both of the escapes found by
running the harness by hand — the settings dialog centred on the window, and
the reaction picker at 82vh landing below the container — would have failed it,
and neither was visible to typechecking, linting or the unit tests.
Users and rooms are created through the Synapse admin and client-server APIs
rather than by driving an interface, and the harness now takes its credentials
from its own query string so that a test can say which account and room to use.
A host reading its own URL is proper; it was Element Call doing so that was the
mistake.
Playwright gains a second web server for the harness on port 3001, a Vite dev
server whether or not the app itself is served from Docker, since the harness is
a development page with nothing to build.