mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-07 00:08:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
|
|
@ -0,0 +1,13 @@
|
|||
var { Cc, Ci } = require("chrome");
|
||||
var { once } = require("sdk/system/events");
|
||||
|
||||
var observerService = Cc["@mozilla.org/observer-service;1"].getService(Ci.nsIObserverService);
|
||||
var observer = {
|
||||
observe: function () {
|
||||
debugger;
|
||||
}
|
||||
};
|
||||
|
||||
once("sdk:loader:destroy", () => observerService.removeObserver(observer, "debuggerAttached"));
|
||||
|
||||
observerService.addObserver(observer, "debuggerAttached", false);
|
||||
|
|
@ -0,0 +1,9 @@
|
|||
{
|
||||
"name": "browser_dbg_addon3",
|
||||
"title": "browser_dbg_addon3",
|
||||
"id": "jid1-ami3akps3baaeg",
|
||||
"description": "a basic add-on",
|
||||
"author": "",
|
||||
"license": "MPL 2.0",
|
||||
"version": "0.1"
|
||||
}
|
||||
36
devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js
vendored
Normal file
36
devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js
vendored
Normal file
|
|
@ -0,0 +1,36 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
var { interfaces: Ci, utils: Cu } = Components;
|
||||
|
||||
function notify() {
|
||||
// Log objects so makeDebuggeeValue can get the global to use
|
||||
console.log({ msg: "Hello again" });
|
||||
}
|
||||
|
||||
function startup(aParams, aReason) {
|
||||
const { Services } = Cu.import("resource://gre/modules/Services.jsm", {});
|
||||
let res = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||
res.setSubstitution("browser_dbg_addon4", aParams.resourceURI);
|
||||
|
||||
// Load a JS module
|
||||
Cu.import("resource://browser_dbg_addon4/test.jsm"); // eslint-disable-line mozilla/no-single-arg-cu-import
|
||||
// Log objects so makeDebuggeeValue can get the global to use
|
||||
console.log({ msg: "Hello from the test add-on" });
|
||||
|
||||
Services.obs.addObserver(notify, "addon-test-ping", false);
|
||||
}
|
||||
|
||||
function shutdown(aParams, aReason) {
|
||||
Services.obs.removeObserver(notify, "addon-test-ping");
|
||||
|
||||
// Unload the JS module
|
||||
Cu.unload("resource://browser_dbg_addon4/test.jsm");
|
||||
|
||||
let res = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||
res.setSubstitution("browser_dbg_addon4", null);
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
content browser_dbg_addon4 .
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>browser_dbg_addon4@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
<em:name>Test add-on with JS Modules</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</RDF>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const EXPORTED_SYMBOLS = ["Foo"];
|
||||
|
||||
const Foo = {};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="text/javascript" src="testxul.js"/>
|
||||
<label value="test.xul"/>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const EXPORTED_SYMBOLS = ["Bar"];
|
||||
|
||||
const Bar = {};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="text/javascript" src="testxul2.js"/>
|
||||
<label value="test2.xul"/>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Define something in here or the script may get collected
|
||||
window.addEventListener("unload", function () {
|
||||
window.foo = "bar";
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Define something in here or the script may get collected
|
||||
window.addEventListener("unload", function () {
|
||||
window.foo = "bar";
|
||||
});
|
||||
23
devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js
vendored
Normal file
23
devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js
vendored
Normal file
|
|
@ -0,0 +1,23 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
var { interfaces: Ci, classes: Cc } = Components;
|
||||
|
||||
function startup(aParams, aReason) {
|
||||
Components.utils.import("resource://gre/modules/Services.jsm");
|
||||
let res = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||
res.setSubstitution("browser_dbg_addon5", aParams.resourceURI);
|
||||
|
||||
// Load a JS module
|
||||
Components.utils.import("resource://browser_dbg_addon5/test.jsm");
|
||||
}
|
||||
|
||||
function shutdown(aParams, aReason) {
|
||||
// Unload the JS module
|
||||
Components.utils.unload("resource://browser_dbg_addon5/test.jsm");
|
||||
|
||||
let res = Services.io.getProtocolHandler("resource")
|
||||
.QueryInterface(Ci.nsIResProtocolHandler);
|
||||
res.setSubstitution("browser_dbg_addon5", null);
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
content browser_dbg_addon5 .
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<RDF xmlns="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:em="http://www.mozilla.org/2004/em-rdf#">
|
||||
|
||||
<Description about="urn:mozilla:install-manifest">
|
||||
<em:id>browser_dbg_addon5@tests.mozilla.org</em:id>
|
||||
<em:version>1.0</em:version>
|
||||
<em:name>Test unpacked add-on with JS Modules</em:name>
|
||||
<em:bootstrap>true</em:bootstrap>
|
||||
<em:unpack>true</em:unpack>
|
||||
<em:targetApplication>
|
||||
<Description>
|
||||
<em:id>toolkit@mozilla.org</em:id>
|
||||
<em:minVersion>0</em:minVersion>
|
||||
<em:maxVersion>*</em:maxVersion>
|
||||
</Description>
|
||||
</em:targetApplication>
|
||||
</Description>
|
||||
</RDF>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const EXPORTED_SYMBOLS = ["Foo"];
|
||||
|
||||
const Foo = {};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="text/javascript" src="testxul.js"/>
|
||||
<label value="test.xul"/>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
/* Any copyright is dedicated to the Public Domain.
|
||||
http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const EXPORTED_SYMBOLS = ["Bar"];
|
||||
|
||||
const Bar = {};
|
||||
|
|
@ -0,0 +1,8 @@
|
|||
<?xml version="1.0"?>
|
||||
|
||||
<?xml-stylesheet href="chrome://global/skin/" type="text/css"?>
|
||||
|
||||
<window xmlns="http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul">
|
||||
<script type="text/javascript" src="testxul2.js"/>
|
||||
<label value="test2.xul"/>
|
||||
</window>
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Define something in here or the script may get collected
|
||||
window.addEventListener("unload", function () {
|
||||
window.foo = "bar";
|
||||
});
|
||||
|
|
@ -0,0 +1,4 @@
|
|||
// Define something in here or the script may get collected
|
||||
window.addEventListener("unload", function () {
|
||||
window.foo = "bar";
|
||||
});
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
{
|
||||
"manifest_version": 2,
|
||||
"name": "test content script sources",
|
||||
"description": "test content script sources",
|
||||
"version": "0.1.0",
|
||||
"applications": {
|
||||
"gecko": {
|
||||
"id": "test-contentscript-sources@mozilla.com"
|
||||
}
|
||||
},
|
||||
"content_scripts": [
|
||||
{
|
||||
"matches": ["<all_urls>"],
|
||||
"js": ["webext-content-script.js"],
|
||||
"run_at": "document_start"
|
||||
}
|
||||
]
|
||||
}
|
||||
|
|
@ -0,0 +1 @@
|
|||
console.log("CONTENT SCRIPT LOADED");
|
||||
Binary file not shown.
BIN
devtools/client/debugger/test/mochitest/addon1.xpi
Normal file
BIN
devtools/client/debugger/test/mochitest/addon1.xpi
Normal file
Binary file not shown.
BIN
devtools/client/debugger/test/mochitest/addon2.xpi
Normal file
BIN
devtools/client/debugger/test/mochitest/addon2.xpi
Normal file
Binary file not shown.
BIN
devtools/client/debugger/test/mochitest/addon3.xpi
Normal file
BIN
devtools/client/debugger/test/mochitest/addon3.xpi
Normal file
Binary file not shown.
BIN
devtools/client/debugger/test/mochitest/addon4.xpi
Normal file
BIN
devtools/client/debugger/test/mochitest/addon4.xpi
Normal file
Binary file not shown.
BIN
devtools/client/debugger/test/mochitest/addon5.xpi
Normal file
BIN
devtools/client/debugger/test/mochitest/addon5.xpi
Normal file
Binary file not shown.
317
devtools/client/debugger/test/mochitest/browser.ini
Normal file
317
devtools/client/debugger/test/mochitest/browser.ini
Normal file
|
|
@ -0,0 +1,317 @@
|
|||
# Tests in this directory are split into two manifests (this and browser2.ini)
|
||||
# to facilitate better chunking; see bug 1294489.
|
||||
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
skip-if = (os == 'linux' && debug && bits == 32)
|
||||
support-files =
|
||||
addon1.xpi
|
||||
addon2.xpi
|
||||
addon3.xpi
|
||||
addon4.xpi
|
||||
addon5.xpi
|
||||
addon-webext-contentscript.xpi
|
||||
addon-source/browser_dbg_addon5/*
|
||||
code_binary_search.coffee
|
||||
code_binary_search.js
|
||||
code_binary_search.map
|
||||
code_blackboxing_blackboxme.js
|
||||
code_blackboxing_one.js
|
||||
code_blackboxing_three.js
|
||||
code_blackboxing_two.js
|
||||
code_blackboxing_unblackbox.min.js
|
||||
code_breakpoints-break-on-last-line-of-script-on-reload.js
|
||||
code_breakpoints-other-tabs.js
|
||||
code_bug-896139.js
|
||||
code_frame-script.js
|
||||
code_function-jump-01.js
|
||||
code_function-search-01.js
|
||||
code_function-search-02.js
|
||||
code_function-search-03.js
|
||||
code_location-changes.js
|
||||
code_listworkers-worker1.js
|
||||
code_listworkers-worker2.js
|
||||
code_math.js
|
||||
code_math.map
|
||||
code_math.min.js
|
||||
code_math_bogus_map.js
|
||||
code_same-line-functions.js
|
||||
code_script-eval.js
|
||||
code_script-switching-01.js
|
||||
code_script-switching-02.js
|
||||
code_test-editor-mode
|
||||
code_ugly.js
|
||||
code_ugly-2.js
|
||||
code_ugly-3.js
|
||||
code_ugly-4.js
|
||||
code_ugly-5.js
|
||||
code_ugly-6.js
|
||||
code_ugly-7.js
|
||||
code_ugly-8
|
||||
code_ugly-8^headers^
|
||||
code_worker-source-map.coffee
|
||||
code_worker-source-map.js
|
||||
code_worker-source-map.js.map
|
||||
code_WorkerActor.attach-worker1.js
|
||||
code_WorkerActor.attach-worker2.js
|
||||
code_WorkerActor.attachThread-worker.js
|
||||
doc_auto-pretty-print-01.html
|
||||
doc_auto-pretty-print-02.html
|
||||
doc_binary_search.html
|
||||
doc_blackboxing.html
|
||||
doc_blackboxing_unblackbox.html
|
||||
doc_breakpoints-break-on-last-line-of-script-on-reload.html
|
||||
doc_breakpoints-other-tabs.html
|
||||
doc_breakpoints-reload.html
|
||||
doc_bug-896139.html
|
||||
doc_closures.html
|
||||
doc_closure-optimized-out.html
|
||||
doc_cmd-break.html
|
||||
doc_cmd-dbg.html
|
||||
doc_breakpoint-move.html
|
||||
doc_conditional-breakpoints.html
|
||||
doc_domnode-variables.html
|
||||
doc_editor-mode.html
|
||||
doc_empty-tab-01.html
|
||||
doc_empty-tab-02.html
|
||||
doc_event-listeners-01.html
|
||||
doc_event-listeners-02.html
|
||||
doc_event-listeners-03.html
|
||||
doc_event-listeners-04.html
|
||||
doc_frame-parameters.html
|
||||
doc_function-display-name.html
|
||||
doc_function-jump.html
|
||||
doc_function-search.html
|
||||
doc_global-method-override.html
|
||||
doc_iframes.html
|
||||
doc_included-script.html
|
||||
doc_inline-debugger-statement.html
|
||||
doc_inline-script.html
|
||||
doc_large-array-buffer.html
|
||||
doc_listworkers-tab.html
|
||||
doc_map-set.html
|
||||
doc_minified.html
|
||||
doc_minified_bogus_map.html
|
||||
doc_native-event-handler.html
|
||||
doc_no-page-sources.html
|
||||
doc_pause-exceptions.html
|
||||
doc_pretty-print.html
|
||||
doc_pretty-print-2.html
|
||||
doc_pretty-print-3.html
|
||||
doc_pretty-print-on-paused.html
|
||||
doc_promise-get-allocation-stack.html
|
||||
doc_promise-get-fulfillment-stack.html
|
||||
doc_promise-get-rejection-stack.html
|
||||
doc_promise.html
|
||||
doc_proxy.html
|
||||
doc_random-javascript.html
|
||||
doc_recursion-stack.html
|
||||
doc_scope-variable.html
|
||||
doc_scope-variable-2.html
|
||||
doc_scope-variable-3.html
|
||||
doc_scope-variable-4.html
|
||||
doc_script-eval.html
|
||||
doc_script-bookmarklet.html
|
||||
doc_script-switching-01.html
|
||||
doc_script-switching-02.html
|
||||
doc_script_webext_contentscript.html
|
||||
doc_split-console-paused-reload.html
|
||||
doc_step-many-statements.html
|
||||
doc_step-out.html
|
||||
doc_terminate-on-tab-close.html
|
||||
doc_watch-expressions.html
|
||||
doc_watch-expression-button.html
|
||||
doc_whitespace-property-names.html
|
||||
doc_with-frame.html
|
||||
doc_worker-source-map.html
|
||||
doc_WorkerActor.attach-tab1.html
|
||||
doc_WorkerActor.attach-tab2.html
|
||||
doc_WorkerActor.attachThread-tab.html
|
||||
head.js
|
||||
sjs_post-page.sjs
|
||||
sjs_random-javascript.sjs
|
||||
testactors.js
|
||||
!/devtools/client/commandline/test/helpers.js
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
|
||||
[browser_dbg_aaa_run_first_leaktest.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_addonactor.js]
|
||||
tags = addons
|
||||
[browser_dbg_addon-sources.js]
|
||||
tags = addons
|
||||
[browser_dbg_addon-workers-dbg-enabled.js]
|
||||
tags = addons
|
||||
[browser_dbg_addon-modules.js]
|
||||
skip-if = e10s # TODO
|
||||
tags = addons
|
||||
[browser_dbg_addon-modules-unpacked.js]
|
||||
skip-if = e10s # TODO
|
||||
tags = addons
|
||||
[browser_dbg_addon-panels.js]
|
||||
tags = addons
|
||||
[browser_dbg_addon-console.js]
|
||||
skip-if = e10s && debug || os == 'win' # bug 1005274
|
||||
tags = addons
|
||||
[browser_dbg_auto-pretty-print-01.js]
|
||||
[browser_dbg_auto-pretty-print-02.js]
|
||||
[browser_dbg_auto-pretty-print-03.js]
|
||||
[browser_dbg_bfcache.js]
|
||||
skip-if = e10s || true # bug 1113935
|
||||
[browser_dbg_blackboxing-01.js]
|
||||
[browser_dbg_blackboxing-02.js]
|
||||
[browser_dbg_blackboxing-03.js]
|
||||
[browser_dbg_blackboxing-04.js]
|
||||
[browser_dbg_blackboxing-05.js]
|
||||
[browser_dbg_blackboxing-06.js]
|
||||
[browser_dbg_blackboxing-07.js]
|
||||
[browser_dbg_breadcrumbs-access.js]
|
||||
[browser_dbg_break-in-anon.js]
|
||||
[browser_dbg_break-on-next.js]
|
||||
[browser_dbg_break-on-next-console.js]
|
||||
[browser_dbg_break-on-dom-01.js]
|
||||
[browser_dbg_break-on-dom-02.js]
|
||||
[browser_dbg_break-on-dom-03.js]
|
||||
[browser_dbg_break-on-dom-04.js]
|
||||
[browser_dbg_break-on-dom-05.js]
|
||||
[browser_dbg_break-on-dom-06.js]
|
||||
[browser_dbg_break-on-dom-07.js]
|
||||
[browser_dbg_break-on-dom-08.js]
|
||||
[browser_dbg_break-on-dom-event-01.js]
|
||||
skip-if = e10s || os == "mac" || e10s # Bug 895426
|
||||
[browser_dbg_break-on-dom-event-02.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_break-on-dom-event-03.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_break-unselected.js]
|
||||
[browser_dbg_breakpoints-actual-location.js]
|
||||
[browser_dbg_breakpoints-actual-location2.js]
|
||||
[browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js]
|
||||
skip-if = e10s # Bug 1093535
|
||||
[browser_dbg_breakpoints-button-01.js]
|
||||
[browser_dbg_breakpoints-button-02.js]
|
||||
[browser_dbg_breakpoints-condition-thrown-message.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-contextmenu-add.js]
|
||||
[browser_dbg_breakpoints-contextmenu.js]
|
||||
[browser_dbg_breakpoints-disabled-reload.js]
|
||||
skip-if = e10s # Bug 1093535
|
||||
[browser_dbg_breakpoints-editor.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-eval.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-highlight.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-new-script.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-other-tabs.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-pane.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_breakpoints-reload.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_bug-896139.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_chrome-create.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_chrome-debugging.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_clean-exit-window.js]
|
||||
skip-if = true # Bug 933950 (leaky test)
|
||||
[browser_dbg_clean-exit.js]
|
||||
skip-if = true # Bug 1044985 (racy test)
|
||||
[browser_dbg_closure-inspection.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_cmd-blackbox.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_cmd-break.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_cmd-dbg.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_conditional-breakpoints-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_conditional-breakpoints-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_conditional-breakpoints-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_conditional-breakpoints-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_conditional-breakpoints-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_console-eval.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_console-named-eval.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_server-conditional-bp-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_server-conditional-bp-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_server-conditional-bp-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_server-conditional-bp-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_server-conditional-bp-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_controller-evaluate-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_controller-evaluate-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_debugger-statement.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_editor-contextmenu.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_editor-mode.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_event-listeners-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_event-listeners-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_event-listeners-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_event-listeners-04.js]
|
||||
skip-if = debug || e10s # debug bug 1142597, e10s bug 1146603.
|
||||
[browser_dbg_file-reload.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_function-display-name.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_global-method-override.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_globalactor.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_hide-toolbar-buttons.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_host-layout.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_jump-to-function-definition.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_iframes.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_instruments-pane-collapse.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_instruments-pane-collapse_keyboard.js]
|
||||
skip-if = (os == 'mac' && e10s && debug) # Full keyboard navigation on OSX only works if Full Keyboard Access setting is set to All Control
|
||||
[browser_dbg_interrupts.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_listaddons.js]
|
||||
skip-if = e10s && debug
|
||||
tags = addons
|
||||
[browser_dbg_listtabs-01.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_listtabs-02.js]
|
||||
skip-if = true # Never worked for remote frames, needs a mock DebuggerServerConnection
|
||||
[browser_dbg_listtabs-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_listworkers.js]
|
||||
[browser_dbg_location-changes-01-simple.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_location-changes-02-blank.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_location-changes-03-new.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_location-changes-04-breakpoint.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_multiple-windows.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_navigation.js]
|
||||
skip-if = e10s && debug
|
||||
460
devtools/client/debugger/test/mochitest/browser2.ini
Normal file
460
devtools/client/debugger/test/mochitest/browser2.ini
Normal file
|
|
@ -0,0 +1,460 @@
|
|||
# Tests in this directory are split into two manifests (this and browser.ini)
|
||||
# to facilitate better chunking; see bug 1294489.
|
||||
|
||||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
skip-if = (os == 'linux' && debug && bits == 32)
|
||||
support-files =
|
||||
addon1.xpi
|
||||
addon2.xpi
|
||||
addon3.xpi
|
||||
addon4.xpi
|
||||
addon5.xpi
|
||||
addon-webext-contentscript.xpi
|
||||
addon-source/browser_dbg_addon5/*
|
||||
code_binary_search.coffee
|
||||
code_binary_search.js
|
||||
code_binary_search.map
|
||||
code_blackboxing_blackboxme.js
|
||||
code_blackboxing_one.js
|
||||
code_blackboxing_three.js
|
||||
code_blackboxing_two.js
|
||||
code_blackboxing_unblackbox.min.js
|
||||
code_breakpoints-break-on-last-line-of-script-on-reload.js
|
||||
code_breakpoints-other-tabs.js
|
||||
code_bug-896139.js
|
||||
code_frame-script.js
|
||||
code_function-jump-01.js
|
||||
code_function-search-01.js
|
||||
code_function-search-02.js
|
||||
code_function-search-03.js
|
||||
code_location-changes.js
|
||||
code_listworkers-worker1.js
|
||||
code_listworkers-worker2.js
|
||||
code_math.js
|
||||
code_math.map
|
||||
code_math.min.js
|
||||
code_math_bogus_map.js
|
||||
code_same-line-functions.js
|
||||
code_script-eval.js
|
||||
code_script-switching-01.js
|
||||
code_script-switching-02.js
|
||||
code_test-editor-mode
|
||||
code_ugly.js
|
||||
code_ugly-2.js
|
||||
code_ugly-3.js
|
||||
code_ugly-4.js
|
||||
code_ugly-5.js
|
||||
code_ugly-6.js
|
||||
code_ugly-7.js
|
||||
code_ugly-8
|
||||
code_ugly-8^headers^
|
||||
code_worker-source-map.coffee
|
||||
code_worker-source-map.js
|
||||
code_worker-source-map.js.map
|
||||
code_WorkerActor.attach-worker1.js
|
||||
code_WorkerActor.attach-worker2.js
|
||||
code_WorkerActor.attachThread-worker.js
|
||||
doc_auto-pretty-print-01.html
|
||||
doc_auto-pretty-print-02.html
|
||||
doc_binary_search.html
|
||||
doc_blackboxing.html
|
||||
doc_blackboxing_unblackbox.html
|
||||
doc_breakpoints-break-on-last-line-of-script-on-reload.html
|
||||
doc_breakpoints-other-tabs.html
|
||||
doc_breakpoints-reload.html
|
||||
doc_bug-896139.html
|
||||
doc_closures.html
|
||||
doc_closure-optimized-out.html
|
||||
doc_cmd-break.html
|
||||
doc_cmd-dbg.html
|
||||
doc_breakpoint-move.html
|
||||
doc_conditional-breakpoints.html
|
||||
doc_domnode-variables.html
|
||||
doc_editor-mode.html
|
||||
doc_empty-tab-01.html
|
||||
doc_empty-tab-02.html
|
||||
doc_event-listeners-01.html
|
||||
doc_event-listeners-02.html
|
||||
doc_event-listeners-03.html
|
||||
doc_event-listeners-04.html
|
||||
doc_frame-parameters.html
|
||||
doc_function-display-name.html
|
||||
doc_function-jump.html
|
||||
doc_function-search.html
|
||||
doc_global-method-override.html
|
||||
doc_iframes.html
|
||||
doc_included-script.html
|
||||
doc_inline-debugger-statement.html
|
||||
doc_inline-script.html
|
||||
doc_large-array-buffer.html
|
||||
doc_listworkers-tab.html
|
||||
doc_map-set.html
|
||||
doc_minified.html
|
||||
doc_minified_bogus_map.html
|
||||
doc_native-event-handler.html
|
||||
doc_no-page-sources.html
|
||||
doc_pause-exceptions.html
|
||||
doc_pretty-print.html
|
||||
doc_pretty-print-2.html
|
||||
doc_pretty-print-3.html
|
||||
doc_pretty-print-on-paused.html
|
||||
doc_promise-get-allocation-stack.html
|
||||
doc_promise-get-fulfillment-stack.html
|
||||
doc_promise-get-rejection-stack.html
|
||||
doc_promise.html
|
||||
doc_proxy.html
|
||||
doc_random-javascript.html
|
||||
doc_recursion-stack.html
|
||||
doc_scope-variable.html
|
||||
doc_scope-variable-2.html
|
||||
doc_scope-variable-3.html
|
||||
doc_scope-variable-4.html
|
||||
doc_script-eval.html
|
||||
doc_script-bookmarklet.html
|
||||
doc_script-switching-01.html
|
||||
doc_script-switching-02.html
|
||||
doc_script_webext_contentscript.html
|
||||
doc_split-console-paused-reload.html
|
||||
doc_step-many-statements.html
|
||||
doc_step-out.html
|
||||
doc_terminate-on-tab-close.html
|
||||
doc_watch-expressions.html
|
||||
doc_watch-expression-button.html
|
||||
doc_whitespace-property-names.html
|
||||
doc_with-frame.html
|
||||
doc_worker-source-map.html
|
||||
doc_WorkerActor.attach-tab1.html
|
||||
doc_WorkerActor.attach-tab2.html
|
||||
doc_WorkerActor.attachThread-tab.html
|
||||
head.js
|
||||
sjs_post-page.sjs
|
||||
sjs_random-javascript.sjs
|
||||
testactors.js
|
||||
!/devtools/client/commandline/test/helpers.js
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
|
||||
[browser_dbg_no-dangling-breakpoints.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_no-page-sources.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_on-pause-highlight.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_on-pause-raise.js]
|
||||
skip-if = e10s && debug || os == "linux" # Bug 888811 & bug 891176
|
||||
[browser_dbg_optimized-out-vars.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_panel-size.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-07.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-08.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-09.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-10.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_parser-11.js]
|
||||
[browser_dbg_parser-computed-name.js]
|
||||
[browser_dbg_parser-function-defaults.js]
|
||||
[browser_dbg_parser-spread-expression.js]
|
||||
[browser_dbg_parser-template-strings.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pause-exceptions-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pause-exceptions-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pause-no-step.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pause-resume.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pause-warning.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_paused-keybindings.js]
|
||||
skip-if = e10s
|
||||
[browser_dbg_post-page.js]
|
||||
[browser_dbg_pretty-print-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-07.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-08.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-09.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-10.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-11.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-12.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-13.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_pretty-print-on-paused.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_progress-listener-bug.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_promises-allocation-stack.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_promises-chrome-allocation-stack.js]
|
||||
skip-if = true # Bug 1177730
|
||||
[browser_dbg_promises-fulfillment-stack.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_promises-rejection-stack.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_reload-preferred-script-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_reload-preferred-script-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_reload-same-script.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_scripts-switching-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_scripts-switching-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_scripts-switching-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-autofill-identifier.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-basic-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-basic-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-basic-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-basic-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-global-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-global-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-global-03.js]
|
||||
skip-if = e10s # Bug 1093535
|
||||
[browser_dbg_search-global-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-global-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-global-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-popup-jank.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-sources-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-sources-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-sources-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_search-symbols.js]
|
||||
skip-if = (e10s && debug) || os == "linux" # Bug 1132375
|
||||
[browser_dbg_searchbox-help-popup-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_searchbox-help-popup-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_searchbox-parse.js]
|
||||
skip-if = (debug) || (os == 'linux' && asan) # asan, bug 1313861, debug: bug 1313861
|
||||
[browser_dbg_source-maps-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_source-maps-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_source-maps-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_source-maps-04.js]
|
||||
skip-if = e10s # Bug 1093535
|
||||
[browser_dbg_sources-cache.js]
|
||||
[browser_dbg_sources-contextmenu-01.js]
|
||||
subsuite = clipboard
|
||||
[browser_dbg_sources-contextmenu-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_sources-eval-01.js]
|
||||
skip-if = true # non-named eval sources turned off for now, bug 1124106
|
||||
[browser_dbg_sources-eval-02.js]
|
||||
[browser_dbg_sources-iframe-reload.js]
|
||||
[browser_dbg_sources-keybindings.js]
|
||||
subsuite = clipboard
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_sources-labels.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_sources-large.js]
|
||||
[browser_dbg_sources-sorting.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_sources-bookmarklet.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_sources-webext-contentscript.js]
|
||||
[browser_dbg_split-console-paused-reload.js]
|
||||
skip-if = true # Bug 1288348 - previously e10s && debug
|
||||
[browser_dbg_stack-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_stack-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_stack-03.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_stack-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_stack-05.js]
|
||||
skip-if = e10s && (debug || asan) # timeouts
|
||||
[browser_dbg_stack-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_stack-07.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_stack-contextmenu-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_stack-contextmenu-02.js]
|
||||
subsuite = clipboard
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_step-out.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_tabactor-01.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_tabactor-02.js]
|
||||
skip-if = e10s # TODO
|
||||
[browser_dbg_terminate-on-tab-close.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-07.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-08.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-accessibility.js]
|
||||
subsuite = clipboard
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-data.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-cancel.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-click.js]
|
||||
skip-if = e10s || (os == 'mac' || os == 'win') && (debug == false) # Bug 986166
|
||||
[browser_dbg_variables-view-edit-getset-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-getset-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-value.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-edit-watch.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-pref.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-filter-searchbox.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-parameters-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-parameters-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-parameters-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frame-with.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-frozen-sealed-nonext.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-hide-non-enums.js]
|
||||
[browser_dbg_variables-view-large-array-buffer.js]
|
||||
[browser_dbg_variables-view-map-set.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-override-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-override-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-04.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-05.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-06.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-07.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-08.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-09.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-10.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-11.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-12.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-13.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-14.js]
|
||||
skip-if = true # Bug 1029545
|
||||
[browser_dbg_variables-view-popup-15.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-16.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-popup-17.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-reexpand-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-reexpand-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-reexpand-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_variables-view-webidl.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_watch-expressions-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_watch-expressions-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_worker-console-01.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_worker-console-02.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_worker-console-03.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_worker-source-map.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_worker-window.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_WorkerActor.attach.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_WorkerActor.attachThread.js]
|
||||
skip-if = e10s && debug
|
||||
[browser_dbg_split-console-keypress.js]
|
||||
skip-if = e10s && (debug || os == "linux") # Bug 1214439
|
||||
|
|
@ -0,0 +1,62 @@
|
|||
var MAX_TOTAL_VIEWERS = "browser.sessionhistory.max_total_viewers";
|
||||
|
||||
var TAB1_URL = EXAMPLE_URL + "doc_WorkerActor.attach-tab1.html";
|
||||
var TAB2_URL = EXAMPLE_URL + "doc_WorkerActor.attach-tab2.html";
|
||||
var WORKER1_URL = "code_WorkerActor.attach-worker1.js";
|
||||
var WORKER2_URL = "code_WorkerActor.attach-worker2.js";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
let oldMaxTotalViewers = SpecialPowers.getIntPref(MAX_TOTAL_VIEWERS);
|
||||
SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, 10);
|
||||
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
let client = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client);
|
||||
|
||||
let tab = yield addTab(TAB1_URL);
|
||||
let { tabs } = yield listTabs(client);
|
||||
let [, tabClient] = yield attachTab(client, findTab(tabs, TAB1_URL));
|
||||
yield listWorkers(tabClient);
|
||||
|
||||
// If a page still has pending network requests, it will not be moved into
|
||||
// the bfcache. Consequently, we cannot use waitForWorkerListChanged here,
|
||||
// because the worker is not guaranteed to have finished loading when it is
|
||||
// registered. Instead, we have to wait for the promise returned by
|
||||
// createWorker in the tab to be resolved.
|
||||
yield createWorkerInTab(tab, WORKER1_URL);
|
||||
let { workers } = yield listWorkers(tabClient);
|
||||
let [, workerClient1] = yield attachWorker(tabClient,
|
||||
findWorker(workers, WORKER1_URL));
|
||||
is(workerClient1.isClosed, false, "worker in tab 1 should not be closed");
|
||||
|
||||
executeSoon(() => {
|
||||
tab.linkedBrowser.loadURI(TAB2_URL);
|
||||
});
|
||||
yield waitForWorkerClose(workerClient1);
|
||||
is(workerClient1.isClosed, true, "worker in tab 1 should be closed");
|
||||
|
||||
yield createWorkerInTab(tab, WORKER2_URL);
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
let [, workerClient2] = yield attachWorker(tabClient,
|
||||
findWorker(workers, WORKER2_URL));
|
||||
is(workerClient2.isClosed, false, "worker in tab 2 should not be closed");
|
||||
|
||||
executeSoon(() => {
|
||||
tab.linkedBrowser.contentWindow.history.back();
|
||||
});
|
||||
yield waitForWorkerClose(workerClient2);
|
||||
is(workerClient2.isClosed, true, "worker in tab 2 should be closed");
|
||||
|
||||
({ workers } = yield listWorkers(tabClient));
|
||||
[, workerClient1] = yield attachWorker(tabClient,
|
||||
findWorker(workers, WORKER1_URL));
|
||||
is(workerClient1.isClosed, false, "worker in tab 1 should not be closed");
|
||||
|
||||
yield close(client);
|
||||
SpecialPowers.setIntPref(MAX_TOTAL_VIEWERS, oldMaxTotalViewers);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
var TAB_URL = EXAMPLE_URL + "doc_WorkerActor.attachThread-tab.html";
|
||||
var WORKER_URL = "code_WorkerActor.attachThread-worker.js";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
|
||||
let client1 = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client1);
|
||||
let client2 = new DebuggerClient(DebuggerServer.connectPipe());
|
||||
yield connect(client2);
|
||||
|
||||
let tab = yield addTab(TAB_URL);
|
||||
let { tabs: tabs1 } = yield listTabs(client1);
|
||||
let [, tabClient1] = yield attachTab(client1, findTab(tabs1, TAB_URL));
|
||||
let { tabs: tabs2 } = yield listTabs(client2);
|
||||
let [, tabClient2] = yield attachTab(client2, findTab(tabs2, TAB_URL));
|
||||
|
||||
yield listWorkers(tabClient1);
|
||||
yield listWorkers(tabClient2);
|
||||
yield createWorkerInTab(tab, WORKER_URL);
|
||||
let { workers: workers1 } = yield listWorkers(tabClient1);
|
||||
let [, workerClient1] = yield attachWorker(tabClient1,
|
||||
findWorker(workers1, WORKER_URL));
|
||||
let { workers: workers2 } = yield listWorkers(tabClient2);
|
||||
let [, workerClient2] = yield attachWorker(tabClient2,
|
||||
findWorker(workers2, WORKER_URL));
|
||||
|
||||
let location = { line: 5 };
|
||||
|
||||
let [, threadClient1] = yield attachThread(workerClient1);
|
||||
let sources1 = yield getSources(threadClient1);
|
||||
let sourceClient1 = threadClient1.source(findSource(sources1,
|
||||
EXAMPLE_URL + WORKER_URL));
|
||||
let [, breakpointClient1] = yield setBreakpoint(sourceClient1, location);
|
||||
yield resume(threadClient1);
|
||||
|
||||
let [, threadClient2] = yield attachThread(workerClient2);
|
||||
let sources2 = yield getSources(threadClient2);
|
||||
let sourceClient2 = threadClient2.source(findSource(sources2,
|
||||
EXAMPLE_URL + WORKER_URL));
|
||||
let [, breakpointClient2] = yield setBreakpoint(sourceClient2, location);
|
||||
yield resume(threadClient2);
|
||||
|
||||
let packet = yield source(sourceClient1);
|
||||
let text = (yield new Promise(function (resolve) {
|
||||
let request = new XMLHttpRequest();
|
||||
request.open("GET", EXAMPLE_URL + WORKER_URL, true);
|
||||
request.send();
|
||||
request.onload = function () {
|
||||
resolve(request.responseText);
|
||||
};
|
||||
}));
|
||||
is(packet.source, text);
|
||||
|
||||
postMessageToWorkerInTab(tab, WORKER_URL, "ping");
|
||||
yield Promise.all([
|
||||
waitForPause(threadClient1).then((packet) => {
|
||||
is(packet.type, "paused");
|
||||
let why = packet.why;
|
||||
is(why.type, "breakpoint");
|
||||
is(why.actors.length, 1);
|
||||
is(why.actors[0], breakpointClient1.actor);
|
||||
let frame = packet.frame;
|
||||
let where = frame.where;
|
||||
is(where.source.actor, sourceClient1.actor);
|
||||
is(where.line, location.line);
|
||||
let variables = frame.environment.bindings.variables;
|
||||
is(variables.a.value, 1);
|
||||
is(variables.b.value.type, "undefined");
|
||||
is(variables.c.value.type, "undefined");
|
||||
return resume(threadClient1);
|
||||
}),
|
||||
waitForPause(threadClient2).then((packet) => {
|
||||
is(packet.type, "paused");
|
||||
let why = packet.why;
|
||||
is(why.type, "breakpoint");
|
||||
is(why.actors.length, 1);
|
||||
is(why.actors[0], breakpointClient2.actor);
|
||||
let frame = packet.frame;
|
||||
let where = frame.where;
|
||||
is(where.source.actor, sourceClient2.actor);
|
||||
is(where.line, location.line);
|
||||
let variables = frame.environment.bindings.variables;
|
||||
is(variables.a.value, 1);
|
||||
is(variables.b.value.type, "undefined");
|
||||
is(variables.c.value.type, "undefined");
|
||||
return resume(threadClient2);
|
||||
}),
|
||||
]);
|
||||
|
||||
terminateWorkerInTab(tab, WORKER_URL);
|
||||
yield waitForWorkerClose(workerClient1);
|
||||
yield waitForWorkerClose(workerClient2);
|
||||
yield close(client1);
|
||||
yield close(client2);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,33 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* This tests if the debugger leaks on initialization and sudden destruction.
|
||||
* You can also use this initialization format as a template for other tests.
|
||||
* If leaks happen here, there's something very, very fishy going on.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
// Wait longer for this very simple test that comes first, to make sure that
|
||||
// GC from previous tests does not interfere with the debugger suite.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
ok(aTab, "Should have a tab available.");
|
||||
ok(aPanel, "Should have a debugger pane available.");
|
||||
|
||||
waitForSourceAndCaretAndScopes(aPanel, "-02.js", 1).then(() => {
|
||||
resumeDebuggerThenCloseAndFinish(aPanel);
|
||||
});
|
||||
|
||||
callInTab(aTab, "firstCall");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that the we can see console messages from the add-on
|
||||
|
||||
const ADDON_ID = "browser_dbg_addon4@tests.mozilla.org";
|
||||
const ADDON_PATH = "addon4.xpi";
|
||||
|
||||
function getCachedMessages(webConsole) {
|
||||
let deferred = promise.defer();
|
||||
webConsole.getCachedMessages(["ConsoleAPI"], (aResponse) => {
|
||||
if (aResponse.error) {
|
||||
deferred.reject(aResponse.error);
|
||||
return;
|
||||
}
|
||||
deferred.resolve(aResponse.messages);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
let addon = yield addTemporaryAddon(ADDON_PATH);
|
||||
let addonDebugger = yield initAddonDebugger(ADDON_ID);
|
||||
|
||||
let webConsole = addonDebugger.webConsole;
|
||||
let messages = yield getCachedMessages(webConsole);
|
||||
is(messages.length, 1, "Should be one cached message");
|
||||
is(messages[0].arguments[0].type, "object", "Should have logged an object");
|
||||
is(messages[0].arguments[0].preview.ownProperties.msg.value, "Hello from the test add-on", "Should have got the right message");
|
||||
|
||||
let consolePromise = addonDebugger.once("console");
|
||||
|
||||
console.log("Bad message");
|
||||
Services.obs.notifyObservers(null, "addon-test-ping", "");
|
||||
|
||||
let messageGrip = yield consolePromise;
|
||||
is(messageGrip.arguments[0].type, "object", "Should have logged an object");
|
||||
is(messageGrip.arguments[0].preview.ownProperties.msg.value, "Hello again", "Should have got the right message");
|
||||
|
||||
yield addonDebugger.destroy();
|
||||
yield removeAddon(addon);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure the add-on actor can see loaded JS Modules from an add-on
|
||||
|
||||
const ADDON_ID = "browser_dbg_addon5@tests.mozilla.org";
|
||||
const ADDON_PATH = "addon-source/browser_dbg_addon5/";
|
||||
const ADDON_URL = getTemporaryAddonURLFromPath(ADDON_PATH);
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
let addon = yield addTemporaryAddon(ADDON_PATH);
|
||||
let tab1 = yield addTab("chrome://browser_dbg_addon5/content/test.xul");
|
||||
|
||||
let addonDebugger = yield initAddonDebugger(ADDON_ID);
|
||||
|
||||
is(addonDebugger.title,
|
||||
`Developer Tools - Test unpacked add-on with JS Modules - ${ADDON_URL}`,
|
||||
"Saw the right toolbox title.");
|
||||
|
||||
// Check the inital list of sources is correct
|
||||
let groups = yield addonDebugger.getSourceGroups();
|
||||
is(groups[0].name, "browser_dbg_addon5@tests.mozilla.org", "Add-on code should be the first group");
|
||||
is(groups[1].name, "chrome://global", "XUL code should be the second group");
|
||||
is(groups.length, 2, "Should be only two groups.");
|
||||
|
||||
let sources = groups[0].sources;
|
||||
is(sources.length, 3, "Should be three sources");
|
||||
ok(sources[0].url.endsWith("/browser_dbg_addon5/bootstrap.js"), "correct url for bootstrap code");
|
||||
is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
|
||||
is(sources[1].url, "resource://browser_dbg_addon5/test.jsm", "correct url for addon code");
|
||||
is(sources[1].label, "test.jsm", "correct label for addon code");
|
||||
is(sources[2].url, "chrome://browser_dbg_addon5/content/testxul.js", "correct url for addon tab code");
|
||||
is(sources[2].label, "testxul.js", "correct label for addon tab code");
|
||||
|
||||
// Load a new module and tab and check they appear in the list of sources
|
||||
Cu.import("resource://browser_dbg_addon5/test2.jsm", {});
|
||||
let tab2 = yield addTab("chrome://browser_dbg_addon5/content/test2.xul");
|
||||
|
||||
groups = yield addonDebugger.getSourceGroups();
|
||||
is(groups[0].name, "browser_dbg_addon5@tests.mozilla.org", "Add-on code should be the first group");
|
||||
is(groups[1].name, "chrome://global", "XUL code should be the second group");
|
||||
is(groups.length, 2, "Should be only two groups.");
|
||||
|
||||
sources = groups[0].sources;
|
||||
is(sources.length, 5, "Should be five sources");
|
||||
ok(sources[0].url.endsWith("/browser_dbg_addon5/bootstrap.js"), "correct url for bootstrap code");
|
||||
is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
|
||||
is(sources[1].url, "resource://browser_dbg_addon5/test.jsm", "correct url for addon code");
|
||||
is(sources[1].label, "test.jsm", "correct label for addon code");
|
||||
is(sources[2].url, "chrome://browser_dbg_addon5/content/testxul.js", "correct url for addon tab code");
|
||||
is(sources[2].label, "testxul.js", "correct label for addon tab code");
|
||||
is(sources[3].url, "resource://browser_dbg_addon5/test2.jsm", "correct url for addon code");
|
||||
is(sources[3].label, "test2.jsm", "correct label for addon code");
|
||||
is(sources[4].url, "chrome://browser_dbg_addon5/content/testxul2.js", "correct url for addon tab code");
|
||||
is(sources[4].label, "testxul2.js", "correct label for addon tab code");
|
||||
|
||||
Cu.unload("resource://browser_dbg_addon5/test2.jsm");
|
||||
yield addonDebugger.destroy();
|
||||
yield removeTab(tab1);
|
||||
yield removeTab(tab2);
|
||||
yield removeAddon(addon);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,66 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure the add-on actor can see loaded JS Modules from an add-on
|
||||
|
||||
const ADDON_ID = "browser_dbg_addon4@tests.mozilla.org";
|
||||
const ADDON_PATH = "addon4.xpi";
|
||||
const ADDON_URL = getTemporaryAddonURLFromPath(ADDON_PATH);
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
let addon = yield addTemporaryAddon(ADDON_PATH);
|
||||
let tab1 = yield addTab("chrome://browser_dbg_addon4/content/test.xul");
|
||||
|
||||
let addonDebugger = yield initAddonDebugger(ADDON_ID);
|
||||
|
||||
is(addonDebugger.title, `Developer Tools - Test add-on with JS Modules - ${ADDON_URL}`,
|
||||
"Saw the right toolbox title.");
|
||||
|
||||
// Check the inital list of sources is correct
|
||||
let groups = yield addonDebugger.getSourceGroups();
|
||||
is(groups[0].name, "browser_dbg_addon4@tests.mozilla.org", "Add-on code should be the first group");
|
||||
is(groups[1].name, "chrome://global", "XUL code should be the second group");
|
||||
is(groups.length, 2, "Should be only two groups.");
|
||||
|
||||
let sources = groups[0].sources;
|
||||
is(sources.length, 3, "Should be three sources");
|
||||
ok(sources[0].url.endsWith("/addon4.xpi!/bootstrap.js"), "correct url for bootstrap code");
|
||||
is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
|
||||
is(sources[1].url, "resource://browser_dbg_addon4/test.jsm", "correct url for addon code");
|
||||
is(sources[1].label, "test.jsm", "correct label for addon code");
|
||||
is(sources[2].url, "chrome://browser_dbg_addon4/content/testxul.js", "correct url for addon tab code");
|
||||
is(sources[2].label, "testxul.js", "correct label for addon tab code");
|
||||
|
||||
// Load a new module and tab and check they appear in the list of sources
|
||||
Cu.import("resource://browser_dbg_addon4/test2.jsm", {});
|
||||
let tab2 = yield addTab("chrome://browser_dbg_addon4/content/test2.xul");
|
||||
|
||||
groups = yield addonDebugger.getSourceGroups();
|
||||
is(groups[0].name, "browser_dbg_addon4@tests.mozilla.org", "Add-on code should be the first group");
|
||||
is(groups[1].name, "chrome://global", "XUL code should be the second group");
|
||||
is(groups.length, 2, "Should be only two groups.");
|
||||
|
||||
sources = groups[0].sources;
|
||||
is(sources.length, 5, "Should be five sources");
|
||||
ok(sources[0].url.endsWith("/addon4.xpi!/bootstrap.js"), "correct url for bootstrap code");
|
||||
is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
|
||||
is(sources[1].url, "resource://browser_dbg_addon4/test.jsm", "correct url for addon code");
|
||||
is(sources[1].label, "test.jsm", "correct label for addon code");
|
||||
is(sources[2].url, "chrome://browser_dbg_addon4/content/testxul.js", "correct url for addon tab code");
|
||||
is(sources[2].label, "testxul.js", "correct label for addon tab code");
|
||||
is(sources[3].url, "resource://browser_dbg_addon4/test2.jsm", "correct url for addon code");
|
||||
is(sources[3].label, "test2.jsm", "correct label for addon code");
|
||||
is(sources[4].url, "chrome://browser_dbg_addon4/content/testxul2.js", "correct url for addon tab code");
|
||||
is(sources[4].label, "testxul2.js", "correct label for addon tab code");
|
||||
|
||||
Cu.unload("resource://browser_dbg_addon4/test2.jsm");
|
||||
yield addonDebugger.destroy();
|
||||
yield removeTab(tab1);
|
||||
yield removeTab(tab2);
|
||||
yield removeAddon(addon);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Ensure that only panels that are relevant to the addon debugger
|
||||
// display in the toolbox
|
||||
|
||||
const ADDON_ID = "jid1-ami3akps3baaeg@jetpack";
|
||||
const ADDON_PATH = "addon3.xpi";
|
||||
|
||||
var gAddon, gClient, gThreadClient, gDebugger, gSources;
|
||||
var PREFS = [
|
||||
["devtools.canvasdebugger.enabled", true],
|
||||
["devtools.shadereditor.enabled", true],
|
||||
["devtools.performance.enabled", true],
|
||||
["devtools.netmonitor.enabled", true],
|
||||
["devtools.scratchpad.enabled", true]
|
||||
];
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
// Store and enable all optional dev tools panels
|
||||
yield pushPrefs(...PREFS);
|
||||
|
||||
let addon = yield addTemporaryAddon(ADDON_PATH);
|
||||
let addonDebugger = yield initAddonDebugger(ADDON_ID);
|
||||
|
||||
// Check only valid tabs are shown
|
||||
let tabs = addonDebugger.frame.contentDocument.getElementById("toolbox-tabs").children;
|
||||
let expectedTabs = ["webconsole", "jsdebugger", "scratchpad"];
|
||||
|
||||
is(tabs.length, expectedTabs.length, "displaying only " + expectedTabs.length + " tabs in addon debugger");
|
||||
Array.forEach(tabs, (tab, i) => {
|
||||
let toolName = expectedTabs[i];
|
||||
is(tab.getAttribute("toolid"), toolName, "displaying " + toolName);
|
||||
});
|
||||
|
||||
// Check no toolbox buttons are shown
|
||||
let buttons = addonDebugger.frame.contentDocument.getElementById("toolbox-buttons").children;
|
||||
Array.forEach(buttons, (btn, i) => {
|
||||
is(btn.hidden, true, "no toolbox buttons for the addon debugger -- " + btn.className);
|
||||
});
|
||||
|
||||
yield addonDebugger.destroy();
|
||||
yield removeAddon(addon);
|
||||
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Ensure that the sources listed when debugging an addon are either from the
|
||||
// addon itself, or the SDK, with proper groups and labels.
|
||||
|
||||
const ADDON_ID = "jid1-ami3akps3baaeg@jetpack";
|
||||
const ADDON_PATH = "addon3.xpi";
|
||||
const ADDON_URL = getTemporaryAddonURLFromPath(ADDON_PATH);
|
||||
|
||||
var gClient;
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
let addon = yield addTemporaryAddon(ADDON_PATH);
|
||||
let addonDebugger = yield initAddonDebugger(ADDON_ID);
|
||||
|
||||
is(addonDebugger.title, `Developer Tools - browser_dbg_addon3 - ${ADDON_URL}`,
|
||||
"Saw the right toolbox title.");
|
||||
|
||||
// Check the inital list of sources is correct
|
||||
let groups = yield addonDebugger.getSourceGroups();
|
||||
is(groups[0].name, "jid1-ami3akps3baaeg@jetpack", "Add-on code should be the first group");
|
||||
is(groups[1].name, "Add-on SDK", "Add-on SDK should be the second group");
|
||||
is(groups.length, 2, "Should be only two groups.");
|
||||
|
||||
let sources = groups[0].sources;
|
||||
is(sources.length, 2, "Should be two sources");
|
||||
ok(sources[0].url.endsWith("/addon3.xpi!/bootstrap.js"), "correct url for bootstrap code");
|
||||
is(sources[0].label, "bootstrap.js", "correct label for bootstrap code");
|
||||
is(sources[1].url, "resource://jid1-ami3akps3baaeg-at-jetpack/browser_dbg_addon3/lib/main.js", "correct url for add-on code");
|
||||
is(sources[1].label, "resources/browser_dbg_addon3/lib/main.js", "correct label for add-on code");
|
||||
|
||||
ok(groups[1].sources.length > 10, "SDK modules are listed");
|
||||
|
||||
yield addonDebugger.destroy();
|
||||
yield removeAddon(addon);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that the Addon Debugger works when devtools.debugger.workers is enabled.
|
||||
// Workers controller cannot be used when debugging an Addon actor.
|
||||
|
||||
const ADDON_ID = "jid1-ami3akps3baaeg@jetpack";
|
||||
const ADDON_PATH = "addon3.xpi";
|
||||
const ADDON_URL = getTemporaryAddonURLFromPath(ADDON_PATH);
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
info("Enable worker debugging.");
|
||||
yield new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({
|
||||
"set": [["devtools.debugger.workers", true]]
|
||||
}, resolve);
|
||||
});
|
||||
|
||||
let addon = yield addTemporaryAddon(ADDON_PATH);
|
||||
let addonDebugger = yield initAddonDebugger(ADDON_ID);
|
||||
|
||||
is(addonDebugger.title,
|
||||
`Developer Tools - browser_dbg_addon3 - ${ADDON_URL}`,
|
||||
"Saw the right toolbox title.");
|
||||
|
||||
info("Check that groups and sources are displayed.");
|
||||
let groups = yield addonDebugger.getSourceGroups();
|
||||
is(groups.length, 2, "Should be only two groups.");
|
||||
let sources = groups[0].sources;
|
||||
is(sources.length, 2, "Should be two sources");
|
||||
|
||||
yield addonDebugger.destroy();
|
||||
yield removeAddon(addon);
|
||||
finish();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure we can attach to addon actors.
|
||||
|
||||
const ADDON3_PATH = "addon3.xpi";
|
||||
const ADDON3_ID = "jid1-ami3akps3baaeg@jetpack";
|
||||
const ADDON_MODULE_URL = "resource://jid1-ami3akps3baaeg-at-jetpack/browser_dbg_addon3/lib/main.js";
|
||||
|
||||
var gAddon, gClient, gThreadClient;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect().then(([aType, aTraits]) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
installAddon()
|
||||
.then(attachAddonActorForId.bind(null, gClient, ADDON3_ID))
|
||||
.then(attachAddonThread)
|
||||
.then(testDebugger)
|
||||
.then(testSources)
|
||||
.then(() => gClient.close())
|
||||
.then(uninstallAddon)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function installAddon() {
|
||||
return addTemporaryAddon(ADDON3_PATH).then(aAddon => {
|
||||
gAddon = aAddon;
|
||||
});
|
||||
}
|
||||
|
||||
function attachAddonThread([aGrip, aResponse]) {
|
||||
info("attached addon actor for Addon ID");
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.attachThread(aResponse.threadActor, (aResponse, aThreadClient) => {
|
||||
info("attached thread");
|
||||
gThreadClient = aThreadClient;
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testDebugger() {
|
||||
info("Entering testDebugger");
|
||||
let deferred = promise.defer();
|
||||
|
||||
once(gClient, "paused").then(() => {
|
||||
ok(true, "Should be able to attach to addon actor");
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
Services.obs.notifyObservers(null, "debuggerAttached", null);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testSources() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gThreadClient.getSources(aResponse => {
|
||||
// source URLs contain launch-specific temporary directory path,
|
||||
// hence the ".contains" call.
|
||||
const matches = aResponse.sources.filter(s => s.url.includes(ADDON_MODULE_URL));
|
||||
ok(matches.length > 0,
|
||||
"the main script of the addon is present in the source list");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function uninstallAddon() {
|
||||
return removeAddon(gAddon);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gClient = null;
|
||||
gAddon = null;
|
||||
gThreadClient = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test auto pretty printing.
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_auto-pretty-print-01.html";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
var gEditor, gSources, gPrefs, gOptions, gView;
|
||||
|
||||
var gFirstSource = EXAMPLE_URL + "code_ugly-5.js";
|
||||
var gSecondSource = EXAMPLE_URL + "code_ugly-6.js";
|
||||
|
||||
var gOriginalPref = Services.prefs.getBoolPref("devtools.debugger.auto-pretty-print");
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: gFirstSource,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gEditor = gDebugger.DebuggerView.editor;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gPrefs = gDebugger.Prefs;
|
||||
gOptions = gDebugger.DebuggerView.Options;
|
||||
gView = gDebugger.DebuggerView;
|
||||
|
||||
Task.spawn(function* () {
|
||||
testSourceIsUgly();
|
||||
|
||||
enableAutoPrettyPrint();
|
||||
testAutoPrettyPrintOn();
|
||||
|
||||
reload(gPanel);
|
||||
yield waitForSourceShown(gPanel, gFirstSource);
|
||||
testSourceIsUgly();
|
||||
yield waitForSourceShown(gPanel, gFirstSource);
|
||||
testSourceIsPretty();
|
||||
disableAutoPrettyPrint();
|
||||
testAutoPrettyPrintOff();
|
||||
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedIndex = 1;
|
||||
yield finished;
|
||||
|
||||
testSecondSourceLabel();
|
||||
testSourceIsUgly();
|
||||
|
||||
enableAutoPrettyPrint();
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().includes("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
function testSecondSourceLabel() {
|
||||
let source = gSources.selectedItem.attachment.source;
|
||||
ok(source.url === gSecondSource,
|
||||
"Second source url is correct.");
|
||||
}
|
||||
|
||||
function testProgressBarShown() {
|
||||
const deck = gDebugger.document.getElementById("editor-deck");
|
||||
is(deck.selectedIndex, 2, "The progress bar should be shown");
|
||||
}
|
||||
|
||||
function testAutoPrettyPrintOn() {
|
||||
is(gPrefs.autoPrettyPrint, true,
|
||||
"The auto-pretty-print pref should be on.");
|
||||
is(gOptions._autoPrettyPrint.getAttribute("checked"), "true",
|
||||
"The Auto pretty print menu item should be checked.");
|
||||
}
|
||||
|
||||
function disableAutoPrettyPrint() {
|
||||
gOptions._autoPrettyPrint.setAttribute("checked", "false");
|
||||
gOptions._toggleAutoPrettyPrint();
|
||||
gOptions._onPopupHidden();
|
||||
}
|
||||
|
||||
function enableAutoPrettyPrint() {
|
||||
gOptions._autoPrettyPrint.setAttribute("checked", "true");
|
||||
gOptions._toggleAutoPrettyPrint();
|
||||
gOptions._onPopupHidden();
|
||||
}
|
||||
|
||||
function testAutoPrettyPrintOff() {
|
||||
is(gPrefs.autoPrettyPrint, false,
|
||||
"The auto-pretty-print pref should be off.");
|
||||
isnot(gOptions._autoPrettyPrint.getAttribute("checked"), "true",
|
||||
"The Auto pretty print menu item should not be checked.");
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().includes("\n "),
|
||||
"The source should be pretty printed.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gEditor = null;
|
||||
gSources = null;
|
||||
gOptions = null;
|
||||
gPrefs = null;
|
||||
gView = null;
|
||||
Services.prefs.setBoolPref("devtools.debugger.auto-pretty-print", gOriginalPref);
|
||||
});
|
||||
|
|
@ -0,0 +1,126 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that auto pretty printing doesn't accidentally toggle
|
||||
* pretty printing off when we switch to a minified source
|
||||
* that is already pretty printed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_auto-pretty-print-02.html";
|
||||
|
||||
var gTab, gDebuggee, gPanel, gDebugger;
|
||||
var gEditor, gSources, gPrefs, gOptions, gView;
|
||||
|
||||
var gFirstSource = EXAMPLE_URL + "code_ugly-6.js";
|
||||
var gSecondSource = EXAMPLE_URL + "code_ugly-7.js";
|
||||
|
||||
var gOriginalPref = Services.prefs.getBoolPref("devtools.debugger.auto-pretty-print");
|
||||
Services.prefs.setBoolPref("devtools.debugger.auto-pretty-print", true);
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: gFirstSource,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab, aDebuggee, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gDebuggee = aDebuggee;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const gPrefs = gDebugger.Prefs;
|
||||
const gOptions = gDebugger.DebuggerView.Options;
|
||||
const gView = gDebugger.DebuggerView;
|
||||
|
||||
// Should be on by default.
|
||||
testAutoPrettyPrintOn();
|
||||
|
||||
Task.spawn(function* () {
|
||||
|
||||
testSourceIsUgly();
|
||||
|
||||
yield waitForSourceShown(gPanel, gFirstSource);
|
||||
testSourceIsPretty();
|
||||
testPrettyPrintButtonOn();
|
||||
|
||||
// select second source
|
||||
yield selectSecondSource();
|
||||
testSecondSourceLabel();
|
||||
|
||||
// select first source
|
||||
yield selectFirstSource();
|
||||
testFirstSourceLabel();
|
||||
testPrettyPrintButtonOn();
|
||||
|
||||
// Disable auto pretty printing so it does not affect the following tests.
|
||||
yield disableAutoPrettyPrint();
|
||||
|
||||
closeDebuggerAndFinish(gPanel)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + DevToolsUtils.safeErrorString(aError));
|
||||
});
|
||||
});
|
||||
|
||||
function selectSecondSource() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN, 2);
|
||||
gSources.selectedIndex = 1;
|
||||
return finished;
|
||||
}
|
||||
|
||||
function selectFirstSource() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
gSources.selectedIndex = 0;
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testSourceIsUgly() {
|
||||
ok(!gEditor.getText().includes("\n "),
|
||||
"The source shouldn't be pretty printed yet.");
|
||||
}
|
||||
|
||||
function testFirstSourceLabel() {
|
||||
let source = gSources.selectedItem.attachment.source;
|
||||
ok(source.url === gFirstSource,
|
||||
"First source url is correct.");
|
||||
}
|
||||
|
||||
function testSecondSourceLabel() {
|
||||
let source = gSources.selectedItem.attachment.source;
|
||||
ok(source.url === gSecondSource,
|
||||
"Second source url is correct.");
|
||||
}
|
||||
|
||||
function testAutoPrettyPrintOn() {
|
||||
is(gPrefs.autoPrettyPrint, true,
|
||||
"The auto-pretty-print pref should be on.");
|
||||
is(gOptions._autoPrettyPrint.getAttribute("checked"), "true",
|
||||
"The Auto pretty print menu item should be checked.");
|
||||
}
|
||||
|
||||
function testPrettyPrintButtonOn() {
|
||||
is(gDebugger.document.getElementById("pretty-print").checked, true,
|
||||
"The button should be checked when the source is selected.");
|
||||
}
|
||||
|
||||
function disableAutoPrettyPrint() {
|
||||
gOptions._autoPrettyPrint.setAttribute("checked", "false");
|
||||
gOptions._toggleAutoPrettyPrint();
|
||||
gOptions._onPopupHidden();
|
||||
info("Disabled auto pretty printing.");
|
||||
}
|
||||
|
||||
function testSourceIsPretty() {
|
||||
ok(gEditor.getText().includes("\n "),
|
||||
"The source should be pretty printed.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.setBoolPref("devtools.debugger.auto-pretty-print", gOriginalPref);
|
||||
});
|
||||
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* If auto pretty-printing it enabled, make sure that if
|
||||
* pretty-printing fails that it still properly shows the original
|
||||
* source.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_auto-pretty-print-02.html";
|
||||
|
||||
var FIRST_SOURCE = EXAMPLE_URL + "code_ugly-6.js";
|
||||
var SECOND_SOURCE = EXAMPLE_URL + "code_ugly-7.js";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: FIRST_SOURCE,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab, aDebuggee, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
|
||||
const gController = gDebugger.DebuggerController;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
|
||||
Task.spawn(function* () {
|
||||
const secondSource = queries.getSourceByURL(gController.getState(), SECOND_SOURCE);
|
||||
actions.selectSource(secondSource);
|
||||
|
||||
// It should be showing the loading text
|
||||
is(gEditor.getText(), gDebugger.DebuggerView._loadingText,
|
||||
"The editor loading text is shown");
|
||||
|
||||
gController.dispatch({
|
||||
type: constants.TOGGLE_PRETTY_PRINT,
|
||||
status: "error",
|
||||
source: secondSource,
|
||||
});
|
||||
|
||||
is(gEditor.getText(), gDebugger.DebuggerView._loadingText,
|
||||
"The editor loading text is shown");
|
||||
|
||||
yield waitForSourceShown(gPanel, SECOND_SOURCE);
|
||||
|
||||
ok(gEditor.getText().includes("function foo"),
|
||||
"The second source is shown");
|
||||
|
||||
yield closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,95 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that the debugger is updated with the correct sources when moving
|
||||
* back and forward in the tab.
|
||||
*/
|
||||
|
||||
const TAB_URL_1 = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
const TAB_URL_2 = EXAMPLE_URL + "doc_recursion-stack.html";
|
||||
|
||||
var gTab, gDebuggee, gPanel, gDebugger;
|
||||
var gSources;
|
||||
|
||||
const test = Task.async(function* () {
|
||||
info("Starting browser_dbg_bfcache.js's `test`.");
|
||||
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
([gTab, gDebuggee, gPanel]) = yield initDebugger(TAB_URL_1, options);
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
yield testFirstPage();
|
||||
yield testLocationChange();
|
||||
yield testBack();
|
||||
yield testForward();
|
||||
return closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
|
||||
function testFirstPage() {
|
||||
info("Testing first page.");
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => gDebuggee.firstCall());
|
||||
|
||||
return waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1)
|
||||
.then(validateFirstPage);
|
||||
}
|
||||
|
||||
function testLocationChange() {
|
||||
info("Navigating to a different page.");
|
||||
|
||||
return navigateActiveTabTo(gPanel,
|
||||
TAB_URL_2,
|
||||
gDebugger.EVENTS.SOURCES_ADDED)
|
||||
.then(validateSecondPage);
|
||||
}
|
||||
|
||||
function testBack() {
|
||||
info("Going back.");
|
||||
|
||||
return navigateActiveTabInHistory(gPanel,
|
||||
"back",
|
||||
gDebugger.EVENTS.SOURCES_ADDED)
|
||||
.then(validateFirstPage);
|
||||
}
|
||||
|
||||
function testForward() {
|
||||
info("Going forward.");
|
||||
|
||||
return navigateActiveTabInHistory(gPanel,
|
||||
"forward",
|
||||
gDebugger.EVENTS.SOURCES_ADDED)
|
||||
.then(validateSecondPage);
|
||||
}
|
||||
|
||||
function validateFirstPage() {
|
||||
is(gSources.itemCount, 2,
|
||||
"Found the expected number of sources.");
|
||||
ok(gSources.getItemForAttachment(e => e.label == "code_script-switching-01.js"),
|
||||
"Found the first source label.");
|
||||
ok(gSources.getItemForAttachment(e => e.label == "code_script-switching-02.js"),
|
||||
"Found the second source label.");
|
||||
}
|
||||
|
||||
function validateSecondPage() {
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
ok(gSources.getItemForAttachment(e => e.label == "doc_recursion-stack.html"),
|
||||
"Found the single source label.");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that if we black box a source and then refresh, it is still black boxed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_binary_search.html";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_binary_search.coffee",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
testBlackBoxSource()
|
||||
.then(testBlackBoxReload)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
const bbButton = getBlackBoxButton(gPanel);
|
||||
ok(!bbButton.checked, "Should not be black boxed by default");
|
||||
|
||||
return toggleBlackBoxing(gPanel).then(source => {
|
||||
ok(source.isBlackBoxed, "The source should be black boxed now.");
|
||||
ok(bbButton.checked, "The checkbox should no longer be checked.");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxReload() {
|
||||
return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(() => {
|
||||
const bbButton = getBlackBoxButton(gPanel);
|
||||
const selectedSource = getSelectedSourceElement(gPanel);
|
||||
ok(bbButton.checked, "Should still be black boxed.");
|
||||
ok(selectedSource.classList.contains("black-boxed"),
|
||||
"'black-boxed' class should still be applied");
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that black boxed frames are compressed into a single frame on the stack
|
||||
* view.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
var gFrames;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: BLACKBOXME_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
testBlackBoxSource()
|
||||
.then(testBlackBoxStack)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
return toggleBlackBoxing(gPanel).then(source => {
|
||||
ok(source.isBlackBoxed, "The source should be black boxed now.");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxStack() {
|
||||
let finished = waitForSourceAndCaretAndScopes(gPanel, ".html", 21).then(() => {
|
||||
is(gFrames.itemCount, 3,
|
||||
"Should only get 3 frames.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
|
||||
"And one of them should be the combined black boxed frames.");
|
||||
});
|
||||
|
||||
callInTab(gTab, "runTest");
|
||||
return finished;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that black boxed frames are compressed into a single frame on the stack
|
||||
* view when we are already paused.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
var gFrames, gSources;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: BLACKBOXME_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 21)
|
||||
.then(testBlackBoxStack)
|
||||
.then(testBlackBoxSource)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
callInTab(gTab, "runTest");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxStack() {
|
||||
is(gFrames.itemCount, 6,
|
||||
"Should get 6 frames.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 0,
|
||||
"And none of them are black boxed.");
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
return toggleBlackBoxing(gPanel, getSourceActor(gSources, BLACKBOXME_URL)).then(aSource => {
|
||||
ok(aSource.isBlackBoxed, "The source should be black boxed now.");
|
||||
|
||||
is(gFrames.itemCount, 3,
|
||||
"Should only get 3 frames.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 1,
|
||||
"And one of them should be the combined black boxed frames.");
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,65 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that we get a stack frame for each black boxed source, not a single one
|
||||
* for all of them.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
var gFrames, gSources;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: BLACKBOXME_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
blackBoxSources()
|
||||
.then(testBlackBoxStack)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function blackBoxSources() {
|
||||
let finished = waitForThreadEvents(gPanel, "blackboxchange", 3);
|
||||
|
||||
toggleBlackBoxing(gPanel, getSourceActor(gSources, EXAMPLE_URL + "code_blackboxing_one.js"));
|
||||
toggleBlackBoxing(gPanel, getSourceActor(gSources, EXAMPLE_URL + "code_blackboxing_two.js"));
|
||||
toggleBlackBoxing(gPanel, getSourceActor(gSources, EXAMPLE_URL + "code_blackboxing_three.js"));
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBlackBoxStack() {
|
||||
let finished = waitForSourceAndCaretAndScopes(gPanel, ".html", 21).then(() => {
|
||||
is(gFrames.itemCount, 4,
|
||||
"Should get 4 frames (one -> two -> three -> doDebuggerStatement).");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe-black-boxed").length, 3,
|
||||
"And 'one', 'two', and 'three' should each have their own black boxed frame.");
|
||||
});
|
||||
|
||||
callInTab(gTab, "one");
|
||||
return finished;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gFrames = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that a "this source is blackboxed" message is shown when necessary
|
||||
* and can be properly dismissed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_binary_search.html";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
var gDeck;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_binary_search.coffee",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gDeck = gDebugger.document.getElementById("editor-deck");
|
||||
|
||||
testSourceEditorShown();
|
||||
toggleBlackBoxing(gPanel)
|
||||
.then(testBlackBoxMessageShown)
|
||||
.then(clickStopBlackBoxingButton)
|
||||
.then(testSourceEditorShownAgain)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testSourceEditorShown() {
|
||||
is(gDeck.selectedIndex, "0",
|
||||
"The first item in the deck should be selected (the source editor).");
|
||||
}
|
||||
|
||||
function testBlackBoxMessageShown() {
|
||||
is(gDeck.selectedIndex, "1",
|
||||
"The second item in the deck should be selected (the black box message).");
|
||||
}
|
||||
|
||||
function clickStopBlackBoxingButton() {
|
||||
// Give the test a chance to finish before triggering the click event.
|
||||
executeSoon(() => getEditorBlackboxMessageButton().click());
|
||||
return waitForDispatch(gPanel, gDebugger.constants.BLACKBOX);
|
||||
}
|
||||
|
||||
function testSourceEditorShownAgain() {
|
||||
// Wait a tick for the final check to make sure the frontend's click handlers
|
||||
// have finished.
|
||||
return new Promise(resolve => {
|
||||
is(gDeck.selectedIndex, "0",
|
||||
"The first item in the deck should be selected again (the source editor).");
|
||||
resolve();
|
||||
});
|
||||
}
|
||||
|
||||
function getEditorBlackboxMessageButton() {
|
||||
return gDebugger.document.getElementById("black-boxed-message-button");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gDeck = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that clicking the black box checkbox when paused doesn't re-select the
|
||||
* currently paused frame's source.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
var gSources;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_blackboxing_blackboxme.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
waitForCaretAndScopes(gPanel, 21)
|
||||
.then(testBlackBox)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
callInTab(gTab, "runTest");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBox() {
|
||||
const selectedActor = gSources.selectedValue;
|
||||
|
||||
let finished = waitForSourceShown(gPanel, "blackboxme.js").then(() => {
|
||||
const newSelectedActor = gSources.selectedValue;
|
||||
isnot(selectedActor, newSelectedActor,
|
||||
"Should not have the same url selected.");
|
||||
|
||||
return toggleBlackBoxing(gPanel).then(() => {
|
||||
is(gSources.selectedValue, newSelectedActor,
|
||||
"The selected source did not change.");
|
||||
});
|
||||
});
|
||||
|
||||
gSources.selectedIndex = 0;
|
||||
return finished;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
gSources = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that if we unblackbox a source which has been automatically blackboxed
|
||||
* and then refresh, it is still unblackboxed.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_blackboxing_unblackbox.html";
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_blackboxing_unblackbox.min.js",
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
testBlackBoxSource()
|
||||
.then(testBlackBoxReload)
|
||||
.then(() => closeDebuggerAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxSource() {
|
||||
const bbButton = getBlackBoxButton(gPanel);
|
||||
ok(bbButton.checked, "Should be black boxed by default");
|
||||
|
||||
return toggleBlackBoxing(gPanel).then(aSource => {
|
||||
ok(!aSource.isBlackBoxed, "The source should no longer be blackboxed.");
|
||||
});
|
||||
}
|
||||
|
||||
function testBlackBoxReload() {
|
||||
return reloadActiveTab(gPanel, gDebugger.EVENTS.SOURCE_SHOWN).then(() => {
|
||||
const selectedSource = getSelectedSourceElement(gPanel);
|
||||
ok(!selectedSource.isBlackBoxed, "The source should not be blackboxed.");
|
||||
});
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,98 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests if the stackframe breadcrumbs are keyboard accessible.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gSources, gFrames;
|
||||
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gFrames = gDebugger.DebuggerView.StackFrames;
|
||||
|
||||
waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6)
|
||||
.then(checkNavigationWhileNotFocused)
|
||||
.then(focusCurrentStackFrame)
|
||||
.then(checkNavigationWhileFocused)
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
|
||||
function checkNavigationWhileNotFocused() {
|
||||
checkState({ frame: 1, source: 1, line: 6 });
|
||||
|
||||
return Task.spawn(function* () {
|
||||
EventUtils.sendKey("DOWN", gDebugger);
|
||||
checkState({ frame: 1, source: 1, line: 7 });
|
||||
|
||||
EventUtils.sendKey("UP", gDebugger);
|
||||
checkState({ frame: 1, source: 1, line: 6 });
|
||||
});
|
||||
}
|
||||
|
||||
function focusCurrentStackFrame() {
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gFrames.selectedItem.target,
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function checkNavigationWhileFocused() {
|
||||
return Task.spawn(function* () {
|
||||
yield promise.all([
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
|
||||
waitForSourceAndCaret(gPanel, "-01.js", 5),
|
||||
EventUtils.sendKey("UP", gDebugger)
|
||||
]);
|
||||
checkState({ frame: 0, source: 0, line: 5 });
|
||||
|
||||
// Need to refocus the stack frame due to a focus bug in e10s
|
||||
// (See Bug 1205482)
|
||||
focusCurrentStackFrame();
|
||||
|
||||
yield promise.all([
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
|
||||
waitForSourceAndCaret(gPanel, "-02.js", 6),
|
||||
EventUtils.sendKey("END", gDebugger)
|
||||
]);
|
||||
checkState({ frame: 1, source: 1, line: 6 });
|
||||
|
||||
// Need to refocus the stack frame due to a focus bug in e10s
|
||||
// (See Bug 1205482)
|
||||
focusCurrentStackFrame();
|
||||
|
||||
yield promise.all([
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES),
|
||||
waitForSourceAndCaret(gPanel, "-01.js", 5),
|
||||
EventUtils.sendKey("HOME", gDebugger)
|
||||
]);
|
||||
checkState({ frame: 0, source: 0, line: 5 });
|
||||
});
|
||||
}
|
||||
|
||||
function checkState({ frame, source, line, column }) {
|
||||
is(gFrames.selectedIndex, frame,
|
||||
"The currently selected stackframe is incorrect.");
|
||||
is(gSources.selectedIndex, source,
|
||||
"The currently selected source is incorrect.");
|
||||
ok(isCaretPos(gPanel, line, column),
|
||||
"The source editor caret position was incorrect.");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure anonymous eval scripts can still break with a `debugger`
|
||||
* statement
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-eval.html";
|
||||
|
||||
function test() {
|
||||
const options = {
|
||||
source: EXAMPLE_URL + "code_script-eval.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
return Task.spawn(function* () {
|
||||
is(gSources.values.length, 1, "Should have 1 source");
|
||||
|
||||
callInTab(gTab, "evalSourceWithDebugger");
|
||||
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
|
||||
is(gSources.values.length, 2, "Should have 2 sources");
|
||||
|
||||
let item = gSources.getItemForAttachment(e => e.label.indexOf("SCRIPT") === 0);
|
||||
ok(item, "Source label is incorrect.");
|
||||
is(item.attachment.group, gDebugger.L10N.getStr("anonymousSourcesLabel"),
|
||||
"Source group is incorrect");
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,58 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Whitelisting this test.
|
||||
// As part of bug 1077403, the leaking uncaught rejections should be fixed.
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed("[object Object]");
|
||||
thisTestLeaksUncaughtRejectionsAndShouldBeFixed(
|
||||
"TypeError: this.transport is null");
|
||||
|
||||
/**
|
||||
* Tests that event listeners aren't fetched when the events tab isn't selected.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
let gPanel = aPanel;
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gEvents = gView.EventListeners;
|
||||
let gController = gDebugger.DebuggerController;
|
||||
let constants = gDebugger.require("./content/constants");
|
||||
|
||||
gDebugger.on(gDebugger.EVENTS.EVENT_LISTENERS_FETCHED, () => {
|
||||
ok(false, "Shouldn't have fetched any event listeners.");
|
||||
});
|
||||
gDebugger.on(gDebugger.EVENTS.EVENT_BREAKPOINTS_UPDATED, () => {
|
||||
ok(false, "Shouldn't have updated any event breakpoints.");
|
||||
});
|
||||
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false });
|
||||
|
||||
is(gView.instrumentsPaneHidden, false,
|
||||
"The instruments pane should be visible now.");
|
||||
is(gView.instrumentsPaneTab, "variables-tab",
|
||||
"The variables tab should be selected by default.");
|
||||
|
||||
Task.spawn(function* () {
|
||||
is(gEvents.itemCount, 0, "There should be no events before reloading.");
|
||||
|
||||
let reloaded = waitForNavigation(gPanel);
|
||||
gDebugger.DebuggerController._target.activeTab.reload();
|
||||
|
||||
is(gEvents.itemCount, 0, "There should be no events while reloading.");
|
||||
yield reloaded;
|
||||
is(gEvents.itemCount, 0, "There should be no events after reloading.");
|
||||
|
||||
yield closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that event listeners are fetched when the events tab is selected
|
||||
* or while sources are fetched and the events tab is focused.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
let gPanel = aPanel;
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gEvents = gView.EventListeners;
|
||||
let gController = gDebugger.DebuggerController;
|
||||
let constants = gDebugger.require("./content/constants");
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield testFetchOnFocus();
|
||||
yield testFetchOnReloadWhenFocused();
|
||||
yield testFetchOnReloadWhenNotFocused();
|
||||
yield closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
|
||||
function testFetchOnFocus() {
|
||||
return Task.spawn(function* () {
|
||||
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
|
||||
is(gView.instrumentsPaneHidden, false,
|
||||
"The instruments pane should be visible now.");
|
||||
is(gView.instrumentsPaneTab, "events-tab",
|
||||
"The events tab should be selected.");
|
||||
|
||||
yield fetched;
|
||||
|
||||
ok(true,
|
||||
"Event listeners were fetched when the events tab was selected");
|
||||
is(gEvents.itemCount, 4,
|
||||
"There should be 4 events displayed in the view.");
|
||||
});
|
||||
}
|
||||
|
||||
function testFetchOnReloadWhenFocused() {
|
||||
return Task.spawn(function* () {
|
||||
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
|
||||
let reloading = once(gDebugger.gTarget, "will-navigate");
|
||||
let reloaded = waitForNavigation(gPanel);
|
||||
gDebugger.DebuggerController._target.activeTab.reload();
|
||||
|
||||
yield reloading;
|
||||
|
||||
is(gEvents.itemCount, 0,
|
||||
"There should be no events displayed in the view while reloading.");
|
||||
ok(true,
|
||||
"Event listeners were removed when the target started navigating.");
|
||||
|
||||
yield reloaded;
|
||||
|
||||
is(gView.instrumentsPaneHidden, false,
|
||||
"The instruments pane should still be visible.");
|
||||
is(gView.instrumentsPaneTab, "events-tab",
|
||||
"The events tab should still be selected.");
|
||||
|
||||
yield fetched;
|
||||
|
||||
is(gEvents.itemCount, 4,
|
||||
"There should be 4 events displayed in the view after reloading.");
|
||||
ok(true,
|
||||
"Event listeners were added back after the target finished navigating.");
|
||||
});
|
||||
}
|
||||
|
||||
function testFetchOnReloadWhenNotFocused() {
|
||||
return Task.spawn(function* () {
|
||||
gController.dispatch({
|
||||
type: gDebugger.services.WAIT_UNTIL,
|
||||
predicate: action => {
|
||||
return (action.type === constants.FETCH_EVENT_LISTENERS ||
|
||||
action.type === constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
},
|
||||
run: (dispatch, getState, action) => {
|
||||
if (action.type === constants.FETCH_EVENT_LISTENERS) {
|
||||
ok(false, "Shouldn't have fetched any event listeners.");
|
||||
}
|
||||
else if (action.type === constants.UPDATE_EVENT_BREAKPOINTS) {
|
||||
ok(false, "Shouldn't have updated any event breakpoints.");
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false }, 0);
|
||||
is(gView.instrumentsPaneHidden, false,
|
||||
"The instruments pane should still be visible.");
|
||||
is(gView.instrumentsPaneTab, "variables-tab",
|
||||
"The variables tab should be selected.");
|
||||
|
||||
let reloading = once(gDebugger.gTarget, "will-navigate");
|
||||
let reloaded = waitForNavigation(gPanel);
|
||||
gDebugger.DebuggerController._target.activeTab.reload();
|
||||
|
||||
yield reloading;
|
||||
|
||||
is(gEvents.itemCount, 0,
|
||||
"There should be no events displayed in the view while reloading.");
|
||||
ok(true,
|
||||
"Event listeners were removed when the target started navigating.");
|
||||
|
||||
yield reloaded;
|
||||
|
||||
is(gView.instrumentsPaneHidden, false,
|
||||
"The instruments pane should still be visible.");
|
||||
is(gView.instrumentsPaneTab, "variables-tab",
|
||||
"The variables tab should still be selected.");
|
||||
|
||||
// Just to be really sure that the events will never ever fire.
|
||||
yield waitForTime(1000);
|
||||
|
||||
is(gEvents.itemCount, 0,
|
||||
"There should be no events displayed in the view after reloading.");
|
||||
ok(true,
|
||||
"Event listeners were not added after the target finished navigating.");
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that event listeners are properly displayed in the view.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gEvents = gView.EventListeners;
|
||||
let gController = gDebugger.DebuggerController;
|
||||
let constants = gDebugger.require("./content/constants");
|
||||
|
||||
Task.spawn(function* () {
|
||||
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
|
||||
yield fetched;
|
||||
|
||||
is(gEvents.widget._parent.querySelectorAll(".side-menu-widget-group").length, 3,
|
||||
"There should be 3 groups shown in the view.");
|
||||
|
||||
let groupCheckboxes = gEvents.widget._parent.querySelectorAll(
|
||||
".side-menu-widget-group-checkbox");
|
||||
is(groupCheckboxes.length, 3,
|
||||
"There should be a checkbox for each group shown in the view.");
|
||||
for (let cb of groupCheckboxes) {
|
||||
isnot(cb.getAttribute("tooltiptext"), "undefined",
|
||||
"A valid tooltip text should be defined on group checkboxes");
|
||||
}
|
||||
|
||||
is(gEvents.widget._parent.querySelectorAll(".side-menu-widget-item").length, 4,
|
||||
"There should be 4 items shown in the view.");
|
||||
is(gEvents.widget._parent.querySelectorAll(".side-menu-widget-item-checkbox").length, 4,
|
||||
"There should be a checkbox for each item shown in the view.");
|
||||
|
||||
testEventItem(0, "doc_event-listeners-02.html", "change", ["body > input:nth-child(2)"], false);
|
||||
testEventItem(1, "doc_event-listeners-02.html", "click", ["body > button:nth-child(1)"], false);
|
||||
testEventItem(2, "doc_event-listeners-02.html", "keydown", ["window", "body"], false);
|
||||
testEventItem(3, "doc_event-listeners-02.html", "keyup", ["body > input:nth-child(2)"], false);
|
||||
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
|
||||
is(gEvents.getAllEvents().toString(), "change,click,keydown,keyup",
|
||||
"The getAllEvents() method returns the correct stuff.");
|
||||
is(gEvents.getCheckedEvents().toString(), "",
|
||||
"The getCheckedEvents() method returns the correct stuff.");
|
||||
|
||||
yield ensureThreadClientState(aPanel, "attached");
|
||||
yield closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
|
||||
function testEventItem(index, label, type, selectors, checked) {
|
||||
let item = gEvents.items[index];
|
||||
let node = item.target;
|
||||
|
||||
ok(item.attachment.url.includes(label),
|
||||
"The event at index " + index + " has the correct url.");
|
||||
is(item.attachment.type, type,
|
||||
"The event at index " + index + " has the correct type.");
|
||||
is(item.attachment.selectors.toString(), selectors,
|
||||
"The event at index " + index + " has the correct selectors.");
|
||||
is(item.attachment.checkboxState, checked,
|
||||
"The event at index " + index + " has the correct checkbox state.");
|
||||
|
||||
let targets = selectors.length > 1
|
||||
? gDebugger.L10N.getFormatStr("eventNodes", selectors.length)
|
||||
: selectors.toString();
|
||||
|
||||
is(node.querySelector(".dbg-event-listener-type").getAttribute("value"), type,
|
||||
"The correct type is shown for this event.");
|
||||
is(node.querySelector(".dbg-event-listener-targets").getAttribute("value"), targets,
|
||||
"The correct target is shown for this event.");
|
||||
is(node.querySelector(".dbg-event-listener-location").getAttribute("value"), label,
|
||||
"The correct location is shown for this event.");
|
||||
is(node.parentNode.querySelector(".side-menu-widget-item-checkbox").checked, checked,
|
||||
"The correct checkbox state is shown for this event.");
|
||||
}
|
||||
|
||||
function testEventGroup(string, checked) {
|
||||
let name = gDebugger.L10N.getStr(string);
|
||||
let group = gEvents.widget._parent
|
||||
.querySelector(".side-menu-widget-group[name=" + name + "]");
|
||||
|
||||
is(group.querySelector(".side-menu-widget-group-title > .name").value, name,
|
||||
"The correct label is shown for the group named " + name + ".");
|
||||
is(group.querySelector(".side-menu-widget-group-checkbox").checked, checked,
|
||||
"The correct checkbox state is shown for the group named " + name + ".");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that checking/unchecking an event listener in the view correctly
|
||||
* causes the active thread to get updated with the new event breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gController = gDebugger.DebuggerController;
|
||||
let gEvents = gView.EventListeners;
|
||||
let constants = gDebugger.require("./content/constants");
|
||||
|
||||
Task.spawn(function* () {
|
||||
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
|
||||
yield fetched;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, true);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "change");
|
||||
|
||||
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
yield ensureThreadClientState(aPanel, "attached");
|
||||
yield closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
|
||||
function getItemCheckboxNode(index) {
|
||||
return gEvents.items[index].target.parentNode
|
||||
.querySelector(".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function getGroupCheckboxNode(string) {
|
||||
return gEvents.widget._parent
|
||||
.querySelector(".side-menu-widget-group[name=" + gDebugger.L10N.getStr(string) + "]")
|
||||
.querySelector(".side-menu-widget-group-checkbox");
|
||||
}
|
||||
|
||||
function testEventItem(index, checked) {
|
||||
is(gEvents.attachments[index].checkboxState, checked,
|
||||
"The event at index " + index + " has the correct checkbox state.");
|
||||
is(getItemCheckboxNode(index).checked, checked,
|
||||
"The correct checkbox state is shown for this event.");
|
||||
}
|
||||
|
||||
function testEventGroup(string, checked) {
|
||||
is(getGroupCheckboxNode(string).checked, checked,
|
||||
"The correct checkbox state is shown for the group " + string + ".");
|
||||
}
|
||||
|
||||
function testEventArrays(all, checked) {
|
||||
is(gEvents.getAllEvents().toString(), all,
|
||||
"The getAllEvents() method returns the correct stuff.");
|
||||
is(gEvents.getCheckedEvents().toString(), checked,
|
||||
"The getCheckedEvents() method returns the correct stuff.");
|
||||
is(gController.getState().eventListeners.activeEventNames.toString(), checked,
|
||||
"The correct event names are listed as being active breakpoints.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,128 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that checking/unchecking an event listener's group in the view will
|
||||
* cause the active thread to get updated with the new event breakpoints for
|
||||
* all children inside that group.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gController = gDebugger.DebuggerController;
|
||||
let gEvents = gView.EventListeners;
|
||||
let constants = gDebugger.require("./content/constants");
|
||||
|
||||
Task.spawn(function* () {
|
||||
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
|
||||
yield fetched;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("interactionEvents"), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, true);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", true);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "change");
|
||||
|
||||
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("interactionEvents"), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("keyboardEvents"), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, true);
|
||||
testEventItem(3, true);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", true);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "keydown,keyup");
|
||||
|
||||
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getGroupCheckboxNode("keyboardEvents"), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
yield ensureThreadClientState(aPanel, "attached");
|
||||
yield closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
|
||||
function getItemCheckboxNode(index) {
|
||||
return gEvents.items[index].target.parentNode
|
||||
.querySelector(".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function getGroupCheckboxNode(string) {
|
||||
return gEvents.widget._parent
|
||||
.querySelector(".side-menu-widget-group[name=" + gDebugger.L10N.getStr(string) + "]")
|
||||
.querySelector(".side-menu-widget-group-checkbox");
|
||||
}
|
||||
|
||||
function testEventItem(index, checked) {
|
||||
is(gEvents.attachments[index].checkboxState, checked,
|
||||
"The event at index " + index + " has the correct checkbox state.");
|
||||
is(getItemCheckboxNode(index).checked, checked,
|
||||
"The correct checkbox state is shown for this event.");
|
||||
}
|
||||
|
||||
function testEventGroup(string, checked) {
|
||||
is(getGroupCheckboxNode(string).checked, checked,
|
||||
"The correct checkbox state is shown for the group " + string + ".");
|
||||
}
|
||||
|
||||
function testEventArrays(all, checked) {
|
||||
is(gEvents.getAllEvents().toString(), all,
|
||||
"The getAllEvents() method returns the correct stuff.");
|
||||
is(gEvents.getCheckedEvents().toString(), checked,
|
||||
"The getCheckedEvents() method returns the correct stuff.");
|
||||
is(gController.getState().eventListeners.activeEventNames.toString(), checked,
|
||||
"The correct event names are listed as being active breakpoints.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the event listener states are preserved in the view after the
|
||||
* target navigates.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gController = gDebugger.DebuggerController;
|
||||
let gEvents = gView.EventListeners;
|
||||
let gBreakpoints = gController.Breakpoints;
|
||||
let constants = gDebugger.require("./content/constants");
|
||||
|
||||
Task.spawn(function* () {
|
||||
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
|
||||
yield fetched;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(2), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, true);
|
||||
testEventItem(1, true);
|
||||
testEventItem(2, true);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "change,click,keydown");
|
||||
|
||||
reload(aPanel);
|
||||
yield waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
|
||||
testEventItem(0, true);
|
||||
testEventItem(1, true);
|
||||
testEventItem(2, true);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "change,click,keydown");
|
||||
|
||||
updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(0), gDebugger);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(2), gDebugger);
|
||||
yield updated;
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
reload(aPanel);
|
||||
yield waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
|
||||
testEventItem(0, false);
|
||||
testEventItem(1, false);
|
||||
testEventItem(2, false);
|
||||
testEventItem(3, false);
|
||||
testEventGroup("interactionEvents", false);
|
||||
testEventGroup("keyboardEvents", false);
|
||||
testEventGroup("mouseEvents", false);
|
||||
testEventArrays("change,click,keydown,keyup", "");
|
||||
|
||||
yield ensureThreadClientState(aPanel, "attached");
|
||||
yield closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
|
||||
function getItemCheckboxNode(index) {
|
||||
return gEvents.items[index].target.parentNode
|
||||
.querySelector(".side-menu-widget-item-checkbox");
|
||||
}
|
||||
|
||||
function getGroupCheckboxNode(string) {
|
||||
return gEvents.widget._parent
|
||||
.querySelector(".side-menu-widget-group[name=" + gDebugger.L10N.getStr(string) + "]")
|
||||
.querySelector(".side-menu-widget-group-checkbox");
|
||||
}
|
||||
|
||||
function testEventItem(index, checked) {
|
||||
is(gEvents.attachments[index].checkboxState, checked,
|
||||
"The event at index " + index + " has the correct checkbox state.");
|
||||
is(getItemCheckboxNode(index).checked, checked,
|
||||
"The correct checkbox state is shown for this event.");
|
||||
}
|
||||
|
||||
function testEventGroup(string, checked) {
|
||||
is(getGroupCheckboxNode(string).checked, checked,
|
||||
"The correct checkbox state is shown for the group " + string + ".");
|
||||
}
|
||||
|
||||
function testEventArrays(all, checked) {
|
||||
is(gEvents.getAllEvents().toString(), all,
|
||||
"The getAllEvents() method returns the correct stuff.");
|
||||
is(gEvents.getCheckedEvents().toString(), checked,
|
||||
"The getCheckedEvents() method returns the correct stuff.");
|
||||
is(gController.getState().eventListeners.activeEventNames.toString(), checked,
|
||||
"The correct event names are listed as being active breakpoints.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that system event listeners don't get duplicated in the view.
|
||||
*/
|
||||
|
||||
function test() {
|
||||
initDebugger().then(([aTab,, aPanel]) => {
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gEvents = gView.EventListeners;
|
||||
let gL10N = gDebugger.L10N;
|
||||
|
||||
is(gEvents.itemCount, 0,
|
||||
"There are no events displayed in the corresponding pane yet.");
|
||||
|
||||
gEvents.addListener({
|
||||
type: "foo",
|
||||
node: { selector: "#first" },
|
||||
function: { url: null }
|
||||
});
|
||||
|
||||
is(gEvents.itemCount, 1,
|
||||
"There was a system event listener added in the view.");
|
||||
is(gEvents.attachments[0].url, gL10N.getStr("eventNative"),
|
||||
"The correct string is used as the event's url.");
|
||||
is(gEvents.attachments[0].type, "foo",
|
||||
"The correct string is used as the event's type.");
|
||||
is(gEvents.attachments[0].selectors.toString(), "#first",
|
||||
"The correct array of selectors is used as the event's target.");
|
||||
|
||||
gEvents.addListener({
|
||||
type: "bar",
|
||||
node: { selector: "#second" },
|
||||
function: { url: null }
|
||||
});
|
||||
|
||||
is(gEvents.itemCount, 2,
|
||||
"There was another system event listener added in the view.");
|
||||
is(gEvents.attachments[1].url, gL10N.getStr("eventNative"),
|
||||
"The correct string is used as the event's url.");
|
||||
is(gEvents.attachments[1].type, "bar",
|
||||
"The correct string is used as the event's type.");
|
||||
is(gEvents.attachments[1].selectors.toString(), "#second",
|
||||
"The correct array of selectors is used as the event's target.");
|
||||
|
||||
gEvents.addListener({
|
||||
type: "foo",
|
||||
node: { selector: "#first" },
|
||||
function: { url: null }
|
||||
});
|
||||
|
||||
is(gEvents.itemCount, 2,
|
||||
"There wasn't another system event listener added in the view.");
|
||||
is(gEvents.attachments[0].url, gL10N.getStr("eventNative"),
|
||||
"The correct string is used as the event's url.");
|
||||
is(gEvents.attachments[0].type, "foo",
|
||||
"The correct string is used as the event's type.");
|
||||
is(gEvents.attachments[0].selectors.toString(), "#first",
|
||||
"The correct array of selectors is used as the event's target.");
|
||||
|
||||
gEvents.addListener({
|
||||
type: "foo",
|
||||
node: { selector: "#second" },
|
||||
function: { url: null }
|
||||
});
|
||||
|
||||
is(gEvents.itemCount, 2,
|
||||
"There still wasn't another system event listener added in the view.");
|
||||
is(gEvents.attachments[0].url, gL10N.getStr("eventNative"),
|
||||
"The correct string is used as the event's url.");
|
||||
is(gEvents.attachments[0].type, "foo",
|
||||
"The correct string is used as the event's type.");
|
||||
is(gEvents.attachments[0].selectors.toString(), "#first,#second",
|
||||
"The correct array of selectors is used as the event's target.");
|
||||
|
||||
|
||||
gEvents.addListener({
|
||||
type: null,
|
||||
node: { selector: "#bogus" },
|
||||
function: { url: null }
|
||||
});
|
||||
|
||||
is(gEvents.itemCount, 2,
|
||||
"No bogus system event listener was added in the view.");
|
||||
|
||||
is(gEvents.attachments[0].url, gL10N.getStr("eventNative"),
|
||||
"The correct string is used as the first event's url.");
|
||||
is(gEvents.attachments[0].type, "foo",
|
||||
"The correct string is used as the first event's type.");
|
||||
is(gEvents.attachments[0].selectors.toString(), "#first,#second",
|
||||
"The correct array of selectors is used as the first event's target.");
|
||||
|
||||
is(gEvents.attachments[1].url, gL10N.getStr("eventNative"),
|
||||
"The correct string is used as the second event's url.");
|
||||
is(gEvents.attachments[1].type, "bar",
|
||||
"The correct string is used as the second event's type.");
|
||||
is(gEvents.attachments[1].selectors.toString(), "#second",
|
||||
"The correct array of selectors is used as the second event's target.");
|
||||
|
||||
closeDebuggerAndFinish(aPanel);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that breaking on an event selects the variables view tab.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-02.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
let gTab = aTab;
|
||||
let gDebugger = aPanel.panelWin;
|
||||
let gView = gDebugger.DebuggerView;
|
||||
let gEvents = gView.EventListeners;
|
||||
let gController = gDebugger.DebuggerController;
|
||||
let constants = gDebugger.require("./content/constants");
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield callInTab(gTab, "addBodyClickEventListener");
|
||||
|
||||
let fetched = waitForDispatch(aPanel, constants.FETCH_EVENT_LISTENERS);
|
||||
gView.toggleInstrumentsPane({ visible: true, animated: false }, 1);
|
||||
yield fetched;
|
||||
yield ensureThreadClientState(aPanel, "attached");
|
||||
|
||||
is(gView.instrumentsPaneHidden, false,
|
||||
"The instruments pane should be visible.");
|
||||
is(gView.instrumentsPaneTab, "events-tab",
|
||||
"The events tab should be selected.");
|
||||
|
||||
let updated = waitForDispatch(aPanel, constants.UPDATE_EVENT_BREAKPOINTS);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, getItemCheckboxNode(1), gDebugger);
|
||||
yield updated;
|
||||
yield ensureThreadClientState(aPanel, "attached");
|
||||
|
||||
let paused = waitForCaretAndScopes(aPanel, 48);
|
||||
generateMouseClickInTab(gTab, "content.document.body");
|
||||
yield paused;
|
||||
yield ensureThreadClientState(aPanel, "paused");
|
||||
|
||||
is(gView.instrumentsPaneHidden, false,
|
||||
"The instruments pane should be visible.");
|
||||
is(gView.instrumentsPaneTab, "variables-tab",
|
||||
"The variables tab should be selected.");
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(aPanel);
|
||||
});
|
||||
|
||||
function getItemCheckboxNode(index) {
|
||||
return gEvents.items[index].target.parentNode
|
||||
.querySelector(".side-menu-widget-item-checkbox");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,225 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the break-on-dom-events request works.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-01.html";
|
||||
|
||||
var gClient, gThreadClient, gInput, gButton;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect().then(([aType, aTraits]) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
addTab(TAB_URL)
|
||||
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
|
||||
.then(setupGlobals)
|
||||
.then(pauseDebuggee)
|
||||
.then(testBreakOnAll)
|
||||
.then(testBreakOnDisabled)
|
||||
.then(testBreakOnNone)
|
||||
.then(testBreakOnClick)
|
||||
.then(() => gClient.close())
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function setupGlobals(aThreadClient) {
|
||||
gThreadClient = aThreadClient;
|
||||
gInput = content.document.querySelector("input");
|
||||
gButton = content.document.querySelector("button");
|
||||
}
|
||||
|
||||
function pauseDebuggee() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.type, "paused",
|
||||
"We should now be paused.");
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"The debugger statement was hit.");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(triggerButtonClick);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test pause on all events.
|
||||
function testBreakOnAll() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a paused state.
|
||||
gThreadClient.pauseOnDOMEvents("*", (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-any-event request completed successfully.");
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "keyupHandler",
|
||||
"The keyupHandler is entered.");
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "clickHandler",
|
||||
"The clickHandler is entered.");
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "onchange",
|
||||
"The onchange handler is entered.");
|
||||
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
gThreadClient.resume(triggerInputChange);
|
||||
});
|
||||
|
||||
gThreadClient.resume(triggerButtonClick);
|
||||
});
|
||||
|
||||
gThreadClient.resume(triggerInputKeyup);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test that removing events from the array disables them.
|
||||
function testBreakOnDisabled() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents(["click"], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-click-only request completed successfully.");
|
||||
|
||||
gClient.addListener("paused", unexpectedListener);
|
||||
|
||||
// This non-capturing event listener is guaranteed to run after the page's
|
||||
// capturing one had a chance to execute and modify window.foobar.
|
||||
once(gInput, "keyup").then(() => {
|
||||
is(content.wrappedJSObject.foobar, "keyupHandler",
|
||||
"No hidden breakpoint was hit.");
|
||||
|
||||
gClient.removeListener("paused", unexpectedListener);
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
triggerInputKeyup();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test that specifying an empty event array clears all hidden breakpoints.
|
||||
function testBreakOnNone() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents([], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-none request completed successfully.");
|
||||
|
||||
gClient.addListener("paused", unexpectedListener);
|
||||
|
||||
// This non-capturing event listener is guaranteed to run after the page's
|
||||
// capturing one had a chance to execute and modify window.foobar.
|
||||
once(gInput, "keyup").then(() => {
|
||||
is(content.wrappedJSObject.foobar, "keyupHandler",
|
||||
"No hidden breakpoint was hit.");
|
||||
|
||||
gClient.removeListener("paused", unexpectedListener);
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
triggerInputKeyup();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test pause on a single event.
|
||||
function testBreakOnClick() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents(["click"], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-click request completed successfully.");
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
is(aPacket.frame.callee.name, "clickHandler",
|
||||
"The clickHandler is entered.");
|
||||
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
triggerButtonClick();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function unexpectedListener() {
|
||||
gClient.removeListener("paused", unexpectedListener);
|
||||
ok(false, "An unexpected hidden breakpoint was hit.");
|
||||
gThreadClient.resume(testBreakOnClick);
|
||||
}
|
||||
|
||||
function triggerInputKeyup() {
|
||||
// Make sure that the focus is not on the input box so that a focus event
|
||||
// will be triggered.
|
||||
window.focus();
|
||||
gBrowser.selectedBrowser.focus();
|
||||
gButton.focus();
|
||||
|
||||
// Focus the element and wait for focus event.
|
||||
once(gInput, "focus").then(() => {
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey("e", { shiftKey: 1 }, content);
|
||||
});
|
||||
});
|
||||
|
||||
gInput.focus();
|
||||
}
|
||||
|
||||
function triggerButtonClick() {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, gButton);
|
||||
}
|
||||
|
||||
function triggerInputChange() {
|
||||
gInput.focus();
|
||||
gInput.value = "foo";
|
||||
gInput.blur();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
gInput = null;
|
||||
gButton = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,105 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the break-on-dom-events request works even for bound event
|
||||
* listeners and handler objects with 'handleEvent' methods.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-03.html";
|
||||
|
||||
var gClient, gThreadClient;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect().then(([aType, aTraits]) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
addTab(TAB_URL)
|
||||
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
|
||||
.then(aThreadClient => gThreadClient = aThreadClient)
|
||||
.then(pauseDebuggee)
|
||||
.then(testBreakOnClick)
|
||||
.then(() => gClient.close())
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pauseDebuggee() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.type, "paused",
|
||||
"We should now be paused.");
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"The debugger statement was hit.");
|
||||
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => triggerButtonClick("initialSetup"));
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test pause on a single event.
|
||||
function testBreakOnClick() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents(["click"], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-click request completed successfully.");
|
||||
let handlers = ["clicker"];
|
||||
|
||||
gClient.addListener("paused", function tester(aEvent, aPacket) {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
|
||||
switch (handlers.length) {
|
||||
case 1:
|
||||
is(aPacket.frame.where.line, 26, "Found the clicker handler.");
|
||||
handlers.push("handleEventClick");
|
||||
break;
|
||||
case 2:
|
||||
is(aPacket.frame.where.line, 36, "Found the handleEventClick handler.");
|
||||
handlers.push("boundHandleEventClick");
|
||||
break;
|
||||
case 3:
|
||||
is(aPacket.frame.where.line, 46, "Found the boundHandleEventClick handler.");
|
||||
gClient.removeListener("paused", tester);
|
||||
deferred.resolve();
|
||||
}
|
||||
|
||||
gThreadClient.resume(() => triggerButtonClick(handlers.slice(-1)));
|
||||
});
|
||||
|
||||
triggerButtonClick(handlers.slice(-1));
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function triggerButtonClick(aNodeId) {
|
||||
let button = content.document.getElementById(aNodeId);
|
||||
EventUtils.sendMouseEvent({ type: "click" }, button);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the break-on-dom-events request works for load event listeners.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_event-listeners-04.html";
|
||||
|
||||
var gClient, gThreadClient;
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect().then(([aType, aTraits]) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
addTab(TAB_URL)
|
||||
.then(() => attachThreadActorForUrl(gClient, TAB_URL))
|
||||
.then(aThreadClient => gThreadClient = aThreadClient)
|
||||
.then(pauseDebuggee)
|
||||
.then(testBreakOnLoad)
|
||||
.then(() => gClient.close())
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function pauseDebuggee() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
gClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
is(aPacket.type, "paused",
|
||||
"We should now be paused.");
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"The debugger statement was hit.");
|
||||
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
});
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow
|
||||
// this function to return first.
|
||||
executeSoon(() => triggerButtonClick());
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test pause on a load event.
|
||||
function testBreakOnLoad() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Test calling pauseOnDOMEvents from a running state.
|
||||
gThreadClient.pauseOnDOMEvents(["load"], (aPacket) => {
|
||||
is(aPacket.error, undefined,
|
||||
"The pause-on-load request completed successfully.");
|
||||
let handlers = ["loadHandler"];
|
||||
|
||||
gClient.addListener("paused", function tester(aEvent, aPacket) {
|
||||
is(aPacket.why.type, "pauseOnDOMEvents",
|
||||
"A hidden breakpoint was hit.");
|
||||
|
||||
is(aPacket.frame.where.line, 15, "Found the load event listener.");
|
||||
gClient.removeListener("paused", tester);
|
||||
deferred.resolve();
|
||||
|
||||
gThreadClient.resume(() => triggerButtonClick(handlers.slice(-1)));
|
||||
});
|
||||
|
||||
getTabActorForUrl(gClient, TAB_URL).then(aGrip => {
|
||||
gClient.attachTab(aGrip.actor, (aResponse, aTabClient) => {
|
||||
aTabClient.reload();
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function triggerButtonClick() {
|
||||
let button = content.document.querySelector("button");
|
||||
EventUtils.sendMouseEvent({ type: "click" }, button);
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,61 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if 'break on next' functionality works from executions
|
||||
* in content triggered by the console in the toolbox.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-eval.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gSources, gBreakpoints, gTarget, gResumeButton, gResumeKey, gThreadClient;
|
||||
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-eval.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gTarget = gDebugger.gTarget;
|
||||
gThreadClient = gDebugger.gThreadClient;
|
||||
gResumeButton = gDebugger.document.getElementById("resume");
|
||||
gResumeKey = gDebugger.document.getElementById("resumeKey");
|
||||
|
||||
testConsole()
|
||||
.then(() => closeDebuggerAndFinish(gPanel));
|
||||
});
|
||||
|
||||
let testConsole = Task.async(function* () {
|
||||
info("Starting testConsole");
|
||||
|
||||
let oncePaused = gTarget.once("thread-paused");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
|
||||
let jsterm = yield getSplitConsole(gDevTools.getToolbox(gPanel.target));
|
||||
let executed = jsterm.execute("1+1");
|
||||
yield oncePaused;
|
||||
|
||||
let updatedFrame = yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
|
||||
let variables = gDebugger.DebuggerView.Variables;
|
||||
|
||||
is(variables._store.length, 3, "Correct number of scopes available");
|
||||
is(variables.getScopeAtIndex(0).name, "With scope [Object]",
|
||||
"Paused with correct scope (0)");
|
||||
is(variables.getScopeAtIndex(1).name, "Block scope",
|
||||
"Paused with correct scope (1)");
|
||||
is(variables.getScopeAtIndex(2).name, "Global scope [Window]",
|
||||
"Paused with correct scope (2)");
|
||||
|
||||
let onceResumed = gTarget.once("thread-resumed");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
|
||||
yield onceResumed;
|
||||
|
||||
yield executed;
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,103 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if 'break on next' functionality works from executions
|
||||
* in content that are triggered by the page.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-eval.html";
|
||||
|
||||
function test() {
|
||||
let gTab, gPanel, gDebugger;
|
||||
let gSources, gBreakpoints, gTarget, gResumeButton, gResumeKey, gThreadClient;
|
||||
|
||||
const options = {
|
||||
source: EXAMPLE_URL + "code_script-eval.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
gTarget = gDebugger.gTarget;
|
||||
gThreadClient = gDebugger.gThreadClient;
|
||||
gResumeButton = gDebugger.document.getElementById("resume");
|
||||
gResumeKey = gDebugger.document.getElementById("resumeKey");
|
||||
|
||||
testInterval()
|
||||
.then(testEvent)
|
||||
.then(() => closeDebuggerAndFinish(gPanel));
|
||||
});
|
||||
|
||||
// Testing an interval instead of a timeout / rAF because
|
||||
// it's less likely to fail due to timing issues. If the
|
||||
// first callback happens to fire before the break request
|
||||
// happens then we'll just get it next time.
|
||||
let testInterval = Task.async(function* () {
|
||||
info("Starting testInterval");
|
||||
|
||||
yield evalInTab(gTab, `
|
||||
var interval = setInterval(function() {
|
||||
return 1+1;
|
||||
}, 100);
|
||||
`);
|
||||
|
||||
let oncePaused = gTarget.once("thread-paused");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
|
||||
yield oncePaused;
|
||||
|
||||
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
let variables = gDebugger.DebuggerView.Variables;
|
||||
|
||||
is(variables._store.length, 3, "Correct number of scopes available");
|
||||
is(variables.getScopeAtIndex(0).name, "Function scope [interval<]",
|
||||
"Paused with correct scope (0)");
|
||||
is(variables.getScopeAtIndex(1).name, "Block scope",
|
||||
"Paused with correct scope (1)");
|
||||
is(variables.getScopeAtIndex(2).name, "Global scope [Window]",
|
||||
"Paused with correct scope (2)");
|
||||
|
||||
yield evalInTab(gTab, "clearInterval(interval)");
|
||||
let onceResumed = gTarget.once("thread-resumed");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
|
||||
yield onceResumed;
|
||||
});
|
||||
|
||||
let testEvent = Task.async(function* () {
|
||||
info("Starting testEvent");
|
||||
|
||||
let oncePaused = gTarget.once("thread-paused");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
|
||||
once(gDebugger.gClient, "willInterrupt").then(() => {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
});
|
||||
yield oncePaused;
|
||||
|
||||
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
let variables = gDebugger.DebuggerView.Variables;
|
||||
|
||||
is(variables._store.length, 6, "Correct number of scopes available");
|
||||
is(variables.getScopeAtIndex(0).name, "Function scope [onclick]",
|
||||
"Paused with correct scope (0)");
|
||||
// Non-syntactic lexical scope introduced by non-syntactic scope chain.
|
||||
is(variables.getScopeAtIndex(1).name, "Block scope",
|
||||
"Paused with correct scope (1)");
|
||||
is(variables.getScopeAtIndex(2).name, "With scope [HTMLButtonElement]",
|
||||
"Paused with correct scope (2)");
|
||||
is(variables.getScopeAtIndex(3).name, "With scope [HTMLDocument]",
|
||||
"Paused with correct scope (3)");
|
||||
// Global lexical scope.
|
||||
is(variables.getScopeAtIndex(4).name, "Block scope",
|
||||
"Paused with correct scope (4)");
|
||||
is(variables.getScopeAtIndex(5).name, "Global scope [Window]",
|
||||
"Paused with correct scope (5)");
|
||||
|
||||
let onceResumed = gTarget.once("thread-resumed");
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" }, gResumeButton, gDebugger);
|
||||
yield onceResumed;
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test breaking in code and jumping to the debugger before
|
||||
* the debugger UI has been initialized.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
const tab = yield getTab(TAB_URL);
|
||||
const target = TargetFactory.forTab(tab);
|
||||
const toolbox = yield gDevTools.showToolbox(target, "webconsole");
|
||||
|
||||
is(toolbox.currentToolId, "webconsole", "Console is the current panel");
|
||||
|
||||
toolbox.target.on("thread-paused", Task.async(function* () {
|
||||
// Wait for the toolbox to handle the event and switch tools
|
||||
yield waitForTick();
|
||||
|
||||
is(toolbox.currentToolId, "jsdebugger", "Debugger is the current panel");
|
||||
|
||||
// Wait until it's actually fully loaded
|
||||
yield toolbox.loadTool("jsdebugger");
|
||||
|
||||
const panel = toolbox.getCurrentPanel();
|
||||
const queries = panel.panelWin.require("./content/queries");
|
||||
const getState = panel.panelWin.DebuggerController.getState;
|
||||
|
||||
is(panel.panelWin.gThreadClient.state, "paused",
|
||||
"Thread is still paused");
|
||||
|
||||
yield waitForSourceAndCaret(panel, "debugger-statement.html", 16);
|
||||
is(queries.getSelectedSource(getState()).url, TAB_URL,
|
||||
"Selected source is the current tab url");
|
||||
is(queries.getSelectedSourceOpts(getState()).line, 16,
|
||||
"Line 16 is highlighted in the editor");
|
||||
|
||||
resumeDebuggerThenCloseAndFinish(panel);
|
||||
}));
|
||||
|
||||
callInTab(tab, "runDebuggerStatement");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 737803: Setting a breakpoint in a line without code should move
|
||||
* the icon to the actual location.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const gController = gDebugger.DebuggerController;
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
|
||||
|
||||
is(queries.getBreakpoints(gController.getState()).length, 0,
|
||||
"There are no breakpoints in the editor");
|
||||
|
||||
const response = yield actions.addBreakpoint({
|
||||
actor: gSources.selectedValue, line: 4
|
||||
});
|
||||
|
||||
ok(response.actualLocation, "has an actualLocation");
|
||||
is(response.actualLocation.line, 6, "moved to line 6");
|
||||
|
||||
is(queries.getBreakpoints(gController.getState()).length, 1,
|
||||
"There is only one breakpoint in the editor");
|
||||
|
||||
ok(!queries.getBreakpoint(gController.getState(), { actor: gSources.selectedValue, line: 4 }),
|
||||
"There isn't any breakpoint added on an invalid line.");
|
||||
ok(queries.getBreakpoint(gController.getState(), { actor: gSources.selectedValue, line: 6 }),
|
||||
"There isn't any breakpoint added on an invalid line.");
|
||||
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 1008372: Setting a breakpoint in a line without code should move
|
||||
* the icon to the actual location, and if a breakpoint already exists
|
||||
* on the new location don't duplicate
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_breakpoint-move.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const gController = gDebugger.DebuggerController;
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
|
||||
function resumeAndTestBreakpoint(line) {
|
||||
return Task.spawn(function* () {
|
||||
let event = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
|
||||
doResume(gPanel);
|
||||
yield event;
|
||||
testBreakpoint(line);
|
||||
});
|
||||
}
|
||||
|
||||
function testBreakpoint(line) {
|
||||
let bp = gSources._selectedBreakpoint;
|
||||
ok(bp, "There should be a selected breakpoint on line " + line);
|
||||
is(bp.location.line, line,
|
||||
"The breakpoint on line " + line + " was not hit");
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
let onCaretUpdated = waitForCaretAndScopes(gPanel, 16);
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield onCaretUpdated;
|
||||
|
||||
is(queries.getBreakpoints(gController.getState()).length, 0,
|
||||
"There are no breakpoints in the editor");
|
||||
|
||||
yield actions.addBreakpoint({
|
||||
actor: gSources.selectedValue,
|
||||
line: 19
|
||||
});
|
||||
yield actions.addBreakpoint({
|
||||
actor: gSources.selectedValue,
|
||||
line: 20
|
||||
});
|
||||
|
||||
const response = yield actions.addBreakpoint({
|
||||
actor: gSources.selectedValue,
|
||||
line: 17
|
||||
});
|
||||
|
||||
is(response.actualLocation.line, 19,
|
||||
"Breakpoint client line is new.");
|
||||
|
||||
yield resumeAndTestBreakpoint(19);
|
||||
|
||||
yield actions.removeBreakpoint({
|
||||
actor: gSources.selectedValue,
|
||||
line: 19
|
||||
});
|
||||
|
||||
yield resumeAndTestBreakpoint(20);
|
||||
yield doResume(gPanel);
|
||||
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES);
|
||||
|
||||
yield resumeAndTestBreakpoint(20);
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,116 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 978019: Setting a breakpoint on the last line of a Debugger.Script and
|
||||
* reloading should still hit the breakpoint.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_breakpoints-break-on-last-line-of-script-on-reload.html";
|
||||
const CODE_URL = EXAMPLE_URL + "code_breakpoints-break-on-last-line-of-script-on-reload.js";
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let gPanel, gDebugger, gThreadClient, gEvents, gSources;
|
||||
|
||||
const options = {
|
||||
source: CODE_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gThreadClient = gDebugger.gThreadClient;
|
||||
gEvents = gDebugger.EVENTS;
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
const actions = bindActionCreators(gPanel);
|
||||
|
||||
Task.spawn(function* () {
|
||||
try {
|
||||
|
||||
// Refresh and hit the debugger statement before the location we want to
|
||||
// set our breakpoints. We have to pause before the breakpoint locations
|
||||
// so that GC doesn't get a chance to kick in and collect the IIFE's
|
||||
// script, which would causes us to receive a 'noScript' error from the
|
||||
// server when we try to set the breakpoints.
|
||||
const [paused, ] = yield promise.all([
|
||||
waitForThreadEvents(gPanel, "paused"),
|
||||
reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN),
|
||||
]);
|
||||
|
||||
is(paused.why.type, "debuggerStatement");
|
||||
|
||||
// Set our breakpoints.
|
||||
const sourceActor = getSourceActor(gSources, CODE_URL);
|
||||
yield promise.all([
|
||||
actions.addBreakpoint({
|
||||
actor: sourceActor,
|
||||
line: 3
|
||||
}),
|
||||
actions.addBreakpoint({
|
||||
actor: sourceActor,
|
||||
line: 4
|
||||
}),
|
||||
actions.addBreakpoint({
|
||||
actor: sourceActor,
|
||||
line: 5
|
||||
})
|
||||
]);
|
||||
|
||||
// Refresh and hit the debugger statement again.
|
||||
yield promise.all([
|
||||
reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN),
|
||||
waitForCaretAndScopes(gPanel, 1)
|
||||
]);
|
||||
|
||||
// And we should hit the breakpoints as we resume.
|
||||
yield promise.all([
|
||||
doResume(gPanel),
|
||||
waitForCaretAndScopes(gPanel, 3)
|
||||
]);
|
||||
yield promise.all([
|
||||
doResume(gPanel),
|
||||
waitForCaretAndScopes(gPanel, 4)
|
||||
]);
|
||||
yield promise.all([
|
||||
doResume(gPanel),
|
||||
waitForCaretAndScopes(gPanel, 5)
|
||||
]);
|
||||
|
||||
// Clean up the breakpoints.
|
||||
yield promise.all([
|
||||
actions.removeBreakpoint({ actor: sourceActor, line: 3 }),
|
||||
actions.removeBreakpoint({ actor: sourceActor, line: 4 }),
|
||||
actions.removeBreakpoint({ actor: sourceActor, line: 5 })
|
||||
]);
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
|
||||
} catch (e) {
|
||||
DevToolsUtils.reportException(
|
||||
"browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js",
|
||||
e
|
||||
);
|
||||
ok(false);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
function setBreakpoint(location) {
|
||||
let item = gSources.getItemByValue(getSourceActor(gSources, location.url));
|
||||
let source = gThreadClient.source(item.attachment.source);
|
||||
|
||||
let deferred = promise.defer();
|
||||
source.setBreakpoint(location, ({ error, message }, bpClient) => {
|
||||
if (error) {
|
||||
deferred.reject(error + ": " + message);
|
||||
}
|
||||
deferred.resolve(bpClient);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if the breakpoints toggle button works as advertised.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
function checkBreakpointsDisabled(isDisabled, total = 3) {
|
||||
let breakpoints = gDebugger.queries.getBreakpoints(getState());
|
||||
|
||||
is(breakpoints.length, total,
|
||||
"Breakpoints should still be set.");
|
||||
is(breakpoints.filter(bp => bp.disabled === isDisabled).length, total,
|
||||
"Breakpoints should be " + (isDisabled ? "disabled" : "enabled") + ".");
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield actions.addBreakpoint({ actor: gSources.values[0], line: 5 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 6 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 7 });
|
||||
yield ensureThreadClientState(gPanel, "resumed");
|
||||
|
||||
gSources.toggleBreakpoints();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 3);
|
||||
checkBreakpointsDisabled(true);
|
||||
|
||||
const finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.BREAKPOINT_ADDED, 3);
|
||||
gSources.toggleBreakpoints();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 3);
|
||||
checkBreakpointsDisabled(false);
|
||||
|
||||
if (gDebugger.gThreadClient.state !== "attached") {
|
||||
yield waitForThreadEvents(gPanel, "resumed");
|
||||
}
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if the breakpoints toggle button works as advertised when there are
|
||||
* some breakpoints already disabled.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
function checkBreakpointsDisabled(isDisabled, total = 3) {
|
||||
let breakpoints = gDebugger.queries.getBreakpoints(getState());
|
||||
|
||||
is(breakpoints.length, total,
|
||||
"Breakpoints should still be set.");
|
||||
is(breakpoints.filter(bp => bp.disabled === isDisabled).length, total,
|
||||
"Breakpoints should be " + (isDisabled ? "disabled" : "enabled") + ".");
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield promise.all([
|
||||
actions.addBreakpoint({ actor: gSources.values[0], line: 5 }),
|
||||
actions.addBreakpoint({ actor: gSources.values[1], line: 6 }),
|
||||
actions.addBreakpoint({ actor: gSources.values[1], line: 7 })
|
||||
]);
|
||||
if (gDebugger.gThreadClient.state !== "attached") {
|
||||
yield waitForThreadEvents(gPanel, "resumed");
|
||||
}
|
||||
|
||||
yield promise.all([
|
||||
actions.disableBreakpoint({ actor: gSources.values[0], line: 5 }),
|
||||
actions.disableBreakpoint({ actor: gSources.values[1], line: 6 })
|
||||
]);
|
||||
|
||||
gSources.toggleBreakpoints();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 1);
|
||||
checkBreakpointsDisabled(true);
|
||||
|
||||
gSources.toggleBreakpoints();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 3);
|
||||
checkBreakpointsDisabled(false);
|
||||
|
||||
if (gDebugger.gThreadClient.state !== "attached") {
|
||||
yield waitForThreadEvents(gPanel, "resumed");
|
||||
}
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that the message which breakpoint condition throws
|
||||
* could be displayed on UI correctly
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
function initialCheck(aCaretLine) {
|
||||
let bp = gDebugger.queries.getBreakpoint(getState(),
|
||||
{ actor: gSources.values[0], line: aCaretLine });
|
||||
ok(bp, "There should be a breakpoint on line " + aCaretLine);
|
||||
|
||||
let attachment = gSources._getBreakpoint(bp).attachment;
|
||||
ok(attachment,
|
||||
"There should be a breakpoint on line " + aCaretLine + " in the sources pane.");
|
||||
|
||||
let thrownNode = attachment.view.container.querySelector(".dbg-breakpoint-condition-thrown-message");
|
||||
ok(thrownNode,
|
||||
"The breakpoint item should contain a thrown message node.");
|
||||
|
||||
ok(!attachment.view.container.classList.contains("dbg-breakpoint-condition-thrown"),
|
||||
"The thrown message on line " + aCaretLine + " should be hidden when condition has not been evaluated.");
|
||||
}
|
||||
|
||||
function resumeAndTestThrownMessage(line) {
|
||||
doResume(gPanel);
|
||||
|
||||
return waitForCaretUpdated(gPanel, line).then(() => {
|
||||
// Test that the thrown message is correctly shown.
|
||||
let bp = gDebugger.queries.getBreakpoint(
|
||||
getState(),
|
||||
{ actor: gSources.values[0], line: line }
|
||||
);
|
||||
let attachment = gSources._getBreakpoint(bp).attachment;
|
||||
ok(attachment.view.container.classList.contains("dbg-breakpoint-condition-thrown"),
|
||||
"Message on line " + line + " should be shown when condition throws.");
|
||||
});
|
||||
}
|
||||
|
||||
function resumeAndTestNoThrownMessage(line) {
|
||||
doResume(gPanel);
|
||||
|
||||
return waitForCaretUpdated(gPanel, line).then(() => {
|
||||
// test that the thrown message is correctly shown
|
||||
let bp = gDebugger.queries.getBreakpoint(
|
||||
getState(),
|
||||
{ actor: gSources.values[0], line: line }
|
||||
);
|
||||
let attachment = gSources._getBreakpoint(bp).attachment;
|
||||
ok(!attachment.view.container.classList.contains("dbg-breakpoint-condition-thrown"),
|
||||
"Message on line " + line + " should be hidden if condition doesn't throw.");
|
||||
});
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
let onCaretUpdated = waitForCaretAndScopes(gPanel, 17);
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield onCaretUpdated;
|
||||
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 }, " 1afff");
|
||||
// Close the popup because a SET_BREAKPOINT_CONDITION action is
|
||||
// fired when it's closed, and it sets it on the currently
|
||||
// selected breakpoint and we want to make sure it uses the
|
||||
// current breakpoint. This isn't a problem outside of tests
|
||||
// because any UI interaction will close the popup before the
|
||||
// new breakpoint is added.
|
||||
gSources._hideConditionalPopup();
|
||||
initialCheck(18);
|
||||
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 19 }, "true");
|
||||
gSources._hideConditionalPopup();
|
||||
initialCheck(19);
|
||||
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 20 }, "false");
|
||||
gSources._hideConditionalPopup();
|
||||
initialCheck(20);
|
||||
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 22 }, "randomVar");
|
||||
gSources._hideConditionalPopup();
|
||||
initialCheck(22);
|
||||
|
||||
yield resumeAndTestThrownMessage(18);
|
||||
yield resumeAndTestNoThrownMessage(19);
|
||||
yield resumeAndTestThrownMessage(22);
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test adding breakpoints from the source editor context menu
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const gContextMenu = gDebugger.document.getElementById("sourceEditorContextMenu");
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(queries.getSourceCount(getState()), 2,
|
||||
"Found the expected number of sources.");
|
||||
isnot(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gContextMenu,
|
||||
"The source editor's context menupopup is available.");
|
||||
|
||||
gEditor.focus();
|
||||
gEditor.setSelection({ line: 1, ch: 0 }, { line: 1, ch: 10 });
|
||||
|
||||
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
|
||||
gEditor.emit("gutterClick", 6, 2);
|
||||
|
||||
yield once(gContextMenu, "popupshown");
|
||||
is(queries.getBreakpoints(getState()).length, 0, "no breakpoints added");
|
||||
|
||||
let cmd = gContextMenu.querySelector("menuitem[command=addBreakpointCommand]");
|
||||
EventUtils.synthesizeMouseAtCenter(cmd, {}, gDebugger);
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT);
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 1,
|
||||
"1 breakpoint correctly added");
|
||||
ok(queries.getBreakpoint(getState(),
|
||||
{ actor: gSources.values[1], line: 7 }),
|
||||
"Breakpoint on line 7 exists");
|
||||
|
||||
gContextMenu.openPopup(gEditor.container, "overlap", 0, 0, true, false);
|
||||
gEditor.emit("gutterClick", 7, 2);
|
||||
|
||||
yield once(gContextMenu, "popupshown");
|
||||
is(queries.getBreakpoints(getState()).length, 1,
|
||||
"1 breakpoint correctly added");
|
||||
|
||||
cmd = gContextMenu.querySelector("menuitem[command=addConditionalBreakpointCommand]");
|
||||
EventUtils.synthesizeMouseAtCenter(cmd, {}, gDebugger);
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT);
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 2,
|
||||
"2 breakpoints correctly added");
|
||||
ok(queries.getBreakpoint(getState(),
|
||||
{ actor: gSources.values[1], line: 8 }),
|
||||
"Breakpoint on line 8 exists");
|
||||
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,252 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if the context menu associated with each breakpoint does what it should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
// Debug test slaves are a bit slow at this test.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
Task.spawn(function* () {
|
||||
const options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
const [gTab,, gPanel ] = yield initDebugger(TAB_URL, options);
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
const addBreakpoints = Task.async(function* () {
|
||||
yield actions.addBreakpoint({ actor: gSources.values[0], line: 5 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 6 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 7 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 8 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 9 });
|
||||
yield ensureThreadClientState(gPanel, "resumed");
|
||||
gSources.highlightBreakpoint({ actor: gSources.values[1], line: 9 });
|
||||
});
|
||||
|
||||
const pauseAndCheck = Task.async(function* () {
|
||||
let source = queries.getSelectedSource(getState());
|
||||
is(source.url, EXAMPLE_URL + "code_script-switching-02.js",
|
||||
"The currently selected source is incorrect (1).");
|
||||
is(gSources.selectedIndex, 1,
|
||||
"The currently selected source is incorrect (2).");
|
||||
ok(isCaretPos(gPanel, 9),
|
||||
"The editor location is correct before pausing.");
|
||||
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
|
||||
return waitForSourceAndCaretAndScopes(gPanel, "-01.js", 5).then(() => {
|
||||
let source = queries.getSelectedSource(getState());
|
||||
is(source.url, EXAMPLE_URL + "code_script-switching-01.js",
|
||||
"The currently selected source is incorrect (3).");
|
||||
is(gSources.selectedIndex, 0,
|
||||
"The currently selected source is incorrect (4).");
|
||||
ok(isCaretPos(gPanel, 5),
|
||||
"The editor location is correct after pausing.");
|
||||
});
|
||||
});
|
||||
|
||||
let initialChecks = Task.async(function* () {
|
||||
for (let bp of queries.getBreakpoints(getState())) {
|
||||
ok(bp.actor, "All breakpoint items should have an actor");
|
||||
ok(!bp.disabled, "All breakpoints should initially be enabled.");
|
||||
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let identifier = queries.makeLocationId(bp.location);
|
||||
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
|
||||
|
||||
// Check to make sure that only the bp context menu is shown when right clicking
|
||||
// this node (Bug 1159276).
|
||||
let breakpointItem = gSources._getBreakpoint(bp);
|
||||
let menu = gDebugger.document.getElementById("bp-mPop-" + identifier);
|
||||
let contextMenuShown = once(gDebugger.document, "popupshown");
|
||||
EventUtils.synthesizeMouseAtCenter(breakpointItem.prebuiltNode, {type: "contextmenu", button: 2}, gDebugger);
|
||||
let event = yield contextMenuShown;
|
||||
is(event.originalTarget.id, menu.id, "The correct context menu was shown");
|
||||
let contextMenuHidden = once(gDebugger.document, "popuphidden");
|
||||
menu.hidePopup();
|
||||
yield contextMenuHidden;
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should initially be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should initially not be hidden'.");
|
||||
|
||||
is(breakpointItem.attachment.view.checkbox.getAttribute("checked"), "true",
|
||||
"All breakpoints should initially have a checked checkbox.");
|
||||
}
|
||||
});
|
||||
|
||||
const checkBreakpointToggleSelf = Task.async(function* (index) {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[index],
|
||||
gDebugger);
|
||||
|
||||
let selectedBreakpoint = gSources._selectedBreakpoint;
|
||||
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
|
||||
|
||||
ok(selectedBreakpoint.actor,
|
||||
"Selected breakpoint should have an actor.");
|
||||
ok(!selectedBreakpoint.disabled,
|
||||
"The breakpoint should not be disabled yet (" + index + ").");
|
||||
|
||||
let prefix = "bp-cMenu-"; // "breakpoints context menu"
|
||||
let identifier = queries.makeLocationId(selectedBreakpoint.location);
|
||||
let enableSelfId = prefix + "enableSelf-" + identifier + "-menuitem";
|
||||
let disableSelfId = prefix + "disableSelf-" + identifier + "-menuitem";
|
||||
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should not be hidden'.");
|
||||
|
||||
ok(isCaretPos(gPanel, selectedBreakpoint.location.line),
|
||||
"The source editor caret position was incorrect (" + index + ").");
|
||||
|
||||
// Test disabling this breakpoint.
|
||||
gSources._onDisableSelf(selectedBreakpoint.location);
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT);
|
||||
|
||||
ok(!!queries.getBreakpoint(getState(), selectedBreakpoint.location).disabled,
|
||||
"The breakpoint should be disabled.");
|
||||
|
||||
ok(!gDebugger.document.getElementById(enableSelfId).hasAttribute("hidden"),
|
||||
"The 'Enable breakpoint' context menu item should not be hidden'.");
|
||||
is(gDebugger.document.getElementById(disableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Disable breakpoint' context menu item should be hidden'.");
|
||||
ok(!selectedBreakpointItem.attachment.view.checkbox.hasAttribute("checked"),
|
||||
"The breakpoint should now be unchecked.");
|
||||
|
||||
gSources._onEnableSelf(selectedBreakpoint.location);
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT);
|
||||
|
||||
ok(!queries.getBreakpoint(getState(), selectedBreakpoint.location).disabled,
|
||||
"The breakpoint should be enabled.");
|
||||
is(gDebugger.document.getElementById(enableSelfId).getAttribute("hidden"), "true",
|
||||
"The 'Enable breakpoint' context menu item should be hidden'.");
|
||||
ok(!gDebugger.document.getElementById(disableSelfId).hasAttribute("hidden"),
|
||||
"The 'Disable breakpoint' context menu item should not be hidden'.");
|
||||
ok(selectedBreakpointItem.attachment.view.checkbox.hasAttribute("checked"),
|
||||
"The breakpoint should now be checked.");
|
||||
});
|
||||
|
||||
const checkBreakpointToggleOthers = Task.async(function* (index) {
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[index],
|
||||
gDebugger
|
||||
);
|
||||
|
||||
// Test disabling other breakpoints.
|
||||
disableOthers();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 4);
|
||||
|
||||
let selectedBreakpoint = queries.getBreakpoint(getState(), gSources._selectedBreakpoint.location);
|
||||
|
||||
ok(selectedBreakpoint.actor,
|
||||
"There should be a breakpoint actor.");
|
||||
ok(!selectedBreakpoint.disabled,
|
||||
"The targetted breakpoint should not have been disabled (" + index + ").");
|
||||
|
||||
for (let bp of queries.getBreakpoints(getState())) {
|
||||
if (bp !== selectedBreakpoint) {
|
||||
ok(bp.disabled,
|
||||
"Non-targetted breakpoints should have been disabled.");
|
||||
}
|
||||
}
|
||||
|
||||
// Test re-enabling other breakpoints.
|
||||
enableOthers();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 4);
|
||||
for (let bp of queries.getBreakpoints(getState())) {
|
||||
ok(!bp.disabled, "All breakpoints should be enabled.");
|
||||
}
|
||||
|
||||
// Test disabling all breakpoints.
|
||||
disableAll();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 5);
|
||||
for (let bp of queries.getBreakpoints(getState())) {
|
||||
ok(!!bp.disabled, "All breakpoints should be disabled.");
|
||||
}
|
||||
|
||||
// Test re-enabling all breakpoints.
|
||||
enableAll();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.ADD_BREAKPOINT, 5);
|
||||
for (let bp of queries.getBreakpoints(getState())) {
|
||||
ok(!bp.disabled, "All breakpoints should be enabled.");
|
||||
}
|
||||
});
|
||||
|
||||
const testDeleteAll = Task.async(function* () {
|
||||
// Test deleting all breakpoints.
|
||||
deleteAll();
|
||||
yield waitForDispatch(gPanel, gDebugger.constants.REMOVE_BREAKPOINT, 5);
|
||||
|
||||
ok(!gSources._selectedBreakpoint,
|
||||
"There should be no breakpoint available after removing all breakpoints.");
|
||||
|
||||
for (let bp of queries.getBreakpoints(getState())) {
|
||||
ok(false, "It's a trap!");
|
||||
}
|
||||
});
|
||||
|
||||
function disableOthers() {
|
||||
gSources._onDisableOthers(gSources._selectedBreakpoint.location);
|
||||
}
|
||||
function enableOthers() {
|
||||
gSources._onEnableOthers(gSources._selectedBreakpoint.location);
|
||||
}
|
||||
function disableAll() {
|
||||
gSources._onDisableAll();
|
||||
}
|
||||
function enableAll() {
|
||||
gSources._onEnableAll();
|
||||
}
|
||||
function deleteAll() {
|
||||
gSources._onDeleteAll();
|
||||
}
|
||||
|
||||
yield addBreakpoints();
|
||||
yield initialChecks();
|
||||
yield checkBreakpointToggleSelf(0);
|
||||
yield checkBreakpointToggleOthers(0);
|
||||
yield checkBreakpointToggleSelf(1);
|
||||
yield checkBreakpointToggleOthers(1);
|
||||
yield checkBreakpointToggleSelf(2);
|
||||
yield checkBreakpointToggleOthers(2);
|
||||
yield checkBreakpointToggleSelf(3);
|
||||
yield checkBreakpointToggleOthers(3);
|
||||
yield checkBreakpointToggleSelf(4);
|
||||
yield checkBreakpointToggleOthers(4);
|
||||
yield testDeleteAll();
|
||||
|
||||
yield addBreakpoints();
|
||||
yield initialChecks();
|
||||
yield pauseAndCheck();
|
||||
yield checkBreakpointToggleSelf(0);
|
||||
yield checkBreakpointToggleOthers(0);
|
||||
yield checkBreakpointToggleSelf(1);
|
||||
yield checkBreakpointToggleOthers(1);
|
||||
yield checkBreakpointToggleSelf(2);
|
||||
yield checkBreakpointToggleOthers(2);
|
||||
yield checkBreakpointToggleSelf(3);
|
||||
yield checkBreakpointToggleOthers(3);
|
||||
yield checkBreakpointToggleSelf(4);
|
||||
yield checkBreakpointToggleOthers(4);
|
||||
yield testDeleteAll();
|
||||
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,124 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that disabled breakpoints survive target navigation.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gPanel = aPanel;
|
||||
const gTab = aTab;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEvents = gDebugger.EVENTS;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
let gBreakpointLocation;
|
||||
|
||||
Task.spawn(function* () {
|
||||
gBreakpointLocation = { actor: getSourceActor(gSources, EXAMPLE_URL + "code_script-switching-01.js"),
|
||||
line: 5 };
|
||||
|
||||
yield actions.addBreakpoint(gBreakpointLocation);
|
||||
|
||||
yield ensureThreadClientState(gPanel, "resumed");
|
||||
yield testWhenBreakpointEnabledAndFirstSourceShown();
|
||||
|
||||
gSources._preferredSourceURL = EXAMPLE_URL + "code_script-switching-02.js";
|
||||
yield reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN);
|
||||
yield testWhenBreakpointEnabledAndSecondSourceShown();
|
||||
|
||||
yield actions.disableBreakpoint(gBreakpointLocation);
|
||||
yield reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN);
|
||||
|
||||
yield testWhenBreakpointDisabledAndSecondSourceShown();
|
||||
|
||||
yield actions.enableBreakpoint(gBreakpointLocation);
|
||||
yield reloadActiveTab(gPanel, gEvents.SOURCE_SHOWN);
|
||||
yield testWhenBreakpointEnabledAndSecondSourceShown();
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
|
||||
function verifyView({ disabled }) {
|
||||
return Task.spawn(function* () {
|
||||
// It takes a tick for the checkbox in the SideMenuWidget and the
|
||||
// gutter in the editor to get updated.
|
||||
yield waitForTick();
|
||||
|
||||
let breakpoint = queries.getBreakpoint(getState(), gBreakpointLocation);
|
||||
let breakpointItem = gSources._getBreakpoint(breakpoint);
|
||||
is(!!breakpoint.disabled, disabled,
|
||||
"The selected breakpoint state was correct.");
|
||||
|
||||
is(breakpointItem.attachment.view.checkbox.hasAttribute("checked"), !disabled,
|
||||
"The selected breakpoint's checkbox state was correct.");
|
||||
});
|
||||
}
|
||||
|
||||
// All the following executeSoon()'s are required to spin the event loop
|
||||
// before causing the debuggee to pause, to allow functions to yield first.
|
||||
|
||||
function testWhenBreakpointEnabledAndFirstSourceShown() {
|
||||
return Task.spawn(function* () {
|
||||
yield ensureSourceIs(gPanel, "-01.js");
|
||||
yield verifyView({ disabled: false });
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
yield waitForDebuggerEvents(gPanel, gEvents.FETCHED_SCOPES);
|
||||
yield ensureSourceIs(gPanel, "-01.js");
|
||||
yield ensureCaretAt(gPanel, 5);
|
||||
yield verifyView({ disabled: false });
|
||||
|
||||
executeSoon(() => gDebugger.gThreadClient.resume());
|
||||
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6);
|
||||
yield verifyView({ disabled: false });
|
||||
});
|
||||
}
|
||||
|
||||
function testWhenBreakpointEnabledAndSecondSourceShown() {
|
||||
return Task.spawn(function* () {
|
||||
yield ensureSourceIs(gPanel, "-02.js", true);
|
||||
yield verifyView({ disabled: false });
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
yield waitForSourceAndCaretAndScopes(gPanel, "-01.js", 1);
|
||||
yield verifyView({ disabled: false });
|
||||
|
||||
executeSoon(() => gDebugger.gThreadClient.resume());
|
||||
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 6);
|
||||
yield verifyView({ disabled: false });
|
||||
});
|
||||
}
|
||||
|
||||
function testWhenBreakpointDisabledAndSecondSourceShown() {
|
||||
return Task.spawn(function* () {
|
||||
yield ensureSourceIs(gPanel, "-02.js", true);
|
||||
yield verifyView({ disabled: true });
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
yield waitForDebuggerEvents(gPanel, gEvents.FETCHED_SCOPES);
|
||||
yield ensureSourceIs(gPanel, "-02.js");
|
||||
yield ensureCaretAt(gPanel, 6);
|
||||
yield verifyView({ disabled: true });
|
||||
|
||||
executeSoon(() => gDebugger.gThreadClient.resume());
|
||||
yield waitForDebuggerEvents(gPanel, gEvents.AFTER_FRAMES_CLEARED);
|
||||
yield ensureSourceIs(gPanel, "-02.js");
|
||||
yield ensureCaretAt(gPanel, 6);
|
||||
yield verifyView({ disabled: true });
|
||||
});
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,241 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723069: Test the debugger breakpoint API and connection to the
|
||||
* source editor.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(queries.getSourceCount(getState()), 2,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("debugger"), 166,
|
||||
"The correct source was loaded initially.");
|
||||
is(queries.getSelectedSource(getState()).actor, gSources.values[1],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 0,
|
||||
"No breakpoints currently added.");
|
||||
|
||||
info("Add the first breakpoint.");
|
||||
gEditor.once("breakpointAdded", onEditorBreakpointAddFirst);
|
||||
let location = { actor: gSources.selectedValue, line: 6 };
|
||||
yield actions.addBreakpoint(location);
|
||||
checkFirstBreakpoint(location);
|
||||
|
||||
info("Remove the first breakpoint.");
|
||||
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveFirst);
|
||||
yield actions.removeBreakpoint(location);
|
||||
checkFirstBreakpointRemoved(location);
|
||||
checkBackgroundBreakpoint(yield testBreakpointAddBackground());
|
||||
|
||||
info("Switch to the first source, which is not yet selected");
|
||||
gEditor.once("breakpointAdded", onEditorBreakpointAddSwitch);
|
||||
gEditor.once("change", onEditorTextChanged);
|
||||
actions.selectSource(gSources.items[0].attachment.source);
|
||||
yield waitForDebuggerEvents(gPanel, gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
onReadyForClick();
|
||||
});
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
let editorBreakpointChanges = 0;
|
||||
|
||||
function onEditorBreakpointAddFirst(aEvent, aLine) {
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint1 added to the editor.");
|
||||
is(aLine, 5,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct.");
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveFirst(aEvent, aLine) {
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint1 removed from the editor.");
|
||||
is(aLine, 5,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"editor.getBreakpoints().length is correct.");
|
||||
}
|
||||
|
||||
function checkFirstBreakpoint(location) {
|
||||
breakpointsAdded++;
|
||||
const bp = queries.getBreakpoint(getState(), location);
|
||||
|
||||
ok(bp,
|
||||
"breakpoint1 exists");
|
||||
is(bp.location.actor, queries.getSelectedSource(getState()).actor,
|
||||
"breakpoint1 actor is correct.");
|
||||
is(bp.location.line, 6,
|
||||
"breakpoint1 line is correct.");
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 1,
|
||||
"The list of added breakpoints holds only one breakpoint.");
|
||||
|
||||
is(queries.getSelectedSource(getState()).actor, gSources.values[1],
|
||||
"The second source should be currently selected.");
|
||||
}
|
||||
|
||||
function checkFirstBreakpointRemoved(location) {
|
||||
breakpointsRemoved++;
|
||||
const bp = queries.getBreakpoint(getState(), location);
|
||||
ok(!bp, "breakpoint1 removed");
|
||||
}
|
||||
|
||||
function testBreakpointAddBackground() {
|
||||
is(queries.getBreakpoints(getState()).length, 0,
|
||||
"No breakpoints currently added.");
|
||||
|
||||
is(gSources.values[1], gSources.selectedValue,
|
||||
"The second source should be currently selected.");
|
||||
|
||||
info("Add a breakpoint to the first source, which is not selected.");
|
||||
let location = { actor: gSources.values[0], line: 5 };
|
||||
gEditor.on("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
|
||||
return actions.addBreakpoint(location).then(() => location);
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddBackgroundTrap() {
|
||||
// Trap listener: no breakpoint must be added to the editor when a
|
||||
// breakpoint is added to a source that is not currently selected.
|
||||
editorBreakpointChanges++;
|
||||
ok(false, "breakpoint2 must not be added to the editor.");
|
||||
}
|
||||
|
||||
function checkBackgroundBreakpoint(location) {
|
||||
breakpointsAdded++;
|
||||
const bp = queries.getBreakpoint(getState(), location);
|
||||
|
||||
ok(bp,
|
||||
"breakpoint2 added, client received");
|
||||
is(bp.location.actor, gSources.values[0],
|
||||
"breakpoint2 client url is correct.");
|
||||
is(bp.location.line, 5,
|
||||
"breakpoint2 client line is correct.");
|
||||
|
||||
ok(queries.getBreakpoint(getState(), bp.location),
|
||||
"breakpoint2 found in the list of added breakpoints.");
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 1,
|
||||
"The list of added breakpoints holds only one breakpoint.");
|
||||
|
||||
is(queries.getSelectedSource(getState()).actor, gSources.values[1],
|
||||
"The second source should be currently selected.");
|
||||
|
||||
// Remove the trap listener.
|
||||
gEditor.off("breakpointAdded", onEditorBreakpointAddBackgroundTrap);
|
||||
}
|
||||
|
||||
function onEditorBreakpointAddSwitch(aEvent, aLine) {
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint2 added to the editor.");
|
||||
is(aLine, 4,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 1,
|
||||
"editor.getBreakpoints().length is correct");
|
||||
}
|
||||
|
||||
function onEditorTextChanged() {
|
||||
// Wait for the actual text to be shown.
|
||||
if (gEditor.getText() == gDebugger.L10N.getStr("loadingText"))
|
||||
return void gEditor.once("change", onEditorTextChanged);
|
||||
|
||||
is(gEditor.getText().indexOf("debugger"), -1,
|
||||
"The second source is no longer displayed.");
|
||||
is(gEditor.getText().indexOf("firstCall"), 118,
|
||||
"The first source is displayed.");
|
||||
|
||||
is(gSources.values[0], gSources.selectedValue,
|
||||
"The first source should be currently selected.");
|
||||
}
|
||||
|
||||
function onReadyForClick() {
|
||||
info("Remove the second breakpoint using the mouse.");
|
||||
gEditor.once("breakpointRemoved", onEditorBreakpointRemoveSecond);
|
||||
|
||||
let iframe = gEditor.container;
|
||||
let testWin = iframe.ownerDocument.defaultView;
|
||||
|
||||
// Flush the layout for the iframe.
|
||||
info("rect " + iframe.contentDocument.documentElement.getBoundingClientRect());
|
||||
|
||||
let utils = testWin
|
||||
.QueryInterface(Ci.nsIInterfaceRequestor)
|
||||
.getInterface(Ci.nsIDOMWindowUtils);
|
||||
|
||||
let coords = gEditor.getCoordsFromPosition({ line: 4, ch: 0 });
|
||||
let rect = iframe.getBoundingClientRect();
|
||||
let left = rect.left + 10;
|
||||
let top = rect.top + coords.top + 4;
|
||||
utils.sendMouseEventToWindow("mousedown", left, top, 0, 1, 0, false, 0, 0);
|
||||
utils.sendMouseEventToWindow("mouseup", left, top, 0, 1, 0, false, 0, 0);
|
||||
}
|
||||
|
||||
function onEditorBreakpointRemoveSecond(aEvent, aLine) {
|
||||
editorBreakpointChanges++;
|
||||
|
||||
ok(aEvent,
|
||||
"breakpoint2 removed from the editor.");
|
||||
is(aLine, 4,
|
||||
"Editor breakpoint line is correct.");
|
||||
|
||||
is(gEditor.getBreakpoints().length, 0,
|
||||
"editor.getBreakpoints().length is correct.");
|
||||
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
finalCheck();
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
}
|
||||
|
||||
function finalCheck() {
|
||||
is(queries.getBreakpoints(getState()).length, 0,
|
||||
"No breakpoints currently added.");
|
||||
|
||||
is(breakpointsAdded, 2,
|
||||
"Correct number of breakpoints have been added.");
|
||||
is(breakpointsRemoved, 1,
|
||||
"Correct number of breakpoints have been removed.");
|
||||
is(editorBreakpointChanges, 4,
|
||||
"Correct number of editor breakpoint changes.");
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test setting breakpoints on an eval script
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-eval.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-eval.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const actions = bindActionCreators(gPanel);
|
||||
|
||||
Task.spawn(function* () {
|
||||
let newSource = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.NEW_SOURCE);
|
||||
callInTab(gTab, "evalSourceWithSourceURL");
|
||||
yield newSource;
|
||||
// Wait for it to be added to the UI
|
||||
yield waitForTick();
|
||||
|
||||
const newSourceActor = getSourceActor(gSources, EXAMPLE_URL + "bar.js");
|
||||
yield actions.addBreakpoint({
|
||||
actor: newSourceActor,
|
||||
line: 2
|
||||
});
|
||||
yield ensureThreadClientState(gPanel, "resumed");
|
||||
|
||||
const paused = waitForThreadEvents(gPanel, "paused");
|
||||
callInTab(gTab, "bar");
|
||||
let frame = (yield paused).frame;
|
||||
is(frame.where.source.actor, newSourceActor, "Should have broken on the eval'ed source");
|
||||
is(frame.where.line, 2, "Should break on line 2");
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,90 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test if breakpoints are highlighted when they should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
const addBreakpoints = Task.async(function* () {
|
||||
yield actions.addBreakpoint({ actor: gSources.values[0], line: 5 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 6 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 7 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 8 });
|
||||
yield actions.addBreakpoint({ actor: gSources.values[1], line: 9 });
|
||||
});
|
||||
|
||||
function clickBreakpointAndCheck(aBreakpointIndex, aSourceIndex, aCaretLine) {
|
||||
let finished = waitForCaretUpdated(gPanel, aCaretLine).then(() => {
|
||||
checkHighlight(gSources.values[aSourceIndex], aCaretLine);
|
||||
checkEditorContents(aSourceIndex);
|
||||
|
||||
is(queries.getSelectedSource(getState()).actor,
|
||||
gSources.items[aSourceIndex].value,
|
||||
"The currently selected source value is incorrect (1).");
|
||||
ok(isCaretPos(gPanel, aCaretLine),
|
||||
"The editor caret line and column were incorrect (1).");
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent(
|
||||
{ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aBreakpointIndex],
|
||||
gDebugger
|
||||
);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function checkHighlight(actor, line) {
|
||||
let breakpoint = gSources._selectedBreakpoint;
|
||||
let breakpointItem = gSources._getBreakpoint(breakpoint);
|
||||
|
||||
is(breakpoint.location.actor, actor,
|
||||
"The currently selected breakpoint actor is incorrect.");
|
||||
is(breakpoint.location.line, line,
|
||||
"The currently selected breakpoint line is incorrect.");
|
||||
is(breakpointItem.attachment.actor, actor,
|
||||
"The selected breakpoint item's source location attachment is incorrect.");
|
||||
ok(breakpointItem.target.classList.contains("selected"),
|
||||
"The selected breakpoint item's target should have a selected class.");
|
||||
}
|
||||
|
||||
function checkEditorContents(aSourceIndex) {
|
||||
if (aSourceIndex == 0) {
|
||||
is(gEditor.getText().indexOf("firstCall"), 118,
|
||||
"The first source is correctly displayed.");
|
||||
} else {
|
||||
is(gEditor.getText().indexOf("debugger"), 166,
|
||||
"The second source is correctly displayed.");
|
||||
}
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield addBreakpoints();
|
||||
yield clickBreakpointAndCheck(0, 0, 5);
|
||||
yield clickBreakpointAndCheck(1, 1, 6);
|
||||
yield clickBreakpointAndCheck(2, 1, 7);
|
||||
yield clickBreakpointAndCheck(3, 1, 8);
|
||||
yield clickBreakpointAndCheck(4, 1, 9);
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 771452: Make sure that setting a breakpoint in an inline source doesn't
|
||||
* add it twice.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-script.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require('./content/queries');
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
function testResume() {
|
||||
const deferred = promise.defer();
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint wasn't hit yet.");
|
||||
|
||||
gDebugger.gThreadClient.resume(() => {
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
|
||||
is(aPacket.why.type, "breakpoint",
|
||||
"Execution has advanced to the next breakpoint.");
|
||||
isnot(aPacket.why.type, "debuggerStatement",
|
||||
"The breakpoint was hit before the debugger statement.");
|
||||
ok(isCaretPos(gPanel, 20),
|
||||
"The source editor caret position is incorrect (2).");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testBreakpointHit() {
|
||||
const deferred = promise.defer();
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The breakpoint was hit.");
|
||||
|
||||
gDebugger.gThreadClient.addOneTimeListener("paused", (aEvent, aPacket) => {
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
|
||||
is(aPacket.why.type, "debuggerStatement",
|
||||
"Execution has advanced to the next line.");
|
||||
isnot(aPacket.why.type, "breakpoint",
|
||||
"No ghost breakpoint was hit.");
|
||||
ok(isCaretPos(gPanel, 20),
|
||||
"The source editor caret position is incorrect (3).");
|
||||
|
||||
deferred.resolve();
|
||||
});
|
||||
});
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
Task.spawn(function(){
|
||||
let onCaretUpdated = waitForCaretAndScopes(gPanel, 16);
|
||||
callInTab(gTab, "runDebuggerStatement");
|
||||
yield onCaretUpdated;
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"The debugger statement was reached.");
|
||||
ok(isCaretPos(gPanel, 16),
|
||||
"The source editor caret position is incorrect (1).");
|
||||
|
||||
yield actions.addBreakpoint({ actor: getSourceActor(gSources, TAB_URL), line: 20 });
|
||||
yield testResume();
|
||||
yield testBreakpointHit();
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that setting a breakpoint in one tab, doesn't cause another tab at
|
||||
* the same source to pause at that location.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_breakpoints-other-tabs.html";
|
||||
|
||||
var test = Task.async(function* () {
|
||||
const options = {
|
||||
source: EXAMPLE_URL + "code_breakpoints-other-tabs.js",
|
||||
line: 1
|
||||
};
|
||||
const [tab1,, panel1] = yield initDebugger(TAB_URL, options);
|
||||
const [tab2,, panel2] = yield initDebugger(TAB_URL, options);
|
||||
const queries = panel1.panelWin.require("./content/queries");
|
||||
const actions = bindActionCreators(panel1);
|
||||
const getState = panel1.panelWin.DebuggerController.getState;
|
||||
|
||||
const sources = panel1.panelWin.DebuggerView.Sources;
|
||||
|
||||
yield actions.addBreakpoint({
|
||||
actor: queries.getSelectedSource(getState()).actor,
|
||||
line: 2
|
||||
});
|
||||
|
||||
const paused = waitForThreadEvents(panel2, "paused");
|
||||
callInTab(tab2, "testCase");
|
||||
const packet = yield paused;
|
||||
|
||||
is(packet.why.type, "debuggerStatement",
|
||||
"Should have stopped at the debugger statement, not the other tab's breakpoint");
|
||||
is(packet.frame.where.line, 3,
|
||||
"Should have stopped at line 3 (debugger statement), not line 2 (other tab's breakpoint)");
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(panel2);
|
||||
});
|
||||
|
|
@ -0,0 +1,238 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 723071: Test adding a pane to display the list of breakpoints across
|
||||
* all sources in the debuggee.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
const { getBreakpoint } = queries;
|
||||
|
||||
let breakpointsAdded = 0;
|
||||
let breakpointsDisabled = 0;
|
||||
let breakpointsRemoved = 0;
|
||||
let breakpointsList;
|
||||
|
||||
const addBreakpoints = Task.async(function* (aIncrementFlag) {
|
||||
const loc1 = { actor: gSources.selectedValue, line: 6 };
|
||||
yield actions.addBreakpoint(loc1);
|
||||
onBreakpointAdd(getBreakpoint(getState(), loc1), {
|
||||
increment: aIncrementFlag,
|
||||
line: 6,
|
||||
text: "debugger;"
|
||||
});
|
||||
|
||||
const loc2 = { actor: gSources.selectedValue, line: 7 };
|
||||
yield actions.addBreakpoint(loc2);
|
||||
onBreakpointAdd(getBreakpoint(getState(), loc2), {
|
||||
increment: aIncrementFlag,
|
||||
line: 7,
|
||||
text: "function foo() {}"
|
||||
});
|
||||
|
||||
const loc3 = {actor: gSources.selectedValue, line: 9 };
|
||||
yield actions.addBreakpoint(loc3);
|
||||
onBreakpointAdd(getBreakpoint(getState(), loc3), {
|
||||
increment: aIncrementFlag,
|
||||
line: 9,
|
||||
text: "foo();"
|
||||
});
|
||||
});
|
||||
|
||||
function disableBreakpoints() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let nodes = breakpointsList.querySelectorAll(".dbg-breakpoint");
|
||||
info("Nodes to disable: " + breakpointsAdded.length);
|
||||
|
||||
is(nodes.length, breakpointsAdded,
|
||||
"The number of nodes to disable is incorrect.");
|
||||
|
||||
for (let node of nodes) {
|
||||
info("Disabling breakpoint: " + node.id);
|
||||
|
||||
let sourceItem = gSources.getItemForElement(node);
|
||||
let breakpointItem = gSources.getItemForElement.call(sourceItem, node);
|
||||
info("Found data: " + breakpointItem.attachment.toSource());
|
||||
|
||||
actions.disableBreakpoint(breakpointItem.attachment).then(() => {
|
||||
if (++breakpointsDisabled == breakpointsAdded) {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function removeBreakpoints() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let nodes = breakpointsList.querySelectorAll(".dbg-breakpoint");
|
||||
info("Nodes to remove: " + breakpointsAdded.length);
|
||||
|
||||
is(nodes.length, breakpointsAdded,
|
||||
"The number of nodes to remove is incorrect.");
|
||||
|
||||
for (let node of nodes) {
|
||||
info("Removing breakpoint: " + node.id);
|
||||
|
||||
let sourceItem = gSources.getItemForElement(node);
|
||||
let breakpointItem = gSources.getItemForElement.call(sourceItem, node);
|
||||
info("Found data: " + breakpointItem.attachment.toSource());
|
||||
|
||||
actions.removeBreakpoint(breakpointItem.attachment).then(() => {
|
||||
if (++breakpointsRemoved == breakpointsAdded) {
|
||||
deferred.resolve();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function onBreakpointAdd(bp, testData) {
|
||||
if (testData.increment) {
|
||||
breakpointsAdded++;
|
||||
}
|
||||
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
testData.increment
|
||||
? "Should have added a breakpoint in the pane."
|
||||
: "Should have the same number of breakpoints in the pane.");
|
||||
|
||||
let identifier = queries.makeLocationId(bp.location);
|
||||
let node = gDebugger.document.getElementById("breakpoint-" + identifier);
|
||||
let line = node.getElementsByClassName("dbg-breakpoint-line")[0];
|
||||
let text = node.getElementsByClassName("dbg-breakpoint-text")[0];
|
||||
let check = node.querySelector("checkbox");
|
||||
|
||||
ok(node,
|
||||
"Breakpoint element found successfully.");
|
||||
is(line.getAttribute("value"), testData.line,
|
||||
"The expected information wasn't found in the breakpoint element.");
|
||||
is(text.getAttribute("value"), testData.text,
|
||||
"The expected line text wasn't found in the breakpoint element.");
|
||||
is(check.getAttribute("checked"), "true",
|
||||
"The breakpoint enable checkbox is checked as expected.");
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
yield waitForSourceAndCaretAndScopes(gPanel, "-02.js", 1);
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(queries.getSourceCount(getState()), 2,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("debugger"), 166,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[1],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 0,
|
||||
"No breakpoints currently added.");
|
||||
|
||||
let breakpointsParent = gSources.widget._parent;
|
||||
breakpointsList = gSources.widget._list;
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, 0,
|
||||
"No breakpoints should be visible at this point.");
|
||||
|
||||
yield addBreakpoints(true);
|
||||
|
||||
is(breakpointsAdded, 3,
|
||||
"Should have added 3 breakpoints so far.");
|
||||
is(breakpointsDisabled, 0,
|
||||
"Shouldn't have disabled anything so far.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, 3,
|
||||
"3 breakpoints should be visible at this point.");
|
||||
|
||||
yield disableBreakpoints();
|
||||
|
||||
is(breakpointsAdded, 3,
|
||||
"Should still have 3 breakpoints added so far.");
|
||||
is(breakpointsDisabled, 3,
|
||||
"Should have 3 disabled breakpoints.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
"Should have the same number of breakpoints in the pane.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsDisabled,
|
||||
"Should have the same number of disabled breakpoints.");
|
||||
|
||||
yield addBreakpoints();
|
||||
|
||||
is(breakpointsAdded, 3,
|
||||
"Should still have only 3 breakpoints added so far.");
|
||||
is(breakpointsDisabled, 3,
|
||||
"Should still have 3 disabled breakpoints.");
|
||||
is(breakpointsRemoved, 0,
|
||||
"Shouldn't have removed anything so far.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, breakpointsAdded,
|
||||
"Since half of the breakpoints already existed, but disabled, " +
|
||||
"only half of the added breakpoints are actually in the pane.");
|
||||
|
||||
yield removeBreakpoints();
|
||||
|
||||
is(breakpointsRemoved, 3,
|
||||
"Should have 3 removed breakpoints.");
|
||||
|
||||
is(breakpointsParent.childNodes.length, 1, // one sources list
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.childNodes.length, 1, // one sources group
|
||||
"Found junk in the breakpoints container.");
|
||||
is(breakpointsList.querySelectorAll(".dbg-breakpoint").length, 0,
|
||||
"No breakpoints should be visible at this point.");
|
||||
|
||||
const cleared = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED);
|
||||
gDebugger.gThreadClient.resume();
|
||||
yield cleared;
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 0,
|
||||
"No breakpoints currently added.");
|
||||
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
|
||||
callInTab(gTab, "firstCall");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that setting a breakpoint on code that gets run on load, will get
|
||||
* hit when we reload.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_breakpoints-reload.html";
|
||||
|
||||
var test = Task.async(function* () {
|
||||
requestLongerTimeout(4);
|
||||
|
||||
const options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
const [tab,, panel] = yield initDebugger(TAB_URL, options);
|
||||
const actions = bindActionCreators(panel);
|
||||
|
||||
const sources = panel.panelWin.DebuggerView.Sources;
|
||||
yield actions.addBreakpoint({
|
||||
actor: sources.selectedValue,
|
||||
line: 10 // "break on me" string
|
||||
});
|
||||
|
||||
const paused = waitForThreadEvents(panel, "paused");
|
||||
yield reloadActiveTab(panel, panel.panelWin.EVENTS.SOURCE_SHOWN);
|
||||
const packet = yield paused;
|
||||
|
||||
is(packet.why.type, "breakpoint",
|
||||
"Should have hit the breakpoint after the reload");
|
||||
is(packet.frame.where.line, 10,
|
||||
"Should have stopped at line 10, where we set the breakpoint");
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(panel);
|
||||
});
|
||||
|
|
@ -0,0 +1,48 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 896139 - Breakpoints not triggering when reloading script.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_bug-896139.html";
|
||||
const SCRIPT_URL = EXAMPLE_URL + "code_bug-896139.js";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
function testBreakpoint() {
|
||||
let promise = waitForDebuggerEvents(panel, win.EVENTS.FETCHED_SCOPES);
|
||||
callInTab(tab, "f");
|
||||
return promise.then(() => doResume(panel));
|
||||
}
|
||||
|
||||
let options = {
|
||||
source: SCRIPT_URL,
|
||||
line: 1
|
||||
};
|
||||
let [tab,, panel] = yield initDebugger(TAB_URL, options);
|
||||
let win = panel.panelWin;
|
||||
|
||||
let Sources = win.DebuggerView.Sources;
|
||||
|
||||
yield panel.addBreakpoint({
|
||||
actor: getSourceActor(win.DebuggerView.Sources, SCRIPT_URL),
|
||||
line: 6
|
||||
});
|
||||
|
||||
// Race condition: the setBreakpoint request sometimes leaves the
|
||||
// debugger in paused state for a bit because we are called before
|
||||
// that request finishes (see bug 1156531 for plans to fix)
|
||||
if (panel.panelWin.gThreadClient.state !== "attached") {
|
||||
yield waitForThreadEvents(panel, "resumed");
|
||||
}
|
||||
|
||||
yield testBreakpoint();
|
||||
yield reloadActiveTab(panel, win.EVENTS.SOURCE_SHOWN);
|
||||
yield testBreakpoint();
|
||||
|
||||
yield closeDebuggerAndFinish(panel);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that a chrome debugger can be created in a new process.
|
||||
*/
|
||||
|
||||
var gProcess;
|
||||
|
||||
function test() {
|
||||
// Windows XP and 8.1 test slaves are terribly slow at this test.
|
||||
requestLongerTimeout(5);
|
||||
Services.prefs.setBoolPref("devtools.debugger.remote-enabled", true);
|
||||
|
||||
initChromeDebugger(aOnClose).then(aProcess => {
|
||||
gProcess = aProcess;
|
||||
|
||||
info("Starting test...");
|
||||
performTest();
|
||||
});
|
||||
}
|
||||
|
||||
function performTest() {
|
||||
ok(gProcess._dbgProcess,
|
||||
"The remote debugger process wasn't created properly!");
|
||||
ok(gProcess._dbgProcess.isRunning,
|
||||
"The remote debugger process isn't running!");
|
||||
is(typeof gProcess._dbgProcess.pid, "number",
|
||||
"The remote debugger process doesn't have a pid (?!)");
|
||||
|
||||
info("process location: " + gProcess._dbgProcess.location);
|
||||
info("process pid: " + gProcess._dbgProcess.pid);
|
||||
info("process name: " + gProcess._dbgProcess.processName);
|
||||
info("process sig: " + gProcess._dbgProcess.processSignature);
|
||||
|
||||
ok(gProcess._dbgProfilePath,
|
||||
"The remote debugger profile wasn't created properly!");
|
||||
is(gProcess._dbgProfilePath, OS.Path.join(OS.Constants.Path.profileDir, "chrome_debugger_profile"),
|
||||
"The remote debugger profile isn't where we expect it!");
|
||||
|
||||
info("profile path: " + gProcess._dbgProfilePath);
|
||||
|
||||
gProcess.close();
|
||||
}
|
||||
|
||||
function aOnClose() {
|
||||
ok(!gProcess._dbgProcess.isRunning,
|
||||
"The remote debugger process isn't closed as it should be!");
|
||||
is(gProcess._dbgProcess.exitValue, (Services.appinfo.OS == "WINNT" ? 0 : 256),
|
||||
"The remote debugger process didn't die cleanly.");
|
||||
|
||||
info("process exit value: " + gProcess._dbgProcess.exitValue);
|
||||
|
||||
info("profile path: " + gProcess._dbgProfilePath);
|
||||
|
||||
finish();
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.remote-enabled");
|
||||
gProcess = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that chrome debugging works.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
var gClient, gThreadClient;
|
||||
var gAttached = promise.defer();
|
||||
var gNewGlobal = promise.defer();
|
||||
var gNewChromeSource = promise.defer();
|
||||
|
||||
var { DevToolsLoader } = Cu.import("resource://devtools/shared/Loader.jsm", {});
|
||||
var customLoader = new DevToolsLoader();
|
||||
customLoader.invisibleToDebugger = true;
|
||||
var { DebuggerServer } = customLoader.require("devtools/server/main");
|
||||
|
||||
function test() {
|
||||
if (!DebuggerServer.initialized) {
|
||||
DebuggerServer.init();
|
||||
DebuggerServer.addBrowserActors();
|
||||
}
|
||||
DebuggerServer.allowChromeProcess = true;
|
||||
|
||||
let transport = DebuggerServer.connectPipe();
|
||||
gClient = new DebuggerClient(transport);
|
||||
gClient.connect().then(([aType, aTraits]) => {
|
||||
is(aType, "browser",
|
||||
"Root actor should identify itself as a browser.");
|
||||
|
||||
promise.all([gAttached.promise, gNewGlobal.promise, gNewChromeSource.promise])
|
||||
.then(resumeAndCloseConnection)
|
||||
.then(finish)
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
|
||||
testChromeActor();
|
||||
});
|
||||
}
|
||||
|
||||
function testChromeActor() {
|
||||
gClient.getProcess().then(aResponse => {
|
||||
gClient.addListener("newGlobal", onNewGlobal);
|
||||
|
||||
let actor = aResponse.form.actor;
|
||||
gClient.attachTab(actor, (response, tabClient) => {
|
||||
tabClient.attachThread(null, (aResponse, aThreadClient) => {
|
||||
gThreadClient = aThreadClient;
|
||||
gThreadClient.addListener("newSource", onNewSource);
|
||||
|
||||
if (aResponse.error) {
|
||||
ok(false, "Couldn't attach to the chrome debugger.");
|
||||
gAttached.reject();
|
||||
} else {
|
||||
ok(true, "Attached to the chrome debugger.");
|
||||
gAttached.resolve();
|
||||
|
||||
// Ensure that a new chrome global will be created.
|
||||
gBrowser.selectedTab = gBrowser.addTab("about:mozilla");
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onNewGlobal() {
|
||||
ok(true, "Received a new chrome global.");
|
||||
|
||||
gClient.removeListener("newGlobal", onNewGlobal);
|
||||
gNewGlobal.resolve();
|
||||
}
|
||||
|
||||
function onNewSource(aEvent, aPacket) {
|
||||
if (aPacket.source.url.startsWith("chrome:")) {
|
||||
ok(true, "Received a new chrome source: " + aPacket.source.url);
|
||||
|
||||
gThreadClient.removeListener("newSource", onNewSource);
|
||||
gNewChromeSource.resolve();
|
||||
}
|
||||
}
|
||||
|
||||
function resumeAndCloseConnection() {
|
||||
let deferred = promise.defer();
|
||||
gThreadClient.resume(() => deferred.resolve(gClient.close()));
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gClient = null;
|
||||
gThreadClient = null;
|
||||
gAttached = null;
|
||||
gNewGlobal = null;
|
||||
gNewChromeSource = null;
|
||||
|
||||
customLoader = null;
|
||||
DebuggerServer = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that closing a window with the debugger in a paused state exits cleanly.
|
||||
*/
|
||||
|
||||
var gDebuggee, gPanel, gDebugger, gWindow;
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
function test() {
|
||||
addWindow(TAB_URL)
|
||||
.then(win => initDebugger(TAB_URL, { window: win }))
|
||||
.then(([aTab, aDebuggee, aPanel, aWindow]) => {
|
||||
gDebuggee = aDebuggee;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gWindow = aWindow;
|
||||
|
||||
return testCleanExit();
|
||||
})
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
}
|
||||
|
||||
function testCleanExit() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
ok(!!gWindow, "Second window created.");
|
||||
|
||||
gWindow.focus();
|
||||
|
||||
is(Services.wm.getMostRecentWindow("navigator:browser"), gWindow,
|
||||
"The second window is on top.");
|
||||
|
||||
let isActive = promise.defer();
|
||||
let isLoaded = promise.defer();
|
||||
|
||||
promise.all([isActive.promise, isLoaded.promise]).then(() => {
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 16).then(() => {
|
||||
is(gDebugger.gThreadClient.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
gWindow.close();
|
||||
deferred.resolve();
|
||||
finish();
|
||||
});
|
||||
|
||||
gDebuggee.runDebuggerStatement();
|
||||
});
|
||||
|
||||
if (Services.focus.activeWindow != gWindow) {
|
||||
gWindow.addEventListener("activate", function onActivate(aEvent) {
|
||||
if (aEvent.target != gWindow) {
|
||||
return;
|
||||
}
|
||||
gWindow.removeEventListener("activate", onActivate, true);
|
||||
isActive.resolve();
|
||||
}, true);
|
||||
} else {
|
||||
isActive.resolve();
|
||||
}
|
||||
|
||||
if (gWindow.content.location.href != TAB_URL) {
|
||||
gWindow.document.addEventListener("load", function onLoad(aEvent) {
|
||||
if (aEvent.target.documentURI != TAB_URL) {
|
||||
return;
|
||||
}
|
||||
gWindow.document.removeEventListener("load", onLoad, true);
|
||||
isLoaded.resolve();
|
||||
}, true);
|
||||
} else {
|
||||
isLoaded.resolve();
|
||||
}
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gWindow = null;
|
||||
gDebuggee = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Test that closing a tab with the debugger in a paused state exits cleanly.
|
||||
*/
|
||||
|
||||
var gTab, gPanel, gDebugger;
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_inline-debugger-statement.html";
|
||||
|
||||
function test() {
|
||||
const options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
testCleanExit();
|
||||
});
|
||||
}
|
||||
|
||||
function testCleanExit() {
|
||||
promise.all([
|
||||
waitForSourceAndCaretAndScopes(gPanel, ".html", 16),
|
||||
waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_REFILLED)
|
||||
]).then(() => {
|
||||
is(gDebugger.gThreadClient.paused, true,
|
||||
"Should be paused after the debugger statement.");
|
||||
}).then(() => closeDebuggerAndFinish(gPanel, { whilePaused: true }));
|
||||
|
||||
callInTab(gTab, "runDebuggerStatement");
|
||||
}
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
gTab = null;
|
||||
gPanel = null;
|
||||
gDebugger = null;
|
||||
});
|
||||
|
|
@ -0,0 +1,153 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_closures.html";
|
||||
|
||||
// Test that inspecting a closure works as expected.
|
||||
|
||||
function test() {
|
||||
let gPanel, gTab, gDebugger;
|
||||
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
gTab = aTab;
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
|
||||
testClosure()
|
||||
.then(() => resumeDebuggerThenCloseAndFinish(gPanel))
|
||||
.then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
});
|
||||
|
||||
function testClosure() {
|
||||
generateMouseClickInTab(gTab, "content.document.querySelector('button')");
|
||||
|
||||
return waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES).then(() => {
|
||||
let gVars = gDebugger.DebuggerView.Variables;
|
||||
let localScope = gVars.getScopeAtIndex(0);
|
||||
let localNodes = localScope.target.querySelector(".variables-view-element-details").childNodes;
|
||||
|
||||
is(localNodes[4].querySelector(".name").getAttribute("value"), "person",
|
||||
"Should have the right property name for |person|.");
|
||||
is(localNodes[4].querySelector(".value").getAttribute("value"), "Object",
|
||||
"Should have the right property value for |person|.");
|
||||
|
||||
// Expand the 'person' tree node. This causes its properties to be
|
||||
// retrieved and displayed.
|
||||
let personNode = gVars.getItemForNode(localNodes[4]);
|
||||
let personFetched = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES);
|
||||
personNode.expand();
|
||||
|
||||
return personFetched.then(() => {
|
||||
is(personNode.expanded, true,
|
||||
"|person| should be expanded at this point.");
|
||||
|
||||
is(personNode.get("getName").target.querySelector(".name")
|
||||
.getAttribute("value"), "getName",
|
||||
"Should have the right property name for 'getName' in person.");
|
||||
is(personNode.get("getName").target.querySelector(".value")
|
||||
.getAttribute("value"), "_pfactory/<.getName()",
|
||||
"'getName' in person should have the right value.");
|
||||
is(personNode.get("getFoo").target.querySelector(".name")
|
||||
.getAttribute("value"), "getFoo",
|
||||
"Should have the right property name for 'getFoo' in person.");
|
||||
is(personNode.get("getFoo").target.querySelector(".value")
|
||||
.getAttribute("value"), "_pfactory/<.getFoo()",
|
||||
"'getFoo' in person should have the right value.");
|
||||
|
||||
// Expand the function nodes. This causes their properties to be
|
||||
// retrieved and displayed.
|
||||
let getFooNode = personNode.get("getFoo");
|
||||
let getNameNode = personNode.get("getName");
|
||||
let funcsFetched = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 2);
|
||||
let funcClosuresFetched = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_SCOPES, 2);
|
||||
getFooNode.expand();
|
||||
getNameNode.expand();
|
||||
|
||||
return funcsFetched.then(() => {
|
||||
is(getFooNode.expanded, true,
|
||||
"|person.getFoo| should be expanded at this point.");
|
||||
is(getNameNode.expanded, true,
|
||||
"|person.getName| should be expanded at this point.");
|
||||
|
||||
is(getFooNode.get("<Closure>").target.querySelector(".name")
|
||||
.getAttribute("value"), "<Closure>",
|
||||
"Found the closure node for getFoo.");
|
||||
is(getFooNode.get("<Closure>").target.querySelector(".value")
|
||||
.getAttribute("value"), "",
|
||||
"The closure node has no value for getFoo.");
|
||||
is(getNameNode.get("<Closure>").target.querySelector(".name")
|
||||
.getAttribute("value"), "<Closure>",
|
||||
"Found the closure node for getName.");
|
||||
is(getNameNode.get("<Closure>").target.querySelector(".value")
|
||||
.getAttribute("value"), "",
|
||||
"The closure node has no value for getName.");
|
||||
|
||||
// Expand the closure nodes. This causes their environments to be
|
||||
// retrieved and displayed.
|
||||
let getFooClosure = getFooNode.get("<Closure>");
|
||||
let getNameClosure = getNameNode.get("<Closure>");
|
||||
getFooClosure.expand();
|
||||
getNameClosure.expand();
|
||||
|
||||
return funcClosuresFetched.then(() => {
|
||||
is(getFooClosure.expanded, true,
|
||||
"|person.getFoo| closure should be expanded at this point.");
|
||||
is(getNameClosure.expanded, true,
|
||||
"|person.getName| closure should be expanded at this point.");
|
||||
|
||||
is(getFooClosure.get("Function scope [_pfactory]").target.querySelector(".name")
|
||||
.getAttribute("value"), "Function scope [_pfactory]",
|
||||
"Found the function scope node for the getFoo closure.");
|
||||
is(getFooClosure.get("Function scope [_pfactory]").target.querySelector(".value")
|
||||
.getAttribute("value"), "",
|
||||
"The function scope node has no value for the getFoo closure.");
|
||||
is(getNameClosure.get("Function scope [_pfactory]").target.querySelector(".name")
|
||||
.getAttribute("value"), "Function scope [_pfactory]",
|
||||
"Found the function scope node for the getName closure.");
|
||||
is(getNameClosure.get("Function scope [_pfactory]").target.querySelector(".value")
|
||||
.getAttribute("value"), "",
|
||||
"The function scope node has no value for the getName closure.");
|
||||
|
||||
// Expand the scope nodes.
|
||||
let getFooInnerScope = getFooClosure.get("Function scope [_pfactory]");
|
||||
let getNameInnerScope = getNameClosure.get("Function scope [_pfactory]");
|
||||
let innerFuncsFetched = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.FETCHED_PROPERTIES, 2);
|
||||
getFooInnerScope.expand();
|
||||
getNameInnerScope.expand();
|
||||
|
||||
return funcsFetched.then(() => {
|
||||
is(getFooInnerScope.expanded, true,
|
||||
"|person.getFoo| inner scope should be expanded at this point.");
|
||||
is(getNameInnerScope.expanded, true,
|
||||
"|person.getName| inner scope should be expanded at this point.");
|
||||
|
||||
// Only test that each function closes over the necessary variable.
|
||||
// We wouldn't want future SpiderMonkey closure space
|
||||
// optimizations to break this test.
|
||||
is(getFooInnerScope.get("foo").target.querySelector(".name")
|
||||
.getAttribute("value"), "foo",
|
||||
"Found the foo node for the getFoo inner scope.");
|
||||
is(getFooInnerScope.get("foo").target.querySelector(".value")
|
||||
.getAttribute("value"), "10",
|
||||
"The foo node has the expected value.");
|
||||
is(getNameInnerScope.get("name").target.querySelector(".name")
|
||||
.getAttribute("value"), "name",
|
||||
"Found the name node for the getName inner scope.");
|
||||
is(getNameInnerScope.get("name").target.querySelector(".value")
|
||||
.getAttribute("value"), '"Bob"',
|
||||
"The name node has the expected value.");
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,117 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the 'dbg blackbox' and 'dbg unblackbox' commands work as
|
||||
* they should.
|
||||
*/
|
||||
|
||||
const TEST_URL = EXAMPLE_URL + "doc_blackboxing.html";
|
||||
const BLACKBOXME_URL = EXAMPLE_URL + "code_blackboxing_blackboxme.js";
|
||||
const BLACKBOXONE_URL = EXAMPLE_URL + "code_blackboxing_one.js";
|
||||
const BLACKBOXTWO_URL = EXAMPLE_URL + "code_blackboxing_two.js";
|
||||
const BLACKBOXTHREE_URL = EXAMPLE_URL + "code_blackboxing_three.js";
|
||||
|
||||
function test() {
|
||||
return Task.spawn(spawnTest).then(finish, helpers.handleError);
|
||||
}
|
||||
|
||||
function* spawnTest() {
|
||||
let options = yield helpers.openTab(TEST_URL);
|
||||
yield helpers.openToolbar(options);
|
||||
|
||||
let toolbox = yield gDevTools.showToolbox(options.target, "jsdebugger");
|
||||
let panel = toolbox.getCurrentPanel();
|
||||
let constants = panel.panelWin.require("./content/constants");
|
||||
|
||||
yield waitForDebuggerEvents(panel, panel.panelWin.EVENTS.SOURCE_SHOWN);
|
||||
|
||||
function cmd(aTyped, aEventRepeat = 1, aOutput = "") {
|
||||
return promise.all([
|
||||
waitForDispatch(panel, constants.BLACKBOX, aEventRepeat),
|
||||
helpers.audit(options, [{ setup: aTyped, output: aOutput, exec: {} }])
|
||||
]);
|
||||
}
|
||||
|
||||
// test Black-Box Source
|
||||
yield cmd("dbg blackbox " + BLACKBOXME_URL);
|
||||
|
||||
let bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(bbButton.checked,
|
||||
"Should be able to black box a specific source.");
|
||||
|
||||
// test Un-Black-Box Source
|
||||
yield cmd("dbg unblackbox " + BLACKBOXME_URL);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(!bbButton.checked,
|
||||
"Should be able to stop black boxing a specific source.");
|
||||
|
||||
// test Black-Box Glob
|
||||
yield cmd("dbg blackbox --glob *blackboxing_t*.js", 2,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g]);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackboxme should not be black boxed because it doesn't match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXONE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_one should not be black boxed because it doesn't match the glob.");
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTWO_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackbox_two should be black boxed because it matches the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTHREE_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackbox_three should be black boxed because it matches the glob.");
|
||||
|
||||
// test Un-Black-Box Glob
|
||||
yield cmd("dbg unblackbox --glob *blackboxing_t*.js", 2);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTWO_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_two should be un-black boxed because it matches the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTHREE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_three should be un-black boxed because it matches the glob.");
|
||||
|
||||
// test Black-Box Invert
|
||||
yield cmd("dbg blackbox --invert --glob *blackboxing_t*.js", 3,
|
||||
[/blackboxing_three\.js/g, /blackboxing_two\.js/g]);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackboxme should be black boxed because it doesn't match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXONE_URL);
|
||||
ok(bbButton.checked,
|
||||
"blackbox_one should be black boxed because it doesn't match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, TEST_URL);
|
||||
ok(bbButton.checked,
|
||||
"TEST_URL should be black boxed because it doesn't match the glob.");
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTWO_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_two should not be black boxed because it matches the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXTHREE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_three should not be black boxed because it matches the glob.");
|
||||
|
||||
// test Un-Black-Box Invert
|
||||
yield cmd("dbg unblackbox --invert --glob *blackboxing_t*.js", 3);
|
||||
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXME_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackboxme should be un-black boxed because it does not match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, BLACKBOXONE_URL);
|
||||
ok(!bbButton.checked,
|
||||
"blackbox_one should be un-black boxed because it does not match the glob.");
|
||||
bbButton = yield selectSourceAndGetBlackBoxButton(panel, TEST_URL);
|
||||
ok(!bbButton.checked,
|
||||
"TEST_URL should be un-black boxed because it doesn't match the glob.");
|
||||
|
||||
yield teardown(panel, { noTabRemoval: true });
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
}
|
||||
225
devtools/client/debugger/test/mochitest/browser_dbg_cmd-break.js
Normal file
225
devtools/client/debugger/test/mochitest/browser_dbg_cmd-break.js
Normal file
|
|
@ -0,0 +1,225 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the break commands works as they should.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_cmd-break.html";
|
||||
var TAB_URL_ACTOR;
|
||||
|
||||
function test() {
|
||||
let gPanel, gDebugger, gThreadClient, gSources;
|
||||
let gLineNumber;
|
||||
|
||||
let expectedActorObj = {
|
||||
value: null,
|
||||
message: ""
|
||||
};
|
||||
|
||||
helpers.addTabWithToolbar(TAB_URL, aOptions => {
|
||||
return Task.spawn(function* () {
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break",
|
||||
check: {
|
||||
input: "break",
|
||||
hints: " add line",
|
||||
markup: "IIIII",
|
||||
status: "ERROR",
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break add",
|
||||
check: {
|
||||
input: "break add",
|
||||
hints: " line",
|
||||
markup: "IIIIIVIII",
|
||||
status: "ERROR"
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break add line",
|
||||
check: {
|
||||
input: "break add line",
|
||||
hints: " <file> <line>",
|
||||
markup: "VVVVVVVVVVVVVV",
|
||||
status: "ERROR"
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
name: "open toolbox",
|
||||
setup: Task.async(function* () {
|
||||
let [aTab, aDebuggee, aPanel] = yield initDebugger(gBrowser.selectedTab);
|
||||
|
||||
// Spin the event loop before causing the debuggee to pause, to allow this
|
||||
// function to return first.
|
||||
executeSoon(() => aDebuggee.firstCall());
|
||||
|
||||
yield waitForSourceAndCaretAndScopes(aPanel, ".html", 1);
|
||||
|
||||
gPanel = aPanel;
|
||||
gDebugger = gPanel.panelWin;
|
||||
gThreadClient = gPanel.panelWin.gThreadClient;
|
||||
gLineNumber = yield ContentTask.spawn(aOptions.browser, {}, function* () {
|
||||
return "" + content.wrappedJSObject.gLineNumber;
|
||||
});
|
||||
gSources = gDebugger.DebuggerView.Sources;
|
||||
|
||||
expectedActorObj.value = getSourceActor(gSources, TAB_URL);
|
||||
}),
|
||||
post: function () {
|
||||
ok(gThreadClient, "Debugger client exists.");
|
||||
is(gLineNumber, 14, "gLineNumber is correct.");
|
||||
},
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
name: "break add line .../doc_cmd-break.html 14",
|
||||
setup: function () {
|
||||
// We have to setup in a function to allow gLineNumber to be initialized.
|
||||
let line = "break add line " + TAB_URL + " " + gLineNumber;
|
||||
return helpers.setInput(aOptions, line);
|
||||
},
|
||||
check: {
|
||||
hints: "",
|
||||
status: "VALID",
|
||||
message: "",
|
||||
args: {
|
||||
file: expectedActorObj,
|
||||
line: { value: 14 }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: "Added breakpoint"
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break add line " + TAB_URL + " 17",
|
||||
check: {
|
||||
hints: "",
|
||||
status: "VALID",
|
||||
message: "",
|
||||
args: {
|
||||
file: expectedActorObj,
|
||||
line: { value: 17 }
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: "Added breakpoint"
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break list",
|
||||
check: {
|
||||
input: "break list",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVV",
|
||||
status: "VALID"
|
||||
},
|
||||
exec: {
|
||||
output: [
|
||||
/Source/, /Remove/,
|
||||
/doc_cmd-break\.html:14/,
|
||||
/doc_cmd-break\.html:17/
|
||||
]
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
name: "cleanup",
|
||||
setup: function () {
|
||||
let deferred = promise.defer();
|
||||
gThreadClient.resume(deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break del 14",
|
||||
check: {
|
||||
input: "break del 14",
|
||||
hints: " -> doc_cmd-break.html:14",
|
||||
markup: "VVVVVVVVVVII",
|
||||
status: "ERROR",
|
||||
args: {
|
||||
breakpoint: {
|
||||
status: "INCOMPLETE",
|
||||
message: "Value required for \u2018breakpoint\u2019."
|
||||
}
|
||||
}
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break del doc_cmd-break.html:14",
|
||||
check: {
|
||||
input: "break del doc_cmd-break.html:14",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV",
|
||||
status: "VALID",
|
||||
args: {
|
||||
breakpoint: { arg: " doc_cmd-break.html:14" },
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: "Breakpoint removed"
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break list",
|
||||
check: {
|
||||
input: "break list",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVV",
|
||||
status: "VALID"
|
||||
},
|
||||
exec: {
|
||||
output: [
|
||||
/Source/, /Remove/,
|
||||
/doc_cmd-break\.html:17/
|
||||
]
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break del doc_cmd-break.html:17",
|
||||
check: {
|
||||
input: "break del doc_cmd-break.html:17",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVVVVVVVVVVVVVVVVVVVVVVV",
|
||||
status: "VALID",
|
||||
args: {
|
||||
breakpoint: { arg: " doc_cmd-break.html:17" },
|
||||
}
|
||||
},
|
||||
exec: {
|
||||
output: "Breakpoint removed"
|
||||
}
|
||||
}]);
|
||||
|
||||
yield helpers.audit(aOptions, [{
|
||||
setup: "break list",
|
||||
check: {
|
||||
input: "break list",
|
||||
hints: "",
|
||||
markup: "VVVVVVVVVV",
|
||||
status: "VALID"
|
||||
},
|
||||
exec: {
|
||||
output: "No breakpoints set"
|
||||
},
|
||||
post: function () {
|
||||
return teardown(gPanel, { noTabRemoval: true });
|
||||
}
|
||||
}]);
|
||||
});
|
||||
}).then(finish);
|
||||
}
|
||||
102
devtools/client/debugger/test/mochitest/browser_dbg_cmd-dbg.js
Normal file
102
devtools/client/debugger/test/mochitest/browser_dbg_cmd-dbg.js
Normal file
|
|
@ -0,0 +1,102 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that the debugger commands work as they should.
|
||||
*/
|
||||
|
||||
const TEST_URI = EXAMPLE_URL + "doc_cmd-dbg.html";
|
||||
|
||||
function test() {
|
||||
return Task.spawn(function* () {
|
||||
let options = yield helpers.openTab(TEST_URI);
|
||||
yield helpers.openToolbar(options);
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg open",
|
||||
exec: { output: "" }
|
||||
}]);
|
||||
|
||||
let [gTab, gDebuggee, gPanel] = yield initDebugger(gBrowser.selectedTab);
|
||||
let gDebugger = gPanel.panelWin;
|
||||
let gThreadClient = gDebugger.gThreadClient;
|
||||
|
||||
yield helpers.audit(options, [{
|
||||
setup: "dbg list",
|
||||
exec: { output: /doc_cmd-dbg.html/ }
|
||||
}]);
|
||||
|
||||
let button = gDebuggee.document.querySelector("input[type=button]");
|
||||
let output = gDebuggee.document.querySelector("input[type=text]");
|
||||
|
||||
let cmd = function (aTyped, aState) {
|
||||
return promise.all([
|
||||
waitForThreadEvents(gPanel, aState),
|
||||
helpers.audit(options, [{ setup: aTyped, exec: { output: "" } }])
|
||||
]);
|
||||
};
|
||||
|
||||
let click = function (aElement, aState) {
|
||||
return promise.all([
|
||||
waitForThreadEvents(gPanel, aState),
|
||||
executeSoon(() => EventUtils.sendMouseEvent({ type: "click" }, aElement, gDebuggee))
|
||||
]);
|
||||
};
|
||||
|
||||
yield cmd("dbg interrupt", "paused");
|
||||
is(gThreadClient.state, "paused", "Debugger is paused.");
|
||||
|
||||
yield cmd("dbg continue", "resumed");
|
||||
isnot(gThreadClient.state, "paused", "Debugger has continued.");
|
||||
|
||||
yield click(button, "paused");
|
||||
is(gThreadClient.state, "paused", "Debugger is paused again.");
|
||||
|
||||
yield cmd("dbg step in", "paused");
|
||||
yield cmd("dbg step in", "paused");
|
||||
yield cmd("dbg step in", "paused");
|
||||
is(output.value, "step in", "Debugger stepped in.");
|
||||
|
||||
yield cmd("dbg step over", "paused");
|
||||
is(output.value, "step over", "Debugger stepped over.");
|
||||
|
||||
yield cmd("dbg step out", "paused");
|
||||
is(output.value, "step out", "Debugger stepped out.");
|
||||
|
||||
yield cmd("dbg continue", "paused");
|
||||
is(output.value, "dbg continue", "Debugger continued.");
|
||||
|
||||
let closeDebugger = function () {
|
||||
let deferred = promise.defer();
|
||||
|
||||
helpers.audit(options, [{
|
||||
setup: "dbg close",
|
||||
exec: { output: "" }
|
||||
}])
|
||||
.then(() => {
|
||||
let toolbox = gDevTools.getToolbox(options.target);
|
||||
if (!toolbox) {
|
||||
ok(true, "Debugger is closed.");
|
||||
deferred.resolve();
|
||||
} else {
|
||||
toolbox.on("destroyed", () => {
|
||||
ok(true, "Debugger just closed.");
|
||||
deferred.resolve();
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
};
|
||||
|
||||
// We close the debugger twice to ensure 'dbg close' doesn't error when
|
||||
// toolbox is already closed. See bug 884638 for more info.
|
||||
yield closeDebugger();
|
||||
yield closeDebugger();
|
||||
yield helpers.closeToolbar(options);
|
||||
yield helpers.closeTab(options);
|
||||
|
||||
}).then(finish, helpers.handleError);
|
||||
}
|
||||
|
|
@ -0,0 +1,218 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 740825: Test the debugger conditional breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
// Linux debug test slaves are a bit slow at this test sometimes.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
const addBreakpoints = Task.async(function* () {
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 },
|
||||
"undefined");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 19 },
|
||||
"null");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 20 },
|
||||
"42");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 21 },
|
||||
"true");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 22 },
|
||||
"'nasu'");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 23 },
|
||||
"/regexp/");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 24 },
|
||||
"({})");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 25 },
|
||||
"(function() {})");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 26 },
|
||||
"(function() { return false; })()");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 27 },
|
||||
"a");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 28 },
|
||||
"a !== undefined");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 29 },
|
||||
"b");
|
||||
yield actions.addBreakpoint({ actor: gSources.selectedValue, line: 30 },
|
||||
"a !== null");
|
||||
});
|
||||
|
||||
function resumeAndTestBreakpoint(line) {
|
||||
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
|
||||
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function resumeAndTestNoBreakpoint() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gSources.selectedItem,
|
||||
"There should be a selected source in the sources pane.");
|
||||
ok(!gSources._selectedBreakpoint,
|
||||
"There should be no selected breakpoint in the sources pane.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"There should be no visible stackframes.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-breakpoint").length, 13,
|
||||
"There should be thirteen visible breakpoints.");
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBreakpoint(line, highlightBreakpoint) {
|
||||
// Highlight the breakpoint only if required.
|
||||
if (highlightBreakpoint) {
|
||||
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
|
||||
gSources.highlightBreakpoint({ actor: gSources.selectedValue, line: line });
|
||||
return finished;
|
||||
}
|
||||
|
||||
let selectedActor = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpoint;
|
||||
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
|
||||
|
||||
ok(selectedActor,
|
||||
"There should be a selected item in the sources pane.");
|
||||
ok(selectedBreakpoint,
|
||||
"There should be a selected breakpoint in the sources pane.");
|
||||
|
||||
let source = gSources.selectedItem.attachment.source;
|
||||
let bp = queries.getBreakpoint(getState(), selectedBreakpoint.location);
|
||||
|
||||
ok(bp, "The selected breakpoint exists");
|
||||
is(bp.location.actor, source.actor,
|
||||
"The breakpoint on line " + line + " wasn't added on the correct source.");
|
||||
is(bp.location.line, line,
|
||||
"The breakpoint on line " + line + " wasn't found.");
|
||||
is(!!bp.disabled, false,
|
||||
"The breakpoint on line " + line + " should be enabled.");
|
||||
is(!!selectedBreakpointItem.attachment.openPopup, false,
|
||||
"The breakpoint on line " + line + " should not have opened a popup.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not have been shown.");
|
||||
isnot(bp.condition, undefined,
|
||||
"The breakpoint on line " + line + " should have a conditional expression.");
|
||||
ok(isCaretPos(gPanel, line),
|
||||
"The editor caret position is not properly set.");
|
||||
}
|
||||
|
||||
const testAfterReload = Task.async(function* () {
|
||||
let selectedActor = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpoint;
|
||||
|
||||
ok(selectedActor,
|
||||
"There should be a selected item in the sources pane after reload.");
|
||||
ok(!selectedBreakpoint,
|
||||
"There should be no selected breakpoint in the sources pane after reload.");
|
||||
|
||||
yield testBreakpoint(18, true);
|
||||
yield testBreakpoint(19, true);
|
||||
yield testBreakpoint(20, true);
|
||||
yield testBreakpoint(21, true);
|
||||
yield testBreakpoint(22, true);
|
||||
yield testBreakpoint(23, true);
|
||||
yield testBreakpoint(24, true);
|
||||
yield testBreakpoint(25, true);
|
||||
yield testBreakpoint(26, true);
|
||||
yield testBreakpoint(27, true);
|
||||
yield testBreakpoint(28, true);
|
||||
yield testBreakpoint(29, true);
|
||||
yield testBreakpoint(30, true);
|
||||
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded again.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gSources.selectedItem,
|
||||
"There should be a selected source in the sources pane.");
|
||||
ok(gSources._selectedBreakpoint,
|
||||
"There should be a selected breakpoint in the sources pane.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
});
|
||||
|
||||
Task.spawn(function* () {
|
||||
let onCaretUpdated = waitForCaretAndScopes(gPanel, 17);
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield onCaretUpdated;
|
||||
|
||||
yield addBreakpoints();
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(queries.getSourceCount(getState()), 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
is(queries.getBreakpoints(getState()).length, 13,
|
||||
"13 breakpoints currently added.");
|
||||
|
||||
yield resumeAndTestBreakpoint(20);
|
||||
yield resumeAndTestBreakpoint(21);
|
||||
yield resumeAndTestBreakpoint(22);
|
||||
yield resumeAndTestBreakpoint(23);
|
||||
yield resumeAndTestBreakpoint(24);
|
||||
yield resumeAndTestBreakpoint(25);
|
||||
yield resumeAndTestBreakpoint(27);
|
||||
yield resumeAndTestBreakpoint(28);
|
||||
yield resumeAndTestBreakpoint(29);
|
||||
yield resumeAndTestBreakpoint(30);
|
||||
yield resumeAndTestNoBreakpoint();
|
||||
|
||||
let sourceShown = waitForSourceShown(gPanel, ".html");
|
||||
reload(gPanel),
|
||||
yield sourceShown;
|
||||
|
||||
testAfterReload();
|
||||
|
||||
// Reset traits back to default value
|
||||
client.mainRoot.traits.conditionalBreakpoints = true;
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,219 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Bug 740825: Test the debugger conditional breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
const CONDITIONAL_POPUP_SHOWN = gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
function addBreakpoint1() {
|
||||
return actions.addBreakpoint({ actor: gSources.selectedValue, line: 18 });
|
||||
}
|
||||
|
||||
function addBreakpoint2() {
|
||||
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
|
||||
setCaretPosition(19);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function modBreakpoint2() {
|
||||
setCaretPosition(19);
|
||||
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
return popupShown;
|
||||
}
|
||||
|
||||
function* addBreakpoint3() {
|
||||
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
|
||||
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
|
||||
setCaretPosition(20);
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
yield finished;
|
||||
yield popupShown;
|
||||
}
|
||||
|
||||
function* modBreakpoint3() {
|
||||
setCaretPosition(20);
|
||||
|
||||
let popupShown = waitForDebuggerEvents(gPanel, CONDITIONAL_POPUP_SHOWN);
|
||||
gSources._onCmdAddConditionalBreakpoint();
|
||||
yield popupShown;
|
||||
|
||||
typeText(gSources._cbTextbox, "bamboocha");
|
||||
|
||||
let finished = waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
|
||||
EventUtils.sendKey("RETURN", gDebugger);
|
||||
yield finished;
|
||||
}
|
||||
|
||||
function addBreakpoint4() {
|
||||
let finished = waitForDispatch(gPanel, constants.ADD_BREAKPOINT);
|
||||
setCaretPosition(21);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function delBreakpoint4() {
|
||||
let finished = waitForDispatch(gPanel, constants.REMOVE_BREAKPOINT);
|
||||
setCaretPosition(21);
|
||||
gSources._onCmdAddBreakpoint();
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBreakpoint(aLine, aPopupVisible, aConditionalExpression) {
|
||||
const source = queries.getSelectedSource(getState());
|
||||
ok(source,
|
||||
"There should be a selected item in the sources pane.");
|
||||
|
||||
const bp = queries.getBreakpoint(getState(), {
|
||||
actor: source.actor,
|
||||
line: aLine
|
||||
});
|
||||
const bpItem = gSources._getBreakpoint(bp);
|
||||
ok(bp, "There should be a breakpoint.");
|
||||
ok(bpItem, "There should be a breakpoint in the sources pane.");
|
||||
|
||||
is(bp.location.actor, source.actor,
|
||||
"The breakpoint on line " + aLine + " wasn't added on the correct source.");
|
||||
is(bp.location.line, aLine,
|
||||
"The breakpoint on line " + aLine + " wasn't found.");
|
||||
is(!!bp.disabled, false,
|
||||
"The breakpoint on line " + aLine + " should be enabled.");
|
||||
is(gSources._conditionalPopupVisible, aPopupVisible,
|
||||
"The breakpoint on line " + aLine + " should have a correct popup state (2).");
|
||||
is(bp.condition, aConditionalExpression,
|
||||
"The breakpoint on line " + aLine + " should have a correct conditional expression.");
|
||||
}
|
||||
|
||||
function testNoBreakpoint(aLine) {
|
||||
let selectedActor = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpoint;
|
||||
|
||||
ok(selectedActor,
|
||||
"There should be a selected item in the sources pane for line " + aLine + ".");
|
||||
ok(!selectedBreakpoint,
|
||||
"There should be no selected brekapoint in the sources pane for line " + aLine + ".");
|
||||
|
||||
ok(isCaretPos(gPanel, aLine),
|
||||
"The editor caret position is not properly set.");
|
||||
}
|
||||
|
||||
function setCaretPosition(aLine) {
|
||||
gEditor.setCursor({ line: aLine - 1, ch: 0 });
|
||||
}
|
||||
|
||||
function clickOnBreakpoint(aIndex) {
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelectorAll(".dbg-breakpoint")[aIndex],
|
||||
gDebugger);
|
||||
}
|
||||
|
||||
function waitForConditionUpdate() {
|
||||
// This will close the popup and send another request to update
|
||||
// the condition
|
||||
gSources._hideConditionalPopup();
|
||||
return waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
let onCaretUpdated = waitForCaretAndScopes(gPanel, 17);
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield onCaretUpdated;
|
||||
|
||||
is(gDebugger.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(queries.getSourceCount(getState()), 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
is(queries.getBreakpoints(getState()).length, 0,
|
||||
"No breakpoints currently added.");
|
||||
|
||||
yield addBreakpoint1();
|
||||
testBreakpoint(18, false, undefined);
|
||||
|
||||
yield addBreakpoint2();
|
||||
testBreakpoint(19, false, undefined);
|
||||
yield modBreakpoint2();
|
||||
testBreakpoint(19, true, undefined);
|
||||
yield waitForConditionUpdate();
|
||||
yield addBreakpoint3();
|
||||
testBreakpoint(20, true, "");
|
||||
yield waitForConditionUpdate();
|
||||
yield modBreakpoint3();
|
||||
testBreakpoint(20, false, "bamboocha");
|
||||
yield addBreakpoint4();
|
||||
testBreakpoint(21, false, undefined);
|
||||
yield delBreakpoint4();
|
||||
|
||||
setCaretPosition(18);
|
||||
is(gSources._selectedBreakpoint.location.line, 18,
|
||||
"The selected breakpoint is line 18");
|
||||
yield testBreakpoint(18, false, undefined);
|
||||
|
||||
setCaretPosition(19);
|
||||
is(gSources._selectedBreakpoint.location.line, 19,
|
||||
"The selected breakpoint is line 19");
|
||||
yield testBreakpoint(19, false, "");
|
||||
|
||||
setCaretPosition(20);
|
||||
is(gSources._selectedBreakpoint.location.line, 20,
|
||||
"The selected breakpoint is line 20");
|
||||
yield testBreakpoint(20, false, "bamboocha");
|
||||
|
||||
setCaretPosition(17);
|
||||
yield testNoBreakpoint(17);
|
||||
|
||||
setCaretPosition(21);
|
||||
yield testNoBreakpoint(21);
|
||||
|
||||
clickOnBreakpoint(0);
|
||||
is(gSources._selectedBreakpoint.location.line, 18,
|
||||
"The selected breakpoint is line 18");
|
||||
yield testBreakpoint(18, false, undefined);
|
||||
|
||||
clickOnBreakpoint(1);
|
||||
is(gSources._selectedBreakpoint.location.line, 19,
|
||||
"The selected breakpoint is line 19");
|
||||
yield testBreakpoint(19, false, "");
|
||||
|
||||
clickOnBreakpoint(2);
|
||||
is(gSources._selectedBreakpoint.location.line, 20,
|
||||
"The selected breakpoint is line 20");
|
||||
testBreakpoint(20, true, "bamboocha");
|
||||
|
||||
// Reset traits back to default value
|
||||
client.mainRoot.traits.conditionalBreakpoints = true;
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests that conditional breakpoint expressions survive disabled breakpoints.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
initDebugger().then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
function waitForConditionUpdate() {
|
||||
// This will close the popup and send another request to update
|
||||
// the condition
|
||||
gSources._hideConditionalPopup();
|
||||
return waitForDispatch(gPanel, constants.SET_BREAKPOINT_CONDITION);
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
let onCaretUpdated = waitForCaretUpdated(gPanel, 17);
|
||||
yield navigateActiveTabTo(gPanel,
|
||||
TAB_URL,
|
||||
gDebugger.EVENTS.SOURCE_SHOWN);
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield onCaretUpdated;
|
||||
|
||||
const location = { actor: gSources.selectedValue, line: 18 };
|
||||
|
||||
yield actions.addBreakpoint(location, "hello");
|
||||
yield actions.disableBreakpoint(location);
|
||||
yield actions.addBreakpoint(location);
|
||||
|
||||
const bp = queries.getBreakpoint(getState(), location);
|
||||
is(bp.condition, "hello", "The conditional expression is correct.");
|
||||
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN);
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelector(".dbg-breakpoint"),
|
||||
gDebugger);
|
||||
yield finished;
|
||||
|
||||
const textbox = gDebugger.document.getElementById("conditional-breakpoint-panel-textbox");
|
||||
is(textbox.value, "hello", "The expression is correct (2).");
|
||||
|
||||
yield waitForConditionUpdate();
|
||||
yield actions.disableBreakpoint(location);
|
||||
yield actions.setBreakpointCondition(location, "foo");
|
||||
yield actions.addBreakpoint(location);
|
||||
|
||||
finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.CONDITIONAL_BREAKPOINT_POPUP_SHOWN);
|
||||
EventUtils.sendMouseEvent({ type: "click" },
|
||||
gDebugger.document.querySelector(".dbg-breakpoint"),
|
||||
gDebugger);
|
||||
yield finished;
|
||||
is(textbox.value, "foo", "The expression is correct (3).");
|
||||
|
||||
// Reset traits back to default value
|
||||
client.mainRoot.traits.conditionalBreakpoints = true;
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that conditional breakpoints with blank expressions
|
||||
* maintain their conditions after enabling them.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
Task.spawn(function* () {
|
||||
let onCaretUpdated = waitForCaretAndScopes(gPanel, 17);
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield onCaretUpdated;
|
||||
|
||||
const location = { actor: gSources.selectedValue, line: 18 };
|
||||
|
||||
yield actions.addBreakpoint(location, "");
|
||||
yield actions.disableBreakpoint(location);
|
||||
yield actions.addBreakpoint(location);
|
||||
|
||||
const bp = queries.getBreakpoint(getState(), location);
|
||||
is(bp.condition, "", "The conditional expression is correct.");
|
||||
|
||||
// Reset traits back to default value
|
||||
client.mainRoot.traits.conditionalBreakpoints = true;
|
||||
resumeDebuggerThenCloseAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,141 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Make sure that conditional breakpoints with an exception-throwing expression
|
||||
* could pause on hit
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_conditional-breakpoints.html";
|
||||
|
||||
function test() {
|
||||
let options = {
|
||||
source: TAB_URL,
|
||||
line: 1
|
||||
};
|
||||
initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => {
|
||||
const gTab = aTab;
|
||||
const gPanel = aPanel;
|
||||
const gDebugger = gPanel.panelWin;
|
||||
const gEditor = gDebugger.DebuggerView.editor;
|
||||
const gSources = gDebugger.DebuggerView.Sources;
|
||||
const queries = gDebugger.require("./content/queries");
|
||||
const constants = gDebugger.require("./content/constants");
|
||||
const actions = bindActionCreators(gPanel);
|
||||
const getState = gDebugger.DebuggerController.getState;
|
||||
|
||||
// This test forces conditional breakpoints to be evaluated on the
|
||||
// client-side
|
||||
var client = gPanel.target.client;
|
||||
client.mainRoot.traits.conditionalBreakpoints = false;
|
||||
|
||||
function resumeAndTestBreakpoint(line) {
|
||||
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
|
||||
EventUtils.sendMouseEvent({ type: "mousedown" },
|
||||
gDebugger.document.getElementById("resume"),
|
||||
gDebugger);
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function resumeAndTestNoBreakpoint() {
|
||||
let finished = waitForDebuggerEvents(gPanel, gDebugger.EVENTS.AFTER_FRAMES_CLEARED).then(() => {
|
||||
is(gSources.itemCount, 1,
|
||||
"Found the expected number of sources.");
|
||||
is(gEditor.getText().indexOf("ermahgerd"), 253,
|
||||
"The correct source was loaded initially.");
|
||||
is(gSources.selectedValue, gSources.values[0],
|
||||
"The correct source is selected.");
|
||||
|
||||
ok(gSources.selectedItem,
|
||||
"There should be a selected source in the sources pane.");
|
||||
ok(!gSources._selectedBreakpoint,
|
||||
"There should be no selected breakpoint in the sources pane.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not be shown.");
|
||||
|
||||
is(gDebugger.document.querySelectorAll(".dbg-stackframe").length, 0,
|
||||
"There should be no visible stackframes.");
|
||||
is(gDebugger.document.querySelectorAll(".dbg-breakpoint").length, 6,
|
||||
"There should be thirteen visible breakpoints.");
|
||||
});
|
||||
|
||||
gDebugger.gThreadClient.resume();
|
||||
|
||||
return finished;
|
||||
}
|
||||
|
||||
function testBreakpoint(line, highlightBreakpoint) {
|
||||
// Highlight the breakpoint only if required.
|
||||
if (highlightBreakpoint) {
|
||||
let finished = waitForCaretUpdated(gPanel, line).then(() => testBreakpoint(line));
|
||||
gSources.highlightBreakpoint({ actor: gSources.selectedValue, line: line });
|
||||
return finished;
|
||||
}
|
||||
|
||||
let selectedActor = gSources.selectedValue;
|
||||
let selectedBreakpoint = gSources._selectedBreakpoint;
|
||||
let selectedBreakpointItem = gSources._getBreakpoint(selectedBreakpoint);
|
||||
let source = queries.getSource(getState(), selectedActor);
|
||||
|
||||
ok(selectedActor,
|
||||
"There should be a selected item in the sources pane.");
|
||||
ok(selectedBreakpoint,
|
||||
"There should be a selected breakpoint.");
|
||||
ok(selectedBreakpointItem,
|
||||
"There should be a selected breakpoint item in the sources pane.");
|
||||
|
||||
is(selectedBreakpoint.location.actor, source.actor,
|
||||
"The breakpoint on line " + line + " wasn't added on the correct source.");
|
||||
is(selectedBreakpoint.location.line, line,
|
||||
"The breakpoint on line " + line + " wasn't found.");
|
||||
is(!!selectedBreakpoint.location.disabled, false,
|
||||
"The breakpoint on line " + line + " should be enabled.");
|
||||
is(gSources._conditionalPopupVisible, false,
|
||||
"The breakpoint conditional expression popup should not have been shown.");
|
||||
|
||||
isnot(selectedBreakpoint.condition, undefined,
|
||||
"The breakpoint on line " + line + " should have a conditional expression.");
|
||||
|
||||
ok(isCaretPos(gPanel, line),
|
||||
"The editor caret position is not properly set.");
|
||||
}
|
||||
|
||||
Task.spawn(function* () {
|
||||
let onCaretUpdated = waitForCaretAndScopes(gPanel, 17);
|
||||
callInTab(gTab, "ermahgerd");
|
||||
yield onCaretUpdated;
|
||||
|
||||
yield actions.addBreakpoint(
|
||||
{ actor: gSources.selectedValue, line: 18 }, " 1a"
|
||||
);
|
||||
yield actions.addBreakpoint(
|
||||
{ actor: gSources.selectedValue, line: 19 }, "new Error()"
|
||||
);
|
||||
yield actions.addBreakpoint(
|
||||
{ actor: gSources.selectedValue, line: 20 }, "true"
|
||||
);
|
||||
yield actions.addBreakpoint(
|
||||
{ actor: gSources.selectedValue, line: 21 }, "false"
|
||||
);
|
||||
yield actions.addBreakpoint(
|
||||
{ actor: gSources.selectedValue, line: 22 }, "0"
|
||||
);
|
||||
yield actions.addBreakpoint(
|
||||
{ actor: gSources.selectedValue, line: 23 }, "randomVar"
|
||||
);
|
||||
|
||||
yield resumeAndTestBreakpoint(18);
|
||||
yield resumeAndTestBreakpoint(19);
|
||||
yield resumeAndTestBreakpoint(20);
|
||||
yield resumeAndTestBreakpoint(23);
|
||||
yield resumeAndTestNoBreakpoint();
|
||||
|
||||
// Reset traits back to default value
|
||||
client.mainRoot.traits.conditionalBreakpoints = true;
|
||||
closeDebuggerAndFinish(gPanel);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,41 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Breaking in the middle of a script evaluated by the console should
|
||||
* work
|
||||
*/
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
let TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
|
||||
let [,, panel] = yield initDebugger(TAB_URL, { source: null });
|
||||
let dbgWin = panel.panelWin;
|
||||
let sources = dbgWin.DebuggerView.Sources;
|
||||
let frames = dbgWin.DebuggerView.StackFrames;
|
||||
let editor = dbgWin.DebuggerView.editor;
|
||||
let toolbox = gDevTools.getToolbox(panel.target);
|
||||
|
||||
let paused = promise.all([
|
||||
waitForEditorEvents(panel, "cursorActivity"),
|
||||
waitForDebuggerEvents(panel, dbgWin.EVENTS.SOURCE_SHOWN)
|
||||
]);
|
||||
|
||||
toolbox.once("webconsole-ready", () => {
|
||||
ok(toolbox.splitConsole, "Split console is shown.");
|
||||
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
|
||||
jsterm.execute("debugger");
|
||||
});
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, dbgWin);
|
||||
|
||||
yield paused;
|
||||
is(sources.selectedItem.attachment.label, "SCRIPT0",
|
||||
"Anonymous source is selected in sources");
|
||||
ok(editor.getText() === "debugger", "Editor has correct text");
|
||||
|
||||
yield toolbox.closeSplitConsole();
|
||||
yield resumeDebuggerThenCloseAndFinish(panel);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Breaking in the middle of a named eval script created by the
|
||||
* console should work
|
||||
*/
|
||||
|
||||
function test() {
|
||||
Task.spawn(runTests);
|
||||
}
|
||||
|
||||
function* runTests() {
|
||||
let TAB_URL = EXAMPLE_URL + "doc_empty-tab-01.html";
|
||||
let [,, panel] = yield initDebugger(TAB_URL, { source: null });
|
||||
let dbgWin = panel.panelWin;
|
||||
let sources = dbgWin.DebuggerView.Sources;
|
||||
let frames = dbgWin.DebuggerView.StackFrames;
|
||||
let editor = dbgWin.DebuggerView.editor;
|
||||
let toolbox = gDevTools.getToolbox(panel.target);
|
||||
|
||||
let paused = waitForSourceAndCaretAndScopes(panel, "foo.js", 1);
|
||||
|
||||
toolbox.once("webconsole-ready", () => {
|
||||
ok(toolbox.splitConsole, "Split console is shown.");
|
||||
let jsterm = toolbox.getPanel("webconsole").hud.jsterm;
|
||||
jsterm.execute("eval('debugger; //# sourceURL=foo.js')");
|
||||
});
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {}, dbgWin);
|
||||
|
||||
yield paused;
|
||||
is(sources.selectedItem.attachment.label, "foo.js",
|
||||
"New source is selected in sources");
|
||||
is(sources.selectedItem.attachment.group, "http://example.com",
|
||||
"New source is in the right group");
|
||||
ok(editor.getText() === "debugger; //# sourceURL=foo.js", "Editor has correct text");
|
||||
|
||||
yield toolbox.closeSplitConsole();
|
||||
yield resumeDebuggerThenCloseAndFinish(panel);
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/**
|
||||
* Tests the public evaluation API from the debugger controller.
|
||||
*/
|
||||
|
||||
const TAB_URL = EXAMPLE_URL + "doc_script-switching-01.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
const options = {
|
||||
source: EXAMPLE_URL + "code_script-switching-01.js",
|
||||
line: 1
|
||||
};
|
||||
const [tab,, panel] = yield initDebugger(TAB_URL, options);
|
||||
const win = panel.panelWin;
|
||||
const frames = win.DebuggerController.StackFrames;
|
||||
const framesView = win.DebuggerView.StackFrames;
|
||||
const sourcesView = win.DebuggerView.Sources;
|
||||
const editorView = win.DebuggerView.editor;
|
||||
const events = win.EVENTS;
|
||||
const queries = win.require("./content/queries");
|
||||
const constants = win.require("./content/constants");
|
||||
const actions = bindActionCreators(panel);
|
||||
const getState = win.DebuggerController.getState;
|
||||
|
||||
function checkView(frameDepth, selectedSource, caretLine, editorText) {
|
||||
is(win.gThreadClient.state, "paused",
|
||||
"Should only be getting stack frames while paused.");
|
||||
is(framesView.itemCount, 2,
|
||||
"Should have four frames.");
|
||||
is(framesView.selectedDepth, frameDepth,
|
||||
"The correct frame is selected in the widget.");
|
||||
is(sourcesView.selectedIndex, selectedSource,
|
||||
"The correct source is selected in the widget.");
|
||||
ok(isCaretPos(panel, caretLine),
|
||||
"Editor caret location is correct.");
|
||||
is(editorView.getText().search(editorText[0]), editorText[1],
|
||||
"The correct source is not displayed.");
|
||||
}
|
||||
|
||||
// Cache the sources text to avoid having to wait for their
|
||||
// retrieval.
|
||||
const sources = queries.getSources(getState());
|
||||
yield promise.all(Object.keys(sources).map(k => {
|
||||
return actions.loadSourceText(sources[k]);
|
||||
}));
|
||||
|
||||
is(Object.keys(getState().sources.sourcesText).length, 2,
|
||||
"There should be two cached sources in the cache.");
|
||||
|
||||
// Eval while not paused.
|
||||
try {
|
||||
yield frames.evaluate("foo");
|
||||
} catch (error) {
|
||||
is(error.message, "No stack frame available.",
|
||||
"Evaluating shouldn't work while the debuggee isn't paused.");
|
||||
}
|
||||
|
||||
callInTab(tab, "firstCall");
|
||||
yield waitForSourceAndCaretAndScopes(panel, "-02.js", 6);
|
||||
checkView(0, 1, 6, [/secondCall/, 118]);
|
||||
|
||||
// Eval in the topmost frame, while paused.
|
||||
let updatedView = waitForDebuggerEvents(panel, events.FETCHED_SCOPES);
|
||||
let result = yield frames.evaluate("foo");
|
||||
ok(!result.throw, "The evaluation hasn't thrown.");
|
||||
is(result.return.type, "object", "The evaluation return type is correct.");
|
||||
is(result.return.class, "Function", "The evaluation return class is correct.");
|
||||
|
||||
yield updatedView;
|
||||
checkView(0, 1, 6, [/secondCall/, 118]);
|
||||
ok(true, "Evaluating in the topmost frame works properly.");
|
||||
|
||||
// Eval in a different frame, while paused.
|
||||
updatedView = waitForDebuggerEvents(panel, events.FETCHED_SCOPES);
|
||||
try {
|
||||
yield frames.evaluate("foo", { depth: 1 }); // oldest frame
|
||||
} catch (result) {
|
||||
is(result.return.type, "object", "The evaluation thrown type is correct.");
|
||||
is(result.return.class, "Error", "The evaluation thrown class is correct.");
|
||||
ok(!result.return, "The evaluation hasn't returned.");
|
||||
}
|
||||
|
||||
yield updatedView;
|
||||
checkView(0, 1, 6, [/secondCall/, 118]);
|
||||
ok(true, "Evaluating in a custom frame works properly.");
|
||||
|
||||
// Eval in a non-existent frame, while paused.
|
||||
waitForDebuggerEvents(panel, events.FETCHED_SCOPES).then(() => {
|
||||
ok(false, "Shouldn't have updated the view when trying to evaluate " +
|
||||
"an expression in a non-existent stack frame.");
|
||||
});
|
||||
try {
|
||||
yield frames.evaluate("foo", { depth: 4 }); // non-existent frame
|
||||
} catch (error) {
|
||||
is(error.message, "No stack frame available.",
|
||||
"Evaluating shouldn't work if the specified frame doesn't exist.");
|
||||
}
|
||||
|
||||
yield resumeDebuggerThenCloseAndFinish(panel);
|
||||
});
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue