Bug 876277 - Cleanup debugger variables view tests, r=past

--HG--
rename : browser/devtools/debugger/test/browser_dbg_propertyview-02.js => browser/devtools/debugger/test/browser_dbg_variables-view-01.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-03.js => browser/devtools/debugger/test/browser_dbg_variables-view-02.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-04.js => browser/devtools/debugger/test/browser_dbg_variables-view-03.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-05.js => browser/devtools/debugger/test/browser_dbg_variables-view-04.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-06.js => browser/devtools/debugger/test/browser_dbg_variables-view-05.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-data.js => browser/devtools/debugger/test/browser_dbg_variables-view-data.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-data-getset-01.js => browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-01.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-data-getset-02.js => browser/devtools/debugger/test/browser_dbg_variables-view-edit-getset-02.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-edit-value.js => browser/devtools/debugger/test/browser_dbg_variables-view-edit-value.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-edit-watch.js => browser/devtools/debugger/test/browser_dbg_variables-view-edit-watch.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-filter-01.js => browser/devtools/debugger/test/browser_dbg_variables-view-filter-01.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-filter-02.js => browser/devtools/debugger/test/browser_dbg_variables-view-filter-02.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-filter-05.js => browser/devtools/debugger/test/browser_dbg_variables-view-filter-03.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-filter-06.js => browser/devtools/debugger/test/browser_dbg_variables-view-filter-04.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-filter-08.js => browser/devtools/debugger/test/browser_dbg_variables-view-filter-05.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-filter-03.js => browser/devtools/debugger/test/browser_dbg_variables-view-filter-pref.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-08.js => browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-01.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-07.js => browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-02.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-09.js => browser/devtools/debugger/test/browser_dbg_variables-view-frame-parameters-03.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-10.js => browser/devtools/debugger/test/browser_dbg_variables-view-frame-with.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-12.js => browser/devtools/debugger/test/browser_dbg_variables-view-frozen-sealed-nonext.js
rename : browser/devtools/debugger/test/browser_dbg_bug786070_hide_nonenums.js => browser/devtools/debugger/test/browser_dbg_variables-view-hide-non-enums.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-data-big.js => browser/devtools/debugger/test/browser_dbg_variables-view-large-array-buffer.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-reexpand.js => browser/devtools/debugger/test/browser_dbg_variables-view-reexpand-01.js
rename : browser/devtools/debugger/test/browser_dbg_propertyview-11.js => browser/devtools/debugger/test/browser_dbg_variables-view-webidl.js
This commit is contained in:
Victor Porof 2013-09-13 16:23:18 +03:00
parent a3021547e7
commit 9b762a09b1
50 changed files with 5584 additions and 5769 deletions

View File

@ -1,129 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
testNonEnumProperties();
});
}
function testNonEnumProperties() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
let testScope = gDebugger.DebuggerView.Variables.addScope("test-scope");
let testVar = testScope.addItem("foo");
testVar.addItems({
foo: {
value: "bar",
enumerable: true
},
bar: {
value: "foo",
enumerable: false
}
});
// Expand the variable.
testScope.expand();
testVar.expand();
executeSoon(function() {
let details = testVar._enum;
let nonenum = testVar._nonenum;
is(details.childNodes.length, 1,
"There should be just one property in the .details container.");
ok(details.hasAttribute("open"),
".details container should be visible.");
ok(nonenum.hasAttribute("open"),
".nonenum container should be visible.");
is(nonenum.childNodes.length, 1,
"There should be just one property in the .nonenum container.");
// Uncheck 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "true");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
executeSoon(function() {
ok(details.hasAttribute("open"),
".details container should stay visible.");
ok(!nonenum.hasAttribute("open"),
".nonenum container should become hidden.");
// Check 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "false");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
executeSoon(function() {
ok(details.hasAttribute("open"),
".details container should stay visible.");
ok(nonenum.hasAttribute("open"),
".nonenum container should become visible.");
// Collapse the variable.
testVar.collapse();
executeSoon(function() {
ok(!details.hasAttribute("open"),
".details container should be hidden.");
ok(!nonenum.hasAttribute("open"),
".nonenum container should be hidden.");
// Uncheck 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "true");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
executeSoon(function() {
ok(!details.hasAttribute("open"),
".details container should stay hidden.");
ok(!nonenum.hasAttribute("open"),
".nonenum container should stay hidden.");
// Check 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "false");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
executeSoon(function() {
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
});
});
});
});
});
});
}}, 0);
});
gDebuggee.simpleCall();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,134 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
testSimpleCall();
});
}
function testSimpleCall() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
let testScope = gDebugger.DebuggerView.Variables.addScope("test");
ok(testScope,
"Should have created a scope.");
is(testScope.id.substring(0, 4), "test",
"The newly created scope should have the default id set.");
is(testScope.target.querySelector(".name").getAttribute("value"), "test",
"Any new scope should have the designated title.");
is(testScope.target.querySelector(".variables-view-element-details").childNodes.length, 0,
"Any new scope should have a container with no child nodes.");
is(gDebugger.DebuggerView.Variables._list.childNodes.length, 3,
"Should have 3 scopes created.");
ok(!testScope.expanded,
"Any new created scope should be initially collapsed.");
ok(testScope.visible,
"Any new created scope should be initially visible.");
let expandCallbackSender = null;
let collapseCallbackSender = null;
let toggleCallbackSender = null;
let hideCallbackSender = null;
let showCallbackSender = null;
testScope.onexpand = function(sender) { expandCallbackSender = sender; };
testScope.oncollapse = function(sender) { collapseCallbackSender = sender; };
testScope.ontoggle = function(sender) { toggleCallbackSender = sender; };
testScope.onhide = function(sender) { hideCallbackSender = sender; };
testScope.onshow = function(sender) { showCallbackSender = sender; };
testScope.expand();
ok(testScope.expanded,
"The testScope shouldn't be collapsed anymore.");
is(expandCallbackSender, testScope,
"The expandCallback wasn't called as it should.");
testScope.collapse();
ok(!testScope.expanded,
"The testScope should be collapsed again.");
is(collapseCallbackSender, testScope,
"The collapseCallback wasn't called as it should.");
testScope.expanded = true;
ok(testScope.expanded,
"The testScope shouldn't be collapsed anymore.");
testScope.toggle();
ok(!testScope.expanded,
"The testScope should be collapsed again.");
is(toggleCallbackSender, testScope,
"The toggleCallback wasn't called as it should.");
testScope.hide();
ok(!testScope.visible,
"The testScope should be invisible after hiding.");
is(hideCallbackSender, testScope,
"The hideCallback wasn't called as it should.");
testScope.show();
ok(testScope.visible,
"The testScope should be visible again.");
is(showCallbackSender, testScope,
"The showCallback wasn't called as it should.");
testScope.visible = false;
ok(!testScope.visible,
"The testScope should be invisible after hiding.");
ok(!testScope.expanded,
"The testScope should remember it is collapsed even if it is hidden.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testScope.target.querySelector(".title"),
gDebugger);
ok(testScope.expanded,
"Clicking the testScope tilte should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testScope.target.querySelector(".title"),
gDebugger);
ok(!testScope.expanded,
"Clicking again the testScope tilte should collapse it.");
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}}, 0);
});
gDebuggee.simpleCall();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,211 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
testSimpleCall();
});
}
function testSimpleCall() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
let testScope = gDebugger.DebuggerView.Variables.addScope("test-scope");
let testVar = testScope.addItem("something");
let duplVar = testScope.addItem("something");
info("Scope id: " + testScope.target.id);
info("Scope name: " + testScope.target.name);
info("Variable id: " + testVar.target.id);
info("Variable name: " + testVar.target.name);
ok(testScope,
"Should have created a scope.");
ok(testVar,
"Should have created a variable.");
ok(testScope.id.contains("test-scope"),
"Should have the correct scope id.");
ok(testScope.target.id.contains("test-scope"),
"Should have the correct scope id on the element.");
is(testScope.name, "test-scope",
"Should have the correct scope name.");
ok(testVar.id.contains("something"),
"Should have the correct variable id.");
ok(testVar.target.id.contains("something"),
"Should have the correct variable id on the element.");
is(testVar.name, "something",
"Should have the correct variable name.");
is(duplVar, null,
"Shouldn't be able to duplicate variables in the same scope.");
is(testVar.target.querySelector(".name").getAttribute("value"), "something",
"Any new variable should have the designated title.");
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 0,
"Any new variable should have a details container with no child nodes.");
let properties = testVar.addItems({ "child": { "value": { "type": "object",
"class": "Object" } } });
ok(!testVar.expanded,
"Any new created variable should be initially collapsed.");
ok(testVar.visible,
"Any new created variable should be initially visible.");
testVar.expand();
ok(testVar.expanded,
"The testVar shouldn't be collapsed anymore.");
testVar.collapse();
ok(!testVar.expanded,
"The testVar should be collapsed again.");
testVar.expanded = true;
ok(testVar.expanded,
"The testVar shouldn't be collapsed anymore.");
testVar.toggle();
ok(!testVar.expanded,
"The testVar should be collapsed again.");
testVar.hide();
ok(!testVar.visible,
"The testVar should be invisible after hiding.");
testVar.show();
ok(testVar.visible,
"The testVar should be visible again.");
testVar.visible = false;
ok(!testVar.visible,
"The testVar should be invisible after hiding.");
ok(!testVar.expanded,
"The testVar should remember it is collapsed even if it is hidden.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".name"),
gDebugger);
ok(testVar.expanded,
"Clicking the testVar name should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".name"),
gDebugger);
ok(!testVar.expanded,
"Clicking again the testVar name should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".arrow"),
gDebugger);
ok(testVar.expanded,
"Clicking the testVar arrow should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".arrow"),
gDebugger);
ok(!testVar.expanded,
"Clicking again the testVar arrow should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".title"),
gDebugger);
ok(testVar.expanded,
"Clicking the testVar title div should expand it again.");
testScope.show();
testScope.expand();
testVar.show();
testVar.expand();
ok(!testVar.get("child").expanded,
"The testVar child property should remember it is collapsed even if it is hidden.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.get("child").target.querySelector(".name"),
gDebugger);
ok(testVar.get("child").expanded,
"Clicking the testVar child property name should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.get("child").target.querySelector(".name"),
gDebugger);
ok(!testVar.get("child").expanded,
"Clicking again the testVar child property name should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.get("child").target.querySelector(".arrow"),
gDebugger);
ok(testVar.get("child").expanded,
"Clicking the testVar child property arrow should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.get("child").target.querySelector(".arrow"),
gDebugger);
ok(!testVar.get("child").expanded,
"Clicking again the testVar child property arrow should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.get("child").target.querySelector(".title"),
gDebugger);
ok(testVar.get("child").expanded,
"Clicking the testVar child property title div should expand it again.");
gDebugger.DebuggerView.Variables.empty();
is(gDebugger.DebuggerView.Variables._list.childNodes.length, 0,
"The scopes should have been removed from the parent container tree.");
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}}, 0);
});
gDebuggee.simpleCall();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,78 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
testSimpleCall();
});
}
function testSimpleCall() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
let testScope = gDebugger.DebuggerView.Variables.addScope("test");
let testVar = testScope.addItem("something");
let properties = testVar.addItems({
"child": {
"value": {
"type": "object",
"class": "Object"
},
"enumerable": true
}
});
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 1,
"A new detail node should have been added in the variable tree.");
ok(testVar.get("child"),
"The added detail property should be accessible from the variable.");
let properties2 = testVar.get("child").addItems({
"grandchild": {
"value": {
"type": "object",
"class": "Object"
},
"enumerable": true
}
});
is(testVar.get("child").target.querySelector(".variables-view-element-details").childNodes.length, 1,
"A new detail node should have been added in the variable tree.");
ok(testVar.get("child").get("grandchild"),
"The added detail property should be accessible from the variable.");
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}}, 0);
});
gDebuggee.simpleCall();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,95 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
requestLongerTimeout(3);
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
testSimpleCall();
});
}
function testSimpleCall() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
let testScope = gDebugger.DebuggerView.Variables.addScope("test");
let testVar = testScope.addItem("something");
testVar.setGrip(1.618);
is(testVar.target.querySelector(".value").getAttribute("value"), "1.618",
"The grip information for the variable wasn't set correctly.");
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 0,
"Adding a value property shouldn't add any new tree nodes.");
testVar.setGrip({ "type": "object", "class": "Window" });
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 0,
"Adding type and class properties shouldn't add any new tree nodes.");
is(testVar.target.querySelector(".value").getAttribute("value"), "Window",
"The information for the variable wasn't set correctly.");
testVar.addItems({ "helloWorld": { "value": "hello world", "enumerable": true } });
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 1,
"A new detail node should have been added in the variable tree.");
testVar.addItems({ "helloWorld": { "value": "hello jupiter", "enumerable": true } });
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 1,
"Shouldn't be able to duplicate nodes added in the variable tree.");
testVar.addItems({ "someProp0": { "value": "random string", "enumerable": true },
"someProp1": { "value": "another string", "enumerable": true } });
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 3,
"Two new detail nodes should have been added in the variable tree.");
testVar.addItems({ "someProp2": { "value": { "type": "null" }, "enumerable": true },
"someProp3": { "value": { "type": "undefined" }, "enumerable": true },
"someProp4": {
"value": { "type": "object", "class": "Object" },
"enumerable": true
}
});
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 6,
"Three new detail nodes should have been added in the variable tree.");
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}}, 0);
});
gDebuggee.simpleCall();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,236 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
testSimpleCall();
});
}
function testSimpleCall() {
gDebugger.DebuggerController.activeThread.addOneTimeListener("framesadded", function() {
Services.tm.currentThread.dispatch({ run: function() {
let globalScope = gDebugger.DebuggerView.Variables.addScope("Test-Global");
let localScope = gDebugger.DebuggerView.Variables.addScope("Test-Local");
let windowVar = globalScope.addItem("window");
let documentVar = globalScope.addItem("document");
let localVar0 = localScope.addItem("localVariable");
let localVar1 = localScope.addItem("localVar1");
let localVar2 = localScope.addItem("localVar2");
let localVar3 = localScope.addItem("localVar3");
let localVar4 = localScope.addItem("localVar4");
let localVar5 = localScope.addItem("localVar5");
let localVar6 = localScope.addItem("localVar6");
let localVar7 = localScope.addItem("localVar7");
let localVar8 = localScope.addItem("localVar8");
let localVar9 = localScope.addItem("localVar9");
localVar0.setGrip(42);
localVar1.setGrip(true);
localVar2.setGrip("nasu");
localVar3.setGrip({ "type": "undefined" });
localVar4.setGrip({ "type": "null" });
localVar5.setGrip({ "type": "object", "class": "Object" });
localVar6.setGrip({ "type": "Infinity" });
localVar7.setGrip({ "type": "-Infinity" });
localVar8.setGrip({ "type": "NaN" });
localVar9.setGrip({ "type": "-0" });
localVar5.addItems({
"someProp0": { "value": 42, "enumerable": true },
"someProp1": { "value": true , "enumerable": true},
"someProp2": { "value": "nasu", "enumerable": true},
"someProp3": { "value": { "type": "undefined" }, "enumerable": true},
"someProp4": { "value": { "type": "null" }, "enumerable": true },
"someProp5": {
"value": { "type": "object", "class": "Object" },
"enumerable": true
},
"someProp6": { "value": { "type": "Infinity" }, "enumerable": true },
"someProp7": { "value": { "type": "-Infinity" }, "enumerable": true },
"someProp8": { "value": { "type": "NaN" }, "enumerable": true },
"someProp9": { "value": { "type": "undefined" }, "enumerable": true },
"someProp10": { "value": { "type": "-0" }, "enumerable": true },
"someProp11": {
"get": { "type": "object", "class": "Function" },
"set": { "type": "undefined" },
"enumerable": true
},
});
localVar5.get("someProp5").addItems({
"someProp0": { "value": 42, "enumerable": true },
"someProp1": { "value": true, "enumerable": true },
"someProp2": { "value": "nasu", "enumerable": true },
"someProp3": { "value": { "type": "undefined" }, "enumerable": true },
"someProp4": { "value": { "type": "null" }, "enumerable": true },
"someProp5": {
"value": { "type": "object", "class": "Object" },
"enumerable": true
},
"someProp6": { "value": { "type": "Infinity" }, "enumerable": true },
"someProp7": { "value": { "type": "-Infinity" }, "enumerable": true },
"someProp8": { "value": { "type": "NaN" }, "enumerable": true },
"someProp9": { "value": { "type": "undefined" }, "enumerable": true },
"someProp10": { "value": { "type": "-0" }, "enumerable": true },
"someProp11": {
"get": { "type": "object", "class": "Function" },
"set": { "type": "undefined" },
"enumerable": true
},
});
windowVar.setGrip({ "type": "object", "class": "Window" });
windowVar.addItems({
"helloWorld": { "value": "hello world" }
});
documentVar.setGrip({ "type": "object", "class": "HTMLDocument" });
documentVar.addItems({
"onload": { "value": { "type": "null" } },
"onunload": { "value": { "type": "null" } },
"onfocus": { "value": { "type": "null" } },
"onblur": { "value": { "type": "null" } },
"onclick": { "value": { "type": "null" } },
"onkeypress": { "value": { "type": "null" } }
});
ok(windowVar, "The windowVar hasn't been created correctly.");
ok(documentVar, "The documentVar hasn't been created correctly.");
ok(localVar0, "The localVar0 hasn't been created correctly.");
ok(localVar1, "The localVar1 hasn't been created correctly.");
ok(localVar2, "The localVar2 hasn't been created correctly.");
ok(localVar3, "The localVar3 hasn't been created correctly.");
ok(localVar4, "The localVar4 hasn't been created correctly.");
ok(localVar5, "The localVar5 hasn't been created correctly.");
ok(localVar6, "The localVar6 hasn't been created correctly.");
ok(localVar7, "The localVar7 hasn't been created correctly.");
ok(localVar8, "The localVar8 hasn't been created correctly.");
ok(localVar9, "The localVar8 hasn't been created correctly.");
for each (let elt in globalScope.target.querySelector(".nonenum").childNodes) {
info("globalScope :: " + { id: elt.id, className: elt.className }.toSource());
}
is(globalScope.target.querySelector(".nonenum").childNodes.length, 2,
"The globalScope doesn't contain all the created variable elements.");
for each (let elt in localScope.target.querySelector(".nonenum").childNodes) {
info("localScope :: " + { id: elt.id, className: elt.className }.toSource());
}
is(localScope.target.querySelector(".nonenum").childNodes.length, 10,
"The localScope doesn't contain all the created variable elements.");
is(localVar5.target.querySelector(".variables-view-element-details").childNodes.length, 12,
"The localVar5 doesn't contain all the created properties.");
is(localVar5.get("someProp5").target.querySelector(".variables-view-element-details").childNodes.length, 12,
"The localVar5.someProp5 doesn't contain all the created properties.");
is(windowVar.target.querySelector(".value").getAttribute("value"), "Window",
"The grip information for the windowVar wasn't set correctly.");
is(documentVar.target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"The grip information for the documentVar wasn't set correctly.");
is(localVar0.target.querySelector(".value").getAttribute("value"), "42",
"The grip information for the localVar0 wasn't set correctly.");
is(localVar1.target.querySelector(".value").getAttribute("value"), "true",
"The grip information for the localVar1 wasn't set correctly.");
is(localVar2.target.querySelector(".value").getAttribute("value"), "\"nasu\"",
"The grip information for the localVar2 wasn't set correctly.");
is(localVar3.target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the localVar3 wasn't set correctly.");
is(localVar4.target.querySelector(".value").getAttribute("value"), "null",
"The grip information for the localVar4 wasn't set correctly.");
is(localVar5.target.querySelector(".value").getAttribute("value"), "Object",
"The grip information for the localVar5 wasn't set correctly.");
is(localVar6.target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the localVar6 wasn't set correctly.");
is(localVar7.target.querySelector(".value").getAttribute("value"), "-Infinity",
"The grip information for the localVar7 wasn't set correctly.");
is(localVar8.target.querySelector(".value").getAttribute("value"), "NaN",
"The grip information for the localVar8 wasn't set correctly.");
is(localVar9.target.querySelector(".value").getAttribute("value"), "-0",
"The grip information for the localVar9 wasn't set correctly.");
is(localVar5.get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
"The grip information for the someProp0 wasn't set correctly.");
is(localVar5.get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
"The grip information for the someProp1 wasn't set correctly.");
is(localVar5.get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
"The grip information for the someProp2 wasn't set correctly.");
is(localVar5.get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the someProp3 wasn't set correctly.");
is(localVar5.get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
"The grip information for the someProp4 wasn't set correctly.");
is(localVar5.get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
"The grip information for the someProp5 wasn't set correctly.");
is(localVar5.get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the someProp6 wasn't set correctly.");
is(localVar5.get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
"The grip information for the someProp7 wasn't set correctly.");
is(localVar5.get("someProp8").target.querySelector(".value").getAttribute("value"), "NaN",
"The grip information for the someProp8 wasn't set correctly.");
is(localVar5.get("someProp9").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the someProp9 wasn't set correctly.");
is(localVar5.get("someProp10").target.querySelector(".value").getAttribute("value"), "-0",
"The grip information for the someProp10 wasn't set correctly.");
is(localVar5.get("someProp11").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the someProp11 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
"The grip information for the sub-someProp0 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
"The grip information for the sub-someProp1 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
"The grip information for the sub-someProp2 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the sub-someProp3 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
"The grip information for the sub-someProp4 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
"The grip information for the sub-someProp5 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the sub-someProp6 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
"The grip information for the sub-someProp7 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp8").target.querySelector(".value").getAttribute("value"), "NaN",
"The grip information for the sub-someProp8 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp9").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the sub-someProp9 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp10").target.querySelector(".value").getAttribute("value"), "-0",
"The grip information for the sub-someProp10 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp11").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the sub-someProp11 wasn't set correctly.");
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}}, 0);
});
gDebuggee.simpleCall();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,106 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view displays function parameters.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
testFrameParameters();
});
}
function testFrameParameters()
{
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
localScope = gDebugger.DebuggerView.Variables._list.querySelector(".variables-view-scope"),
localNodes = localScope.querySelector(".variables-view-element-details").childNodes;
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
"Should have three frames.");
is(localNodes.length, 12,
"The localScope should contain all the created variable elements.");
is(localNodes[0].querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for 'this'.");
is(localNodes[1].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'aArg'.");
is(localNodes[2].querySelector(".value").getAttribute("value"), '"beta"',
"Should have the right property value for 'bArg'.");
is(localNodes[3].querySelector(".value").getAttribute("value"), "3",
"Should have the right property value for 'cArg'.");
is(localNodes[4].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for 'dArg'.");
is(localNodes[5].querySelector(".value").getAttribute("value"), "null",
"Should have the right property value for 'eArg'.");
is(localNodes[6].querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'fArg'.");
is(localNodes[7].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'a'.");
is(localNodes[8].querySelector(".value").getAttribute("value"), "Arguments",
"Should have the right property value for 'arguments'.");
is(localNodes[9].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'b'.");
is(localNodes[10].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'c'.");
resumeAndFinish();
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function resumeAndFinish() {
gDebugger.addEventListener("Debugger:AfterFramesCleared", function listener() {
gDebugger.removeEventListener("Debugger:AfterFramesCleared", listener, true);
var frames = gDebugger.DebuggerView.StackFrames.widget._list;
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
"Should have no frames.");
closeDebuggerAndFinish();
}, true);
gDebugger.DebuggerController.activeThread.resume();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
});

View File

@ -1,244 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view displays the properties of objects.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
testFrameParameters();
});
}
function testFrameParameters()
{
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[0],
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
localNonEnums = localScope.querySelector(".nonenum").childNodes;
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
"Should have three frames.");
is(localNodes.length + localNonEnums.length, 12,
"The localScope and localNonEnums should contain all the created variable elements.");
is(localNodes[0].querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for 'this'.");
is(localNodes[8].querySelector(".value").getAttribute("value"), "Arguments",
"Should have the right property value for 'arguments'.");
is(localNodes[10].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'c'.");
let gVars = gDebugger.DebuggerView.Variables;
is(gVars.getScopeForNode(
gVars._list.querySelectorAll(".variables-view-scope")[0]).target,
gVars._list.querySelectorAll(".variables-view-scope")[0],
"getScopeForNode([0]) didn't return the expected scope.");
is(gVars.getScopeForNode(
gVars._list.querySelectorAll(".variables-view-scope")[1]).target,
gVars._list.querySelectorAll(".variables-view-scope")[1],
"getScopeForNode([1]) didn't return the expected scope.");
is(gVars.getScopeForNode(
gVars._list.querySelectorAll(".variables-view-scope")[2]).target,
gVars._list.querySelectorAll(".variables-view-scope")[2],
"getScopeForNode([2]) didn't return the expected scope.");
is(gVars.getScopeForNode(gVars._list.querySelectorAll(".variables-view-scope")[0]).expanded, true,
"The local scope should be expanded by default.");
is(gVars.getScopeForNode(gVars._list.querySelectorAll(".variables-view-scope")[1]).expanded, false,
"The block scope should be collapsed by default.");
is(gVars.getScopeForNode(gVars._list.querySelectorAll(".variables-view-scope")[2]).expanded, false,
"The global scope should be collapsed by default.");
let thisNode = gVars.getItemForNode(localNodes[0]);
let argumentsNode = gVars.getItemForNode(localNodes[8]);
let cNode = gVars.getItemForNode(localNodes[10]);
is(thisNode.expanded, false,
"The thisNode should not be expanded at this point.");
is(argumentsNode.expanded, false,
"The argumentsNode should not be expanded at this point.");
is(cNode.expanded, false,
"The cNode should not be expanded at this point.");
// Expand the 'this', 'arguments' and 'c' tree nodes. This causes
// their properties to be retrieved and displayed.
thisNode.expand();
argumentsNode.expand();
cNode.expand();
is(thisNode.expanded, true,
"The thisNode should be expanded at this point.");
is(argumentsNode.expanded, true,
"The argumentsNode should be expanded at this point.");
is(cNode.expanded, true,
"The cNode should be expanded at this point.");
// Poll every few milliseconds until the properties are retrieved.
// It's important to set the timer in the chrome window, because the
// content window timers are disabled while the debuggee is paused.
let count = 0;
let intervalID = window.setInterval(function(){
info("count: " + count + " ");
if (++count > 50) {
ok(false, "Timed out while polling for the properties.");
window.clearInterval(intervalID);
return resumeAndFinish();
}
if (!thisNode._retrieved ||
!argumentsNode._retrieved ||
!cNode._retrieved) {
return;
}
window.clearInterval(intervalID);
is(thisNode.target.querySelector(".value")
.getAttribute("value"), "Window",
"Should have the right property value for 'this'.");
is(thisNode.get("window").target.querySelector(".name")
.getAttribute("value"), "window",
"Should have the right property name for 'window'.");
is(thisNode.get("window").target.querySelector(".value")
.getAttribute("value"), "Window",
"'window' should be an object.");
is(thisNode.get("document").target.querySelector(".name")
.getAttribute("value"), "document",
"Should have the right property name for 'document'.");
is(thisNode.get("document").target.querySelector(".value")
.getAttribute("value"), "HTMLDocument",
"'document' should be an object.");
is(argumentsNode.target.querySelector(".value")
.getAttribute("value"), "Arguments",
"Should have the right property value for 'arguments'.");
is(argumentsNode.target.querySelectorAll(".variables-view-property > .title > .name")[0]
.getAttribute("value"), "0",
"Should have the right property name for 'arguments[0]'.");
is(argumentsNode.target.querySelectorAll(".variables-view-property > .title > .value")[0]
.getAttribute("value"), "Object",
"'arguments[0]' should be an object.");
is(argumentsNode.target.querySelectorAll(".variables-view-property > .title > .name")[7]
.getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(argumentsNode.target.querySelectorAll(".variables-view-property > .title > .value")[7]
.getAttribute("value"), "Object",
"'__proto__' should be an object.");
is(cNode.target.querySelector(".value")
.getAttribute("value"), "Object",
"Should have the right property value for 'c'.");
is(cNode.target.querySelectorAll(".variables-view-property > .title > .name")[0]
.getAttribute("value"), "a",
"Should have the right property name for 'c.a'.");
is(cNode.target.querySelectorAll(".variables-view-property > .title > .value")[0]
.getAttribute("value"), "1",
"Should have the right value for 'c.a'.");
is(cNode.target.querySelectorAll(".variables-view-property > .title > .name")[1]
.getAttribute("value"), "b",
"Should have the right property name for 'c.b'.");
is(cNode.target.querySelectorAll(".variables-view-property > .title > .value")[1]
.getAttribute("value"), "\"beta\"",
"Should have the right value for 'c.b'.");
is(cNode.target.querySelectorAll(".variables-view-property > .title > .name")[2]
.getAttribute("value"), "c",
"Should have the right property name for 'c.c'.");
is(cNode.target.querySelectorAll(".variables-view-property > .title > .value")[2]
.getAttribute("value"), "true",
"Should have the right value for 'c.c'.");
is(gVars.getItemForNode(
cNode.target.querySelectorAll(".variables-view-property")[0]).target,
cNode.target.querySelectorAll(".variables-view-property")[0],
"getItemForNode([0]) didn't return the expected property.");
is(gVars.getItemForNode(
cNode.target.querySelectorAll(".variables-view-property")[1]).target,
cNode.target.querySelectorAll(".variables-view-property")[1],
"getItemForNode([1]) didn't return the expected property.");
is(gVars.getItemForNode(
cNode.target.querySelectorAll(".variables-view-property")[2]).target,
cNode.target.querySelectorAll(".variables-view-property")[2],
"getItemForNode([2]) didn't return the expected property.");
is(cNode.find(
cNode.target.querySelectorAll(".variables-view-property")[0]).target,
cNode.target.querySelectorAll(".variables-view-property")[0],
"find([0]) didn't return the expected property.");
is(cNode.find(
cNode.target.querySelectorAll(".variables-view-property")[1]).target,
cNode.target.querySelectorAll(".variables-view-property")[1],
"find([1]) didn't return the expected property.");
is(cNode.find(
cNode.target.querySelectorAll(".variables-view-property")[2]).target,
cNode.target.querySelectorAll(".variables-view-property")[2],
"find([2]) didn't return the expected property.");
resumeAndFinish();
}, 100);
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function resumeAndFinish() {
gDebugger.addEventListener("Debugger:AfterFramesCleared", function listener() {
gDebugger.removeEventListener("Debugger:AfterFramesCleared", listener, true);
var frames = gDebugger.DebuggerView.StackFrames.widget._list;
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
"Should have no frames.");
closeDebuggerAndFinish();
}, true);
gDebugger.DebuggerController.activeThread.resume();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
});

View File

@ -1,105 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view populates the global scope pane.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = false;
testFrameParameters();
});
}
function testFrameParameters()
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 2 Debugger:FetchedVariables events, one from the global object
// scope and the regular one.
if (++count < 2) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
globalScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[2],
globalNodes = globalScope.querySelector(".variables-view-element-details").childNodes;
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
is(frames.querySelectorAll(".dbg-stackframe").length, 3,
"Should have three frames.");
is(globalNodes[1].querySelector(".name").getAttribute("value"), "SpecialPowers",
"Should have the right property name for |SpecialPowers|.");
is(globalNodes[1].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for |SpecialPowers|.");
let globalScopeObject = gDebugger.DebuggerView.Variables.getScopeForNode(globalScope);
let documentNode = globalScopeObject.get("document");
is(documentNode.target.querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for |document|.");
is(documentNode.target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"Should have the right property value for |document|.");
let len = globalNodes.length - 1;
is(globalNodes[len].querySelector(".name").getAttribute("value"), "window",
"Should have the right property name for |window|.");
is(globalNodes[len].querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for |window|.");
resumeAndFinish();
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function resumeAndFinish() {
gDebugger.addEventListener("Debugger:AfterFramesCleared", function listener() {
gDebugger.removeEventListener("Debugger:AfterFramesCleared", listener, true);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list;
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
"Should have no frames.");
closeDebuggerAndFinish();
}}, 0);
}, true);
gDebugger.DebuggerController.activeThread.resume();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
});

View File

@ -1,110 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view is correctly populated in |with| frames.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = false;
testWithFrame();
});
}
function testWithFrame()
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 4 Debugger:FetchedVariables events, one from the global object
// scope, two from the |with| scopes and the regular one.
if (++count < 4) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4],
innerNodes = innerScope.querySelector(".variables-view-element-details").childNodes,
globalNodes = globalScope.querySelector(".variables-view-element-details").childNodes;
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
is(frames.querySelectorAll(".dbg-stackframe").length, 2,
"Should have three frames.");
is(scopes.childNodes.length, 5, "Should have 5 variable scopes.");
is(innerNodes[1].querySelector(".name").getAttribute("value"), "one",
"Should have the right property name for |one|.");
is(innerNodes[1].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for |one|.");
let globalScopeObject = gDebugger.DebuggerView.Variables.getScopeForNode(globalScope);
let documentNode = globalScopeObject.get("document");
is(documentNode.target.querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for |document|.");
is(documentNode.target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"Should have the right property value for |document|.");
let len = globalNodes.length - 1;
is(globalNodes[len].querySelector(".name").getAttribute("value"), "window",
"Should have the right property name for |window|.");
is(globalNodes[len].querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for |window|.");
resumeAndFinish();
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function resumeAndFinish() {
gDebugger.addEventListener("Debugger:AfterFramesCleared", function listener() {
gDebugger.removeEventListener("Debugger:AfterFramesCleared", listener, true);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list;
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
"Should have no frames.");
closeDebuggerAndFinish();
}}, 0);
}, true);
gDebugger.DebuggerController.activeThread.resume();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
});

View File

