Web Inspector: Enable WebKit logging configuration and display
authoreric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Oct 2017 22:00:53 +0000 (22:00 +0000)
committereric.carlson@apple.com <eric.carlson@apple.com@268f45cc-cd09-0410-ab3c-d52691b4dbfc>
Tue, 24 Oct 2017 22:00:53 +0000 (22:00 +0000)
https://bugs.webkit.org/show_bug.cgi?id=177027
<rdar://problem/33964767>

Reviewed by Joseph Pecoraro.

Source/JavaScriptCore:

* inspector/ConsoleMessage.cpp:
(Inspector::messageSourceValue): Inspector::Protocol::Console::ConsoleMessage ->
    Inspector::Protocol::Console::ChannelSource.
* inspector/agents/JSGlobalObjectConsoleAgent.cpp:
(Inspector::JSGlobalObjectConsoleAgent::getLoggingChannels): There are no logging channels
    specific to a JSContext yet, so return an empty channel array.
(Inspector::JSGlobalObjectConsoleAgent::setLoggingChannelLevel): No channels, return an error.
* inspector/agents/JSGlobalObjectConsoleAgent.h:

* inspector/protocol/Console.json: Add ChannelSource, ChannelLevel, and Channel. Add getLoggingChannels
    and setLoggingChannelLevel.

* inspector/scripts/codegen/generator.py: Special case "webrtc"-> "WebRTC".
* inspector/scripts/tests/generic/expected/enum-values.json-result:
* inspector/scripts/tests/generic/expected/type-declaration-array-type.json-result:
* inspector/scripts/tests/generic/expected/type-declaration-enum-type.json-result:
* inspector/scripts/tests/generic/expected/type-declaration-object-type.json-result:
* inspector/scripts/tests/generic/expected/type-requiring-runtime-casts.json-result:

* runtime/ConsoleTypes.h: Add Media and WebRTC.

Source/WebCore:

Test: inspector/console/webcore-logging.html

* dom/Document.cpp:
(WebCore::Document::~Document): Stop observing the logger.
(WebCore::Document::logger): Observe the logger.
(WebCore::Document::didLogMessage): Forward logging messages to the inspector.
* dom/Document.h:

* inspector/WebConsoleAgent.cpp:
(WebCore::WebConsoleAgent::getLoggingChannels): New, return the state of log runtime channels.
(WebCore::WebConsoleAgent::setLoggingChannelLevel): New, set the state of a channel.
* inspector/WebConsoleAgent.h:

* platform/Logging.cpp:
(WebCore::getLogChannel): New, get a log channel by name.
* platform/Logging.h:

Source/WebCore/PAL:

* pal/Logger.h:
(PAL::Logger::willLog const): Always return true for Always and Error so those messages are
    always logged to the system.
(PAL::Logger::log): Always log Always and Error to the system, but pay strict attention to level
    and channel state for logging to observers so logging only shows up in the inspector when
    explicitly enabled by the user.

Source/WebInspectorUI:

* Localizations/en.lproj/localizedStrings.js: Add new localized strings.

* UserInterface/Controllers/LogManager.js:
(WI.LogManager): Initialize _loggingChannelSources, fetch _customLoggingChannels.
(WI.LogManager.supportsLogChannels): New.
(WI.LogManager.prototype.get customLoggingChannels): New.
(WI.LogManager.prototype.get logChannelSources): New.

* UserInterface/Main.html:
* UserInterface/Models/ConsoleMessage.js: Add Media and WebRTC.

* UserInterface/Models/IssueMessage.js:
(WI.IssueMessage): Add media and webrtc.

* UserInterface/Models/LoggingChannel.js: Added.
(WI.LoggingChannel):
(WI.LoggingChannel.fromPayload):
(WI.LoggingChannel.prototype.get source):
(WI.LoggingChannel.prototype.get level):

* UserInterface/Views/LogContentView.js:
(WI.LogContentView): Add new scope buttons for "Log", "Info", and "Debug". Create log channel
    scope buttons once logging has started.
(WI.LogContentView.prototype.get navigationItems): Add the log message scope bar when necessary.
(WI.LogContentView.prototype._scopeFromMessageSource): New.
(WI.LogContentView.prototype._scopeFromMessageLevel): Don't group Info, Log, and Debug.
(WI.LogContentView.prototype._messageAdded): Force a UI update the first time a WebKit log
    message is added.

(WI.LogContentView.prototype._messageShouldBeVisible): New, deal with message source bar buttons.
(WI.LogContentView.prototype._messageSourceBarSelectionDidChange): New.
(WI.LogContentView.prototype._filterMessageElements): Deal with message source bar buttons.

* UserInterface/Views/SettingsTabContentView.js:
(WI.SettingsTabContentView.prototype._createGeneralSettingsView): Create and initialize menus
    for each log channel.

Source/WebKitLegacy/mac:

* WebCoreSupport/WebChromeClient.mm:
(stringForMessageSource): Deal with Media and WebRTC message sources.

Tools:

Allow new 'dumpJSConsoleLogInStdErr' test header to redirect log console output to stderr.

* DumpRenderTree/TestOptions.h:
* DumpRenderTree/TestOptions.mm:
(TestOptions::TestOptions):
* DumpRenderTree/mac/DumpRenderTree.mm:
(runTest):
* WebKitTestRunner/TestController.cpp:
(WTR::updateTestOptionsFromTestHeader):
(WTR::TestController::runTest):
* WebKitTestRunner/TestOptions.h:
(WTR::TestOptions::hasSameInitializationOptions const):

LayoutTests:

* inspector/console/webcore-logging-expected.txt: Added.
* inspector/console/webcore-logging.html: Added.
* platform/mac/TestExpectations: Skip new test on Yosemite and ElCapitan.
* platform/win/TestExpectations: Skip new test.

git-svn-id: https://svn.webkit.org/repository/webkit/trunk@223929 268f45cc-cd09-0410-ab3c-d52691b4dbfc

46 files changed:
LayoutTests/ChangeLog
LayoutTests/inspector/console/webcore-logging-expected.txt [new file with mode: 0644]
LayoutTests/inspector/console/webcore-logging.html [new file with mode: 0644]
LayoutTests/platform/mac/TestExpectations
LayoutTests/platform/win/TestExpectations
Source/JavaScriptCore/ChangeLog
Source/JavaScriptCore/inspector/ConsoleMessage.cpp
Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.cpp
Source/JavaScriptCore/inspector/agents/InspectorConsoleAgent.h
Source/JavaScriptCore/inspector/protocol/Console.json
Source/JavaScriptCore/inspector/scripts/codegen/generator.py
Source/JavaScriptCore/inspector/scripts/tests/generic/expected/enum-values.json-result
Source/JavaScriptCore/inspector/scripts/tests/generic/expected/type-declaration-array-type.json-result
Source/JavaScriptCore/inspector/scripts/tests/generic/expected/type-declaration-enum-type.json-result
Source/JavaScriptCore/inspector/scripts/tests/generic/expected/type-declaration-object-type.json-result
Source/JavaScriptCore/inspector/scripts/tests/generic/expected/type-requiring-runtime-casts.json-result
Source/JavaScriptCore/runtime/ConsoleTypes.h
Source/WebCore/ChangeLog
Source/WebCore/PAL/ChangeLog
Source/WebCore/PAL/pal/Logger.h
Source/WebCore/dom/Document.cpp
Source/WebCore/dom/Document.h
Source/WebCore/inspector/WebConsoleAgent.cpp
Source/WebCore/inspector/WebConsoleAgent.h
Source/WebCore/platform/Logging.cpp
Source/WebCore/platform/Logging.h
Source/WebInspectorUI/ChangeLog
Source/WebInspectorUI/Localizations/en.lproj/localizedStrings.js
Source/WebInspectorUI/UserInterface/Controllers/LogManager.js
Source/WebInspectorUI/UserInterface/Main.html
Source/WebInspectorUI/UserInterface/Models/ConsoleMessage.js
Source/WebInspectorUI/UserInterface/Models/IssueMessage.js
Source/WebInspectorUI/UserInterface/Models/LoggingChannel.js [new file with mode: 0644]
Source/WebInspectorUI/UserInterface/Test.html
Source/WebInspectorUI/UserInterface/Views/ConsoleMessageView.css
Source/WebInspectorUI/UserInterface/Views/LogContentView.js
Source/WebInspectorUI/UserInterface/Views/ScopeBarItem.js
Source/WebInspectorUI/UserInterface/Views/SettingsTabContentView.js
Source/WebKitLegacy/mac/ChangeLog
Source/WebKitLegacy/mac/WebCoreSupport/WebChromeClient.mm
Tools/ChangeLog
Tools/DumpRenderTree/TestOptions.h
Tools/DumpRenderTree/TestOptions.mm
Tools/DumpRenderTree/mac/DumpRenderTree.mm
Tools/WebKitTestRunner/TestController.cpp
Tools/WebKitTestRunner/TestOptions.h

index b1a5ece..4b0a29d 100644 (file)
@@ -1,3 +1,16 @@
+2017-10-24  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Enable WebKit logging configuration and display
+        https://bugs.webkit.org/show_bug.cgi?id=177027
+        <rdar://problem/33964767>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/console/webcore-logging-expected.txt: Added.
+        * inspector/console/webcore-logging.html: Added.
+        * platform/mac/TestExpectations: Skip new test on Yosemite and ElCapitan.
+        * platform/win/TestExpectations: Skip new test.
+
 2017-10-24  Dean Jackson  <dino@apple.com>
 
         Implement resizing options for ImageBitmap rendering
