<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head><meta http-equiv="content-type" content="text/html; charset=utf-8" />
<title>[189373] trunk</title>
</head>
<body>

<style type="text/css"><!--
#msg dl.meta { border: 1px #006 solid; background: #369; padding: 6px; color: #fff; }
#msg dl.meta dt { float: left; width: 6em; font-weight: bold; }
#msg dt:after { content:':';}
#msg dl, #msg dt, #msg ul, #msg li, #header, #footer, #logmsg { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt;  }
#msg dl a { font-weight: bold}
#msg dl a:link    { color:#fc3; }
#msg dl a:active  { color:#ff0; }
#msg dl a:visited { color:#cc6; }
h3 { font-family: verdana,arial,helvetica,sans-serif; font-size: 10pt; font-weight: bold; }
#msg pre { overflow: auto; background: #ffc; border: 1px #fa0 solid; padding: 6px; }
#logmsg { background: #ffc; border: 1px #fa0 solid; padding: 1em 1em 0 1em; }
#logmsg p, #logmsg pre, #logmsg blockquote { margin: 0 0 1em 0; }
#logmsg p, #logmsg li, #logmsg dt, #logmsg dd { line-height: 14pt; }
#logmsg h1, #logmsg h2, #logmsg h3, #logmsg h4, #logmsg h5, #logmsg h6 { margin: .5em 0; }
#logmsg h1:first-child, #logmsg h2:first-child, #logmsg h3:first-child, #logmsg h4:first-child, #logmsg h5:first-child, #logmsg h6:first-child { margin-top: 0; }
#logmsg ul, #logmsg ol { padding: 0; list-style-position: inside; margin: 0 0 0 1em; }
#logmsg ul { text-indent: -1em; padding-left: 1em; }#logmsg ol { text-indent: -1.5em; padding-left: 1.5em; }
#logmsg > ul, #logmsg > ol { margin: 0 0 1em 0; }
#logmsg pre { background: #eee; padding: 1em; }
#logmsg blockquote { border: 1px solid #fa0; border-left-width: 10px; padding: 1em 1em 0 1em; background: white;}
#logmsg dl { margin: 0; }
#logmsg dt { font-weight: bold; }
#logmsg dd { margin: 0; padding: 0 0 0.5em 0; }
#logmsg dd:before { content:'\00bb';}
#logmsg table { border-spacing: 0px; border-collapse: collapse; border-top: 4px solid #fa0; border-bottom: 1px solid #fa0; background: #fff; }
#logmsg table th { text-align: left; font-weight: normal; padding: 0.2em 0.5em; border-top: 1px dotted #fa0; }
#logmsg table td { text-align: right; border-top: 1px dotted #fa0; padding: 0.2em 0.5em; }
#logmsg table thead th { text-align: center; border-bottom: 1px solid #fa0; }
#logmsg table th.Corner { text-align: left; }
#logmsg hr { border: none 0; border-top: 2px dashed #fa0; height: 1px; }
#header, #footer { color: #fff; background: #636; border: 1px #300 solid; padding: 6px; }
#patch { width: 100%; }
#patch h4 {font-family: verdana,arial,helvetica,sans-serif;font-size:10pt;padding:8px;background:#369;color:#fff;margin:0;}
#patch .propset h4, #patch .binary h4 {margin:0;}
#patch pre {padding:0;line-height:1.2em;margin:0;}
#patch .diff {width:100%;background:#eee;padding: 0 0 10px 0;overflow:auto;}
#patch .propset .diff, #patch .binary .diff  {padding:10px 0;}
#patch span {display:block;padding:0 10px;}
#patch .modfile, #patch .addfile, #patch .delfile, #patch .propset, #patch .binary, #patch .copfile {border:1px solid #ccc;margin:10px 0;}
#patch ins {background:#dfd;text-decoration:none;display:block;padding:0 10px;}
#patch del {background:#fdd;text-decoration:none;display:block;padding:0 10px;}
#patch .lines, .info {color:#888;background:#fff;}
--></style>
<div id="msg">
<dl class="meta">
<dt>Revision</dt> <dd><a href="http://trac.webkit.org/projects/webkit/changeset/189373">189373</a></dd>
<dt>Author</dt> <dd>commit-queue@webkit.org</dd>
<dt>Date</dt> <dd>2015-09-04 12:53:59 -0700 (Fri, 04 Sep 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: Expand Console domain test coverage
https://bugs.webkit.org/show_bug.cgi?id=148740

Patch by Joseph Pecoraro &lt;pecoraro@apple.com&gt; on 2015-09-04
Reviewed by Brian Burg.

Source/JavaScriptCore:

* inspector/protocol/Console.json:
Update the description of this command now that it only
manipulates $0, and not $1, $2, .. $n.

Source/WebInspectorUI:

* UserInterface/Protocol/RemoteObject.js:
Add a few helpers for checking the RemoteObject type.

LayoutTests:

Test more Console domain commands and events.

* inspector/console/addInspectedNode-expected.txt: Added.
* inspector/console/addInspectedNode.html: Added.
* inspector/console/clearMessages-expected.txt: Added.
* inspector/console/clearMessages.html: Added.
* inspector/console/messageRepeatCountUpdated-expected.txt: Added.
* inspector/console/messageRepeatCountUpdated.html: Added.
* inspector/console/messagesCleared-expected.txt: Added.
* inspector/console/messagesCleared.html: Added.</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreChangeLog">trunk/Source/JavaScriptCore/ChangeLog</a></li>
<li><a href="#trunkSourceJavaScriptCoreinspectorprotocolConsolejson">trunk/Source/JavaScriptCore/inspector/protocol/Console.json</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceProtocolRemoteObjectjs">trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsinspectorconsoleaddInspectedNodeexpectedtxt">trunk/LayoutTests/inspector/console/addInspectedNode-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorconsoleaddInspectedNodehtml">trunk/LayoutTests/inspector/console/addInspectedNode.html</a></li>
<li><a href="#trunkLayoutTestsinspectorconsoleclearMessagesexpectedtxt">trunk/LayoutTests/inspector/console/clearMessages-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorconsoleclearMessageshtml">trunk/LayoutTests/inspector/console/clearMessages.html</a></li>
<li><a href="#trunkLayoutTestsinspectorconsolemessageRepeatCountUpdatedexpectedtxt">trunk/LayoutTests/inspector/console/messageRepeatCountUpdated-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorconsolemessageRepeatCountUpdatedhtml">trunk/LayoutTests/inspector/console/messageRepeatCountUpdated.html</a></li>
<li><a href="#trunkLayoutTestsinspectorconsolemessagesClearedexpectedtxt">trunk/LayoutTests/inspector/console/messagesCleared-expected.txt</a></li>
<li><a href="#trunkLayoutTestsinspectorconsolemessagesClearedhtml">trunk/LayoutTests/inspector/console/messagesCleared.html</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (189372 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-09-04 19:52:15 UTC (rev 189372)
+++ trunk/LayoutTests/ChangeLog        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -1,3 +1,21 @@
</span><ins>+2015-09-04  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Expand Console domain test coverage
+        https://bugs.webkit.org/show_bug.cgi?id=148740
+
+        Reviewed by Brian Burg.
+
+        Test more Console domain commands and events.
+
+        * inspector/console/addInspectedNode-expected.txt: Added.
+        * inspector/console/addInspectedNode.html: Added.
+        * inspector/console/clearMessages-expected.txt: Added.
+        * inspector/console/clearMessages.html: Added.
+        * inspector/console/messageRepeatCountUpdated-expected.txt: Added.
+        * inspector/console/messageRepeatCountUpdated.html: Added.
+        * inspector/console/messagesCleared-expected.txt: Added.
+        * inspector/console/messagesCleared.html: Added.
+
</ins><span class="cx"> 2015-09-04  Jer Noble  &lt;jer.noble@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed gardening; enabling media/ and http/tests/media/ tests (with expected failures) on ios-simulator
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorconsoleaddInspectedNodeexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/addInspectedNode-expected.txt (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/addInspectedNode-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/console/addInspectedNode-expected.txt        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,21 @@
</span><ins>+Test for the Console.addInspectedNode command.
+
+
+== Running test suite: Console.addInspectedNode
+-- Running test case: Check$0IsUndefined
+PASS: $0 should be undefined.
+
+-- Running test case: SetAndCheckNodeA
+PASS: $0 should be a node.
+PASS: $0 should be Node A.
+
+-- Running test case: SetBadNodeId
+PASS: Should be an error
+PASS: $0 should be a node.
+PASS: $0 should be Node A.
+
+-- Running test case: SetAndCheckNodeB
+PASS: $0 should be a node.
+PASS: $0 should not be Node A.
+PASS: $0 should be Node B.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorconsoleaddInspectedNodehtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/addInspectedNode.html (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/addInspectedNode.html                                (rev 0)
+++ trunk/LayoutTests/inspector/console/addInspectedNode.html        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,104 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function test()
+{
+    function evaluate$0(callback) {
+        const objectGroup = &quot;test&quot;;
+        const includeCommandLineAPI = true;
+        const ignorePauseOnExceptionsAndMute = false;
+        const shouldReturnByValue = false;
+        const shouldGeneratePreview = false;
+        const shouldSaveResult = false;
+        WebInspector.runtimeManager.evaluateInInspectedWindow(&quot;$0&quot;, objectGroup, includeCommandLineAPI, ignorePauseOnExceptionsAndMute, shouldReturnByValue, shouldGeneratePreview, shouldSaveResult, callback);
+    }
+
+    let nodeA, nodeB;
+
+    let suite = InspectorTest.createAsyncSuite(&quot;Console.addInspectedNode&quot;);
+
+    suite.addTestCase({
+        name: &quot;Check$0IsUndefined&quot;,
+        description: &quot;No inspected node yet, $0 should be undefined.&quot;,
+        test: (resolve, reject) =&gt; {
+            evaluate$0((remoteObject) =&gt; {
+                InspectorTest.expectThat(remoteObject.isUndefined(), &quot;$0 should be undefined.&quot;);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;SetAndCheckNodeA&quot;,
+        description: &quot;Set the inspected node to be Node A and check that $0 is Node A.&quot;,
+        test: (resolve, reject) =&gt; {
+            ConsoleAgent.addInspectedNode(nodeA.id);
+            evaluate$0((remoteObject) =&gt; {
+                remoteObject.pushNodeToFrontend((nodeId) =&gt; {
+                    InspectorTest.expectThat(remoteObject.isNode(), &quot;$0 should be a node.&quot;);
+                    InspectorTest.expectThat(nodeId === nodeA.id, &quot;$0 should be Node A.&quot;);
+                    resolve();
+                });
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;SetBadNodeId&quot;,
+        description: &quot;If an invalid inspected node is set, it should not be bound to $0.&quot;,
+        test: (resolve, reject) =&gt; {
+            ConsoleAgent.addInspectedNode(999999, (error) =&gt; {
+                InspectorTest.expectThat(error, &quot;Should be an error&quot;);
+            });
+            evaluate$0((remoteObject) =&gt; {
+                remoteObject.pushNodeToFrontend((nodeId) =&gt; {
+                    InspectorTest.expectThat(remoteObject.isNode(), &quot;$0 should be a node.&quot;);
+                    InspectorTest.expectThat(nodeId === nodeA.id, &quot;$0 should be Node A.&quot;);
+                    resolve();
+                });
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;SetAndCheckNodeB&quot;,
+        description: &quot;Set the inspected node to be Node B and check that $0 is Node B.&quot;,
+        test: (resolve, reject) =&gt; {
+            ConsoleAgent.addInspectedNode(nodeB.id);
+            evaluate$0((remoteObject) =&gt; {
+                remoteObject.pushNodeToFrontend((nodeId) =&gt; {
+                    InspectorTest.expectThat(remoteObject.isNode(), &quot;$0 should be a node.&quot;);
+                    InspectorTest.expectThat(nodeId !== nodeA.id, &quot;$0 should not be Node A.&quot;);
+                    InspectorTest.expectThat(nodeId === nodeB.id, &quot;$0 should be Node B.&quot;);
+                    resolve();
+                });
+            });
+        }
+    });
+
+    // FIXME: What should $0 be after reloading / navigating the page. Should it be cleared?
+
+    WebInspector.domTreeManager.requestDocument((documentNode) =&gt; {
+        WebInspector.domTreeManager.querySelector(documentNode.id, &quot;#a&quot;, (contentNodeId) =&gt; {
+            InspectorTest.assert(contentNodeId, &quot;#a node should exist.&quot;);
+            nodeA = WebInspector.domTreeManager.nodeForId(contentNodeId);
+        });
+        WebInspector.domTreeManager.querySelector(documentNode.id, &quot;#b&quot;, (contentNodeId) =&gt; {
+            InspectorTest.assert(contentNodeId, &quot;#b node should exist.&quot;);
+            nodeB = WebInspector.domTreeManager.nodeForId(contentNodeId);
+            suite.runTestCasesAndFinish();
+        });
+    });
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;p&gt;Test for the Console.addInspectedNode command.&lt;/p&gt;
+&lt;div style=&quot;display:none&quot;&gt;
+    &lt;p id=&quot;a&quot;&gt;Node A&lt;/p&gt;
+    &lt;p id=&quot;b&quot;&gt;Node B&lt;/p&gt;
+&lt;/div&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorconsoleclearMessagesexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/clearMessages-expected.txt (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/clearMessages-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/console/clearMessages-expected.txt        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,7 @@
</span><ins>+Test for the Console.clearMessages command.
+
+
+== Running test suite: Console.clearMessages
+-- Running test case: CallClearMessages
+PASS: Cleared event should fire.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorconsoleclearMessageshtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/clearMessages.html (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/clearMessages.html                                (rev 0)
+++ trunk/LayoutTests/inspector/console/clearMessages.html        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,35 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite(&quot;Console.clearMessages&quot;);
+
+    suite.addTestCase({
+        name: &quot;CallClearMessages&quot;,
+        description: &quot;Calling the Console.clearMessages command should trigger Console.messagesCleared.&quot;,
+        test: (resolve, reject) =&gt; {
+            ConsoleAgent.clearMessages();
+
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.MessageAdded, (event) =&gt; {
+                InspectorTest.assert(false, &quot;MessageAdded event should not fire.&quot;);
+                reject();
+            });
+
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.Cleared, (event) =&gt; {
+                InspectorTest.expectThat(event, &quot;Cleared event should fire.&quot;);
+                resolve();
+            });
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;p&gt;Test for the Console.clearMessages command.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorconsolemessageRepeatCountUpdatedexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/messageRepeatCountUpdated-expected.txt (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/messageRepeatCountUpdated-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/console/messageRepeatCountUpdated-expected.txt        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,66 @@
</span><ins>+CONSOLE MESSAGE: line 1: test message
+CONSOLE MESSAGE: line 1: test message
+CONSOLE MESSAGE: line 1: test message
+CONSOLE MESSAGE: line 1: test message
+CONSOLE MESSAGE: line 1: test message
+CONSOLE MESSAGE: line 1: test message
+CONSOLE MESSAGE: line 1: different message
+CONSOLE MESSAGE: line 1: different message
+CONSOLE MESSAGE: line 1: test message
+CONSOLE MESSAGE: line 1: equal parameter values
+CONSOLE MESSAGE: line 1: equal parameter values
+CONSOLE MESSAGE: line 1: object
+CONSOLE MESSAGE: line 1: object
+CONSOLE MESSAGE: line 1: level
+CONSOLE MESSAGE: line 1: level
+Test for the Console.messageRepeatCountUpdated event.
+
+
+== Running test suite: Console.messageRepeatCountUpdated
+-- Running test case: AddTestMessage
+PASS: MessageAdded event should fire.
+PASS: ConsoleMessage repeatCount is 1.
+
+-- Running test case: RepeatTestMessage1
+PASS: PreviousMessageRepeatCountUpdated should fire.
+PASS: Count should be 2.
+
+-- Running test case: RepeatTestMessage2
+PASS: PreviousMessageRepeatCountUpdated should fire.
+PASS: Count should be 3.
+
+-- Running test case: RepeatTestMessage3
+PASS: PreviousMessageRepeatCountUpdated should fire.
+PASS: Count should be 4.
+
+-- Running test case: RepeatTestMessage4
+PASS: PreviousMessageRepeatCountUpdated should fire.
+PASS: Count should be 5.
+
+-- Running test case: RepeatTestMessage5
+PASS: PreviousMessageRepeatCountUpdated should fire.
+PASS: Count should be 6.
+
+-- Running test case: AddDifferentMessage
+PASS: MessageAdded event should fire.
+PASS: ConsoleMessage repeatCount is 1.
+
+-- Running test case: RepeatDifferentMessage
+PASS: PreviousMessageRepeatCountUpdated should fire.
+PASS: Count should be 2.
+
+-- Running test case: AddTestMessageAgain
+PASS: MessageAdded event should fire.
+PASS: ConsoleMessage repeatCount is 1.
+
+-- Running test case: MessagesWithEqualValuesRepeats
+PASS: PreviousMessageRepeatCountUpdated should fire for repeat messages with equal values.
+
+-- Running test case: MessagesWithObjectsDoNotRepeat
+PASS: MessageAdded event should fire.
+PASS: MessageAdded event should fire.
+
+-- Running test case: MessagesWithDifferentLevelsDoNotRepeat
+PASS: MessageAdded event should fire.
+PASS: MessageAdded event should fire.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorconsolemessageRepeatCountUpdatedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/messageRepeatCountUpdated.html (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/messageRepeatCountUpdated.html                                (rev 0)
+++ trunk/LayoutTests/inspector/console/messageRepeatCountUpdated.html        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,190 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function test()
+{
+    const testMessage = &quot;console.log('test message')&quot;;
+    const differentMessage = &quot;console.log('different message')&quot;;
+
+    let suite = InspectorTest.createAsyncSuite(&quot;Console.messageRepeatCountUpdated&quot;);
+
+    suite.addTestCase({
+        name: &quot;AddTestMessage&quot;,
+        description: &quot;Add a new message, it should have a single repeat count.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.evaluateInPage(testMessage);
+
+            let listener = WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                InspectorTest.assert(false, &quot;Should not fire PreviousMessageRepeatCountUpdated yet.&quot;);
+                reject();
+            });
+
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.MessageAdded, (event) =&gt; {
+                InspectorTest.expectThat(event.data.message instanceof WebInspector.ConsoleMessage, &quot;MessageAdded event should fire.&quot;);
+                InspectorTest.expectThat(event.data.message.repeatCount === 1, &quot;ConsoleMessage repeatCount is 1.&quot;);
+                WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, listener, null);
+                resolve();
+            });
+        }
+    });
+
+    for (let i = 1; i &lt;= 5; ++i) {
+        suite.addTestCase({
+            name: `RepeatTestMessage${i}`,
+            description: &quot;Repeat the last message, it should trigger messageRepeatCountUpdated.&quot;,
+            test: (resolve, reject) =&gt; {
+                InspectorTest.evaluateInPage(testMessage);
+
+                let listener = WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.MessageAdded, (event) =&gt; {
+                    InspectorTest.assert(false, &quot;Should not fire MessageAdded, this should be a repeat.&quot;);
+                    reject();
+                });
+
+                WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                    InspectorTest.expectThat(event, &quot;PreviousMessageRepeatCountUpdated should fire.&quot;);
+                    InspectorTest.expectThat(event.data.count === (i + 1), `Count should be ${i + 1}.`);
+                    WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.MessageAdded, listener, null);
+                    resolve();
+                });
+            }
+        });
+    }
+
+    suite.addTestCase({
+        name: &quot;AddDifferentMessage&quot;,
+        description: &quot;Add a different message, it should reset the repeat count.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.evaluateInPage(differentMessage);
+
+            let listener = WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                InspectorTest.assert(false, &quot;Should not fire PreviousMessageRepeatCountUpdated, this message is different.&quot;);
+                reject();
+            });
+
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.MessageAdded, (event) =&gt; {
+                InspectorTest.expectThat(event.data.message instanceof WebInspector.ConsoleMessage, &quot;MessageAdded event should fire.&quot;);
+                InspectorTest.expectThat(event.data.message.repeatCount === 1, &quot;ConsoleMessage repeatCount is 1.&quot;);
+                WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, listener, null);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;RepeatDifferentMessage&quot;,
+        description: &quot;Repeat this different message, it should increment the repeat count.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.evaluateInPage(differentMessage);
+
+            let listener = WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.MessageAdded, (event) =&gt; {
+                InspectorTest.assert(false, &quot;Should not fire MessageAdded, this should be a repeat.&quot;);
+                reject();
+            });
+
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                InspectorTest.expectThat(event, &quot;PreviousMessageRepeatCountUpdated should fire.&quot;);
+                InspectorTest.expectThat(event.data.count === 2, &quot;Count should be 2.&quot;);
+                WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.MessageAdded, listener, null);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;AddTestMessageAgain&quot;,
+        description: &quot;Add the original message again, it should have a single repeat count.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.evaluateInPage(testMessage);
+
+            let listener = WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                InspectorTest.assert(false, &quot;Should not fire PreviousMessageRepeatCountUpdated yet.&quot;);
+                reject();
+            });
+
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.MessageAdded, (event) =&gt; {
+                InspectorTest.expectThat(event.data.message instanceof WebInspector.ConsoleMessage, &quot;MessageAdded event should fire.&quot;);
+                InspectorTest.expectThat(event.data.message.repeatCount === 1, &quot;ConsoleMessage repeatCount is 1.&quot;);
+                WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, listener, null);
+                resolve();
+            });
+        }
+    });
+
+    // --------
+
+    suite.addTestCase({
+        name: &quot;MessagesWithEqualValuesRepeats&quot;,
+        description: &quot;Repeat messages with equal values should trigger messageRepeatCountUpdated.&quot;,
+        test: (resolve, reject) =&gt; {
+            const messageWithValues = &quot;console.log('equal parameter values', 1, 2)&quot;;
+            InspectorTest.evaluateInPage(messageWithValues);
+            InspectorTest.evaluateInPage(messageWithValues);
+
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                InspectorTest.expectThat(event, &quot;PreviousMessageRepeatCountUpdated should fire for repeat messages with equal values.&quot;);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;MessagesWithObjectsDoNotRepeat&quot;,
+        description: &quot;Repeat messages with objects should not trigger messageRepeatCountUpdated.&quot;,
+        test: (resolve, reject) =&gt; {
+            const messageWithObject = &quot;console.log('object', window)&quot;;
+            InspectorTest.evaluateInPage(messageWithObject);
+            InspectorTest.evaluateInPage(messageWithObject);
+
+            let repeatListener = WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                InspectorTest.assert(false, &quot;PreviousMessageRepeatCountUpdated should not fire for repeat messages with object arguments.&quot;);
+                reject();
+            });
+
+            let remaining = 2;
+            WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.MessageAdded, function addListener(event) {
+                InspectorTest.expectThat(event.data.message instanceof WebInspector.ConsoleMessage, &quot;MessageAdded event should fire.&quot;);
+                remaining--;
+                if (!remaining) {
+                    WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, repeatListener, null);
+                    WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.MessageAdded, addListener, null);
+                    resolve();
+                }                
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;MessagesWithDifferentLevelsDoNotRepeat&quot;,
+        description: &quot;Repeat messages with different levels should not trigger messageRepeatCountUpdated.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.evaluateInPage(&quot;console.warn('level')&quot;);
+            InspectorTest.evaluateInPage(&quot;console.error('level')&quot;);
+
+            let repeatListener = WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, (event) =&gt; {
+                InspectorTest.assert(false, &quot;PreviousMessageRepeatCountUpdated should not fire for repeat messages with different levels.&quot;);
+                reject();
+            });
+
+            let remaining = 2;
+            WebInspector.logManager.addEventListener(WebInspector.LogManager.Event.MessageAdded, function addListener(event) {
+                InspectorTest.expectThat(event.data.message instanceof WebInspector.ConsoleMessage, &quot;MessageAdded event should fire.&quot;);
+                remaining--;
+                if (!remaining) {
+                    WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.PreviousMessageRepeatCountUpdated, repeatListener, null);
+                    WebInspector.logManager.removeEventListener(WebInspector.LogManager.Event.MessageAdded, addListener, null);
+                    resolve();
+                }                
+            });
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;p&gt;Test for the Console.messageRepeatCountUpdated event.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorconsolemessagesClearedexpectedtxt"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/messagesCleared-expected.txt (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/messagesCleared-expected.txt                                (rev 0)
+++ trunk/LayoutTests/inspector/console/messagesCleared-expected.txt        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,16 @@
</span><ins>+Test for the Console.messagesCleared event.
+
+
+== Running test suite: Console.messagesCleared
+-- Running test case: ClearViaConsoleClearMessagesAPI
+PASS: Cleared event should fire.
+
+-- Running test case: ClearViaConsoleAPI
+PASS: Cleared event should fire.
+
+-- Running test case: ClearViaCommandLineAPI
+PASS: Cleared event should fire.
+
+-- Running test case: ClearViaPageReload
+PASS: Cleared event should fire.
+
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectorconsolemessagesClearedhtml"></a>
<div class="addfile"><h4>Added: trunk/LayoutTests/inspector/console/messagesCleared.html (0 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/console/messagesCleared.html                                (rev 0)
+++ trunk/LayoutTests/inspector/console/messagesCleared.html        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -0,0 +1,71 @@
</span><ins>+&lt;!doctype html&gt;
+&lt;html&gt;
+&lt;head&gt;
+&lt;script src=&quot;../../http/tests/inspector/resources/inspector-test.js&quot;&gt;&lt;/script&gt;
+&lt;script&gt;
+function test()
+{
+    let suite = InspectorTest.createAsyncSuite(&quot;Console.messagesCleared&quot;);
+
+    suite.addTestCase({
+        name: &quot;ClearViaConsoleClearMessagesAPI&quot;,
+        description: &quot;Calling Console.clearMessages should trigger Console.messagesCleared.&quot;,
+        test: (resolve, reject) =&gt; {
+            ConsoleAgent.clearMessages();
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.Cleared, (event) =&gt; {
+                InspectorTest.expectThat(event, &quot;Cleared event should fire.&quot;);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;ClearViaConsoleAPI&quot;,
+        description: &quot;Calling console.clear() should trigger Console.messagesCleared.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.evaluateInPage(&quot;console.clear()&quot;);
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.Cleared, (event) =&gt; {
+                InspectorTest.expectThat(event, &quot;Cleared event should fire.&quot;);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;ClearViaCommandLineAPI&quot;,
+        description: &quot;Calling `clear()` in the command line API should trigger Console.messagesCleared.&quot;,
+        test: (resolve, reject) =&gt; {
+            const objectGroup = &quot;test&quot;;
+            const includeCommandLineAPI = true;
+            const ignorePauseOnExceptionsAndMute = false;
+            const shouldReturnByValue = false;
+            const shouldGeneratePreview = false;
+            const shouldSaveResult = false;
+            WebInspector.runtimeManager.evaluateInInspectedWindow(&quot;clear()&quot;, objectGroup, includeCommandLineAPI, ignorePauseOnExceptionsAndMute, shouldReturnByValue, shouldGeneratePreview, shouldSaveResult, function(){});
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.Cleared, (event) =&gt; {
+                InspectorTest.expectThat(event, &quot;Cleared event should fire.&quot;);
+                resolve();
+            });
+        }
+    });
+
+    suite.addTestCase({
+        name: &quot;ClearViaPageReload&quot;,
+        description: &quot;Reloading the page should trigger Console.messagesCleared.&quot;,
+        test: (resolve, reject) =&gt; {
+            InspectorTest.reloadPage();
+            WebInspector.logManager.singleFireEventListener(WebInspector.LogManager.Event.Cleared, (event) =&gt; {
+                InspectorTest.expectThat(event, &quot;Cleared event should fire.&quot;);
+                resolve();
+            });
+        }
+    });
+
+    suite.runTestCasesAndFinish();
+}
+&lt;/script&gt;
+&lt;/head&gt;
+&lt;body onload=&quot;runTest()&quot;&gt;
+&lt;p&gt;Test for the Console.messagesCleared event.&lt;/p&gt;
+&lt;/body&gt;
+&lt;/html&gt;
</ins></span></pre></div>
<a id="trunkSourceJavaScriptCoreChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/ChangeLog (189372 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/ChangeLog        2015-09-04 19:52:15 UTC (rev 189372)
+++ trunk/Source/JavaScriptCore/ChangeLog        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -1,5 +1,16 @@
</span><span class="cx"> 2015-09-04  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: Expand Console domain test coverage
+        https://bugs.webkit.org/show_bug.cgi?id=148740
+
+        Reviewed by Brian Burg.
+
+        * inspector/protocol/Console.json:
+        Update the description of this command now that it only
+        manipulates $0, and not $1, $2, .. $n.
+
+2015-09-04  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: Test RuntimeAgent.parse, detecting if a script parse error is recoverable
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=148790
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceJavaScriptCoreinspectorprotocolConsolejson"></a>
<div class="modfile"><h4>Modified: trunk/Source/JavaScriptCore/inspector/protocol/Console.json (189372 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/JavaScriptCore/inspector/protocol/Console.json        2015-09-04 19:52:15 UTC (rev 189372)
+++ trunk/Source/JavaScriptCore/inspector/protocol/Console.json        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -61,9 +61,9 @@
</span><span class="cx">         {
</span><span class="cx">             &quot;name&quot;: &quot;addInspectedNode&quot;,
</span><span class="cx">             &quot;parameters&quot;: [
</span><del>-                { &quot;name&quot;: &quot;nodeId&quot;, &quot;$ref&quot;: &quot;DOM.NodeId&quot;, &quot;description&quot;: &quot;DOM node id to be accessible by means of $x command line API.&quot; }
</del><ins>+                { &quot;name&quot;: &quot;nodeId&quot;, &quot;$ref&quot;: &quot;DOM.NodeId&quot;, &quot;description&quot;: &quot;DOM node id to be accessible by means of $0 command line API.&quot; }
</ins><span class="cx">             ],
</span><del>-            &quot;description&quot;: &quot;Enables console to refer to the node with given id via $x (see Command Line API for more details $x functions).&quot;
</del><ins>+            &quot;description&quot;: &quot;Enables console to refer to the node with given id via $0 (see Command Line API for more details).&quot;
</ins><span class="cx">         }
</span><span class="cx">     ],
</span><span class="cx">     &quot;events&quot;: [
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (189372 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-09-04 19:52:15 UTC (rev 189372)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -1,3 +1,13 @@
</span><ins>+2015-09-04  Joseph Pecoraro  &lt;pecoraro@apple.com&gt;
+
+        Web Inspector: Expand Console domain test coverage
+        https://bugs.webkit.org/show_bug.cgi?id=148740
+
+        Reviewed by Brian Burg.
+
+        * UserInterface/Protocol/RemoteObject.js:
+        Add a few helpers for checking the RemoteObject type.
+
</ins><span class="cx"> 2015-09-02  Commit Queue  &lt;commit-queue@webkit.org&gt;
</span><span class="cx"> 
</span><span class="cx">         Unreviewed, rolling out r189241.
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceProtocolRemoteObjectjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js (189372 => 189373)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js        2015-09-04 19:52:15 UTC (rev 189372)
+++ trunk/Source/WebInspectorUI/UserInterface/Protocol/RemoteObject.js        2015-09-04 19:53:59 UTC (rev 189373)
</span><span class="lines">@@ -345,6 +345,16 @@
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><ins>+    isUndefined()
+    {
+        return this._type === &quot;undefined&quot;;
+    }
+
+    isNode()
+    {
+        return this._subtype === &quot;node&quot;;
+    }
+
</ins><span class="cx">     isArray()
</span><span class="cx">     {
</span><span class="cx">         return this._subtype === &quot;array&quot;;
</span></span></pre>
</div>
</div>

</body>
</html>