@ -1,241 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly displays WebIDL attributes in DOM
* objects.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
let gPane = null;
let gTab = null;
let gDebugger = null;
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = true;
testFrameParameters();
});
}
function testFrameParameters()
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 2 Debugger:FetchedVariables events, one from the global object
// scope and the regular one.
if (++count < 2) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
let anonymousScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[1],
globalScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[2],
anonymousNodes = anonymousScope.querySelector(".variables-view-element-details").childNodes,
globalNodes = globalScope.querySelector(".variables-view-element-details").childNodes,
gVars = gDebugger.DebuggerView.Variables;
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
is(anonymousNodes[1].querySelector(".name").getAttribute("value"), "button",
"Should have the right property name for |button|.");
is(anonymousNodes[1].querySelector(".value").getAttribute("value"), "HTMLButtonElement",
"Should have the right property value for |button|.");
is(anonymousNodes[2].querySelector(".name").getAttribute("value"), "buttonAsProto",
"Should have the right property name for |buttonAsProto|.");
is(anonymousNodes[2].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for |buttonAsProto|.");
let globalScopeObject = gVars.getScopeForNode(globalScope);
let documentNode = globalScopeObject.get("document");
is(documentNode.target.querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for |document|.");
is(documentNode.target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"Should have the right property value for |document|.");
let buttonNode = gVars.getItemForNode(anonymousNodes[1]);
let buttonAsProtoNode = gVars.getItemForNode(anonymousNodes[2]);
is(buttonNode.expanded, false,
"The buttonNode should not be expanded at this point.");
is(buttonAsProtoNode.expanded, false,
"The buttonAsProtoNode should not be expanded at this point.");
is(documentNode.expanded, false,
"The documentNode should not be expanded at this point.");
// Expand the 'button', 'buttonAsProto' and 'document' tree nodes. This
// causes their properties to be retrieved and displayed.
buttonNode.expand();
buttonAsProtoNode.expand();
documentNode.expand();
is(buttonNode.expanded, true,
"The buttonNode should be expanded at this point.");
is(buttonAsProtoNode.expanded, true,
"The buttonAsProtoNode should be expanded at this point.");
is(documentNode.expanded, true,
"The documentNode should be expanded at this point.");
// Poll every few milliseconds until the properties are retrieved.
// It's important to set the timer in the chrome window, because the
// content window timers are disabled while the debuggee is paused.
let count1 = 0;
let intervalID = window.setInterval(function(){
info("count1: " + count1);
if (++count1 > 50) {
ok(false, "Timed out while polling for the properties.");
window.clearInterval(intervalID);
return resumeAndFinish();
}
if (!buttonNode._retrieved ||
!buttonAsProtoNode._retrieved ||
!documentNode._retrieved) {
return;
}
window.clearInterval(intervalID);
// Test the prototypes of these objects.
is(buttonNode.get("__proto__").target.querySelector(".name")
.getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__' in buttonNode.");
ok(buttonNode.get("__proto__").target.querySelector(".value")
.getAttribute("value"), "HTMLButtonElement",
"'__proto__' in buttonNode should be an object.");
is(buttonAsProtoNode.get("__proto__").target.querySelector(".name")
.getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__' in buttonAsProtoNode.");
ok(buttonAsProtoNode.get("__proto__").target.querySelector(".value")
.getAttribute("value"), "HTMLButtonElement",
"'__proto__' in buttonAsProtoNode should be an object.");
is(documentNode.get("__proto__").target.querySelector(".name")
.getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__' in documentNode.");
ok(documentNode.get("__proto__").target.querySelector(".value")
.getAttribute("value"), "HTMLDocument",
"'__proto__' in documentNode should be an object.");
// Now the main course: make sure that the native getters for WebIDL
// attributes have been called and a value has been returned.
is(buttonNode.get("type").target.querySelector(".name")
.getAttribute("value"), "type",
"Should have the right property name for 'type' in buttonProtoNode.");
is(buttonNode.get("type").target.querySelector(".value")
.getAttribute("value"), '"submit"',
"'type' in buttonProtoNode should have the right value.");
is(buttonNode.get("formMethod").target.querySelector(".name")
.getAttribute("value"), "formMethod",
"Should have the right property name for 'formMethod' in buttonProtoNode.");
is(buttonNode.get("formMethod").target.querySelector(".value")
.getAttribute("value"), '""',
"'formMethod' in buttonProtoNode should have the right value.");
is(documentNode.get("domain").target.querySelector(".name")
.getAttribute("value"), "domain",
"Should have the right property name for 'domain' in documentProtoNode.");
is(documentNode.get("domain").target.querySelector(".value")
.getAttribute("value"), '"example.com"',
"'domain' in documentProtoNode should have the right value.");
is(documentNode.get("cookie").target.querySelector(".name")
.getAttribute("value"), "cookie",
"Should have the right property name for 'cookie' in documentProtoNode.");
is(documentNode.get("cookie").target.querySelector(".value")
.getAttribute("value"), '""',
"'cookie' in documentProtoNode should have the right value.");
let buttonAsProtoProtoNode = buttonAsProtoNode.get("__proto__");
is(buttonAsProtoProtoNode.expanded, false,
"The buttonAsProtoProtoNode should not be expanded at this point.");
// Expand the prototypes of 'button', 'buttonAsProto' and 'document'
// tree nodes. This causes their properties to be retrieved and
// displayed.
buttonAsProtoProtoNode.expand();
is(buttonAsProtoProtoNode.expanded, true,
"The buttonAsProtoProtoNode should be expanded at this point.");
// Poll every few milliseconds until the properties are retrieved.
// It's important to set the timer in the chrome window, because the
// content window timers are disabled while the debuggee is paused.
let count2 = 0;
let intervalID1 = window.setInterval(function(){
info("count2: " + count2);
if (++count2 > 50) {
ok(false, "Timed out while polling for the properties.");
window.clearInterval(intervalID1);
return resumeAndFinish();
}
if (!buttonAsProtoProtoNode._retrieved) {
return;
}
window.clearInterval(intervalID1);
// Test this more involved case that reuses an object that is
// present in another cache line.
is(buttonAsProtoProtoNode.get("type").target.querySelector(".name")
.getAttribute("value"), "type",
"Should have the right property name for 'type' in buttonAsProtoProtoProtoNode.");
is(buttonAsProtoProtoNode.get("type").target.querySelector(".value")
.getAttribute("value"), '"submit"',
"'type' in buttonAsProtoProtoProtoNode should have the right value.");
is(buttonAsProtoProtoNode.get("formMethod").target.querySelector(".name")
.getAttribute("value"), "formMethod",
"Should have the right property name for 'formMethod' in buttonAsProtoProtoProtoNode.");
is(buttonAsProtoProtoNode.get("formMethod").target.querySelector(".value")
.getAttribute("value"), '""',
"'formMethod' in buttonAsProtoProtoProtoNode should have the right value.");
resumeAndFinish();
}, 100);
}, 100);
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function resumeAndFinish() {
gDebugger.addEventListener("Debugger:AfterFramesCleared", function listener() {
gDebugger.removeEventListener("Debugger:AfterFramesCleared", listener, true);
Services.tm.currentThread.dispatch({ run: function() {
let frames = gDebugger.DebuggerView.StackFrames.widget._list;
is(frames.querySelectorAll(".dbg-stackframe").length, 0,
"Should have no frames.");
closeDebuggerAndFinish();
}}, 0);
}, true);
gDebugger.DebuggerController.activeThread.resume();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
});

View File

@ -1,95 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
// This test checks that we properly set the frozen, sealed, and non-extensbile
// attributes on variables so that the F/S/N is shown in the variables view.
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
function test() {
debug_tab_pane(STACK_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
testFSN();
});
}
function testFSN() {
gDebugger.addEventListener("Debugger:FetchedVariables", function _onFetchedVariables() {
gDebugger.removeEventListener("Debugger:FetchedVariables", _onFetchedVariables, false);
runTest();
}, false);
gDebuggee.eval("(" + function () {
var frozen = Object.freeze({});
var sealed = Object.seal({});
var nonExtensible = Object.preventExtensions({});
var extensible = {};
var string = "foo bar baz";
debugger;
} + "())");
}
function runTest() {
let hasNoneTester = function (aVariable) {
ok(!aVariable.hasAttribute("frozen"),
"The variable should not be frozen");
ok(!aVariable.hasAttribute("sealed"),
"The variable should not be sealed");
ok(!aVariable.hasAttribute("non-extensible"),
"The variable should be extensible");
};
let testers = {
frozen: function (aVariable) {
ok(aVariable.hasAttribute("frozen"),
"The variable should be frozen")
},
sealed: function (aVariable) {
ok(aVariable.hasAttribute("sealed"),
"The variable should be sealed")
},
nonExtensible: function (aVariable) {
ok(aVariable.hasAttribute("non-extensible"),
"The variable should be non-extensible")
},
extensible: hasNoneTester,
string: hasNoneTester,
arguments: hasNoneTester,
this: hasNoneTester
};
let variables = gDebugger.DebuggerView.Variables._parent
.querySelectorAll(".variable-or-property");
for (let v of variables) {
let name = v.querySelector(".name").getAttribute("value");
let tester = testers[name];
delete testers[name];
ok(tester, "We should have a tester for the '" + name + "' variable.");
tester(v);
}
is(Object.keys(testers).length, 0,
"We should have run and removed all the testers.");
closeDebuggerAndFinish();
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,147 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view remains responsive when faced with
* huge ammounts of data.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_big-data.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
requestLongerTimeout(10);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = false;
gDebugger.DebuggerView.Variables.lazyAppend = true;
testWithFrame();
});
}
function testWithFrame()
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test1() {
// We expect 2 Debugger:FetchedVariables events, one from the global object
// scope and the regular one.
if (++count < 2) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test1, false);
Services.tm.currentThread.dispatch({ run: function() {
var scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
loadScope = scopes.querySelectorAll(".variables-view-scope")[1],
globalScope = scopes.querySelectorAll(".variables-view-scope")[2],
innerNodes = innerScope.querySelector(".variables-view-element-details").childNodes,
arrayNodes = innerNodes[4].querySelector(".variables-view-element-details").childNodes;
is(innerNodes[3].querySelector(".name").getAttribute("value"), "buffer",
"Should have the right property name for |buffer|.");
is(innerNodes[3].querySelector(".value").getAttribute("value"), "ArrayBuffer",
"Should have the right property value for |buffer|.");
is(innerNodes[4].querySelector(".name").getAttribute("value"), "z",
"Should have the right property name for |z|.");
is(innerNodes[4].querySelector(".value").getAttribute("value"), "Int8Array",
"Should have the right property value for |z|.");
EventUtils.sendMouseEvent({ type: "mousedown" }, innerNodes[3].querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, innerNodes[4].querySelector(".arrow"), gDebugger);
gDebugger.addEventListener("Debugger:FetchedProperties", function test2() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test2, false);
Services.tm.currentThread.dispatch({ run: function() {
let total = 10000;
let loaded = 0;
let paints = 0;
waitForProperties(total, {
onLoading: function(count) {
ok(count >= loaded, "Should have loaded more properties.");
info("Displayed " + count + " properties, not finished yet.");
info("Remaining " + (total - count) + " properties to display.");
loaded = count;
paints++;
loadScope.hidden = true;
globalScope.hidden = true;
scopes.parentNode.scrollTop = scopes.parentNode.scrollHeight;
},
onFinished: function(count) {
ok(count == total, "Displayed all the properties.");
isnot(paints, 0, "Debugger was unresponsive, sad panda.");
for (let i = 0; i < arrayNodes.length; i++) {
let node = arrayNodes[i];
let name = node.querySelector(".name").getAttribute("value");
// Don't make the test runner dump to the console for every test
// unless something goes wrong.
if (name !== i + "") {
ok(false, "The array items aren't in the correct order.");
}
}
closeDebuggerAndFinish();
}
});
}}, 0);
}, false);
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function waitForProperties(total, callbacks)
{
var scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
innerNodes = innerScope.querySelector(".variables-view-element-details").childNodes,
arrayNodes = innerNodes[4].querySelector(".variables-view-element-details").childNodes;
// Poll every few milliseconds until the properties are retrieved.
let count = 0;
let intervalID = window.setInterval(function() {
info("count: " + count + " ");
if (++count > total) {
ok(false, "Timed out while polling for the properties.");
window.clearInterval(intervalID);
return closeDebuggerAndFinish();
}
// Still need to wait for a few more properties to be fetched.
if (arrayNodes.length < total) {
callbacks.onLoading(arrayNodes.length);
return;
}
// We got all the properties, it's safe to callback.
window.clearInterval(intervalID);
callbacks.onFinished(arrayNodes.length);
}, 100);
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
});

View File

@ -1,352 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view knows how to edit getters and setters.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gVars = null;
var gWatch = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gVars = gDebugger.DebuggerView.Variables;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars.switch = function() {};
gVars.delete = function() {};
prepareVariablesView();
});
}
function prepareVariablesView() {
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
testVariablesView();
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function testVariablesView()
{
executeSoon(function() {
addWatchExpressions(function() {
testEdit("set", "this._prop = value + ' BEER CAN'", function() {
testEdit("set", "{ this._prop = value + ' BEACON' }", function() {
testEdit("set", "{ this._prop = value + ' BEACON;'; }", function() {
testEdit("set", "{ return this._prop = value + ' BEACON;;'; }", function() {
testEdit("set", "function(value) { this._prop = value + ' BACON' }", function() {
testEdit("get", "'brelx BEER CAN'", function() {
testEdit("get", "{ 'brelx BEACON' }", function() {
testEdit("get", "{ 'brelx BEACON;'; }", function() {
testEdit("get", "{ return 'brelx BEACON;;'; }", function() {
testEdit("get", "function() { return 'brelx BACON'; }", function() {
testEdit("get", "bogus", function() {
testEdit("set", "sugob", function() {
testEdit("get", "", function() {
testEdit("set", "", function() {
waitForWatchExpressions(function() {
testEdit("self", "2507", function() {
closeDebuggerAndFinish();
}, {
"myVar.prop": 2507,
"myVar.prop + 42": "250742"
});
})
gWatch.deleteExpression({ name: "myVar.prop = 'xlerb'" });
}, {
"myVar.prop": "xlerb",
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
});
}, {
"myVar.prop": "ReferenceError: bogus is not defined",
"myVar.prop + 42": "ReferenceError: bogus is not defined",
"myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
});
}, {
"myVar.prop": "ReferenceError: bogus is not defined",
"myVar.prop + 42": "ReferenceError: bogus is not defined",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "brelx BACON",
"myVar.prop + 42": "brelx BACON42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "brelx BEACON;;",
"myVar.prop + 42": "brelx BEACON;;42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "brelx BEER CAN",
"myVar.prop + 42": "brelx BEER CAN42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BACON",
"myVar.prop + 42": "xlerb BACON42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEACON;;",
"myVar.prop + 42": "xlerb BEACON;;42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEACON;",
"myVar.prop + 42": "xlerb BEACON;42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEACON",
"myVar.prop + 42": "xlerb BEACON42",
"myVar.prop = 'xlerb'": "xlerb"
});
}, {
"myVar.prop": "xlerb BEER CAN",
"myVar.prop + 42": "xlerb BEER CAN42",
"myVar.prop = 'xlerb'": "xlerb"
});
});
});
}
function addWatchExpressions(callback)
{
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 1, "There should be 1 evaluation availalble");
let w1 = scope.get("myVar.prop");
let w2 = scope.get("myVar.prop + 42");
let w3 = scope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope");
ok(!w2, "The second watch expression should not be present in the scope");
ok(!w3, "The third watch expression should not be present in the scope");
is(w1.value, 42, "The first value is correct.");
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 2, "There should be 2 evaluations availalble");
let w1 = scope.get("myVar.prop");
let w2 = scope.get("myVar.prop + 42");
let w3 = scope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope");
ok(w2, "The second watch expression should be present in the scope");
ok(!w3, "The third watch expression should not be present in the scope");
is(w1.value, "42", "The first expression value is correct.");
is(w2.value, "84", "The second expression value is correct.");
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 3, "There should be 3 evaluations availalble");
let w1 = scope.get("myVar.prop");
let w2 = scope.get("myVar.prop + 42");
let w3 = scope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope");
ok(w2, "The second watch expression should be present in the scope");
ok(w3, "The third watch expression should be present in the scope");
is(w1.value, "xlerb", "The first expression value is correct.");
is(w2.value, "xlerb42", "The second expression value is correct.");
is(w3.value, "xlerb", "The third expression value is correct.");
callback();
});
gWatch.addExpression("myVar.prop = 'xlerb'");
gDebugger.editor.focus();
});
gWatch.addExpression("myVar.prop + 42");
gDebugger.editor.focus();
});
gWatch.addExpression("myVar.prop");
gDebugger.editor.focus();
}
function testEdit(what, string, callback, expected)
{
let localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[1],
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
myVar = gVars.getItemForNode(localNodes[11]);
waitForProperties(function() {
let prop = myVar.get("prop");
let getterOrSetter = (what != "self" ? prop.get(what) : prop);
EventUtils.sendMouseEvent({ type: "mousedown" },
getterOrSetter._target.querySelector(".title > .value"),
gDebugger);
waitForElement(".element-value-input", true, function() {
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
let w1 = scope.get(Object.keys(expected)[0]);
let w2 = scope.get(Object.keys(expected)[1]);
let w3 = scope.get(Object.keys(expected)[2]);
if (w1) {
if (isNaN(expected[w1.name]) && typeof expected[w1.name] == "number") {
ok(isNaN(w1.value),
"The first expression value is correct after the edit (NaN).");
} else if (expected[w1.name] === undefined) {
is(w1.value.type, "undefined",
"The first expression value is correct after the edit (undefined).");
} else {
is(w1.value, expected[w1.name],
"The first expression value is correct after the edit.");
}
info(w1.value + " is equal to " + expected[w1.name]);
}
if (w2) {
if (isNaN(expected[w2.name]) && typeof expected[w2.name] == "number") {
ok(isNaN(w2.value),
"The second expression value is correct after the edit (NaN).");
} else if (expected[w2.name] === undefined) {
is(w2.value.type, "undefined",
"The second expression value is correct after the edit (undefined).");
} else {
is(w2.value, expected[w2.name],
"The second expression value is correct after the edit.");
}
info(w2.value + " is equal to " + expected[w2.name]);
}
if (w3) {
if (isNaN(expected[w3.name]) && typeof expected[w3.name] == "number") {
ok(isNaN(w3.value),
"The third expression value is correct after the edit (NaN).");
} else if (expected[w3.name] === undefined) {
is(w3.value.type, "undefined",
"The third expression value is correct after the edit (undefined).");
} else {
is(w3.value, expected[w3.name],
"The third expression value is correct after the edit.");
}
info(w3.value + " is equal to " + expected[w3.name]);
}
callback();
});
info("Changing the " + what + "ter with '" + string + "'.");
write(string);
EventUtils.sendKey("RETURN", gDebugger);
});
});
myVar.expand();
gVars.clearHierarchy();
}
function waitForWatchExpressions(callback) {
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForProperties(callback) {
gDebugger.addEventListener("Debugger:FetchedProperties", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedProperties", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForElement(selector, exists, callback)
{
// Poll every few milliseconds until the element are retrieved.
let count = 0;
let intervalID = window.setInterval(function() {
info("count: " + count + " ");
if (++count > 50) {
ok(false, "Timed out while polling for the element.");
window.clearInterval(intervalID);
return closeDebuggerAndFinish();
}
if (!!gVars._list.querySelector(selector) != exists) {
return;
}
// We got the element, it's safe to callback.
window.clearInterval(intervalID);
callback();
}, 100);
}
function write(text) {
if (!text) {
EventUtils.sendKey("BACK_SPACE", gDebugger);
return;
}
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gVars = null;
gWatch = null;
});

View File

@ -1,185 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view is able to override getter properties
* to plain value properties.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gVars = null;
var gWatch = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gVars = gDebugger.DebuggerView.Variables;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars.switch = function() {};
gVars.delete = function() {};
prepareVariablesView();
});
}
function prepareVariablesView() {
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
testVariablesView();
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function testVariablesView()
{
executeSoon(function() {
addWatchExpressions(function() {
testEdit("\"xlerb\"", "xlerb", function() {
closeDebuggerAndFinish();
});
});
});
}
function addWatchExpressions(callback)
{
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 1, "There should be 1 evaluation availalble");
let expr = scope.get("myVar.prop");
ok(expr, "The watch expression should be present in the scope");
is(expr.value, 42, "The value is correct.");
callback();
});
gWatch.addExpression("myVar.prop");
gDebugger.editor.focus();
}
function testEdit(string, expected, callback)
{
let localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[1],
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
myVar = gVars.getItemForNode(localNodes[11]);
waitForProperties(function() {
let prop = myVar.get("prop");
is(prop.ownerView.name, "myVar",
"The right owner property name wasn't found.");
is(prop.name, "prop",
"The right property name wasn't found.");
is(prop.ownerView.value.type, "object",
"The right owner property value type wasn't found.");
is(prop.ownerView.value.class, "Object",
"The right owner property value class wasn't found.");
is(prop.name, "prop",
"The right property name wasn't found.");
is(prop.value, undefined,
"The right property value wasn't found.");
ok(prop.getter,
"The right property getter wasn't found.");
ok(prop.setter,
"The right property setter wasn't found.");
EventUtils.sendMouseEvent({ type: "mousedown" },
prop._target.querySelector(".variables-view-edit"),
gDebugger);
waitForElement(".element-value-input", true, function() {
waitForWatchExpressions(function() {
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
let expr = scope.get("myVar.prop");
is(expr.value, expected, "The value is correct.");
callback();
});
write(string);
EventUtils.sendKey("RETURN", gDebugger);
});
});
myVar.expand();
gVars.clearHierarchy();
}
function waitForWatchExpressions(callback) {
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForProperties(callback) {
gDebugger.addEventListener("Debugger:FetchedProperties", function onFetch() {
gDebugger.removeEventListener("Debugger:FetchedProperties", onFetch, false);
executeSoon(callback);
}, false);
}
function waitForElement(selector, exists, callback)
{
// Poll every few milliseconds until the element are retrieved.
let count = 0;
let intervalID = window.setInterval(function() {
info("count: " + count + " ");
if (++count > 50) {
ok(false, "Timed out while polling for the element.");
window.clearInterval(intervalID);
return closeDebuggerAndFinish();
}
if (!!gVars._list.querySelector(selector) != exists) {
return;
}
// We got the element, it's safe to callback.
window.clearInterval(intervalID);
callback();
}, 100);
}
function write(text) {
if (!text) {
EventUtils.sendKey("BACK_SPACE", gDebugger);
return;
}
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gVars = null;
gWatch = null;
});

View File

@ -1,119 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Make sure that the editing variables or properties values works properly.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_frame-parameters.html";
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
requestLongerTimeout(3);
function test() {
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = false;
testFrameEval();
});
}
function testFrameEval() {
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
var localScope = gDebugger.DebuggerView.Variables._list.querySelector(".variables-view-scope"),
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
varA = localNodes[7];
is(varA.querySelector(".name").getAttribute("value"), "a",
"Should have the right name for 'a'.");
is(varA.querySelector(".value").getAttribute("value"), 1,
"Should have the right initial value for 'a'.");
testModification(varA, function(aVar) {
testModification(aVar, function(aVar) {
testModification(aVar, function(aVar) {
resumeAndFinish();
}, "document.title", '"Debugger Function Call Parameter Test"');
}, "b", "Object");
}, "{ a: 1 }", "Object");
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
content.document.querySelector("button"),
content.window);
}
function testModification(aVar, aCallback, aNewValue, aNewResult) {
function makeChangesAndExitInputMode() {
EventUtils.sendString(aNewValue, gDebugger);
EventUtils.sendKey("RETURN", gDebugger);
}
EventUtils.sendMouseEvent({ type: "mousedown" },
aVar.querySelector(".value"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-value-input"),
"There should be an input element created.");
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 2 Debugger:FetchedVariables events, one from the global
// object scope and the regular one.
if (++count < 2) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
// Get the variable reference anew, since the old ones were discarded when
// we resumed.
var localScope = gDebugger.DebuggerView.Variables._list.querySelector(".variables-view-scope"),
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
varA = localNodes[7];
is(varA.querySelector(".value").getAttribute("value"), aNewResult,
"Should have the right value for 'a'.");
executeSoon(function() {
aCallback(varA);
});
}, false);
makeChangesAndExitInputMode();
});
}
function resumeAndFinish() {
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
});

View File

