зеркало из https://github.com/mozilla/gecko-dev.git
180 строки
5.4 KiB
HTML
180 строки
5.4 KiB
HTML
<!DOCTYPE html>
|
|
<html>
|
|
<head>
|
|
<title>Test for race conditions of Fullscreen API</title>
|
|
<script src="/tests/SimpleTest/SimpleTest.js"></script>
|
|
<script src="/tests/SimpleTest/EventUtils.js"></script>
|
|
<link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/>
|
|
</head>
|
|
<body>
|
|
<script>
|
|
|
|
function Deferred() {
|
|
this.promise = new Promise(resolve => {
|
|
this.resolve = resolve;
|
|
});
|
|
}
|
|
|
|
function checkIsChromeFullscreen(win, inFullscreen) {
|
|
return SimpleTest.promiseWaitForCondition(
|
|
() => win.fullScreen == inFullscreen,
|
|
"The window should exit fullscreen state");
|
|
}
|
|
|
|
SimpleTest.waitForExplicitFinish();
|
|
// XXX This actually exposes a true race condition, but it could rarely
|
|
// happen in real world, because it only happens when requestFullscreen
|
|
// is called immediately after exiting fullscreen in certain condition,
|
|
// and in real life, requestFullscreen can only be called inside a user
|
|
// event handler. But we want to fix this race condition at some point,
|
|
// via queuing all exiting request as well as entering request together
|
|
// which we may eventually need to do for bug 1188256.
|
|
SimpleTest.requestFlakyTimeout(
|
|
"Need to wait for potential fullscreen transition");
|
|
addLoadEvent(function () {
|
|
SpecialPowers.pushPrefEnv({
|
|
"set": [
|
|
["full-screen-api.unprefix.enabled", true],
|
|
["full-screen-api.allow-trusted-requests-only", false],
|
|
// Use legacy data: URI behavior to run test.
|
|
["security.data_uri.unique_opaque_origin", false],
|
|
["security.data_uri.block_toplevel_data_uri_navigations", false],
|
|
]
|
|
}, next);
|
|
});
|
|
|
|
const OPEN_WINDOW_FUNCS = [
|
|
function openNewTab() {
|
|
return new Promise(resolve => {
|
|
var win = window.open("about:blank");
|
|
resolve(win);
|
|
});
|
|
},
|
|
function openNewWindow() {
|
|
return new Promise(resolve => {
|
|
var win = window.open("about:blank", "", "width=300,height=200");
|
|
win.addEventListener("MozAfterPaint", () => {
|
|
resolve(win);
|
|
}, { once: true });
|
|
});
|
|
}
|
|
];
|
|
|
|
const ACTION_FUNCS = [
|
|
function navigate(win) {
|
|
info("About to navigate to another page");
|
|
var deferred = new Deferred();
|
|
win.location = "data:text/html,<html>";
|
|
setTimeout(() => {
|
|
SimpleTest.waitForFocus(() => {
|
|
checkIsChromeFullscreen(win, false).then(() => {
|
|
win.close();
|
|
deferred.resolve();
|
|
});
|
|
}, win);
|
|
}, 0);
|
|
return deferred.promise;
|
|
},
|
|
function closeWindow(win) {
|
|
info("About to close the window");
|
|
win.close();
|
|
return Promise.resolve();
|
|
},
|
|
function exitFullscreen(win) {
|
|
info("About to cancel fullscreen");
|
|
var deferred = new Deferred();
|
|
function listener() {
|
|
win.removeEventListener("fullscreenchange", listener);
|
|
ok(!win.document.fullscreenElement, "Should exit fullscreen");
|
|
checkIsChromeFullscreen(win, false).then(() => {
|
|
win.close();
|
|
deferred.resolve();
|
|
});
|
|
}
|
|
win.addEventListener("fullscreenchange", listener);
|
|
win.document.exitFullscreen();
|
|
return deferred.promise;
|
|
},
|
|
function exitAndClose(win) {
|
|
info("About to cancel fullscreen and close the window");
|
|
win.document.exitFullscreen();
|
|
win.close();
|
|
return Promise.resolve();
|
|
}
|
|
];
|
|
|
|
function* testGenerator() {
|
|
for (var openWinFunc of OPEN_WINDOW_FUNCS) {
|
|
for (var actionFunc of ACTION_FUNCS) {
|
|
info(`Testing ${openWinFunc.name}, ${actionFunc.name}`);
|
|
yield { openWinFunc: openWinFunc, actionFunc: actionFunc };
|
|
}
|
|
}
|
|
}
|
|
|
|
function runTest(test) {
|
|
var winPromise = test.openWinFunc();
|
|
return winPromise.then((win) => {
|
|
return new Promise(resolve => {
|
|
SimpleTest.waitForFocus(() => resolve(win), win, true);
|
|
});
|
|
}).then((win) => {
|
|
return new Promise((resolve, reject) => {
|
|
var retried = false;
|
|
function listener(evt) {
|
|
if (!retried && evt.type == "fullscreenerror") {
|
|
todo(false, "Failed to enter fullscreen, but try again");
|
|
retried = true;
|
|
SimpleTest.waitForFocus(() => {
|
|
win.document.documentElement.requestFullscreen();
|
|
}, win, true);
|
|
return;
|
|
}
|
|
win.removeEventListener("fullscreenchange", listener);
|
|
win.removeEventListener("fullscreenerror", listener);
|
|
is(evt.type, "fullscreenchange", "Should get fullscreenchange");
|
|
ok(win.document.fullscreenElement, "Should have entered fullscreen");
|
|
ok(win.fullScreen, "The window should be in fullscreen");
|
|
test.actionFunc(win).then(() => resolve(win));
|
|
}
|
|
if (win.fullScreen) {
|
|
todo(false, "Should not open in fullscreen mode");
|
|
win.close();
|
|
reject();
|
|
return;
|
|
}
|
|
info("About to enter fullscreen");
|
|
win.addEventListener("fullscreenchange", listener);
|
|
win.addEventListener("fullscreenerror", listener);
|
|
win.document.documentElement.requestFullscreen();
|
|
});
|
|
}).then((win) => {
|
|
ok(win.closed, "The window should have been closed");
|
|
});
|
|
}
|
|
|
|
var tests = testGenerator();
|
|
|
|
function next() {
|
|
var test = tests.next().value;
|
|
if (test) {
|
|
runTest(test).catch(() => {
|
|
return new Promise(resolve => {
|
|
SimpleTest.waitForFocus(resolve);
|
|
}).then(() => runTest(test));
|
|
}).catch(() => {
|
|
ok(false, "Fail to run test " +
|
|
`${test.openWinFunc.name}, ${test.actionFunc.name}`);
|
|
}).then(() => {
|
|
setTimeout(() => SimpleTest.waitForFocus(next), 1000);
|
|
});
|
|
} else {
|
|
SimpleTest.finish();
|
|
return;
|
|
}
|
|
}
|
|
|
|
</script>
|
|
</body>
|
|
</html>
|