/* Any copyright is dedicated to the Public Domain. http://creativecommons.org/publicdomain/zero/1.0/ */ "use strict"; add_task(function* () { let tab = yield addTab("data:text/html,mop"); let {rdm, manager} = yield openRDM(tab, "menu"); let container = gBrowser.getBrowserContainer(); is(container.getAttribute("responsivemode"), "true", "Should be in responsive mode."); is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "true", "Menu item should be checked"); ok(rdm, "An instance of the RDM should be attached to the tab."); let originalWidth = (yield getSizing()).width; let documentLoaded = waitForDocLoadComplete(); gBrowser.loadURI("data:text/html;charset=utf-8,mop" + "
<%2Fdiv>"); yield documentLoaded; let newWidth = (yield getSizing()).width; is(originalWidth, newWidth, "Floating scrollbars shouldn't change the width"); yield testPresets(rdm, manager); info("Testing mouse resizing"); yield testManualMouseResize(rdm, manager); info("Testing mouse resizing with shift key"); yield testManualMouseResize(rdm, manager, "shift"); info("Testing mouse resizing with ctrl key"); yield testManualMouseResize(rdm, manager, "ctrl"); info("Testing resizing with user custom keyboard input"); yield testResizeUsingCustomInput(rdm, manager); info("Testing invalid keyboard input"); yield testInvalidUserInput(rdm); info("Testing rotation"); yield testRotate(rdm, manager); let {width: widthBeforeClose, height: heightBeforeClose} = yield getSizing(); info("Restarting responsive mode"); yield closeRDM(rdm); let resized = waitForResizeTo(manager, widthBeforeClose, heightBeforeClose); ({rdm} = yield openRDM(tab, "keyboard")); yield resized; let currentSize = yield getSizing(); is(currentSize.width, widthBeforeClose, "width should be restored"); is(currentSize.height, heightBeforeClose, "height should be restored"); container = gBrowser.getBrowserContainer(); is(container.getAttribute("responsivemode"), "true", "In responsive mode."); is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "true", "menu item should be checked"); let isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1; if (!isWinXP) { yield testScreenshot(rdm); } yield closeRDM(rdm); is(document.getElementById("menu_responsiveUI").getAttribute("checked"), "false", "menu item should be unchecked"); }); function* testPresets(rdm, manager) { // Starting from length - 4 because last 3 items are not presets : // the separator, the add button and the remove button for (let c = rdm.menulist.firstChild.childNodes.length - 4; c >= 0; c--) { let item = rdm.menulist.firstChild.childNodes[c]; let [width, height] = extractSizeFromString(item.getAttribute("label")); yield setPresetIndex(rdm, manager, c); let {width: contentWidth, height: contentHeight} = yield getSizing(); is(contentWidth, width, "preset" + c + ": the width should be changed"); is(contentHeight, height, "preset" + c + ": the height should be changed"); } } function* testManualMouseResize(rdm, manager, pressedKey) { yield setSize(rdm, manager, 100, 100); let {width: initialWidth, height: initialHeight} = yield getSizing(); is(initialWidth, 100, "Width should be reset to 100"); is(initialHeight, 100, "Height should be reset to 100"); let x = 2, y = 2; EventUtils.synthesizeMouse(rdm.resizer, x, y, {type: "mousedown"}, window); let mouseMoveParams = {type: "mousemove"}; if (pressedKey == "shift") { x += 23; y += 10; mouseMoveParams.shiftKey = true; } else if (pressedKey == "ctrl") { x += 120; y += 60; mouseMoveParams.ctrlKey = true; } else { x += 20; y += 10; } EventUtils.synthesizeMouse(rdm.resizer, x, y, mouseMoveParams, window); EventUtils.synthesizeMouse(rdm.resizer, x, y, {type: "mouseup"}, window); yield once(manager, "content-resize"); let expectedWidth = initialWidth + 20; let expectedHeight = initialHeight + 10; info("initial width: " + initialWidth); info("initial height: " + initialHeight); yield verifyResize(rdm, expectedWidth, expectedHeight); } function* testResizeUsingCustomInput(rdm, manager) { let {width: initialWidth, height: initialHeight} = yield getSizing(); let expectedWidth = initialWidth - 20, expectedHeight = initialHeight - 10; let userInput = expectedWidth + " x " + expectedHeight; rdm.menulist.inputField.value = ""; rdm.menulist.focus(); processStringAsKey(userInput); // While typing, the size should not change let currentSize = yield getSizing(); is(currentSize.width, initialWidth, "Typing shouldn't change the width"); is(currentSize.height, initialHeight, "Typing shouldn't change the height"); // Only the `change` event must change the size EventUtils.synthesizeKey("VK_RETURN", {}); yield once(manager, "content-resize"); yield verifyResize(rdm, expectedWidth, expectedHeight); } function* testInvalidUserInput(rdm) { let {width: initialWidth, height: initialHeight} = yield getSizing(); let index = rdm.menulist.selectedIndex; let expectedValue = initialWidth + "\u00D7" + initialHeight; let expectedLabel = rdm.menulist.firstChild.firstChild.getAttribute("label"); let userInput = "I'm wrong"; rdm.menulist.inputField.value = ""; rdm.menulist.focus(); processStringAsKey(userInput); EventUtils.synthesizeKey("VK_RETURN", {}); let currentSize = yield getSizing(); is(currentSize.width, initialWidth, "Width should not change"); is(currentSize.height, initialHeight, "Height should not change"); is(rdm.menulist.selectedIndex, index, "Selected item should not change."); is(rdm.menulist.value, expectedValue, "Value should be reset"); let label = rdm.menulist.firstChild.firstChild.getAttribute("label"); is(label, expectedLabel, "Custom menuitem's label should not change"); } function* testRotate(rdm, manager) { yield setSize(rdm, manager, 100, 200); let {width: initialWidth, height: initialHeight} = yield getSizing(); rdm.rotate(); yield once(manager, "content-resize"); let newSize = yield getSizing(); is(newSize.width, initialHeight, "The width should now be the height."); is(newSize.height, initialWidth, "The height should now be the width."); let label = rdm.menulist.firstChild.firstChild.getAttribute("label"); let [width, height] = extractSizeFromString(label); is(width, initialHeight, "Width in label should be updated"); is(height, initialWidth, "Height in label should be updated"); } function* verifyResize(rdm, expectedWidth, expectedHeight) { let currentSize = yield getSizing(); is(currentSize.width, expectedWidth, "Width should now change"); is(currentSize.height, expectedHeight, "Height should now change"); is(rdm.menulist.selectedIndex, -1, "Custom menuitem cannot be selected"); let label = rdm.menulist.firstChild.firstChild.getAttribute("label"); let value = rdm.menulist.value; isnot(label, value, "The menulist item label should be different than the menulist value"); let [width, height] = extractSizeFromString(label); is(width, expectedWidth, "Width in label should be updated"); is(height, expectedHeight, "Height in label should be updated"); [width, height] = extractSizeFromString(value); is(width, expectedWidth, "Value should be updated with new width"); is(height, expectedHeight, "Value should be updated with new height"); } function* testScreenshot(rdm) { info("Testing screenshot"); rdm.screenshot("responsiveui"); let {FileUtils} = Cu.import("resource://gre/modules/FileUtils.jsm", {}); while (true) { // while(true) until we find the file. // no need for a timeout, the test will get killed anyway. let file = FileUtils.getFile("DfltDwnld", [ "responsiveui.png" ]); if (file.exists()) { ok(true, "Screenshot file exists"); file.remove(false); break; } info("checking if file exists in 200ms"); yield wait(200); } } function* getSizing() { let browser = gBrowser.selectedBrowser; let sizing = yield ContentTask.spawn(browser, {}, function* () { return { width: content.innerWidth, height: content.innerHeight }; }); return sizing; } function extractSizeFromString(str) { let numbers = str.match(/(\d+)[^\d]*(\d+)/); if (numbers) { return [numbers[1], numbers[2]]; } return [null, null]; } function processStringAsKey(str) { for (let i = 0, l = str.length; i < l; i++) { EventUtils.synthesizeKey(str.charAt(i), {}); } }