2017-02-07 10:52:06 +00:00
|
|
|
/* eslint-env mozilla/frame-script */
|
2017-08-10 18:48:21 +00:00
|
|
|
/* eslint-disable mozilla/no-arbitrary-setTimeout */
|
2017-02-07 10:52:06 +00:00
|
|
|
|
2015-05-05 22:04:31 +00:00
|
|
|
"use strict";
|
|
|
|
|
2018-10-26 02:04:01 +00:00
|
|
|
// This test tends to trigger a race in the fullscreen time telemetry,
|
|
|
|
// where the fullscreen enter and fullscreen exit events (which use the
|
|
|
|
// same histogram ID) overlap. That causes TelemetryStopwatch to log an
|
|
|
|
// error.
|
|
|
|
SimpleTest.ignoreAllUncaughtExceptions(true);
|
|
|
|
|
2015-09-15 18:19:45 +00:00
|
|
|
var gMessageManager;
|
2015-05-05 22:04:31 +00:00
|
|
|
|
|
|
|
function frameScript() {
|
|
|
|
addMessageListener("Test:RequestFullscreen", () => {
|
2016-02-17 00:47:11 +00:00
|
|
|
content.document.body.requestFullscreen();
|
2015-05-05 22:04:31 +00:00
|
|
|
});
|
|
|
|
addMessageListener("Test:ExitFullscreen", () => {
|
2016-02-17 00:47:11 +00:00
|
|
|
content.document.exitFullscreen();
|
2015-05-05 22:04:31 +00:00
|
|
|
});
|
|
|
|
addMessageListener("Test:QueryFullscreenState", () => {
|
|
|
|
sendAsyncMessage("Test:FullscreenState", {
|
2016-02-17 00:47:11 +00:00
|
|
|
inDOMFullscreen: !!content.document.fullscreenElement,
|
2018-08-31 05:59:17 +00:00
|
|
|
inFullscreen: content.fullScreen,
|
2015-05-05 22:04:31 +00:00
|
|
|
});
|
|
|
|
});
|
2017-06-05 06:56:00 +00:00
|
|
|
addMessageListener("Test:WaitActivated", () => {
|
|
|
|
waitUntilActive();
|
|
|
|
});
|
2016-02-17 00:47:11 +00:00
|
|
|
content.document.addEventListener("fullscreenchange", () => {
|
2015-05-05 22:04:31 +00:00
|
|
|
sendAsyncMessage("Test:FullscreenChanged", {
|
2016-02-17 00:47:11 +00:00
|
|
|
inDOMFullscreen: !!content.document.fullscreenElement,
|
2018-08-31 05:59:17 +00:00
|
|
|
inFullscreen: content.fullScreen,
|
2015-05-05 22:04:31 +00:00
|
|
|
});
|
|
|
|
});
|
|
|
|
function waitUntilActive() {
|
2018-05-21 23:58:23 +00:00
|
|
|
if (docShell.isActive && content.document.hasFocus()) {
|
2015-05-05 22:04:31 +00:00
|
|
|
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;
|
|
|
|
|
2017-06-05 06:56:00 +00:00
|
|
|
function waitForDocActivated() {
|
|
|
|
return new Promise(resolve => {
|
|
|
|
listenOneMessage("Test:Activated", resolve);
|
|
|
|
gMessageManager.sendAsyncMessage("Test:WaitActivated");
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-05-05 22:04:31 +00:00
|
|
|
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)
|
|
|
|
) {
|
2017-06-05 06:56:00 +00:00
|
|
|
// In the platforms that support reporting occlusion state (e.g. Mac),
|
|
|
|
// enter/exit fullscreen mode will trigger docshell being set to
|
|
|
|
// non-activate and then set to activate back again.
|
|
|
|
// For those platform, we should wait until the docshell has been
|
|
|
|
// activated again, otherwise, the fullscreen request might be denied.
|
|
|
|
waitForDocActivated().then(() => {
|
|
|
|
if (!fullscreenData) {
|
|
|
|
queryFullscreenState().then(resolve);
|
|
|
|
} else {
|
|
|
|
resolve(fullscreenData);
|
|
|
|
}
|
|
|
|
});
|
2015-05-05 22:04:31 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
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();
|
|
|
|
});
|
|
|
|
}
|
|
|
|
});
|
|
|
|
}
|
|
|
|
|
2015-09-15 18:19:45 +00:00
|
|
|
var gTests = [
|
2015-05-05 22:04:31 +00:00
|
|
|
{
|
|
|
|
desc: "document method",
|
|
|
|
affectsFullscreenMode: false,
|
|
|
|
exitFunc: () => {
|
|
|
|
gMessageManager.sendAsyncMessage("Test:ExitFullscreen");
|
2018-08-31 05:59:17 +00:00
|
|
|
},
|
2015-05-05 22:04:31 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "escape key",
|
|
|
|
affectsFullscreenMode: false,
|
|
|
|
exitFunc: () => {
|
2018-02-14 19:15:39 +00:00
|
|
|
executeSoon(() => EventUtils.synthesizeKey("KEY_Escape"));
|
2018-08-31 05:59:17 +00:00
|
|
|
},
|
2015-05-05 22:04:31 +00:00
|
|
|
},
|
|
|
|
{
|
|
|
|
desc: "F11 key",
|
|
|
|
affectsFullscreenMode: true,
|
2016-12-29 23:34:54 +00:00
|
|
|
exitFunc() {
|
2018-02-14 19:15:39 +00:00
|
|
|
executeSoon(() => EventUtils.synthesizeKey("KEY_F11"));
|
2018-08-31 05:59:17 +00:00
|
|
|
},
|
|
|
|
},
|
2015-05-05 22:04:31 +00:00
|
|
|
];
|
|
|
|
|
2015-09-18 01:33:54 +00:00
|
|
|
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");
|
2016-02-17 00:47:11 +00:00
|
|
|
is(
|
|
|
|
!!document.fullscreenElement,
|
|
|
|
expectedStates.inDOMFullscreen,
|
2015-09-18 01:33:54 +00:00
|
|
|
"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";
|
|
|
|
|
2017-05-12 12:42:39 +00:00
|
|
|
add_task(async function() {
|
|
|
|
await pushPrefs(
|
2015-07-13 10:44:36 +00:00
|
|
|
["full-screen-api.transition-duration.enter", "0 0"],
|
|
|
|
["full-screen-api.transition-duration.leave", "0 0"]
|
|
|
|
);
|
|
|
|
|
2017-06-16 22:56:11 +00:00
|
|
|
registerCleanupFunction(async function() {
|
|
|
|
if (window.fullScreen) {
|
|
|
|
executeSoon(() => BrowserFullScreen());
|
|
|
|
await waitForFullscreenChanges(FS_CHANGE_SIZE);
|
2015-05-05 22:04:31 +00:00
|
|
|
}
|
|
|
|
});
|
|
|
|
|
2017-06-16 22:56:11 +00:00
|
|
|
let tab = await BrowserTestUtils.openNewForegroundTab({
|
|
|
|
gBrowser,
|
|
|
|
url: kPage,
|
|
|
|
});
|
|
|
|
let browser = tab.linkedBrowser;
|
|
|
|
|
2015-05-05 22:04:31 +00:00
|
|
|
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.
|
2017-05-12 12:42:39 +00:00
|
|
|
await new Promise(resolve => listenOneMessage("Test:Activated", resolve));
|
2015-05-05 22:04:31 +00:00
|
|
|
|
|
|
|
for (let test of gTests) {
|
2015-09-18 01:33:54 +00:00
|
|
|
let contentStates;
|
2015-05-05 22:04:31 +00:00
|
|
|
info("Testing exit DOM fullscreen via " + test.desc);
|
|
|
|
|
2017-05-12 12:42:39 +00:00
|
|
|
contentStates = await queryFullscreenState();
|
2015-09-18 01:33:54 +00:00
|
|
|
checkState({ inDOMFullscreen: false, inFullscreen: false }, contentStates);
|
2015-05-05 22:04:31 +00:00
|
|
|
|
|
|
|
/* DOM fullscreen without fullscreen mode */
|
|
|
|
|
2015-09-18 01:33:54 +00:00
|
|
|
info("> Enter DOM fullscreen");
|
2015-05-05 22:04:31 +00:00
|
|
|
gMessageManager.sendAsyncMessage("Test:RequestFullscreen");
|
2017-05-12 12:42:39 +00:00
|
|
|
contentStates = await waitForFullscreenChanges(FS_CHANGE_BOTH);
|
2015-09-18 01:33:54 +00:00
|
|
|
checkState({ inDOMFullscreen: true, inFullscreen: true }, contentStates);
|
2015-05-05 22:04:31 +00:00
|
|
|
|
2015-09-18 01:33:54 +00:00
|
|
|
info("> Exit DOM fullscreen");
|
2015-05-05 22:04:31 +00:00
|
|
|
test.exitFunc();
|
2017-05-12 12:42:39 +00:00
|
|
|
contentStates = await waitForFullscreenChanges(FS_CHANGE_BOTH);
|
2015-09-18 01:33:54 +00:00
|
|
|
checkState({ inDOMFullscreen: false, inFullscreen: false }, contentStates);
|
2015-05-05 22:04:31 +00:00
|
|
|
|
|
|
|
/* DOM fullscreen with fullscreen mode */
|
|
|
|
|
2015-09-18 01:33:54 +00:00
|
|
|
info("> Enter fullscreen mode");
|
2015-05-05 22:04:31 +00:00
|
|
|
// 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());
|
2017-05-12 12:42:39 +00:00
|
|
|
contentStates = await waitForFullscreenChanges(FS_CHANGE_SIZE);
|
2015-09-18 01:33:54 +00:00
|
|
|
checkState({ inDOMFullscreen: false, inFullscreen: true }, contentStates);
|
2015-05-05 22:04:31 +00:00
|
|
|
|
2015-09-18 01:33:54 +00:00
|
|
|
info("> Enter DOM fullscreen in fullscreen mode");
|
2015-05-05 22:04:31 +00:00
|
|
|
gMessageManager.sendAsyncMessage("Test:RequestFullscreen");
|
2017-05-12 12:42:39 +00:00
|
|
|
contentStates = await waitForFullscreenChanges(FS_CHANGE_DOM);
|
2015-09-18 01:33:54 +00:00
|
|
|
checkState({ inDOMFullscreen: true, inFullscreen: true }, contentStates);
|
2015-05-05 22:04:31 +00:00
|
|
|
|
2015-09-18 01:33:54 +00:00
|
|
|
info("> Exit DOM fullscreen in fullscreen mode");
|
2015-05-05 22:04:31 +00:00
|
|
|
test.exitFunc();
|
2017-05-12 12:42:39 +00:00
|
|
|
contentStates = await waitForFullscreenChanges(
|
2015-09-18 01:33:54 +00:00
|
|
|
test.affectsFullscreenMode ? FS_CHANGE_BOTH : FS_CHANGE_DOM
|
|
|
|
);
|
|
|
|
checkState(
|
|
|
|
{
|
|
|
|
inDOMFullscreen: false,
|
2018-08-31 05:59:17 +00:00
|
|
|
inFullscreen: !test.affectsFullscreenMode,
|
2015-09-18 01:33:54 +00:00
|
|
|
},
|
|
|
|
contentStates
|
|
|
|
);
|
2015-05-05 22:04:31 +00:00
|
|
|
|
|
|
|
/* Cleanup */
|
|
|
|
|
|
|
|
// Exit fullscreen mode if we are still in
|
2015-09-18 01:33:54 +00:00
|
|
|
if (window.fullScreen) {
|
|
|
|
info("> Cleanup");
|
2015-05-05 22:04:31 +00:00
|
|
|
executeSoon(() => BrowserFullScreen());
|
2017-05-12 12:42:39 +00:00
|
|
|
await waitForFullscreenChanges(FS_CHANGE_SIZE);
|
2015-05-05 22:04:31 +00:00
|
|
|
}
|
|
|
|
}
|
2017-06-16 22:56:11 +00:00
|
|
|
|
2018-03-19 02:16:45 +00:00
|
|
|
BrowserTestUtils.removeTab(tab);
|
2015-05-05 22:04:31 +00:00
|
|
|
});
|