@ -1,514 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/*
* Any copyright is dedicated to the Public Domain.
* http://creativecommons.org/publicdomain/zero/1.0/
*/
/**
* Make sure that the editing or removing watch expressions works properly.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_watch-expressions.html";
var gPane = null;
var gTab = null;
var gDebuggee = null;
var gDebugger = null;
var gWatch = null;
var gVars = null;
requestLongerTimeout(3);
function test() {
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gDebuggee = aDebuggee;
gPane = aPane;
gDebugger = gPane.panelWin;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars = gDebugger.DebuggerView.Variables;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = false;
testFrameEval();
});
}
function testFrameEval() {
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function test() {
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", test, false);
Services.tm.currentThread.dispatch({ run: function() {
is(gDebugger.DebuggerController.activeThread.state, "paused",
"Should only be getting stack frames while paused.");
var localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[1],
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
aArg = localNodes[1],
varT = localNodes[3];
is(aArg.querySelector(".name").getAttribute("value"), "aArg",
"Should have the right name for 'aArg'.");
is(varT.querySelector(".name").getAttribute("value"), "t",
"Should have the right name for 't'.");
is(aArg.querySelector(".value").getAttribute("value"), "undefined",
"Should have the right initial value for 'aArg'.");
is(varT.querySelector(".value").getAttribute("value"), "\"Browser Debugger Watch Expressions Test\"",
"Should have the right initial value for 't'.");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 5, "There should be 5 evaluations availalble");
is(scope.get("this")._isContentVisible, true,
"Should have the right visibility state for 'this'.");
is(scope.get("this").target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'this'.");
is(scope.get("this").name, "this",
"Should have the right name for 'this'.");
is(scope.get("this").value.type, "object",
"Should have the right value type for 'this'.");
is(scope.get("this").value.class, "Window",
"Should have the right value type for 'this'.");
is(scope.get("ermahgerd")._isContentVisible, true,
"Should have the right visibility state for 'ermahgerd'.");
is(scope.get("ermahgerd").target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'ermahgerd'.");
is(scope.get("ermahgerd").name, "ermahgerd",
"Should have the right name for 'ermahgerd'.");
is(scope.get("ermahgerd").value.type, "object",
"Should have the right value type for 'ermahgerd'.");
is(scope.get("ermahgerd").value.class, "Function",
"Should have the right value type for 'ermahgerd'.");
is(scope.get("aArg")._isContentVisible, true,
"Should have the right visibility state for 'aArg'.");
is(scope.get("aArg").target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'aArg'.");
is(scope.get("aArg").name, "aArg",
"Should have the right name for 'aArg'.");
is(scope.get("aArg").value.type, "undefined",
"Should have the right value for 'aArg'.");
is(scope.get("aArg").value.class, undefined,
"Should have the right value for 'aArg'.");
is(scope.get("document.title")._isContentVisible, true,
"Should have the right visibility state for 'document.title'.");
is(scope.get("document.title").target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'document.title'.");
is(scope.get("document.title").name, "document.title",
"Should have the right name for 'document.title'.");
is(scope.get("document.title").value, "42",
"Should have the right value for 'document.title'.");
is(typeof scope.get("document.title").value, "string",
"Should have the right value type for 'document.title'.");
is(scope.get("document.title = 42")._isContentVisible, true,
"Should have the right visibility state for 'document.title = 42'.");
is(scope.get("document.title = 42").target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'document.title = 42'.");
is(scope.get("document.title = 42").name, "document.title = 42",
"Should have the right name for 'document.title = 42'.");
is(scope.get("document.title = 42").value, 42,
"Should have the right value for 'document.title = 42'.");
is(typeof scope.get("document.title = 42").value, "number",
"Should have the right value type for 'document.title = 42'.");
testModification(scope.get("document.title = 42").target, test1, function(scope) {
testModification(scope.get("aArg").target, test2, function(scope) {
testModification(scope.get("aArg = 44").target, test3, function(scope) {
testModification(scope.get("document.title = 43").target, test4, function(scope) {
testModification(scope.get("document.title").target, test5, function(scope) {
testExprDeletion(scope.get("this").target, test6, function(scope) {
testExprDeletion(null, test7, function(scope) {
resumeAndFinish();
}, 44, 0, true, true);
}, 44);
}, " \t\r\n", "\"43\"", 44, 1, true);
}, " \t\r\ndocument.title \t\r\n", "\"43\"", 44);
}, " \t\r\ndocument.title \t\r\n", "\"43\"", 44);
}, "aArg = 44", 44, 44);
}, "document.title = 43", 43, "undefined");
}}, 0);
}, false);
addWatchExpression("this");
addWatchExpression("ermahgerd");
addWatchExpression("aArg");
addWatchExpression("document.title");
addCmdWatchExpression("document.title = 42");
executeSoon(function() {
gDebuggee.ermahgerd(); // ermahgerd!!
});
}
function testModification(aVar, aTest, aCallback, aNewValue, aNewResult, aArgResult,
aLocalScopeIndex = 1, aDeletionFlag = null)
{
function makeChangesAndExitInputMode() {
EventUtils.sendString(aNewValue, gDebugger);
EventUtils.sendKey("RETURN", gDebugger);
}
EventUtils.sendMouseEvent({ type: "dblclick" },
aVar.querySelector(".name"),
gDebugger);
executeSoon(function() {
ok(aVar.querySelector(".element-name-input"),
"There should be an input element created.");
let testContinued = false;
let fetchedVariables = false;
let fetchedExpressions = false;
let countV = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function testV() {
// We expect 2 Debugger:FetchedVariables events, one from the global
// object scope and the regular one.
if (++countV < 2) {
info("Number of received Debugger:FetchedVariables events: " + countV);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", testV, false);
fetchedVariables = true;
executeSoon(continueTest);
}, false);
let countE = 0;
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function testE() {
// We expect only one Debugger:FetchedWatchExpressions event, since all
// expressions are evaluated at the same time.
if (++countE < 1) {
info("Number of received Debugger:FetchedWatchExpressions events: " + countE);
return;
}
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", testE, false);
fetchedExpressions = true;
executeSoon(continueTest);
}, false);
function continueTest() {
if (testContinued || !fetchedVariables || !fetchedExpressions) {
return;
}
testContinued = true;
// Get the variable reference anew, since the old ones were discarded when
// we resumed.
var localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[aLocalScopeIndex],
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
aArg = localNodes[1];
is(aArg.querySelector(".value").getAttribute("value"), aArgResult,
"Should have the right value for 'aArg'.");
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
info("Found the watch expressions scope: " + scope);
let aExp = scope.get(aVar.querySelector(".name").getAttribute("value"));
info("Found the watch expression variable: " + aExp);
if (aDeletionFlag) {
ok(fetchedVariables, "The variables should have been fetched.");
ok(fetchedExpressions, "The variables should have been fetched.");
is(aExp, undefined, "The watch expression should not have been found.");
performCallback(scope);
return;
}
is(aExp.target.querySelector(".name").getAttribute("value"), aNewValue.trim(),
"Should have the right name for '" + aNewValue + "'.");
is(aExp.target.querySelector(".value").getAttribute("value"), aNewResult,
"Should have the right value for '" + aNewValue + "'.");
performCallback(scope);
}
makeChangesAndExitInputMode();
});
function performCallback(scope) {
executeSoon(function() {
aTest(scope);
aCallback(scope);
});
}
}
function testExprDeletion(aVar, aTest, aCallback, aArgResult,
aLocalScopeIndex = 1, aFinalFlag = null, aRemoveAllFlag = null)
{
let testContinued = false;
let fetchedVariables = false;
let fetchedExpressions = false;
let countV = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function testV() {
// We expect 2 Debugger:FetchedVariables events, one from the global
// object scope and the regular one.
if (++countV < 2) {
info("Number of received Debugger:FetchedVariables events: " + countV);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", testV, false);
fetchedVariables = true;
executeSoon(continueTest);
}, false);
let countE = 0;
gDebugger.addEventListener("Debugger:FetchedWatchExpressions", function testE() {
// We expect only one Debugger:FetchedWatchExpressions event, since all
// expressions are evaluated at the same time.
if (++countE < 1) {
info("Number of received Debugger:FetchedWatchExpressions events: " + countE);
return;
}
gDebugger.removeEventListener("Debugger:FetchedWatchExpressions", testE, false);
fetchedExpressions = true;
executeSoon(continueTest);
}, false);
function continueTest() {
if ((testContinued || !fetchedVariables || !fetchedExpressions) && !aFinalFlag) {
return;
}
testContinued = true;
// Get the variable reference anew, since the old ones were discarded when
// we resumed.
var localScope = gDebugger.DebuggerView.Variables._list.querySelectorAll(".variables-view-scope")[aLocalScopeIndex],
localNodes = localScope.querySelector(".variables-view-element-details").childNodes,
aArg = localNodes[1];
is(aArg.querySelector(".value").getAttribute("value"), aArgResult,
"Should have the right value for 'aArg'.");
let label = gDebugger.L10N.getStr("watchExpressionsScopeLabel");
let scope = gVars._currHierarchy.get(label);
info("Found the watch expressions scope: " + scope);
if (aFinalFlag) {
ok(fetchedVariables, "The variables should have been fetched.");
ok(!fetchedExpressions, "The variables should never have been fetched.");
is(scope, undefined, "The watch expressions scope should not have been found.");
performCallback(scope);
return;
}
let aExp = scope.get(aVar.querySelector(".name").getAttribute("value"));
info("Found the watch expression variable: " + aExp);
is(aExp, undefined, "Should not have found the watch expression after deletion.");
performCallback(scope);
}
function performCallback(scope) {
executeSoon(function() {
aTest(scope);
aCallback(scope);
});
}
if (aRemoveAllFlag) {
gWatch._onCmdRemoveAllExpressions();
return;
}
EventUtils.sendMouseEvent({ type: "click" },
aVar.querySelector(".variables-view-delete"),
gDebugger);
}
function test1(scope) {
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 5, "There should be 5 evaluations availalble");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "aArg",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "aArg",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(3).attachment.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch.getItemAtIndex(3).attachment.currentExpression, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch.getItemAtIndex(4).attachment.inputNode.value, "this",
"The fifth textbox input value is not the correct one");
is(gWatch.getItemAtIndex(4).attachment.currentExpression, "this",
"The fifth textbox input value is not the correct one");
}
function test2(scope) {
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 5, "There should be 5 evaluations availalble");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "aArg = 44",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "aArg = 44",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(3).attachment.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch.getItemAtIndex(3).attachment.currentExpression, "ermahgerd",
"The fourth textbox input value is not the correct one");
is(gWatch.getItemAtIndex(4).attachment.inputNode.value, "this",
"The fifth textbox input value is not the correct one");
is(gWatch.getItemAtIndex(4).attachment.currentExpression, "this",
"The fifth textbox input value is not the correct one");
}
function test3(scope) {
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 4,
"There should be 4 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 4, "There should be 4 evaluations availalble");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "document.title",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(3).attachment.inputNode.value, "this",
"The fourth textbox input value is not the correct one");
is(gWatch.getItemAtIndex(3).attachment.currentExpression, "this",
"The fourth textbox input value is not the correct one");
}
function test4(scope) {
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 3,
"There should be 3 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 3, "There should be 3 evaluations availalble");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title",
"The first textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "this",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "this",
"The third textbox input value is not the correct one");
}
function test5(scope) {
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 2,
"There should be 2 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 2, "There should be 2 evaluations availalble");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "ermahgerd",
"The second textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "this",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "this",
"The third textbox input value is not the correct one");
}
function test6(scope) {
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 1,
"There should be 1 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
ok(scope, "There should be a wach expressions scope in the variables view");
is(scope._store.size, 1, "There should be 1 evaluation availalble");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "ermahgerd",
"The third textbox input value is not the correct one");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "ermahgerd",
"The third textbox input value is not the correct one");
}
function test7(scope) {
is(gWatch.widget._parent.querySelectorAll(".dbg-expression[hidden=true]").length, 0,
"There should be 0 hidden nodes in the watch expressions container");
is(gWatch.widget._parent.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container");
is(scope, undefined, "There should be no watch expressions scope available.");
is(gWatch.itemCount, 0, "The watch expressions container should be empty.");
}
function addWatchExpression(string) {
gWatch.addExpression(string);
gDebugger.editor.focus();
}
function addCmdWatchExpression(string) {
gWatch._onCmdAddExpression(string);
gDebugger.editor.focus();
}
function resumeAndFinish() {
gDebugger.DebuggerController.activeThread.resume(function() {
closeDebuggerAndFinish();
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gDebugger = null;
gWatch = null;
gVars = null;
});

View File

@ -1,516 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly filters nodes by name.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gDebuggee = null;
var gSearchBox = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.delayedSearch = false;
testSearchbox();
prepareVariables(testVariablesFiltering);
});
}
function testSearchbox()
{
ok(!gDebugger.DebuggerView.Variables._searchboxNode,
"There should not initially be a searchbox available in the variables view.");
ok(!gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should not be found.");
gDebugger.DebuggerView.Variables._enableSearch();
ok(gDebugger.DebuggerView.Variables._searchboxNode,
"There should be a searchbox available after enabling.");
ok(gDebugger.DebuggerView.Variables._searchboxContainer.hidden,
"The searchbox container should be hidden at this point.");
ok(gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should be found.");
gDebugger.DebuggerView.Variables._disableSearch();
ok(!gDebugger.DebuggerView.Variables._searchboxNode,
"There shouldn't be a searchbox available after disabling.");
ok(!gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should not be found.");
gDebugger.DebuggerView.Variables._enableSearch();
ok(gDebugger.DebuggerView.Variables._searchboxNode,
"There should be a searchbox available after enabling.");
ok(gDebugger.DebuggerView.Variables._searchboxContainer.hidden,
"The searchbox container should be hidden at this point.");
ok(gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should be found.");
let placeholder = "freshly squeezed mango juice";
gDebugger.DebuggerView.Variables.searchPlaceholder = placeholder;
is(gDebugger.DebuggerView.Variables.searchPlaceholder, placeholder,
"The placeholder getter didn't return the expected string");
ok(gDebugger.DebuggerView.Variables._searchboxNode.getAttribute("placeholder"),
placeholder, "There correct placeholder should be applied to the searchbox.");
gDebugger.DebuggerView.Variables._disableSearch();
ok(!gDebugger.DebuggerView.Variables._searchboxNode,
"There shouldn't be a searchbox available after disabling again.");
ok(!gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should not be found.");
gDebugger.DebuggerView.Variables._enableSearch();
ok(gDebugger.DebuggerView.Variables._searchboxNode,
"There should be a searchbox available after enabling again.");
ok(gDebugger.DebuggerView.Variables._searchboxContainer.hidden,
"The searchbox container should be hidden at this point.");
ok(gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should be found.");
ok(gDebugger.DebuggerView.Variables._searchboxNode.getAttribute("placeholder"),
placeholder, "There correct placeholder should be applied to the searchbox again.");
gDebugger.DebuggerView.Variables.searchEnabled = false;
ok(!gDebugger.DebuggerView.Variables._searchboxNode,
"There shouldn't be a searchbox available after disabling again.");
ok(!gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should not be found.");
gDebugger.DebuggerView.Variables.searchEnabled = true;
ok(gDebugger.DebuggerView.Variables._searchboxNode,
"There should be a searchbox available after enabling again.");
ok(gDebugger.DebuggerView.Variables._searchboxContainer.hidden,
"The searchbox container should be hidden at this point.");
ok(gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should be found.");
ok(gDebugger.DebuggerView.Variables._searchboxNode.getAttribute("placeholder"),
placeholder, "There correct placeholder should be applied to the searchbox again.");
}
function testVariablesFiltering()
{
ok(!gDebugger.DebuggerView.Variables._searchboxContainer.hidden,
"The searchbox container should not be hidden at this point.");
function test1()
{
write("location");
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
is(thisItem.expanded, true,
"The local scope 'this' should be expanded");
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded");
ignoreExtraMatchedProperties();
locationItem.toggle();
locationItem.toggle();
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 3,
"There should be 3 variables displayed in the global scope");
ok(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length > 6,
"There should be more than 6 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"this", "The only inner variable displayed should be 'this'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"window", "The third inner property displayed should be 'window'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[3].getAttribute("value"),
"document", "The fourth inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[4].getAttribute("value"),
"location", "The fifth inner property displayed should be 'location'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"location", "The first global variable displayed should be 'location'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"locationbar", "The second global variable displayed should be 'locationbar'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[2].getAttribute("value"),
"Location", "The third global variable displayed should be 'Location'");
}
function test2()
{
innerScopeItem.collapse();
mathScopeItem.collapse();
testScopeItem.collapse();
loadScopeItem.collapse();
globalScopeItem.collapse();
thisItem.collapse();
windowItem.collapse();
documentItem.collapse();
locationItem.collapse();
is(innerScopeItem.expanded, false,
"The innerScope expanded getter should return false");
is(mathScopeItem.expanded, false,
"The mathScope expanded getter should return false");
is(testScopeItem.expanded, false,
"The testScope expanded getter should return false");
is(loadScopeItem.expanded, false,
"The loadScope expanded getter should return false");
is(globalScopeItem.expanded, false,
"The globalScope expanded getter should return false");
is(thisItem.expanded, false,
"The local scope 'this' should not be expanded");
is(windowItem.expanded, false,
"The local scope 'this.window' should not be expanded");
is(documentItem.expanded, false,
"The local scope 'this.window.document' should not be expanded");
is(locationItem.expanded, false,
"The local scope 'this.window.document.location' should not be expanded");
write("location");
is(thisItem.expanded, true,
"The local scope 'this' should be expanded");
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded");
ignoreExtraMatchedProperties();
locationItem.toggle();
locationItem.toggle();
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 3,
"There should be 3 variables displayed in the global scope");
ok(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length > 6,
"There should be more than 6 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"this", "The only inner variable displayed should be 'this'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"window", "The third inner property displayed should be 'window'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[3].getAttribute("value"),
"document", "The fourth inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[4].getAttribute("value"),
"location", "The fifth inner property displayed should be 'location'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"location", "The first global variable displayed should be 'location'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"locationbar", "The second global variable displayed should be 'locationbar'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[2].getAttribute("value"),
"Location", "The second global variable displayed should be 'Location'");
}
var scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
let thisItem = innerScopeItem.get("this");
let windowItem = thisItem.get("window");
let documentItem = windowItem.get("document");
let locationItem = documentItem.get("location");
gSearchBox = gDebugger.DebuggerView.Variables._searchboxNode;
executeSoon(function() {
test1();
executeSoon(function() {
test2();
executeSoon(function() {
closeDebuggerAndFinish();
});
});
});
}
function prepareVariables(aCallback)
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 4 Debugger:FetchedVariables events, one from the global object
// scope, two from the |with| scopes and the regular one.
if (++count < 4) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
mathScopeItem.collapse();
testScopeItem.collapse();
loadScopeItem.collapse();
globalScopeItem.collapse();
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, false,
"The mathScope expanded getter should return false");
is(testScopeItem.expanded, false,
"The testScope expanded getter should return false");
is(loadScopeItem.expanded, false,
"The loadScope expanded getter should return false");
is(globalScopeItem.expanded, false,
"The globalScope expanded getter should return false");
EventUtils.sendMouseEvent({ type: "mousedown" }, mathScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, testScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, loadScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, globalScope.querySelector(".arrow"), gDebugger);
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
let thisItem = innerScopeItem.get("this");
is(thisItem.expanded, false,
"The local scope 'this' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test2() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test2, false);
Services.tm.currentThread.dispatch({ run: function() {
let windowItem = thisItem.get("window");
is(windowItem.expanded, false,
"The local scope 'this.window' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test3() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test3, false);
Services.tm.currentThread.dispatch({ run: function() {
let documentItem = windowItem.get("document");
is(documentItem.expanded, false,
"The local scope 'this.window.document' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test4() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test4, false);
Services.tm.currentThread.dispatch({ run: function() {
let locationItem = documentItem.get("location");
is(locationItem.expanded, false,
"The local scope 'this.window.document.location' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test5() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test5, false);
Services.tm.currentThread.dispatch({ run: function() {
is(thisItem.expanded, true,
"The local scope 'this' should be expanded");
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded");
executeSoon(function() {
aCallback();
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
locationItem.target.querySelector(".arrow"),
gDebugger);
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
documentItem.target.querySelector(".arrow"),
gDebugger);
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
windowItem.target.querySelector(".arrow"),
gDebugger);
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
thisItem.target.querySelector(".arrow"),
gDebugger);
is(thisItem.expanded, true,
"The local scope 'this' should be expanded now");
});
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee.window);
}
function ignoreExtraMatchedProperties()
{
for (let [, item] of gDebugger.DebuggerView.Variables._currHierarchy) {
let name = item.name.toLowerCase();
let value = item._valueString || "";
if ((name.contains("tracemallocdumpallocations")) ||
(name.contains("geolocation")) ||
(name.contains("webgl"))) {
item.target.setAttribute("non-match", "");
}
}
}
function clear() {
gSearchBox.focus();
gSearchBox.value = "";
}
function write(text) {
clear();
append(text);
}
function append(text) {
gSearchBox.focus();
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gDebuggee = null;
gSearchBox = null;
});

View File

@ -1,438 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly filters nodes by value.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gDebuggee = null;
var gSearchBox = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.delayedSearch = false;
testSearchbox();
prepareVariables(testVariablesFiltering);
});
}
function testSearchbox()
{
ok(!gDebugger.DebuggerView.Variables._searchboxNode,
"There should not initially be a searchbox available in the variables view.");
ok(!gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should not be found.");
gDebugger.DebuggerView.Variables._enableSearch();
ok(gDebugger.DebuggerView.Variables._searchboxNode,
"There should be a searchbox available after enabling.");
ok(gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should be found.");
ok(gDebugger.DebuggerView.Variables._searchboxContainer.hidden,
"The searchbox container should be hidden at this point.");
}
function testVariablesFiltering()
{
ok(!gDebugger.DebuggerView.Variables._searchboxContainer.hidden,
"The searchbox container should not be hidden at this point.");
function test1()
{
write("htmldocument");
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
is(thisItem.expanded, true,
"The local scope 'this' should be expanded");
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded");
locationItem.toggle();
locationItem.toggle();
documentItem.toggle();
documentItem.toggle();
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 2,
"There should be 2 variables displayed in the global scope");
ok(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length > 3,
"There should be more than 3 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"this", "The only inner variable displayed should be 'this'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[0].getAttribute("value"),
"document", "The first inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[1].getAttribute("value"),
"window", "The second inner property displayed should be 'window'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"document", "The third inner property displayed should be 'document'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"document", "The first global variable displayed should be 'document'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"HTMLDocument", "The first global variable displayed should be 'HTMLDocument'");
}
function test2()
{
innerScopeItem.collapse();
mathScopeItem.collapse();
testScopeItem.collapse();
loadScopeItem.collapse();
globalScopeItem.collapse();
thisItem.collapse();
windowItem.collapse();
documentItem.collapse();
locationItem.collapse();
is(innerScopeItem.expanded, false,
"The innerScope expanded getter should return false");
is(mathScopeItem.expanded, false,
"The mathScope expanded getter should return false");
is(testScopeItem.expanded, false,
"The testScope expanded getter should return false");
is(loadScopeItem.expanded, false,
"The loadScope expanded getter should return false");
is(globalScopeItem.expanded, false,
"The globalScope expanded getter should return false");
is(thisItem.expanded, false,
"The local scope 'this' should not be expanded");
is(windowItem.expanded, false,
"The local scope 'this.window' should not be expanded");
is(documentItem.expanded, false,
"The local scope 'this.window.document' should not be expanded");
is(locationItem.expanded, false,
"The local scope 'this.window.document.location' should not be expanded");
write("htmldocument");
is(thisItem.expanded, true,
"The local scope 'this' should be expanded");
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded");
documentItem.toggle();
documentItem.toggle();
locationItem.toggle();
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 2,
"There should be 2 variables displayed in the global scope");
ok(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length > 3,
"There should be more than 3 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the load scope");
is(globalScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"this", "The only inner variable displayed should be 'this'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[0].getAttribute("value"),
"document", "The first inner property displayed should be 'document'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[1].getAttribute("value"),
"window", "The second inner property displayed should be 'window'");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"document", "The third inner property displayed should be 'document'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"document", "The first global variable displayed should be 'document'");
is(globalScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"HTMLDocument", "The first global variable displayed should be 'HTMLDocument'");
}
var scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
let thisItem = innerScopeItem.get("this");
let windowItem = thisItem.get("window");
let documentItem = windowItem.get("document");
let locationItem = documentItem.get("location");
gSearchBox = gDebugger.DebuggerView.Variables._searchboxNode;
executeSoon(function() {
test1();
executeSoon(function() {
test2();
executeSoon(function() {
closeDebuggerAndFinish();
});
});
});
}
function prepareVariables(aCallback)
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 4 Debugger:FetchedVariables events, one from the global object
// scope, two from the |with| scopes and the regular one.
if (++count < 4) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
mathScopeItem.collapse();
testScopeItem.collapse();
loadScopeItem.collapse();
globalScopeItem.collapse();
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, false,
"The mathScope expanded getter should return false");
is(testScopeItem.expanded, false,
"The testScope expanded getter should return false");
is(loadScopeItem.expanded, false,
"The loadScope expanded getter should return false");
is(globalScopeItem.expanded, false,
"The globalScope expanded getter should return false");
EventUtils.sendMouseEvent({ type: "mousedown" }, mathScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, testScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, loadScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, globalScope.querySelector(".arrow"), gDebugger);
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
let thisItem = innerScopeItem.get("this");
is(thisItem.expanded, false,
"The local scope 'this' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test2() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test2, false);
Services.tm.currentThread.dispatch({ run: function() {
let windowItem = thisItem.get("window");
is(windowItem.expanded, false,
"The local scope 'this.window' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test3() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test3, false);
Services.tm.currentThread.dispatch({ run: function() {
let documentItem = windowItem.get("document");
is(documentItem.expanded, false,
"The local scope 'this.window.document' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test4() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test4, false);
Services.tm.currentThread.dispatch({ run: function() {
let locationItem = documentItem.get("location");
is(locationItem.expanded, false,
"The local scope 'this.window.document.location' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test5() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test5, false);
Services.tm.currentThread.dispatch({ run: function() {
is(thisItem.expanded, true,
"The local scope 'this' should be expanded");
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded");
executeSoon(function() {
aCallback();
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
locationItem.target.querySelector(".arrow"),
gDebugger);
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
documentItem.target.querySelector(".arrow"),
gDebugger);
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
windowItem.target.querySelector(".arrow"),
gDebugger);
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
thisItem.target.querySelector(".arrow"),
gDebugger);
is(thisItem.expanded, true,
"The local scope 'this' should be expanded now");
});
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee.window);
}
function clear() {
gSearchBox.focus();
gSearchBox.value = "";
}
function write(text) {
clear();
append(text);
}
function append(text) {
gSearchBox.focus();
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gDebuggee = null;
gSearchBox = null;
});

View File

@ -1,93 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view filter prefs work properly.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gDebuggee = null;
var gPrevPref = null;
function test()
{
gPrevPref = Services.prefs.getBoolPref(
"devtools.debugger.ui.variables-searchbox-visible");
Services.prefs.setBoolPref(
"devtools.debugger.ui.variables-searchbox-visible", false);
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
testSearchbox();
testPref();
});
}
function testSearchbox()
{
ok(!gDebugger.DebuggerView.Variables._searchboxNode,
"There should not initially be a searchbox available in the variables view.");
ok(!gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"There searchbox element should not be found.");
}
function testPref()
{
is(gDebugger.Prefs.variablesSearchboxVisible, false,
"The debugger searchbox should be preffed as hidden.");
isnot(gDebugger.DebuggerView.Options._showVariablesFilterBoxItem.getAttribute("checked"), "true",
"The options menu item should not be checked.");
gDebugger.DebuggerView.Options._showVariablesFilterBoxItem.setAttribute("checked", "true");
gDebugger.DebuggerView.Options._toggleShowVariablesFilterBox();
executeSoon(function() {
ok(gDebugger.DebuggerView.Variables._searchboxNode,
"There should be a searchbox available in the variables view.");
ok(gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"There searchbox element should be found.");
is(gDebugger.Prefs.variablesSearchboxVisible, true,
"The debugger searchbox should now be preffed as visible.");
is(gDebugger.DebuggerView.Options._showVariablesFilterBoxItem.getAttribute("checked"), "true",
"The options menu item should now be checked.");
gDebugger.DebuggerView.Options._showVariablesFilterBoxItem.setAttribute("checked", "false");
gDebugger.DebuggerView.Options._toggleShowVariablesFilterBox();
executeSoon(function() {
ok(!gDebugger.DebuggerView.Variables._searchboxNode,
"There should not be a searchbox available in the variables view.");
ok(!gDebugger.DebuggerView.Variables._parent.parentNode.querySelector(".variables-view-searchinput"),
"There searchbox element should not be found.");
is(gDebugger.Prefs.variablesSearchboxVisible, false,
"The debugger searchbox should now be preffed as hidden.");
isnot(gDebugger.DebuggerView.Options._showVariablesFilterBoxItem.getAttribute("checked"), "true",
"The options menu item should now be unchecked.");
executeSoon(function() {
Services.prefs.setBoolPref(
"devtools.debugger.ui.variables-searchbox-visible", gPrevPref);
closeDebuggerAndFinish();
});
});
});
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gDebuggee = null;
gPrevPref = null;
});

View File

@ -1,284 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly filters nodes.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gDebuggee = null;
var gSearchBox = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.delayedSearch = false;
prepareVariables(testVariablesFiltering);
});
}
function testVariablesFiltering()
{
function test1()
{
write("*one");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the load scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the load scope");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"one", "The only inner variable displayed should be 'one'");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"button", "The only load variable displayed should be 'button'");
let oneItem = innerScopeItem.get("one");
is(oneItem.expanded, false,
"The one item in the inner scope should not be expanded");
EventUtils.sendKey("RETURN", gDebugger);
is(oneItem.expanded, true,
"The one item in the inner scope should now be expanded");
}
function test2()
{
write("*two");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the load scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
is(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the load scope");
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"two", "The only inner variable displayed should be 'two'");
let twoItem = innerScopeItem.get("two");
is(twoItem.expanded, false,
"The two item in the inner scope should not be expanded");
EventUtils.sendKey("RETURN", gDebugger);
is(twoItem.expanded, true,
"The two item in the inner scope should now be expanded");
}
function test3()
{
backspace(3);
is(gSearchBox.value, "*",
"Searchbox value is incorrect after 3 backspaces");
// variable count includes `__proto__` for object scopes
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 4,
"There should be 4 variables displayed in the inner scope");
isnot(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the math scope");
isnot(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the test scope");
isnot(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the load scope");
isnot(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
ok(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length > 1,
"There should be more than one property displayed in the load scope");
isnot(globalScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be some properties displayed in the global scope");
}
function test4()
{
backspace(1);
is(gSearchBox.value, "",
"Searchbox value is incorrect after 1 backspace");
// variable count includes `__proto__` for object scopes
is(innerScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 4,
"There should be 4 variables displayed in the inner scope");
isnot(mathScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the math scope");
isnot(testScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the test scope");
isnot(loadScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the load scope");
isnot(globalScope.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the global scope");
is(innerScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the inner scope");
is(mathScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the math scope");
is(testScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the test scope");
ok(loadScope.querySelectorAll(".variables-view-property:not([non-match])").length > 1,
"There should be more than one properties displayed in the load scope");
isnot(globalScope.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be some properties displayed in the global scope");
}
var scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
executeSoon(function() {
test1();
executeSoon(function() {
test2();
executeSoon(function() {
test3();
executeSoon(function() {
test4();
executeSoon(function() {
closeDebuggerAndFinish();
});
});
});
});
});
}
function prepareVariables(aCallback)
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 4 Debugger:FetchedVariables events, one from the global object
// scope, two from the |with| scopes and the regular one.
if (++count < 4) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
EventUtils.sendMouseEvent({ type: "mousedown" }, mathScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, testScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, loadScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, globalScope.querySelector(".arrow"), gDebugger);
executeSoon(function() {
aCallback();
});
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee.window);
}
function clear() {
gSearchBox.focus();
gSearchBox.value = "";
}
function write(text) {
clear();
append(text);
}
function backspace(times) {
for (let i = 0; i < times; i++) {
EventUtils.sendKey("BACK_SPACE", gDebugger)
}
}
function append(text) {
gSearchBox.focus();
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gDebuggee = null;
gSearchBox = null;
});

View File

@ -1,249 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly filters nodes.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gDebuggee = null;
var gSearchBox = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = false;
gDebugger.DebuggerView.Variables.delayedSearch = false;
prepareVariables(testVariablesFiltering);
});
}
function testVariablesFiltering()
{
let f = {
test1: function()
{
assertExpansion(1, [true, false, false, false, false]);
clear();
},
test2: function()
{
assertExpansion(2, [true, false, false, false, false]);
EventUtils.sendKey("RETURN", gDebugger);
},
test3: function()
{
assertExpansion(3, [true, false, false, false, false]);
gDebugger.editor.focus();
},
test4: function()
{
assertExpansion(4, [true, false, false, false, false]);
write("*");
},
test5: function() {
assertExpansion(5, [true, true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
test6: function() {
assertExpansion(6, [true, true, true, true, true]);
gDebugger.editor.focus();
},
test7: function() {
assertExpansion(7, [true, true, true, true, true]);
backspace(1);
},
test8: function() {
assertExpansion(8, [true, true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
test9: function() {
assertExpansion(9, [true, true, true, true, true]);
gDebugger.editor.focus();
},
test10: function() {
assertExpansion(10, [true, true, true, true, true]);
innerScopeItem.collapse();
mathScopeItem.collapse();
testScopeItem.collapse();
loadScopeItem.collapse();
globalScopeItem.collapse();
},
test11: function() {
assertExpansion(11, [false, false, false, false, false]);
clear();
},
test12: function() {
assertExpansion(12, [false, false, false, false, false]);
EventUtils.sendKey("RETURN", gDebugger);
},
test13: function() {
assertExpansion(13, [false, false, false, false, false]);
gDebugger.editor.focus();
},
test14: function() {
assertExpansion(14, [false, false, false, false, false]);
write("*");
},
test15: function() {
assertExpansion(15, [true, true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
test16: function() {
assertExpansion(16, [true, true, true, true, true]);
gDebugger.editor.focus();
},
test17: function() {
assertExpansion(17, [true, true, true, true, true]);
backspace(1);
},
test18: function() {
assertExpansion(18, [true, true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
test19: function() {
assertExpansion(19, [true, true, true, true, true]);
gDebugger.editor.focus();
},
test20: function() {
assertExpansion(20, [true, true, true, true, true]);
}
};
function assertExpansion(n, array) {
is(innerScopeItem.expanded, array[0],
"The innerScope should " + (array[0] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(mathScopeItem.expanded, array[1],
"The mathScope should " + (array[1] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(testScopeItem.expanded, array[2],
"The testScope should " + (array[2] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(loadScopeItem.expanded, array[3],
"The loadScope should " + (array[3] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(globalScopeItem.expanded, array[4],
"The globalScope should " + (array[4] ? "" : "not ") +
"be expanded at this point (" + n + ")");
}
var scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
executeSoon(function() {
for (let i = 1; i <= Object.keys(f).length; i++) {
f["test" + i]();
}
closeDebuggerAndFinish();
});
}
function prepareVariables(aCallback)
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 2 Debugger:FetchedVariables events, one from the inner object
// scope and the regular one.
if (++count < 2) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
executeSoon(function() {
aCallback();
});
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee.window);
}
function clear() {
gSearchBox.focus();
gSearchBox.value = "";
}
function write(text) {
clear();
append(text);
}
function backspace(times) {
for (let i = 0; i < times; i++) {
EventUtils.sendKey("BACK_SPACE", gDebugger)
}
}
function append(text) {
gSearchBox.focus();
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gDebuggee = null;
gSearchBox = null;
});

View File

@ -1,324 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly filters nodes.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gDebuggee = null;
var gSearchBox = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.delayedSearch = false;
prepareVariables(testVariablesFiltering);
});
}
function testVariablesFiltering()
{
let f = {
test1: function(aCallback)
{
assertExpansion(1, [true, false, false, false, false]);
write("*arguments");
aCallback();
},
test2: function(aCallback)
{
is(testScopeItem.get("arguments").expanded, false,
"The arguments pseudoarray in the testScope should not be expanded");
is(loadScopeItem.get("arguments").expanded, false,
"The arguments pseudoarray in the testScope should not be expanded");
assertExpansion(1, [true, true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
aCallback();
},
test3: function(aCallback)
{
is(testScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
is(loadScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
waitForFetchedProperties(2, function() {
is(testScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the testScope should have 4 visible properties");
is(loadScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the loadScope should have 4 visible properties");
assertExpansion(2, [true, true, true, true, true]);
backspace(1);
aCallback();
});
},
test4: function(aCallback)
{
is(testScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
is(loadScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
waitForFetchedProperties(0, function() {
is(testScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the testScope should have 4 visible properties");
is(loadScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the loadScope should have 4 visible properties");
assertExpansion(3, [true, true, true, true, true]);
backspace(8);
aCallback();
});
},
test5: function(aCallback)
{
is(testScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
is(loadScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
waitForFetchedProperties(0, function() {
is(testScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the testScope should have 4 visible properties");
is(loadScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the loadScope should have 4 visible properties");
assertExpansion(4, [true, true, true, true, true]);
backspace(1);
aCallback();
});
},
test6: function(aCallback)
{
is(testScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
is(loadScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
waitForFetchedProperties(0, function() {
is(testScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the testScope should have 4 visible properties");
is(loadScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the loadScope should have 4 visible properties");
assertExpansion(5, [true, true, true, true, true]);
write("*");
aCallback();
});
},
test7: function(aCallback)
{
is(testScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
is(loadScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
waitForFetchedProperties(0, function() {
is(testScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the testScope should have 4 visible properties");
is(loadScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"The arguments in the loadScope should have 4 visible properties");
assertExpansion(5, [true, true, true, true, true]);
append("arguments");
aCallback();
});
},
test8: function(aCallback)
{
is(testScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
is(loadScopeItem.get("arguments").expanded, true,
"The arguments pseudoarray in the testScope should now be expanded");
waitForFetchedProperties(0, function() {
is(testScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"The arguments in the testScope should have 0 visible properties");
is(loadScopeItem.get("arguments").target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"The arguments in the loadScope should have 0 visible properties");
assertExpansion(5, [true, true, true, true, true]);
aCallback();
});
},
};
function assertExpansion(n, array) {
is(innerScopeItem.expanded, array[0],
"The innerScope should " + (array[0] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(mathScopeItem.expanded, array[1],
"The mathScope should " + (array[1] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(testScopeItem.expanded, array[2],
"The testScope should " + (array[2] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(loadScopeItem.expanded, array[3],
"The loadScope should " + (array[3] ? "" : "not ") +
"be expanded at this point (" + n + ")");
is(globalScopeItem.expanded, array[4],
"The globalScope should " + (array[4] ? "" : "not ") +
"be expanded at this point (" + n + ")");
}
function waitForFetchedProperties(n, aCallback) {
if (n == 0) {
aCallback();
return;
}
let count = 0;
gDebugger.addEventListener("Debugger:FetchedProperties", function test() {
// We expect n Debugger:FetchedProperties events.
if (++count < n) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedProperties", test, false);
Services.tm.currentThread.dispatch({ run: function() {
executeSoon(aCallback);
}}, 0);
}, false);
}
var scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
executeSoon(function() {
f.test1(function() {
f.test2(function() {
f.test3(function() {
f.test4(function() {
f.test5(function() {
f.test6(function() {
f.test7(function() {
f.test8(function() {
closeDebuggerAndFinish();
});
});
});
});
});
});
});
});
});
}
function prepareVariables(aCallback)
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 2 Debugger:FetchedVariables events, one from the inner object
// scope and the regular one.
if (++count < 2) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
EventUtils.sendMouseEvent({ type: "mousedown" }, mathScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, testScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, loadScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, globalScope.querySelector(".arrow"), gDebugger);
executeSoon(function() {
aCallback();
});
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee.window);
}
function clear() {
gSearchBox.focus();
gSearchBox.value = "";
}
function write(text) {
clear();
append(text);
}
function backspace(times) {
for (let i = 0; i < times; i++) {
EventUtils.sendKey("BACK_SPACE", gDebugger);
}
}
function append(text) {
gSearchBox.focus();
for (let i = 0; i < text.length; i++) {
EventUtils.sendChar(text[i], gDebugger);
}
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gDebuggee = null;
gSearchBox = null;
});

View File

@ -1,394 +0,0 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly re-expands nodes after pauses.
*/
const TAB_URL = EXAMPLE_URL + "browser_dbg_with-frame.html";
var gPane = null;
var gTab = null;
var gDebugger = null;
var gDebuggee = null;
requestLongerTimeout(2);
function test()
{
debug_tab_pane(TAB_URL, function(aTab, aDebuggee, aPane) {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
gDebugger.addEventListener("Debugger:SourceShown", function _onSourceShown() {
gDebugger.removeEventListener("Debugger:SourceShown", _onSourceShown);
addBreakpoint();
});
});
}
function addBreakpoint()
{
gDebugger.DebuggerController.Breakpoints.addBreakpoint({
url: gDebugger.DebuggerView.Sources.selectedValue,
line: 16
}, function(aBreakpointClient, aResponseError) {
ok(!aResponseError, "There shouldn't be an error.");
// Wait for the resume...
gDebugger.gClient.addOneTimeListener("resumed", function() {
gDebugger.DebuggerController.StackFrames.autoScopeExpand = true;
gDebugger.DebuggerView.Variables.nonEnumVisible = false;
gDebugger.DebuggerView.Variables.commitHierarchyIgnoredItems = Object.create(null);
testVariablesExpand();
});
});
}
function testVariablesExpand()
{
let count = 0;
gDebugger.addEventListener("Debugger:FetchedVariables", function test() {
// We expect 4 Debugger:FetchedVariables events, one from the global object
// scope, two from the |with| scopes and the regular one.
if (++count < 4) {
info("Number of received Debugger:FetchedVariables events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedVariables", test, false);
Services.tm.currentThread.dispatch({ run: function() {
var frames = gDebugger.DebuggerView.StackFrames.widget._list,
scopes = gDebugger.DebuggerView.Variables._list,
innerScope = scopes.querySelectorAll(".variables-view-scope")[0],
mathScope = scopes.querySelectorAll(".variables-view-scope")[1],
testScope = scopes.querySelectorAll(".variables-view-scope")[2],
loadScope = scopes.querySelectorAll(".variables-view-scope")[3],
globalScope = scopes.querySelectorAll(".variables-view-scope")[4];
let innerScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
innerScope.querySelector(".name").getAttribute("value"));
let mathScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
mathScope.querySelector(".name").getAttribute("value"));
let testScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
testScope.querySelector(".name").getAttribute("value"));
let loadScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
loadScope.querySelector(".name").getAttribute("value"));
let globalScopeItem = gDebugger.DebuggerView.Variables._currHierarchy.get(
globalScope.querySelector(".name").getAttribute("value"));
is(innerScope.querySelector(".arrow").hasAttribute("open"), true,
"The innerScope arrow should initially be expanded");
is(mathScope.querySelector(".arrow").hasAttribute("open"), true,
"The mathScope arrow should initially be expanded");
is(testScope.querySelector(".arrow").hasAttribute("open"), true,
"The testScope arrow should initially be expanded");
is(loadScope.querySelector(".arrow").hasAttribute("open"), true,
"The loadScope arrow should initially be expanded");
is(globalScope.querySelector(".arrow").hasAttribute("open"), true,
"The globalScope arrow should initially be expanded");
is(innerScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The innerScope enumerables should initially be expanded");
is(mathScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The mathScope enumerables should initially be expanded");
is(testScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The testScope enumerables should initially be expanded");
is(loadScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The loadScope enumerables should initially be expanded");
is(globalScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The globalScope enumerables should initially be expanded");
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
mathScopeItem.collapse();
testScopeItem.collapse();
loadScopeItem.collapse();
globalScopeItem.collapse();
is(innerScope.querySelector(".arrow").hasAttribute("open"), true,
"The innerScope arrow should initially be expanded");
is(mathScope.querySelector(".arrow").hasAttribute("open"), false,
"The mathScope arrow should initially not be expanded");
is(testScope.querySelector(".arrow").hasAttribute("open"), false,
"The testScope arrow should initially not be expanded");
is(loadScope.querySelector(".arrow").hasAttribute("open"), false,
"The loadScope arrow should initially not be expanded");
is(globalScope.querySelector(".arrow").hasAttribute("open"), false,
"The globalScope arrow should initially not be expanded");
is(innerScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The innerScope enumerables should initially be expanded");
is(mathScope.querySelector(".variables-view-element-details").hasAttribute("open"), false,
"The mathScope enumerables should initially not be expanded");
is(testScope.querySelector(".variables-view-element-details").hasAttribute("open"), false,
"The testScope enumerables should initially not be expanded");
is(loadScope.querySelector(".variables-view-element-details").hasAttribute("open"), false,
"The loadScope enumerables should initially not be expanded");
is(globalScope.querySelector(".variables-view-element-details").hasAttribute("open"), false,
"The globalScope enumerables should initially not be expanded");
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, false,
"The mathScope expanded getter should return false");
is(testScopeItem.expanded, false,
"The testScope expanded getter should return false");
is(loadScopeItem.expanded, false,
"The loadScope expanded getter should return false");
is(globalScopeItem.expanded, false,
"The globalScope expanded getter should return false");
EventUtils.sendMouseEvent({ type: "mousedown" }, mathScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, testScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, loadScope.querySelector(".arrow"), gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" }, globalScope.querySelector(".arrow"), gDebugger);
is(innerScope.querySelector(".arrow").hasAttribute("open"), true,
"The innerScope arrow should now be expanded");
is(mathScope.querySelector(".arrow").hasAttribute("open"), true,
"The mathScope arrow should now be expanded");
is(testScope.querySelector(".arrow").hasAttribute("open"), true,
"The testScope arrow should now be expanded");
is(loadScope.querySelector(".arrow").hasAttribute("open"), true,
"The loadScope arrow should now be expanded");
is(globalScope.querySelector(".arrow").hasAttribute("open"), true,
"The globalScope arrow should now be expanded");
is(innerScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The innerScope enumerables should now be expanded");
is(mathScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The mathScope enumerables should now be expanded");
is(testScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The testScope enumerables should now be expanded");
is(loadScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The loadScope enumerables should now be expanded");
is(globalScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The globalScope enumerables should now be expanded");
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
let thisItem = innerScopeItem.get("this");
is(thisItem.expanded, false,
"The local scope 'this' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test2() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test2, false);
Services.tm.currentThread.dispatch({ run: function() {
let windowItem = thisItem.get("window");
is(windowItem.expanded, false,
"The local scope 'this.window' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test3() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test3, false);
Services.tm.currentThread.dispatch({ run: function() {
let documentItem = windowItem.get("document");
is(documentItem.expanded, false,
"The local scope 'this.window.document' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test4() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test4, false);
Services.tm.currentThread.dispatch({ run: function() {
let locationItem = documentItem.get("location");
is(locationItem.expanded, false,
"The local scope 'this.window.document.location' should not be expanded yet");
gDebugger.addEventListener("Debugger:FetchedProperties", function test5() {
gDebugger.removeEventListener("Debugger:FetchedProperties", test5, false);
Services.tm.currentThread.dispatch({ run: function() {
is(thisItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The thisItem arrow should still be expanded (1)");
is(windowItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The windowItem arrow should still be expanded (1)");
is(documentItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The documentItem arrow should still be expanded (1)");
is(locationItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The locationItem arrow should still be expanded (1)");
is(thisItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The thisItem enumerables should still be expanded (1)");
is(windowItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The windowItem enumerables should still be expanded (1)");
is(documentItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The documentItem enumerables should still be expanded (1)");
is(locationItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The locationItem enumerables should still be expanded (1)");
is(thisItem.expanded, true,
"The local scope 'this' should still be expanded (1)");
is(windowItem.expanded, true,
"The local scope 'this.window' should still be expanded (1)");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should still be expanded (1)");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should still be expanded (1)");
let count = 0;
gDebugger.addEventListener("Debugger:FetchedProperties", function test6() {
// We expect 4 Debugger:FetchedProperties events, one from the this
// reference, one for window, one for document and one for location.
if (++count < 4) {
info("Number of received Debugger:FetchedProperties events: " + count);
return;
}
gDebugger.removeEventListener("Debugger:FetchedProperties", test6, false);
Services.tm.currentThread.dispatch({ run: function() {
is(innerScope.querySelector(".arrow").hasAttribute("open"), true,
"The innerScope arrow should still be expanded");
is(mathScope.querySelector(".arrow").hasAttribute("open"), true,
"The mathScope arrow should still be expanded");
is(testScope.querySelector(".arrow").hasAttribute("open"), true,
"The testScope arrow should still be expanded");
is(loadScope.querySelector(".arrow").hasAttribute("open"), true,
"The loadScope arrow should still be expanded");
is(globalScope.querySelector(".arrow").hasAttribute("open"), true,
"The globalScope arrow should still be expanded");
is(innerScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The innerScope enumerables should still be expanded");
is(mathScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The mathScope enumerables should still be expanded");
is(testScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The testScope enumerables should still be expanded");
is(loadScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The loadScope enumerables should still be expanded");
is(globalScope.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The globalScope enumerables should still be expanded");
is(innerScopeItem.expanded, true,
"The innerScope expanded getter should return true");
is(mathScopeItem.expanded, true,
"The mathScope expanded getter should return true");
is(testScopeItem.expanded, true,
"The testScope expanded getter should return true");
is(loadScopeItem.expanded, true,
"The loadScope expanded getter should return true");
is(globalScopeItem.expanded, true,
"The globalScope expanded getter should return true");
is(thisItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The thisItem arrow should still be expanded (2)");
is(windowItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The windowItem arrow should still be expanded (2)");
is(documentItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The documentItem arrow should still be expanded (2)");
is(locationItem.target.querySelector(".arrow").hasAttribute("open"), true,
"The locationItem arrow should still be expanded (2)");
is(thisItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The thisItem enumerables should still be expanded (2)");
is(windowItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The windowItem enumerables should still be expanded (2)");
is(documentItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The documentItem enumerables should still be expanded (2)");
is(locationItem.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The locationItem enumerables should still be expanded (2)");
is(thisItem.expanded, true,
"The local scope 'this' should still be expanded (2)");
is(windowItem.expanded, true,
"The local scope 'this.window' should still be expanded (2)");
is(documentItem.expanded, true,
"The local scope 'this.window.document' should still be expanded (2)");
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should still be expanded (2)");
executeSoon(function() {
closeDebuggerAndFinish();
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
gDebugger.document.querySelector("#step-in"),
gDebugger);
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
locationItem.target.querySelector(".arrow"),
gDebugger);
is(locationItem.expanded, true,
"The local scope 'this.window.document.location' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
documentItem.target.querySelector(".arrow"),
gDebugger);
is(documentItem.expanded, true,
"The local scope 'this.window.document' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
windowItem.target.querySelector(".arrow"),
gDebugger);
is(windowItem.expanded, true,
"The local scope 'this.window' should be expanded now");
});
}}, 0);
}, false);
executeSoon(function() {
EventUtils.sendMouseEvent({ type: "mousedown" },
thisItem.target.querySelector(".arrow"),
gDebugger);
is(thisItem.expanded, true,
"The local scope 'this' should be expanded now");
});
}}, 0);
}, false);
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee.window);
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebugger = null;
gDebuggee = null;
});

View File

@ -0,0 +1,119 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that creating, collpasing and expanding scopes in the
* variables view works as expected.
*/
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");
ok(testScope,
"Should have created a scope.");
ok(testScope.id.contains("test"),
"The newly created scope should have the default id set.");
is(testScope.name, "test",
"The newly created scope should have the desired name set.");
ok(!testScope.displayValue,
"The newly created scope should not have a displayed value (1).");
ok(!testScope.displayValueClassName,
"The newly created scope should not have a displayed value (2).");
ok(testScope.target,
"The newly created scope should point to a target node.");
ok(testScope.target.id.contains("test"),
"Should have the correct scope id on the element.");
is(testScope.target.querySelector(".name").getAttribute("value"), "test",
"Any new scope should have the designated name.");
is(testScope.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"Any new scope should have a container with no enumerable child nodes.");
is(testScope.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"Any new scope should have a container with no non-enumerable child nodes.");
ok(!testScope.expanded,
"Any new created scope should be initially collapsed.");
ok(testScope.visible,
"Any new created scope should be initially visible.");
let expandCallbackArg = null;
let collapseCallbackArg = null;
let toggleCallbackArg = null;
let hideCallbackArg = null;
let showCallbackArg = null;
testScope.onexpand = aScope => expandCallbackArg = aScope;
testScope.oncollapse = aScope => collapseCallbackArg = aScope;
testScope.ontoggle = aScope => toggleCallbackArg = aScope;
testScope.onhide = aScope => hideCallbackArg = aScope;
testScope.onshow = aScope => showCallbackArg = aScope;
testScope.expand();
ok(testScope.expanded,
"The testScope shouldn't be collapsed anymore.");
is(expandCallbackArg, testScope,
"The expandCallback wasn't called as it should.");
testScope.collapse();
ok(!testScope.expanded,
"The testScope should be collapsed again.");
is(collapseCallbackArg, testScope,
"The collapseCallback wasn't called as it should.");
testScope.expanded = true;
ok(testScope.expanded,
"The testScope shouldn't be collapsed anymore.");
testScope.toggle();
ok(!testScope.expanded,
"The testScope should be collapsed again.");
is(toggleCallbackArg, testScope,
"The toggleCallback wasn't called as it should.");
testScope.hide();
ok(!testScope.visible,
"The testScope should be invisible after hiding.");
is(hideCallbackArg, testScope,
"The hideCallback wasn't called as it should.");
testScope.show();
ok(testScope.visible,
"The testScope should be visible again.");
is(showCallbackArg, testScope,
"The showCallback wasn't called as it should.");
testScope.visible = false;
ok(!testScope.visible,
"The testScope should be invisible after hiding.");
ok(!testScope.expanded,
"The testScope should remember it is collapsed even if it is hidden.");
testScope.visible = true;
ok(testScope.visible,
"The testScope should be visible after reshowing.");
ok(!testScope.expanded,
"The testScope should remember it is collapsed after it is reshown.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testScope.target.querySelector(".title"),
aPanel.panelWin);
ok(testScope.expanded,
"Clicking the testScope tilte should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testScope.target.querySelector(".title"),
aPanel.panelWin);
ok(!testScope.expanded,
"Clicking again the testScope tilte should collapse it.");
closeDebuggerAndFinish(aPanel);
});
}

View File

@ -0,0 +1,221 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that creating, collpasing and expanding variables in the
* variables view works as expected.
*/
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");
let testVar = testScope.addItem("something");
let duplVar = testScope.addItem("something");
info("Scope id: " + testScope.id);
info("Scope name: " + testScope.name);
info("Variable id: " + testVar.id);
info("Variable name: " + testVar.name);
ok(testScope,
"Should have created a scope.");
is(duplVar, null,
"Shouldn't be able to duplicate variables in the same scope.");
ok(testVar,
"Should have created a variable.");
ok(testVar.id.contains("something"),
"The newly created variable should have the default id set.");
is(testVar.name, "something",
"The newly created variable should have the desired name set.");
ok(!testVar.displayValue,
"The newly created variable should not have a displayed value yet (1).");
ok(!testVar.displayValueClassName,
"The newly created variable should not have a displayed value yet (2).");
ok(testVar.target,
"The newly created scope should point to a target node.");
ok(testVar.target.id.contains("something"),
"Should have the correct variable id on the element.");
is(testVar.target.querySelector(".name").getAttribute("value"), "something",
"Any new variable should have the designated name.");
is(testVar.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"Any new variable should have a container with no enumerable child nodes.");
is(testVar.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"Any new variable should have a container with no non-enumerable child nodes.");
ok(!testVar.expanded,
"Any new created scope should be initially collapsed.");
ok(testVar.visible,
"Any new created scope should be initially visible.");
let expandCallbackArg = null;
let collapseCallbackArg = null;
let toggleCallbackArg = null;
let hideCallbackArg = null;
let showCallbackArg = null;
testVar.onexpand = aScope => expandCallbackArg = aScope;
testVar.oncollapse = aScope => collapseCallbackArg = aScope;
testVar.ontoggle = aScope => toggleCallbackArg = aScope;
testVar.onhide = aScope => hideCallbackArg = aScope;
testVar.onshow = aScope => showCallbackArg = aScope;
testVar.expand();
ok(testVar.expanded,
"The testVar shouldn't be collapsed anymore.");
is(expandCallbackArg, testVar,
"The expandCallback wasn't called as it should.");
testVar.collapse();
ok(!testVar.expanded,
"The testVar should be collapsed again.");
is(collapseCallbackArg, testVar,
"The collapseCallback wasn't called as it should.");
testVar.expanded = true;
ok(testVar.expanded,
"The testVar shouldn't be collapsed anymore.");
testVar.toggle();
ok(!testVar.expanded,
"The testVar should be collapsed again.");
is(toggleCallbackArg, testVar,
"The toggleCallback wasn't called as it should.");
testVar.hide();
ok(!testVar.visible,
"The testVar should be invisible after hiding.");
is(hideCallbackArg, testVar,
"The hideCallback wasn't called as it should.");
testVar.show();
ok(testVar.visible,
"The testVar should be visible again.");
is(showCallbackArg, testVar,
"The showCallback wasn't called as it should.");
testVar.visible = false;
ok(!testVar.visible,
"The testVar should be invisible after hiding.");
ok(!testVar.expanded,
"The testVar should remember it is collapsed even if it is hidden.");
testVar.visible = true;
ok(testVar.visible,
"The testVar should be visible after reshowing.");
ok(!testVar.expanded,
"The testVar should remember it is collapsed after it is reshown.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".name"),
aPanel.panelWin);
ok(testVar.expanded,
"Clicking the testVar name should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".name"),
aPanel.panelWin);
ok(!testVar.expanded,
"Clicking again the testVar name should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".arrow"),
aPanel.panelWin);
ok(testVar.expanded,
"Clicking the testVar arrow should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".arrow"),
aPanel.panelWin);
ok(!testVar.expanded,
"Clicking again the testVar arrow should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testVar.target.querySelector(".title"),
aPanel.panelWin);
ok(testVar.expanded,
"Clicking the testVar title should expand it again.");
testVar.addItem("child", {
value: {
type: "object",
class: "Object"
}
});
let testChild = testVar.get("child");
ok(testChild,
"Should have created a child property.");
ok(testChild.id.contains("child"),
"The newly created property should have the default id set.");
is(testChild.name, "child",
"The newly created property should have the desired name set.");
is(testChild.displayValue, "Object",
"The newly created property should not have a displayed value yet (1).");
is(testChild.displayValueClassName, "token-other",
"The newly created property should not have a displayed value yet (2).");
ok(testChild.target,
"The newly created scope should point to a target node.");
ok(testChild.target.id.contains("child"),
"Should have the correct property id on the element.");
is(testChild.target.querySelector(".name").getAttribute("value"), "child",
"Any new property should have the designated name.");
is(testChild.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"Any new property should have a container with no enumerable child nodes.");
is(testChild.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"Any new property should have a container with no non-enumerable child nodes.");
ok(!testChild.expanded,
"Any new created scope should be initially collapsed.");
ok(testChild.visible,
"Any new created scope should be initially visible.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testChild.target.querySelector(".name"),
aPanel.panelWin);
ok(testChild.expanded,
"Clicking the testChild name should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testChild.target.querySelector(".name"),
aPanel.panelWin);
ok(!testChild.expanded,
"Clicking again the testChild name should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testChild.target.querySelector(".arrow"),
aPanel.panelWin);
ok(testChild.expanded,
"Clicking the testChild arrow should expand it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testChild.target.querySelector(".arrow"),
aPanel.panelWin);
ok(!testChild.expanded,
"Clicking again the testChild arrow should collapse it.");
EventUtils.sendMouseEvent({ type: "mousedown" },
testChild.target.querySelector(".title"),
aPanel.panelWin);
closeDebuggerAndFinish(aPanel);
});
}

View File

@ -0,0 +1,151 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that recursively creating properties in the variables view works
* as expected.
*/
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");
is(testScope.target.querySelectorAll(".variables-view-element-details.enum").length, 1,
"One enumerable container should be present in the scope.");
is(testScope.target.querySelectorAll(".variables-view-element-details.nonenum").length, 1,
"One non-enumerable container should be present in the scope.");
is(testScope.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"No enumerable variables should be present in the scope.");
is(testScope.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No non-enumerable variables should be present in the scope.");
testScope.addItem("something", {
value: {
type: "object",
class: "Object"
},
enumerable: true
});
is(testScope.target.querySelectorAll(".variables-view-element-details.enum").length, 2,
"Two enumerable containers should be present in the tree.");
is(testScope.target.querySelectorAll(".variables-view-element-details.nonenum").length, 2,
"Two non-enumerable containers should be present in the tree.");
is(testScope.target.querySelector(".variables-view-element-details.enum").childNodes.length, 1,
"A new enumerable variable should have been added in the scope.");
is(testScope.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No new non-enumerable variables should have been added in the scope.");
let testVar = testScope.get("something");
ok(testVar,
"The added variable should be accessible from the scope.");
is(testVar.target.querySelectorAll(".variables-view-element-details.enum").length, 1,
"One enumerable container should be present in the variable.");
is(testVar.target.querySelectorAll(".variables-view-element-details.nonenum").length, 1,
"One non-enumerable container should be present in the variable.");
is(testVar.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"No enumerable properties should be present in the variable.");
is(testVar.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No non-enumerable properties should be present in the variable.");
testVar.addItem("child", {
value: {
type: "object",
class: "Object"
},
enumerable: true
});
is(testScope.target.querySelectorAll(".variables-view-element-details.enum").length, 3,
"Three enumerable containers should be present in the tree.");
is(testScope.target.querySelectorAll(".variables-view-element-details.nonenum").length, 3,
"Three non-enumerable containers should be present in the tree.");
is(testVar.target.querySelector(".variables-view-element-details.enum").childNodes.length, 1,
"A new enumerable property should have been added in the variable.");
is(testVar.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No new non-enumerable properties should have been added in the variable.");
let testChild = testVar.get("child");
ok(testChild,
"The added property should be accessible from the variable.");
is(testChild.target.querySelectorAll(".variables-view-element-details.enum").length, 1,
"One enumerable container should be present in the property.");
is(testChild.target.querySelectorAll(".variables-view-element-details.nonenum").length, 1,
"One non-enumerable container should be present in the property.");
is(testChild.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"No enumerable sub-properties should be present in the property.");
is(testChild.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No non-enumerable sub-properties should be present in the property.");
testChild.addItem("grandChild", {
value: {
type: "object",
class: "Object"
},
enumerable: true
});
is(testScope.target.querySelectorAll(".variables-view-element-details.enum").length, 4,
"Four enumerable containers should be present in the tree.");
is(testScope.target.querySelectorAll(".variables-view-element-details.nonenum").length, 4,
"Four non-enumerable containers should be present in the tree.");
is(testChild.target.querySelector(".variables-view-element-details.enum").childNodes.length, 1,
"A new enumerable sub-property should have been added in the property.");
is(testChild.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No new non-enumerable sub-properties should have been added in the property.");
let testGrandChild = testChild.get("grandChild");
ok(testGrandChild,
"The added sub-property should be accessible from the property.");
is(testGrandChild.target.querySelectorAll(".variables-view-element-details.enum").length, 1,
"One enumerable container should be present in the property.");
is(testGrandChild.target.querySelectorAll(".variables-view-element-details.nonenum").length, 1,
"One non-enumerable container should be present in the property.");
is(testGrandChild.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"No enumerable sub-properties should be present in the property.");
is(testGrandChild.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No non-enumerable sub-properties should be present in the property.");
testGrandChild.addItem("granderChild", {
value: {
type: "object",
class: "Object"
},
enumerable: true
});
is(testScope.target.querySelectorAll(".variables-view-element-details.enum").length, 5,
"Five enumerable containers should be present in the tree.");
is(testScope.target.querySelectorAll(".variables-view-element-details.nonenum").length, 5,
"Five non-enumerable containers should be present in the tree.");
is(testGrandChild.target.querySelector(".variables-view-element-details.enum").childNodes.length, 1,
"A new enumerable variable should have been added in the variable.");
is(testGrandChild.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No new non-enumerable variables should have been added in the variable.");
let testGranderChild = testGrandChild.get("granderChild");
ok(testGranderChild,
"The added sub-property should be accessible from the property.");
is(testGranderChild.target.querySelectorAll(".variables-view-element-details.enum").length, 1,
"One enumerable container should be present in the property.");
is(testGranderChild.target.querySelectorAll(".variables-view-element-details.nonenum").length, 1,
"One non-enumerable container should be present in the property.");
is(testGranderChild.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"No enumerable sub-properties should be present in the property.");
is(testGranderChild.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"No non-enumerable sub-properties should be present in the property.");
closeDebuggerAndFinish(aPanel);
});
}

View File

@ -0,0 +1,112 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that grips are correctly applied to variables.
*/
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let testScope = variables.addScope("test");
let testVar = testScope.addItem("something");
testVar.setGrip(1.618);
is(testVar.target.querySelector(".value").getAttribute("value"), "1.618",
"The grip information for the variable wasn't set correctly (1).");
is(testVar.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"Setting the grip alone shouldn't add any new tree nodes (1).");
is(testVar.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"Setting the grip alone shouldn't add any new tree nodes (2).");
testVar.setGrip({
type: "object",
class: "Window"
});
is(testVar.target.querySelector(".value").getAttribute("value"), "Window",
"The grip information for the variable wasn't set correctly (2).");
is(testVar.target.querySelector(".variables-view-element-details.enum").childNodes.length, 0,
"Setting the grip alone shouldn't add any new tree nodes (3).");
is(testVar.target.querySelector(".variables-view-element-details.nonenum").childNodes.length, 0,
"Setting the grip alone shouldn't add any new tree nodes (4).");
testVar.addItems({
helloWorld: {
value: "hello world",
enumerable: true
}
});
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 1,
"A new detail node should have been added in the variable tree.");
is(testVar.get("helloWorld").target.querySelector(".value").getAttribute("value"), "\"hello world\"",
"The grip information for the variable wasn't set correctly (3).");
testVar.addItems({
helloWorld: {
value: "hello jupiter",
enumerable: true
}
});
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 1,
"Shouldn't be able to duplicate nodes added in the variable tree.");
is(testVar.get("helloWorld").target.querySelector(".value").getAttribute("value"), "\"hello world\"",
"The grip information for the variable wasn't preserved correctly (4).");
testVar.addItems({
someProp0: {
value: "random string",
enumerable: true
},
someProp1: {
value: "another string",
enumerable: true
}
});
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 3,
"Two new detail nodes should have been added in the variable tree.");
is(testVar.get("someProp0").target.querySelector(".value").getAttribute("value"), "\"random string\"",
"The grip information for the variable wasn't set correctly (5).");
is(testVar.get("someProp1").target.querySelector(".value").getAttribute("value"), "\"another string\"",
"The grip information for the variable wasn't set correctly (6).");
testVar.addItems({
someProp2: {
value: {
type: "null"
},
enumerable: true
},
someProp3: {
value: {
type: "undefined"
},
enumerable: true
},
someProp4: {
value: {
type: "object",
class: "Object"
},
enumerable: true
}
});
is(testVar.target.querySelector(".variables-view-element-details").childNodes.length, 6,
"Three new detail nodes should have been added in the variable tree.");
is(testVar.get("someProp2").target.querySelector(".value").getAttribute("value"), "null",
"The grip information for the variable wasn't set correctly (7).");
is(testVar.get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the variable wasn't set correctly (8).");
is(testVar.get("someProp4").target.querySelector(".value").getAttribute("value"), "Object",
"The grip information for the variable wasn't set correctly (9).");
closeDebuggerAndFinish(aPanel);
});
}

View File

@ -0,0 +1,208 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Tests that grips are correctly applied to variables and properties.
*/
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
let variables = aPanel.panelWin.DebuggerView.Variables;
let globalScope = variables.addScope("Test-Global");
let localScope = variables.addScope("Test-Local");
ok(globalScope, "The globalScope hasn't been created correctly.");
ok(localScope, "The localScope hasn't been created correctly.");
let windowVar = globalScope.addItem("window");
let documentVar = globalScope.addItem("document");
ok(windowVar, "The windowVar hasn't been created correctly.");
ok(documentVar, "The documentVar hasn't been created correctly.");
windowVar.setGrip({ type: "object", class: "Window" });
documentVar.setGrip({ type: "object", class: "HTMLDocument" });
let localVar0 = localScope.addItem("localVar0");
let localVar1 = localScope.addItem("localVar1");
let localVar2 = localScope.addItem("localVar2");
let localVar3 = localScope.addItem("localVar3");
let localVar4 = localScope.addItem("localVar4");
let localVar5 = localScope.addItem("localVar5");
let localVar6 = localScope.addItem("localVar6");
let localVar7 = localScope.addItem("localVar7");
let localVar8 = localScope.addItem("localVar8");
let localVar9 = localScope.addItem("localVar9");
ok(localVar0, "The localVar0 hasn't been created correctly.");
ok(localVar1, "The localVar1 hasn't been created correctly.");
ok(localVar2, "The localVar2 hasn't been created correctly.");
ok(localVar3, "The localVar3 hasn't been created correctly.");
ok(localVar4, "The localVar4 hasn't been created correctly.");
ok(localVar5, "The localVar5 hasn't been created correctly.");
ok(localVar6, "The localVar6 hasn't been created correctly.");
ok(localVar7, "The localVar7 hasn't been created correctly.");
ok(localVar8, "The localVar8 hasn't been created correctly.");
ok(localVar9, "The localVar9 hasn't been created correctly.");
localVar0.setGrip(42);
localVar1.setGrip(true);
localVar2.setGrip("nasu");
localVar3.setGrip({ type: "undefined" });
localVar4.setGrip({ type: "null" });
localVar5.setGrip({ type: "object", class: "Object" });
localVar6.setGrip({ type: "Infinity" });
localVar7.setGrip({ type: "-Infinity" });
localVar8.setGrip({ type: "NaN" });
localVar9.setGrip({ type: "-0" });
localVar5.addItems({
someProp0: { value: 42, enumerable: true },
someProp1: { value: true, enumerable: true },
someProp2: { value: "nasu", enumerable: true },
someProp3: { value: { type: "undefined" }, enumerable: true },
someProp4: { value: { type: "null" }, enumerable: true },
someProp5: { value: { type: "object", class: "Object" }, enumerable: true },
someProp6: { value: { type: "Infinity" }, enumerable: true },
someProp7: { value: { type: "-Infinity" }, enumerable: true },
someProp8: { value: { type: "NaN" }, enumerable: true },
someProp9: { value: { type: "-0" }, enumerable: true },
someUndefined: {
get: { type: "undefined" },
set: { type: "undefined" },
enumerable: true
},
someAccessor: {
get: { type: "object", class: "Function" },
set: { type: "undefined" },
enumerable: true
}
});
localVar5.get("someProp5").addItems({
someProp0: { value: 42, enumerable: true },
someProp1: { value: true, enumerable: true },
someProp2: { value: "nasu", enumerable: true },
someProp3: { value: { type: "undefined" }, enumerable: true },
someProp4: { value: { type: "null" }, enumerable: true },
someProp5: { value: { type: "object", class: "Object" }, enumerable: true },
someProp6: { value: { type: "Infinity" }, enumerable: true },
someProp7: { value: { type: "-Infinity" }, enumerable: true },
someProp8: { value: { type: "NaN" }, enumerable: true },
someProp9: { value: { type: "-0" }, enumerable: true },
someUndefined: {
get: { type: "undefined" },
set: { type: "undefined" },
enumerable: true
},
someAccessor: {
get: { type: "object", class: "Function" },
set: { type: "undefined" },
enumerable: true
}
});
is(globalScope.target.querySelector(".enum").childNodes.length, 0,
"The globalScope doesn't contain all the created enumerable variable elements.");
is(globalScope.target.querySelector(".nonenum").childNodes.length, 2,
"The globalScope doesn't contain all the created non-enumerable variable elements.");
is(localScope.target.querySelector(".enum").childNodes.length, 0,
"The localScope doesn't contain all the created enumerable variable elements.");
is(localScope.target.querySelector(".nonenum").childNodes.length, 10,
"The localScope doesn't contain all the created non-enumerable variable elements.");
is(localVar5.target.querySelector(".enum").childNodes.length, 12,
"The localVar5 doesn't contain all the created enumerable properties.");
is(localVar5.target.querySelector(".nonenum").childNodes.length, 0,
"The localVar5 doesn't contain all the created non-enumerable properties.");
is(localVar5.get("someProp5").target.querySelector(".enum").childNodes.length, 12,
"The localVar5.someProp5 doesn't contain all the created enumerable properties.");
is(localVar5.get("someProp5").target.querySelector(".nonenum").childNodes.length, 0,
"The localVar5.someProp5 doesn't contain all the created non-enumerable properties.");
is(windowVar.target.querySelector(".value").getAttribute("value"), "Window",
"The grip information for the windowVar wasn't set correctly.");
is(documentVar.target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"The grip information for the documentVar wasn't set correctly.");
is(localVar0.target.querySelector(".value").getAttribute("value"), "42",
"The grip information for the localVar0 wasn't set correctly.");
is(localVar1.target.querySelector(".value").getAttribute("value"), "true",
"The grip information for the localVar1 wasn't set correctly.");
is(localVar2.target.querySelector(".value").getAttribute("value"), "\"nasu\"",
"The grip information for the localVar2 wasn't set correctly.");
is(localVar3.target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the localVar3 wasn't set correctly.");
is(localVar4.target.querySelector(".value").getAttribute("value"), "null",
"The grip information for the localVar4 wasn't set correctly.");
is(localVar5.target.querySelector(".value").getAttribute("value"), "Object",
"The grip information for the localVar5 wasn't set correctly.");
is(localVar6.target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the localVar6 wasn't set correctly.");
is(localVar7.target.querySelector(".value").getAttribute("value"), "-Infinity",
"The grip information for the localVar7 wasn't set correctly.");
is(localVar8.target.querySelector(".value").getAttribute("value"), "NaN",
"The grip information for the localVar8 wasn't set correctly.");
is(localVar9.target.querySelector(".value").getAttribute("value"), "-0",
"The grip information for the localVar9 wasn't set correctly.");
is(localVar5.get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
"The grip information for the someProp0 wasn't set correctly.");
is(localVar5.get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
"The grip information for the someProp1 wasn't set correctly.");
is(localVar5.get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
"The grip information for the someProp2 wasn't set correctly.");
is(localVar5.get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the someProp3 wasn't set correctly.");
is(localVar5.get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
"The grip information for the someProp4 wasn't set correctly.");
is(localVar5.get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
"The grip information for the someProp5 wasn't set correctly.");
is(localVar5.get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the someProp6 wasn't set correctly.");
is(localVar5.get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
"The grip information for the someProp7 wasn't set correctly.");
is(localVar5.get("someProp8").target.querySelector(".value").getAttribute("value"), "NaN",
"The grip information for the someProp8 wasn't set correctly.");
is(localVar5.get("someProp9").target.querySelector(".value").getAttribute("value"), "-0",
"The grip information for the someProp9 wasn't set correctly.");
is(localVar5.get("someUndefined").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the someUndefined wasn't set correctly.");
is(localVar5.get("someAccessor").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the someAccessor wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp0").target.querySelector(".value").getAttribute("value"), "42",
"The grip information for the sub-someProp0 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp1").target.querySelector(".value").getAttribute("value"), "true",
"The grip information for the sub-someProp1 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp2").target.querySelector(".value").getAttribute("value"), "\"nasu\"",
"The grip information for the sub-someProp2 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp3").target.querySelector(".value").getAttribute("value"), "undefined",
"The grip information for the sub-someProp3 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp4").target.querySelector(".value").getAttribute("value"), "null",
"The grip information for the sub-someProp4 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp5").target.querySelector(".value").getAttribute("value"), "Object",
"The grip information for the sub-someProp5 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp6").target.querySelector(".value").getAttribute("value"), "Infinity",
"The grip information for the sub-someProp6 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp7").target.querySelector(".value").getAttribute("value"), "-Infinity",
"The grip information for the sub-someProp7 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp8").target.querySelector(".value").getAttribute("value"), "NaN",
"The grip information for the sub-someProp8 wasn't set correctly.");
is(localVar5.get("someProp5").get("someProp9").target.querySelector(".value").getAttribute("value"), "-0",
"The grip information for the sub-someProp9 wasn't set correctly.");
is(localVar5.get("someProp5").get("someUndefined").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the sub-someUndefined wasn't set correctly.");
is(localVar5.get("someProp5").get("someAccessor").target.querySelector(".value").getAttribute("value"), "",
"The grip information for the sub-someAccessor wasn't set correctly.");
closeDebuggerAndFinish(aPanel);
});
}

View File

@ -0,0 +1,488 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view is keyboard accessible.
*/
let gTab, gDebuggee, gPanel, gDebugger;
let gVariablesView;
function test() {
initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariablesView = gDebugger.DebuggerView.Variables;
performTest().then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
}
function performTest() {
let arr = [
42,
true,
"nasu",
undefined,
null,
[0, 1, 2],
{ prop1: 9, prop2: 8 }
];
let obj = {
p0: 42,
p1: true,
p2: "nasu",
p3: undefined,
p4: null,
p5: [3, 4, 5],
p6: { prop1: 7, prop2: 6 },
get p7() { return arr; },
set p8(value) { arr[0] = value }
};
let test = {
someProp0: 42,
someProp1: true,
someProp2: "nasu",
someProp3: undefined,
someProp4: null,
someProp5: arr,
someProp6: obj,
get someProp7() { return arr; },
set someProp7(value) { arr[0] = value }
};
gVariablesView.eval = function() {};
gVariablesView.switch = function() {};
gVariablesView.delete = function() {};
gVariablesView.rawObject = test;
gVariablesView.pageSize = 5;
return Task.spawn(function() {
yield waitForTick();
// Part 0: Test generic focus methods on the variables view.
gVariablesView.focusFirstVisibleItem();
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
gVariablesView.focusNextItem();
is(gVariablesView.getFocusedItem().name, "someProp1",
"The 'someProp1' item should be focused.");
gVariablesView.focusPrevItem();
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
// Part 1: Make sure that UP/DOWN keys don't scroll the variables view.
yield synthesizeKeyAndWaitForTick("VK_DOWN", {});
is(gVariablesView._parent.scrollTop, 0,
"The 'variables' view shouldn't scroll when pressing the DOWN key.");
yield synthesizeKeyAndWaitForTick("VK_UP", {});
is(gVariablesView._parent.scrollTop, 0,
"The 'variables' view shouldn't scroll when pressing the UP key.");
// Part 2: Make sure that ENTER/ESCAPE toggle input elements.
yield synthesizeKeyAndWaitForElement("VK_ENTER", {}, ".element-value-input", true);
yield synthesizeKeyAndWaitForElement("VK_ESCAPE", {}, ".element-value-input", false);
yield synthesizeKeyAndWaitForElement("VK_ENTER", { shiftKey: true }, ".element-name-input", true);
yield synthesizeKeyAndWaitForElement("VK_ESCAPE", {}, ".element-name-input", false);
// Part 3: Test simple navigation.
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp1",
"The 'someProp1' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("HOME", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
// Part 4: Test if pressing the same navigation key twice works as expected.
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp1",
"The 'someProp1' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp2",
"The 'someProp2' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp1",
"The 'someProp1' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
// Part 5: Test that HOME/PAGE_UP/PAGE_DOWN are symmetrical.
EventUtils.sendKey("HOME", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("HOME", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("HOME", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
// Part 6: Test that focus doesn't leave the variables view.
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
// Part 7: Test that random offsets don't occur in tandem with HOME/END.
EventUtils.sendKey("HOME", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp1",
"The 'someProp1' item should be focused.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
// Part 8: Test that the RIGHT key expands elements as intended.
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The 'someProp5' item should not be expanded yet.");
yield synthesizeKeyAndWaitForTick("VK_RIGHT", {});
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
is(gVariablesView.getFocusedItem().expanded, true,
"The 'someProp5' item should now be expanded.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "0",
"The '0' item should be focused.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "0",
"The '0' item should still be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "5",
"The '5' item should be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The '5' item should not be expanded yet.");
yield synthesizeKeyAndWaitForTick("VK_RIGHT", {});
is(gVariablesView.getFocusedItem().name, "5",
"The '5' item should be focused.");
is(gVariablesView.getFocusedItem().expanded, true,
"The '5' item should now be expanded.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "0",
"The '0' item should be focused.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "0",
"The '0' item should still be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "6",
"The '6' item should be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The '6' item should not be expanded yet.");
// Part 9: Test that the RIGHT key collapses elements as intended.
EventUtils.sendKey("DOWN", gDebugger);
EventUtils.sendKey("DOWN", gDebugger);
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp6",
"The 'someProp6' item should be focused.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp6",
"The 'someProp6' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
is(gVariablesView.getFocusedItem().expanded, true,
"The '6' item should still be expanded.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should still be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The '6' item should still not be expanded anymore.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should still be focused.");
// Part 9: Test continuous navigation.
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp4",
"The 'someProp4' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp3",
"The 'someProp3' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp2",
"The 'someProp2' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp1",
"The 'someProp1' item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The 'someProp0' item should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The 'someProp5' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp6",
"The 'someProp6' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp7",
"The 'someProp7' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "get",
"The 'get' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "set",
"The 'set' item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' item should be focused.");
// Part 10: Test that BACKSPACE deletes items in the variables view.
EventUtils.sendKey("BACK_SPACE", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The '__proto__' variable should still be focused.");
is(gVariablesView.getFocusedItem().value, "[object Object]",
"The '__proto__' variable should not have an empty value.");
is(gVariablesView.getFocusedItem().visible, false,
"The '__proto__' variable should be hidden.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "set",
"The 'set' item should be focused.");
is(gVariablesView.getFocusedItem().value, "[object Object]",
"The 'set' item should not have an empty value.");
is(gVariablesView.getFocusedItem().visible, true,
"The 'set' item should be visible.");
EventUtils.sendKey("BACK_SPACE", gDebugger);
is(gVariablesView.getFocusedItem().name, "set",
"The 'set' item should still be focused.");
is(gVariablesView.getFocusedItem().value, "[object Object]",
"The 'set' item should not have an empty value.");
is(gVariablesView.getFocusedItem().visible, true,
"The 'set' item should be visible.");
is(gVariablesView.getFocusedItem().twisty, false,
"The 'set' item should be disabled and have a hidden twisty.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "get",
"The 'get' item should be focused.");
is(gVariablesView.getFocusedItem().value, "[object Object]",
"The 'get' item should not have an empty value.");
is(gVariablesView.getFocusedItem().visible, true,
"The 'get' item should be visible.");
EventUtils.sendKey("BACK_SPACE", gDebugger);
is(gVariablesView.getFocusedItem().name, "get",
"The 'get' item should still be focused.");
is(gVariablesView.getFocusedItem().value, "[object Object]",
"The 'get' item should not have an empty value.");
is(gVariablesView.getFocusedItem().visible, true,
"The 'get' item should be visible.");
is(gVariablesView.getFocusedItem().twisty, false,
"The 'get' item should be disabled and have a hidden twisty.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp7",
"The 'someProp7' item should be focused.");
is(gVariablesView.getFocusedItem().value, undefined,
"The 'someProp7' variable should have an empty value.");
is(gVariablesView.getFocusedItem().visible, true,
"The 'someProp7' variable should be visible.");
EventUtils.sendKey("BACK_SPACE", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp7",
"The 'someProp7' variable should still be focused.");
is(gVariablesView.getFocusedItem().value, undefined,
"The 'someProp7' variable should have an empty value.");
is(gVariablesView.getFocusedItem().visible, false,
"The 'someProp7' variable should be hidden.");
yield closeDebuggerAndFinish(gPanel);
});
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariablesView = null;
});
function synthesizeKeyAndWaitForElement(aKey, aModifiers, aSelector, aExistence) {
EventUtils.synthesizeKey(aKey, aModifiers, gDebugger);
return waitForElement(aSelector, aExistence);
}
function synthesizeKeyAndWaitForTick(aKey, aModifiers) {
EventUtils.synthesizeKey(aKey, aModifiers, gDebugger);
return waitForTick();
}
function waitForTick() {
let deferred = promise.defer();
executeSoon(deferred.resolve);
return deferred.promise;
}
function waitForElement(aSelector, aExistence, aInterval = 10) {
let deferred = promise.defer();
// Poll every few milliseconds until the element is retrieved.
let count = 0;
let intervalID = window.setInterval(() => {
// Make sure we don't wait for too long.
if (++count > 1000) {
deferred.reject("Timed out while polling for the element.");
window.clearInterval(intervalID);
return;
}
// Check if the existence condition is fulfilled.
if (!!gVariablesView._list.querySelector(aSelector) != aExistence) {
return;
}
// We got the element, it's safe to callback.
window.clearInterval(intervalID);
deferred.resolve();
}, aInterval);
return deferred.promise;
}

View File

@ -1,33 +1,27 @@
/* vim:set ts=2 sw=2 sts=2 et: */
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the property view correctly populates itself.
* Make sure that the variables view correctly populates itself
* when given some raw data.
*/
var gPane = null;
var gTab = null;
var gDebugger = null;
var gVariablesView = null;
var gScope = null;
var gVariable = null;
let gTab, gDebuggee, gPanel, gDebugger;
let gVariablesView, gScope, gVariable;
function test()
{
debug_tab_pane(TAB1_URL, function(aTab, aDebuggee, aPane) {
function test() {
initDebugger("about:blank").then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gPane = aPane;
gDebugger = gPane.panelWin;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariablesView = gDebugger.DebuggerView.Variables;
gDebugger.DebuggerView.toggleInstrumentsPane({ visible: true, animated: false });
testVariablesView();
performTest();
});
}
function testVariablesView()
{
function performTest() {
let arr = [
42,
true,
@ -39,13 +33,13 @@ function testVariablesView()
];
let obj = {
"p0": 42,
"p1": true,
"p2": "nasu",
"p3": undefined,
"p4": null,
"p5": [3, 4, 5],
"p6": { prop1: 7, prop2: 6 },
p0: 42,
p1: true,
p2: "nasu",
p3: undefined,
p4: null,
p5: [3, 4, 5],
p6: { prop1: 7, prop2: 6 },
get p7() { return arr; },
set p8(value) { arr[0] = value }
};
@ -72,7 +66,7 @@ function testVariablesView()
testFirstLevelContents();
testSecondLevelContents();
testThirdLevelContents();
testIntegrity(arr, obj);
testOriginalRawDataIntegrity(arr, obj);
let fooScope = gVariablesView.addScope("foo");
let anonymousVar = fooScope.addItem();
@ -84,13 +78,8 @@ function testVariablesView()
testAnonymousHeaders(fooScope, anonymousVar, anonymousScope, barVar, bazProperty);
testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar, bazProperty);
executeSoon(function() {
testKeyboardAccessibility(function() {
testClearHierarchy();
closeDebuggerAndFinish();
});
});
testClearHierarchy();
closeDebuggerAndFinish(gPanel);
}
function testHierarchy() {
@ -101,34 +90,34 @@ function testHierarchy() {
gVariable = gVariablesView._currHierarchy.get("[\"\"]");
is(gVariablesView._store.length, 1,
"There should be only one scope in the view");
"There should be only one scope in the view.");
is(gScope._store.size, 1,
"There should be only one variable in the scope");
"There should be only one variable in the scope.");
is(gVariable._store.size, 9,
"There should be 1 __proto__ and 8 properties in the variable");
"There should be 1 __proto__ and 8 properties in the variable.");
}
function testHeader() {
is(gScope.header, false,
"The scope title header should be hidden");
"The scope title header should be hidden.");
is(gVariable.header, false,
"The variable title header should be hidden");
"The variable title header should be hidden.");
gScope.showHeader();
gVariable.showHeader();
is(gScope.header, false,
"The scope title header should still not be visible");
"The scope title header should still not be visible.");
is(gVariable.header, false,
"The variable title header should still not be visible");
"The variable title header should still not be visible.");
gScope.hideHeader();
gVariable.hideHeader();
is(gScope.header, false,
"The scope title header should now still be hidden");
"The scope title header should now still be hidden.");
is(gVariable.header, false,
"The variable title header should now still be hidden");
"The variable title header should now still be hidden.");
}
function testFirstLevelContents() {
@ -211,7 +200,6 @@ function testFirstLevelContents() {
is(__proto__.value.type, "object", "The __proto__ property value type is correct.");
is(__proto__.value.class, "Object", "The __proto__ property value class is correct.");
someProp0.expand();
someProp1.expand();
someProp2.expand();
@ -229,6 +217,7 @@ function testFirstLevelContents() {
function testSecondLevelContents() {
let someProp5 = gVariable.get("someProp5");
let someProp6 = gVariable.get("someProp6");
is(someProp5._store.size, 0, "No properties should be in someProp5 before expanding");
someProp5.expand();
@ -300,9 +289,6 @@ function testSecondLevelContents() {
is(__proto__.value.type, "object", "The __proto__ property value type is correct.");
is(__proto__.value.class, "Array", "The __proto__ property value class is correct.");
let someProp6 = gVariable.get("someProp6");
is(someProp6._store.size, 0, "No properties should be in someProp6 before expanding");
someProp6.expand();
is(someProp6._store.size, 10, "Some properties should be in someProp6 before expanding");
@ -428,8 +414,8 @@ function testThirdLevelContents() {
let array__proto__ = arrayItem5.get("__proto__");
let object__proto__ = arrayItem6.get("__proto__");
ok(array__proto__, "The array should have a __proto__ property");
ok(object__proto__, "The object should have a __proto__ property");
ok(array__proto__, "The array should have a __proto__ property.");
ok(object__proto__, "The object should have a __proto__ property.");
})();
(function() {
@ -461,37 +447,37 @@ function testThirdLevelContents() {
let array__proto__ = objectItem5.get("__proto__");
let object__proto__ = objectItem6.get("__proto__");
ok(array__proto__, "The array should have a __proto__ property");
ok(object__proto__, "The object should have a __proto__ property");
ok(array__proto__, "The array should have a __proto__ property.");
ok(object__proto__, "The object should have a __proto__ property.");
})();
}
function testIntegrity(arr, obj) {
is(arr[0], 42, "The first array item should not have changed");
is(arr[1], true, "The second array item should not have changed");
is(arr[2], "nasu", "The third array item should not have changed");
is(arr[3], undefined, "The fourth array item should not have changed");
is(arr[4], null, "The fifth array item should not have changed");
ok(arr[5] instanceof Array, "The sixth array item should be an Array");
is(arr[5][0], 0, "The sixth array item should not have changed");
is(arr[5][1], 1, "The sixth array item should not have changed");
is(arr[5][2], 2, "The sixth array item should not have changed");
ok(arr[6] instanceof Object, "The seventh array item should be an Object");
is(arr[6].prop1, 9, "The seventh array item should not have changed");
is(arr[6].prop2, 8, "The seventh array item should not have changed");
function testOriginalRawDataIntegrity(arr, obj) {
is(arr[0], 42, "The first array item should not have changed.");
is(arr[1], true, "The second array item should not have changed.");
is(arr[2], "nasu", "The third array item should not have changed.");
is(arr[3], undefined, "The fourth array item should not have changed.");
is(arr[4], null, "The fifth array item should not have changed.");
ok(arr[5] instanceof Array, "The sixth array item should be an Array.");
is(arr[5][0], 0, "The sixth array item should not have changed.");
is(arr[5][1], 1, "The sixth array item should not have changed.");
is(arr[5][2], 2, "The sixth array item should not have changed.");
ok(arr[6] instanceof Object, "The seventh array item should be an Object.");
is(arr[6].prop1, 9, "The seventh array item should not have changed.");
is(arr[6].prop2, 8, "The seventh array item should not have changed.");
is(obj.p0, 42, "The first object property should not have changed");
is(obj.p1, true, "The first object property should not have changed");
is(obj.p2, "nasu", "The first object property should not have changed");
is(obj.p3, undefined, "The first object property should not have changed");
is(obj.p4, null, "The first object property should not have changed");
ok(obj.p5 instanceof Array, "The sixth object property should be an Array");
is(obj.p5[0], 3, "The sixth object property should not have changed");
is(obj.p5[1], 4, "The sixth object property should not have changed");
is(obj.p5[2], 5, "The sixth object property should not have changed");
ok(obj.p6 instanceof Object, "The seventh object property should be an Object");
is(obj.p6.prop1, 7, "The seventh object property should not have changed");
is(obj.p6.prop2, 6, "The seventh object property should not have changed");
is(obj.p0, 42, "The first object property should not have changed.");
is(obj.p1, true, "The first object property should not have changed.");
is(obj.p2, "nasu", "The first object property should not have changed.");
is(obj.p3, undefined, "The first object property should not have changed.");
is(obj.p4, null, "The first object property should not have changed.");
ok(obj.p5 instanceof Array, "The sixth object property should be an Array.");
is(obj.p5[0], 3, "The sixth object property should not have changed.");
is(obj.p5[1], 4, "The sixth object property should not have changed.");
is(obj.p5[2], 5, "The sixth object property should not have changed.");
ok(obj.p6 instanceof Object, "The seventh object property should be an Object.");
is(obj.p6.prop1, 7, "The seventh object property should not have changed.");
is(obj.p6.prop2, 6, "The seventh object property should not have changed.");
}
function testAnonymousHeaders(fooScope, anonymousVar, anonymousScope, barVar, bazProperty) {
@ -517,14 +503,18 @@ function testAnonymousHeaders(fooScope, anonymousVar, anonymousScope, barVar, ba
}
function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar, bazProperty) {
is(fooScope.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all scopes.");
is(fooScope.preventDisableOnChage, gVariablesView.preventDisableOnChage,
"The preventDisableOnChage property should persist from the view to all scopes.");
is(fooScope.preventDescriptorModifiers, gVariablesView.preventDescriptorModifiers,
"The preventDescriptorModifiers property should persist from the view to all scopes.");
is(fooScope.editableNameTooltip, gVariablesView.editableNameTooltip,
"The editableNameTooltip property should persist from the view to all scopes.");
is(fooScope.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all scopes.");
is(fooScope.editButtonTooltip, gVariablesView.editButtonTooltip,
"The editButtonTooltip property should persist from the view to all scopes.");
is(fooScope.deleteButtonTooltip, gVariablesView.deleteButtonTooltip,
"The deleteButtonTooltip property should persist from the view to all scopes.");
is(fooScope.descriptorTooltip, gVariablesView.descriptorTooltip,
"The descriptorTooltip property should persist from the view to all scopes.");
is(fooScope.contextMenuId, gVariablesView.contextMenuId,
"The contextMenuId property should persist from the view to all scopes.");
is(fooScope.separatorStr, gVariablesView.separatorStr,
@ -540,14 +530,18 @@ function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar,
isnot(fooScope.switch, fooScope.delete,
"The eval and switch functions got mixed up in the scope.");
is(barVar.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all variables.");
is(barVar.preventDisableOnChage, gVariablesView.preventDisableOnChage,
"The preventDisableOnChage property should persist from the view to all variables.");
is(barVar.preventDescriptorModifiers, gVariablesView.preventDescriptorModifiers,
"The preventDescriptorModifiers property should persist from the view to all variables.");
is(barVar.editableNameTooltip, gVariablesView.editableNameTooltip,
"The editableNameTooltip property should persist from the view to all variables.");
is(barVar.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all variables.");
is(barVar.editButtonTooltip, gVariablesView.editButtonTooltip,
"The editButtonTooltip property should persist from the view to all variables.");
is(barVar.deleteButtonTooltip, gVariablesView.deleteButtonTooltip,
"The deleteButtonTooltip property should persist from the view to all variables.");
is(barVar.descriptorTooltip, gVariablesView.descriptorTooltip,
"The descriptorTooltip property should persist from the view to all variables.");
is(barVar.contextMenuId, gVariablesView.contextMenuId,
"The contextMenuId property should persist from the view to all variables.");
is(barVar.separatorStr, gVariablesView.separatorStr,
@ -563,14 +557,18 @@ function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar,
isnot(barVar.switch, barVar.delete,
"The eval and switch functions got mixed up in the variable.");
is(bazProperty.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all properties.");
is(bazProperty.preventDisableOnChage, gVariablesView.preventDisableOnChage,
"The preventDisableOnChage property should persist from the view to all properties.");
is(bazProperty.preventDescriptorModifiers, gVariablesView.preventDescriptorModifiers,
"The preventDescriptorModifiers property should persist from the view to all properties.");
is(bazProperty.editableNameTooltip, gVariablesView.editableNameTooltip,
"The editableNameTooltip property should persist from the view to all properties.");
is(bazProperty.editableValueTooltip, gVariablesView.editableValueTooltip,
"The editableValueTooltip property should persist from the view to all properties.");
is(bazProperty.editButtonTooltip, gVariablesView.editButtonTooltip,
"The editButtonTooltip property should persist from the view to all properties.");
is(bazProperty.deleteButtonTooltip, gVariablesView.deleteButtonTooltip,
"The deleteButtonTooltip property should persist from the view to all properties.");
is(bazProperty.descriptorTooltip, gVariablesView.descriptorTooltip,
"The descriptorTooltip property should persist from the view to all properties.");
is(bazProperty.contextMenuId, gVariablesView.contextMenuId,
"The contextMenuId property should persist from the view to all properties.");
is(bazProperty.separatorStr, gVariablesView.separatorStr,
@ -587,288 +585,6 @@ function testPropertyInheritance(fooScope, anonymousVar, anonymousScope, barVar,
"The eval and switch functions got mixed up in the property.");
}
function testKeyboardAccessibility(callback) {
gDebugger.DebuggerView.Filtering._doVariablesFocus();
gDebugger.DebuggerView.Variables.pageSize = 5;
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused.");
gVariablesView.focusNextItem();
is(gVariablesView.getFocusedItem().name, "someProp1",
"The someProp1 item should be focused.");
gVariablesView.focusPrevItem();
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused again.");
ok(!gVariablesView._list.querySelector(".element-value-input"),
"There shouldn't be a value input element created.");
EventUtils.synthesizeKey("VK_ENTER", {}, gDebugger);
waitForElement(".element-value-input", true, function() {
ok(gVariablesView._list.querySelector(".element-value-input"),
"There should be a value input element created.");
EventUtils.sendKey("ESCAPE", gDebugger);
waitForElement(".element-value-input", false, function() {
ok(!gVariablesView._list.querySelector(".element-value-input"),
"There shouldn't be a value input element anymore.");
ok(!gVariablesView._list.querySelector(".element-name-input"),
"There shouldn't be a name input element created.");
EventUtils.synthesizeKey("VK_ENTER", { shiftKey: true }, gDebugger);
waitForElement(".element-name-input", true, function() {
ok(gVariablesView._list.querySelector(".element-name-input"),
"There should be a name input element created.");
EventUtils.sendKey("ESCAPE", gDebugger);
waitForElement(".element-name-input", false, function() {
ok(!gVariablesView._list.querySelector(".element-name-input"),
"There shouldn't be a name input element anymore.");
EventUtils.sendKey("DOWN", gDebugger);
executeSoon(function() {
is(gVariablesView._parent.scrollTop, 0,
"The variables view shouldn't scroll when pressing the DOWN key.");
EventUtils.sendKey("UP", gDebugger);
executeSoon(function() {
is(gVariablesView._parent.scrollTop, 0,
"The variables view shouldn't scroll when pressing the UP key.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The someProp5 item should be focused now.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "0",
"The 0 item should be focused now.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar item should be focused now.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar item should still be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo item should be focused now.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo item should still be focused now.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar item should be focused now.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp7",
"The someProp7 item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The __proto__ item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "set",
"The set item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "get",
"The get item should be focused now.");
EventUtils.sendKey("HOME", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused now.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused now.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused now.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused now.");
for (let i = 0; i < 16; i++) {
// Advance to the first collapsed __proto__ property.
EventUtils.sendKey("DOWN", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "__proto__",
"The __proto__ item should be focused now.");
is(gVariablesView.getFocusedItem().expanded, false,
"The __proto__ item shouldn't be expanded yet.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The __proto__ item should still be focused.");
is(gVariablesView.getFocusedItem().expanded, true,
"The __proto__ item should be expanded now.");
for (let i = 0; i < 3; i++) {
// Advance to the fifth top-level someProp5 property.
EventUtils.sendKey("LEFT", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "5",
"The fifth array item should be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The fifth array item should not be expanded now.");
for (let i = 0; i < 6; i++) {
// Advance to the fifth top-level someProp5 property.
EventUtils.sendKey("UP", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "someProp5",
"The someProp5 item should be focused now.");
is(gVariablesView.getFocusedItem().expanded, true,
"The someProp5 item should already be expanded.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The someProp5 item should still be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The someProp5 item should not be expanded now.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp5",
"The someProp5 item should still be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp4",
"The someProp4 item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp3",
"The someProp3 item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp2",
"The someProp2 item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp1",
"The someProp1 item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "someProp0",
"The someProp0 item should still be focused.");
for (let i = 0; i < 32; i++) {
// Advance to the last property in this scope.
EventUtils.sendKey("DOWN", gDebugger);
}
is(gVariablesView.getFocusedItem().name, "__proto__",
"The top-level __proto__ item should be focused.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused now.");
is(gVariablesView.getFocusedItem().expanded, true,
"The foo scope should already be expanded.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused now.");
is(gVariablesView.getFocusedItem().expanded, false,
"The foo scope shouldn't be expanded now.");
EventUtils.sendKey("DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar variable should be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The bar variable shouldn't be expanded.");
is(gVariablesView.getFocusedItem().visible, true,
"The bar variable shouldn't be hidden.");
EventUtils.sendKey("BACK_SPACE", gDebugger);
is(gVariablesView.getFocusedItem().name, "bar",
"The bar variable should still be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The bar variable should still not be expanded.");
is(gVariablesView.getFocusedItem().visible, false,
"The bar variable should be hidden.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused.");
EventUtils.sendKey("UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The top-level __proto__ item should be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The top-level __proto__ item should not be expanded.");
EventUtils.sendKey("RIGHT", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The top-level __proto__ item should still be focused.");
is(gVariablesView.getFocusedItem().expanded, true,
"The top-level __proto__ item should be expanded.");
EventUtils.sendKey("LEFT", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The top-level __proto__ item should still be focused.");
is(gVariablesView.getFocusedItem().expanded, false,
"The top-level __proto__ item should not be expanded.");
EventUtils.sendKey("END", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused.");
EventUtils.sendKey("PAGE_UP", gDebugger);
is(gVariablesView.getFocusedItem().name, "__proto__",
"The __proto__ property should be focused.");
EventUtils.sendKey("PAGE_DOWN", gDebugger);
is(gVariablesView.getFocusedItem().name, "foo",
"The foo scope should be focused.");
executeSoon(callback);
});
});
});
});
});
});
}
function waitForElement(selector, exists, callback)
{
// Poll every few milliseconds until the element are retrieved.
let count = 0;
let intervalID = window.setInterval(function() {
info("count: " + count + " ");
if (++count > 50) {
ok(false, "Timed out while polling for the element.");
window.clearInterval(intervalID);
return closeDebuggerAndFinish();
}
if (!!gVariablesView._list.querySelector(selector) != exists) {
return;
}
// We got the element, it's safe to callback.
window.clearInterval(intervalID);
callback();
}, 100);
}
function testClearHierarchy() {
gVariablesView.clearHierarchy();
ok(!gVariablesView._prevHierarchy.size,
@ -878,9 +594,9 @@ function testClearHierarchy() {
}
registerCleanupFunction(function() {
removeTab(gTab);
gPane = null;
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariablesView = null;
gScope = null;

View File

@ -0,0 +1,296 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view knows how to edit getters and setters.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gL10N, gEditor, gVars, gWatch;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gL10N = gDebugger.L10N;
gEditor = gDebugger.DebuggerView.editor;
gVars = gDebugger.DebuggerView.Variables;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars.switch = function() {};
gVars.delete = function() {};
waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
.then(() => addWatchExpressions())
.then(() => testEdit("set", "this._prop = value + ' BEER CAN'", {
"myVar.prop": "xlerb BEER CAN",
"myVar.prop + 42": "xlerb BEER CAN42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("set", "{ this._prop = value + ' BEACON' }", {
"myVar.prop": "xlerb BEACON",
"myVar.prop + 42": "xlerb BEACON42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("set", "{ this._prop = value + ' BEACON;'; }", {
"myVar.prop": "xlerb BEACON;",
"myVar.prop + 42": "xlerb BEACON;42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("set", "{ return this._prop = value + ' BEACON;;'; }", {
"myVar.prop": "xlerb BEACON;;",
"myVar.prop + 42": "xlerb BEACON;;42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("set", "function(value) { this._prop = value + ' BACON' }", {
"myVar.prop": "xlerb BACON",
"myVar.prop + 42": "xlerb BACON42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("get", "'brelx BEER CAN'", {
"myVar.prop": "brelx BEER CAN",
"myVar.prop + 42": "brelx BEER CAN42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("get", "{ 'brelx BEACON' }", {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("get", "{ 'brelx BEACON;'; }", {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("get", "{ return 'brelx BEACON;;'; }", {
"myVar.prop": "brelx BEACON;;",
"myVar.prop + 42": "brelx BEACON;;42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("get", "function() { return 'brelx BACON'; }", {
"myVar.prop": "brelx BACON",
"myVar.prop + 42": "brelx BACON42",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("get", "bogus", {
"myVar.prop": "ReferenceError: bogus is not defined",
"myVar.prop + 42": "ReferenceError: bogus is not defined",
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => testEdit("set", "sugob", {
"myVar.prop": "ReferenceError: bogus is not defined",
"myVar.prop + 42": "ReferenceError: bogus is not defined",
"myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
}))
.then(() => testEdit("get", "", {
"myVar.prop": undefined,
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "ReferenceError: sugob is not defined"
}))
.then(() => testEdit("set", "", {
"myVar.prop": "xlerb",
"myVar.prop + 42": NaN,
"myVar.prop = 'xlerb'": "xlerb"
}))
.then(() => deleteWatchExpression("myVar.prop = 'xlerb'"))
.then(() => testEdit("self", "2507", {
"myVar.prop": 2507,
"myVar.prop + 42": 2549
}))
.then(() => deleteWatchExpression("myVar.prop + 42"))
.then(() => testEdit("self", "0910", {
"myVar.prop": 910
}))
.then(() => deleteLastWatchExpression("myVar.prop"))
.then(() => testWatchExpressionsRemoved())
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function addWatchExpressions() {
return promise.resolve(null)
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
gWatch.addExpression("myVar.prop");
gEditor.focus();
return finished;
})
.then(() => {
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 1,
"There should be 1 evaluation available.");
let w1 = exprScope.get("myVar.prop");
let w2 = exprScope.get("myVar.prop + 42");
let w3 = exprScope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope.");
ok(!w2, "The second watch expression should not be present in the scope.");
ok(!w3, "The third watch expression should not be present in the scope.");
is(w1.value, 42, "The first value is correct.");
})
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
gWatch.addExpression("myVar.prop + 42");
gEditor.focus();
return finished;
})
.then(() => {
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 2,
"There should be 2 evaluations available.");
let w1 = exprScope.get("myVar.prop");
let w2 = exprScope.get("myVar.prop + 42");
let w3 = exprScope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope.");
ok(w2, "The second watch expression should be present in the scope.");
ok(!w3, "The third watch expression should not be present in the scope.");
is(w1.value, "42", "The first expression value is correct.");
is(w2.value, "84", "The second expression value is correct.");
})
.then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
gWatch.addExpression("myVar.prop = 'xlerb'");
gEditor.focus();
return finished;
})
.then(() => {
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 3,
"There should be 3 evaluations available.");
let w1 = exprScope.get("myVar.prop");
let w2 = exprScope.get("myVar.prop + 42");
let w3 = exprScope.get("myVar.prop = 'xlerb'");
ok(w1, "The first watch expression should be present in the scope.");
ok(w2, "The second watch expression should be present in the scope.");
ok(w3, "The third watch expression should be present in the scope.");
is(w1.value, "xlerb", "The first expression value is correct.");
is(w2.value, "xlerb42", "The second expression value is correct.");
is(w3.value, "xlerb", "The third expression value is correct.");
});
}
function deleteWatchExpression(aString) {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
gWatch.deleteExpression({ name: aString });
return finished;
}
function deleteLastWatchExpression(aString) {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
gWatch.deleteExpression({ name: aString });
return finished;
}
function testEdit(aWhat, aString, aExpected) {
let localScope = gVars.getScopeAtIndex(1);
let myVar = localScope.get("myVar");
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES).then(() => {
let propVar = myVar.get("prop");
let getterOrSetterOrVar = aWhat != "self" ? propVar.get(aWhat) : propVar;
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS).then(() => {
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, Object.keys(aExpected).length,
"There should be a certain number of evaluations available.");
function testExpression(aExpression) {
if (!aExpression) {
return;
}
let value = aExpected[aExpression.name];
if (isNaN(value)) {
ok(isNaN(aExpression.value),
"The expression value is correct after the edit.");
} else if (value == null) {
is(aExpression.value.type, value + "",
"The expression value is correct after the edit.");
} else {
is(aExpression.value, value,
"The expression value is correct after the edit.");
}
}
testExpression(exprScope.get(Object.keys(aExpected)[0]));
testExpression(exprScope.get(Object.keys(aExpected)[1]));
testExpression(exprScope.get(Object.keys(aExpected)[2]));
});
let editTarget = getterOrSetterOrVar.target;
// Allow the target variable to get painted, so that clicking on
// its value would scroll the new textbox node into view.
executeSoon(() => {
let varValue = editTarget.querySelector(".title > .value");
EventUtils.sendMouseEvent({ type: "mousedown" }, varValue, gDebugger);
let varInput = editTarget.querySelector(".title > .element-value-input");
setText(varInput, aString);
EventUtils.sendKey("RETURN", gDebugger);
});
return finished;
});
myVar.expand();
gVars.clearHierarchy();
return finished;
}
function testWatchExpressionsRemoved() {
let scope = gVars.getScopeAtIndex(0);
ok(scope,
"There should be a local scope in the variables view.");
isnot(scope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should not be marked as 'Watch Expressions'.");
isnot(scope._store.size, 0,
"There should be some variables available.");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVars = null;
gWatch = null;
});

View File

@ -0,0 +1,103 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view is able to override getter properties
* to plain value properties.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gL10N, gEditor, gVars, gWatch;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gL10N = gDebugger.L10N;
gEditor = gDebugger.DebuggerView.editor;
gVars = gDebugger.DebuggerView.Variables;
gWatch = gDebugger.DebuggerView.WatchExpressions;
gVars.switch = function() {};
gVars.delete = function() {};
waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
.then(() => addWatchExpression())
.then(() => testEdit("\"xlerb\"", "xlerb"))
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function addWatchExpression() {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS);
gWatch.addExpression("myVar.prop");
gEditor.focus();
return finished;
}
function testEdit(aString, aExpected) {
let localScope = gVars.getScopeAtIndex(1);
let myVar = localScope.get("myVar");
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES).then(() => {
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS).then(() => {
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 1,
"There should be one evaluation available.");
is(exprScope.get("myVar.prop").value, aExpected,
"The expression value is correct after the edit.");
});
let editTarget = myVar.get("prop").target;
// Allow the target variable to get painted, so that clicking on
// its value would scroll the new textbox node into view.
executeSoon(() => {
let varEdit = editTarget.querySelector(".title > .variables-view-edit");
EventUtils.sendMouseEvent({ type: "mousedown" }, varEdit, gDebugger);
let varInput = editTarget.querySelector(".title > .element-value-input");
setText(varInput, aString);
EventUtils.sendKey("RETURN", gDebugger);
});
return finished;
});
myVar.expand();
gVars.clearHierarchy();
return finished;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVars = null;
gWatch = null;
});

View File

@ -0,0 +1,89 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the editing variables or properties values works properly.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVars;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVars = gDebugger.DebuggerView.Variables;
waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
.then(() => initialChecks())
.then(() => testModification("a", "1"))
.then(() => testModification("{ a: 1 }", "Object"))
.then(() => testModification("[a]", "Array"))
.then(() => testModification("b", "Object"))
.then(() => testModification("b.a", "1"))
.then(() => testModification("c.a", "1"))
.then(() => testModification("Infinity", "Infinity"))
.then(() => testModification("NaN", "NaN"))
.then(() => testModification("new Function", "Function"))
.then(() => testModification("+0", "0"))
.then(() => testModification("-0", "-0"))
.then(() => testModification("Object.keys({})", "Array"))
.then(() => testModification("document.title", '"Debugger test page"'))
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function initialChecks() {
let localScope = gVars.getScopeAtIndex(0);
let aVar = localScope.get("a");
is(aVar.target.querySelector(".name").getAttribute("value"), "a",
"Should have the right name for 'a'.");
is(aVar.target.querySelector(".value").getAttribute("value"), "1",
"Should have the right initial value for 'a'.");
}
function testModification(aNewValue, aNewResult) {
let localScope = gVars.getScopeAtIndex(0);
let aVar = localScope.get("a");
// Allow the target variable to get painted, so that clicking on
// its value would scroll the new textbox node into view.
executeSoon(() => {
let varValue = aVar.target.querySelector(".title > .value");
EventUtils.sendMouseEvent({ type: "mousedown" }, varValue, gDebugger);
let varInput = aVar.target.querySelector(".title > .element-value-input");
setText(varInput, aNewValue);
EventUtils.sendKey("RETURN", gDebugger);
});
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
let localScope = gVars.getScopeAtIndex(0);
let aVar = localScope.get("a");
is(aVar.target.querySelector(".name").getAttribute("value"), "a",
"Should have the right name for 'a'.");
is(aVar.target.querySelector(".value").getAttribute("value"), aNewResult,
"Should have the right new value for 'a'.");
});
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVars = null;
});

View File

@ -0,0 +1,504 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the editing or removing watch expressions works properly.
*/
const TAB_URL = EXAMPLE_URL + "doc_watch-expressions.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gL10N, gEditor, gVars, gWatch;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gL10N = gDebugger.L10N;
gEditor = gDebugger.DebuggerView.editor;
gVars = gDebugger.DebuggerView.Variables;
gWatch = gDebugger.DebuggerView.WatchExpressions;
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS)
.then(() => testInitialVariablesInScope())
.then(() => testInitialExpressionsInScope())
.then(() => testModification("document.title = 42", "document.title = 43", "43", "undefined"))
.then(() => testIntegrity1())
.then(() => testModification("aArg", "aArg = 44", "44", "44"))
.then(() => testIntegrity2())
.then(() => testModification("aArg = 44", "\ \t\r\ndocument.title\ \t\r\n", "\"43\"", "44"))
.then(() => testIntegrity3())
.then(() => testModification("document.title = 43", "\ \t\r\ndocument.title\ \t\r\n", "\"43\"", "44"))
.then(() => testIntegrity4())
.then(() => testModification("document.title", "\ \t\r\n", "\"43\"", "44"))
.then(() => testIntegrity5())
.then(() => testExprDeletion("this", "44"))
.then(() => testIntegrity6())
.then(() => testExprFinalDeletion("ermahgerd", "44"))
.then(() => testIntegrity7())
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
addExpressions();
gDebuggee.ermahgerd();
});
}
function addExpressions() {
addExpression("this");
addExpression("ermahgerd");
addExpression("aArg");
addExpression("document.title");
addCmdExpression("document.title = 42");
is(gWatch.itemCount, 5,
"There should be 5 items availalble in the watch expressions view.");
is(gWatch.getItemAtIndex(4).attachment.initialExpression, "this",
"The first expression's initial value should be correct.");
is(gWatch.getItemAtIndex(3).attachment.initialExpression, "ermahgerd",
"The second expression's initial value should be correct.");
is(gWatch.getItemAtIndex(2).attachment.initialExpression, "aArg",
"The third expression's initial value should be correct.");
is(gWatch.getItemAtIndex(1).attachment.initialExpression, "document.title",
"The fourth expression's initial value should be correct.");
is(gWatch.getItemAtIndex(0).attachment.initialExpression, "document.title = 42",
"The fifth expression's initial value should be correct.");
is(gWatch.getItemAtIndex(4).attachment.currentExpression, "this",
"The first expression's current value should be correct.");
is(gWatch.getItemAtIndex(3).attachment.currentExpression, "ermahgerd",
"The second expression's current value should be correct.");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "aArg",
"The third expression's current value should be correct.");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "document.title",
"The fourth expression's current value should be correct.");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title = 42",
"The fifth expression's current value should be correct.");
}
function testInitialVariablesInScope() {
let localScope = gVars.getScopeAtIndex(1);
let argVar = localScope.get("aArg");
is(argVar.visible, true,
"Should have the right visibility state for 'aArg'.");
is(argVar.name, "aArg",
"Should have the right name for 'aArg'.");
is(argVar.value.type, "undefined",
"Should have the right initial value for 'aArg'.");
}
function testInitialExpressionsInScope() {
let exprScope = gVars.getScopeAtIndex(0);
let thisExpr = exprScope.get("this");
let ermExpr = exprScope.get("ermahgerd");
let argExpr = exprScope.get("aArg");
let docExpr = exprScope.get("document.title");
let docExpr2 = exprScope.get("document.title = 42");
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 5,
"There should be 5 evaluations available.");
is(thisExpr.visible, true,
"Should have the right visibility state for 'this'.");
is(thisExpr.target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'this'.");
is(thisExpr.name, "this",
"Should have the right name for 'this'.");
is(thisExpr.value.type, "object",
"Should have the right value type for 'this'.");
is(thisExpr.value.class, "Window",
"Should have the right value type for 'this'.");
is(ermExpr.visible, true,
"Should have the right visibility state for 'ermahgerd'.");
is(ermExpr.target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'ermahgerd'.");
is(ermExpr.name, "ermahgerd",
"Should have the right name for 'ermahgerd'.");
is(ermExpr.value.type, "object",
"Should have the right value type for 'ermahgerd'.");
is(ermExpr.value.class, "Function",
"Should have the right value type for 'ermahgerd'.");
is(argExpr.visible, true,
"Should have the right visibility state for 'aArg'.");
is(argExpr.target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'aArg'.");
is(argExpr.name, "aArg",
"Should have the right name for 'aArg'.");
is(argExpr.value.type, "undefined",
"Should have the right value for 'aArg'.");
is(docExpr.visible, true,
"Should have the right visibility state for 'document.title'.");
is(docExpr.target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'document.title'.");
is(docExpr.name, "document.title",
"Should have the right name for 'document.title'.");
is(docExpr.value, "42",
"Should have the right value for 'document.title'.");
is(docExpr2.visible, true,
"Should have the right visibility state for 'document.title = 42'.");
is(docExpr2.target.querySelectorAll(".variables-view-delete").length, 1,
"Should have the one close button visible for 'document.title = 42'.");
is(docExpr2.name, "document.title = 42",
"Should have the right name for 'document.title = 42'.");
is(docExpr2.value, 42,
"Should have the right value for 'document.title = 42'.");
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
}
function testModification(aName, aNewValue, aNewResult, aArgResult) {
let exprScope = gVars.getScopeAtIndex(0);
let exprVar = exprScope.get(aName);
let finished = promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS)
])
.then(() => {
let localScope = gVars.getScopeAtIndex(1);
let argVar = localScope.get("aArg");
is(argVar.visible, true,
"Should have the right visibility state for 'aArg'.");
is(argVar.target.querySelector(".name").getAttribute("value"), "aArg",
"Should have the right name for 'aArg'.");
is(argVar.target.querySelector(".value").getAttribute("value"), aArgResult,
"Should have the right new value for 'aArg'.");
let exprScope = gVars.getScopeAtIndex(0);
let exprOldVar = exprScope.get(aName);
let exprNewVar = exprScope.get(aNewValue.trim());
if (!aNewValue.trim()) {
ok(!exprOldVar,
"The old watch expression should have been removed.");
ok(!exprNewVar,
"No new watch expression should have been added.");
} else {
ok(!exprOldVar,
"The old watch expression should have been removed.");
ok(exprNewVar,
"The new watch expression should have been added.");
is(exprNewVar.visible, true,
"Should have the right visibility state for the watch expression.");
is(exprNewVar.target.querySelector(".name").getAttribute("value"), aNewValue.trim(),
"Should have the right name for the watch expression.");
is(exprNewVar.target.querySelector(".value").getAttribute("value"), aNewResult,
"Should have the right new value for the watch expression.");
}
});
let varValue = exprVar.target.querySelector(".title > .name");
EventUtils.sendMouseEvent({ type: "dblclick" }, varValue, gDebugger);
let varInput = exprVar.target.querySelector(".title > .element-name-input");
setText(varInput, aNewValue);
EventUtils.sendKey("RETURN", gDebugger);
return finished;
}
function testExprDeletion(aName, aArgResult) {
let exprScope = gVars.getScopeAtIndex(0);
let exprVar = exprScope.get(aName);
let finished = promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_WATCH_EXPRESSIONS)
])
.then(() => {
let localScope = gVars.getScopeAtIndex(1);
let argVar = localScope.get("aArg");
is(argVar.visible, true,
"Should have the right visibility state for 'aArg'.");
is(argVar.target.querySelector(".name").getAttribute("value"), "aArg",
"Should have the right name for 'aArg'.");
is(argVar.target.querySelector(".value").getAttribute("value"), aArgResult,
"Should have the right new value for 'aArg'.");
let exprScope = gVars.getScopeAtIndex(0);
let exprOldVar = exprScope.get(aName);
ok(!exprOldVar,
"The watch expression should have been deleted.");
});
let varDelete = exprVar.target.querySelector(".variables-view-delete");
EventUtils.sendMouseEvent({ type: "click" }, varDelete, gDebugger);
return finished;
}
function testExprFinalDeletion(aName, aArgResult) {
let exprScope = gVars.getScopeAtIndex(0);
let exprVar = exprScope.get(aName);
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
let localScope = gVars.getScopeAtIndex(0);
let argVar = localScope.get("aArg");
is(argVar.visible, true,
"Should have the right visibility state for 'aArg'.");
is(argVar.target.querySelector(".name").getAttribute("value"), "aArg",
"Should have the right name for 'aArg'.");
is(argVar.target.querySelector(".value").getAttribute("value"), aArgResult,
"Should have the right new value for 'aArg'.");
let exprScope = gVars.getScopeAtIndex(0);
let exprOldVar = exprScope.get(aName);
ok(!exprOldVar,
"The watch expression should have been deleted.");
});
let varDelete = exprVar.target.querySelector(".variables-view-delete");
EventUtils.sendMouseEvent({ type: "click" }, varDelete, gDebugger);
return finished;
}
function testIntegrity1() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 5,
"There should be 5 visible evaluations available.");
is(gWatch.itemCount, 5,
"There should be 5 hidden expression input available.");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "document.title",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "aArg",
"The third textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "aArg",
"The third textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(3).attachment.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(3).attachment.currentExpression, "ermahgerd",
"The fourth textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(4).attachment.inputNode.value, "this",
"The fifth textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(4).attachment.currentExpression, "this",
"The fifth textbox input value is not the correct one.");
}
function testIntegrity2() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 5,
"There should be 5 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 5,
"There should be 5 visible evaluations available.");
is(gWatch.itemCount, 5,
"There should be 5 hidden expression input available.");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "document.title",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "aArg = 44",
"The third textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "aArg = 44",
"The third textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(3).attachment.inputNode.value, "ermahgerd",
"The fourth textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(3).attachment.currentExpression, "ermahgerd",
"The fourth textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(4).attachment.inputNode.value, "this",
"The fifth textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(4).attachment.currentExpression, "this",
"The fifth textbox input value is not the correct one.");
}
function testIntegrity3() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 4,
"There should be 4 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 4,
"There should be 4 visible evaluations available.");
is(gWatch.itemCount, 4,
"There should be 4 hidden expression input available.");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title = 43",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title = 43",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "document.title",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "document.title",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "ermahgerd",
"The third textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "ermahgerd",
"The third textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(3).attachment.inputNode.value, "this",
"The fourth textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(3).attachment.currentExpression, "this",
"The fourth textbox input value is not the correct one.");
}
function testIntegrity4() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 3,
"There should be 3 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 3,
"There should be 3 visible evaluations available.");
is(gWatch.itemCount, 3,
"There should be 3 hidden expression input available.");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "document.title",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "document.title",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "ermahgerd",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "ermahgerd",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.inputNode.value, "this",
"The third textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(2).attachment.currentExpression, "this",
"The third textbox input value is not the correct one.");
}
function testIntegrity5() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 2,
"There should be 2 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 2,
"There should be 2 visible evaluations available.");
is(gWatch.itemCount, 2,
"There should be 2 hidden expression input available.");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "ermahgerd",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "ermahgerd",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.inputNode.value, "this",
"The second textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(1).attachment.currentExpression, "this",
"The second textbox input value is not the correct one.");
}
function testIntegrity6() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 1,
"There should be 1 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
let exprScope = gVars.getScopeAtIndex(0);
ok(exprScope,
"There should be a wach expressions scope in the variables view.");
is(exprScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should be marked as 'Watch Expressions'.");
is(exprScope._store.size, 1,
"There should be 1 visible evaluation available.");
is(gWatch.itemCount, 1,
"There should be 1 hidden expression input available.");
is(gWatch.getItemAtIndex(0).attachment.inputNode.value, "ermahgerd",
"The first textbox input value is not the correct one.");
is(gWatch.getItemAtIndex(0).attachment.currentExpression, "ermahgerd",
"The first textbox input value is not the correct one.");
}
function testIntegrity7() {
is(gDebugger.document.querySelectorAll(".dbg-expression[hidden=true]").length, 0,
"There should be 0 hidden nodes in the watch expressions container.");
is(gDebugger.document.querySelectorAll(".dbg-expression:not([hidden=true])").length, 0,
"There should be 0 visible nodes in the watch expressions container.");
let localScope = gVars.getScopeAtIndex(0);
ok(localScope,
"There should be a local scope in the variables view.");
isnot(localScope.name, gL10N.getStr("watchExpressionsScopeLabel"),
"The scope's name should not be marked as 'Watch Expressions'.");
isnot(localScope._store.size, 0,
"There should be some variables available.");
is(gWatch.itemCount, 0,
"The watch expressions container should be empty.");
}
function addExpression(aString) {
gWatch.addExpression(aString);
gEditor.focus();
}
function addCmdExpression(aString) {
gWatch._onCmdAddExpression(aString);
gEditor.focus();
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gL10N = null;
gEditor = null;
gVars = null;
gWatch = null;
});

View File

@ -0,0 +1,224 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly filters nodes by name.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables, gSearchBox;
function test() {
// Debug test slaves are quite slow at this test.
requestLongerTimeout(4);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
gVariables._enableSearch();
gSearchBox = gVariables._searchboxNode;
// The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work.
promise.all([
waitForSourceAndCaret(gPanel, ".html", 22),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
]).then(prepareVariablesAndProperties)
.then(testVariablesAndPropertiesFiltering)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function testVariablesAndPropertiesFiltering() {
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
let protoVar = localScope.get("__proto__");
let constrVar = protoVar.get("constructor");
let proto2Var = constrVar.get("__proto__");
let constr2Var = proto2Var.get("constructor");
function testFiltered() {
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, true,
"The withScope should be expanded.");
is(functionScope.expanded, true,
"The functionScope should be expanded.");
is(globalScope.expanded, true,
"The globalScope should be expanded.");
is(protoVar.expanded, true,
"The protoVar should be expanded.");
is(constrVar.expanded, true,
"The constrVar should be expanded.");
is(proto2Var.expanded, true,
"The proto2Var should be expanded.");
is(constr2Var.expanded, true,
"The constr2Var should be expanded.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the local scope.");
is(withScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the with scope.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the function scope.");
isnot(globalScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the global scope.");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 3,
"There should be 3 properties displayed in the local scope.");
is(withScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the with scope.");
is(functionScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the function scope.");
is(globalScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the global scope.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"__proto__", "The only inner variable displayed should be '__proto__'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[0].getAttribute("value"),
"constructor", "The first inner property displayed should be 'constructor'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[1].getAttribute("value"),
"__proto__", "The second inner property displayed should be '__proto__'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"constructor", "The third inner property displayed should be 'constructor'");
}
function firstFilter() {
typeText(gSearchBox, "constructor");
testFiltered();
}
function secondFilter() {
localScope.collapse();
withScope.collapse();
functionScope.collapse();
globalScope.collapse();
protoVar.collapse();
constrVar.collapse();
proto2Var.collapse();
constr2Var.collapse();
is(localScope.expanded, false,
"The localScope should not be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded.");
is(functionScope.expanded, false,
"The functionScope should not be expanded.");
is(globalScope.expanded, false,
"The globalScope should not be expanded.");
is(protoVar.expanded, false,
"The protoVar should not be expanded.");
is(constrVar.expanded, false,
"The constrVar should not be expanded.");
is(proto2Var.expanded, false,
"The proto2Var should not be expanded.");
is(constr2Var.expanded, false,
"The constr2Var should not be expanded.");
clearText(gSearchBox);
typeText(gSearchBox, "constructor");
testFiltered();
}
firstFilter();
secondFilter();
}
function prepareVariablesAndProperties() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded yet.");
is(functionScope.expanded, false,
"The functionScope should not be expanded yet.");
is(globalScope.expanded, false,
"The globalScope should not be expanded yet.");
// Wait for only two events to be triggered, because the Function scope is
// an environment to which scope arguments and variables are already attached.
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
is(localScope.expanded, true,
"The localScope should now be expanded.");
is(withScope.expanded, true,
"The withScope should now be expanded.");
is(functionScope.expanded, true,
"The functionScope should now be expanded.");
is(globalScope.expanded, true,
"The globalScope should now be expanded.");
let protoVar = localScope.get("__proto__");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let constrVar = protoVar.get("constructor");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let proto2Var = constrVar.get("__proto__");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let constr2Var = proto2Var.get("constructor");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
is(protoVar.expanded, true,
"The local scope '__proto__' should be expanded.");
is(constrVar.expanded, true,
"The local scope '__proto__.constructor' should be expanded.");
is(proto2Var.expanded, true,
"The local scope '__proto__.constructor.__proto__' should be expanded.");
is(constr2Var.expanded, true,
"The local scope '__proto__.constructor.__proto__.constructor' should be expanded.");
deferred.resolve();
});
constr2Var.expand();
});
proto2Var.expand();
});
constrVar.expand();
});
protoVar.expand();
});
withScope.expand();
functionScope.expand();
globalScope.expand();
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
gSearchBox = null;
});

