Anruf: der Lautsprecher -- und warum es kein Freisprech-Knopf ist
Filipe: "die funktion lautsprecher fehlt." Er ist das Gegenstueck zum Mikrofon: "Mikro aus" heisst, die anderen hoeren MICH nicht -- "Lautsprecher aus" heisst, ICH hoere sie nicht. Beides braucht man, aus verschiedenen Gruenden: das Mikro, wenn es bei einem selbst laut ist; den Lautsprecher, wenn nebenher etwas laeuft oder jemand ins Zimmer kommt. WAS BEWUSST NICHT GEBAUT WURDE: der Umschalter zwischen Hoermuschel und Freisprechen, den ein Telefon hat. Recherchiert statt geraten -- den gibt es im Browser nicht: Auf dem iPhone entscheidet Safari selbst, wohin der Ton geht, und Android laesst einzelne Toene gar nicht auf ein anderes Geraet legen (setSinkId ist dort nicht verfuegbar, weil die Plattform es nicht hergibt). Ein Knopf, der dort nichts tut, waere schlimmer als keiner -- man drueckt ihn und sucht den Fehler dann bei sich. Wo es GEHT (Rechner mit Chrome, Edge, Safari), steht dafuer eine echte Geraeteauswahl daneben. Sie erscheint nur, wenn es mehr als ein Geraet gibt UND die Namen bekannt sind; eine Auswahl mit einem Eintrag ist keine Auswahl, sondern eine Behauptung. DIE PRUEFUNG, AUF DIE ES ANKOMMT: Kommt jemand dazu oder geht jemand, werden die Toenelemente NEU GEBAUT -- und neue Elemente wissen nichts von einem Schalter, der vorher umgelegt wurde. Genau daran scheitern solche Knoepfe sonst: Sie wirken, bis sich die Runde aendert, und dann hoert man ploetzlich wieder mit. Gegenprobe (Anwenden nach dem Neuzeichnen ausgebaut) macht genau diese eine Pruefung rot, waehrend alle anderen gruen bleiben. Geprueft: pruef-anruf 73 -> 80, im echten Dreiergespraech im Browser. Co-Authored-By: Claude Opus 5 <[email protected]>
This commit is contained in:
@@ -628,6 +628,58 @@ melde("=== 8. Zu dritt ===");
|
||||
`${wer} hoert BEIDE anderen (${z.stroeme} Stroeme, „${z.lage}")`);
|
||||
}
|
||||
|
||||
/* ---- DER LAUTSPRECHER (18.09.2026) -------------------------
|
||||
Filipe: „die funktion lautsprecher fehlt."
|
||||
|
||||
Gegenstueck zum Mikrofon: „Mikro aus" heisst, die anderen
|
||||
hoeren mich nicht; „Lautsprecher aus" heisst, ich hoere sie
|
||||
nicht.
|
||||
|
||||
DIE PRUEFUNG, AUF DIE ES ANKOMMT, ist die dritte: Kommt
|
||||
jemand dazu oder geht jemand, werden die Toenelemente NEU
|
||||
GEBAUT -- und neue Elemente wissen nichts von einem Schalter,
|
||||
der vorher umgelegt wurde. Genau daran scheitern solche
|
||||
Knoepfe sonst: Sie wirken, bis sich die Runde aendert, und
|
||||
dann hoert man ploetzlich wieder mit. */
|
||||
const stumm = (x) => x.se.evaluate(() =>
|
||||
[...document.querySelectorAll("#anruf-leute audio, #anruf-leute video")]
|
||||
.filter((m) => !m.classList.contains("anruf__bild--ich"))
|
||||
.map((m) => m.muted));
|
||||
|
||||
{
|
||||
const vorher = await stumm(a);
|
||||
/* Die ANZAHL gehoert in die Bedingung: `every` ist auf einer
|
||||
leeren Liste wahr, und dann waere diese Pruefung gruen,
|
||||
ohne ein einziges Element gesehen zu haben. */
|
||||
ok(vorher.length >= 2 && vorher.every((m) => m === false),
|
||||
`vorher hoert DogFather beide (${vorher.length} Stroeme, keiner stumm)`);
|
||||
|
||||
const knopf = await a.se.evaluate(() => {
|
||||
const k = document.getElementById("anruf-hoeren");
|
||||
return k ? { text: k.textContent.trim(), an: k.getAttribute("aria-pressed") } : null;
|
||||
});
|
||||
ok(knopf?.text === "Lautsprecher an" && knopf?.an === "true",
|
||||
`der Lautsprecher-Knopf ist da und steht auf an („${knopf?.text}")`);
|
||||
|
||||
await a.se.click("#anruf-hoeren");
|
||||
await a.se.waitForTimeout(300);
|
||||
const nachher = await stumm(a);
|
||||
ok(nachher.length >= 2 && nachher.every((m) => m === true),
|
||||
`nach dem Druecken ist ALLES stumm (${nachher.length} Stroeme)`);
|
||||
const knopf2 = await a.se.evaluate(() => {
|
||||
const k = document.getElementById("anruf-hoeren");
|
||||
return { text: k.textContent.trim(), an: k.getAttribute("aria-pressed") };
|
||||
});
|
||||
ok(knopf2.text === "Lautsprecher aus" && knopf2.an === "false",
|
||||
`und der Knopf sagt es auch („${knopf2.text}")`);
|
||||
|
||||
/* NUR BEI IHM. Ein Schalter, der bei den anderen mitwirkt,
|
||||
waere kein Lautsprecher, sondern eine Fernbedienung. */
|
||||
const beiB = await stumm(b);
|
||||
ok(beiB.length >= 2 && beiB.every((m) => m === false),
|
||||
`bei der rechten Hand aendert sich nichts (${beiB.length} Stroeme, keiner stumm)`);
|
||||
}
|
||||
|
||||
/* Einer legt auf -- fuer die anderen laeuft es weiter. */
|
||||
await c.se.click("#anruf-auflegen");
|
||||
await c.se.waitForTimeout(2000);
|
||||
@@ -638,6 +690,17 @@ melde("=== 8. Zu dritt ===");
|
||||
ok(zA.stroeme === 1,
|
||||
`und bei DogFather ist genau ein Strom weniger (${zA.stroeme})`);
|
||||
|
||||
/* DIE FALLE: Die Runde hat sich geaendert, die Elemente wurden
|
||||
neu gebaut. Bliebe der Schalter dabei auf der Strecke, wuerde
|
||||
DogFather ploetzlich wieder mithoeren -- ohne dass irgendwo
|
||||
etwas anders aussieht. */
|
||||
const nachWechsel = await stumm(a);
|
||||
ok(nachWechsel.length === 1 && nachWechsel[0] === true,
|
||||
`und der Lautsprecher bleibt aus, obwohl neu gezeichnet wurde (${nachWechsel.length} Strom)`);
|
||||
const knopfNoch = await a.se.evaluate(() =>
|
||||
document.getElementById("anruf-hoeren")?.getAttribute("aria-pressed"));
|
||||
ok(knopfNoch === "false", "auch der Knopf steht noch richtig");
|
||||
|
||||
await a.se.click("#anruf-auflegen");
|
||||
await b.se.click("#anruf-auflegen");
|
||||
await a.se.waitForTimeout(1200);
|
||||
|
||||
Reference in New Issue
Block a user