Source code

Revision control

Copy as Markdown

Other Tools

Test Info: Warnings

  • This test gets skipped with pattern: debug && os == 'win' OR os == 'mac' && os_version == '11.20' && arch == 'aarch64' OR os == 'mac' && os_version == '10.15' && processor == 'x86_64' OR os == 'mac' && os_version == '14.70' && processor == 'x86_64'
  • Manifest: browser/base/content/test/webrtc/browser.toml
/* This Source Code Form is subject to the terms of the Mozilla Public
* License, v. 2.0. If a copy of the MPL was not distributed with this
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
var gTests = [
{
desc: "getUserMedia audio in a first process + video in a second process",
// These tests call enableObserverVerification manually on a second tab, so
// don't add listeners to the first tab.
skipObserverVerification: true,
run: async function checkMultiProcess() {
// The main purpose of this test is to ensure webrtc sharing indicators
// work with multiple content processes, but it makes sense to run this
// test without e10s too to ensure using webrtc devices in two different
// tabs is handled correctly.
// Request audio in the first tab.
let observerPromise = expectObserverCalled("getUserMedia:request");
let promise = promisePopupNotificationShown("webRTC-shareDevices");
await promiseRequestDevice(true);
await promise;
await observerPromise;
checkDeviceSelectors(["microphone"]);
let observerPromise1 = expectObserverCalled(
"getUserMedia:response:allow"
);
let observerPromise2 = expectObserverCalled("recording-device-events");
let indicator = promiseIndicatorWindow();
await promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});
await observerPromise1;
await observerPromise2;
Assert.deepEqual(
await getMediaCaptureState(),
{ audio: true },
"expected microphone to be shared"
);
await indicator;
await checkSharingUI({ audio: true });
ok(
webrtcUI.showGlobalIndicator,
"webrtcUI wants the global indicator shown"
);
ok(
!webrtcUI.showCameraIndicator,
"webrtcUI wants the camera indicator hidden"
);
ok(
webrtcUI.showMicrophoneIndicator,
"webrtcUI wants the mic indicator shown"
);
is(
webrtcUI.getActiveStreams(false, true).length,
1,
"1 active audio stream"
);
is(
webrtcUI.getActiveStreams(true, true, true).length,
1,
"1 active stream"
);
// If we have reached the max process count already, increase it to ensure
// our new tab can have its own content process.
let childCount = Services.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(
);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
await enableObserverVerification();
// Request video.
observerPromise = expectObserverCalled("getUserMedia:request");
promise = promisePopupNotificationShown("webRTC-shareDevices");
await promiseRequestDevice(false, true);
await promise;
await observerPromise;
checkDeviceSelectors(["camera"]);
observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
observerPromise2 = expectObserverCalled("recording-device-events");
await promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});
await observerPromise1;
await observerPromise2;
await checkSharingUI({ video: true }, window, {
audio: true,
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 shown"
);
is(
webrtcUI.getActiveStreams(false, true).length,
1,
"1 active audio stream"
);
is(webrtcUI.getActiveStreams(true).length, 1, "1 active video stream");
is(
webrtcUI.getActiveStreams(true, true, true).length,
2,
"2 active streams"
);
info("removing the second tab");
await disableObserverVerification();
BrowserTestUtils.removeTab(tab);
// Check that we still show the sharing indicators for the first tab's stream.
await Promise.all([
TestUtils.waitForCondition(() => !webrtcUI.showCameraIndicator),
TestUtils.waitForCondition(
() => webrtcUI.getActiveStreams(true, true, true).length == 1
),
]);
ok(
webrtcUI.showGlobalIndicator,
"webrtcUI wants the global indicator shown"
);
ok(
!webrtcUI.showCameraIndicator,
"webrtcUI wants the camera indicator hidden"
);
ok(
webrtcUI.showMicrophoneIndicator,
"webrtcUI wants the mic indicator shown"
);
is(
webrtcUI.getActiveStreams(false, true).length,
1,
"1 active audio stream"
);
await checkSharingUI({ audio: true });
// Close the first tab's stream and verify that all indicators are removed.
await closeStream(false, null, true);
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",
skipObserverVerification: true,
run: async function checkMultiProcessCamera() {
let observerPromise = expectObserverCalled("getUserMedia:request");
// Request camera in the first tab.
let promise = promisePopupNotificationShown("webRTC-shareDevices");
await promiseRequestDevice(false, true);
await promise;
await observerPromise;
checkDeviceSelectors(["camera"]);
let indicator = promiseIndicatorWindow();
let observerPromise1 = expectObserverCalled(
"getUserMedia:response:allow"
);
let observerPromise2 = expectObserverCalled("recording-device-events");
await promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});
await observerPromise1;
await observerPromise2;
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"
);
// If we have reached the max process count already, increase it to ensure
// our new tab can have its own content process.
let childCount = Services.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(
);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
await enableObserverVerification();
// Request camera in the second tab.
observerPromise = expectObserverCalled("getUserMedia:request");
promise = promisePopupNotificationShown("webRTC-shareDevices");
await promiseRequestDevice(false, true);
await promise;
await observerPromise;
checkDeviceSelectors(["camera"]);
observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
observerPromise2 = expectObserverCalled("recording-device-events");
await promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});
await observerPromise1;
await observerPromise2;
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"
);
await disableObserverVerification();
info("removing the second tab");
BrowserTestUtils.removeTab(tab);
// Check that we still show the sharing indicators for the first tab's stream.
await Promise.all([
TestUtils.waitForCondition(() => webrtcUI.showCameraIndicator),
TestUtils.waitForCondition(
() => webrtcUI.getActiveStreams(true).length == 1
),
]);
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, true, true).length,
1,
"1 active stream"
);
await checkSharingUI({ video: true });
// Close the first tab's stream and verify that all indicators are removed.
await closeStream(false, null, true);
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",
skipObserverVerification: true,
run: async function checkMultiProcessScreen() {
// Request screen sharing in the first tab.
let observerPromise = expectObserverCalled("getUserMedia:request");
let promise = promisePopupNotificationShown("webRTC-shareDevices");
await promiseRequestDevice(false, true, null, "screen");
await promise;
await observerPromise;
is(
PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
"webRTC-shareScreen-notification-icon",
"anchored to device icon"
);
checkDeviceSelectors(["screen"]);
// Select the last screen so that we can have a stream.
let menulist = document.getElementById("webRTC-selectWindow-menulist");
menulist.getItemAtIndex(menulist.itemCount - 1).doCommand();
let indicator = promiseIndicatorWindow();
let observerPromise1 = expectObserverCalled(
"getUserMedia:response:allow"
);
let observerPromise2 = expectObserverCalled("recording-device-events");
await promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});
await observerPromise1;
await observerPromise2;
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"
);
// If we have reached the max process count already, increase it to ensure
// our new tab can have its own content process.
let childCount = Services.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(
);
let tab = await BrowserTestUtils.openNewForegroundTab(gBrowser, url);
await enableObserverVerification();
// Request screen sharing in the second tab.
observerPromise = expectObserverCalled("getUserMedia:request");
promise = promisePopupNotificationShown("webRTC-shareDevices");
await promiseRequestDevice(false, true, null, "screen");
await promise;
await observerPromise;
is(
PopupNotifications.getNotification("webRTC-shareDevices").anchorID,
"webRTC-shareScreen-notification-icon",
"anchored to device icon"
);
checkDeviceSelectors(["screen"]);
// Select the last screen so that we can have a stream.
menulist.getItemAtIndex(menulist.itemCount - 1).doCommand();
observerPromise1 = expectObserverCalled("getUserMedia:response:allow");
observerPromise2 = expectObserverCalled("recording-device-events");
await promiseMessage("ok", () => {
PopupNotifications.panel.firstElementChild.button.click();
});
await observerPromise1;
await observerPromise2;
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"
);
await disableObserverVerification();
info("removing the second tab");
BrowserTestUtils.removeTab(tab);
await TestUtils.waitForCondition(
() => webrtcUI.getActiveStreams(true, true, true).length == 1
);
// Close the first tab's stream and verify that all indicators are removed.
await closeStream(false, null, true);
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);
});