diff options
Diffstat (limited to 'testing/web-platform/tests/audio-output/setSinkId-manual.https.html')
-rw-r--r-- | testing/web-platform/tests/audio-output/setSinkId-manual.https.html | 132 |
1 files changed, 132 insertions, 0 deletions
diff --git a/testing/web-platform/tests/audio-output/setSinkId-manual.https.html b/testing/web-platform/tests/audio-output/setSinkId-manual.https.html new file mode 100644 index 0000000000..a083cdf092 --- /dev/null +++ b/testing/web-platform/tests/audio-output/setSinkId-manual.https.html @@ -0,0 +1,132 @@ +<!doctype html> +<html> +<head> +<title>Test setSinkId behavior with permissions / device changes</title> +<link rel="author" title="Dominique Hazael-Massieux" href="mailto:dom@w3.org"/> +<link rel="help" href="https://www.w3.org/TR/audio-output/#dom-htmlmediaelement-setsinkid"> +<meta name="timeout" content="long"> + +</head> +<body> +<h1 class="instructions">Description</h1> +<p class="instructions">This test checks that <code>setSinkId</code> follows the algorithm, this includes manually checking the proper rendering on new output devices.</p> +<p class="instructions">When prompted to access microphones, please accept as this is the only current way to get permissions for associated output devices.</p> +<p class="instructions">For each authorized output device, check that selecting it makes the audio beat rendered on the corresponding device.</p> +<p>Available but unauthorized devices (only those for which we can gain permission can be selected):</p> +<ul id="available"></ul> +<p>Authorized devices:</p> +<ul id="authorized"></ul> +<audio controls id="beat" src="/media/sound_5.mp3" loop></audio> + +<div id='log'></div> +<script src=/resources/testharness.js></script> +<script src=/resources/testharnessreport.js></script> +<script> +"use strict"; + +const is_output = d => d.kind === "audiooutput"; +const by_id = (id) => d => d.groupId === id; +const is_input = d => d.kind === "audioinput"; +const audio = document.getElementById("beat"); +const available = document.getElementById("available"); +const authorized = document.getElementById("authorized"); + +let outputList; + +const selectDeviceTester = (t) => (e) => { + const groupId = e.target.dataset["groupid"]; + const device = outputList.find(by_id(groupId)); + if (audio.paused) audio.play(); + promise_test(pt => audio.setSinkId(device.deviceId).then(() => { + assert_equals(device.deviceId, audio.sinkId); + + const pass = document.createElement("button"); + const fail = document.createElement("button"); + + const result = (bool) => () => { + assert_true(bool, "Sound rendered on right device"); + fail.remove(); + pass.remove(); + audio.pause(); + e.target.checked = false; + e.target.disabled = true; + t.done(); + }; + + pass.style.backgroundColor = "#0f0"; + pass.textContent = "\u2713 Sound plays on " + device.label; + pass.addEventListener("click", result(true)); + + fail.style.backgroundColor = "#f00"; + fail.textContent = "\u274C Sound doesn't play on " + device.label; + fail.addEventListener("click", result(true)); + + const container = e.target.parentNode.parentNode; + container.appendChild(pass); + container.appendChild(fail); + }), "setSinkId for " + device.label + " resolves"); +}; + +const addAuthorizedDevice = (groupId) => { + const device = outputList.find(by_id(groupId)); + const async_t = async_test("Selecting output device " + device.label + " makes the audio rendered on the proper device"); + const li = document.createElement("li"); + const label = document.createElement("label"); + const input = document.createElement("input"); + input.type = "radio"; + input.name = "device"; + input.dataset["groupid"] = device.groupId; + input.addEventListener("change", selectDeviceTester(async_t)); + const span = document.createElement("span"); + span.textContent = device.label; + label.appendChild(input); + label.appendChild(span); + li.appendChild(label); + authorized.appendChild(li); +}; + +const authorizeDeviceTester = (t) => (e) => { + const groupId = e.target.dataset["groupid"]; + navigator.mediaDevices.getUserMedia({audio: {groupId}}) + .then( () => { + addAuthorizedDevice(groupId); + t.done(); + }); +}; + +promise_test(gum => + navigator.mediaDevices.getUserMedia({audio: true}).then( + () => { + promise_test(t => + navigator.mediaDevices.enumerateDevices().then(list => { + assert_not_equals(list.find(is_output), undefined, "media device list includes at least one audio output device"); + outputList = list.filter(is_output); + outputList.forEach(d => { + const li = document.createElement("li"); + assert_not_equals(d.label, "", "Audio Output Device Labels are available after permission grant"); + li.textContent = d.label; + // Check permission + promise_test(perm => navigator.permissions.query({name: "speaker", deviceId: d.deviceId}).then(({state}) => { + if (state === "granted") { + addAuthorizedDevice(d.groupId); + } else if (state === "prompt") { + const inp = list.find(inp => inp.kind === "audioinput" && inp.groupId === d.groupId); + if (inp || true) { + const async_t = async_test("Authorizing output devices via permission requests for microphones works"); + const button = document.createElement("button"); + button.textContent = "Authorize access"; + button.dataset["groupid"] = d.groupId; + button.addEventListener("click", async_t.step_func_done(authorizeDeviceTester(async_t))); + li.appendChild(button); + } + available.appendChild(li); + } + }, () => { + // if we can't query the permission, we assume it's granted :/ + addAuthorizedDevice(d.groupId); + }) + , "Query permission to use " + d.label); + }); + }), "List media devices"); + }), "Authorize mike access"); +</script> |