mirror of
https://repo.dactyloidae.xyz/Dactyloidae/UXP.git
synced 2026-09-05 15:28:39 +09:00
import FIREFOX_52_6_0esr_RELEASE from mozilla-esr52 hg repo
This commit is contained in:
commit
dcd9973243
150858 changed files with 23884658 additions and 0 deletions
6
devtools/client/webconsole/test/.eslintrc.js
Normal file
6
devtools/client/webconsole/test/.eslintrc.js
Normal file
|
|
@ -0,0 +1,6 @@
|
|||
"use strict";
|
||||
|
||||
module.exports = {
|
||||
// Extend from the shared list of defined globals for mochitests.
|
||||
"extends": "../../../.eslintrc.mochitests.js"
|
||||
};
|
||||
396
devtools/client/webconsole/test/browser.ini
Normal file
396
devtools/client/webconsole/test/browser.ini
Normal file
|
|
@ -0,0 +1,396 @@
|
|||
[DEFAULT]
|
||||
tags = devtools
|
||||
subsuite = devtools
|
||||
support-files =
|
||||
head.js
|
||||
test-bug-585956-console-trace.html
|
||||
test-bug-593003-iframe-wrong-hud-iframe.html
|
||||
test-bug-593003-iframe-wrong-hud.html
|
||||
test-bug-595934-canvas-css.html
|
||||
test-bug-595934-canvas-css.js
|
||||
test-bug-595934-css-loader.css
|
||||
test-bug-595934-css-loader.css^headers^
|
||||
test-bug-595934-css-loader.html
|
||||
test-bug-595934-css-parser.css
|
||||
test-bug-595934-css-parser.html
|
||||
test-bug-595934-empty-getelementbyid.html
|
||||
test-bug-595934-empty-getelementbyid.js
|
||||
test-bug-595934-html.html
|
||||
test-bug-595934-image.html
|
||||
test-bug-595934-image.jpg
|
||||
test-bug-595934-imagemap.html
|
||||
test-bug-595934-malformedxml-external.html
|
||||
test-bug-595934-malformedxml-external.xml
|
||||
test-bug-595934-malformedxml.xhtml
|
||||
test-bug-595934-svg.xhtml
|
||||
test-bug-595934-workers.html
|
||||
test-bug-595934-workers.js
|
||||
test-bug-597136-external-script-errors.html
|
||||
test-bug-597136-external-script-errors.js
|
||||
test-bug-597756-reopen-closed-tab.html
|
||||
test-bug-599725-response-headers.sjs
|
||||
test-bug-600183-charset.html
|
||||
test-bug-600183-charset.html^headers^
|
||||
test-bug-601177-log-levels.html
|
||||
test-bug-601177-log-levels.js
|
||||
test-bug-603750-websocket.html
|
||||
test-bug-603750-websocket.js
|
||||
test-bug-613013-console-api-iframe.html
|
||||
test-bug-618078-network-exceptions.html
|
||||
test-bug-621644-jsterm-dollar.html
|
||||
test-bug-630733-response-redirect-headers.sjs
|
||||
test-bug-632275-getters.html
|
||||
test-bug-632347-iterators-generators.html
|
||||
test-bug-644419-log-limits.html
|
||||
test-bug-646025-console-file-location.html
|
||||
test-bug-658368-time-methods.html
|
||||
test-bug-737873-mixedcontent.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning0.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning1.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning2.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning3.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning4.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning5.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning-inner.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning-nested1.html
|
||||
test-bug-752559-ineffective-iframe-sandbox-warning-nested2.html
|
||||
test-bug-762593-insecure-passwords-about-blank-web-console-warning.html
|
||||
test-bug-762593-insecure-passwords-web-console-warning.html
|
||||
test-bug-766001-console-log.js
|
||||
test-bug-766001-js-console-links.html
|
||||
test-bug-766001-js-errors.js
|
||||
test-bug-782653-css-errors-1.css
|
||||
test-bug-782653-css-errors-2.css
|
||||
test-bug-782653-css-errors.html
|
||||
test-bug-837351-security-errors.html
|
||||
test-bug-859170-longstring-hang.html
|
||||
test-bug-869003-iframe.html
|
||||
test-bug-869003-top-window.html
|
||||
test-closure-optimized-out.html
|
||||
test-closures.html
|
||||
test-console-assert.html
|
||||
test-console-clear.html
|
||||
test-console-count.html
|
||||
test-console-count-external-file.js
|
||||
test-console-extras.html
|
||||
test-console-replaced-api.html
|
||||
test-console-server-logging.sjs
|
||||
test-console-server-logging-array.sjs
|
||||
test-console.html
|
||||
test-console-workers.html
|
||||
test-console-table.html
|
||||
test-console-output-02.html
|
||||
test-console-output-03.html
|
||||
test-console-output-04.html
|
||||
test-console-output-dom-elements.html
|
||||
test-console-output-events.html
|
||||
test-console-output-regexp.html
|
||||
test-console-column.html
|
||||
test-consoleiframes.html
|
||||
test-console-trace-async.html
|
||||
test-certificate-messages.html
|
||||
test-cu-reporterror.js
|
||||
test-data.json
|
||||
test-data.json^headers^
|
||||
test-duplicate-error.html
|
||||
test-encoding-ISO-8859-1.html
|
||||
test-error.html
|
||||
test-eval-in-stackframe.html
|
||||
test-file-location.js
|
||||
test-filter.html
|
||||
test-for-of.html
|
||||
test_hpkp-invalid-headers.sjs
|
||||
test_hsts-invalid-headers.sjs
|
||||
test-iframe-762593-insecure-form-action.html
|
||||
test-iframe-762593-insecure-frame.html
|
||||
test-iframe1.html
|
||||
test-iframe2.html
|
||||
test-iframe3.html
|
||||
test-image.png
|
||||
test-mixedcontent-securityerrors.html
|
||||
test-mutation.html
|
||||
test-network-request.html
|
||||
test-network.html
|
||||
test-observe-http-ajax.html
|
||||
test-own-console.html
|
||||
test-property-provider.html
|
||||
test-repeated-messages.html
|
||||
test-result-format-as-string.html
|
||||
test-trackingprotection-securityerrors.html
|
||||
test-webconsole-error-observer.html
|
||||
test_bug_770099_violation.html
|
||||
test_bug_770099_violation.html^headers^
|
||||
test-autocomplete-in-stackframe.html
|
||||
testscript.js
|
||||
test-bug_923281_console_log_filter.html
|
||||
test-bug_923281_test1.js
|
||||
test-bug_923281_test2.js
|
||||
test-bug_939783_console_trace_duplicates.html
|
||||
test-bug-952277-highlight-nodes-in-vview.html
|
||||
test-bug-609872-cd-iframe-parent.html
|
||||
test-bug-609872-cd-iframe-child.html
|
||||
test-bug-989025-iframe-parent.html
|
||||
test-bug_1050691_click_function_to_source.html
|
||||
test-bug_1050691_click_function_to_source.js
|
||||
test-console-api-stackframe.html
|
||||
test-exception-stackframe.html
|
||||
test_bug_1010953_cspro.html^headers^
|
||||
test_bug_1010953_cspro.html
|
||||
test_bug1045902_console_csp_ignore_reflected_xss_message.html^headers^
|
||||
test_bug1045902_console_csp_ignore_reflected_xss_message.html
|
||||
test_bug1092055_shouldwarn.js^headers^
|
||||
test_bug1092055_shouldwarn.js
|
||||
test_bug1092055_shouldwarn.html
|
||||
test_bug_1247459_violation.html
|
||||
!/devtools/client/framework/test/shared-head.js
|
||||
!/devtools/client/netmonitor/test/sjs_cors-test-server.sjs
|
||||
!/image/test/mochitest/blue.png
|
||||
|
||||
[browser_bug1045902_console_csp_ignore_reflected_xss_message.js]
|
||||
skip-if = (e10s && debug) || (e10s && os == 'win') # Bug 1221499 enabled these on windows
|
||||
[browser_bug664688_sandbox_update_after_navigation.js]
|
||||
[browser_bug_638949_copy_link_location.js]
|
||||
subsuite = clipboard
|
||||
[browser_bug_862916_console_dir_and_filter_off.js]
|
||||
skip-if = (e10s && (os == 'win' || os == 'mac')) # Bug 1243976
|
||||
[browser_bug_865288_repeat_different_objects.js]
|
||||
[browser_bug_865871_variables_view_close_on_esc_key.js]
|
||||
[browser_bug_869003_inspect_cross_domain_object.js]
|
||||
[browser_bug_871156_ctrlw_close_tab.js]
|
||||
[browser_cached_messages.js]
|
||||
[browser_console.js]
|
||||
[browser_console_addonsdk_loader_exception.js]
|
||||
[browser_console_clear_method.js]
|
||||
[browser_console_clear_on_reload.js]
|
||||
[browser_console_click_focus.js]
|
||||
[browser_console_consolejsm_output.js]
|
||||
[browser_console_copy_command.js]
|
||||
subsuite = clipboard
|
||||
[browser_console_dead_objects.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_console_copy_entire_message_context_menu.js]
|
||||
subsuite = clipboard
|
||||
[browser_console_error_source_click.js]
|
||||
[browser_console_filters.js]
|
||||
[browser_console_iframe_messages.js]
|
||||
[browser_console_keyboard_accessibility.js]
|
||||
[browser_console_log_inspectable_object.js]
|
||||
[browser_console_native_getters.js]
|
||||
[browser_console_navigation_marker.js]
|
||||
[browser_console_netlogging.js]
|
||||
[browser_console_nsiconsolemessage.js]
|
||||
[browser_console_optimized_out_vars.js]
|
||||
[browser_console_private_browsing.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests
|
||||
[browser_console_server_logging.js]
|
||||
[browser_console_variables_view.js]
|
||||
[browser_console_variables_view_filter.js]
|
||||
[browser_console_variables_view_dom_nodes.js]
|
||||
[browser_console_variables_view_dont_sort_non_sortable_classes_properties.js]
|
||||
[browser_console_variables_view_special_names.js]
|
||||
[browser_console_variables_view_while_debugging.js]
|
||||
[browser_console_variables_view_while_debugging_and_inspecting.js]
|
||||
[browser_eval_in_debugger_stackframe.js]
|
||||
[browser_eval_in_debugger_stackframe2.js]
|
||||
[browser_jsterm_inspect.js]
|
||||
skip-if = e10s && debug && (os == 'win' || os == 'mac') # Bug 1243966
|
||||
[browser_longstring_hang.js]
|
||||
[browser_output_breaks_after_console_dir_uninspectable.js]
|
||||
[browser_output_longstring_expand.js]
|
||||
[browser_repeated_messages_accuracy.js]
|
||||
[browser_result_format_as_string.js]
|
||||
[browser_warn_user_about_replaced_api.js]
|
||||
[browser_webconsole_allow_mixedcontent_securityerrors.js]
|
||||
tags = mcb
|
||||
[browser_webconsole_script_errordoc_urls.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_assert.js]
|
||||
[browser_webconsole_block_mixedcontent_securityerrors.js]
|
||||
tags = mcb
|
||||
[browser_webconsole_bug_579412_input_focus.js]
|
||||
[browser_webconsole_bug_580001_closing_after_completion.js]
|
||||
[browser_webconsole_bug_580030_errors_after_page_reload.js]
|
||||
[browser_webconsole_bug_580454_timestamp_l10n.js]
|
||||
[browser_webconsole_bug_582201_duplicate_errors.js]
|
||||
[browser_webconsole_bug_583816_No_input_and_Tab_key_pressed.js]
|
||||
[browser_webconsole_bug_585237_line_limit.js]
|
||||
[browser_webconsole_bug_585956_console_trace.js]
|
||||
[browser_webconsole_bug_585991_autocomplete_keys.js]
|
||||
[browser_webconsole_bug_585991_autocomplete_popup.js]
|
||||
[browser_webconsole_bug_586388_select_all.js]
|
||||
[browser_webconsole_bug_587617_output_copy.js]
|
||||
subsuite = clipboard
|
||||
[browser_webconsole_bug_588342_document_focus.js]
|
||||
[browser_webconsole_bug_588730_text_node_insertion.js]
|
||||
[browser_webconsole_bug_588967_input_expansion.js]
|
||||
[browser_webconsole_bug_589162_css_filter.js]
|
||||
[browser_webconsole_bug_592442_closing_brackets.js]
|
||||
[browser_webconsole_bug_593003_iframe_wrong_hud.js]
|
||||
[browser_webconsole_bug_594497_history_arrow_keys.js]
|
||||
[browser_webconsole_bug_595223_file_uri.js]
|
||||
[browser_webconsole_bug_595350_multiple_windows_and_tabs.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_595934_message_categories.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_597103_deactivateHUDForContext_unfocused_window.js]
|
||||
[browser_webconsole_bug_597136_external_script_errors.js]
|
||||
[browser_webconsole_bug_597136_network_requests_from_chrome.js]
|
||||
[browser_webconsole_bug_597460_filter_scroll.js]
|
||||
[browser_webconsole_bug_597756_reopen_closed_tab.js]
|
||||
[browser_webconsole_bug_599725_response_headers.js]
|
||||
[browser_webconsole_bug_600183_charset.js]
|
||||
[browser_webconsole_bug_601177_log_levels.js]
|
||||
[browser_webconsole_bug_601352_scroll.js]
|
||||
[browser_webconsole_bug_601667_filter_buttons.js]
|
||||
[browser_webconsole_bug_603750_websocket.js]
|
||||
[browser_webconsole_bug_611795.js]
|
||||
[browser_webconsole_bug_613013_console_api_iframe.js]
|
||||
[browser_webconsole_bug_613280_jsterm_copy.js]
|
||||
subsuite = clipboard
|
||||
[browser_webconsole_bug_613642_maintain_scroll.js]
|
||||
[browser_webconsole_bug_613642_prune_scroll.js]
|
||||
[browser_webconsole_bug_614793_jsterm_scroll.js]
|
||||
[browser_webconsole_bug_618078_network_exceptions.js]
|
||||
[browser_webconsole_bug_621644_jsterm_dollar.js]
|
||||
[browser_webconsole_bug_622303_persistent_filters.js]
|
||||
[browser_webconsole_bug_623749_ctrl_a_select_all_winnt.js]
|
||||
skip-if = os != "win"
|
||||
[browser_webconsole_bug_630733_response_redirect_headers.js]
|
||||
[browser_webconsole_bug_632275_getters_document_width.js]
|
||||
[browser_webconsole_bug_632347_iterators_generators.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_632817.js]
|
||||
skip-if = true # Bug 1244707
|
||||
[browser_webconsole_bug_642108_pruneTest.js]
|
||||
[browser_webconsole_autocomplete_and_selfxss.js]
|
||||
subsuite = clipboard
|
||||
[browser_webconsole_bug_644419_log_limits.js]
|
||||
[browser_webconsole_bug_646025_console_file_location.js]
|
||||
[browser_webconsole_bug_651501_document_body_autocomplete.js]
|
||||
[browser_webconsole_bug_653531_highlighter_console_helper.js]
|
||||
skip-if = true # Requires direct access to content nodes
|
||||
[browser_webconsole_bug_658368_time_methods.js]
|
||||
[browser_webconsole_bug_659907_console_dir.js]
|
||||
[browser_webconsole_bug_660806_history_nav.js]
|
||||
[browser_webconsole_bug_664131_console_group.js]
|
||||
[browser_webconsole_bug_686937_autocomplete_JSTerm_helpers.js]
|
||||
[browser_webconsole_bug_704295.js]
|
||||
[browser_webconsole_bug_734061_No_input_change_and_Tab_key_pressed.js]
|
||||
[browser_webconsole_bug_737873_mixedcontent.js]
|
||||
tags = mcb
|
||||
[browser_webconsole_bug_752559_ineffective_iframe_sandbox_warning.js]
|
||||
[browser_webconsole_bug_762593_insecure_passwords_about_blank_web_console_warning.js]
|
||||
[browser_webconsole_bug_762593_insecure_passwords_web_console_warning.js]
|
||||
skip-if = true # Bug 1110500 - mouse event failure in test
|
||||
[browser_webconsole_bug_764572_output_open_url.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_bug_766001_JS_Console_in_Debugger.js]
|
||||
[browser_webconsole_bug_770099_violation.js]
|
||||
skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243978
|
||||
[browser_webconsole_bug_782653_CSS_links_in_Style_Editor.js]
|
||||
[browser_webconsole_bug_804845_ctrl_key_nav.js]
|
||||
skip-if = os != "mac"
|
||||
[browser_webconsole_bug_817834_add_edited_input_to_history.js]
|
||||
[browser_webconsole_bug_837351_securityerrors.js]
|
||||
[browser_webconsole_filter_buttons_contextmenu.js]
|
||||
[browser_webconsole_bug_1006027_message_timestamps_incorrect.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug intermittent)
|
||||
[browser_webconsole_bug_1010953_cspro.js]
|
||||
skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243967
|
||||
[browser_webconsole_bug_1247459_violation.js]
|
||||
skip-if = e10s && (os == 'win') # Bug 1264955
|
||||
[browser_webconsole_certificate_messages.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_show_subresource_security_errors.js]
|
||||
skip-if = e10s && (os == 'win' || os == 'mac') # Bug 1243987
|
||||
[browser_webconsole_cached_autocomplete.js]
|
||||
[browser_webconsole_chrome.js]
|
||||
[browser_webconsole_clear_method.js]
|
||||
[browser_webconsole_clickable_urls.js]
|
||||
[browser_webconsole_closure_inspection.js]
|
||||
[browser_webconsole_completion.js]
|
||||
[browser_webconsole_console_extras.js]
|
||||
[browser_webconsole_console_logging_api.js]
|
||||
[browser_webconsole_console_logging_workers_api.js]
|
||||
[browser_webconsole_console_trace_async.js]
|
||||
[browser_webconsole_count.js]
|
||||
[browser_webconsole_dont_navigate_on_doubleclick.js]
|
||||
[browser_webconsole_execution_scope.js]
|
||||
[browser_webconsole_for_of.js]
|
||||
[browser_webconsole_history.js]
|
||||
[browser_webconsole_hpkp_invalid-headers.js]
|
||||
[browser_webconsole_hsts_invalid-headers.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests
|
||||
[browser_webconsole_input_field_focus_on_panel_select.js]
|
||||
[browser_webconsole_inspect-parsed-documents.js]
|
||||
[browser_webconsole_js_input_expansion.js]
|
||||
[browser_webconsole_jsterm.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
||||
[browser_webconsole_live_filtering_of_message_types.js]
|
||||
[browser_webconsole_live_filtering_on_search_strings.js]
|
||||
[browser_webconsole_message_node_id.js]
|
||||
[browser_webconsole_multiline_input.js]
|
||||
[browser_webconsole_netlogging.js]
|
||||
skip-if = true # Bug 1298364
|
||||
[browser_webconsole_netlogging_basic.js]
|
||||
[browser_webconsole_netlogging_panel.js]
|
||||
[browser_webconsole_netlogging_reset_filter.js]
|
||||
[browser_webconsole_notifications.js]
|
||||
[browser_webconsole_open-links-without-callback.js]
|
||||
[browser_webconsole_promise.js]
|
||||
[browser_webconsole_output_copy_newlines.js]
|
||||
subsuite = clipboard
|
||||
[browser_webconsole_output_order.js]
|
||||
[browser_webconsole_property_provider.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole tests disabled with e10s
|
||||
[browser_webconsole_scratchpad_panel_link.js]
|
||||
[browser_webconsole_split.js]
|
||||
[browser_webconsole_split_escape_key.js]
|
||||
[browser_webconsole_split_focus.js]
|
||||
[browser_webconsole_split_persist.js]
|
||||
[browser_webconsole_trackingprotection_errors.js]
|
||||
tags = trackingprotection
|
||||
[browser_webconsole_view_source.js]
|
||||
[browser_webconsole_reflow.js]
|
||||
[browser_webconsole_log_file_filter.js]
|
||||
[browser_webconsole_expandable_timestamps.js]
|
||||
[browser_webconsole_autocomplete_accessibility.js]
|
||||
[browser_webconsole_autocomplete_in_debugger_stackframe.js]
|
||||
[browser_webconsole_autocomplete_popup_close_on_tab_switch.js]
|
||||
[browser_webconsole_autocomplete-properties-with-non-alphanumeric-names.js]
|
||||
[browser_console_hide_jsterm_when_devtools_chrome_enabled_false.js]
|
||||
[browser_console_history_persist.js]
|
||||
[browser_webconsole_output_01.js]
|
||||
[browser_webconsole_output_02.js]
|
||||
[browser_webconsole_output_03.js]
|
||||
[browser_webconsole_output_04.js]
|
||||
[browser_webconsole_output_05.js]
|
||||
[browser_webconsole_output_06.js]
|
||||
[browser_webconsole_output_dom_elements_01.js]
|
||||
[browser_webconsole_output_dom_elements_02.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
||||
[browser_webconsole_output_dom_elements_03.js]
|
||||
skip-if = e10s # Bug 1241019
|
||||
[browser_webconsole_output_dom_elements_04.js]
|
||||
skip-if = e10s # Bug 1042253 - webconsole e10s tests (Linux debug timeout)
|
||||
[browser_webconsole_output_dom_elements_05.js]
|
||||
[browser_webconsole_output_events.js]
|
||||
[browser_webconsole_output_regexp.js]
|
||||
[browser_webconsole_output_table.js]
|
||||
[browser_console_variables_view_highlighter.js]
|
||||
[browser_webconsole_start_netmon_first.js]
|
||||
[browser_webconsole_console_trace_duplicates.js]
|
||||
[browser_webconsole_cd_iframe.js]
|
||||
[browser_webconsole_autocomplete_crossdomain_iframe.js]
|
||||
[browser_webconsole_console_custom_styles.js]
|
||||
[browser_webconsole_console_api_stackframe.js]
|
||||
[browser_webconsole_exception_stackframe.js]
|
||||
[browser_webconsole_column_numbers.js]
|
||||
[browser_console_open_or_focus.js]
|
||||
[browser_webconsole_bug_922212_console_dirxml.js]
|
||||
[browser_webconsole_shows_reqs_in_netmonitor.js]
|
||||
[browser_netmonitor_shows_reqs_in_webconsole.js]
|
||||
[browser_webconsole_bug_1050691_click_function_to_source.js]
|
||||
[browser_webconsole_context_menu_open_in_var_view.js]
|
||||
[browser_webconsole_context_menu_store_as_global.js]
|
||||
[browser_webconsole_strict_mode_errors.js]
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that a file with an unsupported CSP directive ('reflected-xss filter')
|
||||
// displays the appropriate message to the console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const EXPECTED_RESULT = "Not supporting directive \u2018reflected-xss\u2019. " +
|
||||
"Directive and values will be ignored.";
|
||||
const TEST_FILE = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test_bug1045902_console_csp_ignore_reflected_xss_" +
|
||||
"message.html";
|
||||
|
||||
var hud = undefined;
|
||||
|
||||
var TEST_URI = "data:text/html;charset=utf8,Web Console CSP ignoring " +
|
||||
"reflected XSS (bug 1045902)";
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
hud = yield openConsole();
|
||||
|
||||
yield loadDocument(browser);
|
||||
yield testViolationMessage();
|
||||
|
||||
hud = null;
|
||||
});
|
||||
|
||||
function loadDocument(browser) {
|
||||
hud.jsterm.clearOutput();
|
||||
browser.loadURI(TEST_FILE);
|
||||
return BrowserTestUtils.browserLoaded(browser);
|
||||
}
|
||||
|
||||
function testViolationMessage() {
|
||||
let aOutputNode = hud.outputNode;
|
||||
|
||||
return waitForSuccess({
|
||||
name: "Confirming that CSP logs messages to the console when " +
|
||||
"\u2018reflected-xss\u2019 directive is used!",
|
||||
validator: function () {
|
||||
console.log(aOutputNode.textContent);
|
||||
let success = false;
|
||||
success = aOutputNode.textContent.indexOf(EXPECTED_RESULT) > -1;
|
||||
return success;
|
||||
}
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests if the JSTerm sandbox is updated when the user navigates from one
|
||||
// domain to another, in order to avoid permission denied errors with a sandbox
|
||||
// created for a different origin.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI1 = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
const TEST_URI2 = "http://example.org/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
yield loadTab(TEST_URI1);
|
||||
let hud = yield openConsole();
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
info("wait for window.location.href");
|
||||
|
||||
let msgForLocation1 = {
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "window.location.href jsterm input",
|
||||
text: "window.location.href",
|
||||
category: CATEGORY_INPUT,
|
||||
},
|
||||
{
|
||||
name: "window.location.href result is displayed",
|
||||
text: TEST_URI1,
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
],
|
||||
};
|
||||
|
||||
yield waitForMessages(msgForLocation1);
|
||||
|
||||
// load second url
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI2);
|
||||
yield loadBrowser(gBrowser.selectedBrowser);
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
info("wait for window.location.href after page navigation");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "window.location.href jsterm input",
|
||||
text: "window.location.href",
|
||||
category: CATEGORY_INPUT,
|
||||
},
|
||||
{
|
||||
name: "window.location.href result is displayed",
|
||||
text: TEST_URI2,
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
|
||||
// Navigation clears messages. Wait for that clear to happen before
|
||||
// continuing the test or it might destroy messages we wait later on (Bug
|
||||
// 1270234).
|
||||
let cleared = hud.jsterm.once("messages-cleared");
|
||||
|
||||
gBrowser.goBack();
|
||||
|
||||
info("Waiting for messages to be cleared due to navigation");
|
||||
yield cleared;
|
||||
|
||||
info("Messages cleared after navigation; checking location");
|
||||
hud.jsterm.execute("window.location.href");
|
||||
|
||||
info("wait for window.location.href after goBack()");
|
||||
yield waitForMessages(msgForLocation1);
|
||||
is(hud.outputNode.textContent.indexOf("Permission denied"), -1,
|
||||
"no permission denied errors");
|
||||
});
|
||||
|
|
@ -0,0 +1,107 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test for the "Copy link location" context menu item shown when you right
|
||||
// click network requests in the output.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html?_date=" + Date.now();
|
||||
const COMMAND_NAME = "consoleCmd_copyURL";
|
||||
const CONTEXT_MENU_ID = "#menu_copyURL";
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.webconsole.filter.networkinfo");
|
||||
});
|
||||
|
||||
Services.prefs.setBoolPref("devtools.webconsole.filter.networkinfo", true);
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
let output = hud.outputNode;
|
||||
let menu = hud.iframeWindow.document.getElementById("output-contextmenu");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
content.console.log("bug 638949");
|
||||
|
||||
// Test that the "Copy Link Location" command is disabled for non-network
|
||||
// messages.
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "bug 638949",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
output.focus();
|
||||
let message = [...result.matched][0];
|
||||
|
||||
goUpdateCommand(COMMAND_NAME);
|
||||
ok(!isEnabled(), COMMAND_NAME + " is disabled");
|
||||
|
||||
// Test that the "Copy Link Location" menu item is hidden for non-network
|
||||
// messages.
|
||||
yield waitForContextMenu(menu, message, () => {
|
||||
let isHidden = menu.querySelector(CONTEXT_MENU_ID).hidden;
|
||||
ok(isHidden, CONTEXT_MENU_ID + " is hidden");
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
// Reloading will produce network logging
|
||||
content.location.reload();
|
||||
|
||||
// Test that the "Copy Link Location" command is enabled and works
|
||||
// as expected for any network-related message.
|
||||
// This command should copy only the URL.
|
||||
[result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
output.focus();
|
||||
message = [...result.matched][0];
|
||||
hud.ui.output.selectMessage(message);
|
||||
|
||||
goUpdateCommand(COMMAND_NAME);
|
||||
ok(isEnabled(), COMMAND_NAME + " is enabled");
|
||||
|
||||
info("expected clipboard value: " + message.url);
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
waitForClipboard((aData) => {
|
||||
return aData.trim() == message.url;
|
||||
}, () => {
|
||||
goDoCommand(COMMAND_NAME);
|
||||
}, () => {
|
||||
deferred.resolve(null);
|
||||
}, () => {
|
||||
deferred.reject(null);
|
||||
});
|
||||
|
||||
yield deferred.promise;
|
||||
|
||||
// Test that the "Copy Link Location" menu item is visible for network-related
|
||||
// messages.
|
||||
yield waitForContextMenu(menu, message, () => {
|
||||
let isVisible = !menu.querySelector(CONTEXT_MENU_ID).hidden;
|
||||
ok(isVisible, CONTEXT_MENU_ID + " is visible");
|
||||
});
|
||||
|
||||
// Return whether "Copy Link Location" command is enabled or not.
|
||||
function isEnabled() {
|
||||
let controller = top.document.commandDispatcher
|
||||
.getControllerForCommand(COMMAND_NAME);
|
||||
return controller && controller.isCommandEnabled(COMMAND_NAME);
|
||||
}
|
||||
});
|
||||
|
|
@ -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/ */
|
||||
|
||||
// Check that the output for console.dir() works even if Logging filter is off.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>test for bug 862916";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
ok(hud, "web console opened");
|
||||
|
||||
hud.setFilterState("log", false);
|
||||
registerCleanupFunction(() => hud.setFilterState("log", true));
|
||||
|
||||
hud.jsterm.execute("window.fooBarz = 'bug862916'; " +
|
||||
"console.dir(window)");
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "variables view object");
|
||||
|
||||
yield findVariableViewProperties(varView, [
|
||||
{ name: "fooBarz", value: "bug862916" },
|
||||
], { webconsole: hud });
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,63 @@
|
|||
/* -*- 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 makes sure messages are not considered repeated when console.log()
|
||||
// is invoked with different objects, see bug 865288.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-repeated-messages.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
info("waiting for 3 console.log objects");
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.jsterm.execute("window.testConsoleObjects()");
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "3 console.log messages",
|
||||
text: "abba",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
count: 3,
|
||||
repeats: 1,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let msgs = [...result.matched];
|
||||
is(msgs.length, 3, "3 message elements");
|
||||
|
||||
for (let i = 0; i < msgs.length; i++) {
|
||||
info("test message element #" + i);
|
||||
|
||||
let msg = msgs[i];
|
||||
let clickable = msg.querySelector(".message-body a");
|
||||
ok(clickable, "clickable object #" + i);
|
||||
|
||||
msg.scrollIntoView(false);
|
||||
yield clickObject(clickable, i);
|
||||
}
|
||||
|
||||
function* clickObject(obj, i) {
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(obj, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "variables view fetched #" + i);
|
||||
|
||||
yield findVariableViewProperties(varView, [
|
||||
{ name: "id", value: "abba" + i },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
});
|
||||
|
||||
|
|
@ -0,0 +1,75 @@
|
|||
/* -*- 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 the variables view sidebar can be closed by pressing Escape in the
|
||||
// web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
function test() {
|
||||
let hud;
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
let {tab} = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole(tab);
|
||||
let jsterm = hud.jsterm;
|
||||
let result;
|
||||
let vview;
|
||||
let msg;
|
||||
|
||||
yield openSidebar("fooObj",
|
||||
'testProp: "testValue"',
|
||||
{ name: "testProp", value: "testValue" });
|
||||
|
||||
let prop = result.matchedProp;
|
||||
ok(prop, "matched the |testProp| property in the variables view");
|
||||
|
||||
vview.window.focus();
|
||||
|
||||
let sidebarClosed = jsterm.once("sidebar-closed");
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
yield sidebarClosed;
|
||||
|
||||
jsterm.clearOutput();
|
||||
|
||||
yield openSidebar("window.location",
|
||||
"Location \u2192 http://example.com/browser/",
|
||||
{ name: "host", value: "example.com" });
|
||||
|
||||
vview.window.focus();
|
||||
|
||||
msg.scrollIntoView();
|
||||
sidebarClosed = jsterm.once("sidebar-closed");
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
yield sidebarClosed;
|
||||
|
||||
function* openSidebar(objName, expectedText, expectedObj) {
|
||||
msg = yield jsterm.execute(objName);
|
||||
ok(msg, "output message found");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(anchor, "object anchor");
|
||||
ok(body, "message body");
|
||||
ok(body.textContent.includes(expectedText), "message text check");
|
||||
|
||||
msg.scrollIntoView();
|
||||
yield EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
let vviewVar = yield jsterm.once("variablesview-fetched");
|
||||
vview = vviewVar._variablesView;
|
||||
ok(vview, "variables view object exists");
|
||||
|
||||
[result] = yield findVariableViewProperties(vviewVar, [
|
||||
expectedObj,
|
||||
], { webconsole: hud });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,77 @@
|
|||
/* -*- 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 users can inspect objects logged from cross-domain iframes -
|
||||
// bug 869003.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-869003-top-window.html";
|
||||
|
||||
add_task(function* () {
|
||||
// This test is slightly more involved: it opens the web console, then the
|
||||
// variables view for a given object, it updates a property in the view and
|
||||
// checks the result. We can get a timeout with debug builds on slower
|
||||
// machines.
|
||||
requestLongerTimeout(2);
|
||||
|
||||
yield loadTab("data:text/html;charset=utf8,<p>hello");
|
||||
let hud = yield openConsole();
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "console.log message",
|
||||
text: "foobar",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element");
|
||||
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(body, "message body");
|
||||
|
||||
let clickable = result.clickableElements[0];
|
||||
ok(clickable, "clickable object found");
|
||||
ok(body.textContent.includes('{ hello: "world!",'), "message text check");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let aVar = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(aVar, "variables view fetched");
|
||||
ok(aVar._variablesView, "variables view object");
|
||||
|
||||
[result] = yield findVariableViewProperties(aVar, [
|
||||
{ name: "hello", value: "world!" },
|
||||
{ name: "bug", value: 869003 },
|
||||
], { webconsole: hud });
|
||||
|
||||
let prop = result.matchedProp;
|
||||
ok(prop, "matched the |hello| property in the variables view");
|
||||
|
||||
// Check that property value updates work.
|
||||
aVar = yield updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "'omgtest'",
|
||||
webconsole: hud,
|
||||
});
|
||||
|
||||
info("onFetchAfterUpdate");
|
||||
|
||||
yield findVariableViewProperties(aVar, [
|
||||
{ name: "hello", value: "omgtest" },
|
||||
{ name: "bug", value: 869003 },
|
||||
], { webconsole: hud });
|
||||
});
|
||||
|
|
@ -0,0 +1,78 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that Ctrl-W closes the Browser Console and that Ctrl-W closes the
|
||||
// current tab when using the Web Console - bug 871156.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "data:text/html;charset=utf8,<title>bug871156</title>\n" +
|
||||
"<p>hello world";
|
||||
let firstTab = gBrowser.selectedTab;
|
||||
|
||||
Services.prefs.setBoolPref("browser.tabs.animate", false);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("browser.tabs.animate");
|
||||
});
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
let tabClosed = promise.defer();
|
||||
let toolboxDestroyed = promise.defer();
|
||||
let tabSelected = promise.defer();
|
||||
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabClose", function onTabClose() {
|
||||
gBrowser.tabContainer.removeEventListener("TabClose", onTabClose);
|
||||
info("tab closed");
|
||||
tabClosed.resolve(null);
|
||||
});
|
||||
|
||||
gBrowser.tabContainer.addEventListener("TabSelect", function onTabSelect() {
|
||||
gBrowser.tabContainer.removeEventListener("TabSelect", onTabSelect);
|
||||
if (gBrowser.selectedTab == firstTab) {
|
||||
info("tab selected");
|
||||
tabSelected.resolve(null);
|
||||
}
|
||||
});
|
||||
|
||||
toolbox.once("destroyed", () => {
|
||||
info("toolbox destroyed");
|
||||
toolboxDestroyed.resolve(null);
|
||||
});
|
||||
|
||||
// Get out of the web console initialization.
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey("w", { accelKey: true });
|
||||
});
|
||||
|
||||
yield promise.all([tabClosed.promise, toolboxDestroyed.promise,
|
||||
tabSelected.promise]);
|
||||
info("promise.all resolved. start testing the Browser Console");
|
||||
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "Browser Console opened");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
Services.obs.addObserver(function onDestroy() {
|
||||
Services.obs.removeObserver(onDestroy, "web-console-destroyed");
|
||||
ok(true, "the Browser Console closed");
|
||||
|
||||
deferred.resolve(null);
|
||||
}, "web-console-destroyed", false);
|
||||
|
||||
waitForFocus(() => {
|
||||
EventUtils.synthesizeKey("w", { accelKey: true }, hud.iframeWindow);
|
||||
}, hud.iframeWindow);
|
||||
|
||||
yield deferred.promise;
|
||||
});
|
||||
59
devtools/client/webconsole/test/browser_cached_messages.js
Normal file
59
devtools/client/webconsole/test/browser_cached_messages.js
Normal file
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- 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 to see if the cached messages are displayed when the console UI is
|
||||
// opened.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-webconsole-error-observer.html";
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
function test() {
|
||||
waitForExplicitFinish();
|
||||
|
||||
loadTab(TEST_URI).then(testOpenUI);
|
||||
}
|
||||
|
||||
function testOpenUI(aTestReopen) {
|
||||
openConsole().then((hud) => {
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "log Bazzle",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "error Bazzle",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "bazBug611032",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "cssColorBug611032",
|
||||
category: CATEGORY_CSS,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
],
|
||||
}).then(() => {
|
||||
closeConsole(gBrowser.selectedTab).then(() => {
|
||||
aTestReopen && info("will reopen the Web Console");
|
||||
executeSoon(aTestReopen ? testOpenUI : finishTest);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
160
devtools/client/webconsole/test/browser_console.js
Normal file
160
devtools/client/webconsole/test/browser_console.js
Normal file
|
|
@ -0,0 +1,160 @@
|
|||
/* -*- 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 the basic features of the Browser Console, bug 587757.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html?" + Date.now();
|
||||
const TEST_FILE = "chrome://mochitests/content/browser/devtools/client/" +
|
||||
"webconsole/test/test-cu-reporterror.js";
|
||||
|
||||
const TEST_XHR_ERROR_URI = `http://example.com/404.html?${Date.now()}`;
|
||||
|
||||
const TEST_IMAGE = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-image.png";
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let opened = waitForConsole();
|
||||
|
||||
let hud = HUDService.getBrowserConsole();
|
||||
ok(!hud, "browser console is not open");
|
||||
info("wait for the browser console to open with ctrl-shift-j");
|
||||
EventUtils.synthesizeKey("j", { accelKey: true, shiftKey: true }, window);
|
||||
|
||||
hud = yield opened;
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
yield consoleOpened(hud);
|
||||
});
|
||||
|
||||
function consoleOpened(hud) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
expectUncaughtException();
|
||||
executeSoon(() => {
|
||||
foobarExceptionBug587757();
|
||||
});
|
||||
|
||||
// Add a message from a chrome window.
|
||||
hud.iframeWindow.console.log("bug587757a");
|
||||
|
||||
// Check Cu.reportError stack.
|
||||
// Use another js script to not depend on the test file line numbers.
|
||||
Services.scriptloader.loadSubScript(TEST_FILE, hud.iframeWindow);
|
||||
|
||||
// Add a message from a content window.
|
||||
content.console.log("bug587757b");
|
||||
|
||||
// Test eval.
|
||||
hud.jsterm.execute("document.location.href");
|
||||
|
||||
// Check for network requests.
|
||||
let xhr = new XMLHttpRequest();
|
||||
xhr.onload = () => console.log("xhr loaded, status is: " + xhr.status);
|
||||
xhr.open("get", TEST_URI, true);
|
||||
xhr.send();
|
||||
|
||||
// Check for xhr error.
|
||||
let xhrErr = new XMLHttpRequest();
|
||||
xhrErr.onload = () => {
|
||||
console.log("xhr error loaded, status is: " + xhrErr.status);
|
||||
};
|
||||
xhrErr.open("get", TEST_XHR_ERROR_URI, true);
|
||||
xhrErr.send();
|
||||
|
||||
// Check that Fetch requests are categorized as "XHR".
|
||||
fetch(TEST_IMAGE).then(() => { console.log("fetch loaded"); });
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "chrome window console.log() is displayed",
|
||||
text: "bug587757a",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "Cu.reportError is displayed",
|
||||
text: "bug1141222",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
stacktrace: [{
|
||||
file: TEST_FILE,
|
||||
line: 2,
|
||||
}, {
|
||||
file: TEST_FILE,
|
||||
line: 4,
|
||||
},
|
||||
// Ignore the rest of the stack,
|
||||
// just assert Cu.reportError call site
|
||||
// and consoleOpened call
|
||||
]
|
||||
},
|
||||
{
|
||||
name: "content window console.log() is displayed",
|
||||
text: "bug587757b",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "jsterm eval result",
|
||||
text: "browser.xul",
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "exception message",
|
||||
text: "foobarExceptionBug587757",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
name: "network message",
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_INFO,
|
||||
isXhr: true,
|
||||
},
|
||||
{
|
||||
name: "xhr error message",
|
||||
text: "404.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_ERROR,
|
||||
isXhr: true,
|
||||
},
|
||||
{
|
||||
name: "network message",
|
||||
text: "test-image.png",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_INFO,
|
||||
isXhr: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function waitForConsole() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
Services.obs.addObserver(function observer(aSubject) {
|
||||
Services.obs.removeObserver(observer, "web-console-created");
|
||||
aSubject.QueryInterface(Ci.nsISupportsString);
|
||||
|
||||
let hud = HUDService.getBrowserConsole();
|
||||
ok(hud, "browser console is open");
|
||||
is(aSubject.data, hud.hudId, "notification hudId is correct");
|
||||
|
||||
executeSoon(() => deferred.resolve(hud));
|
||||
}, "web-console-created", false);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,92 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that exceptions from scripts loaded with the addon-sdk loader are
|
||||
// opened correctly in View Source from the Browser Console.
|
||||
// See bug 866950.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>hello world from bug 866950";
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(2);
|
||||
|
||||
let webconsole, browserconsole;
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
let {tab} = yield loadTab(TEST_URI);
|
||||
webconsole = yield openConsole(tab);
|
||||
ok(webconsole, "web console opened");
|
||||
|
||||
browserconsole = yield HUDService.toggleBrowserConsole();
|
||||
ok(browserconsole, "browser console opened");
|
||||
|
||||
// Cause an exception in a script loaded with the addon-sdk loader.
|
||||
let toolbox = gDevTools.getToolbox(webconsole.target);
|
||||
let oldPanels = toolbox._toolPanels;
|
||||
// non-iterable
|
||||
toolbox._toolPanels = {};
|
||||
|
||||
function fixToolbox() {
|
||||
toolbox._toolPanels = oldPanels;
|
||||
}
|
||||
|
||||
info("generate exception and wait for message");
|
||||
|
||||
executeSoon(() => {
|
||||
executeSoon(fixToolbox);
|
||||
expectUncaughtException();
|
||||
toolbox.getToolPanels();
|
||||
});
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: browserconsole,
|
||||
messages: [{
|
||||
text: "TypeError: this._toolPanels is not iterable",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
|
||||
fixToolbox();
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element found");
|
||||
let locationNode = msg
|
||||
.querySelector(".message .message-location > .frame-link");
|
||||
ok(locationNode, "message location element found");
|
||||
|
||||
let url = locationNode.getAttribute("data-url");
|
||||
info("location node url: " + url);
|
||||
ok(url.indexOf("resource://") === 0, "error comes from a subscript");
|
||||
|
||||
let viewSource = browserconsole.viewSource;
|
||||
let URL = null;
|
||||
let clickPromise = promise.defer();
|
||||
browserconsole.viewSourceInDebugger = (sourceURL) => {
|
||||
info("browserconsole.viewSourceInDebugger() was invoked: " + sourceURL);
|
||||
URL = sourceURL;
|
||||
clickPromise.resolve(null);
|
||||
};
|
||||
|
||||
msg.scrollIntoView();
|
||||
EventUtils.synthesizeMouse(locationNode, 2, 2, {},
|
||||
browserconsole.iframeWindow);
|
||||
|
||||
info("wait for click on locationNode");
|
||||
yield clickPromise.promise;
|
||||
|
||||
info("view-source url: " + URL);
|
||||
ok(URL, "we have some source URL after the click");
|
||||
isnot(URL.indexOf("toolbox.js"), -1,
|
||||
"we have the expected view source URL");
|
||||
is(URL.indexOf("->"), -1, "no -> in the URL given to view-source");
|
||||
|
||||
browserconsole.viewSourceInDebugger = viewSource;
|
||||
}
|
||||
}
|
||||
|
|
@ -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/ */
|
||||
|
||||
// Check that console.clear() does not clear the output of the browser console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>Bug 1296870";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
|
||||
info("Log a new message from the content page");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.console.log("msg");
|
||||
});
|
||||
yield waitForMessage("msg", hud);
|
||||
|
||||
info("Send a console.clear() from the content page");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.console.clear();
|
||||
});
|
||||
yield waitForMessage("Console was cleared", hud);
|
||||
|
||||
info("Check that the messages logged after the first clear are still displayed");
|
||||
isnot(hud.outputNode.textContent.indexOf("msg"), -1, "msg is in the output");
|
||||
});
|
||||
|
||||
function waitForMessage(message, webconsole) {
|
||||
return waitForMessages({
|
||||
webconsole,
|
||||
messages: [{
|
||||
text: message,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that clear output on page reload works - bug 705921.
|
||||
// Check that clear output and page reload remove the sidebar - bug 971967.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
Services.prefs.setBoolPref(PREF, false);
|
||||
registerCleanupFunction(() => Services.prefs.clearUserPref(PREF));
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
yield openSidebar("fooObj", { name: "testProp", value: "testValue" });
|
||||
|
||||
let sidebarClosed = hud.jsterm.once("sidebar-closed");
|
||||
hud.jsterm.clearOutput();
|
||||
yield sidebarClosed;
|
||||
|
||||
hud.jsterm.execute("console.log('foobarz1')");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
yield openSidebar("fooObj", { name: "testProp", value: "testValue" });
|
||||
|
||||
BrowserReload();
|
||||
|
||||
sidebarClosed = hud.jsterm.once("sidebar-closed");
|
||||
loadBrowser(gBrowser.selectedBrowser);
|
||||
yield sidebarClosed;
|
||||
|
||||
hud.jsterm.execute("console.log('foobarz2')");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
},
|
||||
{
|
||||
text: "foobarz2",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("foobarz1"), -1,
|
||||
"foobarz1 has been removed from output");
|
||||
|
||||
function* openSidebar(objName, expectedObj) {
|
||||
let msg = yield hud.jsterm.execute(objName);
|
||||
ok(msg, "output message found");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(anchor, "object anchor");
|
||||
ok(body, "message body");
|
||||
|
||||
yield EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
let vviewVar = yield hud.jsterm.once("variablesview-fetched");
|
||||
let vview = vviewVar._variablesView;
|
||||
ok(vview, "variables view object exists");
|
||||
|
||||
yield findVariableViewProperties(vviewVar, [
|
||||
expectedObj,
|
||||
], { webconsole: hud });
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the input field is focused when the console is opened.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "Dolske Digs Bacon",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
let outputItem = msg.querySelector(".message-body");
|
||||
ok(outputItem, "found a logged message");
|
||||
|
||||
let inputNode = hud.jsterm.inputNode;
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused, first");
|
||||
|
||||
yield waitForBlurredInput(inputNode);
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused, second time");
|
||||
|
||||
yield waitForBlurredInput(inputNode);
|
||||
|
||||
info("Setting a text selection and making sure a click does not re-focus");
|
||||
let selection = hud.iframeWindow.getSelection();
|
||||
selection.selectAllChildren(outputItem);
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, hud.outputNode);
|
||||
ok(!inputNode.getAttribute("focused"),
|
||||
"input node is not focused after drag");
|
||||
});
|
||||
|
||||
function waitForBlurredInput(inputNode) {
|
||||
return new Promise(resolve => {
|
||||
let lostFocus = () => {
|
||||
inputNode.removeEventListener("blur", lostFocus);
|
||||
ok(!inputNode.getAttribute("focused"), "input node is not focused");
|
||||
resolve();
|
||||
};
|
||||
inputNode.addEventListener("blur", lostFocus);
|
||||
document.getElementById("urlbar").click();
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,285 @@
|
|||
/* -*- 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 Console.jsm outputs messages to the Browser Console, bug 851231.
|
||||
|
||||
"use strict";
|
||||
|
||||
function onNewMessage(aEvent, aNewMessages) {
|
||||
for (let msg of aNewMessages) {
|
||||
// Messages that shouldn't be output contain the substring FAIL_TEST
|
||||
if (msg.node.textContent.includes("FAIL_TEST")) {
|
||||
ok(false, "Message shouldn't have been output: " + msg.node.textContent);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {console} = Cu.import("resource://gre/modules/Console.jsm", {});
|
||||
console.log("bug861338-log-cached");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "cached console.log message",
|
||||
text: "bug861338-log-cached",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
function testTrace() {
|
||||
console.trace();
|
||||
}
|
||||
|
||||
console.time("foobarTimer");
|
||||
let foobar = { bug851231prop: "bug851231value" };
|
||||
|
||||
console.log("bug851231-log");
|
||||
console.info("bug851231-info");
|
||||
console.warn("bug851231-warn");
|
||||
console.error("bug851231-error", foobar);
|
||||
console.debug("bug851231-debug");
|
||||
console.dir(document);
|
||||
testTrace();
|
||||
console.timeEnd("foobarTimer");
|
||||
|
||||
info("wait for the Console.jsm messages");
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "console.log output",
|
||||
text: "bug851231-log",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "console.info output",
|
||||
text: "bug851231-info",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_INFO,
|
||||
},
|
||||
{
|
||||
name: "console.warn output",
|
||||
text: "bug851231-warn",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
{
|
||||
name: "console.error output",
|
||||
text: /\bbug851231-error\b.+\{\s*bug851231prop:\s"bug851231value"\s*\}/,
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
objects: true,
|
||||
},
|
||||
{
|
||||
name: "console.debug output",
|
||||
text: "bug851231-debug",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "console.trace output",
|
||||
consoleTrace: {
|
||||
file: "browser_console_consolejsm_output.js",
|
||||
fn: "testTrace",
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "console.dir output",
|
||||
consoleDir: /XULDocument\s+.+\s+chrome:\/\/.+\/browser\.xul/,
|
||||
},
|
||||
{
|
||||
name: "console.time output",
|
||||
consoleTime: "foobarTimer",
|
||||
},
|
||||
{
|
||||
name: "console.timeEnd output",
|
||||
consoleTimeEnd: "foobarTimer",
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let consoleErrorMsg = results[3];
|
||||
ok(consoleErrorMsg, "console.error message element found");
|
||||
let clickable = consoleErrorMsg.clickableElements[0];
|
||||
ok(clickable, "clickable object found for console.error");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
let onFetch = (aEvent, aVar) => {
|
||||
// Skip the notification from console.dir variablesview-fetched.
|
||||
if (aVar._variablesView != hud.jsterm._variablesView) {
|
||||
return;
|
||||
}
|
||||
hud.jsterm.off("variablesview-fetched", onFetch);
|
||||
|
||||
deferred.resolve(aVar);
|
||||
};
|
||||
|
||||
hud.jsterm.on("variablesview-fetched", onFetch);
|
||||
|
||||
clickable.scrollIntoView(false);
|
||||
|
||||
info("wait for variablesview-fetched");
|
||||
executeSoon(() =>
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow));
|
||||
|
||||
let varView = yield deferred.promise;
|
||||
ok(varView, "object inspector opened on click");
|
||||
|
||||
yield findVariableViewProperties(varView, [{
|
||||
name: "bug851231prop",
|
||||
value: "bug851231value",
|
||||
}], { webconsole: hud });
|
||||
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
||||
add_task(function* testPrefix() {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
|
||||
let consoleOptions = {
|
||||
maxLogLevel: "error",
|
||||
prefix: "Log Prefix",
|
||||
};
|
||||
let console2 = new ConsoleAPI(consoleOptions);
|
||||
console2.error("Testing a prefix");
|
||||
console2.log("FAIL_TEST: Below the maxLogLevel");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
hud.ui.on("new-messages", onNewMessage);
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "cached console.error message",
|
||||
prefix: "Log Prefix:",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Testing a prefix",
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.ui.off("new-messages", onNewMessage);
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
||||
add_task(function* testMaxLogLevelPrefMissing() {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
|
||||
let consoleOptions = {
|
||||
maxLogLevel: "error",
|
||||
maxLogLevelPref: "testing.maxLogLevel",
|
||||
};
|
||||
let console = new ConsoleAPI(consoleOptions);
|
||||
|
||||
is(Services.prefs.getPrefType(consoleOptions.maxLogLevelPref),
|
||||
Services.prefs.PREF_INVALID,
|
||||
"Check log level pref is missing");
|
||||
|
||||
// Since the maxLogLevelPref doesn't exist, we should fallback to the passed
|
||||
// maxLogLevel of "error".
|
||||
console.warn("FAIL_TEST: Below the maxLogLevel");
|
||||
console.error("Error should be shown");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
|
||||
hud.ui.on("new-messages", onNewMessage);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "defaulting to error level",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Error should be shown",
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.ui.off("new-messages", onNewMessage);
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
||||
add_task(function* testMaxLogLevelPref() {
|
||||
let consoleStorage = Cc["@mozilla.org/consoleAPI-storage;1"];
|
||||
let storage = consoleStorage.getService(Ci.nsIConsoleAPIStorage);
|
||||
storage.clearEvents();
|
||||
|
||||
let {ConsoleAPI} = Cu.import("resource://gre/modules/Console.jsm", {});
|
||||
let consoleOptions = {
|
||||
maxLogLevel: "error",
|
||||
maxLogLevelPref: "testing.maxLogLevel",
|
||||
};
|
||||
|
||||
info("Setting the pref to warn");
|
||||
Services.prefs.setCharPref(consoleOptions.maxLogLevelPref, "Warn");
|
||||
|
||||
let console = new ConsoleAPI(consoleOptions);
|
||||
|
||||
is(console.maxLogLevel, "warn", "Check pref was read at initialization");
|
||||
|
||||
console.info("FAIL_TEST: info is below the maxLogLevel");
|
||||
console.error("Error should be shown");
|
||||
console.warn("Warn should be shown due to the initial pref value");
|
||||
|
||||
info("Setting the pref to info");
|
||||
Services.prefs.setCharPref(consoleOptions.maxLogLevelPref, "INFO");
|
||||
is(console.maxLogLevel, "info", "Check pref was lowercased");
|
||||
|
||||
console.info("info should be shown due to the pref change being observed");
|
||||
|
||||
info("Clearing the pref");
|
||||
Services.prefs.clearUserPref(consoleOptions.maxLogLevelPref);
|
||||
|
||||
console.warn("FAIL_TEST: Shouldn't be shown due to defaulting to error");
|
||||
console.error("Should be shown due to defaulting to error");
|
||||
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
hud.ui.on("new-messages", onNewMessage);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "error > warn",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Error should be shown",
|
||||
},
|
||||
{
|
||||
name: "warn is the inital pref value",
|
||||
severity: SEVERITY_WARNING,
|
||||
text: "Warn should be shown due to the initial pref value",
|
||||
},
|
||||
{
|
||||
name: "pref changed to info",
|
||||
severity: SEVERITY_INFO,
|
||||
text: "info should be shown due to the pref change being observed",
|
||||
},
|
||||
{
|
||||
name: "default to intial maxLogLevel if pref is removed",
|
||||
severity: SEVERITY_ERROR,
|
||||
text: "Should be shown due to defaulting to error",
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.ui.off("new-messages", onNewMessage);
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
});
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the `copy` console helper works as intended.
|
||||
|
||||
"use strict";
|
||||
|
||||
var gWebConsole, gJSTerm;
|
||||
|
||||
var TEXT = "Lorem ipsum dolor sit amet, consectetur adipisicing " +
|
||||
"elit, sed do eiusmod tempor incididunt ut labore et dolore magna " +
|
||||
"aliqua. Ut enim ad minim veniam, quis nostrud exercitation ullamco " +
|
||||
"laboris nisi ut aliquip ex ea commodo consequat. Duis aute irure " +
|
||||
"dolor in reprehenderit in voluptate velit esse cillum dolore eu " +
|
||||
"fugiat nulla pariatur. Excepteur sint occaecat cupidatat non " +
|
||||
"proident, sunt in culpa qui officia deserunt mollit anim id est laborum." +
|
||||
new Date();
|
||||
|
||||
var ID = "select-me";
|
||||
|
||||
add_task(function* init() {
|
||||
yield loadTab("data:text/html;charset=utf-8," +
|
||||
"<body>" +
|
||||
" <div>" +
|
||||
" <h1>Testing copy command</h1>" +
|
||||
" <p>This is some example text</p>" +
|
||||
" <p id='select-me'>" + TEXT + "</p>" +
|
||||
" </div>" +
|
||||
" <div><p></p></div>" +
|
||||
"</body>");
|
||||
|
||||
gWebConsole = yield openConsole();
|
||||
gJSTerm = gWebConsole.jsterm;
|
||||
});
|
||||
|
||||
add_task(function* testCopy() {
|
||||
let RANDOM = Math.random();
|
||||
let string = "Text: " + RANDOM;
|
||||
let obj = {a: 1, b: "foo", c: RANDOM};
|
||||
|
||||
let samples = [
|
||||
[RANDOM, RANDOM],
|
||||
[JSON.stringify(string), string],
|
||||
[obj.toSource(), JSON.stringify(obj, null, " ")],
|
||||
[
|
||||
"$('#" + ID + "')",
|
||||
content.document.getElementById(ID).outerHTML
|
||||
]
|
||||
];
|
||||
for (let [source, reference] of samples) {
|
||||
let deferredResult = promise.defer();
|
||||
|
||||
SimpleTest.waitForClipboard(
|
||||
"" + reference,
|
||||
() => {
|
||||
let command = "copy(" + source + ")";
|
||||
info("Attempting to copy: " + source);
|
||||
info("Executing command: " + command);
|
||||
gJSTerm.execute(command, msg => {
|
||||
is(msg, undefined, "Command success: " + command);
|
||||
});
|
||||
},
|
||||
deferredResult.resolve,
|
||||
deferredResult.reject);
|
||||
|
||||
yield deferredResult.promise;
|
||||
}
|
||||
});
|
||||
|
||||
add_task(function* cleanup() {
|
||||
gWebConsole = gJSTerm = null;
|
||||
gBrowser.removeTab(gBrowser.selectedTab);
|
||||
finishTest();
|
||||
});
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* globals goDoCommand */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test copying of the entire console message when right-clicked
|
||||
// with no other text selected. See Bug 1100562.
|
||||
|
||||
add_task(function* () {
|
||||
let hud;
|
||||
let outputNode;
|
||||
let contextMenu;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/test/test-console.html";
|
||||
|
||||
const { tab, browser } = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole(tab);
|
||||
outputNode = hud.outputNode;
|
||||
contextMenu = hud.iframeWindow.document.getElementById("output-contextmenu");
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
hud = outputNode = contextMenu = null;
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
yield ContentTask.spawn(browser, {}, function* () {
|
||||
let button = content.document.getElementById("testTrace");
|
||||
button.click();
|
||||
});
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "bug 1100562",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
lines: 1,
|
||||
},
|
||||
{
|
||||
name: "console.trace output",
|
||||
consoleTrace: true,
|
||||
lines: 3,
|
||||
},
|
||||
]
|
||||
});
|
||||
|
||||
outputNode.focus();
|
||||
|
||||
for (let result of results) {
|
||||
let message = [...result.matched][0];
|
||||
|
||||
yield waitForContextMenu(contextMenu, message, () => {
|
||||
let copyItem = contextMenu.querySelector("#cMenu_copy");
|
||||
copyItem.doCommand();
|
||||
|
||||
let controller = top.document.commandDispatcher
|
||||
.getControllerForCommand("cmd_copy");
|
||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||
});
|
||||
|
||||
let clipboardText;
|
||||
|
||||
yield waitForClipboardPromise(
|
||||
() => goDoCommand("cmd_copy"),
|
||||
(str) => {
|
||||
clipboardText = str;
|
||||
return message.textContent == clipboardText;
|
||||
}
|
||||
);
|
||||
|
||||
ok(clipboardText, "Clipboard text was found and saved");
|
||||
|
||||
let lines = clipboardText.split("\n");
|
||||
ok(lines.length > 0, "There is at least one newline in the message");
|
||||
is(lines.pop(), "", "There is a newline at the end");
|
||||
is(lines.length, result.lines, `There are ${result.lines} lines in the message`);
|
||||
|
||||
// Test the first line for "timestamp message repeat file:line"
|
||||
let firstLine = lines.shift();
|
||||
ok(/^[\d:.]+ .+ \d+ .+:\d+$/.test(firstLine),
|
||||
"The message's first line has the right format");
|
||||
|
||||
// Test the remaining lines (stack trace) for "TABfunctionName sourceURL:line:col"
|
||||
for (let line of lines) {
|
||||
ok(/^\t.+ .+:\d+:\d+$/.test(line), "The stack trace line has the right format");
|
||||
}
|
||||
}
|
||||
|
||||
yield closeConsole(tab);
|
||||
yield finishTest();
|
||||
});
|
||||
|
|
@ -0,0 +1,88 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that Dead Objects do not break the Web/Browser Consoles.
|
||||
// See bug 883649.
|
||||
// This test does:
|
||||
// - opens a new tab,
|
||||
// - opens the Browser Console,
|
||||
// - stores a reference to the content document of the tab on the chrome
|
||||
// window object,
|
||||
// - closes the tab,
|
||||
// - tries to use the object that was pointing to the now-defunct content
|
||||
// document. This is the dead object.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>dead objects!";
|
||||
|
||||
function test() {
|
||||
let hud = null;
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref("devtools.chrome.enabled");
|
||||
});
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
Services.prefs.setBoolPref("devtools.chrome.enabled", true);
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
info("open the browser console");
|
||||
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
jsterm.clearOutput();
|
||||
|
||||
// Add the reference to the content document.
|
||||
yield jsterm.execute("Cu = Components.utils;" +
|
||||
"Cu.import('resource://gre/modules/Services.jsm');" +
|
||||
"chromeWindow = Services.wm.getMostRecentWindow('" +
|
||||
"navigator:browser');" +
|
||||
"foobarzTezt = chromeWindow.content.document;" +
|
||||
"delete chromeWindow");
|
||||
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
let msg = yield jsterm.execute("foobarzTezt");
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf("[object DeadObject]"), -1,
|
||||
"dead object found");
|
||||
|
||||
jsterm.setInputValue("foobarzTezt");
|
||||
|
||||
for (let c of ".hello") {
|
||||
EventUtils.synthesizeKey(c, {}, hud.iframeWindow);
|
||||
}
|
||||
|
||||
yield jsterm.execute();
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf("can't access dead object"), -1,
|
||||
"'cannot access dead object' message found");
|
||||
|
||||
// Click the second execute output.
|
||||
let clickable = msg.querySelector("a");
|
||||
ok(clickable, "clickable object found");
|
||||
isnot(clickable.textContent.indexOf("[object DeadObject]"), -1,
|
||||
"message text check");
|
||||
|
||||
msg.scrollIntoView();
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouseAtCenter(clickable, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
yield jsterm.once("variablesview-fetched");
|
||||
ok(true, "variables view fetched");
|
||||
|
||||
msg = yield jsterm.execute("delete window.foobarzTezt; 2013-26");
|
||||
|
||||
isnot(msg.textContent.indexOf("1987"), -1, "result message found");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,79 @@
|
|||
/* -*- 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 errors and CSS warnings open view source when their source link
|
||||
// is clicked in the Browser Console. See bug 877778.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>hello world from bug 877778 " +
|
||||
"<button onclick='foobar.explode()' " +
|
||||
"style='test-color: green-please'>click!</button>";
|
||||
|
||||
add_task(function* () {
|
||||
yield new Promise(resolve => {
|
||||
SpecialPowers.pushPrefEnv({"set": [
|
||||
["devtools.browserconsole.filter.cssparser", true]
|
||||
]}, resolve);
|
||||
});
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
info("generate exception and wait for the message");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let button = content.document.querySelector("button");
|
||||
button.click();
|
||||
});
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "ReferenceError: foobar is not defined",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "Unknown property \u2018test-color\u2019",
|
||||
category: CATEGORY_CSS,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let viewSourceCalled = false;
|
||||
|
||||
let viewSource = hud.viewSource;
|
||||
hud.viewSource = () => {
|
||||
viewSourceCalled = true;
|
||||
};
|
||||
|
||||
for (let result of results) {
|
||||
viewSourceCalled = false;
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element found for: " + result.text);
|
||||
ok(!msg.classList.contains("filtered-by-type"), "message element is not filtered");
|
||||
let selector = ".message .message-location .frame-link-source";
|
||||
let locationNode = msg.querySelector(selector);
|
||||
ok(locationNode, "message location element found");
|
||||
|
||||
locationNode.click();
|
||||
|
||||
ok(viewSourceCalled, "view source opened");
|
||||
}
|
||||
|
||||
hud.viewSource = viewSource;
|
||||
|
||||
yield finishTest();
|
||||
});
|
||||
60
devtools/client/webconsole/test/browser_console_filters.js
Normal file
60
devtools/client/webconsole/test/browser_console_filters.js
Normal file
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that the Browser Console does not use the same filter prefs as the Web
|
||||
// Console. See bug 878186.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>browser console filters";
|
||||
const WEB_CONSOLE_PREFIX = "devtools.webconsole.filter.";
|
||||
const BROWSER_CONSOLE_PREFIX = "devtools.browserconsole.filter.";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
info("open the web console");
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "web console opened");
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (web console)");
|
||||
|
||||
info("toggle 'exception' filter");
|
||||
hud.setFilterState("exception", false);
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), false,
|
||||
"'exception' filter is disabled (web console)");
|
||||
|
||||
hud.setFilterState("exception", true);
|
||||
|
||||
// We need to let the console opening event loop to finish.
|
||||
let deferred = promise.defer();
|
||||
executeSoon(() => closeConsole().then(() => deferred.resolve(null)));
|
||||
yield deferred.promise;
|
||||
|
||||
info("web console closed");
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (web console)");
|
||||
|
||||
info("toggle 'exception' filter");
|
||||
hud.setFilterState("exception", false);
|
||||
|
||||
is(Services.prefs.getBoolPref(BROWSER_CONSOLE_PREFIX + "exception"), false,
|
||||
"'exception' filter is disabled (browser console)");
|
||||
is(Services.prefs.getBoolPref(WEB_CONSOLE_PREFIX + "exception"), true,
|
||||
"'exception' filter is enabled (web console)");
|
||||
|
||||
hud.setFilterState("exception", true);
|
||||
});
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/*
|
||||
* Bug 922161 - Hide Browser Console JS input field if devtools.chrome.enabled
|
||||
* is false.
|
||||
* when devtools.chrome.enabled then
|
||||
* -browser console jsterm should be enabled
|
||||
* -browser console object inspector properties should be set.
|
||||
* -webconsole jsterm should be enabled
|
||||
* -webconsole object inspector properties should be set.
|
||||
*
|
||||
* when devtools.chrome.enabled == false then
|
||||
* -browser console jsterm should be disabled
|
||||
* -browser console object inspector properties should not be set.
|
||||
* -webconsole jsterm should be enabled
|
||||
* -webconsole object inspector properties should be set.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
function testObjectInspectorPropertiesAreNotSet(variablesView) {
|
||||
is(variablesView.eval, null, "vview.eval is null");
|
||||
is(variablesView.switch, null, "vview.switch is null");
|
||||
is(variablesView.delete, null, "vview.delete is null");
|
||||
}
|
||||
|
||||
function* getVariablesView(hud) {
|
||||
function openVariablesView(event, vview) {
|
||||
deferred.resolve(vview._variablesView);
|
||||
}
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
// Filter out other messages to ensure ours stays visible.
|
||||
hud.ui.filterBox.value = "browser_console_hide_jsterm_test";
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
hud.jsterm.execute("new Object({ browser_console_hide_jsterm_test: true })");
|
||||
|
||||
let [message] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "Object { browser_console_hide_jsterm_test: true }",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.once("variablesview-fetched", openVariablesView);
|
||||
|
||||
let anchor = [...message.matched][0].querySelector("a");
|
||||
|
||||
executeSoon(() =>
|
||||
EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow)
|
||||
);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testJSTermIsVisible(hud) {
|
||||
let inputContainer = hud.ui.window.document
|
||||
.querySelector(".jsterm-input-container");
|
||||
isnot(inputContainer.style.display, "none", "input is visible");
|
||||
}
|
||||
|
||||
function testObjectInspectorPropertiesAreSet(variablesView) {
|
||||
isnot(variablesView.eval, null, "vview.eval is set");
|
||||
isnot(variablesView.switch, null, "vview.switch is set");
|
||||
isnot(variablesView.delete, null, "vview.delete is set");
|
||||
}
|
||||
|
||||
function testJSTermIsNotVisible(hud) {
|
||||
let inputContainer = hud.ui.window.document
|
||||
.querySelector(".jsterm-input-container");
|
||||
is(inputContainer.style.display, "none", "input is not visible");
|
||||
}
|
||||
|
||||
function* testRunner() {
|
||||
let browserConsole, webConsole, variablesView;
|
||||
|
||||
Services.prefs.setBoolPref("devtools.chrome.enabled", true);
|
||||
|
||||
browserConsole = yield HUDService.toggleBrowserConsole();
|
||||
variablesView = yield getVariablesView(browserConsole);
|
||||
testJSTermIsVisible(browserConsole);
|
||||
testObjectInspectorPropertiesAreSet(variablesView);
|
||||
|
||||
let {tab: browserTab} = yield loadTab("data:text/html;charset=utf8,hello world");
|
||||
webConsole = yield openConsole(browserTab);
|
||||
variablesView = yield getVariablesView(webConsole);
|
||||
testJSTermIsVisible(webConsole);
|
||||
testObjectInspectorPropertiesAreSet(variablesView);
|
||||
yield closeConsole(browserTab);
|
||||
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
Services.prefs.setBoolPref("devtools.chrome.enabled", false);
|
||||
|
||||
browserConsole = yield HUDService.toggleBrowserConsole();
|
||||
variablesView = yield getVariablesView(browserConsole);
|
||||
testJSTermIsNotVisible(browserConsole);
|
||||
testObjectInspectorPropertiesAreNotSet(variablesView);
|
||||
|
||||
webConsole = yield openConsole(browserTab);
|
||||
variablesView = yield getVariablesView(webConsole);
|
||||
testJSTermIsVisible(webConsole);
|
||||
testObjectInspectorPropertiesAreSet(variablesView);
|
||||
yield closeConsole(browserTab);
|
||||
}
|
||||
|
||||
function test() {
|
||||
Task.spawn(testRunner).then(finishTest);
|
||||
}
|
||||
|
|
@ -0,0 +1,119 @@
|
|||
/* -*- 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 console command input is persisted across toolbox loads.
|
||||
// See Bug 943306.
|
||||
|
||||
"use strict";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"persisting history - bug 943306";
|
||||
const INPUT_HISTORY_COUNT = 10;
|
||||
|
||||
add_task(function* () {
|
||||
info("Setting custom input history pref to " + INPUT_HISTORY_COUNT);
|
||||
Services.prefs.setIntPref("devtools.webconsole.inputHistoryCount",
|
||||
INPUT_HISTORY_COUNT);
|
||||
|
||||
// First tab: run a bunch of commands and then make sure that you can
|
||||
// navigate through their history.
|
||||
yield loadTab(TEST_URI);
|
||||
let hud1 = yield openConsole();
|
||||
is(JSON.stringify(hud1.jsterm.history), "[]",
|
||||
"No history on first tab initially");
|
||||
yield populateInputHistory(hud1);
|
||||
is(JSON.stringify(hud1.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"First tab has populated history");
|
||||
|
||||
// Second tab: Just make sure that you can navigate through the history
|
||||
// generated by the first tab.
|
||||
yield loadTab(TEST_URI);
|
||||
let hud2 = yield openConsole();
|
||||
is(JSON.stringify(hud2.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"Second tab has populated history");
|
||||
yield testNaviatingHistoryInUI(hud2);
|
||||
is(JSON.stringify(hud2.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9",""]',
|
||||
"An empty entry has been added in the second tab due to history perusal");
|
||||
|
||||
// Third tab: Should have the same history as first tab, but if we run a
|
||||
// command, then the history of the first and second shouldn't be affected
|
||||
yield loadTab(TEST_URI);
|
||||
let hud3 = yield openConsole();
|
||||
is(JSON.stringify(hud3.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"Third tab has populated history");
|
||||
|
||||
// Set input value separately from execute so UP arrow accurately navigates
|
||||
// history.
|
||||
hud3.jsterm.setInputValue('"hello from third tab"');
|
||||
hud3.jsterm.execute();
|
||||
|
||||
is(JSON.stringify(hud1.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9"]',
|
||||
"First tab history hasn't changed due to command in third tab");
|
||||
is(JSON.stringify(hud2.jsterm.history),
|
||||
'["0","1","2","3","4","5","6","7","8","9",""]',
|
||||
"Second tab history hasn't changed due to command in third tab");
|
||||
is(JSON.stringify(hud3.jsterm.history),
|
||||
'["1","2","3","4","5","6","7","8","9","\\"hello from third tab\\""]',
|
||||
"Third tab has updated history (and purged the first result) after " +
|
||||
"running a command");
|
||||
|
||||
// Fourth tab: Should have the latest command from the third tab, followed
|
||||
// by the rest of the history from the first tab.
|
||||
yield loadTab(TEST_URI);
|
||||
let hud4 = yield openConsole();
|
||||
is(JSON.stringify(hud4.jsterm.history),
|
||||
'["1","2","3","4","5","6","7","8","9","\\"hello from third tab\\""]',
|
||||
"Fourth tab has most recent history");
|
||||
|
||||
yield hud4.jsterm.clearHistory();
|
||||
is(JSON.stringify(hud4.jsterm.history), "[]",
|
||||
"Clearing history for a tab works");
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud5 = yield openConsole();
|
||||
is(JSON.stringify(hud5.jsterm.history), "[]",
|
||||
"Clearing history carries over to a new tab");
|
||||
|
||||
info("Clearing custom input history pref");
|
||||
Services.prefs.clearUserPref("devtools.webconsole.inputHistoryCount");
|
||||
});
|
||||
|
||||
/**
|
||||
* Populate the history by running the following commands:
|
||||
* [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
|
||||
*/
|
||||
function* populateInputHistory(hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
for (let i = 0; i < INPUT_HISTORY_COUNT; i++) {
|
||||
// Set input value separately from execute so UP arrow accurately navigates
|
||||
// history.
|
||||
jsterm.setInputValue(i);
|
||||
jsterm.execute();
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check pressing up results in history traversal like:
|
||||
* [9, 8, 7, 6, 5, 4, 3, 2, 1, 0]
|
||||
*/
|
||||
function* testNaviatingHistoryInUI(hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
jsterm.focus();
|
||||
|
||||
// Count backwards from original input and make sure that pressing up
|
||||
// restores this.
|
||||
for (let i = INPUT_HISTORY_COUNT - 1; i >= 0; i--) {
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
is(jsterm.getInputValue(), i, "Pressing up restores last input");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,114 @@
|
|||
/* -*- 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 cached messages from nested iframes are displayed in the
|
||||
// Web/Browser Console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-consoleiframes.html";
|
||||
|
||||
const expectedMessages = [
|
||||
{
|
||||
text: "main file",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "blah",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR
|
||||
},
|
||||
{
|
||||
text: "iframe 2",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG
|
||||
},
|
||||
{
|
||||
text: "iframe 3",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG
|
||||
}
|
||||
];
|
||||
|
||||
// "iframe 1" console messages can be coalesced into one if they follow each
|
||||
// other in the sequence of messages (depending on timing). If they do not, then
|
||||
// they will be displayed in the console output independently, as separate
|
||||
// messages. This is why we need to match any of the following two rules.
|
||||
const expectedMessagesAny = [
|
||||
{
|
||||
name: "iframe 1 (count: 2)",
|
||||
text: "iframe 1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
count: 2
|
||||
},
|
||||
{
|
||||
name: "iframe 1 (repeats: 2)",
|
||||
text: "iframe 1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 2
|
||||
},
|
||||
];
|
||||
|
||||
add_task(function* () {
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "web console opened");
|
||||
|
||||
yield testWebConsole(hud);
|
||||
yield closeConsole();
|
||||
info("web console closed");
|
||||
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
yield testBrowserConsole(hud);
|
||||
yield closeConsole();
|
||||
});
|
||||
|
||||
function* testWebConsole(hud) {
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
});
|
||||
|
||||
info("first messages matched");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessagesAny,
|
||||
matchCondition: "any",
|
||||
});
|
||||
}
|
||||
|
||||
function* testBrowserConsole(hud) {
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
// TODO: The browser console doesn't show page's console.log statements
|
||||
// in e10s windows. See Bug 1241289.
|
||||
if (Services.appinfo.browserTabsRemoteAutostart) {
|
||||
todo(false, "Bug 1241289");
|
||||
return;
|
||||
}
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
});
|
||||
|
||||
info("first messages matched");
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessagesAny,
|
||||
matchCondition: "any",
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/* -*- 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 basic keyboard shortcuts work in the web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
info("dump some spew into the console for scrolling");
|
||||
hud.jsterm.execute("(function() { for (var i = 0; i < 100; i++) { " +
|
||||
"console.log('foobarz' + i);" +
|
||||
"}})();");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz99",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
let currentPosition = hud.ui.outputWrapper.scrollTop;
|
||||
let bottom = currentPosition;
|
||||
|
||||
EventUtils.synthesizeKey("VK_PAGE_UP", {});
|
||||
isnot(hud.ui.outputWrapper.scrollTop, currentPosition,
|
||||
"scroll position changed after page up");
|
||||
|
||||
currentPosition = hud.ui.outputWrapper.scrollTop;
|
||||
EventUtils.synthesizeKey("VK_PAGE_DOWN", {});
|
||||
ok(hud.ui.outputWrapper.scrollTop > currentPosition,
|
||||
"scroll position now at bottom");
|
||||
|
||||
EventUtils.synthesizeKey("VK_HOME", {});
|
||||
is(hud.ui.outputWrapper.scrollTop, 0, "scroll position now at top");
|
||||
|
||||
EventUtils.synthesizeKey("VK_END", {});
|
||||
|
||||
let scrollTop = hud.ui.outputWrapper.scrollTop;
|
||||
ok(scrollTop > 0 && Math.abs(scrollTop - bottom) <= 5,
|
||||
"scroll position now at bottom");
|
||||
|
||||
info("try ctrl-l to clear output");
|
||||
executeSoon(() => {
|
||||
let clearShortcut;
|
||||
if (Services.appinfo.OS === "Darwin") {
|
||||
clearShortcut = WCUL10n.getStr("webconsole.clear.keyOSX");
|
||||
} else {
|
||||
clearShortcut = WCUL10n.getStr("webconsole.clear.key");
|
||||
}
|
||||
synthesizeKeyShortcut(clearShortcut);
|
||||
});
|
||||
yield hud.jsterm.once("messages-cleared");
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("foobarz1"), -1, "output cleared");
|
||||
is(hud.jsterm.inputNode.getAttribute("focused"), "true",
|
||||
"jsterm input is focused");
|
||||
|
||||
info("try ctrl-f to focus filter");
|
||||
synthesizeKeyShortcut(WCUL10n.getStr("webconsole.find.key"));
|
||||
ok(!hud.jsterm.inputNode.getAttribute("focused"),
|
||||
"jsterm input is not focused");
|
||||
is(hud.ui.filterBox.getAttribute("focused"), "true",
|
||||
"filter input is focused");
|
||||
|
||||
if (Services.appinfo.OS == "Darwin") {
|
||||
ok(hud.ui.getFilterState("network"), "network category is enabled");
|
||||
EventUtils.synthesizeKey("t", { ctrlKey: true });
|
||||
ok(!hud.ui.getFilterState("network"), "accesskey for Network works");
|
||||
EventUtils.synthesizeKey("t", { ctrlKey: true });
|
||||
ok(hud.ui.getFilterState("network"), "accesskey for Network works (again)");
|
||||
} else {
|
||||
EventUtils.synthesizeKey("N", { altKey: true });
|
||||
let net = hud.ui.document.querySelector("toolbarbutton[category=net]");
|
||||
is(hud.ui.document.activeElement, net,
|
||||
"accesskey for Network category focuses the Net button");
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that objects given to console.log() are inspectable.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab("data:text/html;charset=utf8,test for bug 676722 - " +
|
||||
"inspectable objects for window.console");
|
||||
|
||||
let hud = yield openConsole();
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
yield hud.jsterm.execute("myObj = {abba: 'omgBug676722'}");
|
||||
hud.jsterm.execute("console.log('fooBug676722', myObj)");
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "fooBug676722",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...result.matched][0];
|
||||
ok(msg, "message element");
|
||||
|
||||
let body = msg.querySelector(".message-body");
|
||||
ok(body, "message body");
|
||||
|
||||
let clickable = result.clickableElements[0];
|
||||
ok(clickable, "the console.log() object anchor was found");
|
||||
ok(body.textContent.includes('{ abba: "omgBug676722" }'),
|
||||
"clickable node content is correct");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "object inspector opened on click");
|
||||
|
||||
yield findVariableViewProperties(varView, [{
|
||||
name: "abba",
|
||||
value: "omgBug676722",
|
||||
}], { webconsole: hud });
|
||||
});
|
||||
|
|
@ -0,0 +1,101 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that native getters and setters for DOM elements work as expected in
|
||||
// variables view - bug 870220.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<title>bug870220</title>\n" +
|
||||
"<p>hello world\n<p>native getters!";
|
||||
|
||||
requestLongerTimeout(2);
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
jsterm.execute("document");
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "HTMLDocument \u2192 data:text/html;charset=utf8",
|
||||
category: CATEGORY_OUTPUT,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let clickable = result.clickableElements[0];
|
||||
ok(clickable, "clickable object found");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let fetchedVar = yield jsterm.once("variablesview-fetched");
|
||||
|
||||
let variablesView = fetchedVar._variablesView;
|
||||
ok(variablesView, "variables view object");
|
||||
|
||||
let results = yield findVariableViewProperties(fetchedVar, [
|
||||
{ name: "title", value: "bug870220" },
|
||||
{ name: "bgColor" },
|
||||
], { webconsole: hud });
|
||||
|
||||
let prop = results[1].matchedProp;
|
||||
ok(prop, "matched the |bgColor| property in the variables view");
|
||||
|
||||
// Check that property value updates work.
|
||||
let updatedVar = yield updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "'red'",
|
||||
webconsole: hud,
|
||||
});
|
||||
|
||||
info("on fetch after background update");
|
||||
|
||||
jsterm.clearOutput(true);
|
||||
jsterm.execute("document.bgColor");
|
||||
|
||||
[result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "red",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}],
|
||||
});
|
||||
|
||||
yield findVariableViewProperties(updatedVar, [
|
||||
{ name: "bgColor", value: "red" },
|
||||
], { webconsole: hud });
|
||||
|
||||
jsterm.execute("$$('p')");
|
||||
|
||||
[result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "Array [",
|
||||
category: CATEGORY_OUTPUT,
|
||||
objects: true,
|
||||
}],
|
||||
});
|
||||
|
||||
clickable = result.clickableElements[0];
|
||||
ok(clickable, "clickable object found");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
fetchedVar = yield jsterm.once("variablesview-fetched");
|
||||
|
||||
yield findVariableViewProperties(fetchedVar, [
|
||||
{ name: "0.textContent", value: /hello world/ },
|
||||
{ name: "1.textContent", value: /native getters/ },
|
||||
], { webconsole: hud });
|
||||
});
|
||||
|
|
@ -0,0 +1,81 @@
|
|||
/* -*- 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 the navigation marker shows on page reload - bug 793996.
|
||||
|
||||
"use strict";
|
||||
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
var hud;
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole();
|
||||
|
||||
yield consoleOpened();
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserReload();
|
||||
yield loaded;
|
||||
|
||||
yield onReload();
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf("foobarz1"), -1,
|
||||
"foobarz1 is still in the output");
|
||||
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
|
||||
hud = null;
|
||||
});
|
||||
|
||||
function consoleOpened() {
|
||||
ok(hud, "Web Console opened");
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("foobarz1");
|
||||
});
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz1",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
function onReload() {
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("foobarz2");
|
||||
});
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "page reload",
|
||||
text: "test-console.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "foobarz2",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "navigation marker",
|
||||
text: "test-console.html",
|
||||
type: Messages.NavigationMarker,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that network log messages bring up the network panel.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_NETWORK_REQUEST_URI =
|
||||
"http://example.com/browser/devtools/client/webconsole/test/" +
|
||||
"test-network-request.html";
|
||||
|
||||
add_task(function* () {
|
||||
let finishedRequest = waitForFinishedRequest(({ request }) => {
|
||||
return request.url === TEST_NETWORK_REQUEST_URI;
|
||||
});
|
||||
|
||||
const hud = yield loadPageAndGetHud(TEST_NETWORK_REQUEST_URI,
|
||||
"browserConsole");
|
||||
let request = yield finishedRequest;
|
||||
|
||||
ok(request, "Page load was logged");
|
||||
|
||||
let client = hud.ui.webConsoleClient;
|
||||
let args = [request.actor];
|
||||
const postData = yield getPacket(client, "getRequestPostData", args);
|
||||
const responseContent = yield getPacket(client, "getResponseContent", args);
|
||||
|
||||
is(request.request.url, TEST_NETWORK_REQUEST_URI,
|
||||
"Logged network entry is page load");
|
||||
is(request.request.method, "GET", "Method is correct");
|
||||
ok(!postData.postData.text, "No request body was stored");
|
||||
ok(postData.postDataDiscarded, "Request body was discarded");
|
||||
ok(!responseContent.content.text, "No response body was stored");
|
||||
ok(responseContent.contentDiscarded || request.fromCache,
|
||||
"Response body was discarded or response came from the cache");
|
||||
});
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/* -*- 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 nsIConsoleMessages are displayed in the Browser Console.
|
||||
// See bug 859756.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<title>bug859756</title>\n" +
|
||||
"<p>hello world\n<p>nsIConsoleMessages ftw!";
|
||||
|
||||
function test() {
|
||||
const FILTER_PREF = "devtools.browserconsole.filter.jslog";
|
||||
Services.prefs.setBoolPref(FILTER_PREF, true);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(FILTER_PREF);
|
||||
});
|
||||
|
||||
Task.spawn(function* () {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
|
||||
// Test for cached nsIConsoleMessages.
|
||||
Services.console.logStringMessage("test1 for bug859756");
|
||||
|
||||
info("open web console");
|
||||
let hud = yield openConsole(tab);
|
||||
|
||||
ok(hud, "web console opened");
|
||||
Services.console.logStringMessage("do-not-show-me");
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("foobarz");
|
||||
});
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarz",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
let text = hud.outputNode.textContent;
|
||||
is(text.indexOf("do-not-show-me"), -1,
|
||||
"nsIConsoleMessages are not displayed");
|
||||
is(text.indexOf("test1 for bug859756"), -1,
|
||||
"nsIConsoleMessages are not displayed (confirmed)");
|
||||
|
||||
yield closeConsole(tab);
|
||||
|
||||
info("web console closed");
|
||||
hud = yield HUDService.toggleBrowserConsole();
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
Services.console.logStringMessage("test2 for bug859756");
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test1 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
}, {
|
||||
text: "test2 for bug859756",
|
||||
category: CATEGORY_JS,
|
||||
}, {
|
||||
text: "do-not-show-me",
|
||||
category: CATEGORY_JS,
|
||||
}],
|
||||
});
|
||||
|
||||
let msg = [...results[2].matched][0];
|
||||
ok(msg, "message element for do-not-show-me (nsIConsoleMessage)");
|
||||
isnot(msg.textContent.indexOf("do-not-show"), -1,
|
||||
"element content is correct");
|
||||
ok(!msg.classList.contains("filtered-by-type"), "element is not filtered");
|
||||
|
||||
hud.setFilterState("jslog", false);
|
||||
|
||||
ok(msg.classList.contains("filtered-by-type"), "element is filtered");
|
||||
}).then(finishTest);
|
||||
}
|
||||
|
|
@ -0,0 +1,46 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that the "browser console" menu item opens or focuses (if already open)
|
||||
// the console window instead of toggling it open/close.
|
||||
|
||||
"use strict";
|
||||
|
||||
var {Tools} = require("devtools/client/definitions");
|
||||
|
||||
add_task(function* () {
|
||||
let currWindow, hud, mainWindow;
|
||||
|
||||
mainWindow = Services.wm.getMostRecentWindow(null);
|
||||
|
||||
yield HUDService.openBrowserConsoleOrFocus();
|
||||
|
||||
hud = HUDService.getBrowserConsole();
|
||||
|
||||
console.log("testmessage");
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "testmessage"
|
||||
}],
|
||||
});
|
||||
|
||||
currWindow = Services.wm.getMostRecentWindow(null);
|
||||
is(currWindow.document.documentURI, Tools.webConsole.url,
|
||||
"The Browser Console is open and has focus");
|
||||
|
||||
mainWindow.focus();
|
||||
|
||||
yield HUDService.openBrowserConsoleOrFocus();
|
||||
|
||||
currWindow = Services.wm.getMostRecentWindow(null);
|
||||
is(currWindow.document.documentURI, Tools.webConsole.url,
|
||||
"The Browser Console is open and has focus");
|
||||
|
||||
yield HUDService.toggleBrowserConsole();
|
||||
|
||||
hud = HUDService.getBrowserConsole();
|
||||
ok(!hud, "Browser Console has been closed");
|
||||
});
|
||||
|
|
@ -0,0 +1,91 @@
|
|||
/* -*- 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 inspecting an optimized out variable works when execution is
|
||||
// paused.
|
||||
|
||||
"use strict";
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-closure-optimized-out.html";
|
||||
let {tab} = yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole(tab);
|
||||
let { toolbox, panel, panelWin } = yield openDebugger();
|
||||
|
||||
let sources = panelWin.DebuggerView.Sources;
|
||||
yield panel.addBreakpoint({ actor: sources.values[0], line: 18 });
|
||||
yield ensureThreadClientState(panel, "resumed");
|
||||
|
||||
let fetchedScopes = panelWin.once(panelWin.EVENTS.FETCHED_SCOPES);
|
||||
|
||||
// Cause the debuggee to pause
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let button = content.document.querySelector("button");
|
||||
button.click();
|
||||
});
|
||||
|
||||
yield fetchedScopes;
|
||||
ok(true, "Scopes were fetched");
|
||||
|
||||
yield toolbox.selectTool("webconsole");
|
||||
|
||||
// This is the meat of the test: evaluate the optimized out variable.
|
||||
hud.jsterm.execute("upvar");
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "optimized out",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}]
|
||||
});
|
||||
|
||||
finishTest();
|
||||
}).then(null, aError => {
|
||||
ok(false, "Got an error: " + aError.message + "\n" + aError.stack);
|
||||
});
|
||||
}
|
||||
|
||||
// Debugger helper functions stolen from devtools/client/debugger/test/head.js.
|
||||
|
||||
function ensureThreadClientState(aPanel, aState) {
|
||||
let thread = aPanel.panelWin.gThreadClient;
|
||||
let state = thread.state;
|
||||
|
||||
info("Thread is: '" + state + "'.");
|
||||
|
||||
if (state == aState) {
|
||||
return promise.resolve(null);
|
||||
}
|
||||
return waitForThreadEvents(aPanel, aState);
|
||||
}
|
||||
|
||||
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(eventName, ...args) {
|
||||
info("Thread event '" + eventName + "' fired: " + (++count) + " time(s).");
|
||||
|
||||
if (count == aEventRepeat) {
|
||||
ok(true, "Enough '" + eventName + "' thread events have been fired.");
|
||||
thread.removeListener(eventName, onEvent);
|
||||
deferred.resolve.apply(deferred, args);
|
||||
}
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,192 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Bug 874061: test for how the browser and web consoles display messages coming
|
||||
// from private windows. See bug for description of expected behavior.
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>hello world! bug 874061" +
|
||||
"<button onclick='console.log(\"foobar bug 874061\");" +
|
||||
"fooBazBaz.yummy()'>click</button>";
|
||||
let ConsoleAPIStorage = Cc["@mozilla.org/consoleAPI-storage;1"]
|
||||
.getService(Ci.nsIConsoleAPIStorage);
|
||||
let privateWindow, privateBrowser, privateTab, privateContent;
|
||||
let hud, expectedMessages, nonPrivateMessage;
|
||||
|
||||
// This test is slightly more involved: it opens the web console twice,
|
||||
// a new private window once, and the browser console twice. We can get
|
||||
// a timeout with debug builds on slower machines.
|
||||
requestLongerTimeout(2);
|
||||
start();
|
||||
|
||||
function start() {
|
||||
gBrowser.selectedTab = gBrowser.addTab("data:text/html;charset=utf8," +
|
||||
"<p>hello world! I am not private!");
|
||||
gBrowser.selectedBrowser.addEventListener("load", onLoadTab, true);
|
||||
}
|
||||
|
||||
function onLoadTab() {
|
||||
gBrowser.selectedBrowser.removeEventListener("load", onLoadTab, true);
|
||||
info("onLoadTab()");
|
||||
|
||||
// Make sure we have a clean state to start with.
|
||||
Services.console.reset();
|
||||
ConsoleAPIStorage.clearEvents();
|
||||
|
||||
// Add a non-private message to the browser console.
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null, function* () {
|
||||
content.console.log("bug874061-not-private");
|
||||
});
|
||||
|
||||
nonPrivateMessage = {
|
||||
name: "console message from a non-private window",
|
||||
text: "bug874061-not-private",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
};
|
||||
|
||||
privateWindow = OpenBrowserWindow({ private: true });
|
||||
ok(privateWindow, "new private window");
|
||||
ok(PrivateBrowsingUtils.isWindowPrivate(privateWindow), "window's private");
|
||||
|
||||
whenDelayedStartupFinished(privateWindow, onPrivateWindowReady);
|
||||
}
|
||||
|
||||
function onPrivateWindowReady() {
|
||||
info("private browser window opened");
|
||||
privateBrowser = privateWindow.gBrowser;
|
||||
|
||||
privateTab = privateBrowser.selectedTab = privateBrowser.addTab(TEST_URI);
|
||||
privateBrowser.selectedBrowser.addEventListener("load", function onLoad() {
|
||||
info("private tab opened");
|
||||
privateBrowser.selectedBrowser.removeEventListener("load", onLoad, true);
|
||||
privateContent = privateBrowser.selectedBrowser.contentWindow;
|
||||
ok(PrivateBrowsingUtils.isBrowserPrivate(privateBrowser.selectedBrowser),
|
||||
"tab window is private");
|
||||
openConsole(privateTab).then(consoleOpened);
|
||||
}, true);
|
||||
}
|
||||
|
||||
function addMessages() {
|
||||
let button = privateContent.document.querySelector("button");
|
||||
ok(button, "button in page");
|
||||
EventUtils.synthesizeMouse(button, 2, 2, {}, privateContent);
|
||||
}
|
||||
|
||||
function consoleOpened(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "web console opened");
|
||||
|
||||
addMessages();
|
||||
expectedMessages = [
|
||||
{
|
||||
name: "script error",
|
||||
text: "fooBazBaz is not defined",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
name: "console message",
|
||||
text: "foobar bug 874061",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
];
|
||||
|
||||
// Make sure messages are displayed in the web console as they happen, even
|
||||
// if this is a private tab.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
}).then(testCachedMessages);
|
||||
}
|
||||
|
||||
function testCachedMessages() {
|
||||
info("testCachedMessages()");
|
||||
closeConsole(privateTab).then(() => {
|
||||
info("web console closed");
|
||||
openConsole(privateTab).then(consoleReopened);
|
||||
});
|
||||
}
|
||||
|
||||
function consoleReopened(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "web console reopened");
|
||||
|
||||
// Make sure that cached messages are displayed in the web console, even
|
||||
// if this is a private tab.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
}).then(testBrowserConsole);
|
||||
}
|
||||
|
||||
function testBrowserConsole() {
|
||||
info("testBrowserConsole()");
|
||||
closeConsole(privateTab).then(() => {
|
||||
info("web console closed");
|
||||
HUDService.toggleBrowserConsole().then(onBrowserConsoleOpen);
|
||||
});
|
||||
}
|
||||
|
||||
// Make sure that the cached messages from private tabs are not displayed in
|
||||
// the browser console.
|
||||
function checkNoPrivateMessages() {
|
||||
let text = hud.outputNode.textContent;
|
||||
is(text.indexOf("fooBazBaz"), -1, "no exception displayed");
|
||||
is(text.indexOf("bug 874061"), -1, "no console message displayed");
|
||||
}
|
||||
|
||||
function onBrowserConsoleOpen(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "browser console opened");
|
||||
|
||||
checkNoPrivateMessages();
|
||||
addMessages();
|
||||
expectedMessages.push(nonPrivateMessage);
|
||||
|
||||
// Make sure that live messages are displayed in the browser console, even
|
||||
// from private tabs.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: expectedMessages,
|
||||
}).then(testPrivateWindowClose);
|
||||
}
|
||||
|
||||
function testPrivateWindowClose() {
|
||||
info("close the private window and check if private messages are removed");
|
||||
hud.jsterm.once("private-messages-cleared", () => {
|
||||
isnot(hud.outputNode.textContent.indexOf("bug874061-not-private"), -1,
|
||||
"non-private messages are still shown after private window closed");
|
||||
checkNoPrivateMessages();
|
||||
|
||||
info("close the browser console");
|
||||
HUDService.toggleBrowserConsole().then(() => {
|
||||
info("reopen the browser console");
|
||||
executeSoon(() =>
|
||||
HUDService.toggleBrowserConsole().then(onBrowserConsoleReopen));
|
||||
});
|
||||
});
|
||||
privateWindow.BrowserTryToCloseWindow();
|
||||
}
|
||||
|
||||
function onBrowserConsoleReopen(injectedHud) {
|
||||
hud = injectedHud;
|
||||
ok(hud, "browser console reopened");
|
||||
|
||||
// Make sure that the non-private message is still shown after reopen.
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [nonPrivateMessage],
|
||||
}).then(() => {
|
||||
// Make sure that no private message is displayed after closing the
|
||||
// private window and reopening the Browser Console.
|
||||
checkNoPrivateMessages();
|
||||
executeSoon(finishTest);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Check that server log appears in the console panel - bug 1168872
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/test/test-console-server-logging.sjs";
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
// Set logging filter and wait till it's set on the backend
|
||||
hud.setFilterState("serverlog", true);
|
||||
yield updateServerLoggingListener(hud);
|
||||
|
||||
BrowserReloadSkipCache();
|
||||
|
||||
// Note that the test is also checking out the (printf like)
|
||||
// formatters and encoding of UTF8 characters (see the one at the end).
|
||||
let text = "values: string Object { a: 10 } 123 1.12 \u2713";
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: text,
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
// Clean up filter
|
||||
hud.setFilterState("serverlog", false);
|
||||
yield updateServerLoggingListener(hud);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/test/test-console-server-logging-array.sjs";
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
// Set logging filter and wait till it's set on the backend
|
||||
hud.setFilterState("serverlog", true);
|
||||
yield updateServerLoggingListener(hud);
|
||||
|
||||
BrowserReloadSkipCache();
|
||||
// Note that the test is also checking out the (printf like)
|
||||
// formatters and encoding of UTF8 characters (see the one at the end).
|
||||
let text = "Object { best: \"Firefox\", reckless: \"Chrome\", " +
|
||||
"new_ie: \"Safari\", new_new_ie: \"Edge\" }";
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: text,
|
||||
category: CATEGORY_SERVER,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
// Clean up filter
|
||||
hud.setFilterState("serverlog", false);
|
||||
yield updateServerLoggingListener(hud);
|
||||
});
|
||||
|
||||
function updateServerLoggingListener(hud) {
|
||||
let deferred = promise.defer();
|
||||
hud.ui._updateServerLoggingListener(response => {
|
||||
deferred.resolve(response);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,204 @@
|
|||
/* -*- 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 variables view works as expected in the web console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
var hud, gVariablesView;
|
||||
|
||||
registerCleanupFunction(function () {
|
||||
hud = gVariablesView = null;
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
hud = yield openConsole();
|
||||
|
||||
let msg = yield hud.jsterm.execute("(function foo(){})");
|
||||
|
||||
ok(msg, "output message found");
|
||||
ok(msg.textContent.includes("function foo()"),
|
||||
"message text check");
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeMouse(msg.querySelector("a"), 2, 2, {}, hud.iframeWindow);
|
||||
});
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "object inspector opened on click");
|
||||
|
||||
yield findVariableViewProperties(varView, [{
|
||||
name: "name",
|
||||
value: "foo",
|
||||
}], { webconsole: hud });
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
let msg = yield hud.jsterm.execute("fooObj");
|
||||
|
||||
ok(msg, "output message found");
|
||||
ok(msg.textContent.includes('{ testProp: "testValue" }'),
|
||||
"message text check");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
ok(anchor, "object link found");
|
||||
|
||||
let fetched = hud.jsterm.once("variablesview-fetched");
|
||||
|
||||
// executeSoon
|
||||
EventUtils.synthesizeMouse(anchor, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
let view = yield fetched;
|
||||
|
||||
let results = yield onFooObjFetch(view);
|
||||
|
||||
let vView = yield onTestPropFound(results);
|
||||
let results2 = yield onFooObjFetchAfterUpdate(vView);
|
||||
|
||||
let vView2 = yield onUpdatedTestPropFound(results2);
|
||||
let results3 = yield onFooObjFetchAfterPropRename(vView2);
|
||||
|
||||
let vView3 = yield onRenamedTestPropFound(results3);
|
||||
let results4 = yield onPropUpdateError(vView3);
|
||||
|
||||
yield onRenamedTestPropFoundAgain(results4);
|
||||
|
||||
let prop = results4[0].matchedProp;
|
||||
yield testPropDelete(prop);
|
||||
});
|
||||
|
||||
function onFooObjFetch(aVar) {
|
||||
gVariablesView = aVar._variablesView;
|
||||
ok(gVariablesView, "variables view object");
|
||||
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testProp", value: "testValue" },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
function onTestPropFound(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the |testProp| property in the variables view");
|
||||
|
||||
is("testValue", aResults[0].value,
|
||||
"|fooObj.testProp| value is correct");
|
||||
|
||||
// Check that property value updates work and that jsterm functions can be
|
||||
// used.
|
||||
return updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "document.title + window.location + $('p')",
|
||||
webconsole: hud
|
||||
});
|
||||
}
|
||||
|
||||
function onFooObjFetchAfterUpdate(aVar) {
|
||||
info("onFooObjFetchAfterUpdate");
|
||||
let expectedValue = content.document.title + content.location +
|
||||
"[object HTMLParagraphElement]";
|
||||
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testProp", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
function onUpdatedTestPropFound(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the updated |testProp| property value");
|
||||
|
||||
is(content.wrappedJSObject.fooObj.testProp, aResults[0].value,
|
||||
"|fooObj.testProp| value has been updated");
|
||||
|
||||
// Check that property name updates work.
|
||||
return updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "name",
|
||||
string: "testUpdatedProp",
|
||||
webconsole: hud
|
||||
});
|
||||
}
|
||||
|
||||
function* onFooObjFetchAfterPropRename(aVar) {
|
||||
info("onFooObjFetchAfterPropRename");
|
||||
|
||||
let expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + content.location + para;
|
||||
});
|
||||
|
||||
// Check that the new value is in the variables view.
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testUpdatedProp", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
function onRenamedTestPropFound(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the renamed |testProp| property");
|
||||
|
||||
ok(!content.wrappedJSObject.fooObj.testProp,
|
||||
"|fooObj.testProp| has been deleted");
|
||||
is(content.wrappedJSObject.fooObj.testUpdatedProp, aResults[0].value,
|
||||
"|fooObj.testUpdatedProp| is correct");
|
||||
|
||||
// Check that property value updates that cause exceptions are reported in
|
||||
// the web console output.
|
||||
return updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "foobarzFailure()",
|
||||
webconsole: hud
|
||||
});
|
||||
}
|
||||
|
||||
function* onPropUpdateError(aVar) {
|
||||
info("onPropUpdateError");
|
||||
|
||||
let expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + content.location + para;
|
||||
});
|
||||
|
||||
// Make sure the property did not change.
|
||||
return findVariableViewProperties(aVar, [
|
||||
{ name: "testUpdatedProp", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
}
|
||||
|
||||
function onRenamedTestPropFoundAgain(aResults) {
|
||||
let prop = aResults[0].matchedProp;
|
||||
ok(prop, "matched the renamed |testProp| property again");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "exception in property update reported in the web console output",
|
||||
text: "foobarzFailure",
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
function testPropDelete(aProp) {
|
||||
gVariablesView.window.focus();
|
||||
aProp.focus();
|
||||
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey("VK_DELETE", {}, gVariablesView.window);
|
||||
});
|
||||
|
||||
return waitForSuccess({
|
||||
name: "property deleted",
|
||||
timeout: 60000,
|
||||
validator: () => !("testUpdatedProp" in content.wrappedJSObject.fooObj)
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- 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 ensures DOM nodes are rendered correctly in VariablesView.
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
const TEST_URI = `
|
||||
data:text/html;charset=utf-8,
|
||||
<html>
|
||||
<head>
|
||||
<title>Test for DOM nodes in variables view</title>
|
||||
</head>
|
||||
<body>
|
||||
<div></div>
|
||||
<div id="testID"></div>
|
||||
<div class="single-class"></div>
|
||||
<div class="multiple-classes another-class"></div>
|
||||
<div class="class-and-id" id="class-and-id"></div>
|
||||
<div class="multiple-classes-and-id another-class"
|
||||
id="multiple-classes-and-id"></div>
|
||||
<div class=" whitespace-start"></div>
|
||||
<div class="whitespace-end "></div>
|
||||
<div class="multiple spaces"></div>
|
||||
</body>
|
||||
</html>
|
||||
`;
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
const hud = yield openConsole(tab);
|
||||
const jsterm = hud.jsterm;
|
||||
|
||||
let deferred = promise.defer();
|
||||
jsterm.once("variablesview-fetched", (_, val) => deferred.resolve(val));
|
||||
jsterm.execute("inspect(document.querySelectorAll('div'))");
|
||||
|
||||
let variableScope = yield deferred.promise;
|
||||
ok(variableScope, "Variables view opened");
|
||||
|
||||
yield findVariableViewProperties(variableScope, [
|
||||
{ name: "0", value: "<div>"},
|
||||
{ name: "1", value: "<div#testID>"},
|
||||
{ name: "2", value: "<div.single-class>"},
|
||||
{ name: "3", value: "<div.multiple-classes.another-class>"},
|
||||
{ name: "4", value: "<div#class-and-id.class-and-id>"},
|
||||
{ name: "5", value: "<div#multiple-classes-and-id." +
|
||||
"multiple-classes-and-id.another-class>"},
|
||||
{ name: "6", value: "<div.whitespace-start>"},
|
||||
{ name: "7", value: "<div.whitespace-end>"},
|
||||
{ name: "8", value: "<div.multiple.spaces>"},
|
||||
], { webconsole: hud});
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,135 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
/* Test case that ensures Array and other list types are not sorted in variables
|
||||
* view.
|
||||
*
|
||||
* The tested types are:
|
||||
* - Array
|
||||
* - Int8Array
|
||||
* - Int16Array
|
||||
* - Int32Array
|
||||
* - Uint8Array
|
||||
* - Uint16Array
|
||||
* - Uint32Array
|
||||
* - Uint8ClampedArray
|
||||
* - Float32Array
|
||||
* - Float64Array
|
||||
* - NodeList
|
||||
*/
|
||||
|
||||
function test() {
|
||||
const TEST_URI = "data:text/html;charset=utf-8, \
|
||||
<html> \
|
||||
<head> \
|
||||
<title>Test document for bug 977500</title> \
|
||||
</head> \
|
||||
<body> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
<div></div> \
|
||||
</body> \
|
||||
</html>";
|
||||
|
||||
let jsterm;
|
||||
|
||||
function* runner() {
|
||||
const typedArrayTypes = ["Int8Array", "Int16Array", "Int32Array",
|
||||
"Uint8Array", "Uint16Array", "Uint32Array",
|
||||
"Uint8ClampedArray", "Float32Array",
|
||||
"Float64Array"];
|
||||
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
const hud = yield openConsole(tab);
|
||||
jsterm = hud.jsterm;
|
||||
|
||||
// Create an ArrayBuffer of 80 bytes to test TypedArrays. 80 bytes is
|
||||
// enough to get 10 items in all different TypedArrays.
|
||||
yield jsterm.execute("let buf = new ArrayBuffer(80);");
|
||||
|
||||
// Array
|
||||
yield testNotSorted("Array(0,1,2,3,4,5,6,7,8,9,10)");
|
||||
// NodeList
|
||||
yield testNotSorted("document.querySelectorAll('div')");
|
||||
// Object
|
||||
yield testSorted("Object({'hello':1,1:5,10:2,4:2,'abc':1})");
|
||||
|
||||
// Typed arrays.
|
||||
for (let type of typedArrayTypes) {
|
||||
yield testNotSorted("new " + type + "(buf)");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* A helper that ensures the properties are not sorted when an object
|
||||
* specified by aObject is inspected.
|
||||
*
|
||||
* @param string aObject
|
||||
* A string that, once executed, creates and returns the object to
|
||||
* inspect.
|
||||
*/
|
||||
function* testNotSorted(aObject) {
|
||||
info("Testing " + aObject);
|
||||
let deferred = promise.defer();
|
||||
jsterm.once("variablesview-fetched", (_, aVar) => deferred.resolve(aVar));
|
||||
jsterm.execute("inspect(" + aObject + ")");
|
||||
|
||||
let variableScope = yield deferred.promise;
|
||||
ok(variableScope, "Variables view opened");
|
||||
|
||||
// If the properties are sorted: keys = ["0", "1", "10",...] <- incorrect
|
||||
// If the properties are not sorted: keys = ["0", "1", "2",...] <- correct
|
||||
let keyIterator = variableScope._store.keys();
|
||||
is(keyIterator.next().value, "0", "First key is 0");
|
||||
is(keyIterator.next().value, "1", "Second key is 1");
|
||||
|
||||
// If the properties are sorted, the next one will be 10.
|
||||
is(keyIterator.next().value, "2", "Third key is 2, not 10");
|
||||
}
|
||||
/**
|
||||
* A helper that ensures the properties are sorted when an object
|
||||
* specified by aObject is inspected.
|
||||
*
|
||||
* @param string aObject
|
||||
* A string that, once executed, creates and returns the object to
|
||||
* inspect.
|
||||
*/
|
||||
function* testSorted(aObject) {
|
||||
info("Testing " + aObject);
|
||||
let deferred = promise.defer();
|
||||
jsterm.once("variablesview-fetched", (_, aVar) => deferred.resolve(aVar));
|
||||
jsterm.execute("inspect(" + aObject + ")");
|
||||
|
||||
let variableScope = yield deferred.promise;
|
||||
ok(variableScope, "Variables view opened");
|
||||
|
||||
// If the properties are sorted:
|
||||
// keys = ["1", "4", "10",..., "abc", "hello"] <- correct
|
||||
// If the properties are not sorted:
|
||||
// keys = ["1", "10", "4",...] <- incorrect
|
||||
let keyIterator = variableScope._store.keys();
|
||||
is(keyIterator.next().value, "1", "First key should be 1");
|
||||
is(keyIterator.next().value, "4", "Second key should be 4");
|
||||
|
||||
// If the properties are sorted, the next one will be 10.
|
||||
is(keyIterator.next().value, "10", "Third key is 10");
|
||||
// If sorted next properties should be "abc" then "hello"
|
||||
is(keyIterator.next().value, "abc", "Fourth key is abc");
|
||||
is(keyIterator.next().value, "hello", "Fifth key is hello");
|
||||
}
|
||||
|
||||
Task.spawn(runner).then(finishTest);
|
||||
}
|
||||
|
|
@ -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 variables view filter feature works fine in the console.
|
||||
|
||||
function props(view, prefix = "") {
|
||||
// First match only the visible one, not hidden by a search
|
||||
let visible = [...view].filter(([id, prop]) => prop._isMatch);
|
||||
// Then flatten the list into a list of strings
|
||||
// being the jsonpath of each attribute being visible in the view
|
||||
return visible.reduce((list, [id, prop]) => {
|
||||
list.push(prefix + id);
|
||||
return list.concat(props(prop, prefix + id + "."));
|
||||
}, []);
|
||||
}
|
||||
|
||||
function assertAttrs(view, expected, message) {
|
||||
is(props(view).join(","), expected, message);
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab("data:text/html;charset=utf-8,webconsole-filter");
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
let fetched = jsterm.once("variablesview-fetched");
|
||||
|
||||
yield jsterm.execute("inspect({ foo: { bar : \"baz\" } })");
|
||||
|
||||
let view = yield fetched;
|
||||
let variablesView = view._variablesView;
|
||||
let searchbox = variablesView._searchboxNode;
|
||||
|
||||
assertAttrs(view, "foo,__proto__",
|
||||
"To start with, we just see the top level foo attr");
|
||||
|
||||
fetched = jsterm.once("variablesview-fetched");
|
||||
searchbox.value = "bar";
|
||||
searchbox.doCommand();
|
||||
view = yield fetched;
|
||||
|
||||
assertAttrs(view, "",
|
||||
"If we don't manually expand nested attr, we don't see them");
|
||||
|
||||
fetched = jsterm.once("variablesview-fetched");
|
||||
searchbox.value = "";
|
||||
searchbox.doCommand();
|
||||
view = yield fetched;
|
||||
|
||||
assertAttrs(view, "foo",
|
||||
"If we reset the search, we get back to original state");
|
||||
|
||||
yield [...view][0][1].expand();
|
||||
|
||||
fetched = jsterm.once("variablesview-fetched");
|
||||
searchbox.value = "bar";
|
||||
searchbox.doCommand();
|
||||
view = yield fetched;
|
||||
|
||||
assertAttrs(view, "foo,foo.bar", "Now if we expand, we see the nested attr");
|
||||
|
||||
fetched = jsterm.once("variablesview-fetched");
|
||||
searchbox.value = "baz";
|
||||
searchbox.doCommand();
|
||||
view = yield fetched;
|
||||
|
||||
assertAttrs(view, "foo,foo.bar", "We can also search for attr values");
|
||||
|
||||
fetched = jsterm.once("variablesview-fetched");
|
||||
searchbox.value = "";
|
||||
searchbox.doCommand();
|
||||
view = yield fetched;
|
||||
|
||||
assertAttrs(view, "foo",
|
||||
"If we reset again, we get back to original state again");
|
||||
});
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that variables view is linked to the inspector for highlighting and
|
||||
// selecting DOM nodes
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-952277-highlight-nodes-in-vview.html";
|
||||
|
||||
var gWebConsole, gJSTerm, gVariablesView, gToolbox;
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then(hud => {
|
||||
consoleOpened(hud);
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function consoleOpened(hud) {
|
||||
gWebConsole = hud;
|
||||
gJSTerm = hud.jsterm;
|
||||
gToolbox = gDevTools.getToolbox(hud.target);
|
||||
gJSTerm.execute("document.querySelectorAll('p')").then(onQSAexecuted);
|
||||
}
|
||||
|
||||
function onQSAexecuted(msg) {
|
||||
ok(msg, "output message found");
|
||||
let anchor = msg.querySelector("a");
|
||||
ok(anchor, "object link found");
|
||||
|
||||
gJSTerm.once("variablesview-fetched", onNodeListViewFetched);
|
||||
|
||||
executeSoon(() =>
|
||||
EventUtils.synthesizeMouse(anchor, 2, 2, {}, gWebConsole.iframeWindow)
|
||||
);
|
||||
}
|
||||
|
||||
function onNodeListViewFetched(event, variable) {
|
||||
gVariablesView = variable._variablesView;
|
||||
ok(gVariablesView, "variables view object");
|
||||
|
||||
// Transform the vview into an array we can filter properties from
|
||||
let props = [...variable].map(([id, prop]) => [id, prop]);
|
||||
|
||||
// These properties are the DOM nodes ones
|
||||
props = props.filter(v => v[0].match(/[0-9]+/));
|
||||
|
||||
function hoverOverDomNodeVariableAndAssertHighlighter(index) {
|
||||
if (props[index]) {
|
||||
let prop = props[index][1];
|
||||
|
||||
gToolbox.once("node-highlight", () => {
|
||||
ok(true, "The highlighter was shown on hover of the DOMNode");
|
||||
gToolbox.highlighterUtils.unhighlight().then(() => {
|
||||
clickOnDomNodeVariableAndAssertInspectorSelected(index);
|
||||
});
|
||||
});
|
||||
|
||||
// Rather than trying to emulate a mouseenter event, let's call the
|
||||
// variable's highlightDomNode and see if it has the desired effect
|
||||
prop.highlightDomNode();
|
||||
} else {
|
||||
finishUp();
|
||||
}
|
||||
}
|
||||
|
||||
function clickOnDomNodeVariableAndAssertInspectorSelected(index) {
|
||||
let prop = props[index][1];
|
||||
|
||||
// Make sure the inspector is initialized so we can listen to its events
|
||||
gToolbox.initInspector().then(() => {
|
||||
// Rather than trying to click on the value here, let's just call the
|
||||
// variable's openNodeInInspector function and see if it has the
|
||||
// desired effect
|
||||
prop.openNodeInInspector().then(() => {
|
||||
is(gToolbox.currentToolId, "inspector",
|
||||
"The toolbox switched over the inspector on DOMNode click");
|
||||
gToolbox.selectTool("webconsole").then(() => {
|
||||
hoverOverDomNodeVariableAndAssertHighlighter(index + 1);
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
hoverOverDomNodeVariableAndAssertHighlighter(0);
|
||||
}
|
||||
|
||||
function finishUp() {
|
||||
gWebConsole = gJSTerm = gVariablesView = gToolbox = null;
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
|
@ -0,0 +1,38 @@
|
|||
/* -*- 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 variables view handles special names like "<return>"
|
||||
// properly for ordinary displays.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>test for bug 1084430";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
ok(hud, "web console opened");
|
||||
|
||||
hud.setFilterState("log", false);
|
||||
registerCleanupFunction(() => hud.setFilterState("log", true));
|
||||
|
||||
hud.jsterm.execute("inspect({ '<return>': 47, '<exception>': 91 })");
|
||||
|
||||
let varView = yield hud.jsterm.once("variablesview-fetched");
|
||||
ok(varView, "variables view object");
|
||||
|
||||
let props = yield findVariableViewProperties(varView, [
|
||||
{ name: "<return>", value: 47 },
|
||||
{ name: "<exception>", value: 91 },
|
||||
], { webconsole: hud });
|
||||
|
||||
for (let prop of props) {
|
||||
ok(!prop.matchedProp._internalItem, prop.name + " is not marked internal");
|
||||
let target = prop.matchedProp._target;
|
||||
ok(!target.hasAttribute("pseudo-item"),
|
||||
prop.name + " is not a pseudo-item");
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,109 @@
|
|||
/* -*- 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 makes sure web console eval happens in the user-selected stackframe
|
||||
// from the js debugger, when changing the value of a property in the variables
|
||||
// view.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
let dbgPanel = yield openDebugger();
|
||||
yield waitForFrameAdded();
|
||||
yield openConsole();
|
||||
yield testVariablesView(hud);
|
||||
});
|
||||
|
||||
function* waitForFrameAdded() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
let thread = toolbox.threadClient;
|
||||
|
||||
info("Waiting for framesadded");
|
||||
yield new Promise(resolve => {
|
||||
thread.addOneTimeListener("framesadded", resolve);
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.firstCall();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function* testVariablesView(hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
let msg = yield jsterm.execute("fooObj");
|
||||
ok(msg, "output message found");
|
||||
ok(msg.textContent.includes('{ testProp2: "testValue2" }'),
|
||||
"message text check");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
ok(anchor, "object link found");
|
||||
|
||||
info("Waiting for variable view to appear");
|
||||
let variable = yield new Promise(resolve => {
|
||||
jsterm.once("variablesview-fetched", (e, variable) => {
|
||||
resolve(variable);
|
||||
});
|
||||
executeSoon(() => EventUtils.synthesizeMouse(anchor, 2, 2, {},
|
||||
hud.iframeWindow));
|
||||
});
|
||||
|
||||
info("Waiting for findVariableViewProperties");
|
||||
let results = yield findVariableViewProperties(variable, [
|
||||
{ name: "testProp2", value: "testValue2" },
|
||||
{ name: "testProp", value: "testValue", dontMatch: true },
|
||||
], { webconsole: hud });
|
||||
|
||||
let prop = results[0].matchedProp;
|
||||
ok(prop, "matched the |testProp2| property in the variables view");
|
||||
|
||||
// Check that property value updates work and that jsterm functions can be
|
||||
// used.
|
||||
variable = yield updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "document.title + foo2 + $('p')",
|
||||
webconsole: hud
|
||||
});
|
||||
|
||||
info("onFooObjFetchAfterUpdate");
|
||||
let expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + "foo2SecondCall" + para;
|
||||
});
|
||||
|
||||
results = yield findVariableViewProperties(variable, [
|
||||
{ name: "testProp2", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
|
||||
prop = results[0].matchedProp;
|
||||
ok(prop, "matched the updated |testProp2| property value");
|
||||
|
||||
// Check that testProp2 was updated.
|
||||
yield new Promise(resolve => {
|
||||
executeSoon(() => {
|
||||
jsterm.execute("fooObj.testProp2").then(resolve);
|
||||
});
|
||||
});
|
||||
|
||||
expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + "foo2SecondCall" + para;
|
||||
});
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf(expectedValue), -1,
|
||||
"fooObj.testProp2 is correct");
|
||||
}
|
||||
|
|
@ -0,0 +1,112 @@
|
|||
/* -*- 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 makes sure web console eval works while the js debugger paused the
|
||||
// page, and while the inspector is active. See bug 886137.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
let dbgPanel = yield openDebugger();
|
||||
yield openInspector();
|
||||
yield waitForFrameAdded();
|
||||
|
||||
yield openConsole();
|
||||
yield testVariablesView(hud);
|
||||
});
|
||||
|
||||
function* waitForFrameAdded() {
|
||||
let target = TargetFactory.forTab(gBrowser.selectedTab);
|
||||
let toolbox = gDevTools.getToolbox(target);
|
||||
let thread = toolbox.threadClient;
|
||||
|
||||
info("Waiting for framesadded");
|
||||
yield new Promise(resolve => {
|
||||
thread.addOneTimeListener("framesadded", resolve);
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.firstCall();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function* testVariablesView(hud) {
|
||||
info("testVariablesView");
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
let msg = yield jsterm.execute("fooObj");
|
||||
ok(msg, "output message found");
|
||||
ok(msg.textContent.includes('{ testProp2: "testValue2" }'),
|
||||
"message text check");
|
||||
|
||||
let anchor = msg.querySelector("a");
|
||||
ok(anchor, "object link found");
|
||||
|
||||
info("Waiting for variable view to appear");
|
||||
let variable = yield new Promise(resolve => {
|
||||
jsterm.once("variablesview-fetched", (e, variable) => {
|
||||
resolve(variable);
|
||||
});
|
||||
executeSoon(() => EventUtils.synthesizeMouse(anchor, 2, 2, {},
|
||||
hud.iframeWindow));
|
||||
});
|
||||
|
||||
info("Waiting for findVariableViewProperties");
|
||||
let results = yield findVariableViewProperties(variable, [
|
||||
{ name: "testProp2", value: "testValue2" },
|
||||
{ name: "testProp", value: "testValue", dontMatch: true },
|
||||
], { webconsole: hud });
|
||||
|
||||
let prop = results[0].matchedProp;
|
||||
ok(prop, "matched the |testProp2| property in the variables view");
|
||||
|
||||
// Check that property value updates work and that jsterm functions can be
|
||||
// used.
|
||||
variable = yield updateVariablesViewProperty({
|
||||
property: prop,
|
||||
field: "value",
|
||||
string: "document.title + foo2 + $('p')",
|
||||
webconsole: hud
|
||||
});
|
||||
|
||||
info("onFooObjFetchAfterUpdate");
|
||||
let expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + "foo2SecondCall" + para;
|
||||
});
|
||||
|
||||
results = yield findVariableViewProperties(variable, [
|
||||
{ name: "testProp2", value: expectedValue },
|
||||
], { webconsole: hud });
|
||||
|
||||
prop = results[0].matchedProp;
|
||||
ok(prop, "matched the updated |testProp2| property value");
|
||||
|
||||
// Check that testProp2 was updated.
|
||||
yield new Promise(resolve => {
|
||||
executeSoon(() => {
|
||||
jsterm.execute("fooObj.testProp2").then(resolve);
|
||||
});
|
||||
});
|
||||
|
||||
expectedValue = yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let para = content.wrappedJSObject.document.querySelector("p");
|
||||
return content.document.title + "foo2SecondCall" + para;
|
||||
});
|
||||
|
||||
isnot(hud.outputNode.textContent.indexOf(expectedValue), -1,
|
||||
"fooObj.testProp2 is correct");
|
||||
}
|
||||
|
|
@ -0,0 +1,157 @@
|
|||
/* -*- 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 makes sure web console eval happens in the user-selected stackframe
|
||||
// from the js debugger.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
var gWebConsole, gJSTerm, gDebuggerWin, gThread, gDebuggerController;
|
||||
var gStackframes;
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then(consoleOpened);
|
||||
});
|
||||
}
|
||||
|
||||
function consoleOpened(hud) {
|
||||
gWebConsole = hud;
|
||||
gJSTerm = hud.jsterm;
|
||||
gJSTerm.execute("foo").then(onExecuteFoo);
|
||||
}
|
||||
|
||||
function onExecuteFoo() {
|
||||
isnot(gWebConsole.outputNode.textContent.indexOf("globalFooBug783499"), -1,
|
||||
"|foo| value is correct");
|
||||
|
||||
gJSTerm.clearOutput();
|
||||
|
||||
// Test for Bug 690529 - Web Console and Scratchpad should evaluate
|
||||
// expressions in the scope of the content window, not in a sandbox.
|
||||
executeSoon(() => {
|
||||
gJSTerm.execute("foo2 = 'newFoo'; window.foo2").then(onNewFoo2);
|
||||
});
|
||||
}
|
||||
|
||||
function onNewFoo2(msg) {
|
||||
is(gWebConsole.outputNode.textContent.indexOf("undefined"), -1,
|
||||
"|undefined| is not displayed after adding |foo2|");
|
||||
|
||||
ok(msg, "output result found");
|
||||
|
||||
isnot(msg.textContent.indexOf("newFoo"), -1,
|
||||
"'newFoo' is displayed after adding |foo2|");
|
||||
|
||||
gJSTerm.clearOutput();
|
||||
|
||||
info("openDebugger");
|
||||
executeSoon(() => openDebugger().then(debuggerOpened));
|
||||
}
|
||||
|
||||
function debuggerOpened(aResult) {
|
||||
gDebuggerWin = aResult.panelWin;
|
||||
gDebuggerController = gDebuggerWin.DebuggerController;
|
||||
gThread = gDebuggerController.activeThread;
|
||||
gStackframes = gDebuggerController.StackFrames;
|
||||
|
||||
info("openConsole");
|
||||
executeSoon(() =>
|
||||
openConsole().then(() =>
|
||||
gJSTerm.execute("foo + foo2").then(onExecuteFooAndFoo2)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function onExecuteFooAndFoo2() {
|
||||
let expected = "globalFooBug783499newFoo";
|
||||
isnot(gWebConsole.outputNode.textContent.indexOf(expected), -1,
|
||||
"|foo + foo2| is displayed after starting the debugger");
|
||||
|
||||
executeSoon(() => {
|
||||
gJSTerm.clearOutput();
|
||||
|
||||
info("openDebugger");
|
||||
openDebugger().then(() => {
|
||||
gThread.addOneTimeListener("framesadded", onFramesAdded);
|
||||
|
||||
info("firstCall()");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.firstCall();
|
||||
});
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onFramesAdded() {
|
||||
info("onFramesAdded, openConsole() now");
|
||||
executeSoon(() =>
|
||||
openConsole().then(() =>
|
||||
gJSTerm.execute("foo + foo2").then(onExecuteFooAndFoo2InSecondCall)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
function onExecuteFooAndFoo2InSecondCall() {
|
||||
let expected = "globalFooBug783499foo2SecondCall";
|
||||
isnot(gWebConsole.outputNode.textContent.indexOf(expected), -1,
|
||||
"|foo + foo2| from |secondCall()|");
|
||||
|
||||
function runOpenConsole() {
|
||||
openConsole().then(() => {
|
||||
gJSTerm.execute("foo + foo2 + foo3").then(onExecuteFoo23InFirstCall);
|
||||
});
|
||||
}
|
||||
|
||||
executeSoon(() => {
|
||||
gJSTerm.clearOutput();
|
||||
|
||||
info("openDebugger and selectFrame(1)");
|
||||
|
||||
openDebugger().then(() => {
|
||||
gStackframes.selectFrame(1);
|
||||
|
||||
info("openConsole");
|
||||
executeSoon(() => runOpenConsole());
|
||||
});
|
||||
});
|
||||
}
|
||||
|
||||
function onExecuteFoo23InFirstCall() {
|
||||
let expected = "fooFirstCallnewFoofoo3FirstCall";
|
||||
isnot(gWebConsole.outputNode.textContent.indexOf(expected), -1,
|
||||
"|foo + foo2 + foo3| from |firstCall()|");
|
||||
|
||||
executeSoon(() =>
|
||||
gJSTerm.execute("foo = 'abba'; foo3 = 'bug783499'; foo + foo3").then(
|
||||
onExecuteFooAndFoo3ChangesInFirstCall));
|
||||
}
|
||||
|
||||
var onExecuteFooAndFoo3ChangesInFirstCall = Task.async(function*() {
|
||||
let expected = "abbabug783499";
|
||||
isnot(gWebConsole.outputNode.textContent.indexOf(expected), -1,
|
||||
"|foo + foo3| updated in |firstCall()|");
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, null, function*() {
|
||||
is(content.wrappedJSObject.foo, "globalFooBug783499",
|
||||
"|foo| in content window");
|
||||
is(content.wrappedJSObject.foo2, "newFoo", "|foo2| in content window");
|
||||
ok(!content.wrappedJSObject.foo3,
|
||||
"|foo3| was not added to the content window");
|
||||
});
|
||||
|
||||
gWebConsole = gJSTerm = gDebuggerWin = gThread = gDebuggerController =
|
||||
gStackframes = null;
|
||||
executeSoon(finishTest);
|
||||
});
|
||||
|
|
@ -0,0 +1,71 @@
|
|||
/* -*- 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 to make sure that web console commands can fire while paused at a
|
||||
// breakpoint that was triggered from a JS call. Relies on asynchronous js
|
||||
// evaluation over the protocol - see Bug 1088861.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-eval-in-stackframe.html";
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
info("open the web console");
|
||||
let hud = yield openConsole();
|
||||
let {jsterm} = hud;
|
||||
|
||||
info("open the debugger");
|
||||
let {panelWin} = yield openDebugger();
|
||||
let {DebuggerController} = panelWin;
|
||||
let {activeThread} = DebuggerController;
|
||||
|
||||
let firstCall = promise.defer();
|
||||
let frameAdded = promise.defer();
|
||||
executeSoon(() => {
|
||||
info("Executing firstCall");
|
||||
activeThread.addOneTimeListener("framesadded", () => {
|
||||
executeSoon(frameAdded.resolve);
|
||||
});
|
||||
jsterm.execute("firstCall()").then(firstCall.resolve);
|
||||
});
|
||||
|
||||
info("Waiting for a frame to be added");
|
||||
yield frameAdded.promise;
|
||||
|
||||
info("Executing basic command while paused");
|
||||
yield executeAndConfirm(jsterm, "1 + 2", "3");
|
||||
|
||||
info("Executing command using scoped variables while paused");
|
||||
yield executeAndConfirm(jsterm, "foo + foo2",
|
||||
'"globalFooBug783499foo2SecondCall"');
|
||||
|
||||
info("Resuming the thread");
|
||||
activeThread.resume();
|
||||
|
||||
info("Checking the first command, which is the last to resolve since it " +
|
||||
"paused");
|
||||
let node = yield firstCall.promise;
|
||||
is(node.querySelector(".message-body").textContent,
|
||||
"undefined",
|
||||
"firstCall() returned correct value");
|
||||
});
|
||||
|
||||
function* executeAndConfirm(jsterm, input, output) {
|
||||
info("Executing command `" + input + "`");
|
||||
|
||||
let node = yield jsterm.execute(input);
|
||||
|
||||
is(node.querySelector(".message-body").textContent, output,
|
||||
"Expected result from call to " + input);
|
||||
}
|
||||
47
devtools/client/webconsole/test/browser_jsterm_inspect.js
Normal file
47
devtools/client/webconsole/test/browser_jsterm_inspect.js
Normal file
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Check that the inspect() jsterm helper function works.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>hello bug 869981";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
/* Check that the window object is inspected */
|
||||
jsterm.execute("testProp = 'testValue'");
|
||||
|
||||
let updated = jsterm.once("variablesview-updated");
|
||||
jsterm.execute("inspect(window)");
|
||||
let view = yield updated;
|
||||
ok(view, "variables view object");
|
||||
|
||||
// The single variable view contains a scope with the variable name
|
||||
// and unnamed subitem that contains the properties
|
||||
let variable = view.getScopeAtIndex(0).get(undefined);
|
||||
ok(variable, "variable object");
|
||||
|
||||
yield findVariableViewProperties(variable, [
|
||||
{ name: "testProp", value: "testValue" },
|
||||
{ name: "document", value: /HTMLDocument \u2192 data:/ },
|
||||
], { webconsole: hud });
|
||||
|
||||
/* Check that a primitive value can be inspected, too */
|
||||
let updated2 = jsterm.once("variablesview-updated");
|
||||
jsterm.execute("inspect(1)");
|
||||
let view2 = yield updated2;
|
||||
ok(view2, "variables view object");
|
||||
|
||||
// Check the label of the scope - it should contain the value
|
||||
let scope = view.getScopeAtIndex(0);
|
||||
ok(scope, "variable object");
|
||||
|
||||
is(scope.name, "1", "The value of the primitive var is correct");
|
||||
});
|
||||
57
devtools/client/webconsole/test/browser_longstring_hang.js
Normal file
57
devtools/client/webconsole/test/browser_longstring_hang.js
Normal file
|
|
@ -0,0 +1,57 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that very long strings do not hang the browser.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-859170-longstring-hang.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
info("wait for the initial long string");
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "find 'foobar', no 'foobaz', in long string output",
|
||||
text: "foobar",
|
||||
noText: "foobaz",
|
||||
category: CATEGORY_WEBDEV,
|
||||
longString: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
let clickable = results[0].longStrings[0];
|
||||
ok(clickable, "long string ellipsis is shown");
|
||||
clickable.scrollIntoView(false);
|
||||
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
info("wait for long string expansion");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "find 'foobaz' after expand, but no 'boom!' at the end",
|
||||
text: "foobaz",
|
||||
noText: "boom!",
|
||||
category: CATEGORY_WEBDEV,
|
||||
longString: false,
|
||||
},
|
||||
{
|
||||
text: "too long to be displayed",
|
||||
longString: false,
|
||||
},
|
||||
],
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,74 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,Test that the netmonitor " +
|
||||
"displays requests that have been recorded in the " +
|
||||
"web console, even if the netmonitor hadn't opened yet.";
|
||||
|
||||
const TEST_FILE = "test-network-request.html";
|
||||
const TEST_PATH = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/" + TEST_FILE;
|
||||
|
||||
const NET_PREF = "devtools.webconsole.filter.networkinfo";
|
||||
Services.prefs.setBoolPref(NET_PREF, true);
|
||||
registerCleanupFunction(() => {
|
||||
Services.prefs.clearUserPref(NET_PREF);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
let { tab, browser } = yield loadTab(TEST_URI);
|
||||
|
||||
// Test that the request appears in the console.
|
||||
let hud = yield openConsole();
|
||||
info("Web console is open");
|
||||
|
||||
yield loadDocument(browser);
|
||||
info("Document loaded.");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "network message",
|
||||
text: TEST_FILE,
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG
|
||||
}
|
||||
]
|
||||
});
|
||||
|
||||
// Test that the request appears in the network panel.
|
||||
let target = TargetFactory.forTab(tab);
|
||||
let toolbox = yield gDevTools.showToolbox(target, "netmonitor");
|
||||
info("Network panel is open.");
|
||||
|
||||
testNetmonitor(toolbox);
|
||||
});
|
||||
|
||||
function loadDocument(browser) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
browser.addEventListener("load", function onLoad() {
|
||||
browser.removeEventListener("load", onLoad, true);
|
||||
deferred.resolve();
|
||||
}, true);
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_PATH);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testNetmonitor(toolbox) {
|
||||
let monitor = toolbox.getCurrentPanel();
|
||||
let { RequestsMenu } = monitor.panelWin.NetMonitorView;
|
||||
RequestsMenu.lazyUpdate = false;
|
||||
|
||||
is(RequestsMenu.itemCount, 1, "Network request appears in the network panel");
|
||||
|
||||
let item = RequestsMenu.getItemAtIndex(0);
|
||||
is(item.attachment.method, "GET", "The attached method is correct.");
|
||||
is(item.attachment.url, TEST_PATH, "The attached url is correct.");
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure that the Web Console output does not break after we try to call
|
||||
// console.dir() for objects that are not inspectable.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,test for bug 773466";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
hud.jsterm.execute("console.log('fooBug773466a')");
|
||||
hud.jsterm.execute("myObj = Object.create(null)");
|
||||
hud.jsterm.execute("console.dir(myObj)");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "fooBug773466a",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
name: "console.dir output",
|
||||
consoleDir: "[object Object]",
|
||||
}],
|
||||
});
|
||||
|
||||
content.console.log("fooBug773466b");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "fooBug773466b",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,85 @@
|
|||
/* -*- 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 long strings can be expanded in the console output.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,test for bug 787981 - check " +
|
||||
"that long strings can be expanded in the output.";
|
||||
|
||||
add_task(function* () {
|
||||
let { DebuggerServer } = require("devtools/server/main");
|
||||
|
||||
let longString = (new Array(DebuggerServer.LONG_STRING_LENGTH + 4))
|
||||
.join("a") + "foobar";
|
||||
let initialString =
|
||||
longString.substring(0, DebuggerServer.LONG_STRING_INITIAL_LENGTH);
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.jsterm.execute("console.log('bazbaz', '" + longString + "', 'boom')");
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "console.log output",
|
||||
text: ["bazbaz", "boom", initialString],
|
||||
noText: "foobar",
|
||||
longString: true,
|
||||
}],
|
||||
});
|
||||
|
||||
let clickable = result.longStrings[0];
|
||||
ok(clickable, "long string ellipsis is shown");
|
||||
|
||||
clickable.scrollIntoView(false);
|
||||
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "full string",
|
||||
text: ["bazbaz", "boom", longString],
|
||||
category: CATEGORY_WEBDEV,
|
||||
longString: false,
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
let msg = yield execute(hud, "'" + longString + "'");
|
||||
|
||||
isnot(msg.textContent.indexOf(initialString), -1,
|
||||
"initial string is shown");
|
||||
is(msg.textContent.indexOf(longString), -1,
|
||||
"full string is not shown");
|
||||
|
||||
clickable = msg.querySelector(".longStringEllipsis");
|
||||
ok(clickable, "long string ellipsis is shown");
|
||||
|
||||
clickable.scrollIntoView(false);
|
||||
|
||||
EventUtils.synthesizeMouse(clickable, 3, 4, {}, hud.iframeWindow);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "full string",
|
||||
text: longString,
|
||||
category: CATEGORY_OUTPUT,
|
||||
longString: false,
|
||||
}],
|
||||
});
|
||||
});
|
||||
|
||||
function execute(hud, str) {
|
||||
let deferred = promise.defer();
|
||||
hud.jsterm.execute(str, deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,178 @@
|
|||
/* -*- 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 makes sure messages are not considered repeated when coming from
|
||||
// different lines of code, or from different severities, etc.
|
||||
// See bugs 720180 and 800510.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-repeated-messages.html";
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield consoleOpened(hud);
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserReload();
|
||||
yield loaded;
|
||||
|
||||
yield testCSSRepeats(hud);
|
||||
yield testCSSRepeatsAfterReload(hud);
|
||||
yield testConsoleRepeats(hud);
|
||||
yield testConsoleFalsyValues(hud);
|
||||
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
});
|
||||
|
||||
function consoleOpened(hud) {
|
||||
// Check that css warnings are not coalesced if they come from different
|
||||
// lines.
|
||||
info("waiting for 2 css warnings");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "two css warnings",
|
||||
category: CATEGORY_CSS,
|
||||
count: 2,
|
||||
repeats: 1,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
function testCSSRepeats(hud) {
|
||||
info("wait for repeats after page reload");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "two css warnings, repeated twice",
|
||||
category: CATEGORY_CSS,
|
||||
repeats: 2,
|
||||
count: 2,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
||||
function testCSSRepeatsAfterReload(hud) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.jsterm.execute("testConsole()");
|
||||
|
||||
info("wait for repeats with the console API");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "console.log 'foo repeat' repeated twice",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 2,
|
||||
},
|
||||
{
|
||||
name: "console.log 'foo repeat' repeated once",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 1,
|
||||
},
|
||||
{
|
||||
name: "console.error 'foo repeat' repeated once",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
repeats: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function testConsoleRepeats(hud) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.jsterm.execute("undefined");
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.console.log("undefined");
|
||||
});
|
||||
|
||||
info("make sure console API messages are not coalesced with jsterm output");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "'undefined' jsterm input message",
|
||||
text: "undefined",
|
||||
category: CATEGORY_INPUT,
|
||||
},
|
||||
{
|
||||
name: "'undefined' jsterm output message",
|
||||
text: "undefined",
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
{
|
||||
name: "'undefined' console.log message",
|
||||
text: "undefined",
|
||||
category: CATEGORY_WEBDEV,
|
||||
repeats: 1,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
||||
function testConsoleFalsyValues(hud) {
|
||||
hud.jsterm.clearOutput(true);
|
||||
hud.jsterm.execute("testConsoleFalsyValues()");
|
||||
|
||||
info("wait for repeats of falsy values with the console API");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "console.log 'NaN' repeated once",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 1,
|
||||
},
|
||||
{
|
||||
name: "console.log 'undefined' repeated once",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 1,
|
||||
},
|
||||
{
|
||||
name: "console.log 'null' repeated once",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 1,
|
||||
},
|
||||
{
|
||||
name: "console.log 'NaN' repeated twice",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 2,
|
||||
},
|
||||
{
|
||||
name: "console.log 'undefined' repeated twice",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 2,
|
||||
},
|
||||
{
|
||||
name: "console.log 'null' repeated twice",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
repeats: 2,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Make sure that JS eval result are properly formatted as strings.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-result-format-as-string.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
hud.jsterm.clearOutput(true);
|
||||
|
||||
let msg = yield execute(hud, "document.querySelector('p')");
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("bug772506_content"), -1,
|
||||
"no content element found");
|
||||
ok(!hud.outputNode.querySelector("#foobar"), "no #foobar element found");
|
||||
|
||||
ok(msg, "eval output node found");
|
||||
is(msg.textContent.indexOf("<div>"), -1,
|
||||
"<div> string is not displayed");
|
||||
isnot(msg.textContent.indexOf("<p>"), -1,
|
||||
"<p> string is displayed");
|
||||
|
||||
EventUtils.synthesizeMouseAtCenter(msg, {type: "mousemove"});
|
||||
ok(!gBrowser._bug772506, "no content variable");
|
||||
});
|
||||
|
||||
function execute(hud, str) {
|
||||
let deferred = promise.defer();
|
||||
hud.jsterm.execute(str, deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,86 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_REPLACED_API_URI = "http://example.com/browser/devtools/client/" +
|
||||
"webconsole/test/test-console-replaced-api.html";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/testscript.js";
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield testWarningNotPresent(hud);
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserTestUtils.loadURI(browser, TEST_REPLACED_API_URI);
|
||||
yield loaded;
|
||||
|
||||
let hud2 = yield openConsole();
|
||||
|
||||
yield testWarningPresent(hud2);
|
||||
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
});
|
||||
|
||||
function testWarningNotPresent(hud) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
is(hud.outputNode.textContent.indexOf("logging API"), -1,
|
||||
"no warning displayed");
|
||||
|
||||
// Bug 862024: make sure the warning doesn't show after page reload.
|
||||
info("reload " + TEST_URI);
|
||||
executeSoon(function () {
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
ContentTask.spawn(browser, null, "() => content.location.reload()");
|
||||
});
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "testscript.js",
|
||||
category: CATEGORY_NETWORK,
|
||||
}],
|
||||
}).then(() => executeSoon(() => {
|
||||
is(hud.outputNode.textContent.indexOf("logging API"), -1,
|
||||
"no warning displayed");
|
||||
closeConsole().then(deferred.resolve);
|
||||
}));
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testWarningPresent(hud) {
|
||||
info("wait for the warning to show");
|
||||
let deferred = promise.defer();
|
||||
|
||||
let warning = {
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: /logging API .+ disabled by a script/,
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_WARNING,
|
||||
}],
|
||||
};
|
||||
|
||||
waitForMessages(warning).then(() => {
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
executeSoon(() => {
|
||||
info("reload the test page and wait for the warning to show");
|
||||
waitForMessages(warning).then(deferred.resolve);
|
||||
let browser = gBrowser.selectedBrowser;
|
||||
ContentTask.spawn(browser, null, "() => content.location.reload()");
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,69 @@
|
|||
/* -*- 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/ */
|
||||
|
||||
// The test loads a web page with mixed active and display content
|
||||
// on it while the "block mixed content" settings are _off_.
|
||||
// It then checks that the loading mixed content warning messages
|
||||
// are logged to the console and have the correct "Learn More"
|
||||
// url appended to them.
|
||||
// Bug 875456 - Log mixed content messages from the Mixed Content
|
||||
// Blocker to the Security Pane in the Web Console
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-mixedcontent-securityerrors.html";
|
||||
const LEARN_MORE_URI = "https://developer.mozilla.org/docs/Web/Security/" +
|
||||
"Mixed_content" + DOCS_GA_PARAMS;
|
||||
|
||||
add_task(function* () {
|
||||
yield pushPrefEnv();
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "Logged mixed active content",
|
||||
text: "Loading mixed (insecure) active content " +
|
||||
"\u201chttp://example.com/\u201d on a secure page",
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_WARNING,
|
||||
objects: true,
|
||||
},
|
||||
{
|
||||
name: "Logged mixed passive content - image",
|
||||
text: "Loading mixed (insecure) display content " +
|
||||
"\u201chttp://example.com/tests/image/test/mochitest/blue.png\u201d " +
|
||||
"on a secure page",
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_WARNING,
|
||||
objects: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
yield testClickOpenNewTab(hud, results);
|
||||
});
|
||||
|
||||
function pushPrefEnv() {
|
||||
let deferred = promise.defer();
|
||||
let options = {"set":
|
||||
[["security.mixed_content.block_active_content", false],
|
||||
["security.mixed_content.block_display_content", false]
|
||||
]};
|
||||
SpecialPowers.pushPrefEnv(options, deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testClickOpenNewTab(hud, results) {
|
||||
let warningNode = results[0].clickableElements[0];
|
||||
ok(warningNode, "link element");
|
||||
ok(warningNode.classList.contains("learn-more-link"), "link class name");
|
||||
return simulateMessageLinkClick(warningNode, LEARN_MORE_URI);
|
||||
}
|
||||
56
devtools/client/webconsole/test/browser_webconsole_assert.js
Normal file
56
devtools/client/webconsole/test/browser_webconsole_assert.js
Normal file
|
|
@ -0,0 +1,56 @@
|
|||
/* -*- 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 console.assert() works as expected (i.e. outputs only on falsy
|
||||
// asserts). See bug 760193.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console-assert.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
yield consoleOpened(hud);
|
||||
});
|
||||
|
||||
function consoleOpened(hud) {
|
||||
hud.jsterm.execute("test()");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "undefined",
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "start",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "false assert",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "falsy assert",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "end",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
}).then(() => {
|
||||
let nodes = hud.outputNode.querySelectorAll(".message");
|
||||
is(nodes.length, 6,
|
||||
"only six messages are displayed, no output from the true assert");
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
// Test that properties starting with underscores or dollars can be
|
||||
// autocompleted (bug 967468).
|
||||
|
||||
add_task(function* () {
|
||||
const TEST_URI = "data:text/html;charset=utf8,test autocompletion with " +
|
||||
"$ or _";
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
function* autocomplete(term) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
jsterm.setInputValue(term);
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, deferred.resolve);
|
||||
|
||||
yield deferred.promise;
|
||||
|
||||
ok(popup.itemCount > 0,
|
||||
"There's " + popup.itemCount + " suggestions for '" + term + "'");
|
||||
}
|
||||
|
||||
let { jsterm } = yield openConsole();
|
||||
let popup = jsterm.autocompletePopup;
|
||||
|
||||
yield jsterm.execute("var testObject = {$$aaab: '', $$aaac: ''}");
|
||||
|
||||
// Should work with bug 967468.
|
||||
yield autocomplete("Object.__d");
|
||||
yield autocomplete("testObject.$$a");
|
||||
|
||||
// Here's when things go wrong in bug 967468.
|
||||
yield autocomplete("Object.__de");
|
||||
yield autocomplete("testObject.$$aa");
|
||||
|
||||
// Should work with bug 1207868.
|
||||
yield jsterm.execute("let foobar = {a: ''}; const blargh = {a: 1};");
|
||||
yield autocomplete("foobar");
|
||||
yield autocomplete("blargh");
|
||||
yield autocomplete("foobar.a");
|
||||
yield autocomplete("blargh.a");
|
||||
});
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the autocomplete input is being blurred and focused when selecting a value.
|
||||
// This will help screen-readers notify users of the value that was set in the input.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>test code completion";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
let jsterm = hud.jsterm;
|
||||
let input = jsterm.inputNode;
|
||||
|
||||
info("Type 'd' to open the autocomplete popup");
|
||||
yield autocomplete(jsterm, "d");
|
||||
|
||||
// Add listeners for focus and blur events.
|
||||
let wasBlurred = false;
|
||||
input.addEventListener("blur", () => {
|
||||
wasBlurred = true;
|
||||
}, {
|
||||
once: true
|
||||
});
|
||||
|
||||
let wasFocused = false;
|
||||
input.addEventListener("blur", () => {
|
||||
ok(wasBlurred, "jsterm input received a blur event before received back the focus");
|
||||
wasFocused = true;
|
||||
}, {
|
||||
once: true
|
||||
});
|
||||
|
||||
info("Close the autocomplete popup by simulating a TAB key event");
|
||||
let onPopupClosed = jsterm.autocompletePopup.once("popup-closed");
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
|
||||
info("Wait for the autocomplete popup to be closed");
|
||||
yield onPopupClosed;
|
||||
|
||||
ok(wasFocused, "jsterm input received a focus event");
|
||||
});
|
||||
|
||||
function* autocomplete(jsterm, value) {
|
||||
let popup = jsterm.autocompletePopup;
|
||||
|
||||
yield new Promise(resolve => {
|
||||
jsterm.setInputValue(value);
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
ok(popup.isOpen && popup.itemCount > 0,
|
||||
"Autocomplete popup is open and contains suggestions");
|
||||
}
|
||||
|
|
@ -0,0 +1,130 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>test for bug 642615";
|
||||
|
||||
XPCOMUtils.defineLazyServiceGetter(this, "clipboardHelper",
|
||||
"@mozilla.org/widget/clipboardhelper;1",
|
||||
"nsIClipboardHelper");
|
||||
var WebConsoleUtils = require("devtools/client/webconsole/utils").Utils;
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield consoleOpened(hud);
|
||||
});
|
||||
|
||||
function consoleOpened(HUD) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let jsterm = HUD.jsterm;
|
||||
let stringToCopy = "foobazbarBug642615";
|
||||
|
||||
jsterm.clearOutput();
|
||||
|
||||
ok(!jsterm.completeNode.value, "no completeNode.value");
|
||||
|
||||
jsterm.setInputValue("doc");
|
||||
|
||||
let completionValue;
|
||||
|
||||
// wait for key "u"
|
||||
function onCompletionValue() {
|
||||
completionValue = jsterm.completeNode.value;
|
||||
|
||||
// Arguments: expected, setup, success, failure.
|
||||
waitForClipboard(
|
||||
stringToCopy,
|
||||
function () {
|
||||
clipboardHelper.copyString(stringToCopy);
|
||||
},
|
||||
onClipboardCopy,
|
||||
finishTest);
|
||||
}
|
||||
|
||||
function onClipboardCopy() {
|
||||
testSelfXss();
|
||||
|
||||
jsterm.setInputValue("docu");
|
||||
info("wait for completion update after clipboard paste");
|
||||
updateEditUIVisibility();
|
||||
jsterm.once("autocomplete-updated", onClipboardPaste);
|
||||
goDoCommand("cmd_paste");
|
||||
}
|
||||
|
||||
// Self xss prevention tests (bug 994134)
|
||||
function testSelfXss() {
|
||||
info("Self-xss paste tests");
|
||||
WebConsoleUtils.usageCount = 0;
|
||||
is(WebConsoleUtils.usageCount, 0, "Test for usage count getter");
|
||||
// Input some commands to check if usage counting is working
|
||||
for (let i = 0; i <= 3; i++) {
|
||||
jsterm.setInputValue(i);
|
||||
jsterm.execute();
|
||||
}
|
||||
is(WebConsoleUtils.usageCount, 4, "Usage count incremented");
|
||||
WebConsoleUtils.usageCount = 0;
|
||||
updateEditUIVisibility();
|
||||
|
||||
let oldVal = jsterm.getInputValue();
|
||||
goDoCommand("cmd_paste");
|
||||
let notificationbox = jsterm.hud.document.getElementById("webconsole-notificationbox");
|
||||
let notification = notificationbox.getNotificationWithValue("selfxss-notification");
|
||||
ok(notification, "Self-xss notification shown");
|
||||
is(oldVal, jsterm.getInputValue(), "Paste blocked by self-xss prevention");
|
||||
|
||||
// Allow pasting
|
||||
jsterm.setInputValue("allow pasting");
|
||||
let evt = document.createEvent("KeyboardEvent");
|
||||
evt.initKeyEvent("keyup", true, true, window,
|
||||
0, 0, 0, 0,
|
||||
0, " ".charCodeAt(0));
|
||||
jsterm.inputNode.dispatchEvent(evt);
|
||||
jsterm.setInputValue("");
|
||||
goDoCommand("cmd_paste");
|
||||
isnot("", jsterm.getInputValue(), "Paste works");
|
||||
}
|
||||
function onClipboardPaste() {
|
||||
ok(!jsterm.completeNode.value, "no completion value after paste");
|
||||
|
||||
info("wait for completion update after undo");
|
||||
jsterm.once("autocomplete-updated", onCompletionValueAfterUndo);
|
||||
|
||||
// Get out of the webconsole event loop.
|
||||
executeSoon(() => {
|
||||
goDoCommand("cmd_undo");
|
||||
});
|
||||
}
|
||||
|
||||
function onCompletionValueAfterUndo() {
|
||||
is(jsterm.completeNode.value, completionValue,
|
||||
"same completeNode.value after undo");
|
||||
|
||||
info("wait for completion update after clipboard paste (ctrl-v)");
|
||||
jsterm.once("autocomplete-updated", () => {
|
||||
ok(!jsterm.completeNode.value,
|
||||
"no completion value after paste (ctrl-v)");
|
||||
|
||||
// using executeSoon() to get out of the webconsole event loop.
|
||||
executeSoon(deferred.resolve);
|
||||
});
|
||||
|
||||
// Get out of the webconsole event loop.
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey("v", {accelKey: true});
|
||||
});
|
||||
}
|
||||
|
||||
info("wait for completion value after typing 'docu'");
|
||||
jsterm.once("autocomplete-updated", onCompletionValue);
|
||||
|
||||
EventUtils.synthesizeKey("u", {});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that autocomplete doesn't break when trying to reach into objects from
|
||||
// a different domain, bug 989025.
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
let hud;
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-989025-iframe-parent.html";
|
||||
|
||||
Task.spawn(function* () {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
hud = yield openConsole(tab);
|
||||
|
||||
hud.jsterm.execute("document.title");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "989025 - iframe parent",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}],
|
||||
});
|
||||
|
||||
let autocompleteUpdated = hud.jsterm.once("autocomplete-updated");
|
||||
|
||||
hud.jsterm.setInputValue("window[0].document");
|
||||
executeSoon(() => {
|
||||
EventUtils.synthesizeKey(".", {});
|
||||
});
|
||||
|
||||
yield autocompleteUpdated;
|
||||
|
||||
hud.jsterm.setInputValue("window[0].document.title");
|
||||
EventUtils.synthesizeKey("VK_RETURN", {});
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "Permission denied",
|
||||
category: CATEGORY_OUTPUT,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
|
||||
hud.jsterm.execute("window.location");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-bug-989025-iframe-parent.html",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}],
|
||||
});
|
||||
|
||||
yield closeConsole(tab);
|
||||
}).then(finishTest);
|
||||
}
|
||||
|
|
@ -0,0 +1,245 @@
|
|||
/* -*- 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 makes sure web console autocomplete happens in the user-selected
|
||||
// stackframe from the js debugger.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-autocomplete-in-stackframe.html";
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
var gStackframes;
|
||||
registerCleanupFunction(function () {
|
||||
gStackframes = null;
|
||||
});
|
||||
|
||||
requestLongerTimeout(2);
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
yield testCompletion(hud);
|
||||
});
|
||||
|
||||
function* testCompletion(hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
let input = jsterm.inputNode;
|
||||
let popup = jsterm.autocompletePopup;
|
||||
|
||||
// Test that document.title gives string methods. Native getters must execute.
|
||||
input.value = "document.title.";
|
||||
input.setSelectionRange(input.value.length, input.value.length);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
let newItems = popup.getItems();
|
||||
ok(newItems.length > 0, "'document.title.' gave a list of suggestions");
|
||||
ok(newItems.some(function (item) {
|
||||
return item.label == "substr";
|
||||
}), "autocomplete results do contain substr");
|
||||
ok(newItems.some(function (item) {
|
||||
return item.label == "toLowerCase";
|
||||
}), "autocomplete results do contain toLowerCase");
|
||||
ok(newItems.some(function (item) {
|
||||
return item.label == "strike";
|
||||
}), "autocomplete results do contain strike");
|
||||
|
||||
// Test if 'f' gives 'foo1' but not 'foo2' or 'foo3'
|
||||
input.value = "f";
|
||||
input.setSelectionRange(1, 1);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(newItems.length > 0, "'f' gave a list of suggestions");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo1";
|
||||
}), "autocomplete results do contain foo1");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo1Obj";
|
||||
}), "autocomplete results do contain foo1Obj");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo2";
|
||||
}), "autocomplete results do not contain foo2");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo2Obj";
|
||||
}), "autocomplete results do not contain foo2Obj");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo3";
|
||||
}), "autocomplete results do not contain foo3");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo3Obj";
|
||||
}), "autocomplete results do not contain foo3Obj");
|
||||
|
||||
// Test if 'foo1Obj.' gives 'prop1' and 'prop2'
|
||||
input.value = "foo1Obj.";
|
||||
input.setSelectionRange(8, 8);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "prop1";
|
||||
}), "autocomplete results do contain prop1");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "prop2";
|
||||
}), "autocomplete results do contain prop2");
|
||||
|
||||
// Test if 'foo1Obj.prop2.' gives 'prop21'
|
||||
input.value = "foo1Obj.prop2.";
|
||||
input.setSelectionRange(14, 14);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "prop21";
|
||||
}), "autocomplete results do contain prop21");
|
||||
|
||||
info("Opening Debugger");
|
||||
let dbg = yield openDebugger();
|
||||
|
||||
info("Waiting for pause");
|
||||
yield pauseDebugger(dbg);
|
||||
|
||||
info("Opening Console again");
|
||||
yield openConsole();
|
||||
|
||||
// From this point on the
|
||||
// Test if 'f' gives 'foo3' and 'foo1' but not 'foo2'
|
||||
input.value = "f";
|
||||
input.setSelectionRange(1, 1);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(newItems.length > 0, "'f' gave a list of suggestions");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo3";
|
||||
}), "autocomplete results do contain foo3");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo3Obj";
|
||||
}), "autocomplete results do contain foo3Obj");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo1";
|
||||
}), "autocomplete results do contain foo1");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo1Obj";
|
||||
}), "autocomplete results do contain foo1Obj");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo2";
|
||||
}), "autocomplete results do not contain foo2");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo2Obj";
|
||||
}), "autocomplete results do not contain foo2Obj");
|
||||
|
||||
yield openDebugger();
|
||||
|
||||
gStackframes.selectFrame(1);
|
||||
|
||||
info("openConsole");
|
||||
yield openConsole();
|
||||
|
||||
// Test if 'f' gives 'foo2' and 'foo1' but not 'foo3'
|
||||
input.value = "f";
|
||||
input.setSelectionRange(1, 1);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(newItems.length > 0, "'f' gave a list of suggestions");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo2";
|
||||
}), "autocomplete results do contain foo2");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo2Obj";
|
||||
}), "autocomplete results do contain foo2Obj");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo1";
|
||||
}), "autocomplete results do contain foo1");
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "foo1Obj";
|
||||
}), "autocomplete results do contain foo1Obj");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo3";
|
||||
}), "autocomplete results do not contain foo3");
|
||||
ok(newItems.every(function (item) {
|
||||
return item.label != "foo3Obj";
|
||||
}), "autocomplete results do not contain foo3Obj");
|
||||
|
||||
// Test if 'foo2Obj.' gives 'prop1'
|
||||
input.value = "foo2Obj.";
|
||||
input.setSelectionRange(8, 8);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "prop1";
|
||||
}), "autocomplete results do contain prop1");
|
||||
|
||||
// Test if 'foo2Obj.prop1.' gives 'prop11'
|
||||
input.value = "foo2Obj.prop1.";
|
||||
input.setSelectionRange(14, 14);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "prop11";
|
||||
}), "autocomplete results do contain prop11");
|
||||
|
||||
// Test if 'foo2Obj.prop1.prop11.' gives suggestions for a string
|
||||
// i.e. 'length'
|
||||
input.value = "foo2Obj.prop1.prop11.";
|
||||
input.setSelectionRange(21, 21);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
ok(!newItems.every(function (item) {
|
||||
return item.label != "length";
|
||||
}), "autocomplete results do contain length");
|
||||
|
||||
// Test if 'foo1Obj[0].' throws no errors.
|
||||
input.value = "foo2Obj[0].";
|
||||
input.setSelectionRange(11, 11);
|
||||
yield new Promise(resolve => {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY, resolve);
|
||||
});
|
||||
|
||||
newItems = popup.getItems();
|
||||
is(newItems.length, 0, "no items for foo2Obj[0]");
|
||||
}
|
||||
|
||||
function pauseDebugger(aResult) {
|
||||
let debuggerWin = aResult.panelWin;
|
||||
let debuggerController = debuggerWin.DebuggerController;
|
||||
let thread = debuggerController.activeThread;
|
||||
gStackframes = debuggerController.StackFrames;
|
||||
return new Promise(resolve => {
|
||||
thread.addOneTimeListener("framesadded", resolve);
|
||||
|
||||
info("firstCall()");
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.firstCall();
|
||||
});
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,27 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that the autocomplete popup closes on switching tabs. See bug 900448.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>bug 900448 - autocomplete " +
|
||||
"popup closes on tab switch";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
let popup = hud.jsterm.autocompletePopup;
|
||||
let popupShown = once(popup, "popup-opened");
|
||||
|
||||
hud.jsterm.setInputValue("sc");
|
||||
EventUtils.synthesizeKey("r", {});
|
||||
|
||||
yield popupShown;
|
||||
|
||||
yield loadTab("data:text/html;charset=utf-8,<p>testing autocomplete closes");
|
||||
|
||||
ok(!popup.isOpen, "Popup closes on tab switch");
|
||||
});
|
||||
|
|
@ -0,0 +1,110 @@
|
|||
/* -*- 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/ */
|
||||
|
||||
// The test loads a web page with mixed active and display content
|
||||
// on it while the "block mixed content" settings are _on_.
|
||||
// It then checks that the blocked mixed content warning messages
|
||||
// are logged to the console and have the correct "Learn More"
|
||||
// url appended to them. After the first test finishes, it invokes
|
||||
// a second test that overrides the mixed content blocker settings
|
||||
// by clicking on the doorhanger shield and validates that the
|
||||
// appropriate messages are logged to console.
|
||||
// Bug 875456 - Log mixed content messages from the Mixed Content
|
||||
// Blocker to the Security Pane in the Web Console
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "https://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-mixedcontent-securityerrors.html";
|
||||
const LEARN_MORE_URI = "https://developer.mozilla.org/docs/Web/Security/" +
|
||||
"Mixed_content" + DOCS_GA_PARAMS;
|
||||
|
||||
add_task(function* () {
|
||||
yield pushPrefEnv();
|
||||
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
let results = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "Logged blocking mixed active content",
|
||||
text: "Blocked loading mixed active content \u201chttp://example.com/\u201d",
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_ERROR,
|
||||
objects: true,
|
||||
},
|
||||
{
|
||||
name: "Logged blocking mixed passive content - image",
|
||||
text: "Blocked loading mixed active content \u201chttp://example.com/\u201d",
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_ERROR,
|
||||
objects: true,
|
||||
},
|
||||
],
|
||||
});
|
||||
|
||||
yield testClickOpenNewTab(hud, results[0]);
|
||||
|
||||
let results2 = yield mixedContentOverrideTest2(hud, browser);
|
||||
|
||||
yield testClickOpenNewTab(hud, results2[0]);
|
||||
});
|
||||
|
||||
function pushPrefEnv() {
|
||||
let deferred = promise.defer();
|
||||
let options = {
|
||||
"set": [
|
||||
["security.mixed_content.block_active_content", true],
|
||||
["security.mixed_content.block_display_content", true],
|
||||
["security.mixed_content.use_hsts", false],
|
||||
["security.mixed_content.send_hsts_priming", false],
|
||||
]
|
||||
};
|
||||
SpecialPowers.pushPrefEnv(options, deferred.resolve);
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function mixedContentOverrideTest2(hud, browser) {
|
||||
let deferred = promise.defer();
|
||||
let {gIdentityHandler} = browser.ownerGlobal;
|
||||
ok(gIdentityHandler._identityBox.classList.contains("mixedActiveBlocked"),
|
||||
"Mixed Active Content state appeared on identity box");
|
||||
gIdentityHandler.disableMixedContentProtection();
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "Logged blocking mixed active content",
|
||||
text: "Loading mixed (insecure) active content " +
|
||||
"\u201chttp://example.com/\u201d on a secure page",
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_WARNING,
|
||||
objects: true,
|
||||
},
|
||||
{
|
||||
name: "Logged blocking mixed passive content - image",
|
||||
text: "Loading mixed (insecure) display content" +
|
||||
" \u201chttp://example.com/tests/image/test/mochitest/blue.png\u201d" +
|
||||
" on a secure page",
|
||||
category: CATEGORY_SECURITY,
|
||||
severity: SEVERITY_WARNING,
|
||||
objects: true,
|
||||
},
|
||||
],
|
||||
}).then(msgs => deferred.resolve(msgs), e => console.error(e));
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testClickOpenNewTab(hud, match) {
|
||||
let warningNode = match.clickableElements[0];
|
||||
ok(warningNode, "link element");
|
||||
ok(warningNode.classList.contains("learn-more-link"), "link class name");
|
||||
return simulateMessageLinkClick(warningNode, LEARN_MORE_URI);
|
||||
}
|
||||
|
|
@ -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/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
function test() {
|
||||
Task.spawn(runner).then(finishTest);
|
||||
|
||||
function* runner() {
|
||||
const {tab} = yield loadTab("data:text/html;charset=utf8,<title>Test for " +
|
||||
"Bug 1006027");
|
||||
|
||||
const hud = yield openConsole(tab);
|
||||
|
||||
hud.jsterm.execute("console.log('bug1006027')");
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "console.log",
|
||||
text: "bug1006027",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
info("hud.outputNode.textContent:\n" + hud.outputNode.textContent);
|
||||
let timestampNodes = hud.outputNode.querySelectorAll("span.timestamp");
|
||||
let aTimestampMilliseconds = Array.prototype.map.call(timestampNodes,
|
||||
function (value) {
|
||||
// We are parsing timestamps as local time, relative to the begin of
|
||||
// the epoch.
|
||||
// This is not the correct value of the timestamp, but good enough for
|
||||
// comparison.
|
||||
return Date.parse("T" + String.trim(value.textContent));
|
||||
});
|
||||
|
||||
let minTimestamp = Math.min.apply(null, aTimestampMilliseconds);
|
||||
let maxTimestamp = Math.max.apply(null, aTimestampMilliseconds);
|
||||
ok(Math.abs(maxTimestamp - minTimestamp) < 2000,
|
||||
"console.log message timestamp spread < 2000ms confirmed");
|
||||
}
|
||||
}
|
||||
|
|
@ -0,0 +1,55 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
/* We are loading:
|
||||
a script that is allowed by the CSP header but not by the CSPRO header
|
||||
an image which is allowed by the CSPRO header but not by the CSP header.
|
||||
|
||||
So we expect a warning (image has been blocked) and a report
|
||||
(script should not load and was reported)
|
||||
|
||||
The expected console messages in the constants CSP_VIOLATION_MSG and
|
||||
CSP_REPORT_MSG are confirmed to be found in the console messages.
|
||||
*/
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,Web Console CSP report only " +
|
||||
"test (bug 1010953)";
|
||||
const TEST_VIOLATION = "http://example.com/browser/devtools/client/" +
|
||||
"webconsole/test/test_bug_1010953_cspro.html";
|
||||
const CSP_VIOLATION_MSG = "Content Security Policy: The page\u2019s settings " +
|
||||
"blocked the loading of a resource at " +
|
||||
"http://some.example.com/test.png " +
|
||||
"(\u201cimg-src http://example.com\u201d).";
|
||||
const CSP_REPORT_MSG = "Content Security Policy: The page\u2019s settings " +
|
||||
"observed the loading of a resource at " +
|
||||
"http://some.example.com/test_bug_1010953_cspro.js " +
|
||||
"(\u201cscript-src http://example.com\u201d). A CSP report is " +
|
||||
"being sent.";
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserTestUtils.loadURI(browser, TEST_VIOLATION);
|
||||
yield loaded;
|
||||
|
||||
yield waitForSuccess({
|
||||
name: "Confirmed that CSP and CSP-Report-Only log different messages to " +
|
||||
"the console.",
|
||||
validator: function () {
|
||||
console.log(hud.outputNode.textContent);
|
||||
let success = false;
|
||||
success = hud.outputNode.textContent.indexOf(CSP_VIOLATION_MSG) > -1 &&
|
||||
hud.outputNode.textContent.indexOf(CSP_REPORT_MSG) > -1;
|
||||
return success;
|
||||
}
|
||||
});
|
||||
});
|
||||
|
|
@ -0,0 +1,60 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that clicking on a function displays its source in the debugger.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug_1050691_click_function_to_source.html";
|
||||
|
||||
// Force the old debugger UI since it's directly used (see Bug 1301705)
|
||||
Services.prefs.setBoolPref("devtools.debugger.new-debugger-frontend", false);
|
||||
registerCleanupFunction(function* () {
|
||||
Services.prefs.clearUserPref("devtools.debugger.new-debugger-frontend");
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
// Open the Debugger panel.
|
||||
let debuggerPanel = yield openDebugger();
|
||||
// And right after come back to the Console panel.
|
||||
yield openConsole();
|
||||
yield testWithDebuggerOpen(hud, debuggerPanel);
|
||||
});
|
||||
|
||||
function* testWithDebuggerOpen(hud, debuggerPanel) {
|
||||
let clickable = yield printFunction(hud);
|
||||
let panelWin = debuggerPanel.panelWin;
|
||||
let onEditorLocationSet = panelWin.once(panelWin.EVENTS.EDITOR_LOCATION_SET);
|
||||
synthesizeClick(clickable, hud);
|
||||
yield onEditorLocationSet;
|
||||
ok(isDebuggerCaretPos(debuggerPanel, 7),
|
||||
"Clicking on a function should go to its source in the debugger view");
|
||||
}
|
||||
|
||||
function synthesizeClick(clickable, hud) {
|
||||
EventUtils.synthesizeMouse(clickable, 2, 2, {}, hud.iframeWindow);
|
||||
}
|
||||
|
||||
var printFunction = Task.async(function* (hud) {
|
||||
hud.jsterm.clearOutput();
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.foo();
|
||||
});
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
let msg = [...result.matched][0];
|
||||
let clickable = msg.querySelector("a");
|
||||
ok(clickable, "clickable item for object should exist");
|
||||
return clickable;
|
||||
});
|
||||
|
|
@ -0,0 +1,40 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the Web Console CSP messages for two META policies
|
||||
// are correctly displayed.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,Web Console CSP violation test";
|
||||
const TEST_VIOLATION = "https://example.com/browser/devtools/client/" +
|
||||
"webconsole/test/test_bug_1247459_violation.html";
|
||||
const CSP_VIOLATION_MSG = "Content Security Policy: The page\u2019s settings " +
|
||||
"blocked the loading of a resource at " +
|
||||
"http://some.example.com/test.png (\u201cimg-src " +
|
||||
"https://example.com\u201d).";
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserTestUtils.loadURI(browser, TEST_VIOLATION);
|
||||
yield loaded;
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
name: "CSP policy URI warning displayed successfully",
|
||||
text: CSP_VIOLATION_MSG,
|
||||
repeats: 2
|
||||
}
|
||||
]
|
||||
});
|
||||
});
|
||||
|
|
@ -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/ */
|
||||
|
||||
// Tests that the console object still exists after a page reload.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
var browser;
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then((tab) => {
|
||||
browser = tab.browser;
|
||||
|
||||
browser.addEventListener("DOMContentLoaded", testPageReload, false);
|
||||
content.location.reload();
|
||||
});
|
||||
});
|
||||
browser.addEventListener("DOMContentLoaded", onLoad, false);
|
||||
}
|
||||
|
||||
function testPageReload() {
|
||||
browser.removeEventListener("DOMContentLoaded", testPageReload, false);
|
||||
|
||||
let console = browser.contentWindow.wrappedJSObject.console;
|
||||
|
||||
is(typeof console, "object", "window.console is an object, after page reload");
|
||||
is(typeof console.log, "function", "console.log is a function");
|
||||
is(typeof console.info, "function", "console.info is a function");
|
||||
is(typeof console.warn, "function", "console.warn is a function");
|
||||
is(typeof console.error, "function", "console.error is a function");
|
||||
is(typeof console.exception, "function", "console.exception is a function");
|
||||
|
||||
browser = null;
|
||||
finishTest();
|
||||
}
|
||||
|
|
@ -0,0 +1,20 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the input field is focused when the console is opened.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
let inputNode = hud.jsterm.inputNode;
|
||||
ok(inputNode.getAttribute("focused"), "input node is focused");
|
||||
});
|
||||
|
|
@ -0,0 +1,47 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests to ensure that errors don't appear when the console is closed while a
|
||||
// completion is being performed.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
yield testClosingAfterCompletion(hud, browser);
|
||||
});
|
||||
|
||||
function testClosingAfterCompletion(hud, browser) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let errorWhileClosing = false;
|
||||
function errorListener() {
|
||||
errorWhileClosing = true;
|
||||
}
|
||||
|
||||
browser.addEventListener("error", errorListener, false);
|
||||
|
||||
// Focus the jsterm and perform the keycombo to close the WebConsole.
|
||||
hud.jsterm.focus();
|
||||
|
||||
gDevTools.once("toolbox-destroyed", function () {
|
||||
browser.removeEventListener("error", errorListener, false);
|
||||
is(errorWhileClosing, false, "no error while closing the WebConsole");
|
||||
deferred.resolve();
|
||||
});
|
||||
|
||||
if (Services.appinfo.OS == "Darwin") {
|
||||
EventUtils.synthesizeKey("i", { accelKey: true, altKey: true });
|
||||
} else {
|
||||
EventUtils.synthesizeKey("i", { accelKey: true, shiftKey: true });
|
||||
}
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,50 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that errors still show up in the Web Console after a page reload.
|
||||
// See bug 580030: the error handler fails silently after page reload.
|
||||
// https://bugzilla.mozilla.org/show_bug.cgi?id=580030
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-error.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
const hud = yield openConsole(tab);
|
||||
info("console opened");
|
||||
|
||||
executeSoon(() => {
|
||||
hud.jsterm.clearOutput();
|
||||
info("wait for reload");
|
||||
content.location.reload();
|
||||
});
|
||||
|
||||
yield hud.target.once("navigate");
|
||||
info("target navigated");
|
||||
|
||||
let button = content.document.querySelector("button");
|
||||
ok(button, "button found");
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
EventUtils.sendMouseEvent({type: "click"}, button, content);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "fooBazBaz is not defined",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
}).then(finishTest);
|
||||
}
|
||||
|
|
@ -0,0 +1,26 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that appropriately-localized timestamps are printed.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
const TEST_TIMESTAMP = 12345678;
|
||||
let date = new Date(TEST_TIMESTAMP);
|
||||
let localizedString = WCUL10n.timestampString(TEST_TIMESTAMP);
|
||||
isnot(localizedString.indexOf(date.getHours()), -1, "the localized " +
|
||||
"timestamp contains the hours");
|
||||
isnot(localizedString.indexOf(date.getMinutes()), -1, "the localized " +
|
||||
"timestamp contains the minutes");
|
||||
isnot(localizedString.indexOf(date.getSeconds()), -1, "the localized " +
|
||||
"timestamp contains the seconds");
|
||||
isnot(localizedString.indexOf(date.getMilliseconds()), -1, "the localized " +
|
||||
"timestamp contains the milliseconds");
|
||||
});
|
||||
|
|
@ -0,0 +1,49 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that exceptions thrown by content don't show up twice in the Web
|
||||
// Console.
|
||||
|
||||
"use strict";
|
||||
|
||||
const INIT_URI = "data:text/html;charset=utf8,hello world";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-duplicate-error.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(INIT_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "fooDuplicateError1",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "test-duplicate-error.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
let text = hud.outputNode.textContent;
|
||||
let error1pos = text.indexOf("fooDuplicateError1");
|
||||
ok(error1pos > -1, "found fooDuplicateError1");
|
||||
if (error1pos > -1) {
|
||||
ok(text.indexOf("fooDuplicateError1", error1pos + 1) == -1,
|
||||
"no duplicate for fooDuplicateError1");
|
||||
}
|
||||
});
|
||||
|
|
@ -0,0 +1,35 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/browser/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
testCompletion(hud);
|
||||
});
|
||||
|
||||
function testCompletion(hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
let input = jsterm.inputNode;
|
||||
|
||||
jsterm.setInputValue("");
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
is(jsterm.completeNode.value, "<- no result", "<- no result - matched");
|
||||
is(input.value, "", "inputnode is empty - matched");
|
||||
is(input.getAttribute("focused"), "true", "input is still focused");
|
||||
|
||||
// Any thing which is not in property autocompleter
|
||||
jsterm.setInputValue("window.Bug583816");
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
is(jsterm.completeNode.value, " <- no result",
|
||||
"completenode content - matched");
|
||||
is(input.value, "window.Bug583816", "inputnode content - matched");
|
||||
is(input.getAttribute("focused"), "true", "input is still focused");
|
||||
}
|
||||
|
|
@ -0,0 +1,89 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the Web Console limits the number of lines displayed according to
|
||||
// the user's preferences.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf8,test for bug 585237";
|
||||
|
||||
var outputNode;
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
outputNode = hud.outputNode;
|
||||
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
let prefBranch = Services.prefs.getBranch("devtools.hud.loglimit.");
|
||||
prefBranch.setIntPref("console", 20);
|
||||
|
||||
for (let i = 0; i < 30; i++) {
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, i, function (i) {
|
||||
// must change message to prevent repeats
|
||||
content.console.log("foo #" + i);
|
||||
});
|
||||
}
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foo #29",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
is(countMessageNodes(), 20, "there are 20 message nodes in the output " +
|
||||
"when the log limit is set to 20");
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function () {
|
||||
content.console.log("bar bug585237");
|
||||
});
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "bar bug585237",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
is(countMessageNodes(), 20, "there are still 20 message nodes in the " +
|
||||
"output when adding one more");
|
||||
|
||||
prefBranch.setIntPref("console", 30);
|
||||
for (let i = 0; i < 20; i++) {
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, i, function (i) {
|
||||
// must change message to prevent repeats
|
||||
content.console.log("boo #" + i);
|
||||
});
|
||||
}
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "boo #19",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
|
||||
is(countMessageNodes(), 30, "there are 30 message nodes in the output " +
|
||||
"when the log limit is set to 30");
|
||||
|
||||
prefBranch.clearUserPref("console");
|
||||
|
||||
outputNode = null;
|
||||
});
|
||||
|
||||
function countMessageNodes() {
|
||||
return outputNode.querySelectorAll(".message").length;
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/" +
|
||||
"webconsole/test/test-bug-585956-console-trace.html";
|
||||
|
||||
add_task(function* () {
|
||||
let {tab} = yield loadTab("data:text/html;charset=utf8,<p>hello");
|
||||
let hud = yield openConsole(tab);
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
|
||||
|
||||
let [result] = yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "console.trace output",
|
||||
consoleTrace: {
|
||||
file: "test-bug-585956-console-trace.html",
|
||||
fn: "window.foobar585956c",
|
||||
},
|
||||
}],
|
||||
});
|
||||
|
||||
let node = [...result.matched][0];
|
||||
ok(node, "found trace log node");
|
||||
|
||||
let obj = node._messageObject;
|
||||
ok(obj, "console.trace message object");
|
||||
|
||||
// The expected stack trace object.
|
||||
let stacktrace = [
|
||||
{
|
||||
columnNumber: 3,
|
||||
filename: TEST_URI,
|
||||
functionName: "window.foobar585956c",
|
||||
language: 2,
|
||||
lineNumber: 9
|
||||
},
|
||||
{
|
||||
columnNumber: 10,
|
||||
filename: TEST_URI,
|
||||
functionName: "foobar585956b",
|
||||
language: 2,
|
||||
lineNumber: 14
|
||||
},
|
||||
{
|
||||
columnNumber: 10,
|
||||
filename: TEST_URI,
|
||||
functionName: "foobar585956a",
|
||||
language: 2,
|
||||
lineNumber: 18
|
||||
},
|
||||
{
|
||||
columnNumber: 1,
|
||||
filename: TEST_URI,
|
||||
functionName: "",
|
||||
language: 2,
|
||||
lineNumber: 21
|
||||
}
|
||||
];
|
||||
|
||||
ok(obj._stacktrace, "found stacktrace object");
|
||||
is(obj._stacktrace.toSource(), stacktrace.toSource(),
|
||||
"stacktrace is correct");
|
||||
isnot(node.textContent.indexOf("bug-585956"), -1, "found file name");
|
||||
});
|
||||
|
|
@ -0,0 +1,367 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>bug 585991 - autocomplete " +
|
||||
"popup keyboard usage test";
|
||||
|
||||
// We should turn off auto-multiline editing during these tests
|
||||
const PREF_AUTO_MULTILINE = "devtools.webconsole.autoMultiline";
|
||||
var HUD, popup, jsterm, inputNode, completeNode;
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref(PREF_AUTO_MULTILINE, false);
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield consoleOpened(hud);
|
||||
yield popupHideAfterTab();
|
||||
yield testReturnKey();
|
||||
yield dontShowArrayNumbers();
|
||||
yield testReturnWithNoSelection();
|
||||
yield popupHideAfterReturnWithNoSelection();
|
||||
yield testCompletionInText();
|
||||
yield popupHideAfterCompletionInText();
|
||||
|
||||
HUD = popup = jsterm = inputNode = completeNode = null;
|
||||
Services.prefs.setBoolPref(PREF_AUTO_MULTILINE, true);
|
||||
});
|
||||
|
||||
var consoleOpened = Task.async(function* (hud) {
|
||||
let deferred = promise.defer();
|
||||
HUD = hud;
|
||||
info("web console opened");
|
||||
|
||||
jsterm = HUD.jsterm;
|
||||
|
||||
yield jsterm.execute("window.foobarBug585991={" +
|
||||
"'item0': 'value0'," +
|
||||
"'item1': 'value1'," +
|
||||
"'item2': 'value2'," +
|
||||
"'item3': 'value3'" +
|
||||
"}");
|
||||
yield jsterm.execute("window.testBug873250a = 'hello world';"
|
||||
+ "window.testBug873250b = 'hello world 2';");
|
||||
popup = jsterm.autocompletePopup;
|
||||
completeNode = jsterm.completeNode;
|
||||
inputNode = jsterm.inputNode;
|
||||
|
||||
ok(!popup.isOpen, "popup is not open");
|
||||
|
||||
popup.once("popup-opened", () => {
|
||||
ok(popup.isOpen, "popup is open");
|
||||
|
||||
// 4 values, and the following properties:
|
||||
// __defineGetter__ __defineSetter__ __lookupGetter__ __lookupSetter__
|
||||
// __proto__ hasOwnProperty isPrototypeOf propertyIsEnumerable
|
||||
// toLocaleString toString toSource unwatch valueOf watch constructor.
|
||||
is(popup.itemCount, 19, "popup.itemCount is correct");
|
||||
|
||||
let sameItems = popup.getItems().reverse().map(function (e) {
|
||||
return e.label;
|
||||
});
|
||||
|
||||
ok(sameItems.every(function (prop, index) {
|
||||
return [
|
||||
"__defineGetter__",
|
||||
"__defineSetter__",
|
||||
"__lookupGetter__",
|
||||
"__lookupSetter__",
|
||||
"__proto__",
|
||||
"constructor",
|
||||
"hasOwnProperty",
|
||||
"isPrototypeOf",
|
||||
"item0",
|
||||
"item1",
|
||||
"item2",
|
||||
"item3",
|
||||
"propertyIsEnumerable",
|
||||
"toLocaleString",
|
||||
"toSource",
|
||||
"toString",
|
||||
"unwatch",
|
||||
"valueOf",
|
||||
"watch",
|
||||
][index] === prop;
|
||||
}), "getItems returns the items we expect");
|
||||
|
||||
is(popup.selectedIndex, 18,
|
||||
"Index of the first item from bottom is selected.");
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
let prefix = jsterm.getInputValue().replace(/[\S]/g, " ");
|
||||
|
||||
is(popup.selectedIndex, 0, "index 0 is selected");
|
||||
is(popup.selectedItem.label, "watch", "watch is selected");
|
||||
is(completeNode.value, prefix + "watch",
|
||||
"completeNode.value holds watch");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(popup.selectedIndex, 1, "index 1 is selected");
|
||||
is(popup.selectedItem.label, "valueOf", "valueOf is selected");
|
||||
is(completeNode.value, prefix + "valueOf",
|
||||
"completeNode.value holds valueOf");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
is(popup.selectedIndex, 0, "index 0 is selected");
|
||||
is(popup.selectedItem.label, "watch", "watch is selected");
|
||||
is(completeNode.value, prefix + "watch",
|
||||
"completeNode.value holds watch");
|
||||
|
||||
let currentSelectionIndex = popup.selectedIndex;
|
||||
|
||||
EventUtils.synthesizeKey("VK_PAGE_DOWN", {});
|
||||
|
||||
ok(popup.selectedIndex > currentSelectionIndex,
|
||||
"Index is greater after PGDN");
|
||||
|
||||
currentSelectionIndex = popup.selectedIndex;
|
||||
EventUtils.synthesizeKey("VK_PAGE_UP", {});
|
||||
|
||||
ok(popup.selectedIndex < currentSelectionIndex,
|
||||
"Index is less after Page UP");
|
||||
|
||||
EventUtils.synthesizeKey("VK_END", {});
|
||||
is(popup.selectedIndex, 18, "index is last after End");
|
||||
|
||||
EventUtils.synthesizeKey("VK_HOME", {});
|
||||
is(popup.selectedIndex, 0, "index is first after Home");
|
||||
|
||||
info("press Tab and wait for popup to hide");
|
||||
popup.once("popup-closed", () => {
|
||||
deferred.resolve();
|
||||
});
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
});
|
||||
|
||||
jsterm.setInputValue("window.foobarBug585991");
|
||||
EventUtils.synthesizeKey(".", {});
|
||||
|
||||
return deferred.promise;
|
||||
});
|
||||
|
||||
function popupHideAfterTab() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
// At this point the completion suggestion should be accepted.
|
||||
ok(!popup.isOpen, "popup is not open");
|
||||
|
||||
is(jsterm.getInputValue(), "window.foobarBug585991.watch",
|
||||
"completion was successful after VK_TAB");
|
||||
|
||||
ok(!completeNode.value, "completeNode is empty");
|
||||
|
||||
popup.once("popup-opened", function onShown() {
|
||||
ok(popup.isOpen, "popup is open");
|
||||
|
||||
is(popup.itemCount, 19, "popup.itemCount is correct");
|
||||
|
||||
is(popup.selectedIndex, 18, "First index from bottom is selected");
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
let prefix = jsterm.getInputValue().replace(/[\S]/g, " ");
|
||||
|
||||
is(popup.selectedIndex, 0, "index 0 is selected");
|
||||
is(popup.selectedItem.label, "watch", "watch is selected");
|
||||
is(completeNode.value, prefix + "watch",
|
||||
"completeNode.value holds watch");
|
||||
|
||||
popup.once("popup-closed", function onHidden() {
|
||||
ok(!popup.isOpen, "popup is not open after VK_ESCAPE");
|
||||
|
||||
is(jsterm.getInputValue(), "window.foobarBug585991.",
|
||||
"completion was cancelled");
|
||||
|
||||
ok(!completeNode.value, "completeNode is empty");
|
||||
|
||||
deferred.resolve();
|
||||
}, false);
|
||||
|
||||
info("press Escape to close the popup");
|
||||
executeSoon(function () {
|
||||
EventUtils.synthesizeKey("VK_ESCAPE", {});
|
||||
});
|
||||
}, false);
|
||||
|
||||
info("wait for completion: window.foobarBug585991.");
|
||||
executeSoon(function () {
|
||||
jsterm.setInputValue("window.foobarBug585991");
|
||||
EventUtils.synthesizeKey(".", {});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testReturnKey() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
popup.once("popup-opened", function onShown() {
|
||||
ok(popup.isOpen, "popup is open");
|
||||
|
||||
is(popup.itemCount, 19, "popup.itemCount is correct");
|
||||
|
||||
is(popup.selectedIndex, 18, "First index from bottom is selected");
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
let prefix = jsterm.getInputValue().replace(/[\S]/g, " ");
|
||||
|
||||
is(popup.selectedIndex, 0, "index 0 is selected");
|
||||
is(popup.selectedItem.label, "watch", "watch is selected");
|
||||
is(completeNode.value, prefix + "watch",
|
||||
"completeNode.value holds watch");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(popup.selectedIndex, 1, "index 1 is selected");
|
||||
is(popup.selectedItem.label, "valueOf", "valueOf is selected");
|
||||
is(completeNode.value, prefix + "valueOf",
|
||||
"completeNode.value holds valueOf");
|
||||
|
||||
popup.once("popup-closed", function onHidden() {
|
||||
ok(!popup.isOpen, "popup is not open after VK_RETURN");
|
||||
|
||||
is(jsterm.getInputValue(), "window.foobarBug585991.valueOf",
|
||||
"completion was successful after VK_RETURN");
|
||||
|
||||
ok(!completeNode.value, "completeNode is empty");
|
||||
|
||||
deferred.resolve();
|
||||
}, false);
|
||||
|
||||
info("press Return to accept suggestion. wait for popup to hide");
|
||||
|
||||
executeSoon(() => EventUtils.synthesizeKey("VK_RETURN", {}));
|
||||
}, false);
|
||||
|
||||
info("wait for completion suggestions: window.foobarBug585991.");
|
||||
|
||||
executeSoon(function () {
|
||||
jsterm.setInputValue("window.foobarBug58599");
|
||||
EventUtils.synthesizeKey("1", {});
|
||||
EventUtils.synthesizeKey(".", {});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function* dontShowArrayNumbers() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
info("dontShowArrayNumbers");
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.wrappedJSObject.foobarBug585991 = ["Sherlock Holmes"];
|
||||
});
|
||||
|
||||
jsterm = HUD.jsterm;
|
||||
popup = jsterm.autocompletePopup;
|
||||
|
||||
popup.once("popup-opened", function onShown() {
|
||||
let sameItems = popup.getItems().map(function (e) {
|
||||
return e.label;
|
||||
});
|
||||
ok(!sameItems.some(function (prop) {
|
||||
prop === "0";
|
||||
}), "Completing on an array doesn't show numbers.");
|
||||
|
||||
popup.once("popup-closed", function popupHidden() {
|
||||
deferred.resolve();
|
||||
}, false);
|
||||
|
||||
info("wait for popup to hide");
|
||||
executeSoon(() => EventUtils.synthesizeKey("VK_ESCAPE", {}));
|
||||
}, false);
|
||||
|
||||
info("wait for popup to show");
|
||||
executeSoon(() => {
|
||||
jsterm.setInputValue("window.foobarBug585991");
|
||||
EventUtils.synthesizeKey(".", {});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testReturnWithNoSelection() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
info("test pressing return with open popup, but no selection, see bug 873250");
|
||||
|
||||
popup.once("popup-opened", function onShown() {
|
||||
ok(popup.isOpen, "popup is open");
|
||||
is(popup.itemCount, 2, "popup.itemCount is correct");
|
||||
isnot(popup.selectedIndex, -1, "popup.selectedIndex is correct");
|
||||
|
||||
info("press Return and wait for popup to hide");
|
||||
popup.once("popup-closed", function popupHidden() {
|
||||
deferred.resolve();
|
||||
});
|
||||
executeSoon(() => EventUtils.synthesizeKey("VK_RETURN", {}));
|
||||
});
|
||||
|
||||
executeSoon(() => {
|
||||
info("wait for popup to show");
|
||||
jsterm.setInputValue("window.testBu");
|
||||
EventUtils.synthesizeKey("g", {});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function popupHideAfterReturnWithNoSelection() {
|
||||
ok(!popup.isOpen, "popup is not open after VK_RETURN");
|
||||
|
||||
is(jsterm.getInputValue(), "", "inputNode is empty after VK_RETURN");
|
||||
is(completeNode.value, "", "completeNode is empty");
|
||||
is(jsterm.history[jsterm.history.length - 1], "window.testBug",
|
||||
"jsterm history is correct");
|
||||
|
||||
return promise.resolve();
|
||||
}
|
||||
|
||||
function testCompletionInText() {
|
||||
info("test that completion works inside text, see bug 812618");
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
popup.once("popup-opened", function onShown() {
|
||||
ok(popup.isOpen, "popup is open");
|
||||
is(popup.itemCount, 2, "popup.itemCount is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
is(popup.selectedIndex, 0, "popup.selectedIndex is correct");
|
||||
ok(!completeNode.value, "completeNode.value is empty");
|
||||
|
||||
let items = popup.getItems().reverse().map(e => e.label);
|
||||
let sameItems = items.every((prop, index) =>
|
||||
["testBug873250a", "testBug873250b"][index] === prop);
|
||||
ok(sameItems, "getItems returns the items we expect");
|
||||
|
||||
info("press Tab and wait for popup to hide");
|
||||
popup.once("popup-closed", function popupHidden() {
|
||||
deferred.resolve();
|
||||
});
|
||||
EventUtils.synthesizeKey("VK_TAB", {});
|
||||
});
|
||||
|
||||
jsterm.setInputValue("dump(window.testBu)");
|
||||
inputNode.selectionStart = inputNode.selectionEnd = 18;
|
||||
EventUtils.synthesizeKey("g", {});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function popupHideAfterCompletionInText() {
|
||||
// At this point the completion suggestion should be accepted.
|
||||
ok(!popup.isOpen, "popup is not open");
|
||||
is(jsterm.getInputValue(), "dump(window.testBug873250b)",
|
||||
"completion was successful after VK_TAB");
|
||||
is(inputNode.selectionStart, 26, "cursor location is correct");
|
||||
is(inputNode.selectionStart, inputNode.selectionEnd,
|
||||
"cursor location (confirmed)");
|
||||
ok(!completeNode.value, "completeNode is empty");
|
||||
|
||||
return promise.resolve();
|
||||
}
|
||||
|
|
@ -0,0 +1,123 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<p>bug 585991 - autocomplete " +
|
||||
"popup test";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield consoleOpened(hud);
|
||||
});
|
||||
|
||||
function consoleOpened(HUD) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let items = [
|
||||
{label: "item0", value: "value0"},
|
||||
{label: "item1", value: "value1"},
|
||||
{label: "item2", value: "value2"},
|
||||
];
|
||||
|
||||
let popup = HUD.jsterm.autocompletePopup;
|
||||
let input = HUD.jsterm.inputNode;
|
||||
|
||||
ok(!popup.isOpen, "popup is not open");
|
||||
ok(!input.hasAttribute("aria-activedescendant"), "no aria-activedescendant");
|
||||
|
||||
popup.once("popup-opened", () => {
|
||||
ok(popup.isOpen, "popup is open");
|
||||
|
||||
is(popup.itemCount, 0, "no items");
|
||||
ok(!input.hasAttribute("aria-activedescendant"), "no aria-activedescendant");
|
||||
|
||||
popup.setItems(items);
|
||||
|
||||
is(popup.itemCount, items.length, "items added");
|
||||
|
||||
let sameItems = popup.getItems();
|
||||
is(sameItems.every(function (item, index) {
|
||||
return item === items[index];
|
||||
}), true, "getItems returns back the same items");
|
||||
|
||||
is(popup.selectedIndex, 2, "Index of the first item from bottom is selected.");
|
||||
is(popup.selectedItem, items[2], "First item from bottom is selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
|
||||
popup.selectedIndex = 1;
|
||||
|
||||
is(popup.selectedIndex, 1, "index 1 is selected");
|
||||
is(popup.selectedItem, items[1], "item1 is selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
|
||||
popup.selectedItem = items[2];
|
||||
|
||||
is(popup.selectedIndex, 2, "index 2 is selected");
|
||||
is(popup.selectedItem, items[2], "item2 is selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
|
||||
is(popup.selectPreviousItem(), items[1], "selectPreviousItem() works");
|
||||
|
||||
is(popup.selectedIndex, 1, "index 1 is selected");
|
||||
is(popup.selectedItem, items[1], "item1 is selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
|
||||
is(popup.selectNextItem(), items[2], "selectNextItem() works");
|
||||
|
||||
is(popup.selectedIndex, 2, "index 2 is selected");
|
||||
is(popup.selectedItem, items[2], "item2 is selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
|
||||
ok(popup.selectNextItem(), "selectNextItem() works");
|
||||
|
||||
is(popup.selectedIndex, 0, "index 0 is selected");
|
||||
is(popup.selectedItem, items[0], "item0 is selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
|
||||
items.push({label: "label3", value: "value3"});
|
||||
popup.appendItem(items[3]);
|
||||
|
||||
is(popup.itemCount, items.length, "item3 appended");
|
||||
|
||||
popup.selectedIndex = 3;
|
||||
is(popup.selectedItem, items[3], "item3 is selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
|
||||
popup.removeItem(items[2]);
|
||||
|
||||
is(popup.selectedIndex, 2, "index2 is selected");
|
||||
is(popup.selectedItem, items[3], "item3 is still selected");
|
||||
checkActiveDescendant(popup, input);
|
||||
is(popup.itemCount, items.length - 1, "item2 removed");
|
||||
|
||||
popup.clearItems();
|
||||
is(popup.itemCount, 0, "items cleared");
|
||||
ok(!input.hasAttribute("aria-activedescendant"), "no aria-activedescendant");
|
||||
|
||||
popup.once("popup-closed", () => {
|
||||
deferred.resolve();
|
||||
});
|
||||
popup.hidePopup();
|
||||
});
|
||||
|
||||
popup.openPopup(input);
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function checkActiveDescendant(popup, input) {
|
||||
let activeElement = input.ownerDocument.activeElement;
|
||||
let descendantId = activeElement.getAttribute("aria-activedescendant");
|
||||
let popupItem = popup._tooltip.panel.querySelector("#" + descendantId);
|
||||
let cloneItem = input.ownerDocument.querySelector("#" + descendantId);
|
||||
|
||||
ok(popupItem, "Active descendant is found in the popup list");
|
||||
ok(cloneItem, "Active descendant is found in the list clone");
|
||||
is(popupItem.innerHTML, cloneItem.innerHTML,
|
||||
"Cloned item has the same HTML as the original element");
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
yield testSelectionWhenMovingBetweenBoxes(hud);
|
||||
performTestsAfterOutput(hud);
|
||||
});
|
||||
|
||||
var testSelectionWhenMovingBetweenBoxes = Task.async(function* (hud) {
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
// Fill the console with some output.
|
||||
jsterm.clearOutput();
|
||||
yield jsterm.execute("1 + 2");
|
||||
yield jsterm.execute("3 + 4");
|
||||
yield jsterm.execute("5 + 6");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "3",
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
{
|
||||
text: "7",
|
||||
category: CATEGORY_OUTPUT,
|
||||
},
|
||||
{
|
||||
text: "11",
|
||||
category: CATEGORY_OUTPUT,
|
||||
}],
|
||||
});
|
||||
});
|
||||
|
||||
function performTestsAfterOutput(hud) {
|
||||
let outputNode = hud.outputNode;
|
||||
|
||||
ok(outputNode.childNodes.length >= 3, "the output node has children after " +
|
||||
"executing some JavaScript");
|
||||
|
||||
// Test that the global Firefox "Select All" functionality (e.g. Edit >
|
||||
// Select All) works properly in the Web Console.
|
||||
let commandController = hud.ui._commandController;
|
||||
ok(commandController != null, "the window has a command controller object");
|
||||
|
||||
commandController.selectAll();
|
||||
|
||||
let selectedCount = hud.ui.output.getSelectedMessages().length;
|
||||
is(selectedCount, outputNode.childNodes.length,
|
||||
"all console messages are selected after performing a regular browser " +
|
||||
"select-all operation");
|
||||
|
||||
hud.iframeWindow.getSelection().removeAllRanges();
|
||||
|
||||
// Test the context menu "Select All" (which has a different code path) works
|
||||
// properly as well.
|
||||
let contextMenuId = hud.ui.outputWrapper.getAttribute("context");
|
||||
let contextMenu = hud.ui.document.getElementById(contextMenuId);
|
||||
ok(contextMenu != null, "the output node has a context menu");
|
||||
|
||||
let selectAllItem = contextMenu.querySelector("*[command='cmd_selectAll']");
|
||||
ok(selectAllItem != null,
|
||||
"the context menu on the output node has a \"Select All\" item");
|
||||
|
||||
outputNode.focus();
|
||||
|
||||
selectAllItem.doCommand();
|
||||
|
||||
selectedCount = hud.ui.output.getSelectedMessages().length;
|
||||
is(selectedCount, outputNode.childNodes.length,
|
||||
"all console messages are selected after performing a select-all " +
|
||||
"operation from the context menu");
|
||||
|
||||
hud.iframeWindow.getSelection().removeAllRanges();
|
||||
}
|
||||
|
|
@ -0,0 +1,106 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
/* globals goUpdateCommand goDoCommand */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
var HUD, outputNode;
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
yield consoleOpened(hud);
|
||||
yield testContextMenuCopy();
|
||||
|
||||
HUD = outputNode = null;
|
||||
});
|
||||
|
||||
function consoleOpened(hud) {
|
||||
HUD = hud;
|
||||
|
||||
let deferred = promise.defer();
|
||||
|
||||
// See bugs 574036, 586386 and 587617.
|
||||
outputNode = HUD.outputNode;
|
||||
|
||||
HUD.jsterm.clearOutput();
|
||||
|
||||
let controller = top.document.commandDispatcher
|
||||
.getControllerForCommand("cmd_copy");
|
||||
is(controller.isCommandEnabled("cmd_copy"), false, "cmd_copy is disabled");
|
||||
|
||||
ContentTask.spawn(gBrowser.selectedBrowser, null,
|
||||
"() => content.console.log('Hello world! bug587617')");
|
||||
|
||||
waitForMessages({
|
||||
webconsole: HUD,
|
||||
messages: [{
|
||||
text: "bug587617",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
}).then(([result]) => {
|
||||
let msg = [...result.matched][0];
|
||||
HUD.ui.output.selectMessage(msg);
|
||||
|
||||
outputNode.focus();
|
||||
|
||||
goUpdateCommand("cmd_copy");
|
||||
controller = top.document.commandDispatcher
|
||||
.getControllerForCommand("cmd_copy");
|
||||
is(controller.isCommandEnabled("cmd_copy"), true, "cmd_copy is enabled");
|
||||
|
||||
// Remove new lines and whitespace since getSelection() includes
|
||||
// a new line between message and line number, but the clipboard doesn't
|
||||
// @see bug 1119503
|
||||
let selection = (HUD.iframeWindow.getSelection() + "")
|
||||
.replace(/\r?\n|\r| /g, "");
|
||||
isnot(selection.indexOf("bug587617"), -1,
|
||||
"selection text includes 'bug587617'");
|
||||
|
||||
waitForClipboard((str) => {
|
||||
// Strip out spaces for comparison ease
|
||||
return selection.trim() == str.trim().replace(/ /g, "");
|
||||
}, () => {
|
||||
goDoCommand("cmd_copy");
|
||||
}, deferred.resolve, deferred.resolve);
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
// Test that the context menu "Copy" (which has a different code path) works
|
||||
// properly as well.
|
||||
function testContextMenuCopy() {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let contextMenuId = HUD.ui.outputWrapper.getAttribute("context");
|
||||
let contextMenu = HUD.ui.document.getElementById(contextMenuId);
|
||||
ok(contextMenu, "the output node has a context menu");
|
||||
|
||||
let copyItem = contextMenu.querySelector("*[command='cmd_copy']");
|
||||
ok(copyItem, "the context menu on the output node has a \"Copy\" item");
|
||||
|
||||
// Remove new lines and whitespace since getSelection() includes
|
||||
// a new line between message and line number, but the clipboard doesn't
|
||||
// @see bug 1119503
|
||||
let selection = (HUD.iframeWindow.getSelection() + "")
|
||||
.replace(/\r?\n|\r| /g, "");
|
||||
|
||||
copyItem.doCommand();
|
||||
|
||||
waitForClipboard((str) => {
|
||||
// Strip out spaces for comparison ease
|
||||
return selection.trim() == str.trim().replace(/ /g, "");
|
||||
}, () => {
|
||||
goDoCommand("cmd_copy");
|
||||
}, deferred.resolve, deferred.resolve);
|
||||
HUD = outputNode = null;
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,36 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 588342";
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield checkConsoleFocus(hud);
|
||||
|
||||
let isFocused = yield ContentTask.spawn(browser, { }, function* () {
|
||||
var fm = Components.classes["@mozilla.org/focus-manager;1"].
|
||||
getService(Components.interfaces.nsIFocusManager);
|
||||
return fm.focusedWindow == content;
|
||||
});
|
||||
|
||||
ok(isFocused, "content document has focus");
|
||||
});
|
||||
|
||||
function* checkConsoleFocus(hud) {
|
||||
let fm = Cc["@mozilla.org/focus-manager;1"].getService(Ci.nsIFocusManager);
|
||||
|
||||
yield new Promise(resolve => {
|
||||
waitForFocus(resolve);
|
||||
});
|
||||
|
||||
is(hud.jsterm.inputNode.getAttribute("focused"), "true",
|
||||
"jsterm input is focused on web console open");
|
||||
is(fm.focusedWindow, hud.iframeWindow, "hud window is focused");
|
||||
yield closeConsole(null);
|
||||
}
|
||||
|
|
@ -0,0 +1,53 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that adding text to one of the output labels doesn't cause errors.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
yield testTextNodeInsertion(hud);
|
||||
});
|
||||
|
||||
// Test for bug 588730: Adding a text node to an existing label element causes
|
||||
// warnings
|
||||
function testTextNodeInsertion(hud) {
|
||||
let deferred = promise.defer();
|
||||
let outputNode = hud.outputNode;
|
||||
|
||||
let label = document.createElementNS(
|
||||
"http://www.mozilla.org/keymaster/gatekeeper/there.is.only.xul", "label");
|
||||
outputNode.appendChild(label);
|
||||
|
||||
let error = false;
|
||||
let listener = {
|
||||
observe: function (aMessage) {
|
||||
let messageText = aMessage.message;
|
||||
if (messageText.indexOf("JavaScript Warning") !== -1) {
|
||||
error = true;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
Services.console.registerListener(listener);
|
||||
|
||||
// This shouldn't fail.
|
||||
label.appendChild(document.createTextNode("foo"));
|
||||
|
||||
executeSoon(function () {
|
||||
Services.console.unregisterListener(listener);
|
||||
ok(!error, "no error when adding text nodes as children of labels");
|
||||
|
||||
return deferred.resolve();
|
||||
});
|
||||
return deferred.promise;
|
||||
}
|
||||
|
|
@ -0,0 +1,44 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
testInputExpansion(hud);
|
||||
});
|
||||
|
||||
function testInputExpansion(hud) {
|
||||
let input = hud.jsterm.inputNode;
|
||||
|
||||
input.focus();
|
||||
|
||||
is(input.getAttribute("multiline"), "true", "multiline is enabled");
|
||||
|
||||
let ordinaryHeight = input.clientHeight;
|
||||
|
||||
// Tests if the inputNode expands.
|
||||
input.value = "hello\nworld\n";
|
||||
let length = input.value.length;
|
||||
input.selectionEnd = length;
|
||||
input.selectionStart = length;
|
||||
// Performs an "d". This will trigger/test for the input event that should
|
||||
// change the height of the inputNode.
|
||||
EventUtils.synthesizeKey("d", {});
|
||||
ok(input.clientHeight > ordinaryHeight, "the input expanded");
|
||||
|
||||
// Test if the inputNode shrinks again.
|
||||
input.value = "";
|
||||
EventUtils.synthesizeKey("d", {});
|
||||
is(input.clientHeight, ordinaryHeight, "the input's height is normal again");
|
||||
|
||||
input = length = null;
|
||||
}
|
||||
|
|
@ -0,0 +1,39 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,<div style='font-size:3em;" +
|
||||
"foobarCssParser:baz'>test CSS parser filter</div>";
|
||||
|
||||
/**
|
||||
* Unit test for bug 589162:
|
||||
* CSS filtering on the console does not work
|
||||
*/
|
||||
add_task(function* () {
|
||||
let {tab} = yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole(tab);
|
||||
|
||||
// CSS warnings are disabled by default.
|
||||
hud.setFilterState("cssparser", true);
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
BrowserReload();
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "foobarCssParser",
|
||||
category: CATEGORY_CSS,
|
||||
severity: SEVERITY_WARNING,
|
||||
}],
|
||||
});
|
||||
|
||||
hud.setFilterState("cssparser", false);
|
||||
|
||||
let msg = "the unknown CSS property warning is not displayed, " +
|
||||
"after filtering";
|
||||
testLogEntry(hud.outputNode, "foobarCssParser", msg, true, true);
|
||||
});
|
||||
|
|
@ -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/ */
|
||||
|
||||
// Tests that, when the user types an extraneous closing bracket, no error
|
||||
// appears.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,test for bug 592442";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
hud.jsterm.clearOutput();
|
||||
let jsterm = hud.jsterm;
|
||||
|
||||
jsterm.setInputValue("document.getElementById)");
|
||||
|
||||
let error = false;
|
||||
try {
|
||||
jsterm.complete(jsterm.COMPLETE_HINT_ONLY);
|
||||
} catch (ex) {
|
||||
error = true;
|
||||
}
|
||||
|
||||
ok(!error, "no error was thrown when an extraneous bracket was inserted");
|
||||
});
|
||||
|
|
@ -0,0 +1,68 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-593003-iframe-wrong-hud.html";
|
||||
|
||||
const TEST_IFRAME_URI = "http://example.com/browser/devtools/client/" +
|
||||
"webconsole/test/test-bug-593003-iframe-wrong-" +
|
||||
"hud-iframe.html";
|
||||
|
||||
const TEST_DUMMY_URI = "http://example.com/browser/devtools/client/" +
|
||||
"webconsole/test/test-console.html";
|
||||
|
||||
add_task(function* () {
|
||||
|
||||
let tab1 = (yield loadTab(TEST_URI)).tab;
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
content.console.log("FOO");
|
||||
});
|
||||
yield openConsole();
|
||||
|
||||
let tab2 = (yield loadTab(TEST_DUMMY_URI)).tab;
|
||||
yield openConsole(gBrowser.selectedTab);
|
||||
|
||||
info("Reloading tab 1");
|
||||
yield reloadTab(tab1);
|
||||
|
||||
info("Checking for messages");
|
||||
yield checkMessages(tab1, tab2);
|
||||
|
||||
info("Cleaning up");
|
||||
yield closeConsole(tab1);
|
||||
yield closeConsole(tab2);
|
||||
});
|
||||
|
||||
function* reloadTab(tab) {
|
||||
let loaded = BrowserTestUtils.browserLoaded(tab.linkedBrowser);
|
||||
tab.linkedBrowser.reload();
|
||||
yield loaded;
|
||||
}
|
||||
|
||||
function* checkMessages(tab1, tab2) {
|
||||
let hud1 = yield openConsole(tab1);
|
||||
let outputNode1 = hud1.outputNode;
|
||||
|
||||
info("Waiting for messages");
|
||||
yield waitForMessages({
|
||||
webconsole: hud1,
|
||||
messages: [{
|
||||
text: TEST_IFRAME_URI,
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}]
|
||||
});
|
||||
|
||||
let hud2 = yield openConsole(tab2);
|
||||
let outputNode2 = hud2.outputNode;
|
||||
|
||||
isnot(outputNode1, outputNode2,
|
||||
"the two HUD outputNodes must be different");
|
||||
|
||||
let msg = "Didn't find the iframe network request in tab2";
|
||||
testLogEntry(outputNode2, TEST_IFRAME_URI, msg, true, true);
|
||||
}
|
||||
|
|
@ -0,0 +1,155 @@
|
|||
/* -*- 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";
|
||||
|
||||
var jsterm, inputNode, values;
|
||||
|
||||
var TEST_URI = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 594497 and bug 619598";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
setup(hud);
|
||||
performTests();
|
||||
|
||||
jsterm = inputNode = values = null;
|
||||
});
|
||||
|
||||
function setup(HUD) {
|
||||
jsterm = HUD.jsterm;
|
||||
inputNode = jsterm.inputNode;
|
||||
|
||||
jsterm.focus();
|
||||
|
||||
ok(!jsterm.getInputValue(), "jsterm.getInputValue() is empty");
|
||||
|
||||
values = ["document", "window", "document.body"];
|
||||
values.push(values.join(";\n"), "document.location");
|
||||
|
||||
// Execute each of the values;
|
||||
for (let i = 0; i < values.length; i++) {
|
||||
jsterm.setInputValue(values[i]);
|
||||
jsterm.execute();
|
||||
}
|
||||
}
|
||||
|
||||
function performTests() {
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
|
||||
is(jsterm.getInputValue(), values[4],
|
||||
"VK_UP: jsterm.getInputValue() #4 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == values[4].length &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[3],
|
||||
"VK_UP: jsterm.getInputValue() #3 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == values[3].length &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
inputNode.setSelectionRange(values[3].length - 2, values[3].length - 2);
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[3],
|
||||
"VK_UP two times: jsterm.getInputValue() #3 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == jsterm.getInputValue().indexOf("\n") &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[3],
|
||||
"VK_UP again: jsterm.getInputValue() #3 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == 0 &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[2],
|
||||
"VK_UP: jsterm.getInputValue() #2 is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[1],
|
||||
"VK_UP: jsterm.getInputValue() #1 is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_UP", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[0],
|
||||
"VK_UP: jsterm.getInputValue() #0 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == values[0].length &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[1],
|
||||
"VK_DOWN: jsterm.getInputValue() #1 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == values[1].length &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[2],
|
||||
"VK_DOWN: jsterm.getInputValue() #2 is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[3],
|
||||
"VK_DOWN: jsterm.getInputValue() #3 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == values[3].length &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
inputNode.setSelectionRange(2, 2);
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[3],
|
||||
"VK_DOWN two times: jsterm.getInputValue() #3 is correct");
|
||||
|
||||
ok(inputNode.selectionStart > jsterm.getInputValue().lastIndexOf("\n") &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[3],
|
||||
"VK_DOWN again: jsterm.getInputValue() #3 is correct");
|
||||
|
||||
ok(inputNode.selectionStart == values[3].length &&
|
||||
inputNode.selectionStart == inputNode.selectionEnd,
|
||||
"caret location is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
is(jsterm.getInputValue(), values[4],
|
||||
"VK_DOWN: jsterm.getInputValue() #4 is correct");
|
||||
|
||||
EventUtils.synthesizeKey("VK_DOWN", {});
|
||||
|
||||
ok(!jsterm.getInputValue(),
|
||||
"VK_DOWN: jsterm.getInputValue() is empty");
|
||||
}
|
||||
|
|
@ -0,0 +1,64 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
const TEST_FILE = "test-network.html";
|
||||
const TEST_URI = "data:text/html;charset=utf8,<p>test file URI";
|
||||
|
||||
var hud;
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
|
||||
let jar = getJar(getRootDirectory(gTestPath));
|
||||
let dir = jar ?
|
||||
extractJarToTmp(jar) :
|
||||
getChromeDir(getResolvedURI(gTestPath));
|
||||
|
||||
dir.append(TEST_FILE);
|
||||
let uri = Services.io.newFileURI(dir);
|
||||
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
|
||||
hud = yield openConsole();
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, uri.spec);
|
||||
yield loaded;
|
||||
|
||||
yield testMessages();
|
||||
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
hud = null;
|
||||
});
|
||||
|
||||
function testMessages() {
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "running network console logging tests",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "test-network.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "test-image.png",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "testscript.js",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,100 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the Web Console doesn't leak when multiple tabs and windows are
|
||||
// opened and then closed.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for bug 595350";
|
||||
|
||||
var win1 = window, win2;
|
||||
var openTabs = [];
|
||||
var loadedTabCount = 0;
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(3);
|
||||
|
||||
// Add two tabs in the main window.
|
||||
addTabs(win1);
|
||||
|
||||
// Open a new window.
|
||||
win2 = OpenBrowserWindow();
|
||||
win2.addEventListener("load", onWindowLoad, true);
|
||||
}
|
||||
|
||||
function onWindowLoad(aEvent) {
|
||||
win2.removeEventListener(aEvent.type, onWindowLoad, true);
|
||||
|
||||
// Add two tabs in the new window.
|
||||
addTabs(win2);
|
||||
}
|
||||
|
||||
function addTabs(aWindow) {
|
||||
for (let i = 0; i < 2; i++) {
|
||||
let tab = aWindow.gBrowser.addTab(TEST_URI);
|
||||
openTabs.push(tab);
|
||||
|
||||
tab.linkedBrowser.addEventListener("load", function onLoad(aEvent) {
|
||||
tab.linkedBrowser.removeEventListener(aEvent.type, onLoad, true);
|
||||
|
||||
loadedTabCount++;
|
||||
info("tabs loaded: " + loadedTabCount);
|
||||
if (loadedTabCount >= 4) {
|
||||
executeSoon(openConsoles);
|
||||
}
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
function openConsoles() {
|
||||
function open(i) {
|
||||
let tab = openTabs[i];
|
||||
openConsole(tab).then(function (hud) {
|
||||
ok(hud, "HUD is open for tab " + i);
|
||||
let window = hud.target.tab.linkedBrowser.contentWindow;
|
||||
window.console.log("message for tab " + i);
|
||||
|
||||
if (i >= openTabs.length - 1) {
|
||||
// Use executeSoon() to allow the promise to resolve.
|
||||
executeSoon(closeConsoles);
|
||||
}
|
||||
else {
|
||||
executeSoon(() => open(i + 1));
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// open the Web Console for each of the four tabs and log a message.
|
||||
open(0);
|
||||
}
|
||||
|
||||
function closeConsoles() {
|
||||
let consolesClosed = 0;
|
||||
|
||||
function onWebConsoleClose(aSubject, aTopic) {
|
||||
if (aTopic == "web-console-destroyed") {
|
||||
consolesClosed++;
|
||||
info("consoles destroyed: " + consolesClosed);
|
||||
if (consolesClosed == 4) {
|
||||
// Use executeSoon() to allow all the observers to execute.
|
||||
executeSoon(finishTest);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Services.obs.addObserver(onWebConsoleClose, "web-console-destroyed", false);
|
||||
|
||||
registerCleanupFunction(() => {
|
||||
Services.obs.removeObserver(onWebConsoleClose, "web-console-destroyed");
|
||||
});
|
||||
|
||||
win2.close();
|
||||
|
||||
win1.gBrowser.removeTab(openTabs[0]);
|
||||
win1.gBrowser.removeTab(openTabs[1]);
|
||||
|
||||
openTabs = win1 = win2 = null;
|
||||
}
|
||||
|
|
@ -0,0 +1,211 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 595934 - message categories coverage.";
|
||||
const TESTS_PATH = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/";
|
||||
const TESTS = [
|
||||
{
|
||||
// #0
|
||||
file: "test-bug-595934-css-loader.html",
|
||||
category: "CSS Loader",
|
||||
matchString: "text/css",
|
||||
},
|
||||
{
|
||||
// #1
|
||||
file: "test-bug-595934-imagemap.html",
|
||||
category: "Layout: ImageMap",
|
||||
matchString: "shape=\"rect\"",
|
||||
},
|
||||
{
|
||||
// #2
|
||||
file: "test-bug-595934-html.html",
|
||||
category: "HTML",
|
||||
matchString: "multipart/form-data",
|
||||
onload: function () {
|
||||
let form = content.document.querySelector("form");
|
||||
form.submit();
|
||||
},
|
||||
},
|
||||
{
|
||||
// #3
|
||||
file: "test-bug-595934-workers.html",
|
||||
category: "Web Worker",
|
||||
matchString: "fooBarWorker",
|
||||
},
|
||||
{
|
||||
// #4
|
||||
file: "test-bug-595934-malformedxml.xhtml",
|
||||
category: "malformed-xml",
|
||||
matchString: "no root element found",
|
||||
},
|
||||
{
|
||||
// #5
|
||||
file: "test-bug-595934-svg.xhtml",
|
||||
category: "SVG",
|
||||
matchString: "fooBarSVG",
|
||||
},
|
||||
{
|
||||
// #6
|
||||
file: "test-bug-595934-css-parser.html",
|
||||
category: "CSS Parser",
|
||||
matchString: "foobarCssParser",
|
||||
},
|
||||
{
|
||||
// #7
|
||||
file: "test-bug-595934-malformedxml-external.html",
|
||||
category: "malformed-xml",
|
||||
matchString: "</html>",
|
||||
},
|
||||
{
|
||||
// #8
|
||||
file: "test-bug-595934-empty-getelementbyid.html",
|
||||
category: "DOM",
|
||||
matchString: "getElementById",
|
||||
},
|
||||
{
|
||||
// #9
|
||||
file: "test-bug-595934-canvas-css.html",
|
||||
category: "CSS Parser",
|
||||
matchString: "foobarCanvasCssParser",
|
||||
},
|
||||
{
|
||||
// #10
|
||||
file: "test-bug-595934-image.html",
|
||||
category: "Image",
|
||||
matchString: "corrupt",
|
||||
},
|
||||
];
|
||||
|
||||
var pos = -1;
|
||||
|
||||
var foundCategory = false;
|
||||
var foundText = false;
|
||||
var pageLoaded = false;
|
||||
var pageError = false;
|
||||
var output = null;
|
||||
var jsterm = null;
|
||||
var hud = null;
|
||||
var testEnded = false;
|
||||
|
||||
var TestObserver = {
|
||||
QueryInterface: XPCOMUtils.generateQI([Ci.nsIObserver]),
|
||||
|
||||
observe: function testObserve(subject) {
|
||||
if (testEnded || !(subject instanceof Ci.nsIScriptError)) {
|
||||
return;
|
||||
}
|
||||
|
||||
let expectedCategory = TESTS[pos].category;
|
||||
|
||||
info("test #" + pos + " console observer got " + subject.category +
|
||||
", is expecting " + expectedCategory);
|
||||
|
||||
if (subject.category == expectedCategory) {
|
||||
foundCategory = true;
|
||||
startNextTest();
|
||||
} else {
|
||||
info("unexpected message was: " + subject.sourceName + ":" +
|
||||
subject.lineNumber + "; " + subject.errorMessage);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
function consoleOpened(hudConsole) {
|
||||
hud = hudConsole;
|
||||
output = hud.outputNode;
|
||||
jsterm = hud.jsterm;
|
||||
|
||||
Services.console.registerListener(TestObserver);
|
||||
|
||||
registerCleanupFunction(testEnd);
|
||||
|
||||
testNext();
|
||||
}
|
||||
|
||||
function testNext() {
|
||||
jsterm.clearOutput();
|
||||
foundCategory = false;
|
||||
foundText = false;
|
||||
pageLoaded = false;
|
||||
pageError = false;
|
||||
|
||||
pos++;
|
||||
info("testNext: #" + pos);
|
||||
if (pos < TESTS.length) {
|
||||
test = TESTS[pos];
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "message for test #" + pos + ": '" + test.matchString + "'",
|
||||
text: test.matchString,
|
||||
}],
|
||||
}).then(() => {
|
||||
foundText = true;
|
||||
startNextTest();
|
||||
});
|
||||
|
||||
let testLocation = TESTS_PATH + test.file;
|
||||
gBrowser.selectedBrowser.addEventListener("load", function onLoad(evt) {
|
||||
if (content.location.href != testLocation) {
|
||||
return;
|
||||
}
|
||||
gBrowser.selectedBrowser.removeEventListener(evt.type, onLoad, true);
|
||||
|
||||
pageLoaded = true;
|
||||
test.onload && test.onload(evt);
|
||||
|
||||
if (test.expectError) {
|
||||
content.addEventListener("error", function _onError() {
|
||||
content.removeEventListener("error", _onError);
|
||||
pageError = true;
|
||||
startNextTest();
|
||||
});
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
} else {
|
||||
pageError = true;
|
||||
}
|
||||
|
||||
startNextTest();
|
||||
}, true);
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, testLocation);
|
||||
} else {
|
||||
testEnded = true;
|
||||
finishTest();
|
||||
}
|
||||
}
|
||||
|
||||
function testEnd() {
|
||||
if (!testEnded) {
|
||||
info("foundCategory " + foundCategory + " foundText " + foundText +
|
||||
" pageLoaded " + pageLoaded + " pageError " + pageError);
|
||||
}
|
||||
|
||||
Services.console.unregisterListener(TestObserver);
|
||||
hud = TestObserver = output = jsterm = null;
|
||||
}
|
||||
|
||||
function startNextTest() {
|
||||
if (!testEnded && foundCategory && foundText && pageLoaded && pageError) {
|
||||
testNext();
|
||||
}
|
||||
}
|
||||
|
||||
function test() {
|
||||
requestLongerTimeout(2);
|
||||
|
||||
loadTab(TEST_URI).then(() => {
|
||||
openConsole().then(consoleOpened);
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,97 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-console.html";
|
||||
|
||||
var tab1, tab2, win1, win2;
|
||||
var noErrors = true;
|
||||
|
||||
function tab1Loaded() {
|
||||
win2 = OpenBrowserWindow();
|
||||
whenDelayedStartupFinished(win2, win2Loaded);
|
||||
}
|
||||
|
||||
function win2Loaded() {
|
||||
tab2 = win2.gBrowser.addTab(TEST_URI);
|
||||
win2.gBrowser.selectedTab = tab2;
|
||||
tab2.linkedBrowser.addEventListener("load", tab2Loaded, true);
|
||||
}
|
||||
|
||||
function tab2Loaded(aEvent) {
|
||||
tab2.linkedBrowser.removeEventListener(aEvent.type, tab2Loaded, true);
|
||||
|
||||
let consolesOpened = 0;
|
||||
function onWebConsoleOpen() {
|
||||
consolesOpened++;
|
||||
if (consolesOpened == 2) {
|
||||
executeSoon(closeConsoles);
|
||||
}
|
||||
}
|
||||
|
||||
function openConsoles() {
|
||||
try {
|
||||
let target1 = TargetFactory.forTab(tab1);
|
||||
gDevTools.showToolbox(target1, "webconsole").then(onWebConsoleOpen);
|
||||
} catch (ex) {
|
||||
ok(false, "gDevTools.showToolbox(target1) exception: " + ex);
|
||||
noErrors = false;
|
||||
}
|
||||
|
||||
try {
|
||||
let target2 = TargetFactory.forTab(tab2);
|
||||
gDevTools.showToolbox(target2, "webconsole").then(onWebConsoleOpen);
|
||||
} catch (ex) {
|
||||
ok(false, "gDevTools.showToolbox(target2) exception: " + ex);
|
||||
noErrors = false;
|
||||
}
|
||||
}
|
||||
|
||||
function closeConsoles() {
|
||||
try {
|
||||
let target1 = TargetFactory.forTab(tab1);
|
||||
gDevTools.closeToolbox(target1).then(function () {
|
||||
try {
|
||||
let target2 = TargetFactory.forTab(tab2);
|
||||
gDevTools.closeToolbox(target2).then(testEnd);
|
||||
} catch (ex) {
|
||||
ok(false, "gDevTools.closeToolbox(target2) exception: " + ex);
|
||||
noErrors = false;
|
||||
}
|
||||
});
|
||||
} catch (ex) {
|
||||
ok(false, "gDevTools.closeToolbox(target1) exception: " + ex);
|
||||
noErrors = false;
|
||||
}
|
||||
}
|
||||
|
||||
function testEnd() {
|
||||
ok(noErrors, "there were no errors");
|
||||
|
||||
win1.gBrowser.removeTab(tab1);
|
||||
|
||||
Array.forEach(win2.gBrowser.tabs, function (aTab) {
|
||||
win2.gBrowser.removeTab(aTab);
|
||||
});
|
||||
|
||||
executeSoon(function () {
|
||||
win2.close();
|
||||
tab1 = tab2 = win1 = win2 = null;
|
||||
finishTest();
|
||||
});
|
||||
}
|
||||
|
||||
openConsoles();
|
||||
}
|
||||
|
||||
function test() {
|
||||
loadTab(TEST_URI).then(() => {
|
||||
tab1 = gBrowser.selectedTab;
|
||||
win1 = window;
|
||||
tab1Loaded();
|
||||
});
|
||||
}
|
||||
|
|
@ -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/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/" +
|
||||
"webconsole/test/test-bug-597136-external-script-" +
|
||||
"errors.html";
|
||||
|
||||
function test() {
|
||||
Task.spawn(function* () {
|
||||
const {tab} = yield loadTab(TEST_URI);
|
||||
const hud = yield openConsole(tab);
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
BrowserTestUtils.synthesizeMouseAtCenter("button", {}, gBrowser.selectedBrowser);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "bogus is not defined",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
}).then(finishTest);
|
||||
}
|
||||
|
|
@ -0,0 +1,52 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that network requests from chrome don't cause the Web Console to
|
||||
// throw exceptions.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/";
|
||||
|
||||
var good = true;
|
||||
var listener = {
|
||||
QueryInterface: XPCOMUtils.generateQI([ Ci.nsIObserver ]),
|
||||
observe: function (subject) {
|
||||
if (subject instanceof Ci.nsIScriptError &&
|
||||
subject.category === "XPConnect JavaScript" &&
|
||||
subject.sourceName.includes("webconsole")) {
|
||||
good = false;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
var xhr;
|
||||
|
||||
function test() {
|
||||
Services.console.registerListener(listener);
|
||||
|
||||
// trigger a lazy-load of the HUD Service
|
||||
HUDService;
|
||||
|
||||
xhr = new XMLHttpRequest();
|
||||
xhr.addEventListener("load", xhrComplete, false);
|
||||
xhr.open("GET", TEST_URI, true);
|
||||
xhr.send(null);
|
||||
}
|
||||
|
||||
function xhrComplete() {
|
||||
xhr.removeEventListener("load", xhrComplete, false);
|
||||
window.setTimeout(checkForException, 0);
|
||||
}
|
||||
|
||||
function checkForException() {
|
||||
ok(good, "no exception was thrown when sending a network request from a " +
|
||||
"chrome window");
|
||||
|
||||
Services.console.unregisterListener(listener);
|
||||
listener = xhr = null;
|
||||
|
||||
finishTest();
|
||||
}
|
||||
|
|
@ -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/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-network.html";
|
||||
const PREF = "devtools.webconsole.persistlog";
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref(PREF, true);
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
let hud = yield openConsole();
|
||||
|
||||
let results = yield consoleOpened(hud);
|
||||
|
||||
testScroll(results, hud);
|
||||
|
||||
Services.prefs.clearUserPref(PREF);
|
||||
});
|
||||
|
||||
function consoleOpened(hud) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
for (let i = 0; i < 200; i++) {
|
||||
content.console.log("test message " + i);
|
||||
}
|
||||
|
||||
hud.setFilterState("network", false);
|
||||
hud.setFilterState("networkinfo", false);
|
||||
|
||||
hud.ui.filterBox.value = "test message";
|
||||
hud.ui.adjustVisibilityOnSearchStringChange();
|
||||
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
name: "console messages displayed",
|
||||
text: "test message 199",
|
||||
category: CATEGORY_WEBDEV,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
}).then(() => {
|
||||
waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test-network.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
}],
|
||||
}).then(deferred.resolve);
|
||||
|
||||
content.location.reload();
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function testScroll([result], hud) {
|
||||
let scrollNode = hud.ui.outputWrapper;
|
||||
let msgNode = [...result.matched][0];
|
||||
ok(msgNode.classList.contains("filtered-by-type"),
|
||||
"network message is filtered by type");
|
||||
ok(msgNode.classList.contains("filtered-by-string"),
|
||||
"network message is filtered by string");
|
||||
|
||||
ok(scrollNode.scrollTop > 0, "scroll location is not at the top");
|
||||
|
||||
// Make sure the Web Console output is scrolled as near as possible to the
|
||||
// bottom.
|
||||
let nodeHeight = msgNode.clientHeight;
|
||||
ok(scrollNode.scrollTop >= scrollNode.scrollHeight - scrollNode.clientHeight -
|
||||
nodeHeight * 2, "scroll location is correct");
|
||||
|
||||
hud.setFilterState("network", true);
|
||||
hud.setFilterState("networkinfo", true);
|
||||
}
|
||||
|
|
@ -0,0 +1,70 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-597756-reopen-closed-tab.html";
|
||||
|
||||
var HUD;
|
||||
|
||||
add_task(function* () {
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
let { browser } = yield loadTab(TEST_URI);
|
||||
HUD = yield openConsole();
|
||||
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
yield reload(browser);
|
||||
|
||||
yield testMessages();
|
||||
|
||||
yield closeConsole();
|
||||
|
||||
// Close and reopen
|
||||
gBrowser.removeCurrentTab();
|
||||
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
let tab = yield loadTab(TEST_URI);
|
||||
HUD = yield openConsole();
|
||||
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
yield reload(tab.browser);
|
||||
|
||||
yield testMessages();
|
||||
|
||||
HUD = null;
|
||||
});
|
||||
|
||||
function reload(browser) {
|
||||
let loaded = loadBrowser(browser);
|
||||
browser.reload();
|
||||
return loaded;
|
||||
}
|
||||
|
||||
function testMessages() {
|
||||
return waitForMessages({
|
||||
webconsole: HUD,
|
||||
messages: [{
|
||||
name: "error message displayed",
|
||||
text: "fooBug597756_error",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
}],
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,67 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
"use strict";
|
||||
|
||||
const INIT_URI = "data:text/plain;charset=utf8,hello world";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-599725-response-headers.sjs";
|
||||
|
||||
function performTest(request, hud) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
let headers = null;
|
||||
|
||||
function readHeader(name) {
|
||||
for (let header of headers) {
|
||||
if (header.name == name) {
|
||||
return header.value;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
hud.ui.proxy.webConsoleClient.getResponseHeaders(request.actor,
|
||||
function (response) {
|
||||
headers = response.headers;
|
||||
ok(headers, "we have the response headers for reload");
|
||||
|
||||
let contentType = readHeader("Content-Type");
|
||||
let contentLength = readHeader("Content-Length");
|
||||
|
||||
ok(!contentType, "we do not have the Content-Type header");
|
||||
isnot(contentLength, 60, "Content-Length != 60");
|
||||
|
||||
executeSoon(deferred.resolve);
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
let waitForRequest = Task.async(function*(hud) {
|
||||
let request = yield waitForFinishedRequest(req=> {
|
||||
return req.response.status === "304";
|
||||
});
|
||||
|
||||
yield performTest(request, hud);
|
||||
});
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(INIT_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
let gotLastRequest = waitForRequest(hud);
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserTestUtils.loadURI(browser, TEST_URI);
|
||||
yield loaded;
|
||||
|
||||
let reloaded = loadBrowser(browser);
|
||||
ContentTask.spawn(browser, null, "() => content.location.reload()");
|
||||
yield reloaded;
|
||||
|
||||
yield gotLastRequest;
|
||||
});
|
||||
|
|
@ -0,0 +1,59 @@
|
|||
/* -*- 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";
|
||||
|
||||
const INIT_URI = "data:text/html;charset=utf-8,Web Console - bug 600183 test";
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-600183-charset.html";
|
||||
|
||||
function performTest(lastFinishedRequest, console) {
|
||||
let deferred = promise.defer();
|
||||
|
||||
ok(lastFinishedRequest, "charset test page was loaded and logged");
|
||||
HUDService.lastFinishedRequest.callback = null;
|
||||
|
||||
executeSoon(() => {
|
||||
console.webConsoleClient.getResponseContent(lastFinishedRequest.actor,
|
||||
(response) => {
|
||||
ok(!response.contentDiscarded, "response body was not discarded");
|
||||
|
||||
let body = response.content.text;
|
||||
ok(body, "we have the response body");
|
||||
|
||||
// 的问候!
|
||||
let chars = "\u7684\u95ee\u5019!";
|
||||
isnot(body.indexOf("<p>" + chars + "</p>"), -1,
|
||||
"found the chinese simplified string");
|
||||
|
||||
HUDService.lastFinishedRequest.callback = null;
|
||||
executeSoon(deferred.resolve);
|
||||
});
|
||||
});
|
||||
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
function waitForRequest() {
|
||||
let deferred = promise.defer();
|
||||
HUDService.lastFinishedRequest.callback = (req, console) => {
|
||||
performTest(req, console).then(deferred.resolve);
|
||||
};
|
||||
return deferred.promise;
|
||||
}
|
||||
|
||||
add_task(function* () {
|
||||
let { browser } = yield loadTab(INIT_URI);
|
||||
|
||||
yield openConsole();
|
||||
|
||||
let gotLastRequest = waitForRequest();
|
||||
|
||||
let loaded = loadBrowser(browser);
|
||||
BrowserTestUtils.loadURI(browser, TEST_URI);
|
||||
yield loaded;
|
||||
|
||||
yield gotLastRequest;
|
||||
});
|
||||
|
|
@ -0,0 +1,76 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 601177: log levels";
|
||||
const TEST_URI2 = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-601177-log-levels.html";
|
||||
|
||||
add_task(function* () {
|
||||
Services.prefs.setBoolPref("javascript.options.strict", true);
|
||||
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
// On e10s, the exception is triggered in child process
|
||||
// and is ignored by test harness
|
||||
if (!Services.appinfo.browserTabsRemoteAutostart) {
|
||||
expectUncaughtException();
|
||||
}
|
||||
|
||||
yield testLogLevels(hud);
|
||||
|
||||
Services.prefs.clearUserPref("javascript.options.strict");
|
||||
});
|
||||
|
||||
function testLogLevels(hud) {
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI2);
|
||||
|
||||
info("waiting for messages");
|
||||
|
||||
return waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "test-bug-601177-log-levels.html",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "test-bug-601177-log-levels.js",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "test-image.png",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_LOG,
|
||||
},
|
||||
{
|
||||
text: "foobar-known-to-fail.png",
|
||||
category: CATEGORY_NETWORK,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "foobarBug601177exception",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "undefinedPropertyBug601177",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
{
|
||||
text: "foobarBug601177strictError",
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_WARNING,
|
||||
},
|
||||
],
|
||||
});
|
||||
}
|
||||
|
|
@ -0,0 +1,84 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Test that the console output scrolls to JS eval results when there are many
|
||||
// messages displayed. See bug 601352.
|
||||
|
||||
"use strict";
|
||||
|
||||
add_task(function* () {
|
||||
let {tab} = yield loadTab("data:text/html;charset=utf-8,Web Console test " +
|
||||
"for bug 601352");
|
||||
let hud = yield openConsole(tab);
|
||||
hud.jsterm.clearOutput();
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {}, function* () {
|
||||
let longMessage = "";
|
||||
for (let i = 0; i < 50; i++) {
|
||||
longMessage += "LongNonwrappingMessage";
|
||||
}
|
||||
|
||||
for (let i = 0; i < 50; i++) {
|
||||
content.console.log("test1 message " + i);
|
||||
}
|
||||
|
||||
content.console.log(longMessage);
|
||||
|
||||
for (let i = 0; i < 50; i++) {
|
||||
content.console.log("test2 message " + i);
|
||||
}
|
||||
});
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [{
|
||||
text: "test1 message 0",
|
||||
}, {
|
||||
text: "test1 message 49",
|
||||
}, {
|
||||
text: "LongNonwrappingMessage",
|
||||
}, {
|
||||
text: "test2 message 0",
|
||||
}, {
|
||||
text: "test2 message 49",
|
||||
}],
|
||||
});
|
||||
|
||||
let node = yield hud.jsterm.execute("1+1");
|
||||
|
||||
let scrollNode = hud.ui.outputWrapper;
|
||||
let rectNode = node.getBoundingClientRect();
|
||||
let rectOutput = scrollNode.getBoundingClientRect();
|
||||
|
||||
yield ContentTask.spawn(gBrowser.selectedBrowser, {
|
||||
rectNode,
|
||||
rectOutput,
|
||||
scrollHeight: scrollNode.scrollHeight,
|
||||
scrollTop: scrollNode.scrollTop,
|
||||
clientHeight: scrollNode.clientHeight,
|
||||
}, function* (args) {
|
||||
console.debug("rectNode", args.rectNode, "rectOutput", args.rectOutput);
|
||||
console.log("scrollNode scrollHeight", args.scrollHeight,
|
||||
"scrollTop", args.scrollTop, "clientHeight",
|
||||
args.clientHeight);
|
||||
});
|
||||
|
||||
isnot(scrollNode.scrollTop, 0, "scroll location is not at the top");
|
||||
|
||||
// The bounding client rect .top/left coordinates are relative to the
|
||||
// console iframe.
|
||||
|
||||
// Visible scroll viewport.
|
||||
let height = rectOutput.height;
|
||||
|
||||
// Top and bottom coordinates of the last message node, relative to the
|
||||
// outputNode.
|
||||
let top = rectNode.top - rectOutput.top;
|
||||
let bottom = top + rectNode.height;
|
||||
info("node top " + top + " node bottom " + bottom + " node clientHeight " +
|
||||
node.clientHeight);
|
||||
|
||||
ok(top >= 0 && bottom <= height, "last message is visible");
|
||||
});
|
||||
|
|
@ -0,0 +1,267 @@
|
|||
/* -*- indent-tabs-mode: nil; js-indent-level: 2 -*- */
|
||||
/* vim: set ft=javascript ts=2 et sw=2 tw=80: */
|
||||
/* Any copyright is dedicated to the Public Domain.
|
||||
* http://creativecommons.org/publicdomain/zero/1.0/ */
|
||||
|
||||
// Tests that the filter button UI logic works correctly.
|
||||
|
||||
"use strict";
|
||||
|
||||
const TEST_URI = "http://example.com/";
|
||||
const FILTER_PREF_DOMAIN = "devtools.webconsole.filter.";
|
||||
|
||||
var hud, hudId, hudBox;
|
||||
var prefs = {};
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI);
|
||||
|
||||
hud = yield openConsole();
|
||||
hudId = hud.hudId;
|
||||
hudBox = hud.ui.rootElement;
|
||||
|
||||
savePrefs();
|
||||
|
||||
testFilterButtons();
|
||||
|
||||
restorePrefs();
|
||||
|
||||
hud = hudId = hudBox = null;
|
||||
});
|
||||
|
||||
function savePrefs() {
|
||||
let branch = Services.prefs.getBranch(FILTER_PREF_DOMAIN);
|
||||
let children = branch.getChildList("");
|
||||
for (let child of children) {
|
||||
prefs[child] = branch.getBoolPref(child);
|
||||
}
|
||||
}
|
||||
|
||||
function restorePrefs() {
|
||||
let branch = Services.prefs.getBranch(FILTER_PREF_DOMAIN);
|
||||
for (let p in prefs) {
|
||||
branch.setBoolPref(p, prefs[p]);
|
||||
}
|
||||
}
|
||||
|
||||
function testFilterButtons() {
|
||||
testMenuFilterButton("net");
|
||||
testMenuFilterButton("css");
|
||||
testMenuFilterButton("js");
|
||||
testMenuFilterButton("logging");
|
||||
testMenuFilterButton("security");
|
||||
testMenuFilterButton("server");
|
||||
|
||||
testIsolateFilterButton("net");
|
||||
testIsolateFilterButton("css");
|
||||
testIsolateFilterButton("js");
|
||||
testIsolateFilterButton("logging");
|
||||
testIsolateFilterButton("security");
|
||||
testIsolateFilterButton("server");
|
||||
}
|
||||
|
||||
function testMenuFilterButton(category) {
|
||||
let selector = ".webconsole-filter-button[category=\"" + category + "\"]";
|
||||
let button = hudBox.querySelector(selector);
|
||||
ok(button, "we have the \"" + category + "\" button");
|
||||
|
||||
let firstMenuItem = button.querySelector("menuitem");
|
||||
ok(firstMenuItem, "we have the first menu item for the \"" + category +
|
||||
"\" button");
|
||||
|
||||
// Turn all the filters off, if they were on.
|
||||
let menuItem = firstMenuItem;
|
||||
while (menuItem != null) {
|
||||
if (menuItem.hasAttribute("prefKey") && isChecked(menuItem)) {
|
||||
chooseMenuItem(menuItem);
|
||||
}
|
||||
menuItem = menuItem.nextSibling;
|
||||
}
|
||||
|
||||
// Turn all the filters on; make sure the button gets checked.
|
||||
menuItem = firstMenuItem;
|
||||
let prefKey;
|
||||
while (menuItem) {
|
||||
if (menuItem.hasAttribute("prefKey")) {
|
||||
prefKey = menuItem.getAttribute("prefKey");
|
||||
chooseMenuItem(menuItem);
|
||||
ok(isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
category + " is checked after clicking it");
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"on after clicking the appropriate menu item");
|
||||
}
|
||||
menuItem = menuItem.nextSibling;
|
||||
}
|
||||
ok(isChecked(button), "the button for category " + category + " is " +
|
||||
"checked after turning on all its menu items");
|
||||
|
||||
// Turn one filter off; make sure the button is still checked.
|
||||
prefKey = firstMenuItem.getAttribute("prefKey");
|
||||
chooseMenuItem(firstMenuItem);
|
||||
ok(!isChecked(firstMenuItem), "the first menu item for category " +
|
||||
category + " is no longer checked after clicking it");
|
||||
ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"turned off after clicking the appropriate menu item");
|
||||
ok(isChecked(button), "the button for category " + category + " is still " +
|
||||
"checked after turning off its first menu item");
|
||||
|
||||
// Turn all the filters off by clicking the main part of the button.
|
||||
let subbutton = getMainButton(button);
|
||||
ok(subbutton, "we have the subbutton for category " + category);
|
||||
|
||||
clickButton(subbutton);
|
||||
ok(!isChecked(button), "the button for category " + category + " is " +
|
||||
"no longer checked after clicking its main part");
|
||||
|
||||
menuItem = firstMenuItem;
|
||||
while (menuItem) {
|
||||
prefKey = menuItem.getAttribute("prefKey");
|
||||
if (prefKey) {
|
||||
ok(!isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
category + " is no longer checked after clicking the button");
|
||||
ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"off after clicking the button");
|
||||
}
|
||||
menuItem = menuItem.nextSibling;
|
||||
}
|
||||
|
||||
// Turn all the filters on by clicking the main part of the button.
|
||||
clickButton(subbutton);
|
||||
|
||||
ok(isChecked(button), "the button for category " + category + " is " +
|
||||
"checked after clicking its main part");
|
||||
|
||||
menuItem = firstMenuItem;
|
||||
while (menuItem) {
|
||||
if (menuItem.hasAttribute("prefKey")) {
|
||||
prefKey = menuItem.getAttribute("prefKey");
|
||||
// The CSS/Log menu item should not be checked. See bug 971798.
|
||||
if (category == "css" && prefKey == "csslog") {
|
||||
ok(!isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
category + " should not be checked after clicking the button");
|
||||
ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"off after clicking the button");
|
||||
} else {
|
||||
ok(isChecked(menuItem), "menu item " + prefKey + " for category " +
|
||||
category + " is checked after clicking the button");
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"on after clicking the button");
|
||||
}
|
||||
}
|
||||
menuItem = menuItem.nextSibling;
|
||||
}
|
||||
|
||||
// Uncheck the main button by unchecking all the filters
|
||||
menuItem = firstMenuItem;
|
||||
while (menuItem) {
|
||||
// The csslog menu item is already unchecked at this point.
|
||||
// Make sure it is not selected. See bug 971798.
|
||||
prefKey = menuItem.getAttribute("prefKey");
|
||||
if (prefKey && prefKey != "csslog") {
|
||||
chooseMenuItem(menuItem);
|
||||
}
|
||||
menuItem = menuItem.nextSibling;
|
||||
}
|
||||
|
||||
ok(!isChecked(button), "the button for category " + category + " is " +
|
||||
"unchecked after unchecking all its filters");
|
||||
|
||||
// Turn all the filters on again by clicking the button.
|
||||
clickButton(subbutton);
|
||||
}
|
||||
|
||||
function testIsolateFilterButton(category) {
|
||||
let selector = ".webconsole-filter-button[category=\"" + category + "\"]";
|
||||
let targetButton = hudBox.querySelector(selector);
|
||||
ok(targetButton, "we have the \"" + category + "\" button");
|
||||
|
||||
// Get the main part of the filter button.
|
||||
let subbutton = getMainButton(targetButton);
|
||||
ok(subbutton, "we have the subbutton for category " + category);
|
||||
|
||||
// Turn on all the filters by alt clicking the main part of the button.
|
||||
altClickButton(subbutton);
|
||||
ok(isChecked(targetButton), "the button for category " + category +
|
||||
" is checked after isolating for filter");
|
||||
|
||||
// Check if all the filters for the target button are on.
|
||||
let menuItems = targetButton.querySelectorAll("menuitem");
|
||||
Array.forEach(menuItems, (item) => {
|
||||
let prefKey = item.getAttribute("prefKey");
|
||||
// The CSS/Log filter should not be checked. See bug 971798.
|
||||
if (category == "css" && prefKey == "csslog") {
|
||||
ok(!isChecked(item), "menu item " + prefKey + " for category " +
|
||||
category + " should not be checked after isolating for " + category);
|
||||
ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages should be " +
|
||||
"turned off after isolating for " + category);
|
||||
} else if (prefKey) {
|
||||
ok(isChecked(item), "menu item " + prefKey + " for category " +
|
||||
category + " is checked after isolating for " + category);
|
||||
ok(hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"turned on after isolating for " + category);
|
||||
}
|
||||
});
|
||||
|
||||
// Ensure all other filter buttons are toggled off and their
|
||||
// associated filters are turned off
|
||||
let buttons = hudBox.querySelectorAll(".webconsole-filter-button[category]");
|
||||
Array.forEach(buttons, (filterButton) => {
|
||||
if (filterButton !== targetButton) {
|
||||
let categoryBtn = filterButton.getAttribute("category");
|
||||
ok(!isChecked(filterButton), "the button for category " +
|
||||
categoryBtn + " is unchecked after isolating for " + category);
|
||||
|
||||
menuItems = filterButton.querySelectorAll("menuitem");
|
||||
Array.forEach(menuItems, (item) => {
|
||||
let prefKey = item.getAttribute("prefKey");
|
||||
if (prefKey) {
|
||||
ok(!isChecked(item), "menu item " + prefKey + " for category " +
|
||||
category + " is unchecked after isolating for " + category);
|
||||
ok(!hud.ui.filterPrefs[prefKey], prefKey + " messages are " +
|
||||
"turned off after isolating for " + category);
|
||||
}
|
||||
});
|
||||
|
||||
// Turn all the filters on again by clicking the button.
|
||||
let mainButton = getMainButton(filterButton);
|
||||
clickButton(mainButton);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the main part of the target filter button.
|
||||
*/
|
||||
function getMainButton(targetButton) {
|
||||
let anonymousNodes = hud.ui.document.getAnonymousNodes(targetButton);
|
||||
let subbutton;
|
||||
|
||||
for (let i = 0; i < anonymousNodes.length; i++) {
|
||||
let node = anonymousNodes[i];
|
||||
if (node.classList.contains("toolbarbutton-menubutton-button")) {
|
||||
subbutton = node;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return subbutton;
|
||||
}
|
||||
|
||||
function clickButton(node) {
|
||||
EventUtils.sendMouseEvent({ type: "click" }, node);
|
||||
}
|
||||
|
||||
function altClickButton(node) {
|
||||
EventUtils.sendMouseEvent({ type: "click", altKey: true }, node);
|
||||
}
|
||||
|
||||
function chooseMenuItem(node) {
|
||||
let event = document.createEvent("XULCommandEvent");
|
||||
event.initCommandEvent("command", true, true, window, 0, false, false, false,
|
||||
false, null);
|
||||
node.dispatchEvent(event);
|
||||
}
|
||||
|
||||
function isChecked(node) {
|
||||
return node.getAttribute("checked") === "true";
|
||||
}
|
||||
|
|
@ -0,0 +1,37 @@
|
|||
/* -*- 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";
|
||||
|
||||
const TEST_URI = "http://example.com/browser/devtools/client/webconsole/" +
|
||||
"test/test-bug-603750-websocket.html";
|
||||
const TEST_URI2 = "data:text/html;charset=utf-8,Web Console test for " +
|
||||
"bug 603750: Web Socket errors";
|
||||
|
||||
add_task(function* () {
|
||||
yield loadTab(TEST_URI2);
|
||||
|
||||
let hud = yield openConsole();
|
||||
|
||||
BrowserTestUtils.loadURI(gBrowser.selectedBrowser, TEST_URI);
|
||||
|
||||
yield waitForMessages({
|
||||
webconsole: hud,
|
||||
messages: [
|
||||
{
|
||||
text: "ws://0.0.0.0:81",
|
||||
source: { url: "test-bug-603750-websocket.js" },
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
{
|
||||
text: "ws://0.0.0.0:82",
|
||||
source: { url: "test-bug-603750-websocket.js" },
|
||||
category: CATEGORY_JS,
|
||||
severity: SEVERITY_ERROR,
|
||||
},
|
||||
]
|
||||
});
|
||||
});
|
||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Add a link
Reference in a new issue