View File

@ -0,0 +1,229 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly filters nodes by value.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables, gSearchBox;
function test() {
// Debug test slaves are quite slow at this test.
requestLongerTimeout(4);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
gVariables._enableSearch();
gSearchBox = gVariables._searchboxNode;
// The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work.
promise.all([
waitForSourceAndCaret(gPanel, ".html", 22),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
]).then(prepareVariablesAndProperties)
.then(testVariablesAndPropertiesFiltering)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function testVariablesAndPropertiesFiltering() {
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
let protoVar = localScope.get("__proto__");
let constrVar = protoVar.get("constructor");
let proto2Var = constrVar.get("__proto__");
let constr2Var = proto2Var.get("constructor");
function testFiltered() {
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, true,
"The withScope should be expanded.");
is(functionScope.expanded, true,
"The functionScope should be expanded.");
is(globalScope.expanded, true,
"The globalScope should be expanded.");
is(protoVar.expanded, true,
"The protoVar should be expanded.");
is(constrVar.expanded, true,
"The constrVar should be expanded.");
is(proto2Var.expanded, true,
"The proto2Var should be expanded.");
is(constr2Var.expanded, true,
"The constr2Var should be expanded.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the local scope.");
is(withScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the with scope.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the function scope.");
is(globalScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be no variables displayed in the global scope.");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 4,
"There should be 4 properties displayed in the local scope.");
is(withScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the with scope.");
is(functionScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the function scope.");
is(globalScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the global scope.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"__proto__", "The only inner variable displayed should be '__proto__'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[0].getAttribute("value"),
"constructor", "The first inner property displayed should be 'constructor'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[1].getAttribute("value"),
"__proto__", "The second inner property displayed should be '__proto__'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[2].getAttribute("value"),
"constructor", "The third inner property displayed should be 'constructor'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .name")[3].getAttribute("value"),
"name", "The fourth inner property displayed should be 'name'");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match]) > .title > .value")[3].getAttribute("value"),
"\"Function\"", "The fourth inner property displayed should be '\"Function\"'");
}
function firstFilter() {
typeText(gSearchBox, "\"Function\"");
testFiltered();
}
function secondFilter() {
localScope.collapse();
withScope.collapse();
functionScope.collapse();
globalScope.collapse();
protoVar.collapse();
constrVar.collapse();
proto2Var.collapse();
constr2Var.collapse();
is(localScope.expanded, false,
"The localScope should not be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded.");
is(functionScope.expanded, false,
"The functionScope should not be expanded.");
is(globalScope.expanded, false,
"The globalScope should not be expanded.");
is(protoVar.expanded, false,
"The protoVar should not be expanded.");
is(constrVar.expanded, false,
"The constrVar should not be expanded.");
is(proto2Var.expanded, false,
"The proto2Var should not be expanded.");
is(constr2Var.expanded, false,
"The constr2Var should not be expanded.");
backspaceText(gSearchBox, 10);
typeText(gSearchBox, "\"Function\"");
testFiltered();
}
firstFilter();
secondFilter();
}
function prepareVariablesAndProperties() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded yet.");
is(functionScope.expanded, false,
"The functionScope should not be expanded yet.");
is(globalScope.expanded, false,
"The globalScope should not be expanded yet.");
// Wait for only two events to be triggered, because the Function scope is
// an environment to which scope arguments and variables are already attached.
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
is(localScope.expanded, true,
"The localScope should now be expanded.");
is(withScope.expanded, true,
"The withScope should now be expanded.");
is(functionScope.expanded, true,
"The functionScope should now be expanded.");
is(globalScope.expanded, true,
"The globalScope should now be expanded.");
let protoVar = localScope.get("__proto__");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let constrVar = protoVar.get("constructor");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let proto2Var = constrVar.get("__proto__");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let constr2Var = proto2Var.get("constructor");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
is(protoVar.expanded, true,
"The local scope '__proto__' should be expanded.");
is(constrVar.expanded, true,
"The local scope '__proto__.constructor' should be expanded.");
is(proto2Var.expanded, true,
"The local scope '__proto__.constructor.__proto__' should be expanded.");
is(constr2Var.expanded, true,
"The local scope '__proto__.constructor.__proto__.constructor' should be expanded.");
deferred.resolve();
});
constr2Var.expand();
});
proto2Var.expand();
});
constrVar.expand();
});
protoVar.expand();
});
withScope.expand();
functionScope.expand();
globalScope.expand();
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
gSearchBox = null;
});