diff --git a/LayoutTests/inspector/console/webcore-logging-expected.txt b/LayoutTests/inspector/console/webcore-logging-expected.txt
new file mode 100644 (file)
index 0000000..2db4a92
--- /dev/null
@@ -0,0 +1,34 @@
+Test WebKit logging configuration and console display.
+
+
+
+== Running test suite: Console.Logging
+-- Running test case: Console.Logging.BasicProperties
+PASS: Log channels should be supported.
+PASS: Has WI.logManager.customLoggingChannels.
+PASS: WI.logManager.customLoggingChannels is not empty.
+PASS: Has WI.logManager.logChannelSources.
+PASS: WI.logManager.logChannelSources is not empty.
+PASS: Log channel has known source.
+PASS: Log channel disabled by default.
+PASS: Log channel has known source.
+PASS: Log channel disabled by default.
+
+-- Running test case: Console.Logging.InvalidChannel
+PASS: Logging channel not found
+
+-- Running test case: Console.Logging.InvalidLevel
+PASS: Invalid logging level
+
+-- Running test case: Console.Logging.NoLogging
+PASS: Media logging disabled.
+Started Playing
+Stopped Playing
+
+-- Running test case: Console.Logging.MediaLogging
+PASS: Media logging disabled.
+PASS: Media logging has been enabled.
+PASS: Media log message should have source 'media'.
+Started Playing
+Stopped Playing
+
diff --git a/LayoutTests/inspector/console/webcore-logging.html b/LayoutTests/inspector/console/webcore-logging.html
new file mode 100644 (file)
index 0000000..8c4ef6e
--- /dev/null
@@ -0,0 +1,171 @@
+<!doctype html><!-- webkit-test-runner [ dumpJSConsoleLogInStdErr=true ] -->
+<html>
+<head>
+<script src="../../http/tests/inspector/resources/inspector-test.js"></script>
+<script>
+
+let video;
+function setup() 
+{
+    // 250ms of silence in 16-bit signed little endian WAV format.
+    let data = "UklGRmQfAABXQVZFZm10IBAAAAABAAEAgD4AAAB9AAACABAAZGF0YUAfAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAP//AAAAAAAAAAAAAAAAAQAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAAABAP//AAAAAAAA/////wAAAQAAAAAAAAAAAAAAAQD//wAAAAD//wAAAQD/////AAAAAAEA/////wAAAAAAAP//AAD//wAAAQAAAP//AAD//wAAAAABAAEAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAP//AAAAAP//AAD//wAAAAAAAAAAAAAAAP//AAABAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAD//wAA//8AAAAAAAAAAAAAAAAAAAEA//8AAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA/////wAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAABAAEAAAAAAP//AQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAABAAAA//8AAAAAAAAAAAAAAAD//wAAAQAAAAAA//8AAAAAAAAAAAAAAQAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAQAAAAEAAAABAAEAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAD//wAAAAAAAP//AAAAAAAA//8AAAAAAQAAAP//AAABAAAAAAABAAAAAAAAAAAAAQAAAP//AAAAAAAAAAAAAAAA//8AAAAAAAAAAP//AAAAAAAAAAD//wAAAAABAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAP//AQAAAAAAAAAAAAEAAQAAAAAAAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAQAAAAAAAQD//wAAAAD//wAAAQAAAAAAAAAAAAAAAAD//wEAAQAAAAAAAAD//wAAAAAAAAEAAAAAAAAA//8AAAAA//8AAAAAAAD/////AAAAAAEAAAAAAAAAAAAAAAAAAAD//wAAAAD//wAAAAAAAP//AAAAAAAAAAABAP//AAAAAP//AAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8BAAAAAAAAAP//AAAAAAAAAAABAAAAAAABAAAA//8AAAAAAAAAAAAAAQAAAAAAAQABAAEAAAAAAAAAAQAAAAAAAAABAP////8AAAEAAAAAAAAAAAD//wAAAAD//wAAAAD/////AAABAAAAAQAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAA//8AAAAAAQAAAAEAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAAAAAAAAAAABAAAA//8BAAAA//8AAP//AAAAAAAAAAABAAEAAAAAAAAAAAABAAAAAAAAAAAA//8AAAAAAAABAAAAAAAAAAAAAAAAAAAAAAABAAAA//8AAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQABAAAA//8AAAAAAAAAAAAAAAAAAAAAAAD//wAAAAABAAEA//8AAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAA/////wAAAAAAAAAAAQD//wAAAAAAAP//AAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAA//8AAAAAAAAAAAAAAAABAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAQD//wAAAAD//wAAAAABAP//AAAAAAAA//8BAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQAAAAAA//8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8AAAAA//8AAAAAAAAAAP//AAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAP//AAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAQAAAAAA//8AAAAAAAAAAAAAAAABAAAA//8BAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAD//wAAAAAAAAEAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAD//wAAAQAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAQD//wAAAAAAAAEAAQAAAAAA//8AAAAAAQD//wAAAAD//wAA//8AAP///////wAAAAD//////////wAAAAAAAAAAAAAAAP//AQABAAAAAAAAAAAAAAABAAAAAQD//wAA/////wEAAQAAAAAAAQABAAEA//8AAAAA//8BAAAAAAAAAAEAAAAAAAAAAAD//wAAAAAAAAAAAAD//wAAAAAAAP//AAAAAAAA//8BAAAAAAAAAP//AAAAAAAAAAD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAA//8AAAAAAAABAAAAAAD//wAAAAAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAQAAAAAAAAD//wAAAAAAAAAAAQAAAP//AAD//wAAAQAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wEAAQD//wAAAAD//wEAAQAAAAEAAAABAAAAAAABAAAAAQAAAAEAAAAAAP//AAAAAAAAAAAAAAAAAAD//wAAAAD//wAA//8AAP//AAAAAP//AQAAAAEAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAD//wAAAAABAAAAAAAAAAAAAQAAAAEAAAD//wAA//8AAAAAAAABAAAAAAAAAAAAAAAAAAEAAAAAAAAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAP//AAABAAAAAAD//wAAAAAAAAEAAAD//wAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAA//8AAAAAAQAAAAAAAQABAP//AAAAAAAAAQABAAEAAAAAAAAAAQABAP//AAAAAAAAAAABAP//AQD/////AAAAAAAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAP//AQAAAAEA//8BAAAA//8BAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAA//8AAAAAAAAAAAAAAAABAAAAAQAAAAEAAAAAAAAAAQAAAP//AAAAAAAA//8BAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAAAA//8BAAAAAQAAAAAAAAD//wAAAAAAAAAAAAABAAEAAAAAAAAAAAABAAAAAQABAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAQABAAAAAAAAAP//AQAAAP//AAAAAAEAAAAAAAAAAAAAAAAAAAABAP//AAD//wAAAAAAAAEAAAAAAAAAAAABAP////8BAAAAAQD//wEAAAAAAAEAAAAAAAAA//8AAAEAAAABAAAAAAAAAAEAAAAAAAAA//8AAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAABAAAAAAAAAAAAAQAAAP//AAAAAAAAAQABAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABAAAA//8AAP//AAAAAAAAAAD/////AAAAAP//AAAAAAAAAAAAAAAAAAAAAAEAAAABAP//AAD//wAAAAAAAP//AAAAAAAAAAAAAAAAAQAAAAAAAAABAAAA//8AAAAAAAAAAAAAAAAAAP//AQAAAAAAAAAAAP//AAABAAEAAAAAAAEAAQABAAAA//8AAAAAAAAAAAAAAQAAAAAAAQAAAAAAAQD/////AAAAAAAAAAD//wAA//8AAP//AAAAAAAAAAABAAAAAAABAAAAAAAAAAEAAAAAAP//AAAAAAAAAAAAAAAAAQD//wAAAAAAAAAAAAAAAP//AAABAAEAAAAAAAAAAAD//wAAAAAAAAEAAAAAAAAAAAAAAP//AAD/////AAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQD/////AAAAAAAAAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAP////8AAAAAAAAAAAAAAAAAAAAAAAAAAP////8AAAAAAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAABAP//AAD/////AAAAAAAA//8AAAAAAAABAP//AAAAAP//AQAAAAAAAAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAAAAAAAA//8AAAAA//////////8AAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAQABAAAAAAAAAAAAAAD//wAAAAAAAP//AAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAABAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAD//wAAAAABAAAAAAD//wAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAAAAAAAAAABAAAAAAABAAAA/////wAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAEAAQABAAAA/////wAAAAAAAAAAAAAAAAAAAAD//wAA//8AAP//AAAAAAAAAAAAAAAAAAABAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAEAAAAAAAAAAAD//wAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAD/////AAAAAAAAAQAAAAAAAAD//wAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAA//8BAAEAAAAAAAAA/////wAAAAAAAAAA//8AAAAAAAD//wAAAQAAAAAAAAAAAAEAAAAAAAEAAAAAAP//AAAAAAAA//8AAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAEA//8AAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAP//AAAAAAAAAQAAAAAAAAAAAAAAAQAAAAAAAAD/////AAABAAAAAAAAAAAAAAABAAAAAAD//wAAAQAAAAAAAAABAAAAAAD//wEAAAABAAAAAAABAAEAAAD//wAAAAABAAAA//8AAAAAAAD//wAAAAAAAAAAAAD//wAAAAD//wEAAAAAAAAAAAAAAAAAAQAAAAAAAAD//wAAAAAAAAAA//8AAAAAAAAAAP//AQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAP//AQD/////AQAAAAAAAAABAAAAAAAAAAAAAAD//wAAAAABAP////8AAAEAAAAAAP//AAAAAAAAAAD//wEA//8AAAAAAQAAAAAAAQAAAAAA//8AAAAAAQAAAAAAAQAAAAEAAAAAAAEAAAD//wAA//8AAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAEA//8BAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAD/////AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//wEAAAD/////AAAAAAAAAAAAAAAAAAABAAEA//8BAAAAAAD//wAAAAAAAAAAAAD//wEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAAAAP//AAAAAAAAAAD//wAAAAAAAAAAAAD//wAAAAD//wEAAAAAAAAA//8AAAAAAAAAAAEAAAD//wAAAAD//wEA//8AAAAAAQAAAAAAAQAAAAAA//8BAAAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAEA//8AAAAAAAD//wAAAAD//wAAAAABAP//AQAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAA//8BAP//AAAAAAAAAAD//wEAAAABAAAAAAAAAAEAAQABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAAAAAP//AAABAAAAAAAAAP//AAAAAAAA//8AAAAAAQAAAAAAAAAAAAAAAAAAAAEAAQAAAAAAAAABAAAAAAD//wAAAQAAAAAAAAAAAAAA/////wAAAAAAAAAAAAAAAP//AQAAAAEAAAAAAAAAAAAAAAEAAAAAAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAD//wAAAAABAAAAAQAAAP//AAABAAAA//8AAAAAAAD//wAAAQAAAAAAAQAAAAAAAAAAAAAAAAABAAEAAAD//wEAAQAAAAAAAAAAAAAAAAAAAP//AAD//wAAAAD//wEAAAAAAAAAAQAAAAAAAAAAAAEA/////wAAAAAAAAAAAAD//wAAAAABAAAAAAABAAAAAAABAAAAAAAAAAAAAAAAAAAAAAABAAEAAAAAAAAAAAAAAAEAAAD//wAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAQD//wAAAAAAAAAAAAD//wAAAAAAAAAAAAABAAAA//8AAAEAAAAAAP//AAAAAAEAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAEAAAD/////AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAD//////////wAAAAD//wAA//8AAAAAAAAAAAAAAAAAAAEAAAAAAAAAAAD//wAAAQAAAAAAAAABAAAAAAD//wAAAAAAAAAAAAABAP//AAAAAAAAAAABAAAAAQAAAAAAAAAAAAAAAAAAAP//AAAAAAEAAAABAAAAAAD//wAAAAAAAAAA//8AAAAA////////AAD//wAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAAAAP//AAAAAAAAAAABAAAAAAD//wEAAAABAAAAAAAAAAEAAAAAAAAAAQD//wAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAP//AAABAAAAAQAAAAAAAAAAAAAAAQAAAAAAAQAAAP//AQABAAAAAAAAAAAAAAABAAAAAAAAAAAAAAABAAEAAQAAAAAAAQAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAA//8AAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAD//wEAAAAAAAAAAAAAAAAAAAD//wEAAAAAAP//AAAAAP//AQAAAAAAAAABAP//AAAAAAAAAAAAAAAAAAAAAAEA//8AAAAAAAAAAAAAAAD//wAAAAABAAAAAAAAAAAAAAAAAAAAAQD//wAAAQAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAD//wAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAAAAAAAAAAD/////AAAAAAAAAAAAAAAAAAABAAAAAAAAAAEAAAABAAEAAAAAAAAAAAD//wAAAAD/////AAAAAP//AAD/////AAD//wEAAAABAAAA//8AAAAAAAAAAAAA//8AAAAA//8AAAAAAQAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAEAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAD//wAA/////wAAAAD//wAAAAABAAAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAEAAAAAAAAAAAD//wAA//8AAAAAAAAAAP//AAABAAAAAAAAAP////8AAAAAAAD//wAAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAQABAAAA//8AAAAA//8AAAAAAAAAAAAAAAAAAAAA//8AAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAQAAAAAAAAAAAP//AQAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAD//wAAAAD/////AAAAAAAA//8AAAAAAQAAAAAAAAAAAP////8AAAAAAAAAAAAAAAAAAAEA/////wAAAAABAAAAAQD//wAA/////wEAAAAAAAEAAAAAAAAAAAABAAAAAAAAAP//AAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABAAAAAQAAAP//AAAAAAAAAAD/////AAABAAAAAAAAAAAAAAAAAP//AAAAAAAAAQAAAAAAAAAAAP//AAAAAAAAAAAAAAAA//8AAAAAAQD//wAAAAAAAP//AAAAAAEAAAAAAAAAAAAAAP//AAABAAAAAAABAP//AAAAAAAAAAD//wAAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAABAAAAAAD//wAAAAABAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA/////wAAAAD//wAAAAABAAAAAAAAAAAAAAAAAAEAAAAAAP//AAAAAAAAAAAAAAEAAQAAAAEAAAAAAAAAAAAAAAAAAAAAAP////8AAAAAAAABAAAAAAAAAAEAAAABAAAAAAAAAAEAAAD/////AAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAQABAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAEA//8AAAAAAAAAAAEAAAAAAAAAAQAAAAAAAAAAAP//AAD//wAAAAD//wAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAABAAAAAQAAAAAAAAAAAAEA//8AAAAAAAABAAAA//8BAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAAABAAAAAAD//wAAAAAAAAAAAAAAAAAA//8AAAAAAQAAAAAAAQAAAAEAAAAAAAAAAAAAAAAAAAD//wAAAAD//wAAAAABAAAAAAAAAAAAAAAAAAAAAAABAAAAAAABAAAAAAABAAAAAAAAAAEAAAD//wAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA//8AAAAAAAD//wAAAAAAAP//AQAAAAAA/////wAAAAAAAAAA//8AAAAAAAAAAAAAAAAAAAEAAAAAAP//AQABAAAAAQABAAAA//8AAAAAAAAAAAEAAQAAAAEAAAAAAAAA//8AAAAAAAAAAAAAAAD//wAAAAAAAAAAAQAAAAAAAAAAAAAAAAAAAAAAAAAAAP//AAAAAAAA//8AAAAAAAD//wEAAAAAAAAAAAAAAP////8AAAAAAAABAAAAAAAAAAAAAAAAAAAAAAABAP//AAAAAAAAAQAAAP////8AAAEAAAAAAAAAAAABAAAAAAABAAAAAAAAAAEAAQD//wEAAQAAAAAAAAAAAAEAAAAAAAAAAAAAAAAAAAD//wAAAAAAAAAAAAD//wAAAAAAAAAAAAAAAAAA//8AAAAAAAAAAAEAAAAAAAEAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAQAAAAAAAQAAAAAA//8BAAAAAAAAAAAAAAAAAA==";
+    video = document.getElementsByTagName('video')[0];
+    video.src = "data:audio/wav;base64," + data;
+    runTest();
+}
+
+function play()
+{
+    video.currentTime = 0;
+    video.play();
+    TestPage.dispatchEventToFrontend('PlayEvent', {count: 1});
+}
+
+function pause()
+{
+    video.pause();
+    TestPage.dispatchEventToFrontend('PauseEvent', {count: 1});
+}
+
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite("Console.Logging");
+
+    suite.addTestCase({
+        name: "Console.Logging.BasicProperties",
+        description: "Check initial properties.",
+        test(resolve, reject) {
+            ConsoleAgent.getLoggingChannels((error, channels) => {
+                if (error) {
+                    InspectorTest.fail(`ConsoleAgent.getLoggingChannels() failed with error ${error}`);
+                    reject();
+                }
+
+                InspectorTest.expectThat(WI.LogManager.supportsLogChannels(), "Log channels should be supported.");
+                InspectorTest.expectThat(WI.logManager.customLoggingChannels, "Has WI.logManager.customLoggingChannels.");
+                InspectorTest.expectThat(WI.logManager.customLoggingChannels.length, "WI.logManager.customLoggingChannels is not empty.");
+                InspectorTest.expectThat(WI.logManager.logChannelSources, "Has WI.logManager.logChannelSources.");
+                InspectorTest.expectThat(WI.logManager.logChannelSources.length, "WI.logManager.logChannelSources is not empty.");
+
+                let sources = Object.values(WI.ConsoleMessage.MessageSource);
+                WI.logManager.customLoggingChannels.forEach((channel) => {
+                    InspectorTest.expectThat(sources.includes(channel.source), "Log channel has known source.");
+                    InspectorTest.expectEqual(channel.level, WI.LoggingChannel.Level.Off, "Log channel disabled by default.");
+                });
+
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "Console.Logging.InvalidChannel",
+        description: "setLoggingChannelLevel should reject invalid log channel name.",
+        test(resolve, reject) {
+            ConsoleAgent.setLoggingChannelLevel("DOES_NOT_EXIST", WI.LoggingChannel.Level.Off, (error) => {
+                if (!error) {
+                    InspectorTest.fail("Should have an error with invalid channel.");
+                    reject();
+                    return;
+                }
+                InspectorTest.pass(error);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "Console.Logging.InvalidLevel",
+        description: "setLoggingChannelLevel should reject invalid log channel level.",
+        test(resolve, reject) {
+            ConsoleAgent.setLoggingChannelLevel(WI.ConsoleMessage.MessageSource.Media, "DOES_NOT_EXIST", (error) => {
+                if (!error) {
+                    InspectorTest.fail("Should have an error with invalid level.");
+                    reject();
+                    return;
+                }
+                InspectorTest.pass(error);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: "Console.Logging.NoLogging",
+        description: "No <video> logging when disabled.",
+        test(resolve, reject) {
+            let channel = WI.logManager.customLoggingChannels.find(channel => channel.source === WI.ConsoleMessage.MessageSource.Media);
+            InspectorTest.expectThat(channel.level === WI.LoggingChannel.Level.Off, "Media logging disabled.");
+
+            let logListener = WI.logManager.addEventListener(WI.LogManager.Event.MessageAdded, (event) => {
+                InspectorTest.fail("Nothing should be logged to the console.");
+                reject();
+            });
+
+            InspectorTest.awaitEvent("PlayEvent").then((event) => {
+                InspectorTest.log("Started Playing");
+            });
+
+            InspectorTest.awaitEvent("PauseEvent").then((event) => {
+                InspectorTest.log("Stopped Playing");
+                WI.logManager.removeEventListener(WI.LogManager.Event.MessageAdded, logListener, null);
+            }).then(resolve, reject);
+
+            InspectorTest.evaluateInPage(`play()`);
+            InspectorTest.evaluateInPage(`pause()`);
+        }
+    });
+
+
+    suite.addTestCase({
+        name: "Console.Logging.MediaLogging",
+        description: "<video> logging when enabled.",
+        test(resolve, reject) {
+            ConsoleAgent.clearMessages();
+
+            let channel = WI.logManager.customLoggingChannels.find(channel => channel.source === WI.ConsoleMessage.MessageSource.Media);
+            InspectorTest.expectThat(channel.level === WI.LoggingChannel.Level.Off, "Media logging disabled.");
+
+            ConsoleAgent.setLoggingChannelLevel(channel.source, WI.LoggingChannel.Level.Log)
+            ConsoleAgent.getLoggingChannels((error, channels) => {
+                if (error) {
+                    InspectorTest.fail(`ConsoleAgent.getLoggingChannels() failed with error ${error}`);
+                    reject();
+                }
+            
+                let mediaChannel = channels.find(channel => channel.source === WI.ConsoleMessage.MessageSource.Media);
+                InspectorTest.expectThat(mediaChannel.level === WI.LoggingChannel.Level.Log, "Media logging has been enabled.");
+
+                let logListener = WI.logManager.addEventListener(WI.LogManager.Event.MessageAdded, (event) => {
+                    let message = event.data.message;
+                    InspectorTest.assert(message instanceof WI.ConsoleMessage);
+                    InspectorTest.expectThat(message.source === WI.ConsoleMessage.MessageSource.Media, "Media log message should have source 'media'.");
+                    WI.logManager.removeEventListener(WI.LogManager.Event.MessageAdded, logListener, null);
+                    ConsoleAgent.setLoggingChannelLevel(mediaChannel.source, WI.LoggingChannel.Level.Off)
+                    resolve();
+                });
+
+                InspectorTest.awaitEvent("PlayEvent").then((event) => {
+                    InspectorTest.log("Started Playing");
+                });
+
+                InspectorTest.awaitEvent("PauseEvent").then((event) => {
+                    InspectorTest.log("Stopped Playing");
+                }).then(resolve, reject);
+
+                InspectorTest.evaluateInPage(`play()`);
+                InspectorTest.evaluateInPage(`pause()`);
+            })
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+
+</script>
+</head>
+<body onload="setup()">
+<p>Test WebKit logging configuration and console display.</p>
+<video width=320 height=240 controls></video>
+</body>
+</html>
index a5dbcbe..41e5155 100644 (file)
@@ -1772,6 +1772,9 @@ webkit.org/b/176878 [ Debug ] fast/multicol/spanner-crash-when-adding-summary.ht
 # <rdar://problem/34507977>
 webkit.org/b/177119 webgl/1.0.2/conformance/textures/tex-image-and-sub-image-2d-with-video.html [ Pass Failure ]
 
+# Release logging not supported
+[ Yosemite ElCapitan ] inspector/console/webcore-logging.html [ Skip ]
+
 webkit.org/b/177319 imported/w3c/web-platform-tests/html/semantics/forms/the-form-element/form-elements-filter.html [ Failure ]
 
 webkit.org/b/177322 [ Debug ] imported/w3c/web-platform-tests/html/semantics/document-metadata/the-meta-element/pragma-directives/attr-meta-http-equiv-refresh/parsing.html [ Pass Failure ]
index ffb9a20..d299dd8 100644 (file)
@@ -3770,6 +3770,9 @@ webkit.org/b/177109 fast/css/display-contents-style-update.html [ ImageOnlyFailu
 
 webkit.org/b/177212 accessibility/crash-table-recursive-layout.html [ Failure ]
 
+# Release logging not supported
+inspector/console/webcore-logging.html [ Skip ]
+
 webkit.org/b/177216 fast/images/animated-image-mp4.html [ Skip ]
 
 webkit.org/b/177234 http/wpt/resource-timing/rt-cors.html [ Skip ]
index 2b531ff..3e063ed 100644 (file)
@@ -1,3 +1,32 @@
+2017-10-24  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Enable WebKit logging configuration and display
+        https://bugs.webkit.org/show_bug.cgi?id=177027
+        <rdar://problem/33964767>
+
+        Reviewed by Joseph Pecoraro.
+
+        * inspector/ConsoleMessage.cpp:
+        (Inspector::messageSourceValue): Inspector::Protocol::Console::ConsoleMessage -> 
+            Inspector::Protocol::Console::ChannelSource.
+        * inspector/agents/JSGlobalObjectConsoleAgent.cpp:
+        (Inspector::JSGlobalObjectConsoleAgent::getLoggingChannels): There are no logging channels
+            specific to a JSContext yet, so return an empty channel array.
+        (Inspector::JSGlobalObjectConsoleAgent::setLoggingChannelLevel): No channels, return an error.
+        * inspector/agents/JSGlobalObjectConsoleAgent.h:
+
+        * inspector/protocol/Console.json: Add ChannelSource, ChannelLevel, and Channel. Add getLoggingChannels
+            and setLoggingChannelLevel.
+
+        * inspector/scripts/codegen/generator.py: Special case "webrtc"-> "WebRTC".
+        * inspector/scripts/tests/generic/expected/enum-values.json-result:
+        * inspector/scripts/tests/generic/expected/type-declaration-array-type.json-result:
+        * inspector/scripts/tests/generic/expected/type-declaration-enum-type.json-result:
+        * inspector/scripts/tests/generic/expected/type-declaration-object-type.json-result:
+        * inspector/scripts/tests/generic/expected/type-requiring-runtime-casts.json-result:
+
+        * runtime/ConsoleTypes.h: Add Media and WebRTC.
+
 2017-10-24  Michael Saboff  <msaboff@apple.com>
 
         Allow OjbC Weak References when building TestAPI
index 5a10396..9db5dff 100644 (file)
@@ -119,22 +119,24 @@ void ConsoleMessage::autogenerateMetadata(JSC::ExecState* state)
     }
 }
 
-static Inspector::Protocol::Console::ConsoleMessage::Source messageSourceValue(MessageSource source)
+static Inspector::Protocol::Console::ChannelSource messageSourceValue(MessageSource source)
 {
     switch (source) {
-    case MessageSource::XML: return Inspector::Protocol::Console::ConsoleMessage::Source::XML;
-    case MessageSource::JS: return Inspector::Protocol::Console::ConsoleMessage::Source::Javascript;
-    case MessageSource::Network: return Inspector::Protocol::Console::ConsoleMessage::Source::Network;
-    case MessageSource::ConsoleAPI: return Inspector::Protocol::Console::ConsoleMessage::Source::ConsoleAPI;
-    case MessageSource::Storage: return Inspector::Protocol::Console::ConsoleMessage::Source::Storage;
-    case MessageSource::AppCache: return Inspector::Protocol::Console::ConsoleMessage::Source::Appcache;
-    case MessageSource::Rendering: return Inspector::Protocol::Console::ConsoleMessage::Source::Rendering;
-    case MessageSource::CSS: return Inspector::Protocol::Console::ConsoleMessage::Source::CSS;
-    case MessageSource::Security: return Inspector::Protocol::Console::ConsoleMessage::Source::Security;
-    case MessageSource::ContentBlocker: return Inspector::Protocol::Console::ConsoleMessage::Source::ContentBlocker;
-    case MessageSource::Other: return Inspector::Protocol::Console::ConsoleMessage::Source::Other;
+    case MessageSource::XML: return Inspector::Protocol::Console::ChannelSource::XML;
+    case MessageSource::JS: return Inspector::Protocol::Console::ChannelSource::Javascript;
+    case MessageSource::Network: return Inspector::Protocol::Console::ChannelSource::Network;
+    case MessageSource::ConsoleAPI: return Inspector::Protocol::Console::ChannelSource::ConsoleAPI;
+    case MessageSource::Storage: return Inspector::Protocol::Console::ChannelSource::Storage;
+    case MessageSource::AppCache: return Inspector::Protocol::Console::ChannelSource::Appcache;
+    case MessageSource::Rendering: return Inspector::Protocol::Console::ChannelSource::Rendering;
+    case MessageSource::CSS: return Inspector::Protocol::Console::ChannelSource::CSS;
+    case MessageSource::Security: return Inspector::Protocol::Console::ChannelSource::Security;
+    case MessageSource::ContentBlocker: return Inspector::Protocol::Console::ChannelSource::ContentBlocker;
+    case MessageSource::Other: return Inspector::Protocol::Console::ChannelSource::Other;
+    case MessageSource::Media: return Inspector::Protocol::Console::ChannelSource::Media;
+    case MessageSource::WebRTC: return Inspector::Protocol::Console::ChannelSource::WebRTC;
     }
-    return Inspector::Protocol::Console::ConsoleMessage::Source::Other;
+    return Inspector::Protocol::Console::ChannelSource::Other;
 }
 
 static Inspector::Protocol::Console::ConsoleMessage::Type messageTypeValue(MessageType type)
index d453dbb..32d4e30 100644 (file)
@@ -235,4 +235,15 @@ void InspectorConsoleAgent::addConsoleMessage(std::unique_ptr<ConsoleMessage> co
     }
 }
 
+void InspectorConsoleAgent::getLoggingChannels(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Console::Channel>>& channels)
+{
+    // Default implementation has no logging channels.
+    channels = Inspector::Protocol::Array<Inspector::Protocol::Console::Channel>::create();
+}
+
+void InspectorConsoleAgent::setLoggingChannelLevel(ErrorString& errorString, const String&, const String&)
+{
+    errorString = ASCIILiteral("No such channel to enable");
+}
+
 } // namespace Inspector
index 194aa70..2e54188 100644 (file)
@@ -72,6 +72,9 @@ public:
     void takeHeapSnapshot(const String& title);
     void count(JSC::ExecState*, Ref<ScriptArguments>&&);
 
+    void getLoggingChannels(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Console::Channel>>&) override;
+    void setLoggingChannelLevel(ErrorString&, const String& channel, const String& level) override;
+
 protected:
     void addConsoleMessage(std::unique_ptr<ConsoleMessage>);
 
index 32aa798..792d7d0 100644 (file)
@@ -4,11 +4,32 @@
     "workerSupported": true,
     "types": [
         {
+            "id": "ChannelSource",
+            "type": "string",
+            "enum": ["xml", "javascript", "network", "console-api", "storage", "appcache", "rendering", "css", "security", "content-blocker", "media", "webrtc", "other"],
+            "description": "Channels for different types of log messages."
+        },
+        {
+            "id": "ChannelLevel",
+            "type": "string",
+            "enum": ["off", "log", "error", "warning", "info", "debug"],
+            "description": "Level of logging."
+        },
+        {
+            "id": "Channel",
+            "description": "Logging channel.",
+            "type": "object",
+            "properties": [
+                { "name": "source", "$ref": "ChannelSource" },
+                { "name": "level", "$ref": "ChannelLevel" }
+            ]
+        },
+        {
             "id": "ConsoleMessage",
             "type": "object",
             "description": "Console message.",
             "properties": [
-                { "name": "source", "type": "string", "enum": ["xml", "javascript", "network", "console-api", "storage", "appcache", "rendering", "css", "security", "content-blocker", "other"], "description": "Message source." },
+                { "name": "source", "$ref": "ChannelSource"},
                 { "name": "level", "type": "string", "enum": ["log", "info", "warning", "error", "debug"], "description": "Message severity." },
                 { "name": "text", "type": "string", "description": "Message text." },
                 { "name": "type", "type": "string", "optional": true, "enum": ["log", "dir", "dirxml", "table", "trace", "clear", "startGroup", "startGroupCollapsed", "endGroup", "assert", "timing", "profile", "profileEnd"], "description": "Console message type." },
         {
             "name": "clearMessages",
             "description": "Clears console messages collected in the browser."
-        }
+        },
+        {
+            "name": "getLoggingChannels",
+            "description": "List of the different message sources that are non-default logging channels.",
+            "returns": [
+                { "name": "channels", "type": "array", "items": { "$ref": "Channel"}, "description": "Logging channels." }
+            ]
+         },
+         {
+            "name": "setLoggingChannelLevel",
+            "description": "Modify the level of a channel.",
+            "parameters": [
+                { "name": "source", "$ref": "ChannelSource", "description": "Logging channel to modify." },
+                { "name": "level", "$ref": "ChannelLevel", "description": "New level." }
+            ]
+         }
     ],
     "events": [
         {
index 7db67d1..a5cfc3c 100755 (executable)
@@ -46,6 +46,7 @@ _ENUM_IDENTIFIER_RENAME_MAP = {
     'webgl': 'WebGL',  # Canvas.ContextType.webgl
     'webgl2': 'WebGL2',  # Canvas.ContextType.webgl2
     'webgpu': 'WebGPU',  # Canvas.ContextType.webgpu
+    'webrtc': 'WebRTC',  # Console.ChannelSource.webrtc
 }
 
 # These objects are built manually by creating and setting InspectorValues.
index 637add0..df9127a 100644 (file)
@@ -31,6 +31,7 @@
 
 // TypeDomain.
 InspectorBackend.registerEnum("TypeDomain.TypeDomainEnum", {Shared: "shared", Red: "red", Green: "green", Blue: "blue"});
+InspectorBackend.activateDomain("TypeDomain");
 
 // CommandDomain.
 InspectorBackend.registerCommand("CommandDomain.commandWithEnumReturnValue", [], ["returnValue"]);
index 9c3faef..1fc6cae 100644 (file)
@@ -31,6 +31,7 @@
 
 // Debugger.
 InspectorBackend.registerEnum("Debugger.Reason", {Died: "Died", Fainted: "Fainted", Hungry: "Hungry"});
+InspectorBackend.activateDomain("Debugger");
 ### End File: InspectorBackendCommands.js
 
 ### Begin File: TestAlternateBackendDispatchers.h
index a4e2ce0..dd48acf 100644 (file)
@@ -32,6 +32,7 @@
 // Runtime.
 InspectorBackend.registerEnum("Runtime.FarmAnimals", {Pigs: "Pigs", Cows: "Cows", Cats: "Cats", Hens: "Hens"});
 InspectorBackend.registerEnum("Runtime.TwoLeggedAnimals", {Ducks: "Ducks", Hens: "Hens", Crows: "Crows", Flamingos: "Flamingos"});
+InspectorBackend.activateDomain("Runtime");
 ### End File: InspectorBackendCommands.js
 
 ### Begin File: TestAlternateBackendDispatchers.h
index 61bac54..eeb99be 100644 (file)
@@ -33,6 +33,7 @@
 InspectorBackend.registerEnum("Database.MouseButton", {None: "None", Left: "Left", Middle: "Middle", Right: "Right"});
 InspectorBackend.registerEnum("Database.OptionalParameterBundleDirectionality", {LTR: "LTR", RTL: "RTL"});
 InspectorBackend.registerEnum("Database.ParameterBundleDirectionality", {LTR: "LTR", RTL: "RTL"});
+InspectorBackend.activateDomain("Database");
 ### End File: InspectorBackendCommands.js
 
 ### Begin File: TestAlternateBackendDispatchers.h
index 9cc2af9..873358e 100644 (file)
@@ -32,6 +32,7 @@
 // Test.
 InspectorBackend.registerEnum("Test.UncastedAnimals", {Pigs: "Pigs", Cows: "Cows", Cats: "Cats", Hens: "Hens"});
 InspectorBackend.registerEnum("Test.CastedAnimals", {Ducks: "Ducks", Hens: "Hens", Crows: "Crows", Flamingos: "Flamingos"});
+InspectorBackend.activateDomain("Test");
 ### End File: InspectorBackendCommands.js
 
 ### Begin File: TestAlternateBackendDispatchers.h
index 9b670a4..7ca2fe7 100644 (file)
@@ -39,6 +39,8 @@ enum class MessageSource {
     Security,
     ContentBlocker,
     Other,
+    Media,
+    WebRTC,
 };
 
 enum class MessageType {
index 3e0aaa0..11ea5e8 100644 (file)
@@ -1,3 +1,28 @@
+2017-10-24  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Enable WebKit logging configuration and display
+        https://bugs.webkit.org/show_bug.cgi?id=177027
+        <rdar://problem/33964767>
+
+        Reviewed by Joseph Pecoraro.
+
+        Test: inspector/console/webcore-logging.html
+
+        * dom/Document.cpp:
+        (WebCore::Document::~Document): Stop observing the logger.
+        (WebCore::Document::logger): Observe the logger.
+        (WebCore::Document::didLogMessage): Forward logging messages to the inspector.
+        * dom/Document.h:
+
+        * inspector/WebConsoleAgent.cpp:
+        (WebCore::WebConsoleAgent::getLoggingChannels): New, return the state of log runtime channels.
+        (WebCore::WebConsoleAgent::setLoggingChannelLevel): New, set the state of a channel.
+        * inspector/WebConsoleAgent.h:
+
+        * platform/Logging.cpp:
+        (WebCore::getLogChannel): New, get a log channel by name.
+        * platform/Logging.h:
+
 2017-10-24  Dean Jackson  <dino@apple.com>
 
         Attempted build fix for Sierra.
index 1d387c7..449b1dd 100644 (file)
@@ -1,3 +1,18 @@
+2017-10-24  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Enable WebKit logging configuration and display
+        https://bugs.webkit.org/show_bug.cgi?id=177027
+        <rdar://problem/33964767>
+
+        Reviewed by Joseph Pecoraro.
+
+        * pal/Logger.h:
+        (PAL::Logger::willLog const): Always return true for Always and Error so those messages are
+            always logged to the system.
+        (PAL::Logger::log): Always log Always and Error to the system, but pay strict attention to level
+            and channel state for logging to observers so logging only shows up in the inspector when
+            explicitly enabled by the user. 
+
 2017-10-24  Brent Fulgham  <bfulgham@apple.com>
 
         Adopt new secure coding APIs
index ca29471..1c8276e 100644 (file)
@@ -119,10 +119,13 @@ public:
 
     inline bool willLog(const WTFLogChannel& channel, WTFLogLevel level) const
     {
-        if (level != WTFLogLevelAlways && level > channel.level)
+        if (!m_enabled)
             return false;
 
-        if (channel.level != WTFLogLevelAlways && channel.state == WTFLogChannelOff)
+        if (level <= WTFLogLevelError)
+            return true;
+
+        if (channel.state == WTFLogChannelOff || level > channel.level)
             return false;
 
         return m_enabled;
@@ -183,6 +186,9 @@ private:
         os_log(channel.osLogChannel, "%{public}s", logMessage.utf8().data());
 #endif
 
+        if (channel.state == WTFLogChannelOff || level > channel.level)
+            return;
+
         for (Observer& observer : observers())
             observer.didLogMessage(channel, level, logMessage);
     }
index 93d52e1..25d4a5c 100644 (file)
@@ -615,6 +615,9 @@ Document::~Document()
 
     for (unsigned count : m_nodeListAndCollectionCounts)
         ASSERT_UNUSED(count, !count);
+
+    if (m_logger)
+        m_logger->removeObserver(*this);
 }
 
 void Document::removedLastRef()
@@ -7282,11 +7285,12 @@ void Document::setVlinkColor(const String& value)
         bodyElement->setAttributeWithoutSynchronization(vlinkAttr, value);
 }
 
-Logger& Document::logger() const
+Logger& Document::logger()
 {
     if (!m_logger) {
         m_logger = Logger::create(this);
         m_logger->setEnabled(this, sessionID().isAlwaysOnLoggingAllowed());
+        m_logger->addObserver(*this);
     }
 
     return *m_logger;
@@ -7380,4 +7384,64 @@ DocumentTimeline& Document::timeline()
     return *m_timeline;
 }
 
+static MessageSource messageSourceForWTFLogChannel(const WTFLogChannel& channel)
+{
+    static const NeverDestroyed<String> mediaChannel = MAKE_STATIC_STRING_IMPL("media");
+    static const NeverDestroyed<String> webrtcChannel = MAKE_STATIC_STRING_IMPL("webrtc");
+
+    if (equalIgnoringASCIICase(mediaChannel, channel.name))
+        return MessageSource::Media;
+
+    if (equalIgnoringASCIICase(webrtcChannel, channel.name))
+        return MessageSource::WebRTC;
+
+    ASSERT_NOT_REACHED();
+    return MessageSource::Other;
+}
+
+static MessageLevel messageLevelFromWTFLogLevel(WTFLogLevel level)
+{
+    switch (level) {
+    case WTFLogLevelAlways:
+        return MessageLevel::Log;
+    case WTFLogLevelError:
+        return MessageLevel::Error;
+        break;
+    case WTFLogLevelWarning:
+        return MessageLevel::Warning;
+        break;
+    case WTFLogLevelInfo:
+        return MessageLevel::Info;
+        break;
+    case WTFLogLevelDebug:
+        return MessageLevel::Debug;
+        break;
+    }
+
+    ASSERT_NOT_REACHED();
+    return MessageLevel::Log;
+}
+
+void Document::didLogMessage(const WTFLogChannel& channel, WTFLogLevel level, const String& logMessage)
+{
+    if (!this->page())
+        return;
+
+    ASSERT(sessionID().isAlwaysOnLoggingAllowed());
+
+    auto messageSource = messageSourceForWTFLogChannel(channel);
+    auto messageLevel = messageLevelFromWTFLogLevel(level);
+
+    callOnMainThread([documentReference = m_weakFactory.createWeakPtr(*this), messageSource, messageLevel, logMessage]() mutable {
+        ASSERT(isMainThread());
+
+        Document* document = documentReference.get();
+        if (!document)
+            return;
+
+        auto message = std::make_unique<Inspector::ConsoleMessage>(messageSource, MessageType::Log, messageLevel, logMessage);
+        document->addConsoleMessage(WTFMove(message));
+    });
+}
+
 } // namespace WebCore
index f2ba7ab..16717e8 100644 (file)
@@ -51,6 +51,7 @@
 #include "UserActionElementSet.h"
 #include "ViewportArguments.h"
 #include "VisibilityState.h"
+#include <pal/Logger.h>
 #include <pal/SessionID.h>
 #include <wtf/Deque.h>
 #include <wtf/Forward.h>
@@ -72,10 +73,6 @@ class ExecState;
 class InputCursor;
 }
 
-namespace PAL {
-class Logger;
-}
-
 namespace WebCore {
 
 class AXObjectCache;
@@ -307,7 +304,8 @@ class Document
     , public ScriptExecutionContext
     , public FontSelectorClient
     , public FrameDestructionObserver
-    , public Supplementable<Document> {
+    , public Supplementable<Document>
+    , public PAL::Logger::Observer {
 public:
     static Ref<Document> create(Frame* frame, const URL& url)
     {
@@ -1357,7 +1355,7 @@ public:
     TextAutoSizing& textAutoSizing();
 #endif
 
-    PAL::Logger& logger() const;
+    PAL::Logger& logger();
 
     bool hasStorageAccess() const { return m_hasStorageAccess; };
     void requestStorageAccess(Ref<DeferredPromise>&& passedPromise);
@@ -1659,6 +1657,8 @@ private:
 
     void notifyMediaCaptureOfVisibilityChanged();
 
+    void didLogMessage(const WTFLogChannel&, WTFLogLevel, const String&) final;
+
 #if ENABLE(DEVICE_ORIENTATION) && PLATFORM(IOS)
     std::unique_ptr<DeviceMotionClient> m_deviceMotionClient;
     std::unique_ptr<DeviceMotionController> m_deviceMotionController;
index 08512d4..589ba35 100644 (file)
@@ -29,6 +29,7 @@
 
 #include "CommandLineAPIHost.h"
 #include "DOMWindow.h"
+#include "Logging.h"
 #include "ResourceError.h"
 #include "ResourceResponse.h"
 #include "ScriptState.h"
@@ -46,6 +47,100 @@ WebConsoleAgent::WebConsoleAgent(AgentContext& context, InspectorHeapAgent* heap
 {
 }
 
+void WebConsoleAgent::getLoggingChannels(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Console::Channel>>& channels)
+{
+    static const struct ChannelTable {
+        NeverDestroyed<String> name;
+        Inspector::Protocol::Console::ChannelSource source;
+    } channelTable[] = {
+        { MAKE_STATIC_STRING_IMPL("WebRTC"), Inspector::Protocol::Console::ChannelSource::WebRTC },
+        { MAKE_STATIC_STRING_IMPL("Media"), Inspector::Protocol::Console::ChannelSource::Media },
+    };
+
+    channels = Inspector::Protocol::Array<Inspector::Protocol::Console::Channel>::create();
+
+    size_t length = WTF_ARRAY_LENGTH(channelTable);
+    for (size_t i = 0; i < length; ++i) {
+        auto* logChannel = getLogChannel(channelTable[i].name);
+        if (!logChannel)
+            return;
+
+        Inspector::Protocol::Console::ChannelLevel level;
+        if (logChannel->state == WTFLogChannelOff)
+            level = Inspector::Protocol::Console::ChannelLevel::Off;
+        else {
+            switch (logChannel->level) {
+            case WTFLogLevelAlways:
+                level = Inspector::Protocol::Console::ChannelLevel::Log;
+                break;
+            case WTFLogLevelError:
+                level = Inspector::Protocol::Console::ChannelLevel::Error;
+                break;
+            case WTFLogLevelWarning:
+                level = Inspector::Protocol::Console::ChannelLevel::Warning;
+                break;
+            case WTFLogLevelInfo:
+                level = Inspector::Protocol::Console::ChannelLevel::Info;
+                break;
+            case WTFLogLevelDebug:
+                level = Inspector::Protocol::Console::ChannelLevel::Debug;
+                break;
+            }
+        }
+
+        auto channel = Inspector::Protocol::Console::Channel::create()
+            .setSource(channelTable[i].source)
+            .setLevel(level)
+            .release();
+        channels->addItem(WTFMove(channel));
+    }
+}
+
+static std::optional<std::pair<WTFLogChannelState, WTFLogLevel>> channelConfigurationForString(const String& levelString)
+{
+    WTFLogChannelState state;
+    WTFLogLevel level;
+
+    if (equalIgnoringASCIICase(levelString, "off")) {
+        state = WTFLogChannelOff;
+        level = WTFLogLevelError;
+    } else {
+        state = WTFLogChannelOn;
+        if (equalIgnoringASCIICase(levelString, "log"))
+            level = WTFLogLevelAlways;
+        else if (equalIgnoringASCIICase(levelString, "error"))
+            level = WTFLogLevelError;
+        else if (equalIgnoringASCIICase(levelString, "warning"))
+            level = WTFLogLevelWarning;
+        else if (equalIgnoringASCIICase(levelString, "info"))
+            level = WTFLogLevelInfo;
+        else if (equalIgnoringASCIICase(levelString, "debug"))
+            level = WTFLogLevelDebug;
+        else
+            return std::nullopt;
+    }
+
+    return { { state, level } };
+}
+
+void WebConsoleAgent::setLoggingChannelLevel(ErrorString& errorString, const String& channelName, const String& channelLevel)
+{
+    auto* channel = getLogChannel(channelName.utf8().data());
+    if (!channel) {
+        errorString = ASCIILiteral("Logging channel not found");
+        return;
+    }
+
+    auto configuration = channelConfigurationForString(channelLevel);
+    if (!configuration) {
+        errorString = ASCIILiteral("Invalid logging level");
+        return;
+    }
+
+    channel->state = configuration.value().first;
+    channel->level = configuration.value().second;
+}
+
 void WebConsoleAgent::frameWindowDiscarded(DOMWindow* window)
 {
     for (auto& message : m_consoleMessages) {
index 3a55755..aaf2132 100644 (file)
@@ -43,6 +43,9 @@ public:
 
     void frameWindowDiscarded(DOMWindow*);
 
+    void getLoggingChannels(ErrorString&, RefPtr<Inspector::Protocol::Array<Inspector::Protocol::Console::Channel>>&) final;
+    void setLoggingChannelLevel(ErrorString&, const String& channel, const String& level) final;
+
     void didReceiveResponse(unsigned long requestIdentifier, const ResourceResponse&);
     void didFailLoading(unsigned long requestIdentifier, const ResourceError&);
 };
index a015960..f74514c 100644 (file)
@@ -80,6 +80,18 @@ void initializeLogChannelsIfNecessary(std::optional<String> logChannelString)
     WTFInitializeLogChannelStatesFromString(logChannels, logChannelCount, enabledChannelsString.utf8().data());
 }
 
+WTFLogChannel* getLogChannel(const String& name)
+{
+    return WTFLogChannelByName(logChannels, logChannelCount, name.utf8().data());
+}
+
+#else
+
+WTFLogChannel* getLogChannel(const String&)
+{
+    return nullptr;
+}
+
 #endif // !LOG_DISABLED || !RELEASE_LOG_DISABLED
 
 } // namespace WebCore
index 06090cd..651508b 100644 (file)
@@ -109,4 +109,6 @@ WEBCORE_EXPORT void setLogChannelToAccumulate(const String& name);
 
 #endif // !LOG_DISABLED || !RELEASE_LOG_DISABLED
 
+WEBCORE_EXPORT WTFLogChannel* getLogChannel(const String& name);
+
 } // namespace WebCore
index 8dcdf48..ff4ef4d 100644 (file)
@@ -1,3 +1,48 @@
+2017-10-24  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Enable WebKit logging configuration and display
+        https://bugs.webkit.org/show_bug.cgi?id=177027
+        <rdar://problem/33964767>
+
+        Reviewed by Joseph Pecoraro.
+
+        * Localizations/en.lproj/localizedStrings.js: Add new localized strings.
+
+        * UserInterface/Controllers/LogManager.js:
+        (WI.LogManager): Initialize _loggingChannelSources, fetch _customLoggingChannels.
+        (WI.LogManager.supportsLogChannels): New.
+        (WI.LogManager.prototype.get customLoggingChannels): New.
+        (WI.LogManager.prototype.get logChannelSources): New.
+
+        * UserInterface/Main.html:
+        * UserInterface/Models/ConsoleMessage.js: Add Media and WebRTC.
+
+        * UserInterface/Models/IssueMessage.js:
+        (WI.IssueMessage): Add media and webrtc.
+
+        * UserInterface/Models/LoggingChannel.js: Added.
+        (WI.LoggingChannel):
+        (WI.LoggingChannel.fromPayload):
+        (WI.LoggingChannel.prototype.get source):
+        (WI.LoggingChannel.prototype.get level):
+
+        * UserInterface/Views/LogContentView.js:
+        (WI.LogContentView): Add new scope buttons for "Log", "Info", and "Debug". Create log channel
+            scope buttons once logging has started.
+        (WI.LogContentView.prototype.get navigationItems): Add the log message scope bar when necessary.
+        (WI.LogContentView.prototype._scopeFromMessageSource): New.
+        (WI.LogContentView.prototype._scopeFromMessageLevel): Don't group Info, Log, and Debug.
+        (WI.LogContentView.prototype._messageAdded): Force a UI update the first time a WebKit log
+            message is added.
+
+        (WI.LogContentView.prototype._messageShouldBeVisible): New, deal with message source bar buttons.
+        (WI.LogContentView.prototype._messageSourceBarSelectionDidChange): New.
+        (WI.LogContentView.prototype._filterMessageElements): Deal with message source bar buttons.
+
+        * UserInterface/Views/SettingsTabContentView.js:
+        (WI.SettingsTabContentView.prototype._createGeneralSettingsView): Create and initialize menus
+            for each log channel.
+
 2017-10-24  Joseph Pecoraro  <pecoraro@apple.com>
 
         Uncaught Exception: TypeError: null is not an object (evaluating 'this.treeOutline.isXMLMimeType')
index 7a4e362..f9159ae 100644 (file)
@@ -275,12 +275,14 @@ localizedStrings["Database"] = "Database";
 localizedStrings["Database no longer has expected version."] = "Database no longer has expected version.";
 localizedStrings["Databases"] = "Databases";
 localizedStrings["Date"] = "Date";
+localizedStrings["Debug"] = "Debug";
 localizedStrings["Debug: "] = "Debug: ";
 localizedStrings["Debugger"] = "Debugger";
 localizedStrings["Debugger Paused"] = "Debugger Paused";
 localizedStrings["Debugger Statement"] = "Debugger Statement";
 localizedStrings["Debugger disabled during Timeline recording"] = "Debugger disabled during Timeline recording";
 localizedStrings["Debugger:"] = "Debugger:";
+localizedStrings["Debugs"] = "Debugs";
 localizedStrings["Decoded"] = "Decoded";
 localizedStrings["Decoration"] = "Decoration";
 localizedStrings["Default"] = "Default";
@@ -492,7 +494,9 @@ localizedStrings["Indent width:"] = "Indent width:";
 localizedStrings["Index"] = "Index";
 localizedStrings["Index Key \u2014 %s"] = "Index Key \u2014 %s";
 localizedStrings["Indexed Databases"] = "Indexed Databases";
+localizedStrings["Info"] = "Info";
 localizedStrings["Info: "] = "Info: ";
+localizedStrings["Infos"] = "Infos";
 localizedStrings["Inherited From: "] = "Inherited From: ";
 localizedStrings["Inherited from %s"] = "Inherited from %s";
 localizedStrings["Initial State"] = "Initial State";
@@ -545,6 +549,7 @@ localizedStrings["Local Storage"] = "Local Storage";
 localizedStrings["Local Variables"] = "Local Variables";
 localizedStrings["Located at %s"] = "Located at %s";
 localizedStrings["Location"] = "Location";
+localizedStrings["Log"] = "Log";
 localizedStrings["Log Canvas Context"] = "Log Canvas Context";
 localizedStrings["Log Element"] = "Log Element";
 localizedStrings["Log Frame Text"] = "Log Frame Text";
@@ -571,6 +576,8 @@ localizedStrings["Max Comparison"] = "Max Comparison";
 localizedStrings["Maximum"] = "Maximum";
 localizedStrings["Maximum Size: %s"] = "Maximum Size: %s";
 localizedStrings["Maximum maximum memory size in this recording"] = "Maximum maximum memory size in this recording";
+localizedStrings["Media"] = "Media";
+localizedStrings["Media Logging:"] = "Media Logging:";
 localizedStrings["Media: "] = "Media: ";
 localizedStrings["Medium"] = "Medium";
 localizedStrings["Memory"] = "Memory";
@@ -634,6 +641,7 @@ localizedStrings["Number"] = "Number";
 localizedStrings["Numeric"] = "Numeric";
 localizedStrings["Object Graph"] = "Object Graph";
 localizedStrings["Object Store"] = "Object Store";
+localizedStrings["Off"] = "Off";
 localizedStrings["Offset"] = "Offset";
 localizedStrings["Once"] = "Once";
 localizedStrings["Online"] = "Online";
@@ -993,11 +1001,14 @@ localizedStrings["View variable value"] = "View variable value";
 localizedStrings["Visibility"] = "Visibility";
 localizedStrings["Visible"] = "Visible";
 localizedStrings["Waiting"] = "Waiting";
+localizedStrings["Warning"] = "Warning";
 localizedStrings["Warning: "] = "Warning: ";
 localizedStrings["Warnings"] = "Warnings";
 localizedStrings["Watch Expressions"] = "Watch Expressions";
 localizedStrings["Waterfall"] = "Waterfall";
 localizedStrings["Web Inspector"] = "Web Inspector";
+localizedStrings["WebRTC"] = "WebRTC";
+localizedStrings["WebRTC Logging:"] = "WebRTC Logging:";
 localizedStrings["WebSocket Connection Established"] = "WebSocket Connection Established";
 localizedStrings["Weight"] = "Weight";
 localizedStrings["Whitespace"] = "Whitespace";
index e2238e9..72c7367 100644 (file)
@@ -34,10 +34,36 @@ WI.LogManager = class LogManager extends WI.Object
         this._isNewPageOrReload = false;
 
         WI.Frame.addEventListener(WI.Frame.Event.MainResourceDidChange, this._mainResourceDidChange, this);
+
+        this._customLoggingChannels = [];
+        this._loggingChannelSources = [];
+
+        if (WI.LogManager.supportsLogChannels()) {
+            this._loggingChannelSources = [WI.ConsoleMessage.MessageSource.Media, WI.ConsoleMessage.MessageSource.WebRTC];
+            ConsoleAgent.getLoggingChannels((error, channels) => {
+                if (error)
+                    return;
+
+                for (let channel of channels)
+                    console.assert(this._loggingChannelSources.includes(channel.source));
+
+                this._customLoggingChannels = channels.map(WI.LoggingChannel.fromPayload);
+            });
+        }
+    }
+
+    // Static
+
+    static supportsLogChannels()
+    {
+        return !!ConsoleAgent.getLoggingChannels;
     }
 
     // Public
 
+    get customLoggingChannels() { return this._customLoggingChannels; }
+    get logChannelSources() { return this._loggingChannelSources; }
+
     messageWasAdded(target, source, level, text, type, url, line, column, repeatCount, parameters, stackTrace, requestId)
     {
         // Called from WI.ConsoleObserver.
index 4cf802c..37ce79d 100644 (file)
     <script src="Models/LazySourceCodeLocation.js"></script>
     <script src="Models/LineWidget.js"></script>
     <script src="Models/LogObject.js"></script>
+    <script src="Models/LoggingChannel.js"></script>
     <script src="Models/MemoryCategory.js"></script>
     <script src="Models/MemoryInstrument.js"></script>
     <script src="Models/MemoryPressureEvent.js"></script>
index 1243d0c..d148409 100644 (file)
@@ -109,6 +109,8 @@ WI.ConsoleMessage.MessageSource = {
     CSS: "css",
     Security: "security",
     Other: "other",
+    Media: "media",
+    WebRTC: "webrtc",
 };
 
 WI.ConsoleMessage.MessageType = {
index 2f71cec..ad3d248 100644 (file)
@@ -66,6 +66,8 @@ WI.IssueMessage = class IssueMessage extends WI.Object
         case "appcache":
         case "rendering":
         case "other":
+        case "media":
+        case "webrtc":
             this._type = WI.IssueMessage.Type.OtherIssue;
             break;
 
diff --git a/Source/WebInspectorUI/UserInterface/Models/LoggingChannel.js b/Source/WebInspectorUI/UserInterface/Models/LoggingChannel.js
new file mode 100644 (file)
index 0000000..ddb52b3
--- /dev/null
@@ -0,0 +1,60 @@
+/*
+ * Copyright (C) 2017 Apple Inc. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ *    notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ *    notice, this list of conditions and the following disclaimer in the
+ *    documentation and/or other materials provided with the distribution.
+ *
+ * THIS SOFTWARE IS PROVIDED BY APPLE INC. AND ITS CONTRIBUTORS ``AS IS''
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
+ * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
+ * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL APPLE INC. OR ITS CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+ * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+ * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
+ * THE POSSIBILITY OF SUCH DAMAGE.
+ */
+
+WI.LoggingChannel = class LoggingChannel
+{
+    constructor(source, level)
+    {
+        console.assert(typeof source === "string");
+        console.assert(source === WI.ConsoleMessage.MessageSource.Media || source === WI.ConsoleMessage.MessageSource.WebRTC);
+
+        console.assert(typeof level === "string");
+        console.assert(Object.values(WI.LoggingChannel.Level).includes(level));
+
+        this._source = source;
+        this._level = level;
+    }
+
+    // Payload
+
+    static fromPayload(payload)
+    {
+        return new WI.LoggingChannel(payload.source, payload.level);
+    }
+
+    // Public
+
+    get source() { return this._source; }
+    get level() { return this._level; }
+};
+
+WI.LoggingChannel.Level = {
+    Off: "off",
+    Log: "log",
+    Error: "error",
+    Warning: "warning",
+    Info: "info",
+    Debug: "debug",
+};
index c716d98..121b9bd 100644 (file)
     <script src="Models/LayoutInstrument.js"></script>
     <script src="Models/LayoutTimelineRecord.js"></script>
     <script src="Models/LazySourceCodeLocation.js"></script>
+    <script src="Models/LoggingChannel.js"></script>
     <script src="Models/MemoryCategory.js"></script>
     <script src="Models/MemoryInstrument.js"></script>
     <script src="Models/MemoryPressureEvent.js"></script>
index af3fbad..791c1eb 100644 (file)
     color: hsl(0, 75%, 45%);
 }
 
-.console-debug-level .console-message-text {
-    color: blue;
-}
-
 .console-warning-level {
     background-color: hsl(50, 100%, 94%);
     border-color: hsl(40, 100%, 90%);
index 3119df4..2b45e62 100644 (file)
@@ -70,12 +70,26 @@ WI.LogContentView = class LogContentView extends WI.ContentView
             new WI.ScopeBarItem(WI.LogContentView.Scopes.All, WI.UIString("All"), true),
             new WI.ScopeBarItem(WI.LogContentView.Scopes.Errors, WI.UIString("Errors"), false, "errors"),
             new WI.ScopeBarItem(WI.LogContentView.Scopes.Warnings, WI.UIString("Warnings"), false, "warnings"),
-            new WI.ScopeBarItem(WI.LogContentView.Scopes.Logs, WI.UIString("Logs"), false, "logs")
+            new WI.ScopeBarItem(WI.LogContentView.Scopes.Logs, WI.UIString("Logs"), false, "logs"),
+            new WI.ScopeBarItem(WI.LogContentView.Scopes.Infos, WI.UIString("Infos"), false, "infos", true),
+            new WI.ScopeBarItem(WI.LogContentView.Scopes.Debugs, WI.UIString("Debugs"), false, "debugs", true),            
         ];
 
         this._scopeBar = new WI.ScopeBar("log-scope-bar", scopeBarItems, scopeBarItems[0]);
         this._scopeBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._scopeBarSelectionDidChange, this);
 
+        this._hasNonDefaultLogChannelMessage = false;
+        if (WI.LogManager.supportsLogChannels()) {
+            let messageChannelBarItems = [
+                new WI.ScopeBarItem(WI.LogContentView.Scopes.AllChannels, WI.UIString("All"), true),
+                new WI.ScopeBarItem(WI.LogContentView.Scopes.Media, WI.UIString("Media"), false, "media"),
+                new WI.ScopeBarItem(WI.LogContentView.Scopes.WebRTC, WI.UIString("WebRTC"), false, "webrtc")
+            ];
+
+            this._messageSourceBar = new WI.ScopeBar("message-channel-scope-bar", messageChannelBarItems, messageChannelBarItems[0]);
+            this._messageSourceBar.addEventListener(WI.ScopeBar.Event.SelectionChanged, this._messageSourceBarSelectionDidChange, this);
+        }
+
         this._garbageCollectNavigationItem = new WI.ButtonNavigationItem("garbage-collect", WI.UIString("Collect garbage"), "Images/NavigationItemGarbageCollect.svg", 16, 16);
         this._garbageCollectNavigationItem.visibilityPriority = WI.NavigationItem.VisibilityPriority.Low;
         this._garbageCollectNavigationItem.addEventListener(WI.ButtonNavigationItem.Event.Clicked, this._garbageCollect, this);
@@ -103,6 +117,10 @@ WI.LogContentView = class LogContentView extends WI.ContentView
     get navigationItems()
     {
         let navigationItems = [this._scopeBar];
+
+        if (this._hasNonDefaultLogChannelMessage && this._messageSourceBar)
+            navigationItems.push(this._messageSourceBar);
+
         if (HeapAgent.gc)
             navigationItems.push(this._garbageCollectNavigationItem);
 
@@ -346,25 +364,35 @@ WI.LogContentView = class LogContentView extends WI.ContentView
         this._clearProvisionalState();
     }
 
-    _scopeFromMessageLevel(level)
+    _scopeFromMessageSource(source)
     {
-        var messageLevel;
+        switch (source) {
+        case WI.ConsoleMessage.MessageSource.Media:
+            return WI.LogContentView.Scopes.Media;
+        case WI.ConsoleMessage.MessageSource.WebRTC:
+            return WI.LogContentView.Scopes.WebRTC;
+        }
+
+        return undefined;
+    }
 
+    _scopeFromMessageLevel(level)
+    {
         switch (level) {
         case WI.ConsoleMessage.MessageLevel.Warning:
-            messageLevel = WI.LogContentView.Scopes.Warnings;
-            break;
+            return WI.LogContentView.Scopes.Warnings;
         case WI.ConsoleMessage.MessageLevel.Error:
-            messageLevel = WI.LogContentView.Scopes.Errors;
-            break;
+            return WI.LogContentView.Scopes.Errors;
         case WI.ConsoleMessage.MessageLevel.Log:
+            return WI.LogContentView.Scopes.Logs;
         case WI.ConsoleMessage.MessageLevel.Info:
+            return this._hasNonDefaultLogChannelMessage ? WI.LogContentView.Scopes.Infos : WI.LogContentView.Scopes.Logs;
         case WI.ConsoleMessage.MessageLevel.Debug:
-            messageLevel = WI.LogContentView.Scopes.Logs;
-            break;
+            return this._hasNonDefaultLogChannelMessage ? WI.LogContentView.Scopes.Debugs : WI.LogContentView.Scopes.Logs;
         }
+        console.assert(false, "This should not be reached.");
 
-        return messageLevel;
+        return undefined;
     }
 
     _markScopeBarItemUnread(level)
@@ -380,10 +408,18 @@ WI.LogContentView = class LogContentView extends WI.ContentView
 
     _messageAdded(event)
     {
+        let message = event.data.message;
         if (this._startedProvisionalLoad)
-            this._provisionalMessages.push(event.data.message);
+            this._provisionalMessages.push(message);
+
+        if (!this._hasNonDefaultLogChannelMessage && WI.logManager.logChannelSources.includes(message.source)) {
+            this._hasNonDefaultLogChannelMessage = true;
+            this.dispatchEventToListeners(WI.ContentView.Event.NavigationItemsDidChange);
+            this._scopeBar.item(WI.LogContentView.Scopes.Infos).hidden = false;
+            this._scopeBar.item(WI.LogContentView.Scopes.Debugs).hidden = false;
+        }
 
-        this._logViewController.appendConsoleMessage(event.data.message);
+        this._logViewController.appendConsoleMessage(message);
     }
 
     _previousMessageRepeatCountUpdated(event)
@@ -740,33 +776,52 @@ WI.LogContentView = class LogContentView extends WI.ContentView
         }
     }
 
+    _messageShouldBeVisible(message)
+    {
+        let messageSource = this._messageSourceBar && this._scopeFromMessageSource(message.source);
+        if (messageSource && !this._messageSourceBar.item(messageSource).selected && !this._messageSourceBar.item(WI.LogContentView.Scopes.AllChannels).selected)
+            return false;
+
+        let messageLevel = this._scopeFromMessageLevel(message.level);
+        if (messageLevel)
+            return this._scopeBar.item(messageLevel).selected || this._scopeBar.item(WI.LogContentView.Scopes.All).selected;
+
+        return true;
+    }
+
+    _messageSourceBarSelectionDidChange(event)
+    {
+        let selectedItem = this._messageSourceBar.selectedItems[0];
+        if (selectedItem.id === WI.LogContentView.Scopes.AllChannels) {
+            for (let item of this._messageSourceBar.items)
+                item.element.classList.remove("unread");
+        } else
+            selectedItem.element.classList.remove("unread");
+
+        this._filterMessageElements(this._allMessageElements());
+    }
+
     _scopeBarSelectionDidChange(event)
     {
-        var item = this._scopeBar.selectedItems[0];
+        let selectedItem = this._scopeBar.selectedItems[0];
 
-        if (item.id === WI.LogContentView.Scopes.All) {
-            for (var item of this._scopeBar.items)
+        if (selectedItem.id === WI.LogContentView.Scopes.All) {
+            for (let item of this._scopeBar.items)
                 item.element.classList.remove("unread");
         } else
-            item.element.classList.remove("unread");
+            selectedItem.element.classList.remove("unread");
 
         this._filterMessageElements(this._allMessageElements());
     }
 
     _filterMessageElements(messageElements)
     {
-        var showsAll = this._scopeBar.item(WI.LogContentView.Scopes.All).selected;
-
         messageElements.forEach(function(messageElement) {
-            var visible = showsAll || messageElement.__commandView instanceof WI.ConsoleCommandView || messageElement.__message instanceof WI.ConsoleCommandResultMessage;
-            if (!visible) {
-                var messageLevel = this._scopeFromMessageLevel(messageElement.__message.level);
-
-                if (messageLevel)
-                    visible = this._scopeBar.item(messageLevel).selected;
-            }
+            let visible = messageElement.__commandView instanceof WI.ConsoleCommandView || messageElement.__message instanceof WI.ConsoleCommandResultMessage;
+            if (!visible)
+                visible = this._messageShouldBeVisible(messageElement.__message);
 
-            var classList = messageElement.classList;
+            let classList = messageElement.classList;
             if (visible)
                 classList.remove(WI.LogContentView.FilteredOutStyleClassName);
             else {
@@ -1080,7 +1135,12 @@ WI.LogContentView.Scopes = {
     All: "log-all",
     Errors: "log-errors",
     Warnings: "log-warnings",
-    Logs: "log-logs"
+    Logs: "log-logs",
+    Infos: "log-infos",
+    Debugs: "log-debugs",
+    AllChannels: "log-all-channels",
+    Media: "log-media",
+    WebRTC: "log-webrtc",
 };
 
 WI.LogContentView.ItemWrapperStyleClassName = "console-item";
index 1658cee..41ea977 100644 (file)
@@ -25,7 +25,7 @@
 
 WI.ScopeBarItem = class ScopeBarItem extends WI.Object
 {
-    constructor(id, label, exclusive, className)
+    constructor(id, label, exclusive, className, hidden)
     {
         super();
 
@@ -39,10 +39,12 @@ WI.ScopeBarItem = class ScopeBarItem extends WI.Object
         this._id = id;
         this._label = label;
         this._exclusive = exclusive;
+        this._hidden = !!hidden;
 
         this._selectedSetting = new WI.Setting("scopebaritem-" + id, false);
 
         this._element.classList.toggle("selected", this._selectedSetting.value);
+        this._element.classList.toggle("hidden", this._hidden);
     }
 
     // Public
@@ -88,6 +90,21 @@ WI.ScopeBarItem = class ScopeBarItem extends WI.Object
         this.dispatchEventToListeners(WI.ScopeBarItem.Event.SelectionChanged, {withModifier});
     }
 
+    get hidden()
+    {
+        return this._hidden;
+    }
+
+    set hidden(flag)
+    {
+        if (this._hidden === flag)
+            return;
+
+        this._hidden = flag;
+
+        this._element.classList.toggle("hidden", flag);
+    }
+
     // Private
 
     _handleMouseDown(event)
index 38c4d54..4f45f4a 100644 (file)
@@ -229,6 +229,28 @@ WI.SettingsTabContentView = class SettingsTabContentView extends WI.TabContentVi
         zoomEditor.addEventListener(WI.SettingEditor.Event.ValueDidChange, () => { WI.setZoomFactor(zoomEditor.value); });
         WI.settings.zoomFactor.addEventListener(WI.Setting.Event.Changed, () => { zoomEditor.value = WI.getZoomFactor().maxDecimals(2); });
 
+        if (WI.LogManager.supportsLogChannels()) {
+            const logLevels = [
+                [WI.LoggingChannel.Level.Off, WI.UIString("Off")],
+                [WI.LoggingChannel.Level.Log, WI.UIString("Log")],
+                [WI.LoggingChannel.Level.Error, WI.UIString("Error")],
+                [WI.LoggingChannel.Level.Warning, WI.UIString("Warning")],
+                [WI.LoggingChannel.Level.Info, WI.UIString("Info")],
+                [WI.LoggingChannel.Level.Debug, WI.UIString("Debug")],
+            ];
+            const editorLabels = {
+                media: WI.UIString("Media Logging:"),
+                webrtc: WI.UIString("WebRTC Logging:"),
+            };
+
+            let channels = WI.logManager.customLoggingChannels;
+            for (let channel of channels) {
+                let logEditor = generalSettingsView.addGroupWithCustomSetting(editorLabels[channel.source], WI.SettingEditor.Type.Select, {values: logLevels});
+                logEditor.value = channel.level;
+                logEditor.addEventListener(WI.SettingEditor.Event.ValueDidChange, () => { ConsoleAgent.setLoggingChannelLevel(channel.source, logEditor.value); });
+            }
+        }
+
         this.addSettingsView(generalSettingsView);
     }
 
index 9052b01..d3475be 100644 (file)
@@ -1,3 +1,14 @@
+2017-10-24  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Enable WebKit logging configuration and display
+        https://bugs.webkit.org/show_bug.cgi?id=177027
+        <rdar://problem/33964767>
+
+        Reviewed by Joseph Pecoraro.
+
+        * WebCoreSupport/WebChromeClient.mm:
+        (stringForMessageSource): Deal with Media and WebRTC message sources.
+
 2017-10-20  Antoine Quint  <graouts@apple.com>
 
         [Web Animations] Provide basic timeline and animation interfaces
index aa368f8..e29e932 100644 (file)
@@ -116,6 +116,8 @@ NSString *WebConsoleMessageCSSMessageSource = @"CSSMessageSource";
 NSString *WebConsoleMessageSecurityMessageSource = @"SecurityMessageSource";
 NSString *WebConsoleMessageContentBlockerMessageSource = @"ContentBlockerMessageSource";
 NSString *WebConsoleMessageOtherMessageSource = @"OtherMessageSource";
+NSString *WebConsoleMessageMediaMessageSource = @"MediaMessageSource";
+NSString *WebConsoleMessageWebRTCMessageSource = @"WebRTCMessageSource";
 
 NSString *WebConsoleMessageDebugMessageLevel = @"DebugMessageLevel";
 NSString *WebConsoleMessageLogMessageLevel = @"LogMessageLevel";
@@ -391,6 +393,10 @@ inline static NSString *stringForMessageSource(MessageSource source)
         return WebConsoleMessageContentBlockerMessageSource;
     case MessageSource::Other:
         return WebConsoleMessageOtherMessageSource;
+    case MessageSource::Media:
+        return WebConsoleMessageMediaMessageSource;
+    case MessageSource::WebRTC:
+        return WebConsoleMessageWebRTCMessageSource;
     }
     ASSERT_NOT_REACHED();
     return @"";
index 1fdf8d7..adb26ab 100644 (file)
@@ -1,3 +1,24 @@
+2017-10-24  Eric Carlson  <eric.carlson@apple.com>
+
+        Web Inspector: Enable WebKit logging configuration and display
+        https://bugs.webkit.org/show_bug.cgi?id=177027
+        <rdar://problem/33964767>
+
+        Reviewed by Joseph Pecoraro.
+
+        Allow new 'dumpJSConsoleLogInStdErr' test header to redirect log console output to stderr.
+
+        * DumpRenderTree/TestOptions.h:
+        * DumpRenderTree/TestOptions.mm:
+        (TestOptions::TestOptions):
+        * DumpRenderTree/mac/DumpRenderTree.mm:
+        (runTest):
+        * WebKitTestRunner/TestController.cpp:
+        (WTR::updateTestOptionsFromTestHeader):
+        (WTR::TestController::runTest):
+        * WebKitTestRunner/TestOptions.h:
+        (WTR::TestOptions::hasSameInitializationOptions const):
+
 2017-10-24  Alex Christensen  <achristensen@webkit.org>
 
         Apply custom header fields from WebsitePolicies to same-domain requests
index 0f67d19..04df4cc 100644 (file)
@@ -38,6 +38,7 @@ struct TestOptions {
     bool layerBackedWebView { false };
     bool enableIsSecureContextAttribute { true };
     bool enableInspectorAdditions { false };
+    bool dumpJSConsoleLogInStdErr { false };
 
     TestOptions(NSURL*, const TestCommand&);
     bool webViewIsCompatibleWithOptions(const TestOptions&) const;
index 3c4f26f..e978367 100644 (file)
@@ -96,6 +96,8 @@ TestOptions::TestOptions(NSURL *testURL, const TestCommand& command)
             this->enableIsSecureContextAttribute = parseBooleanTestHeaderValue(value);
         else if (key == "enableInspectorAdditions")
             this->enableInspectorAdditions = parseBooleanTestHeaderValue(value);
+        else if (key == "dumpJSConsoleLogInStdErr")
+            this->dumpJSConsoleLogInStdErr = parseBooleanTestHeaderValue(value);
         pairStart = pairEnd + 1;
     }
 }
index 0251f98..7132a45 100644 (file)
@@ -1964,7 +1964,7 @@ static void runTest(const string& inputLine)
     gTestRunner = TestRunner::create(testURL, command.expectedPixelHash);
     gTestRunner->setAllowedHosts(allowedHosts);
     gTestRunner->setCustomTimeout(command.timeout);
-    gTestRunner->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr);
+    gTestRunner->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr || options.dumpJSConsoleLogInStdErr);
     topLoadingFrame = nil;
 #if !PLATFORM(IOS)
     ASSERT(!draggingInfo); // the previous test should have called eventSender.mouseUp to drop!
index 3c59f62..801be72 100644 (file)
@@ -1051,6 +1051,8 @@ static void updateTestOptionsFromTestHeader(TestOptions& testOptions, const std:
             testOptions.enableIsSecureContextAttribute = parseBooleanTestHeaderValue(value);
         if (key == "enableInspectorAdditions")
             testOptions.enableInspectorAdditions = parseBooleanTestHeaderValue(value);
+        if (key == "dumpJSConsoleLogInStdErr")
+            testOptions.dumpJSConsoleLogInStdErr = parseBooleanTestHeaderValue(value);
         pairStart = pairEnd + 1;
     }
 }
@@ -1190,7 +1192,7 @@ bool TestController::runTest(const char* inputLine)
         m_currentInvocation->setIsPixelTest(command.expectedPixelHash);
     if (command.timeout > 0)
         m_currentInvocation->setCustomTimeout(command.timeout);
-    m_currentInvocation->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr);
+    m_currentInvocation->setDumpJSConsoleLogInStdErr(command.dumpJSConsoleLogInStdErr || options.dumpJSConsoleLogInStdErr);
 
     platformWillRunTest(*m_currentInvocation);
 
index 6cdcb22..f60951b 100644 (file)
@@ -51,6 +51,7 @@ struct TestOptions {
     bool enableIsSecureContextAttribute { true };
     bool enableInspectorAdditions { false };
     bool shouldShowTouches { false };
+    bool dumpJSConsoleLogInStdErr { false };
 
     float deviceScaleFactor { 1 };
     Vector<String> overrideLanguages;
@@ -74,7 +75,8 @@ struct TestOptions {
             || enablePointerLock != options.enablePointerLock
             || enableCredentialManagement != options.enableCredentialManagement
             || enableIsSecureContextAttribute != options.enableIsSecureContextAttribute
-            || enableInspectorAdditions != options.enableInspectorAdditions)
+            || enableInspectorAdditions != options.enableInspectorAdditions
+            || dumpJSConsoleLogInStdErr != options.dumpJSConsoleLogInStdErr)
             return false;
 
         return true;