diff options
Diffstat (limited to 'browser/base/content/test/webrtc/browser_notification_silencing.js')
-rw-r--r-- | browser/base/content/test/webrtc/browser_notification_silencing.js | 231 |
1 files changed, 231 insertions, 0 deletions
diff --git a/browser/base/content/test/webrtc/browser_notification_silencing.js b/browser/base/content/test/webrtc/browser_notification_silencing.js new file mode 100644 index 0000000000..8859195285 --- /dev/null +++ b/browser/base/content/test/webrtc/browser_notification_silencing.js @@ -0,0 +1,231 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +const TEST_ROOT = getRootDirectory(gTestPath).replace( + "chrome://mochitests/content/", + "https://example.com/" +); +const TEST_PAGE = TEST_ROOT + "get_user_media.html"; + +/** + * Tests that the screen / window sharing permission popup offers the ability + * for users to silence DOM notifications while sharing. + */ + +/** + * Helper function that exercises a specific browser to test whether or not the + * user can silence notifications via the display sharing permission panel. + * + * First, we ensure that notification silencing is disabled by default. Then, we + * request screen sharing from the browser, and check the checkbox that + * silences notifications. Once screen sharing is established, then we ensure + * that notification silencing is enabled. Then we stop sharing, and ensure that + * notification silencing is disabled again. + * + * @param {<xul:browser>} aBrowser - The window to run the test on. This browser + * should have TEST_PAGE loaded. + * @return Promise + * @resolves undefined - When the test on the browser is complete. + */ +async function testNotificationSilencing(aBrowser) { + let hasIndicator = Services.wm + .getEnumerator("Browser:WebRTCGlobalIndicator") + .hasMoreElements(); + + let window = aBrowser.ownerGlobal; + + let alertsService = Cc["@mozilla.org/alerts-service;1"] + .getService(Ci.nsIAlertsService) + .QueryInterface(Ci.nsIAlertsDoNotDisturb); + Assert.ok(alertsService, "Alerts Service implements nsIAlertsDoNotDisturb"); + Assert.ok( + !alertsService.suppressForScreenSharing, + "Should not be silencing notifications to start." + ); + + let observerPromise = expectObserverCalled( + "getUserMedia:request", + 1, + aBrowser + ); + let promise = promisePopupNotificationShown( + "webRTC-shareDevices", + null, + window + ); + let indicatorPromise = hasIndicator + ? Promise.resolve() + : promiseIndicatorWindow(); + await promiseRequestDevice(false, true, null, "screen", aBrowser); + await promise; + await observerPromise; + + checkDeviceSelectors(["screen"], window); + + let document = window.document; + + // Select one of the windows / screens. It doesn't really matter which. + let menulist = document.getElementById("webRTC-selectWindow-menulist"); + menulist.getItemAtIndex(menulist.itemCount - 1).doCommand(); + + let notification = window.PopupNotifications.panel.firstElementChild; + Assert.ok( + notification.hasAttribute("warninghidden"), + "Notification silencing warning message is hidden by default" + ); + + let checkbox = notification.checkbox; + Assert.ok(!!checkbox, "Notification silencing checkbox is present"); + Assert.ok(!checkbox.checked, "checkbox is not checked by default"); + checkbox.click(); + Assert.ok(checkbox.checked, "checkbox now checked"); + // The orginal behaviour of the checkbox disabled the Allow button. Let's + // make sure we're not still doing that. + Assert.ok(!notification.button.disabled, "Allow button is not disabled"); + Assert.ok( + notification.hasAttribute("warninghidden"), + "No warning message is shown" + ); + + let observerPromise1 = expectObserverCalled( + "getUserMedia:response:allow", + 1, + aBrowser + ); + let observerPromise2 = expectObserverCalled( + "recording-device-events", + 1, + aBrowser + ); + await promiseMessage( + "ok", + () => { + notification.button.click(); + }, + 1, + aBrowser + ); + await observerPromise1; + await observerPromise2; + let indicator = await indicatorPromise; + + Assert.ok( + alertsService.suppressForScreenSharing, + "Should now be silencing notifications" + ); + + let indicatorClosedPromise = hasIndicator + ? Promise.resolve() + : BrowserTestUtils.domWindowClosed(indicator); + + await stopSharing("screen", true, aBrowser, window); + await indicatorClosedPromise; + + Assert.ok( + !alertsService.suppressForScreenSharing, + "Should no longer be silencing notifications" + ); +} + +add_setup(async function() { + // Set prefs so that permissions prompts are shown and loopback devices + // are not used. To test the chrome we want prompts to be shown, and + // these tests are flakey when using loopback devices (though it would + // be desirable to make them work with loopback in future). See bug 1643711. + let prefs = [ + [PREF_PERMISSION_FAKE, true], + [PREF_AUDIO_LOOPBACK, ""], + [PREF_VIDEO_LOOPBACK, ""], + [PREF_FAKE_STREAMS, true], + [PREF_FOCUS_SOURCE, false], + ]; + + await SpecialPowers.pushPrefEnv({ set: prefs }); +}); + +/** + * Tests notification silencing in a normal browser window. + */ +add_task(async function testNormalWindow() { + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: TEST_PAGE, + }, + async browser => { + await testNotificationSilencing(browser); + } + ); +}); + +/** + * Tests notification silencing in a private browser window. + */ +add_task(async function testPrivateWindow() { + let privateWindow = await BrowserTestUtils.openNewBrowserWindow({ + private: true, + }); + await BrowserTestUtils.withNewTab( + { + gBrowser: privateWindow.gBrowser, + url: TEST_PAGE, + }, + async browser => { + await testNotificationSilencing(browser); + } + ); + + await BrowserTestUtils.closeWindow(privateWindow); +}); + +/** + * Tests notification silencing when sharing a screen while already + * sharing the microphone. Alone ensures that if we stop sharing the + * screen, but continue sharing the microphone, that notification + * silencing ends. + */ +add_task(async function testWhileSharingMic() { + await BrowserTestUtils.withNewTab( + { + gBrowser, + url: TEST_PAGE, + }, + async browser => { + let promise = promisePopupNotificationShown("webRTC-shareDevices"); + let observerPromise = expectObserverCalled("getUserMedia:request"); + await promiseRequestDevice(true, true); + await promise; + await observerPromise; + + let indicatorPromise = promiseIndicatorWindow(); + let observerPromise1 = expectObserverCalled( + "getUserMedia:response:allow" + ); + let observerPromise2 = expectObserverCalled("recording-device-events"); + + promise = promiseMessage("ok", () => { + PopupNotifications.panel.firstElementChild.button.click(); + }); + await observerPromise1; + await observerPromise2; + await promise; + + Assert.deepEqual( + await getMediaCaptureState(), + { audio: true, video: true }, + "expected camera and microphone to be shared" + ); + + let indicator = await indicatorPromise; + await checkSharingUI({ audio: true, video: true }); + + await testNotificationSilencing(browser); + + let indicatorClosedPromise = BrowserTestUtils.domWindowClosed(indicator); + await closeStream(); + await indicatorClosedPromise; + } + ); +}); |