From 5f8de423f190bbb79a62f804151bc24824fa32d8 Mon Sep 17 00:00:00 2001 From: "Matt A. Tobin" Date: Fri, 2 Feb 2018 04:16:08 -0500 Subject: Add m-esr52 at 52.6.0 --- devtools/client/debugger/test/.eslintrc.js | 6 + .../addon-source/browser_dbg_addon3/lib/main.js | 13 + .../addon-source/browser_dbg_addon3/package.json | 9 + .../addon-source/browser_dbg_addon4/bootstrap.js | 36 + .../browser_dbg_addon4/chrome.manifest | 1 + .../addon-source/browser_dbg_addon4/install.rdf | 19 + .../addon-source/browser_dbg_addon4/test.jsm | 6 + .../addon-source/browser_dbg_addon4/test.xul | 8 + .../addon-source/browser_dbg_addon4/test2.jsm | 6 + .../addon-source/browser_dbg_addon4/test2.xul | 8 + .../addon-source/browser_dbg_addon4/testxul.js | 4 + .../addon-source/browser_dbg_addon4/testxul2.js | 4 + .../addon-source/browser_dbg_addon5/bootstrap.js | 23 + .../browser_dbg_addon5/chrome.manifest | 1 + .../addon-source/browser_dbg_addon5/install.rdf | 20 + .../addon-source/browser_dbg_addon5/test.jsm | 6 + .../addon-source/browser_dbg_addon5/test.xul | 8 + .../addon-source/browser_dbg_addon5/test2.jsm | 6 + .../addon-source/browser_dbg_addon5/test2.xul | 8 + .../addon-source/browser_dbg_addon5/testxul.js | 4 + .../addon-source/browser_dbg_addon5/testxul2.js | 4 + .../manifest.json | 18 + .../webext-content-script.js | 1 + .../test/mochitest/addon-webext-contentscript.xpi | Bin 0 -> 4648 bytes devtools/client/debugger/test/mochitest/addon1.xpi | Bin 0 -> 5577 bytes devtools/client/debugger/test/mochitest/addon2.xpi | Bin 0 -> 5578 bytes devtools/client/debugger/test/mochitest/addon3.xpi | Bin 0 -> 12718 bytes devtools/client/debugger/test/mochitest/addon4.xpi | Bin 0 -> 7340 bytes devtools/client/debugger/test/mochitest/addon5.xpi | Bin 0 -> 7224 bytes .../client/debugger/test/mochitest/browser.ini | 317 +++++ .../client/debugger/test/mochitest/browser2.ini | 460 +++++++ .../mochitest/browser_dbg_WorkerActor.attach.js | 62 + .../browser_dbg_WorkerActor.attachThread.js | 100 ++ .../browser_dbg_aaa_run_first_leaktest.js | 33 + .../test/mochitest/browser_dbg_addon-console.js | 47 + .../browser_dbg_addon-modules-unpacked.js | 67 + .../test/mochitest/browser_dbg_addon-modules.js | 66 + .../test/mochitest/browser_dbg_addon-panels.js | 49 + .../test/mochitest/browser_dbg_addon-sources.js | 42 + .../browser_dbg_addon-workers-dbg-enabled.js | 41 + .../test/mochitest/browser_dbg_addonactor.js | 95 ++ .../mochitest/browser_dbg_auto-pretty-print-01.js | 117 ++ .../mochitest/browser_dbg_auto-pretty-print-02.js | 126 ++ .../mochitest/browser_dbg_auto-pretty-print-03.js | 58 + .../debugger/test/mochitest/browser_dbg_bfcache.js | 95 ++ .../test/mochitest/browser_dbg_blackboxing-01.js | 57 + .../test/mochitest/browser_dbg_blackboxing-02.js | 60 + .../test/mochitest/browser_dbg_blackboxing-03.js | 65 + .../test/mochitest/browser_dbg_blackboxing-04.js | 65 + .../test/mochitest/browser_dbg_blackboxing-05.js | 74 ++ .../test/mochitest/browser_dbg_blackboxing-06.js | 61 + .../test/mochitest/browser_dbg_blackboxing-07.js | 53 + .../mochitest/browser_dbg_breadcrumbs-access.js | 98 ++ .../test/mochitest/browser_dbg_break-in-anon.js | 40 + .../test/mochitest/browser_dbg_break-on-dom-01.js | 58 + .../test/mochitest/browser_dbg_break-on-dom-02.js | 135 ++ .../test/mochitest/browser_dbg_break-on-dom-03.js | 102 ++ .../test/mochitest/browser_dbg_break-on-dom-04.js | 101 ++ .../test/mochitest/browser_dbg_break-on-dom-05.js | 128 ++ .../test/mochitest/browser_dbg_break-on-dom-06.js | 130 ++ .../test/mochitest/browser_dbg_break-on-dom-07.js | 106 ++ .../test/mochitest/browser_dbg_break-on-dom-08.js | 61 + .../mochitest/browser_dbg_break-on-dom-event-01.js | 225 ++++ .../mochitest/browser_dbg_break-on-dom-event-02.js | 105 ++ .../mochitest/browser_dbg_break-on-dom-event-03.js | 97 ++ .../mochitest/browser_dbg_break-on-next-console.js | 61 + .../test/mochitest/browser_dbg_break-on-next.js | 103 ++ .../test/mochitest/browser_dbg_break-unselected.js | 48 + .../browser_dbg_breakpoints-actual-location.js | 55 + .../browser_dbg_breakpoints-actual-location2.js | 88 ++ ...oints-break-on-last-line-of-script-on-reload.js | 116 ++ .../mochitest/browser_dbg_breakpoints-button-01.js | 55 + .../mochitest/browser_dbg_breakpoints-button-02.js | 64 + ...ser_dbg_breakpoints-condition-thrown-message.js | 107 ++ .../browser_dbg_breakpoints-contextmenu-add.js | 84 ++ .../browser_dbg_breakpoints-contextmenu.js | 252 ++++ .../browser_dbg_breakpoints-disabled-reload.js | 124 ++ .../mochitest/browser_dbg_breakpoints-editor.js | 241 ++++ .../test/mochitest/browser_dbg_breakpoints-eval.js | 47 + .../mochitest/browser_dbg_breakpoints-highlight.js | 90 ++ .../browser_dbg_breakpoints-new-script.js | 92 ++ .../browser_dbg_breakpoints-other-tabs.js | 41 + .../test/mochitest/browser_dbg_breakpoints-pane.js | 238 ++++ .../mochitest/browser_dbg_breakpoints-reload.js | 39 + .../test/mochitest/browser_dbg_bug-896139.js | 48 + .../test/mochitest/browser_dbg_chrome-create.js | 64 + .../test/mochitest/browser_dbg_chrome-debugging.js | 102 ++ .../mochitest/browser_dbg_clean-exit-window.js | 86 ++ .../test/mochitest/browser_dbg_clean-exit.js | 44 + .../mochitest/browser_dbg_closure-inspection.js | 153 +++ .../test/mochitest/browser_dbg_cmd-blackbox.js | 117 ++ .../test/mochitest/browser_dbg_cmd-break.js | 225 ++++ .../debugger/test/mochitest/browser_dbg_cmd-dbg.js | 102 ++ .../browser_dbg_conditional-breakpoints-01.js | 218 ++++ .../browser_dbg_conditional-breakpoints-02.js | 219 ++++ .../browser_dbg_conditional-breakpoints-03.js | 78 ++ .../browser_dbg_conditional-breakpoints-04.js | 52 + .../browser_dbg_conditional-breakpoints-05.js | 141 ++ .../test/mochitest/browser_dbg_console-eval.js | 41 + .../mochitest/browser_dbg_console-named-eval.js | 42 + .../browser_dbg_controller-evaluate-01.js | 106 ++ .../browser_dbg_controller-evaluate-02.js | 78 ++ .../mochitest/browser_dbg_debugger-statement.js | 87 ++ .../mochitest/browser_dbg_editor-contextmenu.js | 68 + .../test/mochitest/browser_dbg_editor-mode.js | 97 ++ .../mochitest/browser_dbg_event-listeners-01.js | 147 +++ .../mochitest/browser_dbg_event-listeners-02.js | 123 ++ .../mochitest/browser_dbg_event-listeners-03.js | 82 ++ .../mochitest/browser_dbg_event-listeners-04.js | 55 + .../test/mochitest/browser_dbg_file-reload.js | 72 ++ .../mochitest/browser_dbg_function-display-name.js | 68 + .../browser_dbg_global-method-override.js | 26 + .../test/mochitest/browser_dbg_globalactor.js | 61 + .../mochitest/browser_dbg_hide-toolbar-buttons.js | 34 + .../test/mochitest/browser_dbg_host-layout.js | 166 +++ .../debugger/test/mochitest/browser_dbg_iframes.js | 72 ++ .../browser_dbg_instruments-pane-collapse.js | 167 +++ ...owser_dbg_instruments-pane-collapse_keyboard.js | 40 + .../test/mochitest/browser_dbg_interrupts.js | 123 ++ .../browser_dbg_jump-to-function-definition.js | 50 + .../test/mochitest/browser_dbg_listaddons.js | 112 ++ .../test/mochitest/browser_dbg_listtabs-01.js | 98 ++ .../test/mochitest/browser_dbg_listtabs-02.js | 219 ++++ .../test/mochitest/browser_dbg_listtabs-03.js | 61 + .../test/mochitest/browser_dbg_listworkers.js | 59 + .../browser_dbg_location-changes-01-simple.js | 60 + .../browser_dbg_location-changes-02-blank.js | 57 + .../browser_dbg_location-changes-03-new.js | 59 + .../browser_dbg_location-changes-04-breakpoint.js | 165 +++ .../test/mochitest/browser_dbg_multiple-windows.js | 165 +++ .../test/mochitest/browser_dbg_navigation.js | 75 ++ .../browser_dbg_no-dangling-breakpoints.js | 25 + .../test/mochitest/browser_dbg_no-page-sources.js | 54 + .../mochitest/browser_dbg_on-pause-highlight.js | 86 ++ .../test/mochitest/browser_dbg_on-pause-raise.js | 120 ++ .../mochitest/browser_dbg_optimized-out-vars.js | 50 + .../test/mochitest/browser_dbg_panel-size.js | 88 ++ .../test/mochitest/browser_dbg_parser-01.js | 33 + .../test/mochitest/browser_dbg_parser-02.js | 30 + .../test/mochitest/browser_dbg_parser-03.js | 79 ++ .../test/mochitest/browser_dbg_parser-04.js | 58 + .../test/mochitest/browser_dbg_parser-05.js | 45 + .../test/mochitest/browser_dbg_parser-06.js | 80 ++ .../test/mochitest/browser_dbg_parser-07.js | 57 + .../test/mochitest/browser_dbg_parser-08.js | 291 +++++ .../test/mochitest/browser_dbg_parser-09.js | 292 +++++ .../test/mochitest/browser_dbg_parser-10.js | 129 ++ .../test/mochitest/browser_dbg_parser-11.js | 41 + .../mochitest/browser_dbg_parser-computed-name.js | 32 + .../browser_dbg_parser-function-defaults.js | 31 + .../browser_dbg_parser-spread-expression.js | 32 + .../browser_dbg_parser-template-strings.js | 29 + .../mochitest/browser_dbg_pause-exceptions-01.js | 246 ++++ .../mochitest/browser_dbg_pause-exceptions-02.js | 204 +++ .../test/mochitest/browser_dbg_pause-no-step.js | 94 ++ .../test/mochitest/browser_dbg_pause-resume.js | 91 ++ .../test/mochitest/browser_dbg_pause-warning.js | 109 ++ .../mochitest/browser_dbg_paused-keybindings.js | 50 + .../test/mochitest/browser_dbg_post-page.js | 53 + .../test/mochitest/browser_dbg_pretty-print-01.js | 52 + .../test/mochitest/browser_dbg_pretty-print-02.js | 41 + .../test/mochitest/browser_dbg_pretty-print-03.js | 40 + .../test/mochitest/browser_dbg_pretty-print-04.js | 50 + .../test/mochitest/browser_dbg_pretty-print-05.js | 66 + .../test/mochitest/browser_dbg_pretty-print-06.js | 80 ++ .../test/mochitest/browser_dbg_pretty-print-07.js | 62 + .../test/mochitest/browser_dbg_pretty-print-08.js | 99 ++ .../test/mochitest/browser_dbg_pretty-print-09.js | 92 ++ .../test/mochitest/browser_dbg_pretty-print-10.js | 48 + .../test/mochitest/browser_dbg_pretty-print-11.js | 65 + .../test/mochitest/browser_dbg_pretty-print-12.js | 51 + .../test/mochitest/browser_dbg_pretty-print-13.js | 53 + .../browser_dbg_pretty-print-on-paused.js | 69 + .../mochitest/browser_dbg_progress-listener-bug.js | 89 ++ .../browser_dbg_promises-allocation-stack.js | 87 ++ ...browser_dbg_promises-chrome-allocation-stack.js | 100 ++ .../browser_dbg_promises-fulfillment-stack.js | 106 ++ .../browser_dbg_promises-rejection-stack.js | 106 ++ .../browser_dbg_reload-preferred-script-02.js | 50 + .../browser_dbg_reload-preferred-script-03.js | 62 + .../mochitest/browser_dbg_reload-same-script.js | 88 ++ .../mochitest/browser_dbg_scripts-switching-01.js | 162 +++ .../mochitest/browser_dbg_scripts-switching-02.js | 163 +++ .../mochitest/browser_dbg_scripts-switching-03.js | 63 + .../browser_dbg_search-autofill-identifier.js | 138 ++ .../test/mochitest/browser_dbg_search-basic-01.js | 330 +++++ .../test/mochitest/browser_dbg_search-basic-02.js | 129 ++ .../test/mochitest/browser_dbg_search-basic-03.js | 123 ++ .../test/mochitest/browser_dbg_search-basic-04.js | 132 ++ .../test/mochitest/browser_dbg_search-global-01.js | 278 ++++ .../test/mochitest/browser_dbg_search-global-02.js | 203 +++ .../test/mochitest/browser_dbg_search-global-03.js | 110 ++ .../test/mochitest/browser_dbg_search-global-04.js | 98 ++ .../test/mochitest/browser_dbg_search-global-05.js | 160 +++ .../test/mochitest/browser_dbg_search-global-06.js | 125 ++ .../mochitest/browser_dbg_search-popup-jank.js | 128 ++ .../mochitest/browser_dbg_search-sources-01.js | 232 ++++ .../mochitest/browser_dbg_search-sources-02.js | 281 ++++ .../mochitest/browser_dbg_search-sources-03.js | 103 ++ .../test/mochitest/browser_dbg_search-symbols.js | 472 +++++++ .../browser_dbg_searchbox-help-popup-01.js | 64 + .../browser_dbg_searchbox-help-popup-02.js | 90 ++ .../test/mochitest/browser_dbg_searchbox-parse.js | 126 ++ .../browser_dbg_server-conditional-bp-01.js | 218 ++++ .../browser_dbg_server-conditional-bp-02.js | 214 ++++ .../browser_dbg_server-conditional-bp-03.js | 73 ++ .../browser_dbg_server-conditional-bp-04.js | 46 + .../browser_dbg_server-conditional-bp-05.js | 134 ++ .../test/mochitest/browser_dbg_source-maps-01.js | 170 +++ .../test/mochitest/browser_dbg_source-maps-02.js | 153 +++ .../test/mochitest/browser_dbg_source-maps-03.js | 88 ++ .../test/mochitest/browser_dbg_source-maps-04.js | 187 +++ .../mochitest/browser_dbg_sources-bookmarklet.js | 53 + .../test/mochitest/browser_dbg_sources-cache.js | 147 +++ .../browser_dbg_sources-contextmenu-01.js | 57 + .../browser_dbg_sources-contextmenu-02.js | 75 ++ .../test/mochitest/browser_dbg_sources-eval-01.js | 44 + .../test/mochitest/browser_dbg_sources-eval-02.js | 55 + .../mochitest/browser_dbg_sources-iframe-reload.js | 35 + .../mochitest/browser_dbg_sources-keybindings.js | 40 + .../test/mochitest/browser_dbg_sources-labels.js | 172 +++ .../test/mochitest/browser_dbg_sources-large.js | 80 ++ .../test/mochitest/browser_dbg_sources-sorting.js | 141 ++ .../browser_dbg_sources-webext-contentscript.js | 63 + .../browser_dbg_split-console-keypress.js | 108 ++ .../browser_dbg_split-console-paused-reload.js | 67 + .../test/mochitest/browser_dbg_stack-01.js | 49 + .../test/mochitest/browser_dbg_stack-02.js | 115 ++ .../test/mochitest/browser_dbg_stack-03.js | 64 + .../test/mochitest/browser_dbg_stack-04.js | 58 + .../test/mochitest/browser_dbg_stack-05.js | 102 ++ .../test/mochitest/browser_dbg_stack-06.js | 92 ++ .../test/mochitest/browser_dbg_stack-07.js | 113 ++ .../mochitest/browser_dbg_stack-contextmenu-01.js | 58 + .../mochitest/browser_dbg_stack-contextmenu-02.js | 58 + .../test/mochitest/browser_dbg_step-out.js | 91 ++ .../test/mochitest/browser_dbg_tabactor-01.js | 65 + .../test/mochitest/browser_dbg_tabactor-02.js | 79 ++ .../browser_dbg_terminate-on-tab-close.js | 34 + .../mochitest/browser_dbg_variables-view-01.js | 132 ++ .../mochitest/browser_dbg_variables-view-02.js | 227 ++++ .../mochitest/browser_dbg_variables-view-03.js | 157 +++ .../mochitest/browser_dbg_variables-view-04.js | 156 +++ .../mochitest/browser_dbg_variables-view-05.js | 234 ++++ .../mochitest/browser_dbg_variables-view-06.js | 125 ++ .../mochitest/browser_dbg_variables-view-07.js | 69 + .../mochitest/browser_dbg_variables-view-08.js | 61 + .../browser_dbg_variables-view-accessibility.js | 557 ++++++++ .../mochitest/browser_dbg_variables-view-data.js | 611 +++++++++ .../browser_dbg_variables-view-edit-cancel.js | 58 + .../browser_dbg_variables-view-edit-click.js | 58 + .../browser_dbg_variables-view-edit-getset-01.js | 300 +++++ .../browser_dbg_variables-view-edit-getset-02.js | 107 ++ .../browser_dbg_variables-view-edit-value.js | 91 ++ .../browser_dbg_variables-view-edit-watch.js | 510 ++++++++ .../browser_dbg_variables-view-filter-01.js | 241 ++++ .../browser_dbg_variables-view-filter-02.js | 249 ++++ .../browser_dbg_variables-view-filter-03.js | 178 +++ .../browser_dbg_variables-view-filter-04.js | 243 ++++ .../browser_dbg_variables-view-filter-05.js | 254 ++++ .../browser_dbg_variables-view-filter-pref.js | 85 ++ .../browser_dbg_variables-view-filter-searchbox.js | 150 +++ ...owser_dbg_variables-view-frame-parameters-01.js | 270 ++++ ...owser_dbg_variables-view-frame-parameters-02.js | 552 ++++++++ ...owser_dbg_variables-view-frame-parameters-03.js | 157 +++ .../browser_dbg_variables-view-frame-with.js | 212 +++ ...wser_dbg_variables-view-frozen-sealed-nonext.js | 93 ++ .../browser_dbg_variables-view-hide-non-enums.js | 111 ++ ...rowser_dbg_variables-view-large-array-buffer.js | 253 ++++ .../browser_dbg_variables-view-map-set.js | 117 ++ .../browser_dbg_variables-view-override-01.js | 240 ++++ .../browser_dbg_variables-view-override-02.js | 75 ++ .../browser_dbg_variables-view-popup-01.js | 67 + .../browser_dbg_variables-view-popup-02.js | 53 + .../browser_dbg_variables-view-popup-03.js | 49 + .../browser_dbg_variables-view-popup-04.js | 38 + .../browser_dbg_variables-view-popup-05.js | 57 + .../browser_dbg_variables-view-popup-06.js | 83 ++ .../browser_dbg_variables-view-popup-07.js | 70 + .../browser_dbg_variables-view-popup-08.js | 75 ++ .../browser_dbg_variables-view-popup-09.js | 39 + .../browser_dbg_variables-view-popup-10.js | 67 + .../browser_dbg_variables-view-popup-11.js | 84 ++ .../browser_dbg_variables-view-popup-12.js | 77 ++ .../browser_dbg_variables-view-popup-13.js | 68 + .../browser_dbg_variables-view-popup-14.js | 55 + .../browser_dbg_variables-view-popup-15.js | 39 + .../browser_dbg_variables-view-popup-16.js | 77 ++ .../browser_dbg_variables-view-popup-17.js | 80 ++ .../browser_dbg_variables-view-reexpand-01.js | 211 +++ .../browser_dbg_variables-view-reexpand-02.js | 226 ++++ .../browser_dbg_variables-view-reexpand-03.js | 120 ++ .../mochitest/browser_dbg_variables-view-webidl.js | 262 ++++ .../mochitest/browser_dbg_watch-expressions-01.js | 227 ++++ .../mochitest/browser_dbg_watch-expressions-02.js | 383 ++++++ .../mochitest/browser_dbg_worker-console-01.js | 21 + .../mochitest/browser_dbg_worker-console-02.js | 58 + .../mochitest/browser_dbg_worker-console-03.js | 46 + .../mochitest/browser_dbg_worker-source-map.js | 89 ++ .../test/mochitest/browser_dbg_worker-window.js | 61 + .../mochitest/code_WorkerActor.attach-worker1.js | 5 + .../mochitest/code_WorkerActor.attach-worker2.js | 5 + .../code_WorkerActor.attachThread-worker.js | 16 + .../test/mochitest/code_binary_search.coffee | 18 + .../debugger/test/mochitest/code_binary_search.js | 29 + .../debugger/test/mochitest/code_binary_search.map | 10 + .../test/mochitest/code_blackboxing_blackboxme.js | 9 + .../test/mochitest/code_blackboxing_one.js | 4 + .../test/mochitest/code_blackboxing_three.js | 4 + .../test/mochitest/code_blackboxing_two.js | 4 + .../mochitest/code_blackboxing_unblackbox.min.js | 1 + ...oints-break-on-last-line-of-script-on-reload.js | 6 + .../test/mochitest/code_breakpoints-other-tabs.js | 4 + .../debugger/test/mochitest/code_bug-896139.js | 8 + .../debugger/test/mochitest/code_frame-script.js | 106 ++ .../test/mochitest/code_function-jump-01.js | 6 + .../test/mochitest/code_function-search-01.js | 42 + .../test/mochitest/code_function-search-02.js | 21 + .../test/mochitest/code_function-search-03.js | 32 + .../test/mochitest/code_listworkers-worker1.js | 3 + .../test/mochitest/code_listworkers-worker2.js | 3 + .../test/mochitest/code_location-changes.js | 7 + .../client/debugger/test/mochitest/code_math.js | 45 + .../client/debugger/test/mochitest/code_math.map | 8 + .../debugger/test/mochitest/code_math.min.js | 2 + .../debugger/test/mochitest/code_math_bogus_map.js | 4 + .../test/mochitest/code_same-line-functions.js | 1 + .../debugger/test/mochitest/code_script-eval.js | 14 + .../test/mochitest/code_script-switching-01.js | 6 + .../test/mochitest/code_script-switching-02.js | 13 + .../debugger/test/mochitest/code_test-editor-mode | 6 + .../client/debugger/test/mochitest/code_ugly-2.js | 1 + .../client/debugger/test/mochitest/code_ugly-3.js | 1 + .../client/debugger/test/mochitest/code_ugly-4.js | 25 + .../client/debugger/test/mochitest/code_ugly-5.js | 14 + .../client/debugger/test/mochitest/code_ugly-6.js | 5 + .../client/debugger/test/mochitest/code_ugly-7.js | 5 + .../client/debugger/test/mochitest/code_ugly-8 | 3 + .../debugger/test/mochitest/code_ugly-8^headers^ | 1 + .../client/debugger/test/mochitest/code_ugly.js | 3 + .../test/mochitest/code_worker-source-map.coffee | 22 + .../test/mochitest/code_worker-source-map.js | 35 + .../test/mochitest/code_worker-source-map.js.map | 10 + .../test/mochitest/code_workeractor-worker.js | 5 + .../mochitest/doc_WorkerActor.attach-tab1.html | 8 + .../mochitest/doc_WorkerActor.attach-tab2.html | 8 + .../doc_WorkerActor.attachThread-tab.html | 8 + .../test/mochitest/doc_auto-pretty-print-01.html | 14 + .../test/mochitest/doc_auto-pretty-print-02.html | 14 + .../debugger/test/mochitest/doc_binary_search.html | 15 + .../debugger/test/mochitest/doc_blackboxing.html | 26 + .../test/mochitest/doc_blackboxing_unblackbox.html | 11 + .../test/mochitest/doc_breakpoint-move.html | 25 + ...nts-break-on-last-line-of-script-on-reload.html | 8 + .../test/mochitest/doc_breakpoints-other-tabs.html | 8 + .../test/mochitest/doc_breakpoints-reload.html | 13 + .../debugger/test/mochitest/doc_bug-896139.html | 18 + .../test/mochitest/doc_closure-optimized-out.html | 34 + .../debugger/test/mochitest/doc_closures.html | 32 + .../debugger/test/mochitest/doc_cmd-break.html | 22 + .../debugger/test/mochitest/doc_cmd-dbg.html | 40 + .../mochitest/doc_conditional-breakpoints.html | 35 + .../test/mochitest/doc_domnode-variables.html | 24 + .../debugger/test/mochitest/doc_editor-mode.html | 20 + .../debugger/test/mochitest/doc_empty-tab-01.html | 14 + .../debugger/test/mochitest/doc_empty-tab-02.html | 14 + .../test/mochitest/doc_event-listeners-01.html | 43 + .../test/mochitest/doc_event-listeners-02.html | 53 + .../test/mochitest/doc_event-listeners-03.html | 63 + .../test/mochitest/doc_event-listeners-04.html | 23 + .../test/mochitest/doc_frame-parameters.html | 37 + .../test/mochitest/doc_function-display-name.html | 31 + .../debugger/test/mochitest/doc_function-jump.html | 17 + .../test/mochitest/doc_function-search.html | 30 + .../test/mochitest/doc_global-method-override.html | 16 + .../debugger/test/mochitest/doc_iframes.html | 15 + .../test/mochitest/doc_included-script.html | 22 + .../mochitest/doc_inline-debugger-statement.html | 21 + .../debugger/test/mochitest/doc_inline-script.html | 25 + .../test/mochitest/doc_large-array-buffer.html | 32 + .../test/mochitest/doc_listworkers-tab.html | 8 + .../debugger/test/mochitest/doc_map-set.html | 42 + .../debugger/test/mochitest/doc_minified.html | 14 + .../test/mochitest/doc_minified_bogus_map.html | 14 + .../test/mochitest/doc_native-event-handler.html | 22 + .../test/mochitest/doc_no-page-sources.html | 11 + .../test/mochitest/doc_pause-exceptions.html | 35 + .../test/mochitest/doc_pretty-print-2.html | 15 + .../test/mochitest/doc_pretty-print-3.html | 8 + .../test/mochitest/doc_pretty-print-on-paused.html | 14 + .../debugger/test/mochitest/doc_pretty-print.html | 8 + .../doc_promise-get-allocation-stack.html | 24 + .../doc_promise-get-fulfillment-stack.html | 24 + .../mochitest/doc_promise-get-rejection-stack.html | 24 + .../debugger/test/mochitest/doc_promise.html | 30 + .../client/debugger/test/mochitest/doc_proxy.html | 39 + .../test/mochitest/doc_random-javascript.html | 15 + .../test/mochitest/doc_recursion-stack.html | 35 + .../test/mochitest/doc_scope-variable-2.html | 30 + .../test/mochitest/doc_scope-variable-3.html | 23 + .../test/mochitest/doc_scope-variable-4.html | 25 + .../test/mochitest/doc_scope-variable.html | 25 + .../test/mochitest/doc_script-bookmarklet.html | 14 + .../debugger/test/mochitest/doc_script-eval.html | 16 + .../test/mochitest/doc_script-switching-01.html | 18 + .../test/mochitest/doc_script-switching-02.html | 18 + .../mochitest/doc_script_webext_contentscript.html | 13 + .../mochitest/doc_split-console-paused-reload.html | 22 + .../test/mochitest/doc_step-many-statements.html | 50 + .../debugger/test/mochitest/doc_step-out.html | 42 + .../test/mochitest/doc_terminate-on-tab-close.html | 20 + .../mochitest/doc_watch-expression-button.html | 31 + .../test/mochitest/doc_watch-expressions.html | 29 + .../mochitest/doc_whitespace-property-names.html | 29 + .../debugger/test/mochitest/doc_with-frame.html | 29 + .../test/mochitest/doc_worker-source-map.html | 18 + devtools/client/debugger/test/mochitest/head.js | 1351 ++++++++++++++++++++ .../debugger/test/mochitest/sjs_post-page.sjs | 16 + .../test/mochitest/sjs_random-javascript.sjs | 11 + .../client/debugger/test/mochitest/testactors.js | 33 + 420 files changed, 34908 insertions(+) create mode 100644 devtools/client/debugger/test/.eslintrc.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/lib/main.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/package.json create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/chrome.manifest create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/install.rdf create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.jsm create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.xul create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test2.jsm create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test2.xul create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/testxul.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/testxul2.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/bootstrap.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/chrome.manifest create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/install.rdf create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/test.jsm create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/test.xul create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/test2.jsm create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/test2.xul create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/testxul.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon5/testxul2.js create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon_webext_contentscript/manifest.json create mode 100644 devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon_webext_contentscript/webext-content-script.js create mode 100644 devtools/client/debugger/test/mochitest/addon-webext-contentscript.xpi create mode 100644 devtools/client/debugger/test/mochitest/addon1.xpi create mode 100644 devtools/client/debugger/test/mochitest/addon2.xpi create mode 100644 devtools/client/debugger/test/mochitest/addon3.xpi create mode 100644 devtools/client/debugger/test/mochitest/addon4.xpi create mode 100644 devtools/client/debugger/test/mochitest/addon5.xpi create mode 100644 devtools/client/debugger/test/mochitest/browser.ini create mode 100644 devtools/client/debugger/test/mochitest/browser2.ini create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_WorkerActor.attach.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_WorkerActor.attachThread.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_aaa_run_first_leaktest.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_addon-console.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_addon-modules-unpacked.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_addon-modules.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_addon-panels.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_addon-sources.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_addon-workers-dbg-enabled.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_addonactor.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_auto-pretty-print-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_auto-pretty-print-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_auto-pretty-print-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_bfcache.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_blackboxing-07.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breadcrumbs-access.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-in-anon.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-07.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-08.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-dom-event-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-next-console.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-on-next.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_break-unselected.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-actual-location.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-actual-location2.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-break-on-last-line-of-script-on-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-button-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-button-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-condition-thrown-message.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-contextmenu-add.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-contextmenu.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-disabled-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-editor.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-eval.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-highlight.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-new-script.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-other-tabs.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-pane.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_breakpoints-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_bug-896139.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_chrome-create.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_chrome-debugging.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_clean-exit-window.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_clean-exit.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_closure-inspection.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_cmd-blackbox.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_cmd-break.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_cmd-dbg.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_conditional-breakpoints-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_conditional-breakpoints-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_conditional-breakpoints-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_conditional-breakpoints-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_conditional-breakpoints-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_console-eval.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_console-named-eval.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_controller-evaluate-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_controller-evaluate-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_debugger-statement.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_editor-contextmenu.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_editor-mode.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_event-listeners-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_file-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_function-display-name.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_global-method-override.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_globalactor.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_hide-toolbar-buttons.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_host-layout.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_iframes.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_instruments-pane-collapse.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_instruments-pane-collapse_keyboard.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_interrupts.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_jump-to-function-definition.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_listaddons.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_listtabs-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_listtabs-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_listtabs-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_listworkers.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_location-changes-01-simple.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_location-changes-02-blank.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_location-changes-03-new.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_location-changes-04-breakpoint.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_multiple-windows.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_navigation.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_no-dangling-breakpoints.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_no-page-sources.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_on-pause-highlight.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_on-pause-raise.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_optimized-out-vars.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_panel-size.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-07.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-08.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-09.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-10.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-computed-name.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-function-defaults.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-spread-expression.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_parser-template-strings.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pause-no-step.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pause-resume.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pause-warning.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_paused-keybindings.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_post-page.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-07.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-08.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-09.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-10.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-11.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-12.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-13.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_pretty-print-on-paused.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_progress-listener-bug.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_promises-allocation-stack.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_promises-chrome-allocation-stack.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_promises-fulfillment-stack.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_promises-rejection-stack.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_reload-preferred-script-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_reload-preferred-script-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_reload-same-script.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_scripts-switching-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_scripts-switching-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_scripts-switching-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-autofill-identifier.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-basic-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-basic-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-basic-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-basic-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-global-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-global-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-global-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-global-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-global-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-global-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-popup-jank.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-sources-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-sources-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-sources-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_search-symbols.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_searchbox-help-popup-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_searchbox-parse.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_server-conditional-bp-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_server-conditional-bp-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_server-conditional-bp-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_server-conditional-bp-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_server-conditional-bp-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_source-maps-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_source-maps-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_source-maps-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_source-maps-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-bookmarklet.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-cache.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-contextmenu-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-eval-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-eval-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-iframe-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-keybindings.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-labels.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-large.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-sorting.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_sources-webext-contentscript.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_split-console-keypress.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_split-console-paused-reload.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-07.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-contextmenu-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_stack-contextmenu-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_step-out.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_tabactor-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_tabactor-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_terminate-on-tab-close.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-07.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-08.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-accessibility.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-data.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-cancel.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-click.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-getset-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-value.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-edit-watch.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-pref.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-filter-searchbox.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-parameters-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frame-with.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-frozen-sealed-nonext.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-hide-non-enums.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-large-array-buffer.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-map-set.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-override-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-override-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-04.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-05.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-06.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-07.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-08.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-09.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-10.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-11.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-12.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-13.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-14.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-15.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-16.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-popup-17.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-reexpand-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_variables-view-webidl.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_watch-expressions-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_watch-expressions-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_worker-console-01.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_worker-console-02.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_worker-console-03.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_worker-source-map.js create mode 100644 devtools/client/debugger/test/mochitest/browser_dbg_worker-window.js create mode 100644 devtools/client/debugger/test/mochitest/code_WorkerActor.attach-worker1.js create mode 100644 devtools/client/debugger/test/mochitest/code_WorkerActor.attach-worker2.js create mode 100644 devtools/client/debugger/test/mochitest/code_WorkerActor.attachThread-worker.js create mode 100644 devtools/client/debugger/test/mochitest/code_binary_search.coffee create mode 100644 devtools/client/debugger/test/mochitest/code_binary_search.js create mode 100644 devtools/client/debugger/test/mochitest/code_binary_search.map create mode 100644 devtools/client/debugger/test/mochitest/code_blackboxing_blackboxme.js create mode 100644 devtools/client/debugger/test/mochitest/code_blackboxing_one.js create mode 100644 devtools/client/debugger/test/mochitest/code_blackboxing_three.js create mode 100644 devtools/client/debugger/test/mochitest/code_blackboxing_two.js create mode 100644 devtools/client/debugger/test/mochitest/code_blackboxing_unblackbox.min.js create mode 100644 devtools/client/debugger/test/mochitest/code_breakpoints-break-on-last-line-of-script-on-reload.js create mode 100644 devtools/client/debugger/test/mochitest/code_breakpoints-other-tabs.js create mode 100644 devtools/client/debugger/test/mochitest/code_bug-896139.js create mode 100644 devtools/client/debugger/test/mochitest/code_frame-script.js create mode 100644 devtools/client/debugger/test/mochitest/code_function-jump-01.js create mode 100644 devtools/client/debugger/test/mochitest/code_function-search-01.js create mode 100644 devtools/client/debugger/test/mochitest/code_function-search-02.js create mode 100644 devtools/client/debugger/test/mochitest/code_function-search-03.js create mode 100644 devtools/client/debugger/test/mochitest/code_listworkers-worker1.js create mode 100644 devtools/client/debugger/test/mochitest/code_listworkers-worker2.js create mode 100644 devtools/client/debugger/test/mochitest/code_location-changes.js create mode 100644 devtools/client/debugger/test/mochitest/code_math.js create mode 100644 devtools/client/debugger/test/mochitest/code_math.map create mode 100644 devtools/client/debugger/test/mochitest/code_math.min.js create mode 100644 devtools/client/debugger/test/mochitest/code_math_bogus_map.js create mode 100644 devtools/client/debugger/test/mochitest/code_same-line-functions.js create mode 100644 devtools/client/debugger/test/mochitest/code_script-eval.js create mode 100644 devtools/client/debugger/test/mochitest/code_script-switching-01.js create mode 100644 devtools/client/debugger/test/mochitest/code_script-switching-02.js create mode 100644 devtools/client/debugger/test/mochitest/code_test-editor-mode create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-2.js create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-3.js create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-4.js create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-5.js create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-6.js create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-7.js create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-8 create mode 100644 devtools/client/debugger/test/mochitest/code_ugly-8^headers^ create mode 100644 devtools/client/debugger/test/mochitest/code_ugly.js create mode 100644 devtools/client/debugger/test/mochitest/code_worker-source-map.coffee create mode 100644 devtools/client/debugger/test/mochitest/code_worker-source-map.js create mode 100644 devtools/client/debugger/test/mochitest/code_worker-source-map.js.map create mode 100644 devtools/client/debugger/test/mochitest/code_workeractor-worker.js create mode 100644 devtools/client/debugger/test/mochitest/doc_WorkerActor.attach-tab1.html create mode 100644 devtools/client/debugger/test/mochitest/doc_WorkerActor.attach-tab2.html create mode 100644 devtools/client/debugger/test/mochitest/doc_WorkerActor.attachThread-tab.html create mode 100644 devtools/client/debugger/test/mochitest/doc_auto-pretty-print-01.html create mode 100644 devtools/client/debugger/test/mochitest/doc_auto-pretty-print-02.html create mode 100644 devtools/client/debugger/test/mochitest/doc_binary_search.html create mode 100644 devtools/client/debugger/test/mochitest/doc_blackboxing.html create mode 100644 devtools/client/debugger/test/mochitest/doc_blackboxing_unblackbox.html create mode 100644 devtools/client/debugger/test/mochitest/doc_breakpoint-move.html create mode 100644 devtools/client/debugger/test/mochitest/doc_breakpoints-break-on-last-line-of-script-on-reload.html create mode 100644 devtools/client/debugger/test/mochitest/doc_breakpoints-other-tabs.html create mode 100644 devtools/client/debugger/test/mochitest/doc_breakpoints-reload.html create mode 100644 devtools/client/debugger/test/mochitest/doc_bug-896139.html create mode 100644 devtools/client/debugger/test/mochitest/doc_closure-optimized-out.html create mode 100644 devtools/client/debugger/test/mochitest/doc_closures.html create mode 100644 devtools/client/debugger/test/mochitest/doc_cmd-break.html create mode 100644 devtools/client/debugger/test/mochitest/doc_cmd-dbg.html create mode 100644 devtools/client/debugger/test/mochitest/doc_conditional-breakpoints.html create mode 100644 devtools/client/debugger/test/mochitest/doc_domnode-variables.html create mode 100644 devtools/client/debugger/test/mochitest/doc_editor-mode.html create mode 100644 devtools/client/debugger/test/mochitest/doc_empty-tab-01.html create mode 100644 devtools/client/debugger/test/mochitest/doc_empty-tab-02.html create mode 100644 devtools/client/debugger/test/mochitest/doc_event-listeners-01.html create mode 100644 devtools/client/debugger/test/mochitest/doc_event-listeners-02.html create mode 100644 devtools/client/debugger/test/mochitest/doc_event-listeners-03.html create mode 100644 devtools/client/debugger/test/mochitest/doc_event-listeners-04.html create mode 100644 devtools/client/debugger/test/mochitest/doc_frame-parameters.html create mode 100644 devtools/client/debugger/test/mochitest/doc_function-display-name.html create mode 100644 devtools/client/debugger/test/mochitest/doc_function-jump.html create mode 100644 devtools/client/debugger/test/mochitest/doc_function-search.html create mode 100644 devtools/client/debugger/test/mochitest/doc_global-method-override.html create mode 100644 devtools/client/debugger/test/mochitest/doc_iframes.html create mode 100644 devtools/client/debugger/test/mochitest/doc_included-script.html create mode 100644 devtools/client/debugger/test/mochitest/doc_inline-debugger-statement.html create mode 100644 devtools/client/debugger/test/mochitest/doc_inline-script.html create mode 100644 devtools/client/debugger/test/mochitest/doc_large-array-buffer.html create mode 100644 devtools/client/debugger/test/mochitest/doc_listworkers-tab.html create mode 100644 devtools/client/debugger/test/mochitest/doc_map-set.html create mode 100644 devtools/client/debugger/test/mochitest/doc_minified.html create mode 100644 devtools/client/debugger/test/mochitest/doc_minified_bogus_map.html create mode 100644 devtools/client/debugger/test/mochitest/doc_native-event-handler.html create mode 100644 devtools/client/debugger/test/mochitest/doc_no-page-sources.html create mode 100644 devtools/client/debugger/test/mochitest/doc_pause-exceptions.html create mode 100644 devtools/client/debugger/test/mochitest/doc_pretty-print-2.html create mode 100644 devtools/client/debugger/test/mochitest/doc_pretty-print-3.html create mode 100644 devtools/client/debugger/test/mochitest/doc_pretty-print-on-paused.html create mode 100644 devtools/client/debugger/test/mochitest/doc_pretty-print.html create mode 100644 devtools/client/debugger/test/mochitest/doc_promise-get-allocation-stack.html create mode 100644 devtools/client/debugger/test/mochitest/doc_promise-get-fulfillment-stack.html create mode 100644 devtools/client/debugger/test/mochitest/doc_promise-get-rejection-stack.html create mode 100644 devtools/client/debugger/test/mochitest/doc_promise.html create mode 100644 devtools/client/debugger/test/mochitest/doc_proxy.html create mode 100644 devtools/client/debugger/test/mochitest/doc_random-javascript.html create mode 100644 devtools/client/debugger/test/mochitest/doc_recursion-stack.html create mode 100644 devtools/client/debugger/test/mochitest/doc_scope-variable-2.html create mode 100644 devtools/client/debugger/test/mochitest/doc_scope-variable-3.html create mode 100644 devtools/client/debugger/test/mochitest/doc_scope-variable-4.html create mode 100644 devtools/client/debugger/test/mochitest/doc_scope-variable.html create mode 100644 devtools/client/debugger/test/mochitest/doc_script-bookmarklet.html create mode 100644 devtools/client/debugger/test/mochitest/doc_script-eval.html create mode 100644 devtools/client/debugger/test/mochitest/doc_script-switching-01.html create mode 100644 devtools/client/debugger/test/mochitest/doc_script-switching-02.html create mode 100644 devtools/client/debugger/test/mochitest/doc_script_webext_contentscript.html create mode 100644 devtools/client/debugger/test/mochitest/doc_split-console-paused-reload.html create mode 100644 devtools/client/debugger/test/mochitest/doc_step-many-statements.html create mode 100644 devtools/client/debugger/test/mochitest/doc_step-out.html create mode 100644 devtools/client/debugger/test/mochitest/doc_terminate-on-tab-close.html create mode 100644 devtools/client/debugger/test/mochitest/doc_watch-expression-button.html create mode 100644 devtools/client/debugger/test/mochitest/doc_watch-expressions.html create mode 100644 devtools/client/debugger/test/mochitest/doc_whitespace-property-names.html create mode 100644 devtools/client/debugger/test/mochitest/doc_with-frame.html create mode 100644 devtools/client/debugger/test/mochitest/doc_worker-source-map.html create mode 100644 devtools/client/debugger/test/mochitest/head.js create mode 100644 devtools/client/debugger/test/mochitest/sjs_post-page.sjs create mode 100644 devtools/client/debugger/test/mochitest/sjs_random-javascript.sjs create mode 100644 devtools/client/debugger/test/mochitest/testactors.js (limited to 'devtools/client/debugger/test') diff --git a/devtools/client/debugger/test/.eslintrc.js b/devtools/client/debugger/test/.eslintrc.js new file mode 100644 index 000000000..8d15a76d9 --- /dev/null +++ b/devtools/client/debugger/test/.eslintrc.js @@ -0,0 +1,6 @@ +"use strict"; + +module.exports = { + // Extend from the shared list of defined globals for mochitests. + "extends": "../../../.eslintrc.mochitests.js" +}; diff --git a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/lib/main.js b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/lib/main.js new file mode 100644 index 000000000..fc00b60a1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/lib/main.js @@ -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); diff --git a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/package.json b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/package.json new file mode 100644 index 000000000..4bf1bed50 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon3/package.json @@ -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" +} diff --git a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js new file mode 100644 index 000000000..e8bb9fcce --- /dev/null +++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/bootstrap.js @@ -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); +} diff --git a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/chrome.manifest b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/chrome.manifest new file mode 100644 index 000000000..ccb88ddf1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/chrome.manifest @@ -0,0 +1 @@ +content browser_dbg_addon4 . diff --git a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/install.rdf b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/install.rdf new file mode 100644 index 000000000..45679ffc9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/install.rdf @@ -0,0 +1,19 @@ + + + + + + browser_dbg_addon4@tests.mozilla.org + 1.0 + Test add-on with JS Modules + true + + + toolkit@mozilla.org + 0 + * + + + + diff --git a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.jsm b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.jsm new file mode 100644 index 000000000..17bebfd8e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.jsm @@ -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 = {}; diff --git a/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.xul b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.xul new file mode 100644 index 000000000..733817ad8 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/addon-source/browser_dbg_addon4/test.xul @@ -0,0 +1,8 @@ + + + + + + ", + "", + "", + "" + ].join("\n"); + let parser = new Parser(); + let parsed = parser.get(source); + + ok(parsed, + "HTML code should be parsed correctly."); + is(parser.errors.length, 0, + "There should be no errors logged when parsing."); + + is(parsed.scriptCount, 3, + "There should be 3 scripts parsed in the parent HTML source."); + + is(parsed.getScriptInfo(0).toSource(), "({start:-1, length:-1, index:-1})", + "There is no script at the beginning of the parent source."); + is(parsed.getScriptInfo(source.length - 1).toSource(), "({start:-1, length:-1, index:-1})", + "There is no script at the end of the parent source."); + + is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:31, length:13, index:0})", + "The first script was located correctly."); + is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13, index:1})", + "The second script was located correctly."); + is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:151, length:13, index:2})", + "The third script was located correctly."); + + is(parsed.getScriptInfo(source.indexOf("let a") - 1).toSource(), "({start:31, length:13, index:0})", + "The left edge of the first script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let b") - 1).toSource(), "({start:85, length:13, index:1})", + "The left edge of the second script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let c") - 1).toSource(), "({start:151, length:13, index:2})", + "The left edge of the third script was interpreted correctly."); + + is(parsed.getScriptInfo(source.indexOf("let a") - 2).toSource(), "({start:-1, length:-1, index:-1})", + "The left outside of the first script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let b") - 2).toSource(), "({start:-1, length:-1, index:-1})", + "The left outside of the second script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let c") - 2).toSource(), "({start:-1, length:-1, index:-1})", + "The left outside of the third script was interpreted correctly."); + + is(parsed.getScriptInfo(source.indexOf("let a") + 12).toSource(), "({start:31, length:13, index:0})", + "The right edge of the first script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let b") + 12).toSource(), "({start:85, length:13, index:1})", + "The right edge of the second script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let c") + 12).toSource(), "({start:151, length:13, index:2})", + "The right edge of the third script was interpreted correctly."); + + is(parsed.getScriptInfo(source.indexOf("let a") + 13).toSource(), "({start:-1, length:-1, index:-1})", + "The right outside of the first script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let b") + 13).toSource(), "({start:-1, length:-1, index:-1})", + "The right outside of the second script was interpreted correctly."); + is(parsed.getScriptInfo(source.indexOf("let c") + 13).toSource(), "({start:-1, length:-1, index:-1})", + "The right outside of the third script was interpreted correctly."); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-04.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-04.js new file mode 100644 index 000000000..b6ae0dfb6 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-04.js @@ -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/ */ + +/** + * Check that faulty JS inside HTML can be separated and identified correctly. + */ + +function test() { + let { Parser } = Cu.import("resource://devtools/shared/Parser.jsm", {}); + + let source = [ + "", + "", + "", + "", + "", + "" + ].join("\n"); + let parser = new Parser(); + // Don't pollute the logs with exceptions that we are going to check anyhow. + parser.logExceptions = false; + let parsed = parser.get(source); + + ok(parsed, + "HTML code should be parsed correctly."); + is(parser.errors.length, 2, + "There should be two errors logged when parsing."); + + is(parser.errors[0].name, "SyntaxError", + "The correct first exception was caught."); + is(parser.errors[0].message, "missing ; before statement", + "The correct first exception was caught."); + + is(parser.errors[1].name, "SyntaxError", + "The correct second exception was caught."); + is(parser.errors[1].message, "missing ; before statement", + "The correct second exception was caught."); + + is(parsed.scriptCount, 1, + "There should be 1 script parsed in the parent HTML source."); + + is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:-1, length:-1, index:-1})", + "The first script shouldn't be considered valid."); + is(parsed.getScriptInfo(source.indexOf("let b")).toSource(), "({start:85, length:13, index:0})", + "The second script was located correctly."); + is(parsed.getScriptInfo(source.indexOf("let c")).toSource(), "({start:-1, length:-1, index:-1})", + "The third script shouldn't be considered valid."); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js new file mode 100644 index 000000000..b34d3952a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-05.js @@ -0,0 +1,45 @@ +/* -*- 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/ */ + +/** + * Check that JS code containing strings that might look like ');", + "a.push('');", + "a.push('');" + ].join("\n"); + let parser = new Parser(); + let parsed = parser.get(source); + + ok(parsed, + "The javascript code should be parsed correctly."); + is(parser.errors.length, 0, + "There should be no errors logged when parsing."); + + is(parsed.scriptCount, 1, + "There should be 1 script parsed in the parent source."); + + is(parsed.getScriptInfo(source.indexOf("let a")).toSource(), "({start:0, length:261, index:0})", + "The script location is correct (1)."); + is(parsed.getScriptInfo(source.indexOf("")).toSource(), "({start:0, length:261, index:0})", + "The script location is correct (3)."); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-06.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-06.js new file mode 100644 index 000000000..4e5583e00 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-06.js @@ -0,0 +1,80 @@ +/* -*- 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/ */ + +/** + * Check that some potentially problematic identifier nodes have the + * right location information attached. + */ + +function test() { + let { Parser, ParserHelpers, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + function verify(source, predicate, [sline, scol], [eline, ecol]) { + let ast = Parser.reflectionAPI.parse(source); + let node = SyntaxTreeVisitor.filter(ast, predicate).pop(); + let loc = ParserHelpers.getNodeLocation(node); + + is(loc.start.toSource(), { line: sline, column: scol }.toSource(), + "The start location was correct for the identifier in: '" + source + "'."); + is(loc.end.toSource(), { line: eline, column: ecol }.toSource(), + "The end location was correct for the identifier in: '" + source + "'."); + } + + // FunctionDeclarations and FunctionExpressions. + + // The location is unavailable for the identifier node "foo". + verify("function foo(){}", e => e.name == "foo", [1, 9], [1, 12]); + verify("\nfunction\nfoo\n(\n)\n{\n}\n", e => e.name == "foo", [3, 0], [3, 3]); + + verify("({bar:function foo(){}})", e => e.name == "foo", [1, 15], [1, 18]); + verify("(\n{\nbar\n:\nfunction\nfoo\n(\n)\n{\n}\n}\n)", e => e.name == "foo", [6, 0], [6, 3]); + + // Just to be sure, check the identifier node "bar" as well. + verify("({bar:function foo(){}})", e => e.name == "bar", [1, 2], [1, 5]); + verify("(\n{\nbar\n:\nfunction\nfoo\n(\n)\n{\n}\n}\n)", e => e.name == "bar", [3, 0], [3, 3]); + + // MemberExpressions. + + // The location is unavailable for the identifier node "bar". + verify("foo.bar", e => e.name == "bar", [1, 4], [1, 7]); + verify("\nfoo\n.\nbar\n", e => e.name == "bar", [4, 0], [4, 3]); + + // Just to be sure, check the identifier node "foo" as well. + verify("foo.bar", e => e.name == "foo", [1, 0], [1, 3]); + verify("\nfoo\n.\nbar\n", e => e.name == "foo", [2, 0], [2, 3]); + + // VariableDeclarator + + // The location is incorrect for the identifier node "foo". + verify("let foo = bar", e => e.name == "foo", [1, 4], [1, 7]); + verify("\nlet\nfoo\n=\nbar\n", e => e.name == "foo", [3, 0], [3, 3]); + + // Just to be sure, check the identifier node "bar" as well. + verify("let foo = bar", e => e.name == "bar", [1, 10], [1, 13]); + verify("\nlet\nfoo\n=\nbar\n", e => e.name == "bar", [5, 0], [5, 3]); + + // Just to be sure, check AssignmentExpreesions as well. + verify("foo = bar", e => e.name == "foo", [1, 0], [1, 3]); + verify("\nfoo\n=\nbar\n", e => e.name == "foo", [2, 0], [2, 3]); + verify("foo = bar", e => e.name == "bar", [1, 6], [1, 9]); + verify("\nfoo\n=\nbar\n", e => e.name == "bar", [4, 0], [4, 3]); + + // LabeledStatement, BreakStatement and ContinueStatement, because it's 1968 again + + verify("foo: bar", e => e.name == "foo", [1, 0], [1, 3]); + verify("\nfoo\n:\nbar\n", e => e.name == "foo", [2, 0], [2, 3]); + + verify("foo: for(;;) break foo", e => e.name == "foo", [1, 19], [1, 22]); + verify("\nfoo\n:\nfor(\n;\n;\n)\nbreak\nfoo\n", e => e.name == "foo", [9, 0], [9, 3]); + + verify("foo: bar", e => e.name == "foo", [1, 0], [1, 3]); + verify("\nfoo\n:\nbar\n", e => e.name == "foo", [2, 0], [2, 3]); + + verify("foo: for(;;) continue foo", e => e.name == "foo", [1, 22], [1, 25]); + verify("\nfoo\n:\nfor(\n;\n;\n)\ncontinue\nfoo\n", e => e.name == "foo", [9, 0], [9, 3]); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-07.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-07.js new file mode 100644 index 000000000..bea913a9e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-07.js @@ -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/ */ + +/** + * Check that nodes with locaiton information attached can be properly + * verified for containing lines and columns. + */ + +function test() { + let { ParserHelpers } = Cu.import("resource://devtools/shared/Parser.jsm", {}); + + let node1 = { loc: { + start: { line: 1, column: 10 }, + end: { line: 10, column: 1 } + }}; + let node2 = { loc: { + start: { line: 1, column: 10 }, + end: { line: 1, column: 20 } + }}; + + ok(ParserHelpers.nodeContainsLine(node1, 1), "1st check."); + ok(ParserHelpers.nodeContainsLine(node1, 5), "2nd check."); + ok(ParserHelpers.nodeContainsLine(node1, 10), "3rd check."); + + ok(!ParserHelpers.nodeContainsLine(node1, 0), "4th check."); + ok(!ParserHelpers.nodeContainsLine(node1, 11), "5th check."); + + ok(ParserHelpers.nodeContainsLine(node2, 1), "6th check."); + ok(!ParserHelpers.nodeContainsLine(node2, 0), "7th check."); + ok(!ParserHelpers.nodeContainsLine(node2, 2), "8th check."); + + ok(!ParserHelpers.nodeContainsPoint(node1, 1, 10), "9th check."); + ok(!ParserHelpers.nodeContainsPoint(node1, 10, 1), "10th check."); + + ok(!ParserHelpers.nodeContainsPoint(node1, 0, 10), "11th check."); + ok(!ParserHelpers.nodeContainsPoint(node1, 11, 1), "12th check."); + + ok(!ParserHelpers.nodeContainsPoint(node1, 1, 9), "13th check."); + ok(!ParserHelpers.nodeContainsPoint(node1, 10, 2), "14th check."); + + ok(ParserHelpers.nodeContainsPoint(node2, 1, 10), "15th check."); + ok(ParserHelpers.nodeContainsPoint(node2, 1, 15), "16th check."); + ok(ParserHelpers.nodeContainsPoint(node2, 1, 20), "17th check."); + + ok(!ParserHelpers.nodeContainsPoint(node2, 0, 10), "18th check."); + ok(!ParserHelpers.nodeContainsPoint(node2, 2, 20), "19th check."); + + ok(!ParserHelpers.nodeContainsPoint(node2, 0, 9), "20th check."); + ok(!ParserHelpers.nodeContainsPoint(node2, 2, 21), "21th check."); + + ok(!ParserHelpers.nodeContainsPoint(node2, 1, 9), "22th check."); + ok(!ParserHelpers.nodeContainsPoint(node2, 1, 21), "23th check."); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-08.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-08.js new file mode 100644 index 000000000..624f3c293 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-08.js @@ -0,0 +1,291 @@ +/* -*- 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 inferring anonymous function information is done correctly. + */ + +function test() { + let { Parser, ParserHelpers, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + function verify(source, predicate, details) { + let { name, chain } = details; + let [[sline, scol], [eline, ecol]] = details.loc; + let ast = Parser.reflectionAPI.parse(source); + let node = SyntaxTreeVisitor.filter(ast, predicate).pop(); + let info = ParserHelpers.inferFunctionExpressionInfo(node); + + is(info.name, name, + "The function expression assignment property name is correct."); + is(chain ? info.chain.toSource() : info.chain, chain ? chain.toSource() : chain, + "The function expression assignment property chain is correct."); + is(info.loc.start.toSource(), { line: sline, column: scol }.toSource(), + "The start location was correct for the identifier in: '" + source + "'."); + is(info.loc.end.toSource(), { line: eline, column: ecol }.toSource(), + "The end location was correct for the identifier in: '" + source + "'."); + } + + // VariableDeclarator + + verify("var foo=function(){}", e => e.type == "FunctionExpression", { + name: "foo", + chain: null, + loc: [[1, 4], [1, 7]] + }); + verify("\nvar\nfoo\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", { + name: "foo", + chain: null, + loc: [[3, 0], [3, 3]] + }); + + // AssignmentExpression + + verify("foo=function(){}", e => e.type == "FunctionExpression", + { name: "foo", chain: [], loc: [[1, 0], [1, 3]] }); + + verify("\nfoo\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", + { name: "foo", chain: [], loc: [[2, 0], [2, 3]] }); + + verify("foo.bar=function(){}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 0], [1, 7]] }); + + verify("\nfoo.bar\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[2, 0], [2, 7]] }); + + verify("this.foo=function(){}", e => e.type == "FunctionExpression", + { name: "foo", chain: ["this"], loc: [[1, 0], [1, 8]] }); + + verify("\nthis.foo\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", + { name: "foo", chain: ["this"], loc: [[2, 0], [2, 8]] }); + + verify("this.foo.bar=function(){}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[1, 0], [1, 12]] }); + + verify("\nthis.foo.bar\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[2, 0], [2, 12]] }); + + verify("foo.this.bar=function(){}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo", "this"], loc: [[1, 0], [1, 12]] }); + + verify("\nfoo.this.bar\n=\nfunction\n(\n)\n{\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo", "this"], loc: [[2, 0], [2, 12]] }); + + // ObjectExpression + + verify("({foo:function(){}})", e => e.type == "FunctionExpression", + { name: "foo", chain: [], loc: [[1, 2], [1, 5]] }); + + verify("(\n{\nfoo\n:\nfunction\n(\n)\n{\n}\n}\n)", e => e.type == "FunctionExpression", + { name: "foo", chain: [], loc: [[3, 0], [3, 3]] }); + + verify("({foo:{bar:function(){}}})", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 7], [1, 10]] }); + + verify("(\n{\nfoo\n:\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n}\n)", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[6, 0], [6, 3]] }); + + // AssignmentExpression + ObjectExpression + + verify("foo={bar:function(){}}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 5], [1, 8]] }); + + verify("\nfoo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[5, 0], [5, 3]] }); + + verify("foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[1, 10], [1, 13]] }); + + verify("\nfoo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.foo={bar:function(){}}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["nested", "foo"], loc: [[1, 12], [1, 15]] }); + + verify("\nnested.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["nested", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("nested.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", + { name: "baz", chain: ["nested", "foo", "bar"], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["nested", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.foo={bar:function(){}}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[1, 10], [1, 13]] }); + + verify("\nthis.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("this.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", + { name: "baz", chain: ["this", "foo", "bar"], loc: [[1, 15], [1, 18]] }); + + verify("\nthis.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["this", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.nested.foo={bar:function(){}}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["this", "nested", "foo"], loc: [[1, 17], [1, 20]] }); + + verify("\nthis.nested.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["this", "nested", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("this.nested.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", + { name: "baz", chain: ["this", "nested", "foo", "bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nthis.nested.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["this", "nested", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.this.foo={bar:function(){}}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["nested", "this", "foo"], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.this.foo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["nested", "this", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("nested.this.foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", + { name: "baz", chain: ["nested", "this", "foo", "bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nnested.this.foo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["nested", "this", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + // VariableDeclarator + AssignmentExpression + ObjectExpression + + verify("let foo={bar:function(){}}", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 9], [1, 12]] }); + + verify("\nlet\nfoo\n=\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["foo"], loc: [[6, 0], [6, 3]] }); + + verify("let foo={bar:{baz:function(){}}}", e => e.type == "FunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[1, 14], [1, 17]] }); + + verify("\nlet\nfoo\n=\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[9, 0], [9, 3]] }); + + // New/CallExpression + AssignmentExpression + ObjectExpression + + verify("foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[1, 5], [1, 8]] }); + + verify("\nfoo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 10], [1, 13]] }); + + verify("\nfoo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[1, 12], [1, 15]] }); + + verify("\nnested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[1, 10], [1, 13]] }); + + verify("\nthis.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 15], [1, 18]] }); + + verify("\nthis.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[1, 17], [1, 20]] }); + + verify("\nthis.nested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("this.nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nthis.nested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.this.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.this.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("nested.this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nnested.this.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + // New/CallExpression + VariableDeclarator + AssignmentExpression + ObjectExpression + + verify("let target=foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 16], [1, 19]] }); + + verify("\nlet\ntarget=\nfoo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 21], [1, 24]] }); + + verify("\nlet\ntarget=\nfoo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 23], [1, 26]] }); + + verify("\nlet\ntarget=\nnested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 28], [1, 31]] }); + + verify("\nlet\ntarget=\nnested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=this.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 21], [1, 24]] }); + + verify("\nlet\ntarget=\nthis.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 26], [1, 29]] }); + + verify("\nlet\ntarget=\nthis.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=this.nested.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 28], [1, 31]] }); + + verify("\nlet\ntarget=\nthis.nested.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=this.nested.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 33], [1, 36]] }); + + verify("\nlet\ntarget=\nthis.nested.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=nested.this.foo({bar:function(){}})", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 28], [1, 31]] }); + + verify("\nlet\ntarget=\nnested.this.foo\n(\n{\nbar\n:\nfunction\n(\n)\n{\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=nested.this.foo({bar:{baz:function(){}}})", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 33], [1, 36]] }); + + verify("\nlet\ntarget=\nnested.this.foo\n(\n{\nbar\n:\n{\nbaz\n:\nfunction\n(\n)\n{\n}\n}\n}\n)\n", e => e.type == "FunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-09.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-09.js new file mode 100644 index 000000000..2e0ac3b89 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-09.js @@ -0,0 +1,292 @@ +/* -*- 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 inferring anonymous function information is done correctly + * from arrow expressions. + */ + +function test() { + let { Parser, ParserHelpers, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + function verify(source, predicate, details) { + let { name, chain } = details; + let [[sline, scol], [eline, ecol]] = details.loc; + let ast = Parser.reflectionAPI.parse(source); + let node = SyntaxTreeVisitor.filter(ast, predicate).pop(); + let info = ParserHelpers.inferFunctionExpressionInfo(node); + + is(info.name, name, + "The function expression assignment property name is correct."); + is(chain ? info.chain.toSource() : info.chain, chain ? chain.toSource() : chain, + "The function expression assignment property chain is correct."); + is(info.loc.start.toSource(), { line: sline, column: scol }.toSource(), + "The start location was correct for the identifier in: '" + source + "'."); + is(info.loc.end.toSource(), { line: eline, column: ecol }.toSource(), + "The end location was correct for the identifier in: '" + source + "'."); + } + + // VariableDeclarator + + verify("var foo=()=>{}", e => e.type == "ArrowFunctionExpression", { + name: "foo", + chain: null, + loc: [[1, 4], [1, 7]] + }); + verify("\nvar\nfoo\n=\n(\n)=>\n{\n}\n", e => e.type == "ArrowFunctionExpression", { + name: "foo", + chain: null, + loc: [[3, 0], [3, 3]] + }); + + // AssignmentExpression + + verify("foo=()=>{}", e => e.type == "ArrowFunctionExpression", + { name: "foo", chain: [], loc: [[1, 0], [1, 3]] }); + + verify("\nfoo\n=\n(\n)=>\n{\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "foo", chain: [], loc: [[2, 0], [2, 3]] }); + + verify("foo.bar=()=>{}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 0], [1, 7]] }); + + verify("\nfoo.bar\n=\n(\n)=>\n{\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[2, 0], [2, 7]] }); + + verify("this.foo=()=>{}", e => e.type == "ArrowFunctionExpression", + { name: "foo", chain: ["this"], loc: [[1, 0], [1, 8]] }); + + verify("\nthis.foo\n=\n(\n)=>\n{\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "foo", chain: ["this"], loc: [[2, 0], [2, 8]] }); + + verify("this.foo.bar=()=>{}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[1, 0], [1, 12]] }); + + verify("\nthis.foo.bar\n=\n(\n)=>\n{\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[2, 0], [2, 12]] }); + + verify("foo.this.bar=()=>{}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo", "this"], loc: [[1, 0], [1, 12]] }); + + verify("\nfoo.this.bar\n=\n(\n)=>\n{\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo", "this"], loc: [[2, 0], [2, 12]] }); + + // ObjectExpression + + verify("({foo:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "foo", chain: [], loc: [[1, 2], [1, 5]] }); + + verify("(\n{\nfoo\n:\n(\n)=>\n{\n}\n}\n)", e => e.type == "ArrowFunctionExpression", + { name: "foo", chain: [], loc: [[3, 0], [3, 3]] }); + + verify("({foo:{bar:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 7], [1, 10]] }); + + verify("(\n{\nfoo\n:\n{\nbar\n:\n(\n)=>\n{\n}\n}\n}\n)", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[6, 0], [6, 3]] }); + + // AssignmentExpression + ObjectExpression + + verify("foo={bar:()=>{}}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 5], [1, 8]] }); + + verify("\nfoo\n=\n{\nbar\n:\n(\n)=>\n{\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[5, 0], [5, 3]] }); + + verify("foo={bar:{baz:()=>{}}}", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[1, 10], [1, 13]] }); + + verify("\nfoo\n=\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.foo={bar:()=>{}}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["nested", "foo"], loc: [[1, 12], [1, 15]] }); + + verify("\nnested.foo\n=\n{\nbar\n:\n(\n)=>\n{\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["nested", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("nested.foo={bar:{baz:()=>{}}}", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["nested", "foo", "bar"], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.foo\n=\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["nested", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.foo={bar:()=>{}}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[1, 10], [1, 13]] }); + + verify("\nthis.foo\n=\n{\nbar\n:\n(\n)=>\n{\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["this", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("this.foo={bar:{baz:()=>{}}}", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["this", "foo", "bar"], loc: [[1, 15], [1, 18]] }); + + verify("\nthis.foo\n=\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["this", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.nested.foo={bar:()=>{}}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["this", "nested", "foo"], loc: [[1, 17], [1, 20]] }); + + verify("\nthis.nested.foo\n=\n{\nbar\n:\n(\n)=>\n{\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["this", "nested", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("this.nested.foo={bar:{baz:()=>{}}}", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["this", "nested", "foo", "bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nthis.nested.foo\n=\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["this", "nested", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.this.foo={bar:()=>{}}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["nested", "this", "foo"], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.this.foo\n=\n{\nbar\n:\n(\n)=>\n{\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["nested", "this", "foo"], loc: [[5, 0], [5, 3]] }); + + verify("nested.this.foo={bar:{baz:()=>{}}}", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["nested", "this", "foo", "bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nnested.this.foo\n=\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["nested", "this", "foo", "bar"], loc: [[8, 0], [8, 3]] }); + + // VariableDeclarator + AssignmentExpression + ObjectExpression + + verify("let foo={bar:()=>{}}", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[1, 9], [1, 12]] }); + + verify("\nlet\nfoo\n=\n{\nbar\n:\n(\n)=>\n{\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["foo"], loc: [[6, 0], [6, 3]] }); + + verify("let foo={bar:{baz:()=>{}}}", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[1, 14], [1, 17]] }); + + verify("\nlet\nfoo\n=\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["foo", "bar"], loc: [[9, 0], [9, 3]] }); + + // New/CallExpression + AssignmentExpression + ObjectExpression + + verify("foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[1, 5], [1, 8]] }); + + verify("\nfoo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 10], [1, 13]] }); + + verify("\nfoo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[1, 12], [1, 15]] }); + + verify("\nnested.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("nested.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[1, 10], [1, 13]] }); + + verify("\nthis.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("this.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 15], [1, 18]] }); + + verify("\nthis.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("this.nested.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[1, 17], [1, 20]] }); + + verify("\nthis.nested.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("this.nested.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nthis.nested.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + verify("nested.this.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[1, 17], [1, 20]] }); + + verify("\nnested.this.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: [], loc: [[5, 0], [5, 3]] }); + + verify("nested.this.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[1, 22], [1, 25]] }); + + verify("\nnested.this.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["bar"], loc: [[8, 0], [8, 3]] }); + + // New/CallExpression + VariableDeclarator + AssignmentExpression + ObjectExpression + + verify("let target=foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 16], [1, 19]] }); + + verify("\nlet\ntarget=\nfoo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 21], [1, 24]] }); + + verify("\nlet\ntarget=\nfoo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=nested.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 23], [1, 26]] }); + + verify("\nlet\ntarget=\nnested.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=nested.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 28], [1, 31]] }); + + verify("\nlet\ntarget=\nnested.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=this.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 21], [1, 24]] }); + + verify("\nlet\ntarget=\nthis.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=this.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 26], [1, 29]] }); + + verify("\nlet\ntarget=\nthis.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=this.nested.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 28], [1, 31]] }); + + verify("\nlet\ntarget=\nthis.nested.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=this.nested.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 33], [1, 36]] }); + + verify("\nlet\ntarget=\nthis.nested.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + verify("let target=nested.this.foo({bar:()=>{}})", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[1, 28], [1, 31]] }); + + verify("\nlet\ntarget=\nnested.this.foo\n(\n{\nbar\n:\n(\n)=>\n{\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "bar", chain: ["target"], loc: [[7, 0], [7, 3]] }); + + verify("let target=nested.this.foo({bar:{baz:()=>{}}})", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[1, 33], [1, 36]] }); + + verify("\nlet\ntarget=\nnested.this.foo\n(\n{\nbar\n:\n{\nbaz\n:\n(\n)=>\n{\n}\n}\n}\n)\n", e => e.type == "ArrowFunctionExpression", + { name: "baz", chain: ["target", "bar"], loc: [[10, 0], [10, 3]] }); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-10.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-10.js new file mode 100644 index 000000000..d340f9f9c --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-10.js @@ -0,0 +1,129 @@ +/* -*- 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 creating an evaluation string for certain nodes works properly. + */ + +function test() { + let { Parser, ParserHelpers, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + function verify(source, predicate, string) { + let ast = Parser.reflectionAPI.parse(source); + let node = SyntaxTreeVisitor.filter(ast, predicate).pop(); + let info = ParserHelpers.getIdentifierEvalString(node); + is(info, string, "The identifier evaluation string is correct."); + } + + // Indentifier or Literal + + verify("foo", e => e.type == "Identifier", "foo"); + verify("undefined", e => e.type == "Identifier", "undefined"); + verify("null", e => e.type == "Literal", "null"); + verify("42", e => e.type == "Literal", "42"); + verify("true", e => e.type == "Literal", "true"); + verify("\"nasu\"", e => e.type == "Literal", "\"nasu\""); + + // MemberExpression or ThisExpression + + verify("this", e => e.type == "ThisExpression", "this"); + verify("foo.bar", e => e.name == "foo", "foo"); + verify("foo.bar", e => e.name == "bar", "foo.bar"); + + // MemberExpression + ThisExpression + + verify("this.foo.bar", e => e.type == "ThisExpression", "this"); + verify("this.foo.bar", e => e.name == "foo", "this.foo"); + verify("this.foo.bar", e => e.name == "bar", "this.foo.bar"); + + verify("foo.this.bar", e => e.name == "foo", "foo"); + verify("foo.this.bar", e => e.name == "this", "foo.this"); + verify("foo.this.bar", e => e.name == "bar", "foo.this.bar"); + + // ObjectExpression + VariableDeclarator + + verify("let foo={bar:baz}", e => e.name == "baz", "baz"); + verify("let foo={bar:undefined}", e => e.name == "undefined", "undefined"); + verify("let foo={bar:null}", e => e.type == "Literal", "null"); + verify("let foo={bar:42}", e => e.type == "Literal", "42"); + verify("let foo={bar:true}", e => e.type == "Literal", "true"); + verify("let foo={bar:\"nasu\"}", e => e.type == "Literal", "\"nasu\""); + verify("let foo={bar:this}", e => e.type == "ThisExpression", "this"); + + verify("let foo={bar:{nested:baz}}", e => e.name == "baz", "baz"); + verify("let foo={bar:{nested:undefined}}", e => e.name == "undefined", "undefined"); + verify("let foo={bar:{nested:null}}", e => e.type == "Literal", "null"); + verify("let foo={bar:{nested:42}}", e => e.type == "Literal", "42"); + verify("let foo={bar:{nested:true}}", e => e.type == "Literal", "true"); + verify("let foo={bar:{nested:\"nasu\"}}", e => e.type == "Literal", "\"nasu\""); + verify("let foo={bar:{nested:this}}", e => e.type == "ThisExpression", "this"); + + verify("let foo={bar:baz}", e => e.name == "bar", "foo.bar"); + verify("let foo={bar:baz}", e => e.name == "foo", "foo"); + + verify("let foo={bar:{nested:baz}}", e => e.name == "nested", "foo.bar.nested"); + verify("let foo={bar:{nested:baz}}", e => e.name == "bar", "foo.bar"); + verify("let foo={bar:{nested:baz}}", e => e.name == "foo", "foo"); + + // ObjectExpression + MemberExpression + + verify("parent.foo={bar:baz}", e => e.name == "bar", "parent.foo.bar"); + verify("parent.foo={bar:baz}", e => e.name == "foo", "parent.foo"); + verify("parent.foo={bar:baz}", e => e.name == "parent", "parent"); + + verify("parent.foo={bar:{nested:baz}}", e => e.name == "nested", "parent.foo.bar.nested"); + verify("parent.foo={bar:{nested:baz}}", e => e.name == "bar", "parent.foo.bar"); + verify("parent.foo={bar:{nested:baz}}", e => e.name == "foo", "parent.foo"); + verify("parent.foo={bar:{nested:baz}}", e => e.name == "parent", "parent"); + + verify("this.foo={bar:{nested:baz}}", e => e.name == "nested", "this.foo.bar.nested"); + verify("this.foo={bar:{nested:baz}}", e => e.name == "bar", "this.foo.bar"); + verify("this.foo={bar:{nested:baz}}", e => e.name == "foo", "this.foo"); + verify("this.foo={bar:{nested:baz}}", e => e.type == "ThisExpression", "this"); + + verify("this.parent.foo={bar:{nested:baz}}", e => e.name == "nested", "this.parent.foo.bar.nested"); + verify("this.parent.foo={bar:{nested:baz}}", e => e.name == "bar", "this.parent.foo.bar"); + verify("this.parent.foo={bar:{nested:baz}}", e => e.name == "foo", "this.parent.foo"); + verify("this.parent.foo={bar:{nested:baz}}", e => e.name == "parent", "this.parent"); + verify("this.parent.foo={bar:{nested:baz}}", e => e.type == "ThisExpression", "this"); + + verify("parent.this.foo={bar:{nested:baz}}", e => e.name == "nested", "parent.this.foo.bar.nested"); + verify("parent.this.foo={bar:{nested:baz}}", e => e.name == "bar", "parent.this.foo.bar"); + verify("parent.this.foo={bar:{nested:baz}}", e => e.name == "foo", "parent.this.foo"); + verify("parent.this.foo={bar:{nested:baz}}", e => e.name == "this", "parent.this"); + verify("parent.this.foo={bar:{nested:baz}}", e => e.name == "parent", "parent"); + + // FunctionExpression + + verify("function foo(){}", e => e.name == "foo", "foo"); + verify("var foo=function(){}", e => e.name == "foo", "foo"); + verify("var foo=function bar(){}", e => e.name == "bar", "bar"); + + // New/CallExpression + + verify("foo()", e => e.name == "foo", "foo"); + verify("new foo()", e => e.name == "foo", "foo"); + + verify("foo(bar)", e => e.name == "bar", "bar"); + verify("foo(bar, baz)", e => e.name == "baz", "baz"); + verify("foo(undefined)", e => e.name == "undefined", "undefined"); + verify("foo(null)", e => e.type == "Literal", "null"); + verify("foo(42)", e => e.type == "Literal", "42"); + verify("foo(true)", e => e.type == "Literal", "true"); + verify("foo(\"nasu\")", e => e.type == "Literal", "\"nasu\""); + verify("foo(this)", e => e.type == "ThisExpression", "this"); + + // New/CallExpression + ObjectExpression + MemberExpression + + verify("fun(this.parent.foo={bar:{nested:baz}})", e => e.name == "nested", "this.parent.foo.bar.nested"); + verify("fun(this.parent.foo={bar:{nested:baz}})", e => e.name == "bar", "this.parent.foo.bar"); + verify("fun(this.parent.foo={bar:{nested:baz}})", e => e.name == "foo", "this.parent.foo"); + verify("fun(this.parent.foo={bar:{nested:baz}})", e => e.name == "parent", "this.parent"); + verify("fun(this.parent.foo={bar:{nested:baz}})", e => e.type == "ThisExpression", "this"); + verify("fun(this.parent.foo={bar:{nested:baz}})", e => e.name == "fun", "fun"); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js new file mode 100644 index 000000000..ee2b4c89d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-11.js @@ -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/ */ + +/** + * Checks if self-closing ', + ].join("\n"); + let parser = new Parser(); + let parsed = parser.get(source); + + is(parser.errors.length, 0, + "There should be no errors logged when parsing."); + is(parsed.scriptCount, 5, + "There should be 5 scripts parsed in the parent HTML source."); + + is(parsed.getScriptInfo(source.indexOf("foo.js\"/>") + 1).toSource(), "({start:-1, length:-1, index:-1})", + "the first script is empty"); + is(parsed.getScriptInfo(source.indexOf("baz.js\"/>") + 1).toSource(), "({start:-1, length:-1, index:-1})", + "the second script is empty"); + is(parsed.getScriptInfo(source.indexOf("foobar.js\"/>") + 1).toSource(), "({start:-1, length:-1, index:-1})", + "the third script is empty"); + + is(parsed.getScriptInfo(source.indexOf("hello third!")).toSource(), "({start:-1, length:-1, index:-1})", + "Inline script on self-closing tag not considered a script"); + is(parsed.getScriptInfo(source.indexOf("hello fourth")).toSource(), "({start:267, length:14, index:4})", + "The fourth script was located correctly."); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-computed-name.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-computed-name.js new file mode 100644 index 000000000..085f9781b --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-computed-name.js @@ -0,0 +1,32 @@ +/* -*- 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 template strings are correctly processed. + */ + +"use strict"; + +function test() { + let { Parser, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + let ast = Parser.reflectionAPI.parse("({ [i]: 1 })"); + let nodes = SyntaxTreeVisitor.filter(ast, e => e.type == "ComputedName"); + ok(nodes && nodes.length === 1, "Found the ComputedName node"); + + let name = nodes[0].name; + ok(name, "The ComputedName node has a name property"); + is(name.type, "Identifier", "The name has a correct type"); + is(name.name, "i", "The name has a correct name"); + + let identNodes = SyntaxTreeVisitor.filter(ast, e => e.type == "Identifier"); + ok(identNodes && identNodes.length === 1, "Found the Identifier node"); + + is(identNodes[0].type, "Identifier", "The identifier has a correct type"); + is(identNodes[0].name, "i", "The identifier has a correct name"); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-function-defaults.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-function-defaults.js new file mode 100644 index 000000000..55fac4055 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-function-defaults.js @@ -0,0 +1,31 @@ +/* -*- 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 function default arguments are correctly processed. + */ + +"use strict"; + +function test() { + let { Parser, ParserHelpers, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + function verify(source, predicate, string) { + let ast = Parser.reflectionAPI.parse(source); + let node = SyntaxTreeVisitor.filter(ast, predicate).pop(); + let info = ParserHelpers.getIdentifierEvalString(node); + is(info, string, "The identifier evaluation string is correct."); + } + + // FunctionDeclaration + verify("function foo(a, b='b') {}", e => e.type == "Literal", "\"b\""); + // FunctionExpression + verify("let foo=function(a, b='b') {}", e => e.type == "Literal", "\"b\""); + // ArrowFunctionExpression + verify("let foo=(a, b='b')=> {}", e => e.type == "Literal", "\"b\""); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-spread-expression.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-spread-expression.js new file mode 100644 index 000000000..4b7d93d2f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-spread-expression.js @@ -0,0 +1,32 @@ +/* -*- 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 spread expressions work both in arrays and function calls. + */ + +"use strict"; + +function test() { + let { Parser, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + const SCRIPTS = ["[...a]", "foo(...a)"]; + + for (let script of SCRIPTS) { + info(`Testing spread expression in '${script}'`); + let ast = Parser.reflectionAPI.parse(script); + let nodes = SyntaxTreeVisitor.filter(ast, + e => e.type == "SpreadExpression"); + ok(nodes && nodes.length === 1, "Found the SpreadExpression node"); + + let expr = nodes[0].expression; + ok(expr, "The SpreadExpression node has the sub-expression"); + is(expr.type, "Identifier", "The sub-expression is an Identifier"); + is(expr.name, "a", "The sub-expression identifier has a correct name"); + } + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_parser-template-strings.js b/devtools/client/debugger/test/mochitest/browser_dbg_parser-template-strings.js new file mode 100644 index 000000000..6ee271137 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_parser-template-strings.js @@ -0,0 +1,29 @@ +/* -*- 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 template strings are correctly processed. + */ + +"use strict"; + +function test() { + let { Parser, SyntaxTreeVisitor } = + Cu.import("resource://devtools/shared/Parser.jsm", {}); + + let ast = Parser.reflectionAPI.parse("`foo${i}bar`"); + let nodes = SyntaxTreeVisitor.filter(ast, e => e.type == "TemplateLiteral"); + ok(nodes && nodes.length === 1, "Found the TemplateLiteral node"); + + let elements = nodes[0].elements; + ok(elements, "The TemplateLiteral node has elements"); + is(elements.length, 3, "There are 3 elements in the literal"); + + ["Literal", "Identifier", "Literal"].forEach((type, i) => { + is(elements[i].type, type, `Element at index ${i} is '${type}'`); + }); + + finish(); +} diff --git a/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js new file mode 100644 index 000000000..92cd7e4bc --- /dev/null +++ b/devtools/client/debugger/test/mochitest/browser_dbg_pause-exceptions-01.js @@ -0,0 +1,246 @@ +/* -*- 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 pausing on exceptions works. + */ + +const TAB_URL = EXAMPLE_URL + "doc_pause-exceptions.html"; + +var gTab, gPanel, gDebugger; +var gFrames, gVariables, gPrefs, gOptions; + +function test() { + requestLongerTimeout(2); + let options = { + source: TAB_URL, + line: 1 + }; + initDebugger(TAB_URL, options).then(([aTab,, aPanel]) => { + gTab = aTab; + gPanel = aPanel; + gDebugger = gPanel.panelWin; + gFrames = gDebugger.DebuggerView.StackFrames; + gVariables = gDebugger.DebuggerView.Variables; + gPrefs = gDebugger.Prefs; + gOptions = gDebugger.DebuggerView.Options; + + is(gPrefs.pauseOnExceptions, false, + "The pause-on-exceptions pref should be disabled by default."); + isnot(gOptions._pauseOnExceptionsItem.getAttribute("checked"), "true", + "The pause-on-exceptions menu item should not be checked."); + + testPauseOnExceptionsDisabled() + .then(enablePauseOnExceptions) + .then(disableIgnoreCaughtExceptions) + .then(testPauseOnExceptionsEnabled) + .then(disablePauseOnExceptions) + .then(enableIgnoreCaughtExceptions) + .then(() => closeDebuggerAndFinish(gPanel)) + .then(null, aError => { + ok(false, "Got an error: " + aError.message + "\n" + aError.stack); + }); + }); +} + +function testPauseOnExceptionsDisabled() { + let finished = waitForCaretAndScopes(gPanel, 26).then(() => { + info("Testing disabled pause-on-exceptions."); + + is(gDebugger.gThreadClient.state, "paused", + "Should only be getting stack frames while paused (1)."); + ok(isCaretPos(gPanel, 26), + "Should be paused on the debugger statement (1)."); + + let innerScope = gVariables.getScopeAtIndex(0); + let innerNodes = innerScope.target.querySelector(".variables-view-element-details").childNodes; + + is(gFrames.itemCount, 1, + "Should have one frame."); + is(gVariables._store.length, 4, + "Should have four scopes."); + + is(innerNodes[0].querySelector(".name").getAttribute("value"), "this", + "Should have the right property name for 'this'."); + is(innerNodes[0].querySelector(".value").getAttribute("value"), " + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_inline-debugger-statement.html b/devtools/client/debugger/test/mochitest/doc_inline-debugger-statement.html new file mode 100644 index 000000000..406e9d9da --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_inline-debugger-statement.html @@ -0,0 +1,21 @@ + + + + + + + Debugger test page + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_inline-script.html b/devtools/client/debugger/test/mochitest/doc_inline-script.html new file mode 100644 index 000000000..d071cc084 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_inline-script.html @@ -0,0 +1,25 @@ + + + + + + + Debugger test page + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_large-array-buffer.html b/devtools/client/debugger/test/mochitest/doc_large-array-buffer.html new file mode 100644 index 000000000..25b1b4d4e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_large-array-buffer.html @@ -0,0 +1,32 @@ + + + + + + + Debugger test page + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_listworkers-tab.html b/devtools/client/debugger/test/mochitest/doc_listworkers-tab.html new file mode 100644 index 000000000..62ab9be7d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_listworkers-tab.html @@ -0,0 +1,8 @@ + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_map-set.html b/devtools/client/debugger/test/mochitest/doc_map-set.html new file mode 100644 index 000000000..7c2c624e1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_map-set.html @@ -0,0 +1,42 @@ + + + + + + + Debugger test page for Maps and Sets + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_minified.html b/devtools/client/debugger/test/mochitest/doc_minified.html new file mode 100644 index 000000000..b229e079f --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_minified.html @@ -0,0 +1,14 @@ + + + + + + + Debugger test page + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_minified_bogus_map.html b/devtools/client/debugger/test/mochitest/doc_minified_bogus_map.html new file mode 100644 index 000000000..d6670a7e1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_minified_bogus_map.html @@ -0,0 +1,14 @@ + + + + + + + Debugger test page + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_native-event-handler.html b/devtools/client/debugger/test/mochitest/doc_native-event-handler.html new file mode 100644 index 000000000..cd2a656bf --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_native-event-handler.html @@ -0,0 +1,22 @@ + + + + + + A video element with native event handlers + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_no-page-sources.html b/devtools/client/debugger/test/mochitest/doc_no-page-sources.html new file mode 100644 index 000000000..5131578ad --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_no-page-sources.html @@ -0,0 +1,11 @@ + + + + + + This page has no sources + + + + \ No newline at end of file diff --git a/devtools/client/debugger/test/mochitest/doc_pause-exceptions.html b/devtools/client/debugger/test/mochitest/doc_pause-exceptions.html new file mode 100644 index 000000000..7766fb49d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_pause-exceptions.html @@ -0,0 +1,35 @@ + + + + + + + Debugger test page + + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_pretty-print-2.html b/devtools/client/debugger/test/mochitest/doc_pretty-print-2.html new file mode 100644 index 000000000..509f57d6b --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_pretty-print-2.html @@ -0,0 +1,15 @@ + + + + + Debugger Pretty Printing Test Page + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_pretty-print-3.html b/devtools/client/debugger/test/mochitest/doc_pretty-print-3.html new file mode 100644 index 000000000..6192642f3 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_pretty-print-3.html @@ -0,0 +1,8 @@ + + + + + Debugger Pretty Printing Test Page + + diff --git a/devtools/client/debugger/test/mochitest/doc_pretty-print-on-paused.html b/devtools/client/debugger/test/mochitest/doc_pretty-print-on-paused.html new file mode 100644 index 000000000..a431d0898 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_pretty-print-on-paused.html @@ -0,0 +1,14 @@ + + + + + + + Pretty printing when debugger is paused Test Page + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_pretty-print.html b/devtools/client/debugger/test/mochitest/doc_pretty-print.html new file mode 100644 index 000000000..dcf595a8d --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_pretty-print.html @@ -0,0 +1,8 @@ + + + + + Debugger Pretty Printing Test Page + + diff --git a/devtools/client/debugger/test/mochitest/doc_promise-get-allocation-stack.html b/devtools/client/debugger/test/mochitest/doc_promise-get-allocation-stack.html new file mode 100644 index 000000000..48546c967 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_promise-get-allocation-stack.html @@ -0,0 +1,24 @@ + + + + + + + Promise test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_promise-get-fulfillment-stack.html b/devtools/client/debugger/test/mochitest/doc_promise-get-fulfillment-stack.html new file mode 100644 index 000000000..0b311a69a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_promise-get-fulfillment-stack.html @@ -0,0 +1,24 @@ + + + + + + + Promise test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_promise-get-rejection-stack.html b/devtools/client/debugger/test/mochitest/doc_promise-get-rejection-stack.html new file mode 100644 index 000000000..9fe203595 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_promise-get-rejection-stack.html @@ -0,0 +1,24 @@ + + + + + + + Promise test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_promise.html b/devtools/client/debugger/test/mochitest/doc_promise.html new file mode 100644 index 000000000..fe6c1d807 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_promise.html @@ -0,0 +1,30 @@ + + + + + + + Debugger + Promise test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_proxy.html b/devtools/client/debugger/test/mochitest/doc_proxy.html new file mode 100644 index 000000000..e2f35104a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_proxy.html @@ -0,0 +1,39 @@ + + + + + + + Debugger + Proxy test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_random-javascript.html b/devtools/client/debugger/test/mochitest/doc_random-javascript.html new file mode 100644 index 000000000..69269e409 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_random-javascript.html @@ -0,0 +1,15 @@ + + + + + + + Debugger test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_recursion-stack.html b/devtools/client/debugger/test/mochitest/doc_recursion-stack.html new file mode 100644 index 000000000..d68fb1d18 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_recursion-stack.html @@ -0,0 +1,35 @@ + + + + + + + Debugger test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_scope-variable-2.html b/devtools/client/debugger/test/mochitest/doc_scope-variable-2.html new file mode 100644 index 000000000..afbfd166a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_scope-variable-2.html @@ -0,0 +1,30 @@ + + + + + + + Debugger test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_scope-variable-3.html b/devtools/client/debugger/test/mochitest/doc_scope-variable-3.html new file mode 100644 index 000000000..fcd45cc0a --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_scope-variable-3.html @@ -0,0 +1,23 @@ + + + + + + + Debugger test page + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_scope-variable-4.html b/devtools/client/debugger/test/mochitest/doc_scope-variable-4.html new file mode 100644 index 000000000..17b0e3b10 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_scope-variable-4.html @@ -0,0 +1,25 @@ + + + + + + + Debugger test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_scope-variable.html b/devtools/client/debugger/test/mochitest/doc_scope-variable.html new file mode 100644 index 000000000..3fa28fab9 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_scope-variable.html @@ -0,0 +1,25 @@ + + + + + + + Debugger test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_script-bookmarklet.html b/devtools/client/debugger/test/mochitest/doc_script-bookmarklet.html new file mode 100644 index 000000000..922010062 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_script-bookmarklet.html @@ -0,0 +1,14 @@ + + + + + + + Debugger test page + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_script-eval.html b/devtools/client/debugger/test/mochitest/doc_script-eval.html new file mode 100644 index 000000000..7e3f253bb --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_script-eval.html @@ -0,0 +1,16 @@ + + + + + + + Debugger test page + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_script-switching-01.html b/devtools/client/debugger/test/mochitest/doc_script-switching-01.html new file mode 100644 index 000000000..afb4484b5 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_script-switching-01.html @@ -0,0 +1,18 @@ + + + + + + + Debugger test page + + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_script-switching-02.html b/devtools/client/debugger/test/mochitest/doc_script-switching-02.html new file mode 100644 index 000000000..cceeea2c8 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_script-switching-02.html @@ -0,0 +1,18 @@ + + + + + + + Debugger test page + + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_script_webext_contentscript.html b/devtools/client/debugger/test/mochitest/doc_script_webext_contentscript.html new file mode 100644 index 000000000..8e88997db --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_script_webext_contentscript.html @@ -0,0 +1,13 @@ + + + + + + + Debugger test page + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_split-console-paused-reload.html b/devtools/client/debugger/test/mochitest/doc_split-console-paused-reload.html new file mode 100644 index 000000000..113c53468 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_split-console-paused-reload.html @@ -0,0 +1,22 @@ + + + + + + + Test page for opening a split-console when execution is paused + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_step-many-statements.html b/devtools/client/debugger/test/mochitest/doc_step-many-statements.html new file mode 100644 index 000000000..edd0e2882 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_step-many-statements.html @@ -0,0 +1,50 @@ + + + + + + + Debugger test page + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_step-out.html b/devtools/client/debugger/test/mochitest/doc_step-out.html new file mode 100644 index 000000000..89eda2be1 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_step-out.html @@ -0,0 +1,42 @@ + + + + + + + Debugger test page + + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_terminate-on-tab-close.html b/devtools/client/debugger/test/mochitest/doc_terminate-on-tab-close.html new file mode 100644 index 000000000..2101b3103 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_terminate-on-tab-close.html @@ -0,0 +1,20 @@ + + + + + + + Debugger test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_watch-expression-button.html b/devtools/client/debugger/test/mochitest/doc_watch-expression-button.html new file mode 100644 index 000000000..a4a5be26e --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_watch-expression-button.html @@ -0,0 +1,31 @@ + + + + + + + Debugger test page + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_watch-expressions.html b/devtools/client/debugger/test/mochitest/doc_watch-expressions.html new file mode 100644 index 000000000..487b5a5a5 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_watch-expressions.html @@ -0,0 +1,29 @@ + + + + + + + Debugger test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_whitespace-property-names.html b/devtools/client/debugger/test/mochitest/doc_whitespace-property-names.html new file mode 100644 index 000000000..6479a5978 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_whitespace-property-names.html @@ -0,0 +1,29 @@ + + + + + + + Debugger + Whitespace property name test page + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_with-frame.html b/devtools/client/debugger/test/mochitest/doc_with-frame.html new file mode 100644 index 000000000..8fa202b18 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_with-frame.html @@ -0,0 +1,29 @@ + + + + + + + Debugger test page + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/doc_worker-source-map.html b/devtools/client/debugger/test/mochitest/doc_worker-source-map.html new file mode 100644 index 000000000..20a14e351 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/doc_worker-source-map.html @@ -0,0 +1,18 @@ + + + + + + + + + diff --git a/devtools/client/debugger/test/mochitest/head.js b/devtools/client/debugger/test/mochitest/head.js new file mode 100644 index 000000000..1f9d38b82 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/head.js @@ -0,0 +1,1351 @@ +/* -*- 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"; + +// shared-head.js handles imports, constants, and utility functions +Services.scriptloader.loadSubScript("chrome://mochitests/content/browser/devtools/client/framework/test/shared-head.js", this); + +// Disable logging for faster test runs. Set this pref to true if you want to +// debug a test in your try runs. Both the debugger server and frontend will +// be affected by this pref. +var gEnableLogging = Services.prefs.getBoolPref("devtools.debugger.log"); +Services.prefs.setBoolPref("devtools.debugger.log", false); + +var { BrowserToolboxProcess } = Cu.import("resource://devtools/client/framework/ToolboxProcess.jsm", {}); +var { DebuggerServer } = require("devtools/server/main"); +var { DebuggerClient, ObjectClient } = require("devtools/shared/client/main"); +var { AddonManager } = Cu.import("resource://gre/modules/AddonManager.jsm", {}); +var EventEmitter = require("devtools/shared/event-emitter"); +var { Toolbox } = require("devtools/client/framework/toolbox"); + +const chromeRegistry = Cc["@mozilla.org/chrome/chrome-registry;1"].getService(Ci.nsIChromeRegistry); + +// Override promise with deprecated-sync-thenables +promise = Cu.import("resource://devtools/shared/deprecated-sync-thenables.js", {}).Promise; + +const EXAMPLE_URL = "http://example.com/browser/devtools/client/debugger/test/mochitest/"; +const FRAME_SCRIPT_URL = getRootDirectory(gTestPath) + "code_frame-script.js"; +const CHROME_URL = "chrome://mochitests/content/browser/devtools/client/debugger/test/mochitest/"; +const CHROME_URI = Services.io.newURI(CHROME_URL, null, null); + +Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false); + +registerCleanupFunction(function* () { + Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend"); + + info("finish() was called, cleaning up..."); + Services.prefs.setBoolPref("devtools.debugger.log", gEnableLogging); + + while (gBrowser && gBrowser.tabs && gBrowser.tabs.length > 1) { + info("Destroying toolbox."); + let target = TargetFactory.forTab(gBrowser.selectedTab); + yield gDevTools.closeToolbox(target); + + info("Removing tab."); + gBrowser.removeCurrentTab(); + } + + // Properly shut down the server to avoid memory leaks. + DebuggerServer.destroy(); + + // Debugger tests use a lot of memory, so force a GC to help fragmentation. + info("Forcing GC after debugger test."); + Cu.forceGC(); +}); + +// Import the GCLI test helper +var testDir = gTestPath.substr(0, gTestPath.lastIndexOf("/")); +testDir = testDir.replace(/\/\//g, "/"); +testDir = testDir.replace("chrome:/mochitest", "chrome://mochitest"); +var helpersjs = testDir + "/../../../commandline/test/helpers.js"; +Services.scriptloader.loadSubScript(helpersjs, this); + +function addWindow(aUrl) { + info("Adding window: " + aUrl); + return promise.resolve(getChromeWindow(window.open(aUrl))); +} + +function getChromeWindow(aWindow) { + return aWindow + .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIWebNavigation) + .QueryInterface(Ci.nsIDocShellTreeItem).rootTreeItem + .QueryInterface(Ci.nsIInterfaceRequestor).getInterface(Ci.nsIDOMWindow); +} + +// Override addTab/removeTab as defined by shared-head, since these have +// an extra window parameter and add a frame script +this.addTab = function addTab(aUrl, aWindow) { + info("Adding tab: " + aUrl); + + let deferred = promise.defer(); + let targetWindow = aWindow || window; + let targetBrowser = targetWindow.gBrowser; + + targetWindow.focus(); + let tab = targetBrowser.selectedTab = targetBrowser.addTab(aUrl); + let linkedBrowser = tab.linkedBrowser; + + info("Loading frame script with url " + FRAME_SCRIPT_URL + "."); + linkedBrowser.messageManager.loadFrameScript(FRAME_SCRIPT_URL, false); + + BrowserTestUtils.browserLoaded(linkedBrowser) + .then(function () { + info("Tab added and finished loading: " + aUrl); + deferred.resolve(tab); + }); + + return deferred.promise; +}; + +this.removeTab = function removeTab(aTab, aWindow) { + info("Removing tab."); + + let deferred = promise.defer(); + let targetWindow = aWindow || window; + let targetBrowser = targetWindow.gBrowser; + let tabContainer = targetBrowser.tabContainer; + + tabContainer.addEventListener("TabClose", function onClose(aEvent) { + tabContainer.removeEventListener("TabClose", onClose, false); + + info("Tab removed and finished closing."); + deferred.resolve(); + }, false); + + targetBrowser.removeTab(aTab); + return deferred.promise; +}; + +function getAddonURIFromPath(aPath) { + let chromeURI = Services.io.newURI(aPath, null, CHROME_URI); + return chromeRegistry.convertChromeURL(chromeURI).QueryInterface(Ci.nsIFileURL); +} + +function getTemporaryAddonURLFromPath(aPath) { + return getAddonURIFromPath(aPath).spec; +} + +function addTemporaryAddon(aPath) { + let addonFile = getAddonURIFromPath(aPath).file; + info("Installing addon: " + addonFile.path); + + return AddonManager.installTemporaryAddon(addonFile); +} + +function removeAddon(aAddon) { + info("Removing addon."); + + let deferred = promise.defer(); + + let listener = { + onUninstalled: function (aUninstalledAddon) { + if (aUninstalledAddon != aAddon) { + return; + } + AddonManager.removeAddonListener(listener); + deferred.resolve(); + } + }; + AddonManager.addAddonListener(listener); + aAddon.uninstall(); + + return deferred.promise; +} + +function getTabActorForUrl(aClient, aUrl) { + let deferred = promise.defer(); + + aClient.listTabs(aResponse => { + let tabActor = aResponse.tabs.filter(aGrip => aGrip.url == aUrl).pop(); + deferred.resolve(tabActor); + }); + + return deferred.promise; +} + +function getAddonActorForId(aClient, aAddonId) { + info("Get addon actor for ID: " + aAddonId); + let deferred = promise.defer(); + + aClient.listAddons(aResponse => { + let addonActor = aResponse.addons.filter(aGrip => aGrip.id == aAddonId).pop(); + info("got addon actor for ID: " + aAddonId); + deferred.resolve(addonActor); + }); + + return deferred.promise; +} + +function attachTabActorForUrl(aClient, aUrl) { + let deferred = promise.defer(); + + getTabActorForUrl(aClient, aUrl).then(aGrip => { + aClient.attachTab(aGrip.actor, aResponse => { + deferred.resolve([aGrip, aResponse]); + }); + }); + + return deferred.promise; +} + +function attachThreadActorForUrl(aClient, aUrl) { + let deferred = promise.defer(); + + attachTabActorForUrl(aClient, aUrl).then(([aGrip, aResponse]) => { + aClient.attachThread(aResponse.threadActor, (aResponse, aThreadClient) => { + aThreadClient.resume(aResponse => { + deferred.resolve(aThreadClient); + }); + }); + }); + + return deferred.promise; +} + +function once(aTarget, aEventName, aUseCapture = false) { + info("Waiting for event: '" + aEventName + "' on " + aTarget + "."); + + let deferred = promise.defer(); + + for (let [add, remove] of [ + ["addEventListener", "removeEventListener"], + ["addListener", "removeListener"], + ["on", "off"] + ]) { + if ((add in aTarget) && (remove in aTarget)) { + aTarget[add](aEventName, function onEvent(...aArgs) { + aTarget[remove](aEventName, onEvent, aUseCapture); + deferred.resolve.apply(deferred, aArgs); + }, aUseCapture); + break; + } + } + + return deferred.promise; +} + +function waitForTick() { + let deferred = promise.defer(); + executeSoon(deferred.resolve); + return deferred.promise; +} + +function waitForTime(aDelay) { + let deferred = promise.defer(); + setTimeout(deferred.resolve, aDelay); + return deferred.promise; +} + +function waitForSourceLoaded(aPanel, aUrl) { + let { Sources } = aPanel.panelWin.DebuggerView; + let isLoaded = Sources.items.some(item => + item.attachment.source.url === aUrl); + if (isLoaded) { + info("The correct source has been loaded."); + return promise.resolve(null); + } else { + return waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.NEW_SOURCE).then(() => { + // Wait for it to be loaded in the UI and appear into Sources.items. + return waitForTick(); + }).then(() => { + return waitForSourceLoaded(aPanel, aUrl); + }); + } + +} + +function waitForSourceShown(aPanel, aUrl) { + return waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.SOURCE_SHOWN).then(aSource => { + let sourceUrl = aSource.url || aSource.introductionUrl; + info("Source shown: " + sourceUrl); + + if (!sourceUrl.includes(aUrl)) { + return waitForSourceShown(aPanel, aUrl); + } else { + ok(true, "The correct source has been shown."); + } + }); +} + +function waitForEditorLocationSet(aPanel) { + return waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.EDITOR_LOCATION_SET); +} + +function ensureSourceIs(aPanel, aUrlOrSource, aWaitFlag = false) { + let sources = aPanel.panelWin.DebuggerView.Sources; + + if (sources.selectedValue === aUrlOrSource || + (sources.selectedItem && + sources.selectedItem.attachment.source.url.includes(aUrlOrSource))) { + ok(true, "Expected source is shown: " + aUrlOrSource); + return promise.resolve(null); + } + if (aWaitFlag) { + return waitForSourceShown(aPanel, aUrlOrSource); + } + ok(false, "Expected source was not already shown: " + aUrlOrSource); + return promise.reject(null); +} + +function waitForCaretUpdated(aPanel, aLine, aCol = 1) { + return waitForEditorEvents(aPanel, "cursorActivity").then(() => { + let cursor = aPanel.panelWin.DebuggerView.editor.getCursor(); + info("Caret updated: " + (cursor.line + 1) + ", " + (cursor.ch + 1)); + + if (!isCaretPos(aPanel, aLine, aCol)) { + return waitForCaretUpdated(aPanel, aLine, aCol); + } else { + ok(true, "The correct caret position has been set."); + } + }); +} + +function ensureCaretAt(aPanel, aLine, aCol = 1, aWaitFlag = false) { + if (isCaretPos(aPanel, aLine, aCol)) { + ok(true, "Expected caret position is set: " + aLine + "," + aCol); + return promise.resolve(null); + } + if (aWaitFlag) { + return waitForCaretUpdated(aPanel, aLine, aCol); + } + ok(false, "Expected caret position was not already set: " + aLine + "," + aCol); + return promise.reject(null); +} + +function isCaretPos(aPanel, aLine, aCol = 1) { + let editor = aPanel.panelWin.DebuggerView.editor; + let cursor = editor.getCursor(); + + // Source editor starts counting line and column numbers from 0. + info("Current editor caret position: " + (cursor.line + 1) + ", " + (cursor.ch + 1)); + return cursor.line == (aLine - 1) && cursor.ch == (aCol - 1); +} + +function isDebugPos(aPanel, aLine) { + let editor = aPanel.panelWin.DebuggerView.editor; + let location = editor.getDebugLocation(); + + // Source editor starts counting line and column numbers from 0. + info("Current editor debug position: " + (location + 1)); + return location != null && editor.hasLineClass(aLine - 1, "debug-line"); +} + +function isEditorSel(aPanel, [start, end]) { + let editor = aPanel.panelWin.DebuggerView.editor; + let range = { + start: editor.getOffset(editor.getCursor("start")), + end: editor.getOffset(editor.getCursor()) + }; + + // Source editor starts counting line and column numbers from 0. + info("Current editor selection: " + (range.start + 1) + ", " + (range.end + 1)); + return range.start == (start - 1) && range.end == (end - 1); +} + +function waitForSourceAndCaret(aPanel, aUrl, aLine, aCol) { + return promise.all([ + waitForSourceShown(aPanel, aUrl), + waitForCaretUpdated(aPanel, aLine, aCol) + ]); +} + +function waitForCaretAndScopes(aPanel, aLine, aCol) { + return promise.all([ + waitForCaretUpdated(aPanel, aLine, aCol), + waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.FETCHED_SCOPES) + ]); +} + +function waitForSourceAndCaretAndScopes(aPanel, aUrl, aLine, aCol) { + return promise.all([ + waitForSourceAndCaret(aPanel, aUrl, aLine, aCol), + waitForDebuggerEvents(aPanel, aPanel.panelWin.EVENTS.FETCHED_SCOPES) + ]); +} + +function waitForDebuggerEvents(aPanel, aEventName, aEventRepeat = 1) { + info("Waiting for debugger event: '" + aEventName + "' to fire: " + aEventRepeat + " time(s)."); + + let deferred = promise.defer(); + let panelWin = aPanel.panelWin; + let count = 0; + + panelWin.on(aEventName, function onEvent(aEventName, ...aArgs) { + info("Debugger event '" + aEventName + "' fired: " + (++count) + " time(s)."); + + if (count == aEventRepeat) { + ok(true, "Enough '" + aEventName + "' panel events have been fired."); + panelWin.off(aEventName, onEvent); + deferred.resolve.apply(deferred, aArgs); + } + }); + + return deferred.promise; +} + +function waitForEditorEvents(aPanel, aEventName, aEventRepeat = 1) { + info("Waiting for editor event: '" + aEventName + "' to fire: " + aEventRepeat + " time(s)."); + + let deferred = promise.defer(); + let editor = aPanel.panelWin.DebuggerView.editor; + let count = 0; + + editor.on(aEventName, function onEvent(...aArgs) { + info("Editor event '" + aEventName + "' fired: " + (++count) + " time(s)."); + + if (count == aEventRepeat) { + ok(true, "Enough '" + aEventName + "' editor events have been fired."); + editor.off(aEventName, onEvent); + deferred.resolve.apply(deferred, aArgs); + } + }); + + return deferred.promise; +} + +function waitForThreadEvents(aPanel, aEventName, aEventRepeat = 1) { + info("Waiting for thread event: '" + aEventName + "' to fire: " + aEventRepeat + " time(s)."); + + let deferred = promise.defer(); + let thread = aPanel.panelWin.gThreadClient; + let count = 0; + + thread.addListener(aEventName, function onEvent(aEventName, ...aArgs) { + info("Thread event '" + aEventName + "' fired: " + (++count) + " time(s)."); + + if (count == aEventRepeat) { + ok(true, "Enough '" + aEventName + "' thread events have been fired."); + thread.removeListener(aEventName, onEvent); + deferred.resolve.apply(deferred, aArgs); + } + }); + + return deferred.promise; +} + +function waitForClientEvents(aPanel, aEventName, aEventRepeat = 1) { + info("Waiting for client event: '" + aEventName + "' to fire: " + aEventRepeat + " time(s)."); + + let deferred = promise.defer(); + let client = aPanel.panelWin.gClient; + let count = 0; + + client.addListener(aEventName, function onEvent(aEventName, ...aArgs) { + info("Thread event '" + aEventName + "' fired: " + (++count) + " time(s)."); + + if (count == aEventRepeat) { + ok(true, "Enough '" + aEventName + "' thread events have been fired."); + client.removeListener(aEventName, onEvent); + deferred.resolve.apply(deferred, aArgs); + } + }); + + return deferred.promise; +} + +function ensureThreadClientState(aPanel, aState) { + let thread = aPanel.panelWin.gThreadClient; + let state = thread.state; + + info("Thread is: '" + state + "'."); + + if (state == aState) { + return promise.resolve(null); + } else { + return waitForThreadEvents(aPanel, aState); + } +} + +function reload(aPanel, aUrl) { + let activeTab = aPanel.panelWin.DebuggerController._target.activeTab; + aUrl ? activeTab.navigateTo(aUrl) : activeTab.reload(); +} + +function navigateActiveTabTo(aPanel, aUrl, aWaitForEventName, aEventRepeat) { + let finished = waitForDebuggerEvents(aPanel, aWaitForEventName, aEventRepeat); + reload(aPanel, aUrl); + return finished; +} + +function navigateActiveTabInHistory(aPanel, aDirection, aWaitForEventName, aEventRepeat) { + let finished = waitForDebuggerEvents(aPanel, aWaitForEventName, aEventRepeat); + content.history[aDirection](); + return finished; +} + +function reloadActiveTab(aPanel, aWaitForEventName, aEventRepeat) { + return navigateActiveTabTo(aPanel, null, aWaitForEventName, aEventRepeat); +} + +function clearText(aElement) { + info("Clearing text..."); + aElement.focus(); + aElement.value = ""; +} + +function setText(aElement, aText) { + clearText(aElement); + info("Setting text: " + aText); + aElement.value = aText; +} + +function typeText(aElement, aText) { + info("Typing text: " + aText); + aElement.focus(); + EventUtils.sendString(aText, aElement.ownerDocument.defaultView); +} + +function backspaceText(aElement, aTimes) { + info("Pressing backspace " + aTimes + " times."); + for (let i = 0; i < aTimes; i++) { + aElement.focus(); + EventUtils.sendKey("BACK_SPACE", aElement.ownerDocument.defaultView); + } +} + +function getTab(aTarget, aWindow) { + if (aTarget instanceof XULElement) { + return promise.resolve(aTarget); + } else { + return addTab(aTarget, aWindow); + } +} + +function getSources(aClient) { + info("Getting sources."); + + let deferred = promise.defer(); + + aClient.getSources((packet) => { + deferred.resolve(packet.sources); + }); + + return deferred.promise; +} + +/** + * Optionaly open a new tab and then open the debugger panel. + * The returned promise resolves only one the panel is fully set. + + * @param {String|xul:tab} urlOrTab + * If a string, consider it as the url of the tab to open before opening the + * debugger panel. + * Otherwise, if a , do nothing, but open the debugger panel against + * the given tab. + * @param {Object} options + * Set of optional arguments: + * - {String} source + * If given, assert the default loaded source once the debugger is loaded. + * This string can be partial to only match a part of the source name. + * If null, do not expect any source and skip SOURCE_SHOWN wait. + * - {Number} line + * If given, wait for the caret to be set on a precise line + * + * @return {Promise} + * Resolves once debugger panel is fully set according to the given options. + */ +let initDebugger = Task.async(function*(urlOrTab, options) { + let { window, source, line } = options || {}; + info("Initializing a debugger panel."); + + let tab, url; + if (urlOrTab instanceof XULElement) { + // `urlOrTab` Is a Tab. + tab = urlOrTab; + } else { + // `urlOrTab` is an url. Open an empty tab first in order to load the page + // only once the panel is ready. That to be able to safely catch the + // SOURCE_SHOWN event. + tab = yield addTab("about:blank", window); + url = urlOrTab; + } + info("Debugee tab added successfully: " + urlOrTab); + + let debuggee = tab.linkedBrowser.contentWindow.wrappedJSObject; + let target = TargetFactory.forTab(tab); + + let toolbox = yield gDevTools.showToolbox(target, "jsdebugger"); + info("Debugger panel shown successfully."); + + let debuggerPanel = toolbox.getCurrentPanel(); + let panelWin = debuggerPanel.panelWin; + let { Sources } = panelWin.DebuggerView; + + prepareDebugger(debuggerPanel); + + if (url && url != "about:blank") { + let onCaretUpdated; + if (line) { + onCaretUpdated = waitForCaretUpdated(debuggerPanel, line); + } + if (source === null) { + // When there is no source in the document, we shouldn't wait for + // SOURCE_SHOWN event + yield reload(debuggerPanel, url); + } else { + yield navigateActiveTabTo(debuggerPanel, + url, + panelWin.EVENTS.SOURCE_SHOWN); + } + if (source) { + let isSelected = Sources.selectedItem.attachment.source.url === source; + if (!isSelected) { + // Ensure that the source is loaded first before trying to select it + yield waitForSourceLoaded(debuggerPanel, source); + // Select the js file. + let onSource = waitForSourceAndCaret(debuggerPanel, source, line ? line : 1); + Sources.selectedValue = getSourceActor(Sources, source); + yield onSource; + } + } + yield onCaretUpdated; + } + + return [tab, debuggee, debuggerPanel, window]; +}); + +// Creates an add-on debugger for a given add-on. The returned AddonDebugger +// object must be destroyed before finishing the test +function initAddonDebugger(aAddonId) { + let addonDebugger = new AddonDebugger(); + return addonDebugger.init(aAddonId).then(() => addonDebugger); +} + +function AddonDebugger() { + this._onMessage = this._onMessage.bind(this); + this._onConsoleAPICall = this._onConsoleAPICall.bind(this); + EventEmitter.decorate(this); +} + +AddonDebugger.prototype = { + init: Task.async(function* (aAddonId) { + info("Initializing an addon debugger panel."); + + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + DebuggerServer.allowChromeProcess = true; + + this.frame = document.createElement("iframe"); + this.frame.setAttribute("height", 400); + document.documentElement.appendChild(this.frame); + window.addEventListener("message", this._onMessage); + + let transport = DebuggerServer.connectPipe(); + this.client = new DebuggerClient(transport); + + yield this.client.connect(); + + let addonActor = yield getAddonActorForId(this.client, aAddonId); + + let targetOptions = { + form: addonActor, + client: this.client, + chrome: true, + isTabActor: false + }; + + let toolboxOptions = { + customIframe: this.frame + }; + + this.target = TargetFactory.forTab(targetOptions); + let toolbox = yield gDevTools.showToolbox(this.target, "jsdebugger", Toolbox.HostType.CUSTOM, toolboxOptions); + + info("Addon debugger panel shown successfully."); + + this.debuggerPanel = toolbox.getCurrentPanel(); + yield waitForSourceShown(this.debuggerPanel, ""); + + prepareDebugger(this.debuggerPanel); + yield this._attachConsole(); + }), + + destroy: Task.async(function* () { + yield this.client.close(); + yield this.debuggerPanel._toolbox.destroy(); + this.frame.remove(); + window.removeEventListener("message", this._onMessage); + }), + + _attachConsole: function () { + let deferred = promise.defer(); + this.client.attachConsole(this.target.form.consoleActor, ["ConsoleAPI"], (aResponse, aWebConsoleClient) => { + if (aResponse.error) { + deferred.reject(aResponse); + } + else { + this.webConsole = aWebConsoleClient; + this.client.addListener("consoleAPICall", this._onConsoleAPICall); + deferred.resolve(); + } + }); + return deferred.promise; + }, + + _onConsoleAPICall: function (aType, aPacket) { + if (aPacket.from != this.webConsole.actor) + return; + this.emit("console", aPacket.message); + }, + + /** + * Returns a list of the groups and sources in the UI. The returned array + * contains objects for each group with properties name and sources. The + * sources property contains an array with objects for each source for that + * group with properties label and url. + */ + getSourceGroups: Task.async(function* () { + let debuggerWin = this.debuggerPanel.panelWin; + let sources = yield getSources(debuggerWin.gThreadClient); + ok(sources.length, "retrieved sources"); + + // groups will be the return value, groupmap and the maps we put in it will + // be used as quick lookups to add the url information in below + let groups = []; + let groupmap = new Map(); + + let uigroups = this.debuggerPanel.panelWin.document.querySelectorAll(".side-menu-widget-group"); + for (let g of uigroups) { + let name = g.querySelector(".side-menu-widget-group-title .name").value; + let group = { + name: name, + sources: [] + }; + groups.push(group); + let labelmap = new Map(); + groupmap.set(name, labelmap); + + for (let l of g.querySelectorAll(".dbg-source-item")) { + let source = { + label: l.value, + url: null + }; + + labelmap.set(l.value, source); + group.sources.push(source); + } + } + + for (let source of sources) { + let { label, group } = debuggerWin.DebuggerView.Sources.getItemByValue(source.actor).attachment; + + if (!groupmap.has(group)) { + ok(false, "Saw a source group not in the UI: " + group); + continue; + } + + if (!groupmap.get(group).has(label)) { + ok(false, "Saw a source label not in the UI: " + label); + continue; + } + + groupmap.get(group).get(label).url = source.url.split(" -> ").pop(); + } + + return groups; + }), + + _onMessage: function (event) { + if (typeof(event.data) !== "string") { + return; + } + let json = JSON.parse(event.data); + switch (json.name) { + case "toolbox-title": + this.title = json.data.value; + break; + } + } +}; + +function initChromeDebugger(aOnClose) { + info("Initializing a chrome debugger process."); + + let deferred = promise.defer(); + + // Wait for the toolbox process to start... + BrowserToolboxProcess.init(aOnClose, (aEvent, aProcess) => { + info("Browser toolbox process started successfully."); + + prepareDebugger(aProcess); + deferred.resolve(aProcess); + }); + + return deferred.promise; +} + +function prepareDebugger(aDebugger) { + if ("target" in aDebugger) { + let view = aDebugger.panelWin.DebuggerView; + view.Variables.lazyEmpty = false; + view.Variables.lazySearch = false; + view.Filtering.FilteredSources._autoSelectFirstItem = true; + view.Filtering.FilteredFunctions._autoSelectFirstItem = true; + } else { + // Nothing to do here yet. + } +} + +function teardown(aPanel, aFlags = {}) { + info("Destroying the specified debugger."); + + let toolbox = aPanel._toolbox; + let tab = aPanel.target.tab; + let debuggerRootActorDisconnected = once(window, "Debugger:Shutdown"); + let debuggerPanelDestroyed = once(aPanel, "destroyed"); + let devtoolsToolboxDestroyed = toolbox.destroy(); + + return promise.all([ + debuggerRootActorDisconnected, + debuggerPanelDestroyed, + devtoolsToolboxDestroyed + ]).then(() => aFlags.noTabRemoval ? null : removeTab(tab)); +} + +function closeDebuggerAndFinish(aPanel, aFlags = {}) { + let thread = aPanel.panelWin.gThreadClient; + if (thread.state == "paused" && !aFlags.whilePaused) { + ok(false, "You should use 'resumeDebuggerThenCloseAndFinish' instead, " + + "unless you're absolutely sure about what you're doing."); + } + return teardown(aPanel, aFlags).then(finish); +} + +function resumeDebuggerThenCloseAndFinish(aPanel, aFlags = {}) { + let deferred = promise.defer(); + let thread = aPanel.panelWin.gThreadClient; + thread.resume(() => closeDebuggerAndFinish(aPanel, aFlags).then(deferred.resolve)); + return deferred.promise; +} + +// Blackboxing helpers + +function getBlackBoxButton(aPanel) { + return aPanel.panelWin.document.getElementById("black-box"); +} + +/** + * Returns the node that has the black-boxed class applied to it. + */ +function getSelectedSourceElement(aPanel) { + return aPanel.panelWin.DebuggerView.Sources.selectedItem.prebuiltNode; +} + +function toggleBlackBoxing(aPanel, aSourceActor = null) { + function clickBlackBoxButton() { + getBlackBoxButton(aPanel).click(); + } + + const blackBoxChanged = waitForDispatch( + aPanel, + aPanel.panelWin.constants.BLACKBOX + ).then(() => { + return aSourceActor ? + getSource(aPanel, aSourceActor) : + getSelectedSource(aPanel); + }); + + if (aSourceActor) { + aPanel.panelWin.DebuggerView.Sources.selectedValue = aSourceActor; + ensureSourceIs(aPanel, aSourceActor, true).then(clickBlackBoxButton); + } else { + clickBlackBoxButton(); + } + + return blackBoxChanged; +} + +function selectSourceAndGetBlackBoxButton(aPanel, aUrl) { + function returnBlackboxButton() { + return getBlackBoxButton(aPanel); + } + + let sources = aPanel.panelWin.DebuggerView.Sources; + sources.selectedValue = getSourceActor(sources, aUrl); + return ensureSourceIs(aPanel, aUrl, true).then(returnBlackboxButton); +} + +// Variables view inspection popup helpers + +function openVarPopup(aPanel, aCoords, aWaitForFetchedProperties) { + let events = aPanel.panelWin.EVENTS; + let editor = aPanel.panelWin.DebuggerView.editor; + let bubble = aPanel.panelWin.DebuggerView.VariableBubble; + let tooltip = bubble._tooltip.panel; + + let popupShown = once(tooltip, "popupshown"); + let fetchedProperties = aWaitForFetchedProperties + ? waitForDebuggerEvents(aPanel, events.FETCHED_BUBBLE_PROPERTIES) + : promise.resolve(null); + let updatedFrame = waitForDebuggerEvents(aPanel, events.FETCHED_SCOPES); + + let { left, top } = editor.getCoordsFromPosition(aCoords); + bubble._findIdentifier(left, top); + return promise.all([popupShown, fetchedProperties, updatedFrame]).then(waitForTick); +} + +// Simulates the mouse hovering a variable in the debugger +// Takes in account the position of the cursor in the text, if the text is +// selected and if a button is currently pushed (aButtonPushed > 0). +// The function returns a promise which returns true if the popup opened or +// false if it didn't +function intendOpenVarPopup(aPanel, aPosition, aButtonPushed) { + let bubble = aPanel.panelWin.DebuggerView.VariableBubble; + let editor = aPanel.panelWin.DebuggerView.editor; + let tooltip = bubble._tooltip; + + let { left, top } = editor.getCoordsFromPosition(aPosition); + + const eventDescriptor = { + clientX: left, + clientY: top, + buttons: aButtonPushed + }; + + bubble._onMouseMove(eventDescriptor); + + const deferred = promise.defer(); + window.setTimeout( + function () { + if (tooltip.isEmpty()) { + deferred.resolve(false); + } else { + deferred.resolve(true); + } + }, + bubble.TOOLTIP_SHOW_DELAY + 1000 + ); + + return deferred.promise; +} + +function hideVarPopup(aPanel) { + let bubble = aPanel.panelWin.DebuggerView.VariableBubble; + let tooltip = bubble._tooltip.panel; + + let popupHiding = once(tooltip, "popuphiding"); + bubble.hideContents(); + return popupHiding.then(waitForTick); +} + +function hideVarPopupByScrollingEditor(aPanel) { + let editor = aPanel.panelWin.DebuggerView.editor; + let bubble = aPanel.panelWin.DebuggerView.VariableBubble; + let tooltip = bubble._tooltip.panel; + + let popupHiding = once(tooltip, "popuphiding"); + editor.setFirstVisibleLine(0); + return popupHiding.then(waitForTick); +} + +function reopenVarPopup(...aArgs) { + return hideVarPopup.apply(this, aArgs).then(() => openVarPopup.apply(this, aArgs)); +} + +function attachAddonActorForId(aClient, aAddonId) { + let deferred = promise.defer(); + + getAddonActorForId(aClient, aAddonId).then(aGrip => { + aClient.attachAddon(aGrip.actor, aResponse => { + deferred.resolve([aGrip, aResponse]); + }); + }); + + return deferred.promise; +} + +function doResume(aPanel) { + const threadClient = aPanel.panelWin.gThreadClient; + return threadClient.resume(); +} + +function doInterrupt(aPanel) { + const threadClient = aPanel.panelWin.gThreadClient; + return threadClient.interrupt(); +} + +function pushPrefs(...aPrefs) { + let deferred = promise.defer(); + SpecialPowers.pushPrefEnv({"set": aPrefs}, deferred.resolve); + return deferred.promise; +} + +function popPrefs() { + let deferred = promise.defer(); + SpecialPowers.popPrefEnv(deferred.resolve); + return deferred.promise; +} + +// Source helpers + +function getSelectedSource(panel) { + const win = panel.panelWin; + return win.queries.getSelectedSource(win.DebuggerController.getState()); +} + +function getSource(panel, actor) { + const win = panel.panelWin; + return win.queries.getSource(win.DebuggerController.getState(), actor); +} + +function getSelectedSourceURL(aSources) { + return (aSources.selectedItem && + aSources.selectedItem.attachment.source.url); +} + +function getSourceURL(aSources, aActor) { + let item = aSources.getItemByValue(aActor); + return item && item.attachment.source.url; +} + +function getSourceActor(aSources, aURL) { + let item = aSources.getItemForAttachment(a => a.source && a.source.url === aURL); + return item && item.value; +} + +function getSourceForm(aSources, aURL) { + let item = aSources.getItemByValue(getSourceActor(aSources, aURL)); + return item.attachment.source; +} + +var nextId = 0; + +function jsonrpc(tab, method, params) { + return new Promise(function (resolve, reject) { + let currentId = nextId++; + let messageManager = tab.linkedBrowser.messageManager; + messageManager.sendAsyncMessage("jsonrpc", { + method: method, + params: params, + id: currentId + }); + messageManager.addMessageListener("jsonrpc", function listener(res) { + const { data: { result, error, id } } = res; + if (id !== currentId) { + return; + } + + messageManager.removeMessageListener("jsonrpc", listener); + if (error != null) { + reject(error); + } + + resolve(result); + }); + }); +} + +function callInTab(tab, name) { + info("Calling function with name '" + name + "' in tab."); + + return jsonrpc(tab, "call", [name, Array.prototype.slice.call(arguments, 2)]); +} + +function evalInTab(tab, string) { + info("Evalling string in tab."); + + return jsonrpc(tab, "_eval", [string]); +} + +function createWorkerInTab(tab, url) { + info("Creating worker with url '" + url + "' in tab."); + + return jsonrpc(tab, "createWorker", [url]); +} + +function terminateWorkerInTab(tab, url) { + info("Terminating worker with url '" + url + "' in tab."); + + return jsonrpc(tab, "terminateWorker", [url]); +} + +function postMessageToWorkerInTab(tab, url, message) { + info("Posting message to worker with url '" + url + "' in tab."); + + return jsonrpc(tab, "postMessageToWorker", [url, message]); +} + +function generateMouseClickInTab(tab, path) { + info("Generating mouse click in tab."); + + return jsonrpc(tab, "generateMouseClick", [path]); +} + +function connect(client) { + info("Connecting client."); + return client.connect(); +} + +function close(client) { + info("Waiting for client to close.\n"); + return client.close(); +} + +function listTabs(client) { + info("Listing tabs."); + return client.listTabs(); +} + +function findTab(tabs, url) { + info("Finding tab with url '" + url + "'."); + for (let tab of tabs) { + if (tab.url === url) { + return tab; + } + } + return null; +} + +function attachTab(client, tab) { + info("Attaching to tab with url '" + tab.url + "'."); + return new Promise(function (resolve) { + client.attachTab(tab.actor, function (response, tabClient) { + resolve([response, tabClient]); + }); + }); +} + +function listWorkers(tabClient) { + info("Listing workers."); + return new Promise(function (resolve) { + tabClient.listWorkers(function (response) { + resolve(response); + }); + }); +} + +function findWorker(workers, url) { + info("Finding worker with url '" + url + "'."); + for (let worker of workers) { + if (worker.url === url) { + return worker; + } + } + return null; +} + +function attachWorker(tabClient, worker) { + info("Attaching to worker with url '" + worker.url + "'."); + return new Promise(function (resolve, reject) { + tabClient.attachWorker(worker.actor, function (response, workerClient) { + resolve([response, workerClient]); + }); + }); +} + +function waitForWorkerListChanged(tabClient) { + info("Waiting for worker list to change."); + return new Promise(function (resolve) { + tabClient.addListener("workerListChanged", function listener() { + tabClient.removeListener("workerListChanged", listener); + resolve(); + }); + }); +} + +function attachThread(workerClient, options) { + info("Attaching to thread."); + return new Promise(function (resolve, reject) { + workerClient.attachThread(options, function (response, threadClient) { + resolve([response, threadClient]); + }); + }); +} + +function waitForWorkerClose(workerClient) { + info("Waiting for worker to close."); + return new Promise(function (resolve) { + workerClient.addOneTimeListener("close", function () { + info("Worker did close."); + resolve(); + }); + }); +} + +function resume(threadClient) { + info("Resuming thread."); + return threadClient.resume(); +} + +function findSource(sources, url) { + info("Finding source with url '" + url + "'.\n"); + for (let source of sources) { + if (source.url === url) { + return source; + } + } + return null; +} + +function waitForEvent(client, type, predicate) { + return new Promise(function (resolve) { + function listener(type, packet) { + if (!predicate(packet)) { + return; + } + client.removeListener(listener); + resolve(packet); + } + + if (predicate) { + client.addListener(type, listener); + } else { + client.addOneTimeListener(type, function (type, packet) { + resolve(packet); + }); + } + }); +} + +function waitForPause(threadClient) { + info("Waiting for pause.\n"); + return waitForEvent(threadClient, "paused"); +} + +function setBreakpoint(sourceClient, location) { + info("Setting breakpoint.\n"); + return sourceClient.setBreakpoint(location); +} + +function source(sourceClient) { + info("Getting source.\n"); + return sourceClient.source(); +} + +// Return a promise with a reference to jsterm, opening the split +// console if necessary. This cleans up the split console pref so +// it won't pollute other tests. +function getSplitConsole(toolbox, win) { + registerCleanupFunction(() => { + Services.prefs.clearUserPref("devtools.toolbox.splitconsoleEnabled"); + }); + + if (!win) { + win = toolbox.win; + } + + if (!toolbox.splitConsole) { + EventUtils.synthesizeKey("VK_ESCAPE", {}, win); + } + + return new Promise(resolve => { + toolbox.getPanelWhenReady("webconsole").then(() => { + ok(toolbox.splitConsole, "Split console is shown."); + let jsterm = toolbox.getPanel("webconsole").hud.jsterm; + resolve(jsterm); + }); + }); +} + +// navigation + +function waitForNavigation(gPanel) { + const target = gPanel.panelWin.gTarget; + const deferred = promise.defer(); + target.once("navigate", () => { + deferred.resolve(); + }); + info("Waiting for navigation..."); + return deferred.promise; +} + +// actions + +function bindActionCreators(panel) { + const win = panel.panelWin; + const dispatch = win.DebuggerController.dispatch; + const { bindActionCreators } = win.require("devtools/client/shared/vendor/redux"); + return bindActionCreators(win.actions, dispatch); +} + +// Wait until an action of `type` is dispatched. This is different +// then `_afterDispatchDone` because it doesn't wait for async actions +// to be done/errored. Use this if you want to listen for the "start" +// action of an async operation (somewhat rare). +function waitForNextDispatch(store, type) { + return new Promise(resolve => { + store.dispatch({ + // Normally we would use `services.WAIT_UNTIL`, but use the + // internal name here so tests aren't forced to always pass it + // in + type: "@@service/waitUntil", + predicate: action => action.type === type, + run: (dispatch, getState, action) => { + resolve(action); + } + }); + }); +} + +// Wait until an action of `type` is dispatched. If it's part of an +// async operation, wait until the `status` field is "done" or "error" +function _afterDispatchDone(store, type) { + return new Promise(resolve => { + store.dispatch({ + // Normally we would use `services.WAIT_UNTIL`, but use the + // internal name here so tests aren't forced to always pass it + // in + type: "@@service/waitUntil", + predicate: action => { + if (action.type === type) { + return action.status ? + (action.status === "done" || action.status === "error") : + true; + } + }, + run: (dispatch, getState, action) => { + resolve(action); + } + }); + }); +} + +function waitForDispatch(panel, type, eventRepeat = 1) { + const controller = panel.panelWin.DebuggerController; + const actionType = panel.panelWin.constants[type]; + let count = 0; + + return Task.spawn(function* () { + info("Waiting for " + type + " to dispatch " + eventRepeat + " time(s)"); + while (count < eventRepeat) { + yield _afterDispatchDone(controller, actionType); + count++; + info(type + " dispatched " + count + " time(s)"); + } + }); +} + +function* initWorkerDebugger(TAB_URL, WORKER_URL) { + if (!DebuggerServer.initialized) { + DebuggerServer.init(); + DebuggerServer.addBrowserActors(); + } + + let client = new DebuggerClient(DebuggerServer.connectPipe()); + yield connect(client); + + let tab = yield addTab(TAB_URL); + let { tabs } = yield listTabs(client); + let [, tabClient] = yield attachTab(client, findTab(tabs, TAB_URL)); + + yield createWorkerInTab(tab, WORKER_URL); + + let { workers } = yield listWorkers(tabClient); + let [, workerClient] = yield attachWorker(tabClient, + findWorker(workers, WORKER_URL)); + + let toolbox = yield gDevTools.showToolbox(TargetFactory.forWorker(workerClient), + "jsdebugger", + Toolbox.HostType.WINDOW); + + let debuggerPanel = toolbox.getCurrentPanel(); + let gDebugger = debuggerPanel.panelWin; + + return {client, tab, tabClient, workerClient, toolbox, gDebugger}; +} + diff --git a/devtools/client/debugger/test/mochitest/sjs_post-page.sjs b/devtools/client/debugger/test/mochitest/sjs_post-page.sjs new file mode 100644 index 000000000..06f7c60d0 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/sjs_post-page.sjs @@ -0,0 +1,16 @@ +/* This Source Code Form is subject to the terms of the Mozilla Public + * License, v. 2.0. If a copy of the MPL was not distributed with this + * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ + +const CC = Components.Constructor; +const BinaryInputStream = CC("@mozilla.org/binaryinputstream;1", + "nsIBinaryInputStream", + "setInputStream"); + +function handleRequest(request, response) +{ + let method = request.method; + let body = ""; + body += "
"; + response.bodyOutputStream.write(body, body.length); +} diff --git a/devtools/client/debugger/test/mochitest/sjs_random-javascript.sjs b/devtools/client/debugger/test/mochitest/sjs_random-javascript.sjs new file mode 100644 index 000000000..3e0ea8e53 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/sjs_random-javascript.sjs @@ -0,0 +1,11 @@ +/* Any copyright is dedicated to the Public Domain. + http://creativecommons.org/publicdomain/zero/1.0/ */ + +function handleRequest(request, response) { + response.setStatusLine(request.httpVersion, 200, "OK"); + response.setHeader("Content-Type", "application/javascript; charset=utf-8", false); + response.write([ + "window.setInterval(function bacon() {", + " var x = '" + Math.random() + "';", + "}, 0);"].join("\n")); +} diff --git a/devtools/client/debugger/test/mochitest/testactors.js b/devtools/client/debugger/test/mochitest/testactors.js new file mode 100644 index 000000000..f7583b615 --- /dev/null +++ b/devtools/client/debugger/test/mochitest/testactors.js @@ -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/ */ + +function TestActor1(aConnection, aTab) +{ + this.conn = aConnection; + this.tab = aTab; +} + +TestActor1.prototype = { + actorPrefix: "test_one", + + grip: function TA1_grip() { + return { actor: this.actorID, + test: "TestActor1" }; + }, + + onPing: function TA1_onPing() { + return { pong: "pong" }; + } +}; + +TestActor1.prototype.requestTypes = { + "ping": TestActor1.prototype.onPing +}; + +DebuggerServer.removeTabActor(TestActor1); +DebuggerServer.removeGlobalActor(TestActor1); + +DebuggerServer.addTabActor(TestActor1, "testTabActor1"); +DebuggerServer.addGlobalActor(TestActor1, "testGlobalActor1"); -- cgit v1.2.3