View File

@ -0,0 +1,163 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly filters nodes when triggered
* from the debugger's searchbox via an operator.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables, gSearchBox;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
// The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work.
promise.all([
waitForSourceAndCaret(gPanel, ".html", 22),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
]).then(prepareVariablesAndProperties)
.then(testVariablesAndPropertiesFiltering)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function testVariablesAndPropertiesFiltering() {
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
function testFiltered() {
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, true,
"The withScope should be expanded.");
is(functionScope.expanded, true,
"The functionScope should be expanded.");
is(globalScope.expanded, true,
"The globalScope should be expanded.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 1,
"There should be 1 variable displayed in the local scope.");
is(withScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the with scope.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be 0 variables displayed in the function scope.");
is(localScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the local scope.");
is(withScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the with scope.");
is(functionScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the function scope.");
is(globalScope.target.querySelectorAll(".variables-view-property:not([non-match])").length, 0,
"There should be 0 properties displayed in the global scope.");
}
function firstFilter() {
typeText(gSearchBox, "*one");
testFiltered("one");
isnot(globalScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be some variables displayed in the global scope.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"one", "The only inner variable displayed should be 'one'");
}
function secondFilter() {
localScope.collapse();
withScope.collapse();
functionScope.collapse();
globalScope.collapse();
is(localScope.expanded, false,
"The localScope should not be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded.");
is(functionScope.expanded, false,
"The functionScope should not be expanded.");
is(globalScope.expanded, false,
"The globalScope should not be expanded.");
backspaceText(gSearchBox, 4);
typeText(gSearchBox, "*two");
testFiltered("two");
is(globalScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length, 0,
"There should be no variables displayed in the global scope.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"two", "The only inner variable displayed should be 'two'");
}
firstFilter();
secondFilter();
}
function prepareVariablesAndProperties() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded yet.");
is(functionScope.expanded, false,
"The functionScope should not be expanded yet.");
is(globalScope.expanded, false,
"The globalScope should not be expanded yet.");
// Wait for only two events to be triggered, because the Function scope is
// an environment to which scope arguments and variables are already attached.
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
is(localScope.expanded, true,
"The localScope should now be expanded.");
is(withScope.expanded, true,
"The withScope should now be expanded.");
is(functionScope.expanded, true,
"The functionScope should now be expanded.");
is(globalScope.expanded, true,
"The globalScope should now be expanded.");
deferred.resolve();
});
withScope.expand();
functionScope.expand();
globalScope.expand();
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
gSearchBox = null;
});

