diff options
Diffstat (limited to 'dom/tests/mochitest/bugs/test_resize_move_windows.html')
-rw-r--r-- | dom/tests/mochitest/bugs/test_resize_move_windows.html | 378 |
1 files changed, 378 insertions, 0 deletions
diff --git a/dom/tests/mochitest/bugs/test_resize_move_windows.html b/dom/tests/mochitest/bugs/test_resize_move_windows.html new file mode 100644 index 000000000..0762e9231 --- /dev/null +++ b/dom/tests/mochitest/bugs/test_resize_move_windows.html @@ -0,0 +1,378 @@ +<!DOCTYPE HTML> +<html> +<!-- +https://bugzilla.mozilla.org/show_bug.cgi?id=565541 +--> +<head> + <title>Test for Bug 565541</title> + <script type="application/javascript" src="/tests/SimpleTest/SimpleTest.js"></script> + <link rel="stylesheet" type="text/css" href="/tests/SimpleTest/test.css"/> +</head> +<body> +<a target="_blank" href="https://bugzilla.mozilla.org/show_bug.cgi?id=565541">Mozilla Bug 565541</a> +<p id="display"></p> +<div id="content" style="display: none"> + +</div> +<pre id="test"> +<script type="application/javascript"> + +/** Test for Bug 565541 **/ + +SimpleTest.waitForExplicitFinish(); + +var previousX, previousY, previousWidth, previousHeight; + +["innerWidth", "innerHeight", "screenX", "screenY", "outerWidth", + "outerHeight"].map(function(name) { + window[name+"Getter"] = Object.getOwnPropertyDescriptor(window, name).get; +}); + +function backValues() +{ + previousX = window.screenX; + previousY = window.screenY; + previousWidth = window.innerWidth; + previousHeight = window.innerHeight; +} + +function restoreValues() +{ + window.screenX = previousX; + window.screenY = previousY; + window.innerWidth = previousWidth; + window.innerHeight = previousHeight; +} + +function getNewWidth(aWindow) +{ + return (aWindow.innerWidth > (screen.width / 2)) ? 100 : screen.width; +} + +function getNewHeight(aWindow) +{ + return (aWindow.innerHeight > (screen.height / 2)) ? 100 : screen.height; +} + +function getNewX(aWindow) +{ + return (aWindow.screenX > ((screen.width - aWindow.outerWidth) / 2)) + ? 0 : screen.width - aWindow.outerWidth; +} + +function getNewY(aWindow) +{ + return (aWindow.screenY > ((screen.height - aWindow.outerHeight) / 2)) + ? 0 : screen.height - aWindow.outerHeight; +} + +/** + * hitEventLoop is called when we want to check something but we can't rely on + * an event or a specific number of event loop hiting. + * This method can be called by specifying a condition, a test (using SimpleTest + * API), how many times the event loop has to be hitten and what to call next. + * If times < 0, the event loop will be hitten as long as the condition isn't + * true or the test doesn't time out. + */ +function hitEventLoop(condition, test, times) { + return new Promise(function(resolve, reject) { + function doMagic() { + if (condition() || times == 0) { + test(); + resolve(); + return; + } + + setTimeout(doMagic, 0, condition, test, times - 1); + } + + doMagic(); + }); +} + +function checkChangeIsDisabled(aWindow) { + // We want to check that nothing has changed. Having a high value would take + // too much time. Worse thing that could happen is random green. + var hits = 5; + + function getProp(propName) { + return window[propName + "Getter"].call(aWindow); + } + + var originalWidth = getProp("innerWidth"); + var originalHeight = getProp("innerHeight"); + + var originalX = getProp("screenX"); + var originalY = getProp("screenY"); + + var oWidth = getProp("outerWidth"); + var oHeight = getProp("outerHeight"); + + function changeCondition() { + return aWindow.innerWidth != originalWidth || + aWindow.innerHeight != originalHeight || + aWindow.screenX != originalX || aWindow.screenY != originalY || + aWindow.outerWidth != oWidth || aWindow.outerHeight != oHeight; + } + + function changeTest() { + is(getProp("innerWidth"), originalWidth, + "Window width shouldn't have changed"); + is(getProp("innerHeight"), originalHeight, + "Window height shouldn't have changed"); + is(getProp("screenX"), originalX, + "Window x position shouldn't have changed"); + is(getProp("screenY"), originalY, + "Window y position shouldn't have changed"); + is(getProp("outerWidth"), oWidth, + "Window outerWidth shouldn't have changed"); + is(getProp("outerHeight"), oHeight, + "Window outerHeight shouldn't have changed"); + } + + /** + * Size changes. + */ + var newWidth = getNewWidth(aWindow); + var newHeight = getNewHeight(aWindow); + + aWindow.innerWidth = newWidth; + aWindow.innerHeight = newHeight; + + aWindow.resizeTo(newWidth, newHeight); + + aWindow.resizeBy(newWidth - aWindow.innerWidth, + newHeight - aWindow.innerHeight); + + aWindow.sizeToContent(); + + /** + * Position checks. + */ + var newX = getNewX(aWindow); + var newY = getNewY(aWindow); + + aWindow.screenX = newX; + aWindow.screenY = newY; + + aWindow.moveTo(newX, newY); + + aWindow.moveBy(newX - aWindow.screenX, + newY - aWindow.screenY); + + /** + * Outer width/height checks. + */ + aWindow.outerWidth *= 2; + aWindow.outerHeight *= 2; + + // We did a lot of changes. Now, we are going to wait and see if something + // happens. + // NOTE: if this happens to fail, you will have to check manually which + // operation has been accepted. + return hitEventLoop(changeCondition, changeTest, hits); +} + +function checkChangeIsEnabled(aWindow, aNext) +{ + // Something should happen. We are not going to go to the next test until + // it does. + var hits = -1; + + var prevWidth; + var prevHeight; + + var prevX; + var prevY; + + var oWidth; + var oHeight; + + function sizeChangeCondition() { + return aWindow.innerWidth != prevWidth && aWindow.innerHeight != prevHeight; + } + + function sizeChangeTest() { + isnot(aWindow.innerWidth, prevWidth, "Window width should have changed"); + isnot(aWindow.innerHeight, prevHeight, "Window height should have changed"); + + prevWidth = aWindow.innerWidth; + prevHeight = aWindow.innerHeight; + } + + function posChangeCondition() { + // With GTK, sometimes, only one dimension changes. + if (navigator.platform.indexOf('Linux') != -1) { + return aWindow.screenX != prevX || aWindow.screenY != prevY; + } + return aWindow.screenX != prevX && aWindow.screenY != prevY; + } + + function posChangeTest() { + // With GTK, sometimes, only one dimension changes. + if (navigator.platform.indexOf('Linux') != -1) { + // With GTK, sometimes, aWindow.screenX changes during two calls. + // So we call it once and save the returned value. + var x = aWindow.screenX; + var y = aWindow.screenY; + if (x != prevX) { + isnot(x, prevX, "Window x position should have changed"); + } + if (y != prevY) { + isnot(y, prevY, "Window y position should have changed"); + } + } else { + isnot(aWindow.screenX, prevX, "Window x position should have changed"); + isnot(aWindow.screenY, prevY, "Window y position should have changed"); + } + + prevX = aWindow.screenX; + prevY = aWindow.screenY; + } + + function outerChangeCondition() { + return aWindow.outerWidth != oWidth && aWindow.outerHeight != oHeight; + } + + function outerChangeTest() { + isnot(aWindow.outerWidth, oWidth, "Window outerWidth should have changed"); + isnot(aWindow.outerHeight, oHeight, "Window outerHeight should have changed"); + } + + /** + * Size checks. + */ + prevWidth = aWindow.innerWidth; + prevHeight = aWindow.innerHeight; + aWindow.innerWidth = getNewWidth(aWindow); + aWindow.innerHeight = getNewHeight(aWindow); + + hitEventLoop(sizeChangeCondition, sizeChangeTest, hits) + .then(function() { + aWindow.resizeTo(getNewWidth(aWindow), getNewHeight(aWindow)); + return hitEventLoop(sizeChangeCondition, sizeChangeTest, hits); + }) + .then(function () { + aWindow.resizeBy(getNewWidth(aWindow) - aWindow.innerWidth, + getNewHeight(aWindow) - aWindow.innerHeight); + return hitEventLoop(sizeChangeCondition, sizeChangeTest, hits); + }) + .then(function() { + aWindow.sizeToContent(); + return hitEventLoop(sizeChangeCondition, sizeChangeTest, hits); + }) + .then(function() { + /** + * Position checks. + */ + prevX = aWindow.screenX; + prevY = aWindow.screenY; + + aWindow.screenX = getNewX(aWindow); + aWindow.screenY = getNewY(aWindow); + return hitEventLoop(posChangeCondition, posChangeTest, hits); + }) + .then(function() { + prevX = aWindow.screenX; + prevY = aWindow.screenY; + + aWindow.moveTo(getNewX(aWindow), getNewY(aWindow)); + return hitEventLoop(posChangeCondition, posChangeTest, hits); + }) + .then(function() { + prevX = aWindow.screenX; + prevY = aWindow.screenY; + + aWindow.moveBy(getNewX(aWindow) - aWindow.screenX, + getNewY(aWindow) - aWindow.screenY); + return hitEventLoop(posChangeCondition, posChangeTest, hits); + }) + .then(function() { + /** + * Outer width/height checks. + */ + oWidth = aWindow.outerWidth; + oHeight = aWindow.outerHeight; + + aWindow.outerWidth = oWidth * 2; + aWindow.outerHeight = oHeight * 2; + return hitEventLoop(outerChangeCondition, outerChangeTest, hits); + }) + .then(function() { + let origWidth = oWidth; + let origHeight = oHeight; + + oWidth = aWindow.outerWidth; + oHeight = aWindow.outerHeight; + + aWindow.outerWidth = origWidth; + aWindow.outerHeight = origHeight; + return hitEventLoop(outerChangeCondition, outerChangeTest, hits); + }) + .then(aNext); +} + +SpecialPowers.pushPrefEnv({"set": [["dom.disable_window_move_resize", false]]}, function() { +SimpleTest.waitForFocus(function() { + if (screen.width <= 200 || screen.height <= 200) { + todo(false, "The screen needs to be bigger than 200px*200px to run this test."); + SimpleTest.finish(); + return; + } + + backValues(); + + // The current window can't change it's own size and position. + checkChangeIsDisabled(window).then(function() { + // We create a window and check that it can change its own size and position. + // However, passing size/position parameters to window.open should work. + var w = window.open("data:text/html,<script>" + + "function check(next) {" + + " var is_range = function(aTest, aValue, aRange, aMsg) {" + + " window.opener.ok(aTest < aValue + aRange && aTest > aValue - aRange, aMsg);" + + " };" + + " is_range(window.innerWidth, 170, 5, 'parameter width should be taken into account');" + + " is_range(window.innerHeight, 170, 5, 'parameter height should be taken into account');" + + " is_range(window.screenX, 65, 5, 'parameter screenX should be taken into account');" + + " is_range(window.screenY, 65, 5, 'parameter screenY should be taken into account');" + + " window.opener.checkChangeIsEnabled(window, next);" + + "} <\/script>", '', + 'width=170,height=170,screenX=65,screenY=65'); + + SimpleTest.waitForFocus(function() { + w.check(function() { + // The current window can change the size and position of the created one. + checkChangeIsEnabled(w, function() { + w.close(); + + // If we call window.open with an empty string as a third parameter, + // by default, it will create a new tab instead of a new window. + // In that case, we shouldn't allow the caller to change the size/position. + w = window.open("data:text/html,<script>" + + "function check(next) {" + + " window.opener.checkChangeIsDisabled(window).then(next);" + + "} <\/script>", '', ''); + + SimpleTest.waitForFocus(function() { + w.check(function() { + + // The current window can't change the size and position of the new tab. + checkChangeIsDisabled(w).then(function() { + w.close(); + + restoreValues(); + SimpleTest.finish(); + }); + }); + }, w, false); + }); + }) + }, w, false); + }); +}); +}); // SpecialPowers.pushPrefEnv() + +</script> +</pre> +</body> +</html> |