summaryrefslogtreecommitdiffstats
path: root/dom/html/test/test_fullscreen-api-race.html
diff options
context:
space:
mode:
Diffstat (limited to 'dom/html/test/test_fullscreen-api-race.html')
-rw-r--r--dom/html/test/test_fullscreen-api-race.html166
1 files changed, 166 insertions, 0 deletions
diff --git a/dom/html/test/test_fullscreen-api-race.html b/dom/html/test/test_fullscreen-api-race.html
new file mode 100644
index 000000000..03c6c6da3
--- /dev/null
+++ b/dom/html/test/test_fullscreen-api-race.html
@@ -0,0 +1,166 @@
+<!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]
+ ]
+ }, next);
+});
+
+const OPEN_WINDOW_FUNCS = [
+ function openNewTab() {
+ return window.open("about:blank");
+ },
+ function openNewWindow() {
+ return window.open("about:blank", "", "width=300,height=200");
+ }
+];
+
+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 win = test.openWinFunc();
+ return new Promise(resolve => {
+ SimpleTest.waitForFocus(resolve, win, true);
+ }).then(() => {
+ 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);
+ }
+ 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(() => {
+ 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>