View File

@ -0,0 +1,229 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly shows/hides nodes when various
* keyboard shortcuts are pressed in the debugger's searchbox.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gVariables, gSearchBox;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gVariables = gDebugger.DebuggerView.Variables;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
// The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work.
promise.all([
waitForSourceAndCaret(gPanel, ".html", 22),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
]).then(prepareVariablesAndProperties)
.then(testVariablesAndPropertiesFiltering)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function testVariablesAndPropertiesFiltering() {
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
let step = 0;
let tests = [
function() {
assertExpansion([true, false, false, false]);
EventUtils.sendKey("RETURN", gDebugger);
},
function() {
assertExpansion([true, false, false, false]);
EventUtils.sendKey("ENTER", gDebugger);
},
function() {
assertExpansion([true, false, false, false]);
gEditor.focus();
},
function() {
assertExpansion([true, false, false, false]);
typeText(gSearchBox, "*");
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("ENTER", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
gEditor.focus();
},
function() {
assertExpansion([true, true, true, true]);
backspaceText(gSearchBox, 1);
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("ENTER", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
gEditor.focus();
},
function() {
assertExpansion([true, true, true, true]);
localScope.collapse();
withScope.collapse();
functionScope.collapse();
globalScope.collapse();
},
function() {
assertExpansion([false, false, false, false]);
EventUtils.sendKey("RETURN", gDebugger);
},
function() {
assertExpansion([false, false, false, false]);
EventUtils.sendKey("ENTER", gDebugger);
},
function() {
assertExpansion([false, false, false, false]);
gEditor.focus();
},
function() {
assertExpansion([false, false, false, false]);
clearText(gSearchBox);
typeText(gSearchBox, "*");
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("ENTER", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
gEditor.focus();
},
function() {
assertExpansion([true, true, true, true]);
backspaceText(gSearchBox, 1);
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("RETURN", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
EventUtils.sendKey("ENTER", gDebugger);
},
function() {
assertExpansion([true, true, true, true]);
gEditor.focus();
},
function() {
assertExpansion([true, true, true, true]);
}
];
function assertExpansion(aFlags) {
is(localScope.expanded, aFlags[0],
"The localScope should " + (aFlags[0] ? "" : "not ") +
"be expanded at this point (" + step + ").");
is(withScope.expanded, aFlags[1],
"The withScope should " + (aFlags[1] ? "" : "not ") +
"be expanded at this point (" + step + ").");
is(functionScope.expanded, aFlags[2],
"The functionScope should " + (aFlags[2] ? "" : "not ") +
"be expanded at this point (" + step + ").");
is(globalScope.expanded, aFlags[3],
"The globalScope should " + (aFlags[3] ? "" : "not ") +
"be expanded at this point (" + step + ").");
step++;
}
return promise.all(tests.map(f => f()));
}
function prepareVariablesAndProperties() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded yet.");
is(functionScope.expanded, false,
"The functionScope should not be expanded yet.");
is(globalScope.expanded, false,
"The globalScope should not be expanded yet.");
// Wait for only two events to be triggered, because the Function scope is
// an environment to which scope arguments and variables are already attached.
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
is(localScope.expanded, true,
"The localScope should now be expanded.");
is(withScope.expanded, true,
"The withScope should now be expanded.");
is(functionScope.expanded, true,
"The functionScope should now be expanded.");
is(globalScope.expanded, true,
"The globalScope should now be expanded.");
withScope.collapse();
functionScope.collapse();
globalScope.collapse();
deferred.resolve();
});
withScope.expand();
functionScope.expand();
globalScope.expand();
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gVariables = null;
gSearchBox = null;
});

View File

