diff options
Diffstat (limited to 'toolkit/components/pictureinpicture/tests/browser_contextMenu.js')
-rw-r--r-- | toolkit/components/pictureinpicture/tests/browser_contextMenu.js | 238 |
1 files changed, 238 insertions, 0 deletions
diff --git a/toolkit/components/pictureinpicture/tests/browser_contextMenu.js b/toolkit/components/pictureinpicture/tests/browser_contextMenu.js new file mode 100644 index 0000000000..ce6a85e91c --- /dev/null +++ b/toolkit/components/pictureinpicture/tests/browser_contextMenu.js @@ -0,0 +1,238 @@ +/* Any copyright is dedicated to the Public Domain. + * http://creativecommons.org/publicdomain/zero/1.0/ */ + +"use strict"; + +/** + * Opens up the content area context menu on a video loaded in a + * browser. + * + * @param {Element} browser The <xul:browser> hosting the <video> + * + * @param {String} videoID The ID of the video to open the context + * menu with. + * + * @returns Promise + * @resolves With the context menu DOM node once opened. + */ +async function openContextMenu(browser, videoID) { + let contextMenu = document.getElementById("contentAreaContextMenu"); + let popupShownPromise = BrowserTestUtils.waitForEvent( + contextMenu, + "popupshown" + ); + await BrowserTestUtils.synthesizeMouseAtCenter( + "#" + videoID, + { type: "contextmenu", button: 2 }, + browser + ); + await popupShownPromise; + return contextMenu; +} + +/** + * Closes the content area context menu. + * + * @param {Element} contextMenu The content area context menu opened with + * openContextMenu. + * + * @returns Promise + * @resolves With undefined + */ +async function closeContextMenu(contextMenu) { + let popupHiddenPromise = BrowserTestUtils.waitForEvent( + contextMenu, + "popuphidden" + ); + contextMenu.hidePopup(); + await popupHiddenPromise; +} + +/** + * Tests that Picture-in-Picture can be opened and closed through the + * context menu + */ +add_task(async () => { + for (const videoId of ["with-controls", "no-controls"]) { + info(`Testing ${videoId} case.`); + + await BrowserTestUtils.withNewTab( + { + url: TEST_PAGE, + gBrowser, + }, + async browser => { + let contextMenu = await openContextMenu(browser, videoId); + + info("Context menu is open."); + + const pipMenuItemId = "context-video-pictureinpicture"; + let menuItem = document.getElementById(pipMenuItemId); + + Assert.ok( + !menuItem.hidden, + "Should show Picture-in-Picture menu item." + ); + Assert.equal( + menuItem.getAttribute("checked"), + "false", + "Picture-in-Picture should be unchecked." + ); + + contextMenu.activateItem(menuItem); + + await SpecialPowers.spawn(browser, [videoId], async videoID => { + let video = content.document.getElementById(videoID); + await ContentTaskUtils.waitForCondition(() => { + return video.isCloningElementVisually; + }, "Video has started being cloned."); + }); + + info("PiP player is now open."); + + contextMenu = await openContextMenu(browser, videoId); + + info("Context menu is open again."); + + contextMenu.activateItem(menuItem); + + await SpecialPowers.spawn(browser, [videoId], async videoID => { + let video = content.document.getElementById(videoID); + await ContentTaskUtils.waitForCondition(() => { + return !video.isCloningElementVisually; + }, "Video has stopped being cloned."); + }); + } + ); + } +}); + +/** + * Tests that the Picture-in-Picture context menu is correctly updated + * based on the Picture-in-Picture state of the video. + */ +add_task(async () => { + for (let videoID of ["with-controls", "no-controls"]) { + info(`Testing ${videoID} case.`); + + await BrowserTestUtils.withNewTab( + { + url: TEST_PAGE, + gBrowser, + }, + async browser => { + let menuItem = document.getElementById( + "context-video-pictureinpicture" + ); + let menu = await openContextMenu(browser, videoID); + Assert.ok( + !menuItem.hidden, + "Should show Picture-in-Picture menu item." + ); + Assert.equal( + menuItem.getAttribute("checked"), + "false", + "Picture-in-Picture should be unchecked." + ); + await closeContextMenu(menu); + + let pipWin = await triggerPictureInPicture(browser, videoID); + ok(pipWin, "Got Picture-in-Picture window."); + + await SpecialPowers.spawn(browser, [videoID], async videoID => { + let video = content.document.getElementById(videoID); + await ContentTaskUtils.waitForCondition(() => { + return video.isCloningElementVisually; + }, "Video has started being cloned."); + }); + + menu = await openContextMenu(browser, videoID); + Assert.ok( + !menuItem.hidden, + "Should show Picture-in-Picture menu item." + ); + Assert.equal( + menuItem.getAttribute("checked"), + "true", + "Picture-in-Picture should be checked." + ); + await closeContextMenu(menu); + + let videoNotCloning = SpecialPowers.spawn( + browser, + [videoID], + async videoID => { + let video = content.document.getElementById(videoID); + await ContentTaskUtils.waitForCondition(() => { + return !video.isCloningElementVisually; + }, "Video has stopped being cloned."); + } + ); + pipWin.close(); + await videoNotCloning; + + menu = await openContextMenu(browser, videoID); + Assert.ok( + !menuItem.hidden, + "Should show Picture-in-Picture menu item." + ); + Assert.equal( + menuItem.getAttribute("checked"), + "false", + "Picture-in-Picture should be unchecked." + ); + await closeContextMenu(menu); + + await SpecialPowers.spawn(browser, [videoID], async videoID => { + // Construct a new video element, and capture a stream from it + // to redirect to the video that we're testing. + let newVideo = content.document.createElement("video"); + content.document.body.appendChild(newVideo); + + let testedVideo = content.document.getElementById(videoID); + newVideo.src = testedVideo.src; + + testedVideo.srcObject = newVideo.mozCaptureStream(); + await newVideo.play(); + await testedVideo.play(); + + await newVideo.pause(); + await testedVideo.pause(); + }); + menu = await openContextMenu(browser, videoID); + Assert.ok( + !menuItem.hidden, + "Should be showing Picture-in-Picture menu item." + ); + Assert.equal( + menuItem.getAttribute("checked"), + "false", + "Picture-in-Picture should be unchecked." + ); + await closeContextMenu(menu); + + pipWin = await triggerPictureInPicture(browser, videoID); + ok(pipWin, "Got Picture-in-Picture window."); + + await SpecialPowers.spawn(browser, [videoID], async videoID => { + let video = content.document.getElementById(videoID); + await ContentTaskUtils.waitForCondition(() => { + return video.isCloningElementVisually; + }, "Video has started being cloned."); + }); + + menu = await openContextMenu(browser, videoID); + Assert.ok( + !menuItem.hidden, + "Should show Picture-in-Picture menu item." + ); + Assert.equal( + menuItem.getAttribute("checked"), + "true", + "Picture-in-Picture should be checked." + ); + await closeContextMenu(menu); + } + ); + } +}); |