1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177
|
<!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.allow-trusted-requests-only", false],
]
}, next);
});
const OPEN_WINDOW_FUNCS = [
function openNewTab() {
return new Promise(resolve => {
var win = window.open("about:blank");
setTimeout(function() {
resolve(win);
}, 0);
});
},
function openNewWindow() {
return new Promise(resolve => {
var win = window.open("about:blank", "", "width=300,height=200");
setTimeout(function() {
resolve(win);
}, 0);
});
}
];
const ACTION_FUNCS = [
function navigate(win) {
info("About to navigate to another page");
var promise = new Promise(resolve => {
window.addEventListener("message", () => {
SimpleTest.waitForFocus(() => {
checkIsChromeFullscreen(win, false).then(() => {
win.close();
resolve();
});
}, win);
}, { once: true });
});
win.location = "file_fullscreen-api-race.html";
return 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, 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();
}
}
</script>
</body>
</html>
|