Bug 1404977 - Tests P1: Add test to check that multiple gums within iFrames succeed. r?pehrsons draft
authorBryce Van Dyk <bvandyk@mozilla.com>
Fri, 27 Apr 2018 12:17:20 -0400
changeset 800922 a03d5d4f274ee4ac162a24996eebc390ea43774c
parent 800921 6750e2de50bd6cc66074b5f68ac586d679b7bd4f
child 800923 e9e19f4b8477fc3a03d17b88caec06d949aa336c
push id111515
push userbvandyk@mozilla.com
push dateTue, 29 May 2018 13:48:26 +0000
reviewerspehrsons
bugs1404977
milestone62.0a1
Bug 1404977 - Tests P1: Add test to check that multiple gums within iFrames succeed. r?pehrsons MozReview-Commit-ID: KD3urI6LyC7
dom/media/tests/mochitest/mochitest.ini
dom/media/tests/mochitest/test_getUserMedia_multipleIframes.html
--- a/dom/media/tests/mochitest/mochitest.ini
+++ b/dom/media/tests/mochitest/mochitest.ini
@@ -80,16 +80,18 @@ skip-if = android_version == '18' # andr
 [test_getUserMedia_mediaElementCapture_tracks.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_mediaElementCapture_video.html]
 skip-if = android_version == '18' # android(Bug 1189784, timeouts on 4.3 emulator)
 [test_getUserMedia_mediaStreamClone.html]
 skip-if = toolkit == 'android' && debug # Bug 1282262
 [test_getUserMedia_mediaStreamConstructors.html]
 [test_getUserMedia_mediaStreamTrackClone.html]
+[test_getUserMedia_multipleIframes.html]
+skip-if = os == 'mac' || os == 'win' || toolkit == 'android' # Bug 1404995, no loopback devices on some platforms
 [test_getUserMedia_playAudioTwice.html]
 [test_getUserMedia_playVideoAudioTwice.html]
 [test_getUserMedia_playVideoTwice.html]
 [test_getUserMedia_scarySources.html]
 skip-if = toolkit == 'android' # no screenshare or windowshare on android
 [test_getUserMedia_spinEventLoop.html]
 [test_getUserMedia_stopAudioStream.html]
 [test_getUserMedia_stopAudioStreamWithFollowupAudio.html]
new file mode 100644
--- /dev/null
+++ b/dom/media/tests/mochitest/test_getUserMedia_multipleIframes.html
@@ -0,0 +1,112 @@
+<!DOCTYPE HTML>
+<html>
+<head>
+  <script type="application/javascript" src="mediaStreamPlayback.js"></script>
+</head>
+<body>
+<pre id="test">
+<script type="application/javascript">
+  createHTML({
+    title: "getUserMedia in Multiple Iframes",
+    bug: "1404977"
+  });
+  /**
+   * Verify that we can successfully call getUserMedia in multiple iframes
+   */
+  runTest(async function() {
+    // Compare constraints and return a string with the differences in
+    // echoCancellation, autoGainControl, and noiseSuppression. The string
+    // will be empty if there are no differences.
+    function getConstraintDifferenceString(constraints, otherConstraints) {
+      let diffString = "";
+      if (constraints.echoCancellation != otherConstraints.echoCancellation) {
+        diffString += "echoCancellation different, ";
+      }
+      if (constraints.autoGainControl != otherConstraints.autoGainControl) {
+        diffString += "autoGainControl different, ";
+      }
+      if (constraints.noiseSuppression != otherConstraints.noiseSuppression) {
+        diffString += "noiseSuppression different, ";
+      }
+      // Replace trailing comma and space if any
+      return diffString.replace(/, $/, "");
+    }
+
+    // We need a real device to get a MediaEngine supporting constraints
+    let audioDevice = SpecialPowers.getCharPref("media.audio_loopback_dev", "");
+    if (!audioDevice) {
+      ok(false, "No device set by framework. Try --use-test-media-devices");
+      return;
+    }
+
+    let requestedConstraints = [
+      true,
+      { echoCancellation: true },
+      { autoGainControl: true },
+      { noiseSuppression: true },
+      { echoCancellation: true, autoGainControl: true },
+      { echoCancellation: true, autoGainControl: true, noiseSuppression: true },
+    ];
+    let iframes = [];
+    let iframeLoadedPromises = [];
+    let gumStreams = [];
+    let playMediaPromises = [];
+
+    for (let i = 0; i < requestedConstraints.length; i++) {
+      let iframe = document.createElement("iframe");
+      // Stick test scripts into the iframes so they can call the gUM helper
+      iframe.srcdoc = `
+      \<html\>
+        \<script type="application/javascript" src="mediaStreamPlayback.js"\>
+        \<\/script\>
+      \<\/html\>`;
+      let loadPromise = new Promise((resolve, reject) => {
+        iframe.onload = () => { resolve(); };
+      });
+      document.documentElement.appendChild(iframe);
+
+      iframes.push(iframe);
+      iframeLoadedPromises.push(loadPromise);
+    }
+    is(iframes.length,
+      requestedConstraints.length,
+      "Should have created an iframe for each constraint");
+
+    // Wait for all iframes to be loaded
+    await Promise.all(iframeLoadedPromises);
+
+    // One by one see if we can grab a gUM stream per iframe
+    for (let i = 0; i < iframes.length; i++) {
+      try {
+        let stream = await iframes[i].contentWindow.getUserMedia({audio: requestedConstraints[i]});
+        gumStreams.push(stream);
+        let differenceString = getConstraintDifferenceString(
+          requestedConstraints[i], stream.getAudioTracks()[0].getSettings());
+        ok(!differenceString,
+          `Stream at index ${i} should have the same constraints as were ` +
+          `requested from gUM. Differences: ${differenceString}`);
+      } catch (e) {
+        ok(false, `getUserMedia calls should not fail! Failed in iframe#: ${i} with: ${e}!`);
+      }
+    }
+    is(gumStreams.length, iframes.length, "Should have a stream for each iframe");
+
+    // Once all streams are collected, make sure constaints haven't changes, play them
+    for (let i = 0; i < gumStreams.length; i++) {
+      let differenceString = getConstraintDifferenceString(
+        requestedConstraints[i], gumStreams[i].getAudioTracks()[0].getSettings());
+      ok(!differenceString,
+        `Stream at index ${i} should not have had contraints altered after ` +
+        `all gUM calls are done. Differences: ${differenceString}`);
+      let testAudio = createMediaElement("audio", `testAudio${i}`);
+      let playback = new LocalMediaStreamPlayback(testAudio, gumStreams[i]);
+      playMediaPromises.push(playback.playMedia(false));
+    }
+
+    await Promise.all(playMediaPromises);
+  });
+
+</script>
+</pre>
+</body>
+</html>