diff options
Diffstat (limited to 'browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js')
-rw-r--r-- | browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js | 221 |
1 files changed, 221 insertions, 0 deletions
diff --git a/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js b/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js new file mode 100644 index 000000000..054fb3cc0 --- /dev/null +++ b/browser/base/content/test/general/browser_domFullscreen_fullscreenMode.js @@ -0,0 +1,221 @@ +"use strict"; + +var gMessageManager; + +function frameScript() { + addMessageListener("Test:RequestFullscreen", () => { + content.document.body.requestFullscreen(); + }); + addMessageListener("Test:ExitFullscreen", () => { + content.document.exitFullscreen(); + }); + addMessageListener("Test:QueryFullscreenState", () => { + sendAsyncMessage("Test:FullscreenState", { + inDOMFullscreen: !!content.document.fullscreenElement, + inFullscreen: content.fullScreen + }); + }); + content.document.addEventListener("fullscreenchange", () => { + sendAsyncMessage("Test:FullscreenChanged", { + inDOMFullscreen: !!content.document.fullscreenElement, + inFullscreen: content.fullScreen + }); + }); + function waitUntilActive() { + let doc = content.document; + if (doc.docShell.isActive && doc.hasFocus()) { + sendAsyncMessage("Test:Activated"); + } else { + setTimeout(waitUntilActive, 10); + } + } + waitUntilActive(); +} + +function listenOneMessage(aMsg, aListener) { + function listener({ data }) { + gMessageManager.removeMessageListener(aMsg, listener); + aListener(data); + } + gMessageManager.addMessageListener(aMsg, listener); +} + +function listenOneEvent(aEvent, aListener) { + function listener(evt) { + removeEventListener(aEvent, listener); + aListener(evt); + } + addEventListener(aEvent, listener); +} + +function queryFullscreenState() { + return new Promise(resolve => { + listenOneMessage("Test:FullscreenState", resolve); + gMessageManager.sendAsyncMessage("Test:QueryFullscreenState"); + }); +} + +function captureUnexpectedFullscreenChange() { + ok(false, "catched an unexpected fullscreen change"); +} + +const FS_CHANGE_DOM = 1 << 0; +const FS_CHANGE_SIZE = 1 << 1; +const FS_CHANGE_BOTH = FS_CHANGE_DOM | FS_CHANGE_SIZE; + +function waitForFullscreenChanges(aFlags) { + return new Promise(resolve => { + let fullscreenData = null; + let sizemodeChanged = false; + function tryResolve() { + if ((!(aFlags & FS_CHANGE_DOM) || fullscreenData) && + (!(aFlags & FS_CHANGE_SIZE) || sizemodeChanged)) { + if (!fullscreenData) { + queryFullscreenState().then(resolve); + } else { + resolve(fullscreenData); + } + } + } + if (aFlags & FS_CHANGE_SIZE) { + listenOneEvent("sizemodechange", () => { + sizemodeChanged = true; + tryResolve(); + }); + } + if (aFlags & FS_CHANGE_DOM) { + gMessageManager.removeMessageListener( + "Test:FullscreenChanged", captureUnexpectedFullscreenChange); + listenOneMessage("Test:FullscreenChanged", data => { + gMessageManager.addMessageListener( + "Test:FullscreenChanged", captureUnexpectedFullscreenChange); + fullscreenData = data; + tryResolve(); + }); + } + }); +} + +var gTests = [ + { + desc: "document method", + affectsFullscreenMode: false, + exitFunc: () => { + gMessageManager.sendAsyncMessage("Test:ExitFullscreen"); + } + }, + { + desc: "escape key", + affectsFullscreenMode: false, + exitFunc: () => { + executeSoon(() => EventUtils.synthesizeKey("VK_ESCAPE", {})); + } + }, + { + desc: "F11 key", + affectsFullscreenMode: true, + exitFunc: function () { + executeSoon(() => EventUtils.synthesizeKey("VK_F11", {})); + } + } +]; + +function checkState(expectedStates, contentStates) { + is(contentStates.inDOMFullscreen, expectedStates.inDOMFullscreen, + "The DOM fullscreen state of the content should match"); + // TODO window.fullScreen is not updated as soon as the fullscreen + // state flips in child process, hence checking it could cause + // anonying intermittent failure. As we just want to confirm the + // fullscreen state of the browser window, we can just check the + // that on the chrome window below. + // is(contentStates.inFullscreen, expectedStates.inFullscreen, + // "The fullscreen state of the content should match"); + is(!!document.fullscreenElement, expectedStates.inDOMFullscreen, + "The DOM fullscreen state of the chrome should match"); + is(window.fullScreen, expectedStates.inFullscreen, + "The fullscreen state of the chrome should match"); +} + +const kPage = "http://example.org/browser/browser/" + + "base/content/test/general/dummy_page.html"; + +add_task(function* () { + yield pushPrefs( + ["full-screen-api.transition-duration.enter", "0 0"], + ["full-screen-api.transition-duration.leave", "0 0"]); + + let tab = gBrowser.addTab(kPage); + let browser = tab.linkedBrowser; + gBrowser.selectedTab = tab; + yield waitForDocLoadComplete(); + + registerCleanupFunction(() => { + if (browser.contentWindow.fullScreen) { + BrowserFullScreen(); + } + gBrowser.removeTab(tab); + }); + + gMessageManager = browser.messageManager; + gMessageManager.loadFrameScript( + "data:,(" + frameScript.toString() + ")();", false); + gMessageManager.addMessageListener( + "Test:FullscreenChanged", captureUnexpectedFullscreenChange); + + // Wait for the document being activated, so that + // fullscreen request won't be denied. + yield new Promise(resolve => listenOneMessage("Test:Activated", resolve)); + + for (let test of gTests) { + let contentStates; + info("Testing exit DOM fullscreen via " + test.desc); + + contentStates = yield queryFullscreenState(); + checkState({inDOMFullscreen: false, inFullscreen: false}, contentStates); + + /* DOM fullscreen without fullscreen mode */ + + info("> Enter DOM fullscreen"); + gMessageManager.sendAsyncMessage("Test:RequestFullscreen"); + contentStates = yield waitForFullscreenChanges(FS_CHANGE_BOTH); + checkState({inDOMFullscreen: true, inFullscreen: true}, contentStates); + + info("> Exit DOM fullscreen"); + test.exitFunc(); + contentStates = yield waitForFullscreenChanges(FS_CHANGE_BOTH); + checkState({inDOMFullscreen: false, inFullscreen: false}, contentStates); + + /* DOM fullscreen with fullscreen mode */ + + info("> Enter fullscreen mode"); + // Need to be asynchronous because sizemodechange event could be + // dispatched synchronously, which would cause the event listener + // miss that event and wait infinitely. + executeSoon(() => BrowserFullScreen()); + contentStates = yield waitForFullscreenChanges(FS_CHANGE_SIZE); + checkState({inDOMFullscreen: false, inFullscreen: true}, contentStates); + + info("> Enter DOM fullscreen in fullscreen mode"); + gMessageManager.sendAsyncMessage("Test:RequestFullscreen"); + contentStates = yield waitForFullscreenChanges(FS_CHANGE_DOM); + checkState({inDOMFullscreen: true, inFullscreen: true}, contentStates); + + info("> Exit DOM fullscreen in fullscreen mode"); + test.exitFunc(); + contentStates = yield waitForFullscreenChanges( + test.affectsFullscreenMode ? FS_CHANGE_BOTH : FS_CHANGE_DOM); + checkState({ + inDOMFullscreen: false, + inFullscreen: !test.affectsFullscreenMode + }, contentStates); + + /* Cleanup */ + + // Exit fullscreen mode if we are still in + if (window.fullScreen) { + info("> Cleanup"); + executeSoon(() => BrowserFullScreen()); + yield waitForFullscreenChanges(FS_CHANGE_SIZE); + } + } +}); |