Bug 1235953 - Refactor responsive mode tests to use add_task, to not use CPOWs, and make sure they all wait for the off event. r=ochameau

This commit is contained in:
Tim Nguyen 2016-01-06 19:09:15 +01:00
parent a0cfa06a42
commit 599baa355b
11 changed files with 503 additions and 574 deletions

View File

@ -5,6 +5,11 @@
],
// All globals made available in the test environment.
"globals": {
"DevToolsUtils": true,
"gDevTools": true,
"once": true,
"synthesizeKeyFromKeyTag": true,
"TargetFactory": true,
"waitForTick": true,
}
}

View File

@ -1,4 +1,8 @@
{
// Extend from the shared list of defined globals for mochitests.
"extends": "../../../.eslintrc.mochitests"
"extends": "../../../.eslintrc.mochitests",
"globals": {
"ResponsiveUI": true,
"helpers": true
}
}

View File

@ -1,6 +1,8 @@
/* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/ */
"use strict";
///////////////////
//
// Whitelisting this test.
@ -14,15 +16,15 @@ function test() {
.hasAttribute("responsivemode");
}
helpers.addTabWithToolbar("data:text/html;charset=utf-8,hi", function(options) {
helpers.addTabWithToolbar("data:text/html;charset=utf-8,hi", (options) => {
return helpers.audit(options, [
{
setup: "resize toggle",
check: {
input: 'resize toggle',
hints: '',
markup: 'VVVVVVVVVVVVV',
status: 'VALID'
input: "resize toggle",
hints: "",
markup: "VVVVVVVVVVVVV",
status: "VALID"
},
exec: {
output: ""
@ -34,10 +36,10 @@ function test() {
{
setup: "resize toggle",
check: {
input: 'resize toggle',
hints: '',
markup: 'VVVVVVVVVVVVV',
status: 'VALID'
input: "resize toggle",
hints: "",
markup: "VVVVVVVVVVVVV",
status: "VALID"
},
exec: {
output: ""
@ -49,10 +51,10 @@ function test() {
{
setup: "resize on",
check: {
input: 'resize on',
hints: '',
markup: 'VVVVVVVVV',
status: 'VALID'
input: "resize on",
hints: "",
markup: "VVVVVVVVV",
status: "VALID"
},
exec: {
output: ""
@ -64,10 +66,10 @@ function test() {
{
setup: "resize off",
check: {
input: 'resize off',
hints: '',
markup: 'VVVVVVVVVV',
status: 'VALID'
input: "resize off",
hints: "",
markup: "VVVVVVVVVV",
status: "VALID"
},
exec: {
output: ""
@ -79,10 +81,10 @@ function test() {
{
setup: "resize to 400 400",
check: {
input: 'resize to 400 400',
hints: '',
markup: 'VVVVVVVVVVVVVVVVV',
status: 'VALID',
input: "resize to 400 400",
hints: "",
markup: "VVVVVVVVVVVVVVVVV",
status: "VALID",
args: {
width: { value: 400 },
height: { value: 400 },
@ -98,10 +100,10 @@ function test() {
{
setup: "resize off",
check: {
input: 'resize off',
hints: '',
markup: 'VVVVVVVVVV',
status: 'VALID'
input: "resize off",
hints: "",
markup: "VVVVVVVVVV",
status: "VALID"
},
exec: {
output: ""

View File

@ -1,62 +1,68 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
let instance;
let mgr = ResponsiveUI.ResponsiveUIManager;
"use strict";
waitForExplicitFinish();
add_task(function*() {
let tab = yield addTab("about:logo");
let {rdm} = yield openRDM(tab);
ok(rdm, "An instance of the RDM should be attached to the tab.");
rdm.setSize(110, 500);
gBrowser.selectedTab = gBrowser.addTab("about:logo");
gBrowser.selectedBrowser.addEventListener("load", function onload() {
gBrowser.selectedBrowser.removeEventListener("load", onload, true);
startTest();
}, true);
info("Checking initial width/height properties.");
yield doInitialChecks();
function startTest() {
mgr.once("on", function() {executeSoon(onUIOpen)});
document.getElementById("Tools:ResponsiveUI").doCommand();
}
function onUIOpen() {
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
instance.stack.setAttribute("notransition", "true");
ok(instance, "instance of the module is attached to the tab.");
instance.setSize(110, 500);
ok(content.innerWidth, 110, "initial width is valid");
let mql = content.matchMedia("(max-device-width:100px)")
ok(!mql.matches, "media query doesn't match.");
mql.addListener(onMediaChange);
instance.setSize(90, 500);
}
function onMediaChange(mql) {
mql.removeListener(onMediaChange);
ok(mql.matches, "media query matches.");
ok(window.screen.width != content.screen.width, "screen.width is not the size of the screen.");
is(content.screen.width, 90, "screen.width is the width of the page.");
is(content.screen.height, 500, "screen.height is the height of the page.");
info("Changing the RDM size");
rdm.setSize(90, 500);
info("Checking for screen props");
yield checkScreenProps();
info("Setting docShell.deviceSizeIsPageSize to false");
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
let docShell = content.QueryInterface(Ci.nsIInterfaceRequestor)
.getInterface(Ci.nsIWebNavigation)
.QueryInterface(Ci.nsIDocShell);
mql.addListener(onMediaChange2);
docShell.deviceSizeIsPageSize = false;
}
});
function onMediaChange2(mql) {
mql.removeListener(onMediaChange);
ok(!mql.matches, "media query has been re-evaluated.");
ok(window.screen.width == content.screen.width, "screen.width is not the size of the screen.");
instance.stack.removeAttribute("notransition");
document.getElementById("Tools:ResponsiveUI").doCommand();
gBrowser.removeCurrentTab();
finish();
}
info("Checking for screen props once again.");
yield checkScreenProps2();
yield closeRDM(rdm);
});
function* doInitialChecks() {
let {innerWidth, matchesMedia} = yield grabContentInfo();
is(innerWidth, 110, "initial width should be 110px");
ok(!matchesMedia, "media query shouldn't match.");
}
function* checkScreenProps() {
let {matchesMedia, screen} = yield grabContentInfo();
ok(matchesMedia, "media query should match");
isnot(window.screen.width, screen.width,
"screen.width should not be the size of the screen.");
is(screen.width, 90, "screen.width should be the page width");
is(screen.height, 500, "screen.height should be the page height");
}
function* checkScreenProps2() {
let {matchesMedia, screen} = yield grabContentInfo();
ok(!matchesMedia, "media query should be re-evaluated.");
is(window.screen.width, screen.width,
"screen.width should be the size of the screen.");
}
function grabContentInfo() {
return ContentTask.spawn(gBrowser.selectedBrowser, {}, function*() {
return {
screen: {
width: content.screen.width,
height: content.screen.height
},
innerWidth: content.innerWidth,
matchesMedia: content.matchMedia("(max-device-width:100px)").matches
};
});
}

View File

@ -35,7 +35,8 @@ add_task(function*() {
info("Try growing the viewport and checking the applied styles");
yield testGrow(view, inspector, rdm);
gBrowser.removeCurrentTab();
yield closeRDM(rdm);
yield closeToolbox();
});
function* testShrink(computedView, inspector, rdm) {

View File

@ -25,7 +25,7 @@ add_task(function*() {
yield addTab(TEST_URI);
info("Open the responsive design mode and set its size to 500x500 to start");
let {rdm, manager} = yield openRDM();
let {rdm} = yield openRDM();
rdm.setSize(500, 500);
info("Open the inspector, rule-view and select the test node");
@ -41,11 +41,12 @@ add_task(function*() {
info("Check that ESC still opens the split console");
yield testEscapeOpensSplitConsole(inspector);
yield closeToolbox();
info("Test the state of the RDM menu item");
yield testMenuItem(manager);
yield testMenuItem(rdm);
Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled");
gBrowser.removeCurrentTab();
});
function* testShrink(ruleView, rdm) {
@ -79,19 +80,14 @@ function* testEscapeOpensSplitConsole(inspector) {
ok(inspector._toolbox._splitConsole, "Console is split after pressing ESC.");
}
function* testMenuItem(manager) {
function* testMenuItem(rdm) {
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
"true",
"The menu item is checked");
"true", "The menu item is checked");
info("Toggle off the RDM");
let onManagerOff = manager.once("off");
manager.toggle(window, gBrowser.selectedTab);
yield onManagerOff;
yield closeRDM(rdm);
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
"false",
"The menu item is unchecked");
"false", "The menu item is unchecked");
}
function numberOfRules(ruleView) {

View File

@ -1,309 +1,255 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("Protocol error (unknownError): Error: Got an invalid root window in DocumentWalker");
"use strict";
function test() {
waitForExplicitFinish();
add_task(function*() {
SimpleTest.requestCompleteLog();
Task.spawn(function*() {
let tab = yield addTab("data:text/html,mop");
function extractSizeFromString(str) {
let numbers = str.match(/(\d+)[^\d]*(\d+)/);
if (numbers) {
return [numbers[1], numbers[2]];
} else {
return [null, null];
}
}
let {rdm, manager} = yield openRDM(tab, "menu");
let container = gBrowser.getBrowserContainer();
is(container.getAttribute("responsivemode"), "true",
"Should be in responsive mode.");
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
"true", "Menu item should be checked");
function processStringAsKey(str) {
for (let i = 0, l = str.length; i < l; i++) {
EventUtils.synthesizeKey(str.charAt(i), {});
}
}
ok(rdm, "An instance of the RDM should be attached to the tab.");
yield addTab("data:text/html,mop");
let originalWidth = (yield getSizing()).width;
let mgr = ResponsiveUI.ResponsiveUIManager;
let documentLoaded = waitForDocLoadComplete();
gBrowser.loadURI("data:text/html;charset=utf-8,mop" +
"<div style%3D'height%3A5000px'><%2Fdiv>");
yield documentLoaded;
synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI"));
let newWidth = (yield getSizing()).width;
is(originalWidth, newWidth, "Floating scrollbars shouldn't change the width");
yield once(mgr, "on");
yield rdm._test_notifyOnResize();
yield waitForTick();
// Is it open?
let container = gBrowser.getBrowserContainer();
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
yield testPresets(rdm, manager);
// Menus are correctly updated?
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
info("Testing mouse resizing");
yield testManualMouseResize(rdm, manager);
let instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
ok(instance, "instance of the module is attached to the tab.");
info("Testing mouse resizing with shift key");
yield testManualMouseResize(rdm, manager, "shift");
let originalWidth = content.innerWidth;
info("Testing mouse resizing with ctrl key");
yield testManualMouseResize(rdm, manager, "ctrl");
let documentLoaded = waitForDocLoadComplete();
content.location = "data:text/html;charset=utf-8,mop<div style%3D'height%3A5000px'><%2Fdiv>";
yield documentLoaded;
info("Testing resizing with user custom keyboard input");
yield testResizeUsingCustomInput(rdm, manager);
let newWidth = content.innerWidth;
is(originalWidth, newWidth, "Floating scrollbars are presents");
info("Testing invalid keyboard input");
yield testInvalidUserInput(rdm);
yield instance._test_notifyOnResize();
info("Testing rotation");
yield testRotate(rdm, manager);
yield nextTick();
let {width: widthBeforeClose, height: heightBeforeClose} = yield getSizing();
instance.transitionsEnabled = false;
info("Restarting responsive mode");
yield closeRDM(rdm);
({rdm} = yield openRDM(tab, "keyboard"));
// Starting from length - 4 because last 3 items are not presets : separator, addbutton and removebutton
for (let c = instance.menulist.firstChild.childNodes.length - 4; c >= 0; c--) {
let item = instance.menulist.firstChild.childNodes[c];
let [width, height] = extractSizeFromString(item.getAttribute("label"));
let onContentResize = once(mgr, "contentResize");
instance.menulist.selectedIndex = c;
yield onContentResize;
is(content.innerWidth, width, "preset " + c + ": dimension valid (width)");
is(content.innerHeight, height, "preset " + c + ": dimension valid (height)");
}
let currentSize = yield getSizing();
is(currentSize.width, widthBeforeClose, "width should be restored");
is(currentSize.height, heightBeforeClose, "height should be restored");
// test custom
container = gBrowser.getBrowserContainer();
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
"true", "menu item should be checked");
instance.setSize(100, 100);
let isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
if (!isWinXP) {
yield testScreenshot(rdm);
}
yield once(mgr, "contentResize");
yield closeRDM(rdm);
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"),
"false", "menu item should be unchecked");
});
let initialWidth = content.innerWidth;
let initialHeight = content.innerHeight;
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"));
let onContentResize = once(manager, "contentResize");
rdm.menulist.selectedIndex = c;
yield onContentResize;
is(initialWidth, 100, "Width reset to 100");
is(initialHeight, 100, "Height reset to 100");
let x = 2, y = 2;
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
x += 20; y += 10;
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove"}, window);
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
yield once(mgr, "contentResize");
let expectedWidth = initialWidth + 20;
let expectedHeight = initialHeight + 10;
info("initial width: " + initialWidth);
info("initial height: " + initialHeight);
is(content.innerWidth, expectedWidth, "Size correctly updated (width).");
is(content.innerHeight, expectedHeight, "Size correctly updated (height).");
is(instance.menulist.selectedIndex, -1, "Custom menuitem cannot be selected");
let label = instance.menulist.firstChild.firstChild.getAttribute("label");
let value = instance.menulist.value;
isnot(label, value, "Label from the menulist item is different than the value of the menulist")
let [width, height] = extractSizeFromString(label);
is(width, expectedWidth, "Label updated (width).");
is(height, expectedHeight, "Label updated (height).");
[width, height] = extractSizeFromString(value);
is(width, expectedWidth, "Value updated (width).");
is(height, expectedHeight, "Value updated (height).");
// With "shift" key pressed
instance.setSize(100, 100);
yield once(mgr, "contentResize");
initialWidth = content.innerWidth;
initialHeight = content.innerHeight;
x = 2; y = 2;
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
x += 23; y += 13;
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove", shiftKey: true}, window);
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
yield once(mgr, "contentResize");
expectedWidth = initialWidth + 20;
expectedHeight = initialHeight + 10;
is(content.innerWidth, expectedWidth, "with shift: Size correctly updated (width).");
is(content.innerHeight, expectedHeight, "with shift: Size correctly updated (height).");
is(instance.menulist.selectedIndex, -1, "with shift: Custom menuitem cannot be selected");
label = instance.menulist.firstChild.firstChild.getAttribute("label");
value = instance.menulist.value;
isnot(label, value, "Label from the menulist item is different than the value of the menulist");
[width, height] = extractSizeFromString(label);
is(width, expectedWidth, "Label updated (width).");
is(height, expectedHeight, "Label updated (height).");
[width, height] = extractSizeFromString(value);
is(width, expectedWidth, "Value updated (width).");
is(height, expectedHeight, "Value updated (height).");
// With "ctrl" key pressed
instance.setSize(100, 100);
yield once(mgr, "contentResize");
initialWidth = content.innerWidth;
initialHeight = content.innerHeight;
x = 2; y = 2;
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousedown"}, window);
x += 60; y += 30;
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mousemove", ctrlKey: true}, window);
EventUtils.synthesizeMouse(instance.resizer, x, y, {type: "mouseup"}, window);
yield once(mgr, "contentResize");
expectedWidth = initialWidth + 10;
expectedHeight = initialHeight + 5;
is(content.innerWidth, expectedWidth, "with ctrl: Size correctly updated (width).");
is(content.innerHeight, expectedHeight, "with ctrl: Size correctly updated (height).");
is(instance.menulist.selectedIndex, -1, "with ctrl: Custom menuitem cannot be selected");
label = instance.menulist.firstChild.firstChild.getAttribute("label");
value = instance.menulist.value;
isnot(label, value, "Label from the menulist item is different than the value of the menulist");
[width, height] = extractSizeFromString(label);
is(width, expectedWidth, "Label updated (width).");
is(height, expectedHeight, "Label updated (height).");
[width, height] = extractSizeFromString(value);
is(width, expectedWidth, "Value updated (width).");
is(height, expectedHeight, "Value updated (height).");
// Test custom input
initialWidth = content.innerWidth;
initialHeight = content.innerHeight;
expectedWidth = initialWidth - 20;
expectedHeight = initialHeight - 10;
let index = instance.menulist.selectedIndex;
let userInput = expectedWidth + " x " + expectedHeight;
instance.menulist.inputField.value = "";
instance.menulist.focus();
processStringAsKey(userInput);
// While typing, the size should not change
is(content.innerWidth, initialWidth, "Size hasn't changed (width).");
is(content.innerHeight, initialHeight, "Size hasn't changed (height).");
// Only the `change` event must change the size
EventUtils.synthesizeKey("VK_RETURN", {});
yield once(mgr, "contentResize");
is(content.innerWidth, expectedWidth, "Size correctly updated (width).");
is(content.innerHeight, expectedHeight, "Size correctly updated (height).");
is(instance.menulist.selectedIndex, -1, "Custom menuitem cannot be selected");
label = instance.menulist.firstChild.firstChild.getAttribute("label");
value = instance.menulist.value;
isnot(label, value, "Label from the menulist item is different than the value of the menulist");
[width, height] = extractSizeFromString(label);
is(width, expectedWidth, "Label updated (width).");
is(height, expectedHeight, "Label updated (height).");
[width, height] = extractSizeFromString(value);
is(width, expectedWidth, "Value updated (width).");
is(height, expectedHeight, "Value updated (height).");
// Invalid input
initialWidth = content.innerWidth;
initialHeight = content.innerHeight;
index = instance.menulist.selectedIndex;
let expectedValue = initialWidth + "\u00D7" + initialHeight;
let expectedLabel = instance.menulist.firstChild.firstChild.getAttribute("label");
userInput = "I'm wrong";
instance.menulist.inputField.value = "";
instance.menulist.focus();
processStringAsKey(userInput);
EventUtils.synthesizeKey("VK_RETURN", {});
is(content.innerWidth, initialWidth, "Size hasn't changed (width).");
is(content.innerHeight, initialHeight, "Size hasn't changed (height).");
is(instance.menulist.selectedIndex, index, "Selected item hasn't changed.");
is(instance.menulist.value, expectedValue, "Value has been reset")
label = instance.menulist.firstChild.firstChild.getAttribute("label");
is(label, expectedLabel, "Custom menuitem's label hasn't changed");
// Rotate
initialWidth = content.innerWidth;
initialHeight = content.innerHeight;
info("rotate");
instance.rotate();
yield once(mgr, "contentResize");
is(content.innerWidth, initialHeight, "The width is now the height.");
is(content.innerHeight, initialWidth, "The height is now the width.");
[width, height] = extractSizeFromString(instance.menulist.firstChild.firstChild.getAttribute("label"));
is(width, initialHeight, "Label updated (width).");
is(height, initialWidth, "Label updated (height).");
let widthBeforeClose = content.innerWidth;
let heightBeforeClose = content.innerHeight;
// Restart
mgr.toggle(window, gBrowser.selectedTab);
yield once(mgr, "off");
mgr.toggle(window, gBrowser.selectedTab);
yield once(mgr, "on");
container = gBrowser.getBrowserContainer();
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
// Menus are correctly updated?
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "true", "menus checked");
is(content.innerWidth, widthBeforeClose, "width restored.");
is(content.innerHeight, heightBeforeClose, "height restored.");
// Screenshot
let isWinXP = navigator.userAgent.indexOf("Windows NT 5.1") != -1;
if (!isWinXP) {
info("screenshot");
instance.screenshot("responsiveui");
let FileUtils = (Cu.import("resource://gre/modules/FileUtils.jsm", {})).FileUtils;
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);
}
}
mgr.toggle(window, gBrowser.selectedTab);
yield once(mgr, "off");
// Menus are correctly updated?
is(document.getElementById("Tools:ResponsiveUI").getAttribute("checked"), "false", "menu unchecked");
delete instance;
gBrowser.removeCurrentTab();
finish();
});
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) {
rdm.setSize(100, 100);
yield once(manager, "contentResize");
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, "contentResize");
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, "contentResize");
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) {
rdm.setSize(100, 200);
yield once(manager, "contentResize");
let {width: initialWidth, height: initialHeight} = yield getSizing();
rdm.rotate();
yield once(manager, "contentResize");
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), {});
}
}

View File

@ -7,19 +7,14 @@ const TEST_URI = "http://mochi.test:8888/browser/devtools/client/" +
"responsivedesign/test/touch.html";
add_task(function*() {
yield addTab(TEST_URI);
let mgr = ResponsiveUI.ResponsiveUIManager;
let mgrOn = once(mgr, "on");
mgr.toggle(window, gBrowser.selectedTab);
yield mgrOn;
let tab = yield addTab(TEST_URI);
let {rdm} = yield openRDM(tab);
yield testWithNoTouch();
yield mgr.getResponsiveUIForTab(gBrowser.selectedTab).enableTouch();
yield rdm.enableTouch();
yield testWithTouch();
yield mgr.getResponsiveUIForTab(gBrowser.selectedTab).disableTouch();
yield rdm.disableTouch();
yield testWithNoTouch();
let mgrOff = once(mgr, "off");
mgr.toggle(window, gBrowser.selectedTab);
yield mgrOff;
yield closeRDM(rdm);
});
function* testWithNoTouch() {
@ -30,7 +25,7 @@ function* testWithNoTouch() {
x += 20; y += 10;
yield BrowserTestUtils.synthesizeMouse("div", x, y,
{ type: "mousemove", isSynthesized: false }, gBrowser.selectedBrowser);
is(div.style.transform, "none", "touch didn't work");
is(div.style.transform, "none", "touch shouldn't work");
yield BrowserTestUtils.synthesizeMouse("div", x, y,
{ type: "mouseup", isSynthesized: false }, gBrowser.selectedBrowser);
}
@ -43,8 +38,8 @@ function* testWithTouch() {
x += 20; y += 10;
yield BrowserTestUtils.synthesizeMouse("div", x, y,
{ type: "mousemove", isSynthesized: false }, gBrowser.selectedBrowser);
is(div.style.transform, "translate(20px, 10px)", "touch worked");
is(div.style.transform, "translate(20px, 10px)", "touch should work");
yield BrowserTestUtils.synthesizeMouse("div", x, y,
{ type: "mouseup", isSynthesized: false }, gBrowser.selectedBrowser);
is(div.style.transform, "none", "end event worked");
is(div.style.transform, "none", "end event should work");
}

View File

@ -1,145 +1,129 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
function test() {
waitForExplicitFinish();
SimpleTest.requestCompleteLog();
"use strict";
let instance, deletedPresetA, deletedPresetB, oldPrompt;
add_task(function*() {
let tab = yield addTab("data:text/html;charset=utf8,Test RDM custom presets");
function getPresetIndex(presetLabel) {
function testOnePreset(c) {
if (c == 0) {
return -1;
}
instance.menulist.selectedIndex = c;
let {rdm} = yield openRDM(tab);
let item = instance.menulist.firstChild.childNodes[c];
if (item.getAttribute("label") === presetLabel) {
return c;
} else {
return testOnePreset(c - 1);
}
let oldPrompt = Services.prompt;
Services.prompt = {
value: "",
returnBool: true,
prompt: function(parent, dialogTitle, text, value, checkMsg, checkState) {
value.value = this.value;
return this.returnBool;
}
return testOnePreset(instance.menulist.firstChild.childNodes.length - 4);
}
};
Task.spawn(function*() {
yield addTab("data:text/html;charset=utf8,test custom presets in responsive mode");
let mgr = ResponsiveUI.ResponsiveUIManager;
synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI"));
yield once(mgr, "on");
oldPrompt = Services.prompt;
Services.prompt = {
value: "",
returnBool: true,
prompt: function(aParent, aDialogTitle, aText, aValue, aCheckMsg, aCheckState) {
aValue.value = this.value;
return this.returnBool;
}
};
registerCleanupFunction(() => Services.prompt = oldPrompt);
// Is it open?
let container = gBrowser.getBrowserContainer();
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
ok(instance, "instance of the module is attached to the tab.");
instance.transitionsEnabled = false;
yield instance._test_notifyOnResize();
// Tries to add a custom preset and cancel the prompt
let idx = instance.menulist.selectedIndex;
let presetCount = instance.presets.length;
Services.prompt.value = "";
Services.prompt.returnBool = false;
instance.addbutton.doCommand();
is(idx, instance.menulist.selectedIndex, "selected item didn't change after add preset and cancel");
is(presetCount, instance.presets.length, "number of presets didn't change after add preset and cancel");
// Adds the custom preset with "Testing preset"
Services.prompt.value = "Testing preset";
Services.prompt.returnBool = true;
let customHeight = 123, customWidth = 456;
instance.startResizing({});
instance.setSize(customWidth, customHeight);
instance.stopResizing({});
instance.addbutton.doCommand();
// Force document reflow to avoid intermittent failures.
info("document height " + document.height);
instance.close();
info("waiting for responsive mode to turn off");
yield once(mgr, "off");
// We're still in the loop of initializing the responsive mode.
// Let's wait next loop to stop it.
yield nextTick();
synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI"));
yield once(mgr, "on");
is(container.getAttribute("responsivemode"), "true", "In responsive mode.");
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
let customPresetIndex = getPresetIndex("456" + "\u00D7" + "123 (Testing preset)");
info(customPresetIndex);
ok(customPresetIndex >= 0, "is the previously added preset (idx = " + customPresetIndex + ") in the list of items");
let resizePromise = instance._test_notifyOnResize();
instance.menulist.selectedIndex = customPresetIndex;
yield resizePromise;
is(content.innerWidth, 456, "add preset, and selected in the list, dimension valid (width)");
is(content.innerHeight, 123, "add preset, and selected in the list, dimension valid (height)");
instance.removebutton.doCommand();
instance.menulist.selectedIndex = 2;
deletedPresetA = instance.menulist.selectedItem.getAttribute("label");
instance.removebutton.doCommand();
instance.menulist.selectedIndex = 2;
deletedPresetB = instance.menulist.selectedItem.getAttribute("label");
instance.removebutton.doCommand();
yield nextTick();
instance.close();
yield once(mgr, "off");
synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI"));
info("waiting for responsive mode to turn on");
yield once(mgr, "on");
instance = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
customPresetIndex = getPresetIndex(deletedPresetA);
is(customPresetIndex, -1, "deleted preset " + deletedPresetA + " is not in the list anymore");
customPresetIndex = getPresetIndex(deletedPresetB);
is(customPresetIndex, -1, "deleted preset " + deletedPresetB + " is not in the list anymore");
yield nextTick();
gBrowser.removeCurrentTab();
finish();
registerCleanupFunction(() => {
Services.prompt = oldPrompt;
});
// Is it open?
let container = gBrowser.getBrowserContainer();
is(container.getAttribute("responsivemode"), "true",
"Should be in responsive mode.");
ok(rdm, "RDM instance should be attached to the tab.");
yield rdm._test_notifyOnResize();
// Tries to add a custom preset and cancel the prompt
let idx = rdm.menulist.selectedIndex;
let presetCount = rdm.presets.length;
Services.prompt.value = "";
Services.prompt.returnBool = false;
rdm.addbutton.doCommand();
is(idx, rdm.menulist.selectedIndex,
"selected item shouldn't change after add preset and cancel");
is(presetCount, rdm.presets.length,
"number of presets shouldn't change after add preset and cancel");
// Adds the custom preset with "Testing preset"
Services.prompt.value = "Testing preset";
Services.prompt.returnBool = true;
let customHeight = 123, customWidth = 456;
rdm.startResizing({});
rdm.setSize(customWidth, customHeight);
rdm.stopResizing({});
rdm.addbutton.doCommand();
// Force document reflow to avoid intermittent failures.
info("document height " + document.height);
yield closeRDM(rdm);
// We're still in the loop of initializing the responsive mode.
// Let's wait next loop to stop it.
yield waitForTick();
({rdm} = yield openRDM(tab));
is(container.getAttribute("responsivemode"), "true",
"Should be in responsive mode.");
let presetLabel = "456" + "\u00D7" + "123 (Testing preset)";
let customPresetIndex = getPresetIndex(rdm, presetLabel);
info(customPresetIndex);
ok(customPresetIndex >= 0, "(idx = " + customPresetIndex + ") should be the" +
" previously added preset in the list of items");
let resizePromise = rdm._test_notifyOnResize();
rdm.menulist.selectedIndex = customPresetIndex;
yield resizePromise;
let browser = gBrowser.selectedBrowser;
let {props} = yield ContentTask.spawn(browser, {}, function*() {
let {innerWidth, innerHeight} = content;
return {innerWidth, innerHeight};
});
is(props.innerWidth, 456, "Selecting preset should change the width");
is(props.innerHeight, 123, "Selecting preset should change the height");
rdm.removebutton.doCommand();
rdm.menulist.selectedIndex = 2;
let deletedPresetA = rdm.menulist.selectedItem.getAttribute("label");
rdm.removebutton.doCommand();
rdm.menulist.selectedIndex = 2;
let deletedPresetB = rdm.menulist.selectedItem.getAttribute("label");
rdm.removebutton.doCommand();
yield closeRDM(rdm);
yield waitForTick();
({rdm} = yield openRDM(tab));
customPresetIndex = getPresetIndex(rdm, deletedPresetA);
is(customPresetIndex, -1,
"Deleted preset " + deletedPresetA + " should not be in the list anymore");
customPresetIndex = getPresetIndex(rdm, deletedPresetB);
is(customPresetIndex, -1,
"Deleted preset " + deletedPresetB + " should not be in the list anymore");
yield closeRDM(rdm);
});
function getPresetIndex(rdm, presetLabel) {
function testOnePreset(c) {
if (c == 0) {
return -1;
}
rdm.menulist.selectedIndex = c;
let item = rdm.menulist.firstChild.childNodes[c];
if (item.getAttribute("label") === presetLabel) {
return c;
}
return testOnePreset(c - 1);
}
return testOnePreset(rdm.menulist.firstChild.childNodes.length - 4);
}

View File

@ -3,12 +3,14 @@
"use strict";
let testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
// shared-head.js handles imports, constants, and utility functions
Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this);
let sharedHeadURI = testDir + "../../../framework/test/shared-head.js";
Services.scriptloader.loadSubScript(sharedHeadURI, this);
// Import the GCLI test helper
var testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/"));
Services.scriptloader.loadSubScript(testDir + "../../../commandline/test/helpers.js", this);
let gcliHelpersURI = testDir + "../../../commandline/test/helpers.js";
Services.scriptloader.loadSubScript(gcliHelpersURI, this);
DevToolsUtils.testing = true;
registerCleanupFunction(() => {
@ -21,22 +23,41 @@ registerCleanupFunction(() => {
/**
* Open the Responsive Design Mode
* @param {Tab} The browser tab to open it into (defaults to the selected tab).
* @return {Promise} Resolves to the instance of the responsive design mode.
* @param {method} The method to use to open the RDM (values: menu, keyboard)
* @return {rdm, manager} Returns the RUI instance and the manager
*/
function openRDM(tab = gBrowser.selectedTab) {
return new Promise(resolve => {
let manager = ResponsiveUI.ResponsiveUIManager;
var openRDM = Task.async(function*(tab = gBrowser.selectedTab,
method = "menu") {
let manager = ResponsiveUI.ResponsiveUIManager;
let mgrOn = once(manager, "on");
if (method == "menu") {
document.getElementById("Tools:ResponsiveUI").doCommand();
executeSoon(() => {
let rdm = manager.getResponsiveUIForTab(tab);
rdm.stack.setAttribute("notransition", "true");
registerCleanupFunction(function() {
rdm.stack.removeAttribute("notransition");
});
resolve({rdm, manager});
});
} else {
synthesizeKeyFromKeyTag(document.getElementById("key_responsiveUI"));
}
yield mgrOn;
let rdm = manager.getResponsiveUIForTab(tab);
rdm.transitionsEnabled = false;
registerCleanupFunction(() => {
rdm.transitionsEnabled = true;
});
}
return {rdm, manager};
});
/**
* Close a responsive mode instance
* @param {rdm} ResponsiveUI instance for the tab
*/
var closeRDM = Task.async(function*(rdm) {
let mgr = ResponsiveUI.ResponsiveUIManager;
if (!rdm) {
rdm = mgr.getResponsiveUIForTab(gBrowser.selectedTab);
}
let mgrOff = mgr.once("off");
rdm.close();
yield mgrOff;
});
/**
* Open the toolbox, with the inspector tool visible.
@ -77,6 +98,11 @@ var openInspector = Task.async(function*() {
};
});
var closeToolbox = Task.async(function*() {
let target = TargetFactory.forTab(gBrowser.selectedTab);
yield gDevTools.closeToolbox(target);
});
/**
* Wait for the toolbox frame to receive focus after it loads
* @param {Toolbox} toolbox
@ -164,67 +190,30 @@ var addTab = Task.async(function* (url) {
return tab;
});
/**
* Wait for eventName on target.
* @param {Object} target An observable object that either supports on/off or
* addEventListener/removeEventListener
* @param {String} eventName
* @param {Boolean} useCapture Optional, for addEventListener/removeEventListener
* @return A promise that resolves when the event has been handled
*/
function once(target, eventName, useCapture=false) {
info("Waiting for event: '" + eventName + "' on " + target + ".");
let deferred = promise.defer();
for (let [add, remove] of [
["addEventListener", "removeEventListener"],
["addListener", "removeListener"],
["on", "off"]
]) {
if ((add in target) && (remove in target)) {
target[add](eventName, function onEvent(...aArgs) {
info("Got event: '" + eventName + "' on " + target + ".");
target[remove](eventName, onEvent, useCapture);
deferred.resolve.apply(deferred, aArgs);
}, useCapture);
break;
}
}
return deferred.promise;
}
function wait(ms) {
let def = promise.defer();
setTimeout(def.resolve, ms);
return def.promise;
}
function nextTick() {
let def = promise.defer();
executeSoon(() => def.resolve())
return def.promise;
}
/**
* Waits for the next load to complete in the current browser.
*
* @return promise
*/
function waitForDocLoadComplete(aBrowser=gBrowser) {
function waitForDocLoadComplete(aBrowser = gBrowser) {
let deferred = promise.defer();
let progressListener = {
onStateChange: function (webProgress, req, flags, status) {
onStateChange: function(webProgress, req, flags, status) {
let docStop = Ci.nsIWebProgressListener.STATE_IS_NETWORK |
Ci.nsIWebProgressListener.STATE_STOP;
info("Saw state " + flags.toString(16) + " and status " + status.toString(16));
info(`Saw state ${flags.toString(16)} and status ${status.toString(16)}`);
// When a load needs to be retargetted to a new process it is cancelled
// with NS_BINDING_ABORTED so ignore that case
if ((flags & docStop) == docStop && status != Cr.NS_BINDING_ABORTED) {
aBrowser.removeProgressListener(progressListener);
info("Browser loaded " + aBrowser.contentWindow.location);
info("Browser loaded");
deferred.resolve();
}
},

View File

@ -33,6 +33,7 @@
"requestLongerTimeout": false,
"SimpleTest": false,
"SpecialPowers": false,
"thisTestLeaksUncaughtRejectionsAndShouldBeFixed": false,
"todo": false,
"todo_is": false,
"todo_isnot": false,