@ -0,0 +1,239 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly shows/hides nodes when various
* keyboard shortcuts are pressed in the debugger's searchbox.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gEditor, gVariables, gSearchBox;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gEditor = gDebugger.DebuggerView.editor;
gVariables = gDebugger.DebuggerView.Variables;
gSearchBox = gDebugger.DebuggerView.Filtering._searchbox;
// The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work.
promise.all([
waitForSourceAndCaret(gPanel, ".html", 22),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
]).then(prepareVariablesAndProperties)
.then(testVariablesAndPropertiesFiltering)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function testVariablesAndPropertiesFiltering() {
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
let step = 0;
let tests = [
function() {
assertScopeExpansion([true, false, false, false]);
typeText(gSearchBox, "*arguments");
},
function() {
assertScopeExpansion([true, true, true, true]);
assertVariablesCountAtLeast([0, 0, 1, 0]);
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"arguments", "The arguments pseudoarray should be visible.");
is(functionScope.get("arguments").expanded, false,
"The arguments pseudoarray in functionScope should not be expanded.");
backspaceText(gSearchBox, 6);
},
function() {
assertScopeExpansion([true, true, true, true]);
assertVariablesCountAtLeast([0, 0, 1, 1]);
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"arguments", "The arguments pseudoarray should be visible.");
is(functionScope.get("arguments").expanded, false,
"The arguments pseudoarray in functionScope should not be expanded.");
is(globalScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"EventTarget", "The EventTarget object should be visible.");
is(globalScope.get("EventTarget").expanded, false,
"The EventTarget object in globalScope should not be expanded.");
backspaceText(gSearchBox, 2);
},
function() {
assertScopeExpansion([true, true, true, true]);
assertVariablesCountAtLeast([0, 1, 3, 1]);
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"aNumber", "The aNumber param should be visible.");
is(functionScope.get("aNumber").expanded, false,
"The aNumber param in functionScope should not be expanded.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"a", "The a variable should be visible.");
is(functionScope.get("a").expanded, false,
"The a variable in functionScope should not be expanded.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[2].getAttribute("value"),
"arguments", "The arguments pseudoarray should be visible.");
is(functionScope.get("arguments").expanded, false,
"The arguments pseudoarray in functionScope should not be expanded.");
backspaceText(gSearchBox, 1);
},
function() {
assertScopeExpansion([true, true, true, true]);
assertVariablesCountAtLeast([4, 1, 3, 1]);
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"this", "The this reference should be visible.");
is(localScope.get("this").expanded, false,
"The this reference in localScope should not be expanded.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"one", "The one variable should be visible.");
is(localScope.get("one").expanded, false,
"The one variable in localScope should not be expanded.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[2].getAttribute("value"),
"two", "The two variable should be visible.");
is(localScope.get("two").expanded, false,
"The two variable in localScope should not be expanded.");
is(localScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[3].getAttribute("value"),
"__proto__", "The __proto__ reference should be visible.");
is(localScope.get("__proto__").expanded, false,
"The __proto__ reference in localScope should not be expanded.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[0].getAttribute("value"),
"aNumber", "The aNumber param should be visible.");
is(functionScope.get("aNumber").expanded, false,
"The aNumber param in functionScope should not be expanded.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[1].getAttribute("value"),
"a", "The a variable should be visible.");
is(functionScope.get("a").expanded, false,
"The a variable in functionScope should not be expanded.");
is(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match]) > .title > .name")[2].getAttribute("value"),
"arguments", "The arguments pseudoarray should be visible.");
is(functionScope.get("arguments").expanded, false,
"The arguments pseudoarray in functionScope should not be expanded.");
}
];
function assertScopeExpansion(aFlags) {
is(localScope.expanded, aFlags[0],
"The localScope should " + (aFlags[0] ? "" : "not ") +
"be expanded at this point (" + step + ").");
is(withScope.expanded, aFlags[1],
"The withScope should " + (aFlags[1] ? "" : "not ") +
"be expanded at this point (" + step + ").");
is(functionScope.expanded, aFlags[2],
"The functionScope should " + (aFlags[2] ? "" : "not ") +
"be expanded at this point (" + step + ").");
is(globalScope.expanded, aFlags[3],
"The globalScope should " + (aFlags[3] ? "" : "not ") +
"be expanded at this point (" + step + ").");
}
function assertVariablesCountAtLeast(aCounts) {
ok(localScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length >= aCounts[0],
"There should be " + aCounts[0] +
" variable displayed in the local scope (" + step + ").");
ok(withScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length >= aCounts[1],
"There should be " + aCounts[1] +
" variable displayed in the with scope (" + step + ").");
ok(functionScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length >= aCounts[2],
"There should be " + aCounts[2] +
" variable displayed in the function scope (" + step + ").");
ok(globalScope.target.querySelectorAll(".variables-view-variable:not([non-match])").length >= aCounts[3],
"There should be " + aCounts[3] +
" variable displayed in the global scope (" + step + ").");
step++;
}
return promise.all(tests.map(f => f()));
}
function prepareVariablesAndProperties() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded yet.");
is(functionScope.expanded, false,
"The functionScope should not be expanded yet.");
is(globalScope.expanded, false,
"The globalScope should not be expanded yet.");
// Wait for only two events to be triggered, because the Function scope is
// an environment to which scope arguments and variables are already attached.
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
is(localScope.expanded, true,
"The localScope should now be expanded.");
is(withScope.expanded, true,
"The withScope should now be expanded.");
is(functionScope.expanded, true,
"The functionScope should now be expanded.");
is(globalScope.expanded, true,
"The globalScope should now be expanded.");
withScope.collapse();
functionScope.collapse();
globalScope.collapse();
deferred.resolve();
});
withScope.expand();
functionScope.expand();
globalScope.expand();
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gEditor = null;
gVariables = null;
gSearchBox = null;
});

View File

@ -0,0 +1,81 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view filter prefs work properly.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gPrefs, gOptions, gVariables;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gPrefs = gDebugger.Prefs;
gOptions = gDebugger.DebuggerView.Options;
gVariables = gDebugger.DebuggerView.Variables;
waitForSourceShown(gPanel, ".html").then(performTest);
});
}
function performTest() {
ok(!gVariables._searchboxNode,
"There should not initially be a searchbox available in the variables view.");
ok(!gVariables._searchboxContainer,
"There should not initially be a searchbox container available in the variables view.");
ok(!gVariables._parent.parentNode.querySelector(".variables-view-searchinput"),
"The searchbox element should not be found.");
is(gPrefs.variablesSearchboxVisible, false,
"The debugger searchbox should be preffed as hidden.");
isnot(gOptions._showVariablesFilterBoxItem.getAttribute("checked"), "true",
"The options menu item should not be checked.");
gOptions._showVariablesFilterBoxItem.setAttribute("checked", "true");
gOptions._toggleShowVariablesFilterBox();
ok(gVariables._searchboxNode,
"There should be a searchbox available in the variables view.");
ok(gVariables._searchboxContainer,
"There should be a searchbox container available in the variables view.");
ok(gVariables._parent.parentNode.querySelector(".variables-view-searchinput"),
"There searchbox element should be found.");
is(gPrefs.variablesSearchboxVisible, true,
"The debugger searchbox should now be preffed as visible.");
is(gOptions._showVariablesFilterBoxItem.getAttribute("checked"), "true",
"The options menu item should now be checked.");
gOptions._showVariablesFilterBoxItem.setAttribute("checked", "false");
gOptions._toggleShowVariablesFilterBox();
ok(!gVariables._searchboxNode,
"There should not be a searchbox available in the variables view.");
ok(!gVariables._searchboxContainer,
"There should not be a searchbox container available in the variables view.");
ok(!gVariables._parent.parentNode.querySelector(".variables-view-searchinput"),
"There searchbox element should not be found.");
is(gPrefs.variablesSearchboxVisible, false,
"The debugger searchbox should now be preffed as hidden.");
isnot(gOptions._showVariablesFilterBoxItem.getAttribute("checked"), "true",
"The options menu item should now be unchecked.");
closeDebuggerAndFinish(gPanel);
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gPrefs = null;
gOptions = null;
gVariables = null;
});

View File

