Bug 1399413 - add mochitests to check multi-tabs gUM. r?jib draft
authorMunro Mengjue Chiang <mchiang@mozilla.com>
Tue, 07 Nov 2017 18:53:47 +0800
changeset 698105 b0de6e49fd62239fb5cb03d3db30d3e62dc808a7
parent 698104 01ccc04507d31e524ceb38c60dbd42a4e66f6951
child 698317 0928fbe1ac09348644c58429d8fa7ec5ed7eb1b0
push id89206
push userbmo:mchiang@mozilla.com
push dateWed, 15 Nov 2017 09:26:10 +0000
reviewersjib
bugs1399413
milestone59.0a1
Bug 1399413 - add mochitests to check multi-tabs gUM. r?jib MozReview-Commit-ID: 8ZtD1ArafvN
browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js
--- a/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js
+++ b/browser/base/content/test/webrtc/browser_devices_get_user_media_multi_process.js
@@ -107,13 +107,221 @@ var gTests = [
     // Close the first tab's stream and verify that all indicators are removed.
     await closeStream();
 
     ok(!webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator hidden");
     is(webrtcUI.getActiveStreams(true, true, true).length, 0, "0 active streams");
   }
 },
 
+{
+  desc: "getUserMedia camera in a first process + camera in a second process",
+  run: async function checkMultiProcessCamera() {
+
+    // Request camera in the first tab.
+    let promise = promisePopupNotificationShown("webRTC-shareDevices");
+    await promiseRequestDevice(false, true);
+    await promise;
+    await expectObserverCalled("getUserMedia:request");
+
+    checkDeviceSelectors(false, true);
+
+    let indicator = promiseIndicatorWindow();
+    await promiseMessage("ok", () => {
+      PopupNotifications.panel.firstChild.button.click();
+    });
+    await expectObserverCalled("getUserMedia:response:allow");
+    await expectObserverCalled("recording-device-events");
+    Assert.deepEqual((await getMediaCaptureState()), {video: true},
+                     "expected camera to be shared");
+
+    await indicator;
+    await checkSharingUI({video: true});
+
+    ok(webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator shown");
+    ok(webrtcUI.showCameraIndicator, "webrtcUI wants the camera indicator shown");
+    ok(!webrtcUI.showMicrophoneIndicator, "webrtcUI wants the mic indicator hidden");
+    is(webrtcUI.getActiveStreams(true).length, 1, "1 active camera stream");
+    is(webrtcUI.getActiveStreams(true, true, true).length, 1, "1 active stream");
+
+    await expectNoObserverCalled();
+
+    // If we have reached the max process count already, increase it to ensure
+    // our new tab can have its own content process.
+    var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+                 .getService(Ci.nsIMessageBroadcaster);
+    ppmm.QueryInterface(Ci.nsIProcessScriptLoader);
+    let childCount = ppmm.childCount;
+    let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount");
+    // The first check is because if we are on a branch where e10s-multi is
+    // disabled, we want to keep testing e10s with a single content process.
+    // The + 1 is because ppmm.childCount also counts the chrome process
+    // (which also runs process scripts).
+    if (maxContentProcess > 1 && childCount == maxContentProcess + 1) {
+      await SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount",
+                                                childCount]]});
+    }
+
+    // Open a new tab with a different hostname.
+    let url = gBrowser.currentURI.spec.replace("https://example.com/",
+                                               "http://127.0.0.1:8888/");
+    let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+    tab.linkedBrowser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
+
+    // Request camera in the second tab.
+    promise = promisePopupNotificationShown("webRTC-shareDevices");
+    await promiseRequestDevice(false, true);
+    await promise;
+    await expectObserverCalled("getUserMedia:request");
+
+    checkDeviceSelectors(false, true);
+
+    await promiseMessage("ok", () => {
+      PopupNotifications.panel.firstChild.button.click();
+    });
+    await expectObserverCalled("getUserMedia:response:allow");
+    await expectObserverCalled("recording-device-events");
+
+    await checkSharingUI({video: true}, window, {video: true});
+
+    ok(webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator shown");
+    ok(webrtcUI.showCameraIndicator, "webrtcUI wants the camera indicator shown");
+    ok(!webrtcUI.showMicrophoneIndicator, "webrtcUI wants the mic indicator hidden");
+    is(webrtcUI.getActiveStreams(true).length, 2, "2 active camera streams");
+    is(webrtcUI.getActiveStreams(true, true, true).length, 2, "2 active streams");
+
+    info("removing the second tab");
+    await BrowserTestUtils.removeTab(tab);
+
+    // Check that we still show the sharing indicators for the first tab's stream.
+    await promiseWaitForCondition(() => webrtcUI.showCameraIndicator);
+    ok(webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator shown");
+    ok(webrtcUI.showCameraIndicator, "webrtcUI wants the camera indicator shown");
+    ok(!webrtcUI.showMicrophoneIndicator, "webrtcUI wants the mic indicator hidden");
+    is(webrtcUI.getActiveStreams(true).length, 1, "1 active camera stream");
+    is(webrtcUI.getActiveStreams(true, true, true).length, 1, "1 active stream");
+
+    await checkSharingUI({video: true});
+
+    // When both tabs use the same content process, the frame script for the
+    // first tab receives observer notifications for things happening in the
+    // second tab, so let's clear the observer call counts before we cleanup
+    // in the first tab.
+    await ignoreObserversCalled();
+
+    // Close the first tab's stream and verify that all indicators are removed.
+    await closeStream();
+
+    ok(!webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator hidden");
+    is(webrtcUI.getActiveStreams(true, true, true).length, 0, "0 active streams");
+  }
+},
+
+{
+  desc: "getUserMedia screen sharing in a first process + screen sharing in a second process",
+  run: async function checkMultiProcessScreen() {
+
+    // Request screen sharing in the first tab.
+    let promise = promisePopupNotificationShown("webRTC-shareDevices");
+    await promiseRequestDevice(false, true, null, "screen");
+    await promise;
+    await expectObserverCalled("getUserMedia:request");
+
+    is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
+       "webRTC-shareScreen-notification-icon", "anchored to device icon");
+    checkDeviceSelectors(false, false, true);
+
+    // Select the first screen so that we can have a stream.
+    document.getElementById("webRTC-selectWindow-menulist").getItemAtIndex(2).doCommand();
+
+    let indicator = promiseIndicatorWindow();
+    await promiseMessage("ok", () => {
+      PopupNotifications.panel.firstChild.button.click();
+    });
+    await expectObserverCalled("getUserMedia:response:allow");
+    await expectObserverCalled("recording-device-events");
+    Assert.deepEqual((await getMediaCaptureState()), {screen: "Screen"},
+                     "expected screen to be shared");
+
+    await indicator;
+    await checkSharingUI({screen: "Screen"});
+
+    ok(webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator shown");
+    ok(webrtcUI.showScreenSharingIndicator, "webrtcUI wants the screen sharing indicator shown");
+    ok(!webrtcUI.showCameraIndicator, "webrtcUI wants the camera indicator hidden");
+    ok(!webrtcUI.showMicrophoneIndicator, "webrtcUI wants the mic indicator hidden");
+    is(webrtcUI.getActiveStreams(false, false, true).length, 1, "1 active screen sharing stream");
+    is(webrtcUI.getActiveStreams(true, true, true).length, 1, "1 active stream");
+
+    await expectNoObserverCalled();
+
+    // If we have reached the max process count already, increase it to ensure
+    // our new tab can have its own content process.
+    var ppmm = Cc["@mozilla.org/parentprocessmessagemanager;1"]
+                 .getService(Ci.nsIMessageBroadcaster);
+    ppmm.QueryInterface(Ci.nsIProcessScriptLoader);
+    let childCount = ppmm.childCount;
+    let maxContentProcess = Services.prefs.getIntPref("dom.ipc.processCount");
+    // The first check is because if we are on a branch where e10s-multi is
+    // disabled, we want to keep testing e10s with a single content process.
+    // The + 1 is because ppmm.childCount also counts the chrome process
+    // (which also runs process scripts).
+    if (maxContentProcess > 1 && childCount == maxContentProcess + 1) {
+      await SpecialPowers.pushPrefEnv({"set": [["dom.ipc.processCount",
+                                                childCount]]});
+    }
+
+    // Open a new tab with a different hostname.
+    let url = gBrowser.currentURI.spec.replace("https://example.com/",
+                                               "https://example.com/");
+    let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
+    tab.linkedBrowser.messageManager.loadFrameScript(CONTENT_SCRIPT_HELPER, true);
+
+    // Request screen sharing in the second tab.
+    promise = promisePopupNotificationShown("webRTC-shareDevices");
+    await promiseRequestDevice(false, true, null, "screen");
+    await promise;
+    await expectObserverCalled("getUserMedia:request");
+
+    is(PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
+       "webRTC-shareScreen-notification-icon", "anchored to device icon");
+    checkDeviceSelectors(false, false, true);
+
+    // Select the first screen so that we can have a stream.
+    document.getElementById("webRTC-selectWindow-menulist").getItemAtIndex(2).doCommand();
+
+    await promiseMessage("ok", () => {
+      PopupNotifications.panel.firstChild.button.click();
+    });
+    await expectObserverCalled("getUserMedia:response:allow");
+    await expectObserverCalled("recording-device-events");
+
+    await checkSharingUI({screen: "Screen"}, window, {screen: "Screen"});
+
+    ok(webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator shown");
+    ok(webrtcUI.showScreenSharingIndicator, "webrtcUI wants the screen sharing indicator shown");
+    ok(!webrtcUI.showCameraIndicator, "webrtcUI wants the camera indicator hidden");
+    ok(!webrtcUI.showMicrophoneIndicator, "webrtcUI wants the mic indicator hidden");
+    is(webrtcUI.getActiveStreams(false, false, true).length, 2, "2 active desktop sharing streams");
+    is(webrtcUI.getActiveStreams(true, true, true).length, 2, "2 active streams");
+
+    info("removing the second tab");
+    await BrowserTestUtils.removeTab(tab);
+
+    // When both tabs use the same content process, the frame script for the
+    // first tab receives observer notifications for things happening in the
+    // second tab, so let's clear the observer call counts before we cleanup
+    // in the first tab.
+    await ignoreObserversCalled();
+
+    // Close the first tab's stream and verify that all indicators are removed.
+    await closeStream();
+
+    ok(!webrtcUI.showGlobalIndicator, "webrtcUI wants the global indicator hidden");
+    is(webrtcUI.getActiveStreams(true, true, true).length, 0, "0 active streams");
+  }
+},
+
 ];
 
 add_task(async function test() {
   await runTests(gTests);
 });