mirror of
https://github.com/mozilla/gecko-dev.git
synced 2025-02-26 04:09:50 +00:00
Bug 1776738: Make fullscreen and pointerlock mochitests use document.fullscreenElement to determine fullscreen-ness. r=edgar
With these changes, it's no longer necessary to store the normalSize on the window, since we never check it, nor check for resize events. This also removes the flaky timeouts, and replaces them with an executeSoon. For some of the fullscreen tests, the number of calls to enter and exit fullscreen are not matched. Since that count is essential for the checks of whether or not the screen is in the expected fullscreen, this defines a method that can force the count to a specific value. This is used in some of the fullscreen tests to get the expected results. Differential Revision: https://phabricator.services.mozilla.com/D172852
This commit is contained in:
parent
562799d5e5
commit
1c8e1b829f
@ -148,9 +148,10 @@ async function testFullscreenMouseBtn(event, button, next) {
|
||||
let evt = fsRequestEvents[i];
|
||||
for (let j = 0; j < mouseButtons.length; j++) {
|
||||
let mouseButton = mouseButtons[j];
|
||||
let fsDenied = addFullscreenErrorContinuation();
|
||||
requestFullscreenMouseBtn(evt, mouseButton);
|
||||
await fsDenied;
|
||||
await new Promise(resolve => {
|
||||
addFullscreenErrorContinuation(resolve);
|
||||
requestFullscreenMouseBtn(evt, mouseButton);
|
||||
});
|
||||
ok(!document.fullscreenElement, `Should not grant request on '${evt}' triggered by mouse button ${mouseButton}`);
|
||||
}
|
||||
}
|
||||
|
@ -2,26 +2,23 @@
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for Bug 724554</title>
|
||||
<script type="application/javascript" src="file_fullscreen-utils.js"></script>
|
||||
</head>
|
||||
<body>
|
||||
|
||||
<script type="application/javascript">
|
||||
|
||||
|
||||
/** Test for Bug 545812 **/
|
||||
function begin(id) {
|
||||
addFullscreenErrorContinuation(function() {
|
||||
opener.addFullscreenErrorContinuation(function() {
|
||||
opener.ok(false, "Fullscreen denied " + id);
|
||||
});
|
||||
addFullscreenChangeContinuation("enter",
|
||||
}, document);
|
||||
opener.addFullscreenChangeContinuation("enter",
|
||||
function() {
|
||||
opener.enteredFullscreen(id);
|
||||
});
|
||||
}, document);
|
||||
document.body.requestFullscreen();
|
||||
}
|
||||
|
||||
|
||||
</script>
|
||||
</pre>
|
||||
</body>
|
||||
|
@ -34,8 +34,11 @@ var window1, window2;
|
||||
function openWindow(id) {
|
||||
var w = window.open("file_fullscreen-multiple-inner.html", "", "width=500,height=500");
|
||||
waitForLoadAndPaint(w, function() {
|
||||
SimpleTest.waitForFocus(function() {
|
||||
info(`Window ${id} is focused, starting test...`);
|
||||
w.begin(id);
|
||||
}, w);
|
||||
w.focus();
|
||||
SimpleTest.waitForFocus(function(){w.begin(id)}, w);
|
||||
});
|
||||
return w;
|
||||
}
|
||||
|
@ -36,14 +36,18 @@ function begin() {
|
||||
|
||||
// The format of each test step is:
|
||||
// [[action, target], [fsOuter, fsInner]] where:
|
||||
// * "action" is either "enter" or "exit", means whether we want to
|
||||
// enter or exit fullscreen in this step.
|
||||
// * "action" is "enter" or "exit" means whether we want to enter or
|
||||
// fullscreen in this step. An action of "reset" means to force
|
||||
// our count of enters to a certain value, to match how many exits
|
||||
// we need to do to leave fullscreen. This is used when one exit
|
||||
// can unwind more than one enter.
|
||||
// * "target" is where we apply this action. For "enter" action, it
|
||||
// is the element we want to call requestFullscreen() on, and for
|
||||
// "exit", it is the document we want to call exitFullscreen() on.
|
||||
// * "fsOuter" and "fsInner" are the expected fullscreen elements of
|
||||
// the outer and inner document respectively after executing the
|
||||
// action in this step.
|
||||
// action in this step. These are only checked after "enter" or
|
||||
// "exit" actions.
|
||||
gTestSteps = [
|
||||
// innerRoot
|
||||
[["enter", innerRoot], [iframe, innerRoot]],
|
||||
@ -66,6 +70,7 @@ function begin() {
|
||||
[[ "exit", document], [ null, null]],
|
||||
[["enter", iframe], [iframe, null]],
|
||||
[["enter", innerRoot], [iframe, innerRoot]],
|
||||
[["reset", 1], [ null, null]],
|
||||
[[ "exit", document], [ null, null]],
|
||||
// root, iframe, innerRoot
|
||||
[["enter", root], [ root, null]],
|
||||
@ -78,6 +83,7 @@ function begin() {
|
||||
[["enter", iframe], [iframe, null]],
|
||||
[["enter", innerRoot], [iframe, innerRoot]],
|
||||
[[ "exit", document], [ root, null]],
|
||||
[["reset", 1], [ null, null]],
|
||||
[[ "exit", document], [ null, null]],
|
||||
];
|
||||
|
||||
@ -111,6 +117,10 @@ function nextStep() {
|
||||
// For "exit" action, the target is the document
|
||||
addFullscreenChangeContinuation("exit", checkAndNext, target);
|
||||
target.exitFullscreen();
|
||||
} else if (action == "reset") {
|
||||
// For "reset" action, the target is the number to setFullscreenChangeEnters.
|
||||
setFullscreenChangeEnters(target);
|
||||
nextStep();
|
||||
} else {
|
||||
ok(false, `Unknown action ${action}`);
|
||||
}
|
||||
|
@ -111,9 +111,16 @@ function change5() {
|
||||
}
|
||||
|
||||
function change6() {
|
||||
addFullscreenChangeContinuation("exit", change7);
|
||||
var element = e('fse-inner');
|
||||
is(document.fullscreenElement, element, "FSE should be e('fse-inner')");
|
||||
|
||||
// We're breaking out of two levels of fullscreen by removing the
|
||||
// fullscreenElement. To make our helper functions work correctly,
|
||||
// we set the fullscreenChangeEnters value to 1. This is a hack, but
|
||||
// it is a hack that supports the expected behavior.
|
||||
setFullscreenChangeEnters(1);
|
||||
addFullscreenChangeContinuation("exit", change7);
|
||||
info(`Removing FSE should exit fullscreen.`);
|
||||
element.remove();
|
||||
}
|
||||
|
||||
|
@ -78,7 +78,11 @@ function checkScrollbars(elem, shouldHaveScrollbars) {
|
||||
}
|
||||
|
||||
function begin() {
|
||||
if (window.matchMedia("(-moz-overlay-scrollbars)").matches) {
|
||||
// Check for the use of overlay scrollbars. We can only get an accurate
|
||||
// answer to our media query if we are Chrome-privileged. Otherwise, the
|
||||
// media query will never match.
|
||||
let wrappedWindow = SpecialPowers.wrap(window);
|
||||
if (wrappedWindow.matchMedia("(-moz-overlay-scrollbars)").matches) {
|
||||
// If overlay scrollbar is enabled, the scrollbar is not measurable,
|
||||
// so we skip this test in that case.
|
||||
info("Skip this test because of overlay scrollbar");
|
||||
@ -96,7 +100,6 @@ function begin() {
|
||||
ok(gHorizontalScrollbarWidth != 0, "Should have horizontal scrollbar");
|
||||
info(`gVerticalScrollbarWidth: ${gVerticalScrollbarWidth}`);
|
||||
info(`gHorizontalScrollbarWidth: ${gHorizontalScrollbarWidth}`);
|
||||
|
||||
info("Entering fullscreen on root");
|
||||
addFullscreenChangeContinuation("enter", enteredFullscreenOnRoot);
|
||||
document.documentElement.requestFullscreen();
|
||||
|
@ -145,6 +145,11 @@ function exit0() {
|
||||
function listener() {
|
||||
if (++count == 3) {
|
||||
document.removeEventListener("fullscreenchange", listener);
|
||||
// We bypassed our fullscreenchangeenters count since we didn't
|
||||
// do our requests with a addFullscreenChangeContinuation, so we
|
||||
// fix up the expected value now that we're done with this part
|
||||
// of the test.
|
||||
setFullscreenChangeEnters(1);
|
||||
enterAll();
|
||||
}
|
||||
}
|
||||
|
@ -1,50 +1,47 @@
|
||||
// Returns true if the window occupies the entire screen.
|
||||
// Note this only returns true once the transition from normal to
|
||||
// fullscreen mode is complete.
|
||||
function inFullscreenMode(win) {
|
||||
return (
|
||||
win.innerWidth == win.screen.width && win.innerHeight == win.screen.height
|
||||
);
|
||||
// Keep track of how many fullscreenChange enters we've received, so that
|
||||
// we can balance them with the number of exits we receive. We reset this
|
||||
// to 0 when we load a test.
|
||||
var fullscreenChangeEnters = 0;
|
||||
|
||||
addLoadEvent(function() {
|
||||
info(`Resetting fullscreen enter count.`);
|
||||
fullscreenChangeEnters = 0;
|
||||
});
|
||||
|
||||
// This can be used to force a certain value for fullscreenChangeEnters
|
||||
// to handle unusual conditions -- such as exiting multiple levels of
|
||||
// fullscreen forcibly.
|
||||
function setFullscreenChangeEnters(enters) {
|
||||
info(`Setting fullscreen enter count to ${enters}.`);
|
||||
fullscreenChangeEnters = enters;
|
||||
}
|
||||
|
||||
// Returns true if the window is in normal mode, i.e. non fullscreen mode.
|
||||
// Note this only returns true once the transition from fullscreen back to
|
||||
// normal mode is complete.
|
||||
function inNormalMode(win) {
|
||||
return (
|
||||
win.innerWidth == win.normalSize.w && win.innerHeight == win.normalSize.h
|
||||
);
|
||||
// Returns true if the window believes it is in fullscreen. This may be true even
|
||||
// before an asynchronous fullscreen transition is complete.
|
||||
function inFullscreenMode(win) {
|
||||
return win.document.fullscreenElement;
|
||||
}
|
||||
|
||||
// Adds a listener that will be called once a fullscreen transition
|
||||
// is complete. When type==='enter', callback is called when we've
|
||||
// received a fullscreenchange event, and the fullscreen transition is
|
||||
// complete. When type==='exit', callback is called when we've
|
||||
// received a fullscreenchange event and the window dimensions match
|
||||
// the window dimensions when the window opened (so don't resize the
|
||||
// window while running your test!). inDoc is the document which
|
||||
// the listeners are added on, if absent, the listeners are added to
|
||||
// received a fullscreenchange event and the window is out of
|
||||
// fullscreen. inDoc is the document which the listeners are added on,
|
||||
// if absent, the listeners are added to the current document.
|
||||
// the current document.
|
||||
function addFullscreenChangeContinuation(type, callback, inDoc) {
|
||||
var doc = inDoc || document;
|
||||
var topWin = doc.defaultView.top;
|
||||
// Remember the window size in non-fullscreen mode.
|
||||
if (!topWin.normalSize) {
|
||||
topWin.normalSize = {
|
||||
w: window.innerWidth,
|
||||
h: window.innerHeight,
|
||||
};
|
||||
}
|
||||
function checkCondition() {
|
||||
if (type == "enter") {
|
||||
fullscreenChangeEnters++;
|
||||
return inFullscreenMode(topWin);
|
||||
} else if (type == "exit") {
|
||||
// If we just revert the state to a previous fullscreen state,
|
||||
// the window won't back to the normal mode. Hence we check
|
||||
// fullscreenElement first here. Note that we need to check
|
||||
// the fullscreen element of the outmost document here instead
|
||||
// of the current one.
|
||||
return topWin.document.fullscreenElement || inNormalMode(topWin);
|
||||
fullscreenChangeEnters--;
|
||||
return fullscreenChangeEnters
|
||||
? inFullscreenMode(topWin)
|
||||
: !inFullscreenMode(topWin);
|
||||
}
|
||||
throw new Error("'type' must be either 'enter', or 'exit'.");
|
||||
}
|
||||
@ -55,36 +52,20 @@ function addFullscreenChangeContinuation(type, callback, inDoc) {
|
||||
}
|
||||
function onFullscreenChange(event) {
|
||||
doc.removeEventListener("fullscreenchange", onFullscreenChange);
|
||||
if (checkCondition()) {
|
||||
invokeCallback(event);
|
||||
return;
|
||||
}
|
||||
function onResize() {
|
||||
if (checkCondition()) {
|
||||
topWin.removeEventListener("resize", onResize);
|
||||
invokeCallback(event);
|
||||
}
|
||||
}
|
||||
topWin.addEventListener("resize", onResize);
|
||||
ok(checkCondition(), `Should ${type} fullscreen.`);
|
||||
invokeCallback(event);
|
||||
}
|
||||
doc.addEventListener("fullscreenchange", onFullscreenChange);
|
||||
}
|
||||
|
||||
// Calls |callback| when the next fullscreenerror is dispatched to inDoc||document.
|
||||
function addFullscreenErrorContinuation(callback, inDoc) {
|
||||
return new Promise(resolve => {
|
||||
let doc = inDoc || document;
|
||||
let listener = function(event) {
|
||||
doc.removeEventListener("fullscreenerror", listener);
|
||||
setTimeout(function() {
|
||||
if (callback) {
|
||||
callback(event);
|
||||
}
|
||||
resolve();
|
||||
}, 0);
|
||||
};
|
||||
doc.addEventListener("fullscreenerror", listener);
|
||||
});
|
||||
let doc = inDoc || document;
|
||||
let listener = function(event) {
|
||||
doc.removeEventListener("fullscreenerror", listener);
|
||||
requestAnimationFrame(() => setTimeout(() => callback(event), 0), 0);
|
||||
};
|
||||
doc.addEventListener("fullscreenerror", listener);
|
||||
}
|
||||
|
||||
// Waits until the window has both the load event and a MozAfterPaint called on
|
||||
|
@ -42,66 +42,45 @@ SimpleTest.finish = function() {
|
||||
opener.nextTest();
|
||||
};
|
||||
|
||||
// Keep track of how many fullscreenChange enters we've received, so that
|
||||
// we can balance them with the number of exits we receive. We reset this
|
||||
// to 0 when we load a test.
|
||||
var fullscreenChangeEnters = 0;
|
||||
|
||||
addLoadEvent(function() {
|
||||
info(`Resetting fullscreen enter count.`);
|
||||
fullscreenChangeEnters = 0;
|
||||
if (typeof start !== "undefined") {
|
||||
// Try to stabilize the initial state of the page so that topWin.normalSize
|
||||
// ends up storing the correct values when entering fullscreen the first time.
|
||||
SimpleTest.requestFlakyTimeout(
|
||||
"Initial window opening animation takes some time."
|
||||
);
|
||||
SimpleTest.waitForFocus(() =>
|
||||
setTimeout(() => requestAnimationFrame(() => setTimeout(start)), 100)
|
||||
);
|
||||
// Delay one event loop to stabilize the initial state of the page.
|
||||
SimpleTest.executeSoon(start);
|
||||
}
|
||||
});
|
||||
|
||||
// Returns true if the window occupies the entire screen.
|
||||
// Note this only returns true once the transition from normal to
|
||||
// fullscreen mode is complete.
|
||||
// Returns true if the window believes it is in fullscreen. This may be true even
|
||||
// before an asynchronous fullscreen transition is complete.
|
||||
function inFullscreenMode(win) {
|
||||
return (
|
||||
win.innerWidth == win.screen.width && win.innerHeight == win.screen.height
|
||||
);
|
||||
}
|
||||
|
||||
// Returns true if the window is in normal mode, i.e. non fullscreen mode.
|
||||
// Note this only returns true once the transition from fullscreen back to
|
||||
// normal mode is complete.
|
||||
function inNormalMode(win) {
|
||||
return (
|
||||
win.innerWidth == win.normalSize.w && win.innerHeight == win.normalSize.h
|
||||
);
|
||||
return win.document.fullscreenElement;
|
||||
}
|
||||
|
||||
// Adds a listener that will be called once a fullscreen transition
|
||||
// is complete. When type==='enter', callback is called when we've
|
||||
// received a fullscreenchange event, and the fullscreen transition is
|
||||
// complete. When type==='exit', callback is called when we've
|
||||
// received a fullscreenchange event and the window dimensions match
|
||||
// the window dimensions when the window opened (so don't resize the
|
||||
// window while running your test!). inDoc is the document which
|
||||
// the listeners are added on, if absent, the listeners are added to
|
||||
// the current document.
|
||||
// received a fullscreenchange event and the window is out of
|
||||
// fullscreen. inDoc is the document which the listeners are added on,
|
||||
// if absent, the listeners are added to the current document.
|
||||
function addFullscreenChangeContinuation(type, callback, inDoc) {
|
||||
var doc = inDoc || document;
|
||||
var topWin = doc.defaultView.top;
|
||||
// Remember the window size in non-fullscreen mode.
|
||||
if (!topWin.normalSize) {
|
||||
topWin.normalSize = {
|
||||
w: window.innerWidth,
|
||||
h: window.innerHeight,
|
||||
};
|
||||
}
|
||||
function checkCondition() {
|
||||
if (type == "enter") {
|
||||
fullscreenChangeEnters++;
|
||||
return inFullscreenMode(topWin);
|
||||
} else if (type == "exit") {
|
||||
// If we just revert the state to a previous fullscreen state,
|
||||
// the window won't back to the normal mode. Hence we check
|
||||
// fullscreenElement first here. Note that we need to check
|
||||
// the fullscreen element of the outmost document here instead
|
||||
// of the current one.
|
||||
return topWin.document.fullscreenElement || inNormalMode(topWin);
|
||||
fullscreenChangeEnters--;
|
||||
return fullscreenChangeEnters
|
||||
? inFullscreenMode(topWin)
|
||||
: !inFullscreenMode(topWin);
|
||||
} else {
|
||||
throw "'type' must be either 'enter', or 'exit'.";
|
||||
}
|
||||
@ -113,17 +92,8 @@ function addFullscreenChangeContinuation(type, callback, inDoc) {
|
||||
}
|
||||
function onFullscreenChange(event) {
|
||||
doc.removeEventListener("fullscreenchange", onFullscreenChange);
|
||||
if (checkCondition()) {
|
||||
invokeCallback(event);
|
||||
return;
|
||||
}
|
||||
function onResize() {
|
||||
if (checkCondition()) {
|
||||
topWin.removeEventListener("resize", onResize);
|
||||
invokeCallback(event);
|
||||
}
|
||||
}
|
||||
topWin.addEventListener("resize", onResize);
|
||||
ok(checkCondition(), `Should ${type} fullscreen.`);
|
||||
invokeCallback(event);
|
||||
}
|
||||
doc.addEventListener("fullscreenchange", onFullscreenChange);
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user