@ -0,0 +1,258 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly displays the properties
* of objects when debugger is paused.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
.then(initialChecks)
.then(testExpandVariables)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function initialChecks() {
let scopeNodes = gDebugger.document.querySelectorAll(".variables-view-scope");
is(scopeNodes.length, 2,
"There should be 2 scopes available.");
ok(scopeNodes[0].querySelector(".name").getAttribute("value").contains("[test]"),
"The local scope should be properly identified.");
ok(scopeNodes[1].querySelector(".name").getAttribute("value").contains("[Window]"),
"The global scope should be properly identified.");
is(gVariables.getScopeAtIndex(0).target, scopeNodes[0],
"getScopeAtIndex(0) didn't return the expected scope.");
is(gVariables.getScopeAtIndex(1).target, scopeNodes[1],
"getScopeAtIndex(1) didn't return the expected scope.");
is(gVariables.getScopeForNode(scopeNodes[0]).target, scopeNodes[0],
"getScopeForNode([0]) didn't return the expected scope.");
is(gVariables.getScopeForNode(scopeNodes[1]).target, scopeNodes[1],
"getScopeForNode([1]) didn't return the expected scope.");
is(gVariables.getScopeForNode(scopeNodes[0]).expanded, true,
"The local scope should be expanded by default.");
is(gVariables.getScopeForNode(scopeNodes[1]).expanded, false,
"The global scope should not be collapsed by default.");
}
function testExpandVariables() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
let localEnums = localScope.target.querySelector(".variables-view-element-details.enum").childNodes;
let thisVar = gVariables.getItemForNode(localEnums[0]);
let argsVar = gVariables.getItemForNode(localEnums[8]);
let cVar = gVariables.getItemForNode(localEnums[10]);
is(thisVar.target.querySelector(".name").getAttribute("value"), "this",
"Should have the right property name for 'this'.");
is(argsVar.target.querySelector(".name").getAttribute("value"), "arguments",
"Should have the right property name for 'arguments'.");
is(cVar.target.querySelector(".name").getAttribute("value"), "c",
"Should have the right property name for 'c'.");
is(thisVar.expanded, false,
"The thisVar should not be expanded at this point.");
is(argsVar.expanded, false,
"The argsVar should not be expanded at this point.");
is(cVar.expanded, false,
"The cVar should not be expanded at this point.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 3).then(() => {
is(thisVar.get("window").target.querySelector(".name").getAttribute("value"), "window",
"Should have the right property name for 'window'.");
is(thisVar.get("window").target.querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for 'window'.");
ok(thisVar.get("window").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'window'.");
is(thisVar.get("document").target.querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for 'document'.");
is(thisVar.get("document").target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"Should have the right property value for 'document'.");
ok(thisVar.get("document").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'document'.");
let argsProps = argsVar.target.querySelectorAll(".variables-view-property");
is(argsProps.length, 8,
"The 'arguments' variable should contain 5 enumerable and 3 non-enumerable properties");
is(argsProps[0].querySelector(".name").getAttribute("value"), "0",
"Should have the right property name for '0'.");
is(argsProps[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '0'.");
ok(argsProps[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '0'.");
is(argsProps[1].querySelector(".name").getAttribute("value"), "1",
"Should have the right property name for '1'.");
is(argsProps[1].querySelector(".value").getAttribute("value"), "\"beta\"",
"Should have the right property value for '1'.");
ok(argsProps[1].querySelector(".value").className.contains("token-string"),
"Should have the right token class for '1'.");
is(argsProps[2].querySelector(".name").getAttribute("value"), "2",
"Should have the right property name for '2'.");
is(argsProps[2].querySelector(".value").getAttribute("value"), "3",
"Should have the right property name for '2'.");
ok(argsProps[2].querySelector(".value").className.contains("token-number"),
"Should have the right token class for '2'.");
is(argsProps[3].querySelector(".name").getAttribute("value"), "3",
"Should have the right property name for '3'.");
is(argsProps[3].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for '3'.");
ok(argsProps[3].querySelector(".value").className.contains("token-boolean"),
"Should have the right token class for '3'.");
is(argsProps[4].querySelector(".name").getAttribute("value"), "4",
"Should have the right property name for '4'.");
is(argsProps[4].querySelector(".value").getAttribute("value"), "null",
"Should have the right property name for '4'.");
ok(argsProps[4].querySelector(".value").className.contains("token-null"),
"Should have the right token class for '4'.");
is(gVariables.getItemForNode(argsProps[0]).target,
argsVar.target.querySelectorAll(".variables-view-property")[0],
"getItemForNode([0]) didn't return the expected property.");
is(gVariables.getItemForNode(argsProps[1]).target,
argsVar.target.querySelectorAll(".variables-view-property")[1],
"getItemForNode([1]) didn't return the expected property.");
is(gVariables.getItemForNode(argsProps[2]).target,
argsVar.target.querySelectorAll(".variables-view-property")[2],
"getItemForNode([2]) didn't return the expected property.");
is(argsVar.find(argsProps[0]).target,
argsVar.target.querySelectorAll(".variables-view-property")[0],
"find([0]) didn't return the expected property.");
is(argsVar.find(argsProps[1]).target,
argsVar.target.querySelectorAll(".variables-view-property")[1],
"find([1]) didn't return the expected property.");
is(argsVar.find(argsProps[2]).target,
argsVar.target.querySelectorAll(".variables-view-property")[2],
"find([2]) didn't return the expected property.");
let cProps = cVar.target.querySelectorAll(".variables-view-property");
is(cProps.length, 7,
"The 'c' variable should contain 6 enumerable and 1 non-enumerable properties");
is(cProps[0].querySelector(".name").getAttribute("value"), "a",
"Should have the right property name for 'a'.");
is(cProps[0].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'a'.");
ok(cProps[0].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'a'.");
is(cProps[1].querySelector(".name").getAttribute("value"), "b",
"Should have the right property name for 'b'.");
is(cProps[1].querySelector(".value").getAttribute("value"), "\"beta\"",
"Should have the right property value for 'b'.");
ok(cProps[1].querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'b'.");
is(cProps[2].querySelector(".name").getAttribute("value"), "c",
"Should have the right property name for 'c'.");
is(cProps[2].querySelector(".value").getAttribute("value"), "3",
"Should have the right property value for 'c'.");
ok(cProps[2].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'c'.");
is(cProps[3].querySelector(".name").getAttribute("value"), "d",
"Should have the right property name for 'd'.");
is(cProps[3].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for 'd'.");
ok(cProps[3].querySelector(".value").className.contains("token-boolean"),
"Should have the right token class for 'd'.");
is(cProps[4].querySelector(".name").getAttribute("value"), "e",
"Should have the right property name for 'e'.");
is(cProps[4].querySelector(".value").getAttribute("value"), "null",
"Should have the right property value for 'e'.");
ok(cProps[4].querySelector(".value").className.contains("token-null"),
"Should have the right token class for 'e'.");
is(cProps[5].querySelector(".name").getAttribute("value"), "f",
"Should have the right property name for 'f'.");
is(cProps[5].querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'f'.");
ok(cProps[5].querySelector(".value").className.contains("token-undefined"),
"Should have the right token class for 'f'.");
is(gVariables.getItemForNode(cProps[0]).target,
cVar.target.querySelectorAll(".variables-view-property")[0],
"getItemForNode([0]) didn't return the expected property.");
is(gVariables.getItemForNode(cProps[1]).target,
cVar.target.querySelectorAll(".variables-view-property")[1],
"getItemForNode([1]) didn't return the expected property.");
is(gVariables.getItemForNode(cProps[2]).target,
cVar.target.querySelectorAll(".variables-view-property")[2],
"getItemForNode([2]) didn't return the expected property.");
is(cVar.find(cProps[0]).target,
cVar.target.querySelectorAll(".variables-view-property")[0],
"find([0]) didn't return the expected property.");
is(cVar.find(cProps[1]).target,
cVar.target.querySelectorAll(".variables-view-property")[1],
"find([1]) didn't return the expected property.");
is(cVar.find(cProps[2]).target,
cVar.target.querySelectorAll(".variables-view-property")[2],
"find([2]) didn't return the expected property.");
});
// Expand the 'this', 'arguments' and 'c' variables view nodes. This causes
// their properties to be retrieved and displayed.
thisVar.expand();
argsVar.expand();
cVar.expand();
is(thisVar.expanded, true,
"The thisVar should be immediately marked as expanded.");
is(argsVar.expanded, true,
"The argsVar should be immediately marked as expanded.");
is(cVar.expanded, true,
"The cVar should be immediately marked as expanded.");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
});

View File

@ -0,0 +1,546 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view displays the right variables and
* properties when debugger is paused.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
.then(testScopeVariables)
.then(testArgumentsProperties)
.then(testSimpleObject)
.then(testComplexObject)
.then(testArgumentObject)
.then(testInnerArgumentObject)
.then(testGetterSetterObject)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function testScopeVariables() {
let localScope = gVariables.getScopeAtIndex(0);
is(localScope.expanded, true,
"The local scope should be expanded by default.");
let localEnums = localScope.target.querySelector(".variables-view-element-details.enum").childNodes;
let localNonEnums = localScope.target.querySelector(".variables-view-element-details.nonenum").childNodes;
is(localEnums.length, 12,
"The local scope should contain all the created enumerable elements.");
is(localNonEnums.length, 0,
"The local scope should contain all the created non-enumerable elements.");
is(localEnums[0].querySelector(".name").getAttribute("value"), "this",
"Should have the right property name for 'this'.");
is(localEnums[0].querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for 'this'.");
ok(localEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'this'.");
is(localEnums[1].querySelector(".name").getAttribute("value"), "aArg",
"Should have the right property name for 'aArg'.");
is(localEnums[1].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'aArg'.");
ok(localEnums[1].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'aArg'.");
is(localEnums[2].querySelector(".name").getAttribute("value"), "bArg",
"Should have the right property name for 'bArg'.");
is(localEnums[2].querySelector(".value").getAttribute("value"), "\"beta\"",
"Should have the right property value for 'bArg'.");
ok(localEnums[2].querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'bArg'.");
is(localEnums[3].querySelector(".name").getAttribute("value"), "cArg",
"Should have the right property name for 'cArg'.");
is(localEnums[3].querySelector(".value").getAttribute("value"), "3",
"Should have the right property value for 'cArg'.");
ok(localEnums[3].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'cArg'.");
is(localEnums[4].querySelector(".name").getAttribute("value"), "dArg",
"Should have the right property name for 'dArg'.");
is(localEnums[4].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for 'dArg'.");
ok(localEnums[4].querySelector(".value").className.contains("token-boolean"),
"Should have the right token class for 'dArg'.");
is(localEnums[5].querySelector(".name").getAttribute("value"), "eArg",
"Should have the right property name for 'eArg'.");
is(localEnums[5].querySelector(".value").getAttribute("value"), "null",
"Should have the right property value for 'eArg'.");
ok(localEnums[5].querySelector(".value").className.contains("token-null"),
"Should have the right token class for 'eArg'.");
is(localEnums[6].querySelector(".name").getAttribute("value"), "fArg",
"Should have the right property name for 'fArg'.");
is(localEnums[6].querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'fArg'.");
ok(localEnums[6].querySelector(".value").className.contains("token-undefined"),
"Should have the right token class for 'fArg'.");
is(localEnums[7].querySelector(".name").getAttribute("value"), "a",
"Should have the right property name for 'a'.");
is(localEnums[7].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'a'.");
ok(localEnums[7].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'a'.");
is(localEnums[8].querySelector(".name").getAttribute("value"), "arguments",
"Should have the right property name for 'arguments'.");
is(localEnums[8].querySelector(".value").getAttribute("value"), "Arguments",
"Should have the right property value for 'arguments'.");
ok(localEnums[8].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'arguments'.");
is(localEnums[9].querySelector(".name").getAttribute("value"), "b",
"Should have the right property name for 'b'.");
is(localEnums[9].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'b'.");
ok(localEnums[9].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'b'.");
is(localEnums[10].querySelector(".name").getAttribute("value"), "c",
"Should have the right property name for 'c'.");
is(localEnums[10].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'c'.");
ok(localEnums[10].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'c'.");
is(localEnums[11].querySelector(".name").getAttribute("value"), "myVar",
"Should have the right property name for 'myVar'.");
is(localEnums[11].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'myVar'.");
ok(localEnums[11].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'myVar'.");
}
function testArgumentsProperties() {
let deferred = promise.defer();
let argsVar = gVariables.getScopeAtIndex(0).get("arguments");
is(argsVar.expanded, false,
"The 'arguments' variable should not be expanded by default.");
let argsEnums = argsVar.target.querySelector(".variables-view-element-details.enum").childNodes;
let argsNonEnums = argsVar.target.querySelector(".variables-view-element-details.nonenum").childNodes;
gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, () => {
is(argsEnums.length, 5,
"The 'arguments' variable should contain all the created enumerable elements.");
is(argsNonEnums.length, 3,
"The 'arguments' variable should contain all the created non-enumerable elements.");
is(argsEnums[0].querySelector(".name").getAttribute("value"), "0",
"Should have the right property name for '0'.");
is(argsEnums[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '0'.");
ok(argsEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '0'.");
is(argsEnums[1].querySelector(".name").getAttribute("value"), "1",
"Should have the right property name for '1'.");
is(argsEnums[1].querySelector(".value").getAttribute("value"), "\"beta\"",
"Should have the right property value for '1'.");
ok(argsEnums[1].querySelector(".value").className.contains("token-string"),
"Should have the right token class for '1'.");
is(argsEnums[2].querySelector(".name").getAttribute("value"), "2",
"Should have the right property name for '2'.");
is(argsEnums[2].querySelector(".value").getAttribute("value"), "3",
"Should have the right property name for '2'.");
ok(argsEnums[2].querySelector(".value").className.contains("token-number"),
"Should have the right token class for '2'.");
is(argsEnums[3].querySelector(".name").getAttribute("value"), "3",
"Should have the right property name for '3'.");
is(argsEnums[3].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for '3'.");
ok(argsEnums[3].querySelector(".value").className.contains("token-boolean"),
"Should have the right token class for '3'.");
is(argsEnums[4].querySelector(".name").getAttribute("value"), "4",
"Should have the right property name for '4'.");
is(argsEnums[4].querySelector(".value").getAttribute("value"), "null",
"Should have the right property name for '4'.");
ok(argsEnums[4].querySelector(".value").className.contains("token-null"),
"Should have the right token class for '4'.");
is(argsNonEnums[0].querySelector(".name").getAttribute("value"), "callee",
"Should have the right property name for 'callee'.");
is(argsNonEnums[0].querySelector(".value").getAttribute("value"), "Function",
"Should have the right property name for 'callee'.");
ok(argsNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'callee'.");
is(argsNonEnums[1].querySelector(".name").getAttribute("value"), "length",
"Should have the right property name for 'length'.");
is(argsNonEnums[1].querySelector(".value").getAttribute("value"), "5",
"Should have the right property value for 'length'.");
ok(argsNonEnums[1].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'length'.");
is(argsNonEnums[2].querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(argsNonEnums[2].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(argsNonEnums[2].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
deferred.resolve();
});
argsVar.expand();
return deferred.promise;
}
function testSimpleObject() {
let deferred = promise.defer();
let bVar = gVariables.getScopeAtIndex(0).get("b");
is(bVar.expanded, false,
"The 'b' variable should not be expanded by default.");
let bEnums = bVar.target.querySelector(".variables-view-element-details.enum").childNodes;
let bNonEnums = bVar.target.querySelector(".variables-view-element-details.nonenum").childNodes;
gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, () => {
is(bEnums.length, 1,
"The 'b' variable should contain all the created enumerable elements.");
is(bNonEnums.length, 1,
"The 'b' variable should contain all the created non-enumerable elements.");
is(bEnums[0].querySelector(".name").getAttribute("value"), "a",
"Should have the right property name for 'a'.");
is(bEnums[0].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'a'.");
ok(bEnums[0].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'a'.");
is(bNonEnums[0].querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(bNonEnums[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(bNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
deferred.resolve();
});
bVar.expand();
return deferred.promise;
}
function testComplexObject() {
let deferred = promise.defer();
let cVar = gVariables.getScopeAtIndex(0).get("c");
is(cVar.expanded, false,
"The 'c' variable should not be expanded by default.");
let cEnums = cVar.target.querySelector(".variables-view-element-details.enum").childNodes;
let cNonEnums = cVar.target.querySelector(".variables-view-element-details.nonenum").childNodes;
gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, () => {
is(cEnums.length, 6,
"The 'c' variable should contain all the created enumerable elements.");
is(cNonEnums.length, 1,
"The 'c' variable should contain all the created non-enumerable elements.");
is(cEnums[0].querySelector(".name").getAttribute("value"), "a",
"Should have the right property name for 'a'.");
is(cEnums[0].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'a'.");
ok(cEnums[0].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'a'.");
is(cEnums[1].querySelector(".name").getAttribute("value"), "b",
"Should have the right property name for 'b'.");
is(cEnums[1].querySelector(".value").getAttribute("value"), "\"beta\"",
"Should have the right property value for 'b'.");
ok(cEnums[1].querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'b'.");
is(cEnums[2].querySelector(".name").getAttribute("value"), "c",
"Should have the right property name for 'c'.");
is(cEnums[2].querySelector(".value").getAttribute("value"), "3",
"Should have the right property value for 'c'.");
ok(cEnums[2].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'c'.");
is(cEnums[3].querySelector(".name").getAttribute("value"), "d",
"Should have the right property name for 'd'.");
is(cEnums[3].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for 'd'.");
ok(cEnums[3].querySelector(".value").className.contains("token-boolean"),
"Should have the right token class for 'd'.");
is(cEnums[4].querySelector(".name").getAttribute("value"), "e",
"Should have the right property name for 'e'.");
is(cEnums[4].querySelector(".value").getAttribute("value"), "null",
"Should have the right property value for 'e'.");
ok(cEnums[4].querySelector(".value").className.contains("token-null"),
"Should have the right token class for 'e'.");
is(cEnums[5].querySelector(".name").getAttribute("value"), "f",
"Should have the right property name for 'f'.");
is(cEnums[5].querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'f'.");
ok(cEnums[5].querySelector(".value").className.contains("token-undefined"),
"Should have the right token class for 'f'.");
is(cNonEnums[0].querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(cNonEnums[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(cNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
deferred.resolve();
});
cVar.expand();
return deferred.promise;
}
function testArgumentObject() {
let deferred = promise.defer();
let argVar = gVariables.getScopeAtIndex(0).get("aArg");
is(argVar.expanded, false,
"The 'aArg' variable should not be expanded by default.");
let argEnums = argVar.target.querySelector(".variables-view-element-details.enum").childNodes;
let argNonEnums = argVar.target.querySelector(".variables-view-element-details.nonenum").childNodes;
gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, () => {
is(argEnums.length, 6,
"The 'aArg' variable should contain all the created enumerable elements.");
is(argNonEnums.length, 1,
"The 'aArg' variable should contain all the created non-enumerable elements.");
is(argEnums[0].querySelector(".name").getAttribute("value"), "a",
"Should have the right property name for 'a'.");
is(argEnums[0].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'a'.");
ok(argEnums[0].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'a'.");
is(argEnums[1].querySelector(".name").getAttribute("value"), "b",
"Should have the right property name for 'b'.");
is(argEnums[1].querySelector(".value").getAttribute("value"), "\"beta\"",
"Should have the right property value for 'b'.");
ok(argEnums[1].querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'b'.");
is(argEnums[2].querySelector(".name").getAttribute("value"), "c",
"Should have the right property name for 'c'.");
is(argEnums[2].querySelector(".value").getAttribute("value"), "3",
"Should have the right property value for 'c'.");
ok(argEnums[2].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'c'.");
is(argEnums[3].querySelector(".name").getAttribute("value"), "d",
"Should have the right property name for 'd'.");
is(argEnums[3].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for 'd'.");
ok(argEnums[3].querySelector(".value").className.contains("token-boolean"),
"Should have the right token class for 'd'.");
is(argEnums[4].querySelector(".name").getAttribute("value"), "e",
"Should have the right property name for 'e'.");
is(argEnums[4].querySelector(".value").getAttribute("value"), "null",
"Should have the right property value for 'e'.");
ok(argEnums[4].querySelector(".value").className.contains("token-null"),
"Should have the right token class for 'e'.");
is(argEnums[5].querySelector(".name").getAttribute("value"), "f",
"Should have the right property name for 'f'.");
is(argEnums[5].querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'f'.");
ok(argEnums[5].querySelector(".value").className.contains("token-undefined"),
"Should have the right token class for 'f'.");
is(argNonEnums[0].querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(argNonEnums[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(argNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
deferred.resolve();
});
argVar.expand();
return deferred.promise;
}
function testInnerArgumentObject() {
let deferred = promise.defer();
let argProp = gVariables.getScopeAtIndex(0).get("arguments").get("0");
is(argProp.expanded, false,
"The 'arguments[0]' property should not be expanded by default.");
let argEnums = argProp.target.querySelector(".variables-view-element-details.enum").childNodes;
let argNonEnums = argProp.target.querySelector(".variables-view-element-details.nonenum").childNodes;
gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, () => {
is(argEnums.length, 6,
"The 'arguments[0]' property should contain all the created enumerable elements.");
is(argNonEnums.length, 1,
"The 'arguments[0]' property should contain all the created non-enumerable elements.");
is(argEnums[0].querySelector(".name").getAttribute("value"), "a",
"Should have the right property name for 'a'.");
is(argEnums[0].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'a'.");
ok(argEnums[0].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'a'.");
is(argEnums[1].querySelector(".name").getAttribute("value"), "b",
"Should have the right property name for 'b'.");
is(argEnums[1].querySelector(".value").getAttribute("value"), "\"beta\"",
"Should have the right property value for 'b'.");
ok(argEnums[1].querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'b'.");
is(argEnums[2].querySelector(".name").getAttribute("value"), "c",
"Should have the right property name for 'c'.");
is(argEnums[2].querySelector(".value").getAttribute("value"), "3",
"Should have the right property value for 'c'.");
ok(argEnums[2].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'c'.");
is(argEnums[3].querySelector(".name").getAttribute("value"), "d",
"Should have the right property name for 'd'.");
is(argEnums[3].querySelector(".value").getAttribute("value"), "false",
"Should have the right property value for 'd'.");
ok(argEnums[3].querySelector(".value").className.contains("token-boolean"),
"Should have the right token class for 'd'.");
is(argEnums[4].querySelector(".name").getAttribute("value"), "e",
"Should have the right property name for 'e'.");
is(argEnums[4].querySelector(".value").getAttribute("value"), "null",
"Should have the right property value for 'e'.");
ok(argEnums[4].querySelector(".value").className.contains("token-null"),
"Should have the right token class for 'e'.");
is(argEnums[5].querySelector(".name").getAttribute("value"), "f",
"Should have the right property name for 'f'.");
is(argEnums[5].querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'f'.");
ok(argEnums[5].querySelector(".value").className.contains("token-undefined"),
"Should have the right token class for 'f'.");
is(argNonEnums[0].querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(argNonEnums[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(argNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
deferred.resolve();
});
argProp.expand();
return deferred.promise;
}
function testGetterSetterObject() {
let deferred = promise.defer();
let myVar = gVariables.getScopeAtIndex(0).get("myVar");
is(myVar.expanded, false,
"The myVar variable should not be expanded by default.");
let myVarEnums = myVar.target.querySelector(".variables-view-element-details.enum").childNodes;
let myVarNonEnums = myVar.target.querySelector(".variables-view-element-details.nonenum").childNodes;
gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, () => {
is(myVarEnums.length, 2,
"The myVar should contain all the created enumerable elements.");
is(myVarNonEnums.length, 1,
"The myVar should contain all the created non-enumerable elements.");
is(myVarEnums[0].querySelector(".name").getAttribute("value"), "_prop",
"Should have the right property name for '_prop'.");
is(myVarEnums[0].querySelector(".value").getAttribute("value"), "42",
"Should have the right property value for '_prop'.");
ok(myVarEnums[0].querySelector(".value").className.contains("token-number"),
"Should have the right token class for '_prop'.");
is(myVarEnums[1].querySelector(".name").getAttribute("value"), "prop",
"Should have the right property name for 'prop'.");
is(myVarEnums[1].querySelector(".value").getAttribute("value"), "",
"Should have the right property value for 'prop'.");
ok(!myVarEnums[1].querySelector(".value").className.contains("token"),
"Should have no token class for 'prop'.");
is(myVarNonEnums[0].querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(myVarNonEnums[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(myVarNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
let propEnums = myVarEnums[1].querySelector(".variables-view-element-details.enum").childNodes;
let propNonEnums = myVarEnums[1].querySelector(".variables-view-element-details.nonenum").childNodes;
is(propEnums.length, 0,
"The propEnums should contain all the created enumerable elements.");
is(propNonEnums.length, 2,
"The propEnums should contain all the created non-enumerable elements.");
is(propNonEnums[0].querySelector(".name").getAttribute("value"), "get",
"Should have the right property name for 'get'.");
is(propNonEnums[0].querySelector(".value").getAttribute("value"), "Function",
"Should have the right property value for 'get'.");
ok(propNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'get'.");
is(propNonEnums[1].querySelector(".name").getAttribute("value"), "set",
"Should have the right property name for 'set'.");
is(propNonEnums[1].querySelector(".value").getAttribute("value"), "Function",
"Should have the right property value for 'set'.");
ok(propNonEnums[1].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'set'.");
deferred.resolve();
});
myVar.expand();
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
});

View File

@ -0,0 +1,151 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view displays the right variables and
* properties in the global scope when debugger is paused.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
.then(expandGlobalScope)
.then(testGlobalScope)
.then(expandWindowVariable)
.then(testWindowVariable)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function expandGlobalScope() {
let deferred = promise.defer();
let globalScope = gVariables.getScopeAtIndex(1);
is(globalScope.expanded, false,
"The global scope should not be expanded by default.");
gDebugger.once(gDebugger.EVENTS.FETCHED_VARIABLES, deferred.resolve);
EventUtils.sendMouseEvent({ type: "mousedown" },
globalScope.target.querySelector(".name"),
gDebugger);
return deferred.promise;
}
function testGlobalScope() {
let globalScope = gVariables.getScopeAtIndex(1);
is(globalScope.expanded, true,
"The global scope should now be expanded.");
is(globalScope.get("InstallTrigger").target.querySelector(".name").getAttribute("value"), "InstallTrigger",
"Should have the right property name for 'InstallTrigger'.");
is(globalScope.get("InstallTrigger").target.querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'InstallTrigger'.");
is(globalScope.get("SpecialPowers").target.querySelector(".name").getAttribute("value"), "SpecialPowers",
"Should have the right property name for 'SpecialPowers'.");
is(globalScope.get("SpecialPowers").target.querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'SpecialPowers'.");
is(globalScope.get("window").target.querySelector(".name").getAttribute("value"), "window",
"Should have the right property name for 'window'.");
is(globalScope.get("window").target.querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for 'window'.");
is(globalScope.get("document").target.querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for 'document'.");
is(globalScope.get("document").target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"Should have the right property value for 'document'.");
is(globalScope.get("undefined").target.querySelector(".name").getAttribute("value"), "undefined",
"Should have the right property name for 'undefined'.");
is(globalScope.get("undefined").target.querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'undefined'.");
is(globalScope.get("undefined").target.querySelector(".enum").childNodes.length, 0,
"Should have no child enumerable properties for 'undefined'.");
is(globalScope.get("undefined").target.querySelector(".nonenum").childNodes.length, 0,
"Should have no child non-enumerable properties for 'undefined'.");
}
function expandWindowVariable() {
let deferred = promise.defer();
let windowVar = gVariables.getScopeAtIndex(1).get("window");
is(windowVar.expanded, false,
"The window variable should not be expanded by default.");
gDebugger.once(gDebugger.EVENTS.FETCHED_PROPERTIES, deferred.resolve);
EventUtils.sendMouseEvent({ type: "mousedown" },
windowVar.target.querySelector(".name"),
gDebugger);
return deferred.promise;
}
function testWindowVariable() {
let windowVar = gVariables.getScopeAtIndex(1).get("window");
is(windowVar.expanded, true,
"The window variable should now be expanded.");
is(windowVar.get("InstallTrigger").target.querySelector(".name").getAttribute("value"), "InstallTrigger",
"Should have the right property name for 'InstallTrigger'.");
is(windowVar.get("InstallTrigger").target.querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'InstallTrigger'.");
is(windowVar.get("SpecialPowers").target.querySelector(".name").getAttribute("value"), "SpecialPowers",
"Should have the right property name for 'SpecialPowers'.");
is(windowVar.get("SpecialPowers").target.querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'SpecialPowers'.");
is(windowVar.get("window").target.querySelector(".name").getAttribute("value"), "window",
"Should have the right property name for 'window'.");
is(windowVar.get("window").target.querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for 'window'.");
is(windowVar.get("document").target.querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for 'document'.");
is(windowVar.get("document").target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"Should have the right property value for 'document'.");
is(windowVar.get("undefined").target.querySelector(".name").getAttribute("value"), "undefined",
"Should have the right property name for 'undefined'.");
is(windowVar.get("undefined").target.querySelector(".value").getAttribute("value"), "undefined",
"Should have the right property value for 'undefined'.");
is(windowVar.get("undefined").target.querySelector(".enum").childNodes.length, 0,
"Should have no child enumerable properties for 'undefined'.");
is(windowVar.get("undefined").target.querySelector(".nonenum").childNodes.length, 0,
"Should have no child non-enumerable properties for 'undefined'.");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
});

View File

@ -0,0 +1,209 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view is correctly populated in 'with' frames.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
// The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work.
promise.all([
waitForSourceAndCaret(gPanel, ".html", 22),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
]).then(testFirstWithScope)
.then(expandSecondWithScope)
.then(testSecondWithScope)
.then(expandFunctionScope)
.then(testFunctionScope)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function testFirstWithScope() {
let firstWithScope = gVariables.getScopeAtIndex(0);
is(firstWithScope.expanded, true,
"The first 'with' scope should be expanded by default.");
ok(firstWithScope.target.querySelector(".name").getAttribute("value").contains("[Object]"),
"The first 'with' scope should be properly identified.");
let withEnums = firstWithScope._enum.childNodes;
let withNonEnums = firstWithScope._nonenum.childNodes;
is(withEnums.length, 3,
"The first 'with' scope should contain all the created enumerable elements.");
is(withNonEnums.length, 1,
"The first 'with' scope should contain all the created non-enumerable elements.");
is(withEnums[0].querySelector(".name").getAttribute("value"), "this",
"Should have the right property name for 'this'.");
is(withEnums[0].querySelector(".value").getAttribute("value"), "Window",
"Should have the right property value for 'this'.");
ok(withEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'this'.");
is(withEnums[1].querySelector(".name").getAttribute("value"), "one",
"Should have the right property name for 'one'.");
is(withEnums[1].querySelector(".value").getAttribute("value"), "1",
"Should have the right property value for 'one'.");
ok(withEnums[1].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'one'.");
is(withEnums[2].querySelector(".name").getAttribute("value"), "two",
"Should have the right property name for 'two'.");
is(withEnums[2].querySelector(".value").getAttribute("value"), "2",
"Should have the right property value for 'two'.");
ok(withEnums[2].querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'two'.");
is(withNonEnums[0].querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(withNonEnums[0].querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(withNonEnums[0].querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
}
function expandSecondWithScope() {
let deferred = promise.defer();
let secondWithScope = gVariables.getScopeAtIndex(1);
is(secondWithScope.expanded, false,
"The second 'with' scope should not be expanded by default.");
gDebugger.once(gDebugger.EVENTS.FETCHED_VARIABLES, deferred.resolve);
EventUtils.sendMouseEvent({ type: "mousedown" },
secondWithScope.target.querySelector(".name"),
gDebugger);
return deferred.promise;
}
function testSecondWithScope() {
let secondWithScope = gVariables.getScopeAtIndex(1);
is(secondWithScope.expanded, true,
"The second 'with' scope should now be expanded.");
ok(secondWithScope.target.querySelector(".name").getAttribute("value").contains("[Math]"),
"The second 'with' scope should be properly identified.");
let withEnums = secondWithScope._enum.childNodes;
let withNonEnums = secondWithScope._nonenum.childNodes;
is(withEnums.length, 0,
"The second 'with' scope should contain all the created enumerable elements.");
isnot(withNonEnums.length, 0,
"The second 'with' scope should contain all the created non-enumerable elements.");
is(secondWithScope.get("E").target.querySelector(".name").getAttribute("value"), "E",
"Should have the right property name for 'E'.");
is(secondWithScope.get("E").target.querySelector(".value").getAttribute("value"), "2.718281828459045",
"Should have the right property value for 'E'.");
ok(secondWithScope.get("E").target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'E'.");
is(secondWithScope.get("PI").target.querySelector(".name").getAttribute("value"), "PI",
"Should have the right property name for 'PI'.");
is(secondWithScope.get("PI").target.querySelector(".value").getAttribute("value"), "3.141592653589793",
"Should have the right property value for 'PI'.");
ok(secondWithScope.get("PI").target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'PI'.");
is(secondWithScope.get("random").target.querySelector(".name").getAttribute("value"), "random",
"Should have the right property name for 'random'.");
is(secondWithScope.get("random").target.querySelector(".value").getAttribute("value"), "Function",
"Should have the right property value for 'random'.");
ok(secondWithScope.get("random").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'random'.");
is(secondWithScope.get("__proto__").target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(secondWithScope.get("__proto__").target.querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for '__proto__'.");
ok(secondWithScope.get("__proto__").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
}
function expandFunctionScope() {
let funcScope = gVariables.getScopeAtIndex(2);
is(funcScope.expanded, false,
"The function scope shouldn't be expanded by default, but the " +
"variables have been already fetched. This is how local scopes work.");
EventUtils.sendMouseEvent({ type: "mousedown" },
funcScope.target.querySelector(".name"),
gDebugger);
return promise.resolve(null);
}
function testFunctionScope() {
let funcScope = gVariables.getScopeAtIndex(2);
is(funcScope.expanded, true,
"The function scope should now be expanded.");
ok(funcScope.target.querySelector(".name").getAttribute("value").contains("[test]"),
"The function scope should be properly identified.");
let funcEnums = funcScope._enum.childNodes;
let funcNonEnums = funcScope._nonenum.childNodes;
is(funcEnums.length, 6,
"The function scope should contain all the created enumerable elements.");
is(funcNonEnums.length, 0,
"The function scope should contain all the created non-enumerable elements.");
is(funcScope.get("aNumber").target.querySelector(".name").getAttribute("value"), "aNumber",
"Should have the right property name for 'aNumber'.");
is(funcScope.get("aNumber").target.querySelector(".value").getAttribute("value"), "10",
"Should have the right property value for 'aNumber'.");
ok(funcScope.get("aNumber").target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'aNumber'.");
is(funcScope.get("a").target.querySelector(".name").getAttribute("value"), "a",
"Should have the right property name for 'a'.");
is(funcScope.get("a").target.querySelector(".value").getAttribute("value"), "314.1592653589793",
"Should have the right property value for 'a'.");
ok(funcScope.get("a").target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'a'.");
is(funcScope.get("r").target.querySelector(".name").getAttribute("value"), "r",
"Should have the right property name for 'r'.");
is(funcScope.get("r").target.querySelector(".value").getAttribute("value"), "10",
"Should have the right property value for 'r'.");
ok(funcScope.get("r").target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'r'.");
is(funcScope.get("foo").target.querySelector(".name").getAttribute("value"), "foo",
"Should have the right property name for 'foo'.");
is(funcScope.get("foo").target.querySelector(".value").getAttribute("value"), "6.283185307179586",
"Should have the right property value for 'foo'.");
ok(funcScope.get("foo").target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'foo'.");
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

View File

@ -0,0 +1,89 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* This test checks that we properly set the frozen, sealed, and non-extensbile
* attributes on variables so that the F/S/N is shown in the variables view.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
prepareTest();
});
}
function prepareTest() {
gDebugger.once(gDebugger.EVENTS.FETCHED_SCOPES, runTest);
gDebuggee.eval("(" + function() {
var frozen = Object.freeze({});
var sealed = Object.seal({});
var nonExtensible = Object.preventExtensions({});
var extensible = {};
var string = "foo bar baz";
debugger;
} + "())");
}
function runTest() {
let hasNoneTester = function(aVariable) {
ok(!aVariable.hasAttribute("frozen"),
"The variable should not be frozen.");
ok(!aVariable.hasAttribute("sealed"),
"The variable should not be sealed.");
ok(!aVariable.hasAttribute("non-extensible"),
"The variable should be extensible.");
};
let testers = {
frozen: function (aVariable) {
ok(aVariable.hasAttribute("frozen"),
"The variable should be frozen.");
},
sealed: function (aVariable) {
ok(aVariable.hasAttribute("sealed"),
"The variable should be sealed.");
},
nonExtensible: function (aVariable) {
ok(aVariable.hasAttribute("non-extensible"),
"The variable should be non-extensible.");
},
extensible: hasNoneTester,
string: hasNoneTester,
arguments: hasNoneTester,
this: hasNoneTester
};
let variables = gDebugger.document.querySelectorAll(".variable-or-property");
for (let variable of variables) {
let name = variable.querySelector(".name").getAttribute("value");
let tester = testers[name];
delete testers[name];
ok(tester, "We should have a tester for the '" + name + "' variable.");
tester(variable);
}
is(Object.keys(testers).length, 0,
"We should have run and removed all the testers.");
resumeDebuggerThenCloseAndFinish(gPanel);
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

View File

@ -0,0 +1,107 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Test that non-enumerable variables and properties can be hidden
* in the variables view.
*/
const TAB_URL = EXAMPLE_URL + "doc_recursion-stack.html";
let gTab, gDebuggee, gPanel, gDebugger;
function test() {
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
waitForSourceAndCaretAndScopes(gPanel, ".html", 14).then(performTest);
gDebuggee.simpleCall();
});
}
function performTest() {
let testScope = gDebugger.DebuggerView.Variables.addScope("test-scope");
let testVar = testScope.addItem("foo");
testVar.addItems({
foo: {
value: "bar",
enumerable: true
},
bar: {
value: "foo",
enumerable: false
}
});
// Expand the scope and variable.
testScope.expand();
testVar.expand();
// Expanding the non-enumerable container is synchronously dispatched
// on the main thread, so wait for the next tick.
executeSoon(() => {
let details = testVar._enum;
let nonenum = testVar._nonenum;
is(details.childNodes.length, 1,
"There should be just one property in the .details container.");
ok(details.hasAttribute("open"),
".details container should be visible.");
ok(nonenum.hasAttribute("open"),
".nonenum container should be visible.");
is(nonenum.childNodes.length, 1,
"There should be just one property in the .nonenum container.");
// Uncheck 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "true");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
ok(details.hasAttribute("open"),
".details container should stay visible.");
ok(!nonenum.hasAttribute("open"),
".nonenum container should become hidden.");
// Check 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "false");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
ok(details.hasAttribute("open"),
".details container should stay visible.");
ok(nonenum.hasAttribute("open"),
".nonenum container should become visible.");
// Collapse the variable. This is done on the current tick.
testVar.collapse();
ok(!details.hasAttribute("open"),
".details container should be hidden.");
ok(!nonenum.hasAttribute("open"),
".nonenum container should be hidden.");
// Uncheck 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "true");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
ok(!details.hasAttribute("open"),
".details container should stay hidden.");
ok(!nonenum.hasAttribute("open"),
".nonenum container should stay hidden.");
// Check 'show hidden properties'.
gDebugger.DebuggerView.Options._showVariablesOnlyEnumItem.setAttribute("checked", "false");
gDebugger.DebuggerView.Options._toggleShowVariablesOnlyEnum();
resumeDebuggerThenCloseAndFinish(gPanel);
});
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
});

View File

@ -0,0 +1,217 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view remains responsive when faced with
* huge ammounts of data.
*/
const TAB_URL = EXAMPLE_URL + "doc_large-array-buffer.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables;
function test() {
// This is a very, very stressful test.
// Thankfully, after bug 830344 none of this will be necessary anymore.
requestLongerTimeout(10);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
gDebugger.DebuggerView.Variables.lazyAppend = true;
waitForSourceAndCaretAndScopes(gPanel, ".html", 18)
.then(() => performTest())
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function performTest() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
is(localScope.expanded, true,
"The local scope should be expanded by default.");
let localEnums = localScope.target.querySelector(".variables-view-element-details.enum").childNodes;
let localNonEnums = localScope.target.querySelector(".variables-view-element-details.nonenum").childNodes;
is(localEnums.length, 5,
"The local scope should contain all the created enumerable elements.");
is(localNonEnums.length, 0,
"The local scope should contain all the created non-enumerable elements.");
let bufferVar = localScope.get("buffer");
let zVar = localScope.get("z");
is(bufferVar.target.querySelector(".name").getAttribute("value"), "buffer",
"Should have the right property name for 'buffer'.");
is(bufferVar.target.querySelector(".value").getAttribute("value"), "ArrayBuffer",
"Should have the right property value for 'buffer'.");
ok(bufferVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'buffer'.");
is(zVar.target.querySelector(".name").getAttribute("value"), "z",
"Should have the right property name for 'z'.");
is(zVar.target.querySelector(".value").getAttribute("value"), "Int8Array",
"Should have the right property value for 'z'.");
ok(zVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'z'.");
EventUtils.sendMouseEvent({ type: "mousedown" },
bufferVar.target.querySelector(".arrow"),
gDebugger);
EventUtils.sendMouseEvent({ type: "mousedown" },
zVar.target.querySelector(".arrow"),
gDebugger);
// Need to wait for 0 enumerable and 2 non-enumerable properties in bufferVar,
// and 10000 enumerable and 5 non-enumerable properties in zVar.
let total = 0 + 2 + 10000 + 5;
let loaded = 0;
let paints = 0;
// Make sure the variables view doesn't scroll while adding the properties.
let scrollTop = gVariables._list.parentNode.scrollTop;
waitForProperties(total, {
onLoading: function(aLoaded) {
ok(aLoaded >= loaded,
"Should have loaded more properties.");
is(gVariables._list.scrollTop, scrollTop,
"The variables view hasn't scrolled.");
info("Displayed " + aLoaded + " properties, not finished yet.");
loaded = aLoaded;
paints++;
},
onFinished: function(aLoaded) {
ok(aLoaded == total,
"Displayed all the properties.");
is(gVariables._list.scrollTop, scrollTop,
"The variables view hasn't scrolled.");
isnot(paints, 0,
"Debugger was unresponsive, sad panda.");
is(bufferVar._enum.childNodes.length, 0,
"The bufferVar should contain all the created enumerable elements.");
is(bufferVar._nonenum.childNodes.length, 2,
"The bufferVar should contain all the created non-enumerable elements.");
let bufferVarByteLengthProp = bufferVar.get("byteLength");
let bufferVarProtoProp = bufferVar.get("__proto__");
is(bufferVarByteLengthProp.target.querySelector(".name").getAttribute("value"), "byteLength",
"Should have the right property name for 'byteLength'.");
is(bufferVarByteLengthProp.target.querySelector(".value").getAttribute("value"), "10000",
"Should have the right property value for 'byteLength'.");
ok(bufferVarByteLengthProp.target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'byteLength'.");
is(bufferVarProtoProp.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(bufferVarProtoProp.target.querySelector(".value").getAttribute("value"), "ArrayBufferPrototype",
"Should have the right property value for '__proto__'.");
ok(bufferVarProtoProp.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
is(zVar._enum.childNodes.length, 10000,
"The zVar should contain all the created enumerable elements.");
is(zVar._nonenum.childNodes.length, 5,
"The zVar should contain all the created non-enumerable elements.");
let zVarByteLengthProp = zVar.get("byteLength");
let zVarByteOffsetProp = zVar.get("byteOffset");
let zVarProtoProp = zVar.get("__proto__");
is(zVarByteLengthProp.target.querySelector(".name").getAttribute("value"), "byteLength",
"Should have the right property name for 'byteLength'.");
is(zVarByteLengthProp.target.querySelector(".value").getAttribute("value"), "10000",
"Should have the right property value for 'byteLength'.");
ok(zVarByteLengthProp.target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'byteLength'.");
is(zVarByteOffsetProp.target.querySelector(".name").getAttribute("value"), "byteOffset",
"Should have the right property name for 'byteOffset'.");
is(zVarByteOffsetProp.target.querySelector(".value").getAttribute("value"), "0",
"Should have the right property value for 'byteOffset'.");
ok(zVarByteOffsetProp.target.querySelector(".value").className.contains("token-number"),
"Should have the right token class for 'byteOffset'.");
is(zVarProtoProp.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(zVarProtoProp.target.querySelector(".value").getAttribute("value"), "Int8ArrayPrototype",
"Should have the right property value for '__proto__'.");
ok(zVarProtoProp.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
let arrayElements = zVar._enum.childNodes;
for (let i = 0, len = arrayElements.length; i < len; i++) {
let node = arrayElements[i];
let name = node.querySelector(".name").getAttribute("value");
let value = node.querySelector(".value").getAttribute("value");
if (name !== i + "" || value !== "0") {
ok(false, "The array items aren't in the correct order.");
}
}
deferred.resolve();
},
onTimeout: function() {
ok(false, "Timed out while polling for the properties.");
deferred.resolve();
}
});
return deferred.promise;
}
function waitForProperties(aTotal, aCallbacks, aInterval = 10) {
let localScope = gVariables.getScopeAtIndex(0);
let bufferEnum = localScope.get("buffer")._enum.childNodes;
let bufferNonEnum = localScope.get("buffer")._nonenum.childNodes;
let zEnum = localScope.get("z")._enum.childNodes;
let zNonEnum = localScope.get("z")._nonenum.childNodes;
// Poll every few milliseconds until the properties are retrieved.
let count = 0;
let intervalId = window.setInterval(() => {
// Make sure we don't wait for too long.
if (++count > 1000) {
window.clearInterval(intervalId);
aCallbacks.onTimeout();
return;
}
// Check if we need to wait for a few more properties to be fetched.
let loaded = bufferEnum.length + bufferNonEnum.length + zEnum.length + zNonEnum.length;
if (loaded < aTotal) {
aCallbacks.onLoading(loaded);
return;
}
// We got all the properties, it's safe to callback.
window.clearInterval(intervalId);
aCallbacks.onFinished(loaded);
}, aInterval);
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
});

View File

@ -0,0 +1,206 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly re-expands nodes after pauses.
*/
const TAB_URL = EXAMPLE_URL + "doc_with-frame.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gBreakpoints, gSources, gVariables;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(4);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gBreakpoints = gDebugger.DebuggerController.Breakpoints;
gSources = gDebugger.DebuggerView.Sources;
gVariables = gDebugger.DebuggerView.Variables;
waitForSourceShown(gPanel, ".html")
.then(addBreakpoint)
.then(() => ensureThreadClientState(gPanel, "resumed"))
.then(pauseDebuggee)
.then(prepareVariablesAndProperties)
.then(stepInDebuggee)
.then(testVariablesExpand)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
});
}
function addBreakpoint() {
return gBreakpoints.addBreakpoint({ url: gSources.selectedValue, line: 21 });
}
function pauseDebuggee() {
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
// The first 'with' scope should be expanded by default, but the
// variables haven't been fetched yet. This is how 'with' scopes work.
return promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES)
]);
}
function stepInDebuggee() {
// Spin the event loop before causing the debuggee to pause, to allow
// this function to return first.
executeSoon(() => {
EventUtils.sendMouseEvent({ type: "mousedown" },
gDebugger.document.querySelector("#step-in"),
gDebugger);
});
return promise.all([
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES, 1),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 3),
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1),
]);
}
function testVariablesExpand() {
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
let thisVar = localScope.get("this");
let windowVar = thisVar.get("window");
is(localScope.target.querySelector(".arrow").hasAttribute("open"), true,
"The localScope arrow should still be expanded.");
is(withScope.target.querySelector(".arrow").hasAttribute("open"), true,
"The withScope arrow should still be expanded.");
is(functionScope.target.querySelector(".arrow").hasAttribute("open"), true,
"The functionScope arrow should still be expanded.");
is(globalScope.target.querySelector(".arrow").hasAttribute("open"), true,
"The globalScope arrow should still be expanded.");
is(thisVar.target.querySelector(".arrow").hasAttribute("open"), true,
"The thisVar arrow should still be expanded.");
is(windowVar.target.querySelector(".arrow").hasAttribute("open"), false,
"The windowVar arrow should not be expanded.");
is(localScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The localScope enumerables should still be expanded.");
is(withScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The withScope enumerables should still be expanded.");
is(functionScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The functionScope enumerables should still be expanded.");
is(globalScope.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The globalScope enumerables should still be expanded.");
is(thisVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), true,
"The thisVar enumerables should still be expanded.");
is(windowVar.target.querySelector(".variables-view-element-details").hasAttribute("open"), false,
"The windowVar enumerables should not be expanded.");
is(localScope.expanded, true,
"The localScope expanded getter should return true.");
is(withScope.expanded, true,
"The withScope expanded getter should return true.");
is(functionScope.expanded, true,
"The functionScope expanded getter should return true.");
is(globalScope.expanded, true,
"The globalScope expanded getter should return true.");
is(thisVar.expanded, true,
"The thisVar expanded getter should return true.");
is(windowVar.expanded, false,
"The windowVar expanded getter should return true.");
}
function prepareVariablesAndProperties() {
let deferred = promise.defer();
let localScope = gVariables.getScopeAtIndex(0);
let withScope = gVariables.getScopeAtIndex(1);
let functionScope = gVariables.getScopeAtIndex(2);
let globalScope = gVariables.getScopeAtIndex(3);
is(localScope.expanded, true,
"The localScope should be expanded.");
is(withScope.expanded, false,
"The withScope should not be expanded yet.");
is(functionScope.expanded, false,
"The functionScope should not be expanded yet.");
is(globalScope.expanded, false,
"The globalScope should not be expanded yet.");
// Wait for only two events to be triggered, because the Function scope is
// an environment to which scope arguments and variables are already attached.
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_VARIABLES, 2).then(() => {
is(localScope.expanded, true,
"The localScope should now be expanded.");
is(withScope.expanded, true,
"The withScope should now be expanded.");
is(functionScope.expanded, true,
"The functionScope should now be expanded.");
is(globalScope.expanded, true,
"The globalScope should now be expanded.");
let thisVar = localScope.get("this");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let windowVar = thisVar.get("window");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let documentVar = windowVar.get("document");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
let locationVar = documentVar.get("location");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 1).then(() => {
is(thisVar.expanded, true,
"The local scope 'this' should be expanded.");
is(windowVar.expanded, true,
"The local scope 'this.window' should be expanded.");
is(documentVar.expanded, true,
"The local scope 'this.window.document' should be expanded.");
is(locationVar.expanded, true,
"The local scope 'this.window.document.location' should be expanded.");
deferred.resolve();
});
locationVar.expand();
});
documentVar.expand();
});
windowVar.expand();
});
thisVar.expand();
});
withScope.expand();
functionScope.expand();
globalScope.expand();
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gBreakpoints = null;
gSources = null;
gVariables = null;
});

View File

@ -0,0 +1,259 @@
/* Any copyright is dedicated to the Public Domain.
http://creativecommons.org/publicdomain/zero/1.0/ */
/**
* Make sure that the variables view correctly displays WebIDL attributes in DOM
* objects.
*/
const TAB_URL = EXAMPLE_URL + "doc_frame-parameters.html";
let gTab, gDebuggee, gPanel, gDebugger;
let gVariables;
function test() {
// Debug test slaves are a bit slow at this test.
requestLongerTimeout(2);
initDebugger(TAB_URL).then(([aTab, aDebuggee, aPanel]) => {
gTab = aTab;
gDebuggee = aDebuggee;
gPanel = aPanel;
gDebugger = gPanel.panelWin;
gVariables = gDebugger.DebuggerView.Variables;
waitForSourceAndCaretAndScopes(gPanel, ".html", 24)
.then(expandGlobalScope)
.then(performTest)
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
.then(null, aError => {
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
});
EventUtils.sendMouseEvent({ type: "click" },
gDebuggee.document.querySelector("button"),
gDebuggee);
});
}
function expandGlobalScope() {
let deferred = promise.defer();
let globalScope = gVariables.getScopeAtIndex(1);
is(globalScope.expanded, false,
"The global scope should not be expanded by default.");
gDebugger.once(gDebugger.EVENTS.FETCHED_VARIABLES, deferred.resolve);
EventUtils.sendMouseEvent({ type: "mousedown" },
globalScope.target.querySelector(".name"),
gDebugger);
return deferred.promise;
}
function performTest() {
let deferred = promise.defer();
let globalScope = gVariables.getScopeAtIndex(1);
let buttonVar = globalScope.get("button");
let buttonAsProtoVar = globalScope.get("buttonAsProto");
let documentVar = globalScope.get("document");
is(buttonVar.target.querySelector(".name").getAttribute("value"), "button",
"Should have the right property name for 'button'.");
is(buttonVar.target.querySelector(".value").getAttribute("value"), "HTMLButtonElement",
"Should have the right property value for 'button'.");
ok(buttonVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'button'.");
is(buttonAsProtoVar.target.querySelector(".name").getAttribute("value"), "buttonAsProto",
"Should have the right property name for 'buttonAsProto'.");
is(buttonAsProtoVar.target.querySelector(".value").getAttribute("value"), "Object",
"Should have the right property value for 'buttonAsProto'.");
ok(buttonAsProtoVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'buttonAsProto'.");
is(documentVar.target.querySelector(".name").getAttribute("value"), "document",
"Should have the right property name for 'document'.");
is(documentVar.target.querySelector(".value").getAttribute("value"), "HTMLDocument",
"Should have the right property value for 'document'.");
ok(documentVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'document'.");
is(buttonVar.expanded, false,
"The buttonVar should not be expanded at this point.");
is(buttonAsProtoVar.expanded, false,
"The buttonAsProtoVar should not be expanded at this point.");
is(documentVar.expanded, false,
"The documentVar should not be expanded at this point.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 3).then(() => {
is(buttonVar.get("type").target.querySelector(".name").getAttribute("value"), "type",
"Should have the right property name for 'type'.");
is(buttonVar.get("type").target.querySelector(".value").getAttribute("value"), "\"submit\"",
"Should have the right property value for 'type'.");
ok(buttonVar.get("type").target.querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'type'.");
is(buttonVar.get("childNodes").target.querySelector(".name").getAttribute("value"), "childNodes",
"Should have the right property name for 'childNodes'.");
is(buttonVar.get("childNodes").target.querySelector(".value").getAttribute("value"), "NodeList",
"Should have the right property value for 'childNodes'.");
ok(buttonVar.get("childNodes").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'childNodes'.");
is(buttonVar.get("onclick").target.querySelector(".name").getAttribute("value"), "onclick",
"Should have the right property name for 'onclick'.");
is(buttonVar.get("onclick").target.querySelector(".value").getAttribute("value"), "Function",
"Should have the right property value for 'onclick'.");
ok(buttonVar.get("onclick").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'onclick'.");
is(documentVar.get("title").target.querySelector(".name").getAttribute("value"), "title",
"Should have the right property name for 'title'.");
is(documentVar.get("title").target.querySelector(".value").getAttribute("value"), "\"Debugger test page\"",
"Should have the right property value for 'title'.");
ok(documentVar.get("title").target.querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'title'.");
is(documentVar.get("childNodes").target.querySelector(".name").getAttribute("value"), "childNodes",
"Should have the right property name for 'childNodes'.");
is(documentVar.get("childNodes").target.querySelector(".value").getAttribute("value"), "NodeList",
"Should have the right property value for 'childNodes'.");
ok(documentVar.get("childNodes").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'childNodes'.");
is(documentVar.get("onclick").target.querySelector(".name").getAttribute("value"), "onclick",
"Should have the right property name for 'onclick'.");
is(documentVar.get("onclick").target.querySelector(".value").getAttribute("value"), "null",
"Should have the right property value for 'onclick'.");
ok(documentVar.get("onclick").target.querySelector(".value").className.contains("token-null"),
"Should have the right token class for 'onclick'.");
let buttonProtoVar = buttonVar.get("__proto__");
let buttonAsProtoProtoVar = buttonAsProtoVar.get("__proto__");
let documentProtoVar = documentVar.get("__proto__");
is(buttonProtoVar.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(buttonProtoVar.target.querySelector(".value").getAttribute("value"), "HTMLButtonElementPrototype",
"Should have the right property value for '__proto__'.");
ok(buttonProtoVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
is(buttonAsProtoProtoVar.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(buttonAsProtoProtoVar.target.querySelector(".value").getAttribute("value"), "HTMLButtonElement",
"Should have the right property value for '__proto__'.");
ok(buttonAsProtoProtoVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
is(documentProtoVar.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(documentProtoVar.target.querySelector(".value").getAttribute("value"), "HTMLDocumentPrototype",
"Should have the right property value for '__proto__'.");
ok(documentProtoVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
is(buttonProtoVar.expanded, false,
"The buttonProtoVar should not be expanded at this point.");
is(buttonAsProtoProtoVar.expanded, false,
"The buttonAsProtoProtoVar should not be expanded at this point.");
is(documentProtoVar.expanded, false,
"The documentProtoVar should not be expanded at this point.");
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 3).then(() => {
is(buttonAsProtoProtoVar.get("type").target.querySelector(".name").getAttribute("value"), "type",
"Should have the right property name for 'type'.");
is(buttonAsProtoProtoVar.get("type").target.querySelector(".value").getAttribute("value"), "\"submit\"",
"Should have the right property value for 'type'.");
ok(buttonAsProtoProtoVar.get("type").target.querySelector(".value").className.contains("token-string"),
"Should have the right token class for 'type'.");
is(buttonAsProtoProtoVar.get("childNodes").target.querySelector(".name").getAttribute("value"), "childNodes",
"Should have the right property name for 'childNodes'.");
is(buttonAsProtoProtoVar.get("childNodes").target.querySelector(".value").getAttribute("value"), "NodeList",
"Should have the right property value for 'childNodes'.");
ok(buttonAsProtoProtoVar.get("childNodes").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'childNodes'.");
is(buttonAsProtoProtoVar.get("onclick").target.querySelector(".name").getAttribute("value"), "onclick",
"Should have the right property name for 'onclick'.");
is(buttonAsProtoProtoVar.get("onclick").target.querySelector(".value").getAttribute("value"), "Function",
"Should have the right property value for 'onclick'.");
ok(buttonAsProtoProtoVar.get("onclick").target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for 'onclick'.");
let buttonProtoProtoVar = buttonProtoVar.get("__proto__");
let buttonAsProtoProtoProtoVar = buttonAsProtoProtoVar.get("__proto__");
let documentProtoProtoVar = documentProtoVar.get("__proto__");
is(buttonProtoProtoVar.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(buttonProtoProtoVar.target.querySelector(".value").getAttribute("value"), "HTMLElementPrototype",
"Should have the right property value for '__proto__'.");
ok(buttonProtoProtoVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
is(buttonAsProtoProtoProtoVar.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(buttonAsProtoProtoProtoVar.target.querySelector(".value").getAttribute("value"), "HTMLButtonElementPrototype",
"Should have the right property value for '__proto__'.");
ok(buttonAsProtoProtoProtoVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.");
is(documentProtoProtoVar.target.querySelector(".name").getAttribute("value"), "__proto__",
"Should have the right property name for '__proto__'.");
is(documentProtoProtoVar.target.querySelector(".value").getAttribute("value"), "DocumentPrototype",
"Should have the right property value for '__proto__'.");
ok(documentProtoProtoVar.target.querySelector(".value").className.contains("token-other"),
"Should have the right token class for '__proto__'.")
is(buttonAsProtoProtoProtoVar.expanded, false,
"The buttonAsProtoProtoProtoVar should not be expanded at this point.");
is(buttonAsProtoProtoProtoVar.expanded, false,
"The buttonAsProtoProtoProtoVar should not be expanded at this point.");
is(documentProtoProtoVar.expanded, false,
"The documentProtoProtoVar should not be expanded at this point.");
deferred.resolve();
});
// Similarly, expand the 'button.__proto__', 'buttonAsProto.__proto__' and
// 'document.__proto__' variables view nodes.
buttonProtoVar.expand();
buttonAsProtoProtoVar.expand();
documentProtoVar.expand();
is(buttonProtoVar.expanded, true,
"The buttonProtoVar should be immediately marked as expanded.");
is(buttonAsProtoProtoVar.expanded, true,
"The buttonAsProtoProtoVar should be immediately marked as expanded.");
is(documentProtoVar.expanded, true,
"The documentProtoVar should be immediately marked as expanded.");
});
// Expand the 'button', 'buttonAsProto' and 'document' variables view nodes.
// This causes their properties to be retrieved and displayed.
buttonVar.expand();
buttonAsProtoVar.expand();
documentVar.expand();
is(buttonVar.expanded, true,
"The buttonVar should be immediately marked as expanded.");
is(buttonAsProtoVar.expanded, true,
"The buttonAsProtoVar should be immediately marked as expanded.");
is(documentVar.expanded, true,
"The documentVar should be immediately marked as expanded.");
return deferred.promise;
}
registerCleanupFunction(function() {
gTab = null;
gDebuggee = null;
gPanel = null;
gDebugger = null;
gVariables = null;
});