diff --git a/tests/browser/audio-check.test.js b/tests/browser/audio-check.test.js index e78bc38ea..4a1db7ff0 100644 --- a/tests/browser/audio-check.test.js +++ b/tests/browser/audio-check.test.js @@ -8,6 +8,7 @@ import { test } from "node:test"; import assert from "node:assert/strict"; import { FakeStream, FakeTrack, settle } from "./fake-media.js"; +import { loadInterview, read } from "./source.js"; import { MIC_CONFIRM_FRAMES, @@ -106,6 +107,41 @@ test("hearing nothing keeps the room closed even with a working microphone", () assert.equal(state.blocker, "output"); }); +test("the Sound step reads the same before and after the preflight paints it", () => { + // The candidate may confirm without playing anything, so no line may read + // as if the test sound were required. The step text is written twice, once + // in the markup and again by `paintPreflight` on every refresh, and the two + // drifting apart would change the instruction under the candidate's eyes. + const markup = /id="audio-output-state"[^>]*>([^<]*) + (target[key] ??= { textContent: "", classList: { toggle() {} } }), + }, + ); + const { paintPreflight } = loadInterview(["paintPreflight"], { nodes }); + paintPreflight( + mediaReadiness({ ...passingMedia, outputConfirmed: false }), + null, + ); + assert.equal( + nodes.audioOutputState.textContent, + markup.replace(/\s+/g, " ").trim(), + ); + assert.equal( + nodes.audioOutputState.textContent, + 'play a test sound to check your audio, or click "I heard it" if it already works.', + ); + // With output the remaining step, the status line says the same thing. + assert.equal( + nodes.audioStatus.textContent, + 'Play the test tone or voice to check your audio, or click "I heard it" if it already works.', + ); +}); + test("all required media proven opens the room", () => { const state = mediaReadiness(passingMedia); diff --git a/web/audio-check.js b/web/audio-check.js index 7c9b4b0a7..5d90bc704 100644 --- a/web/audio-check.js +++ b/web/audio-check.js @@ -124,7 +124,8 @@ export function mediaReadiness({ steps, ready: false, blocker: "output", - message: "Play the test tone or voice and confirm you heard it.", + message: + 'Play the test tone or voice to check your audio, or click "I heard it" if it already works.', }; } return { diff --git a/web/interview.html b/web/interview.html index 416fa113a..e434c31b4 100644 --- a/web/interview.html +++ b/web/interview.html @@ -712,7 +712,8 @@

Sound — play a test sound and confirm you heard it.play a test sound to check your audio, or click "I heard + it" if it already works.

diff --git a/web/interview.js b/web/interview.js index 6c49625b7..1548b17c3 100644 --- a/web/interview.js +++ b/web/interview.js @@ -1704,7 +1704,7 @@ function paintPreflight(state, hint) { nodes.audioStatus.textContent = hint || state.message; nodes.audioOutputState.textContent = state.steps.output ? "Confirmed" - : "play a test sound and confirm you heard it."; + : 'play a test sound to check your audio, or click "I heard it" if it already works.'; nodes.cameraState.textContent = state.cameraSkipped ? `Not used (${state.cameraSkipReason}).` : state.steps.camera