<!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>[188644] 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/188644">188644</a></dd>
<dt>Author</dt> <dd>bburg@apple.com</dd>
<dt>Date</dt> <dd>2015-08-19 12:09:34 -0700 (Wed, 19 Aug 2015)</dd>
</dl>

<h3>Log Message</h3>
<pre>Web Inspector: InspectorTest should be a subclass of TestHarness
https://bugs.webkit.org/show_bug.cgi?id=148079

Reviewed by Timothy Hatcher.

Source/WebInspectorUI:

Extract the frontend test harness into a subclass. Delete some code that
is now redundant. Sprinkle some ES6 syntax where possible.

Rewrite the code that redirects the Inspector page's console messages to
the test page, since it didn't appear to work any more.

* UserInterface/Test.html: Add debug options here, and a wiki link.
* UserInterface/Test/FrontendTestHarness.js: Added.
(FrontendTestHarness):
(FrontendTestHarness.prototype.completeTest):
(FrontendTestHarness.prototype.addResult):
(FrontendTestHarness.prototype.debugLog):
(FrontendTestHarness.prototype.evaluateInPage):
(FrontendTestHarness.prototype.expectNoError):
(FrontendTestHarness.prototype.testPageDidLoad):
(FrontendTestHarness.prototype.reloadPage):
(FrontendTestHarness.prototype.redirectConsoleToTestOutput.createProxyConsoleHandler):
(FrontendTestHarness.prototype.redirectConsoleToTestOutput):
(FrontendTestHarness.prototype.reportUncaughtException):
(FrontendTestHarness.prototype._resendResults):
* UserInterface/Test/Test.js:
(WebInspector.loaded):
(WebInspector.UIString): Arrow it.
(WebInspector.updateDockedState): Arrow it.
(WebInspector.updateDockingAvailability): Arrow it.
(InspectorTest.EventDispatcher.prototype.dispatchEvent): Deleted.
(InspectorTest.EventDispatcher): Deleted.
(InspectorTest.log): Deleted.
(InspectorTest.assert): Deleted.
(InspectorTest.expectThat): Deleted.
(InspectorTest.debugLog): Deleted.
(InspectorTest.expectNoError): Deleted.
(InspectorTest.completeTest): Deleted.
(InspectorTest.evaluateInPage): Deleted.
(InspectorTest.addResult): Deleted.
(InspectorTest._resendResults): Deleted.
(InspectorTest.testPageDidLoad): Deleted.
(InspectorTest.reloadPage): Deleted.
(InspectorTest.reportUncaughtException): Deleted.
* UserInterface/Test/TestSuite.js: Clean an unnecessary self = this.
(SyncTestSuite.prototype.runTestCases):
(SyncTestSuite):
* UserInterface/TestStub.html: Add matching link to wiki.

LayoutTests:

Rename InspectorTestProxy to TestPage. Update some code style in
the harness script files to be consistent.

* http/tests/inspector/debugger/debugger-test.js:
* http/tests/inspector/dom/shapes-test.js:
* http/tests/inspector/replay/replay-test.js:
* http/tests/inspector/resources/inspector-test.js:
(TestPage.registerInitializer):
(runTest.runInitializationMethodsInFrontend):
(runTest.runTestMethodInFrontend):
(runTest):
(TestPage.completeTest):
(TestPage.debugLog):
(TestPage.addResult):
(TestPage.reportUncaughtException):
(InspectorTestProxy.registerInitializer): Deleted.
(InspectorTestProxy.completeTest): Deleted.
(InspectorTestProxy.debugLog): Deleted.
(InspectorTestProxy.addResult): Deleted.
(InspectorTestProxy.reportUncaughtException): Deleted.
* inspector/debugger/breakpoint-action-eval.html:
* inspector/debugger/resources/break-on-exception-tests.js:
* inspector/debugger/resources/script-for-breakpoint-actions.js:
(breakpointActions):
* inspector/debugger/search-scripts.html:
* inspector/replay/window-navigator-plugins-memoized.html:
* inspector/timeline/debugger-paused-while-recording.html:
* inspector/timeline/exception-in-injected-script-while-recording.html:</pre>

<h3>Modified Paths</h3>
<ul>
<li><a href="#trunkLayoutTestsChangeLog">trunk/LayoutTests/ChangeLog</a></li>
<li><a href="#trunkLayoutTestshttptestsinspectordebuggerdebuggertestjs">trunk/LayoutTests/http/tests/inspector/debugger/debugger-test.js</a></li>
<li><a href="#trunkLayoutTestshttptestsinspectordomshapestestjs">trunk/LayoutTests/http/tests/inspector/dom/shapes-test.js</a></li>
<li><a href="#trunkLayoutTestshttptestsinspectorreplayreplaytestjs">trunk/LayoutTests/http/tests/inspector/replay/replay-test.js</a></li>
<li><a href="#trunkLayoutTestshttptestsinspectorresourcesinspectortestjs">trunk/LayoutTests/http/tests/inspector/resources/inspector-test.js</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggerbreakpointactionevalhtml">trunk/LayoutTests/inspector/debugger/breakpoint-action-eval.html</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggerresourcesbreakonexceptiontestsjs">trunk/LayoutTests/inspector/debugger/resources/break-on-exception-tests.js</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggerresourcesscriptforbreakpointactionsjs">trunk/LayoutTests/inspector/debugger/resources/script-for-breakpoint-actions.js</a></li>
<li><a href="#trunkLayoutTestsinspectordebuggersearchscriptshtml">trunk/LayoutTests/inspector/debugger/search-scripts.html</a></li>
<li><a href="#trunkLayoutTestsinspectorreplaywindownavigatorpluginsmemoizedhtml">trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelinedebuggerpausedwhilerecordinghtml">trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording.html</a></li>
<li><a href="#trunkLayoutTestsinspectortimelineexceptionininjectedscriptwhilerecordinghtml">trunk/LayoutTests/inspector/timeline/exception-in-injected-script-while-recording.html</a></li>
<li><a href="#trunkSourceWebInspectorUIChangeLog">trunk/Source/WebInspectorUI/ChangeLog</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTestTestjs">trunk/Source/WebInspectorUI/UserInterface/Test/Test.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTestTestSuitejs">trunk/Source/WebInspectorUI/UserInterface/Test/TestSuite.js</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTesthtml">trunk/Source/WebInspectorUI/UserInterface/Test.html</a></li>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTestStubhtml">trunk/Source/WebInspectorUI/UserInterface/TestStub.html</a></li>
</ul>

<h3>Added Paths</h3>
<ul>
<li><a href="#trunkSourceWebInspectorUIUserInterfaceTestFrontendTestHarnessjs">trunk/Source/WebInspectorUI/UserInterface/Test/FrontendTestHarness.js</a></li>
</ul>

</div>
<div id="patch">
<h3>Diff</h3>
<a id="trunkLayoutTestsChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/ChangeLog (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/ChangeLog        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/ChangeLog        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,3 +1,39 @@
</span><ins>+2015-08-19  Brian Burg  &lt;bburg@apple.com&gt;
+
+        Web Inspector: InspectorTest should be a subclass of TestHarness
+        https://bugs.webkit.org/show_bug.cgi?id=148079
+
+        Reviewed by Timothy Hatcher.
+
+        Rename InspectorTestProxy to TestPage. Update some code style in
+        the harness script files to be consistent.
+
+        * http/tests/inspector/debugger/debugger-test.js:
+        * http/tests/inspector/dom/shapes-test.js:
+        * http/tests/inspector/replay/replay-test.js:
+        * http/tests/inspector/resources/inspector-test.js:
+        (TestPage.registerInitializer):
+        (runTest.runInitializationMethodsInFrontend):
+        (runTest.runTestMethodInFrontend):
+        (runTest):
+        (TestPage.completeTest):
+        (TestPage.debugLog):
+        (TestPage.addResult):
+        (TestPage.reportUncaughtException):
+        (InspectorTestProxy.registerInitializer): Deleted.
+        (InspectorTestProxy.completeTest): Deleted.
+        (InspectorTestProxy.debugLog): Deleted.
+        (InspectorTestProxy.addResult): Deleted.
+        (InspectorTestProxy.reportUncaughtException): Deleted.
+        * inspector/debugger/breakpoint-action-eval.html:
+        * inspector/debugger/resources/break-on-exception-tests.js:
+        * inspector/debugger/resources/script-for-breakpoint-actions.js:
+        (breakpointActions):
+        * inspector/debugger/search-scripts.html:
+        * inspector/replay/window-navigator-plugins-memoized.html:
+        * inspector/timeline/debugger-paused-while-recording.html:
+        * inspector/timeline/exception-in-injected-script-while-recording.html:
+
</ins><span class="cx"> 2015-08-19  Chris Dumez  &lt;cdumez@apple.com&gt;
</span><span class="cx"> 
</span><span class="cx">         WebKit may keep outdated entry in the disk cache after a reload
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsinspectordebuggerdebuggertestjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/inspector/debugger/debugger-test.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/inspector/debugger/debugger-test.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/http/tests/inspector/debugger/debugger-test.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-InspectorTestProxy.registerInitializer(function() {
</del><ins>+TestPage.registerInitializer(function() {
</ins><span class="cx"> 
</span><span class="cx"> InspectorTest.startTracingBreakpoints = function()
</span><span class="cx"> {
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsinspectordomshapestestjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/inspector/dom/shapes-test.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/inspector/dom/shapes-test.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/http/tests/inspector/dom/shapes-test.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-InspectorTestProxy.registerInitializer(function() {
</del><ins>+TestPage.registerInitializer(function() {
</ins><span class="cx"> 
</span><span class="cx"> InspectorTest.Shapes = {
</span><span class="cx">     getShapeOutsideInfoForSelector: function(selector, callback)
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsinspectorreplayreplaytestjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/inspector/replay/replay-test.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/inspector/replay/replay-test.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/http/tests/inspector/replay/replay-test.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-InspectorTestProxy.registerInitializer(function() {
</del><ins>+TestPage.registerInitializer(function() {
</ins><span class="cx"> 
</span><span class="cx"> InspectorTest.Replay = {};
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestshttptestsinspectorresourcesinspectortestjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/http/tests/inspector/resources/inspector-test.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/http/tests/inspector/resources/inspector-test.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/http/tests/inspector/resources/inspector-test.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -24,13 +24,13 @@
</span><span class="cx">  */
</span><span class="cx"> 
</span><span class="cx"> // This namespace is injected into every test page. Its functions are invoked by
</span><del>-// InspectorTest methods on the inspector page via RuntimeAgent.evaluate() calls.
-InspectorTestProxy = {};
-InspectorTestProxy._initializers = [];
</del><ins>+// InspectorTest methods on the inspector page via a TestHarness subclass.
+TestPage = {};
+TestPage._initializers = [];
</ins><span class="cx"> 
</span><span class="cx"> // Helper scripts like `debugger-test.js` must register their initialization
</span><span class="cx"> // function with this method so it will be marshalled to the inspector page.
</span><del>-InspectorTestProxy.registerInitializer = function(initializer)
</del><ins>+TestPage.registerInitializer = function(initializer)
</ins><span class="cx"> {
</span><span class="cx">     if (typeof initializer === &quot;function&quot;)
</span><span class="cx">         this._initializers.push(initializer.toString());
</span><span class="lines">@@ -53,6 +53,12 @@
</span><span class="cx">     window.internals.setInspectorIsUnderTest(true);
</span><span class="cx">     testRunner.showWebInspector();
</span><span class="cx"> 
</span><ins>+    let testFunction = window.test;
+    if (typeof testFunction !== &quot;function&quot;) {
+        alert(&quot;Failed to send test() because it is not a function.&quot;);
+        testRunner.notifyDone();
+    }
+
</ins><span class="cx">     function runInitializationMethodsInFrontend(initializersArray)
</span><span class="cx">     {
</span><span class="cx">         InspectorTest.testPageDidLoad();
</span><span class="lines">@@ -62,7 +68,7 @@
</span><span class="cx">         if (InspectorTest.didInjectTestCode)
</span><span class="cx">             return;
</span><span class="cx"> 
</span><del>-        for (var initializer of initializersArray) {
</del><ins>+        for (let initializer of initializersArray) {
</ins><span class="cx">             try {
</span><span class="cx">                 initializer();
</span><span class="cx">             } catch (e) {
</span><span class="lines">@@ -82,43 +88,41 @@
</span><span class="cx">         try {
</span><span class="cx">             testFunction();
</span><span class="cx">         } catch (e) {
</span><ins>+            // FIXME: the redirected console methods do not forward additional arguments.
</ins><span class="cx">             console.error(&quot;Exception during test execution: &quot; + e, e.stack || &quot;(no stack trace)&quot;);
</span><span class="cx">             InspectorTest.completeTest();
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    var codeStringToEvaluate = &quot;(&quot; + runInitializationMethodsInFrontend.toString() + &quot;)([&quot; + InspectorTestProxy._initializers + &quot;]);&quot;;
-    testRunner.evaluateInWebInspector(codeStringToEvaluate);
</del><ins>+    let initializationCodeString = `(${runInitializationMethodsInFrontend.toString()})([${TestPage._initializers}]);`;
+    let testFunctionCodeString = `(${runTestMethodInFrontend.toString()})(${testFunction.toString()});`;
</ins><span class="cx"> 
</span><del>-    // `test` refers to a function defined in global scope in the test HTML page.
-    codeStringToEvaluate = &quot;(&quot; + runTestMethodInFrontend.toString() + &quot;)(&quot; + test.toString() + &quot;);&quot;;
-    testRunner.evaluateInWebInspector(codeStringToEvaluate);
</del><ins>+    testRunner.evaluateInWebInspector(initializationCodeString);
+    testRunner.evaluateInWebInspector(testFunctionCodeString);
</ins><span class="cx"> }
</span><span class="cx"> 
</span><del>-InspectorTestProxy.completeTest = function()
</del><ins>+TestPage.completeTest = function()
</ins><span class="cx"> {
</span><span class="cx">     // Don't try to use testRunner if running through the browser.
</span><span class="cx">     if (!window.testRunner)
</span><span class="cx">         return;
</span><span class="cx"> 
</span><span class="cx">     // Close inspector asynchrously in case we want to test tear-down behavior.
</span><del>-    setTimeout(function() {
</del><ins>+    setTimeout(() =&gt; {
</ins><span class="cx">         testRunner.closeWebInspector();
</span><del>-        setTimeout(function() {
-            testRunner.notifyDone();
-        }, 0);
</del><ins>+        setTimeout(() =&gt; { testRunner.notifyDone(); }, 0);
</ins><span class="cx">     }, 0);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Logs message to unbuffered process stdout, avoiding timeouts.
</span><span class="cx"> // only be used to debug tests and not to produce normal test output.
</span><del>-InspectorTestProxy.debugLog = function(message)
</del><ins>+TestPage.debugLog = function(message)
</ins><span class="cx"> {
</span><span class="cx">     window.alert(message);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Add and clear test output from the results window.
</span><del>-InspectorTestProxy.addResult = function(text)
</del><ins>+TestPage.addResult = function(text)
</ins><span class="cx"> {
</span><span class="cx">     // For early errors triggered when loading the test page, write to stderr.
</span><span class="cx">     if (!document.body) {
</span><span class="lines">@@ -135,24 +139,24 @@
</span><span class="cx">     this._resultElement.append(text, document.createElement(&quot;br&quot;));
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-InspectorTestProxy.needToSanitizeUncaughtExceptionURLs = false;
</del><ins>+TestPage.needToSanitizeUncaughtExceptionURLs = false;
</ins><span class="cx"> 
</span><del>-InspectorTestProxy.reportUncaughtException = function(message, url, lineNumber)
</del><ins>+TestPage.reportUncaughtException = function(message, url, lineNumber)
</ins><span class="cx"> {
</span><del>-    if (InspectorTestProxy.needToSanitizeUncaughtExceptionURLs) {
-        if (typeof url == &quot;string&quot;) {
-            var lastSlash = url.lastIndexOf(&quot;/&quot;);
-            var lastBackSlash = url.lastIndexOf(&quot;\\&quot;);
-            var lastPathSeparator = Math.max(lastSlash, lastBackSlash);
</del><ins>+    if (TestPage.needToSanitizeUncaughtExceptionURLs) {
+        if (typeof url === &quot;string&quot;) {
+            let lastSlash = url.lastIndexOf(&quot;/&quot;);
+            let lastBackSlash = url.lastIndexOf(&quot;\\&quot;);
+            let lastPathSeparator = Math.max(lastSlash, lastBackSlash);
</ins><span class="cx">             if (lastPathSeparator &gt; 0)
</span><span class="cx">                 url = url.substr(lastPathSeparator + 1);
</span><span class="cx">         }
</span><span class="cx">     }
</span><span class="cx"> 
</span><del>-    var result = &quot;Uncaught exception in test page: &quot; + message + &quot; [&quot; + url + &quot;:&quot; + lineNumber + &quot;]&quot;;
-    InspectorTestProxy.addResult(result);
-    InspectorTestProxy.completeTest();
</del><ins>+    let result = `Uncaught exception in test page: ${message} [${url}:${lineNumber}]`;
+    TestPage.addResult(result);
+    TestPage.completeTest();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> // Catch syntax errors, type errors, and other exceptions. Run this before loading other files.
</span><del>-window.onerror = InspectorTestProxy.reportUncaughtException;
</del><ins>+window.onerror = TestPage.reportUncaughtException.bind(TestPage);
</ins></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerbreakpointactionevalhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/debugger/breakpoint-action-eval.html (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/breakpoint-action-eval.html        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/inspector/debugger/breakpoint-action-eval.html        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -13,8 +13,8 @@
</span><span class="cx"> 
</span><span class="cx"> function action(a, b)
</span><span class="cx"> {
</span><del>-    InspectorTestProxy.addResult(&quot;Breakpoint action evaluated. a:(&quot; + a + &quot;) b:(&quot; + b + &quot;)&quot;);
-    InspectorTestProxy.completeTest();
</del><ins>+    TestPage.addResult(&quot;Breakpoint action evaluated. a:(&quot; + a + &quot;) b:(&quot; + b + &quot;)&quot;);
+    TestPage.completeTest();
</ins><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function test()
</span></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerresourcesbreakonexceptiontestsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/debugger/resources/break-on-exception-tests.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/resources/break-on-exception-tests.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/inspector/debugger/resources/break-on-exception-tests.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,4 +1,4 @@
</span><del>-InspectorTestProxy.needToSanitizeUncaughtExceptionURLs = true;
</del><ins>+TestPage.needToSanitizeUncaughtExceptionURLs = true;
</ins><span class="cx"> 
</span><span class="cx"> var arr = [ 1, 2, 3 ];
</span><span class="cx"> var mapData = [[ &quot;a&quot;, arr ]];
</span></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggerresourcesscriptforbreakpointactionsjs"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/debugger/resources/script-for-breakpoint-actions.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/resources/script-for-breakpoint-actions.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/inspector/debugger/resources/script-for-breakpoint-actions.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> function breakpointActions(a, b)
</span><span class="cx"> {
</span><span class="cx">     // Only preserve this message on the current test page load.
</span><del>-    InspectorTestProxy.addResult(&quot;inside breakpointActions a:(&quot; + a + &quot;) b:(&quot; + b + &quot;)&quot;);
</del><ins>+    TestPage.addResult(&quot;inside breakpointActions a:(&quot; + a + &quot;) b:(&quot; + b + &quot;)&quot;);
</ins><span class="cx"> }
</span></span></pre></div>
<a id="trunkLayoutTestsinspectordebuggersearchscriptshtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/debugger/search-scripts.html (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/debugger/search-scripts.html        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/inspector/debugger/search-scripts.html        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -44,7 +44,7 @@
</span><span class="cx">         });
</span><span class="cx">     });
</span><span class="cx"> 
</span><del>-    InspectorTest.eventDispatcher.addEventListener(InspectorTest.EventDispatcher.Event.TestPageDidLoad, function() {
</del><ins>+    InspectorTest.addEventListener(FrontendTestHarness.Event.TestPageDidLoad, () =&gt; {
</ins><span class="cx">         InspectorTest.evaluateInPage(&quot;performEvals()&quot;);
</span><span class="cx">     });
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectorreplaywindownavigatorpluginsmemoizedhtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/inspector/replay/window-navigator-plugins-memoized.html        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -77,12 +77,12 @@
</span><span class="cx"> // These functions are called in the previous main frame prior to the initial
</span><span class="cx"> // navigation that begins capturing or replaying. Careful, heap state will be lost.
</span><span class="cx"> function setupPreCapture() {
</span><del>-    InspectorTestProxy.addResult(&quot;Enabling plugins before capture.&quot;);
</del><ins>+    TestPage.addResult(&quot;Enabling plugins before capture.&quot;);
</ins><span class="cx">     testRunner.setPluginsEnabled(false);
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function setupPreReplay() {
</span><del>-    InspectorTestProxy.addResult(&quot;Disabling plugins before replay.&quot;);
</del><ins>+    TestPage.addResult(&quot;Disabling plugins before replay.&quot;);
</ins><span class="cx">     testRunner.setPluginsEnabled(true);
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelinedebuggerpausedwhilerecordinghtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording.html (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording.html        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/inspector/timeline/debugger-paused-while-recording.html        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -15,13 +15,13 @@
</span><span class="cx"> 
</span><span class="cx"> function add(a, b)
</span><span class="cx"> {
</span><del>-    InspectorTestProxy.addResult(&quot;Calling add(): &quot; + a + &quot; + &quot; + b);
</del><ins>+    TestPage.addResult(&quot;Calling add(): &quot; + a + &quot; + &quot; + b);
</ins><span class="cx">     return a + b;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function mul(a, b)
</span><span class="cx"> {
</span><del>-    InspectorTestProxy.addResult(&quot;Calling mul(): &quot; + a + &quot; * &quot; + b);
</del><ins>+    TestPage.addResult(&quot;Calling mul(): &quot; + a + &quot; * &quot; + b);
</ins><span class="cx">     return a * b;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkLayoutTestsinspectortimelineexceptionininjectedscriptwhilerecordinghtml"></a>
<div class="modfile"><h4>Modified: trunk/LayoutTests/inspector/timeline/exception-in-injected-script-while-recording.html (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/LayoutTests/inspector/timeline/exception-in-injected-script-while-recording.html        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/LayoutTests/inspector/timeline/exception-in-injected-script-while-recording.html        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -15,13 +15,13 @@
</span><span class="cx"> 
</span><span class="cx"> function add(a, b)
</span><span class="cx"> {
</span><del>-    InspectorTestProxy.addResult(&quot;Calling add(): &quot; + a + &quot; + &quot; + b);
</del><ins>+    TestPage.addResult(&quot;Calling add(): &quot; + a + &quot; + &quot; + b);
</ins><span class="cx">     return a + b;
</span><span class="cx"> }
</span><span class="cx"> 
</span><span class="cx"> function mul(a, b)
</span><span class="cx"> {
</span><del>-    InspectorTestProxy.addResult(&quot;Calling mul(): &quot; + a + &quot; * &quot; + b);
</del><ins>+    TestPage.addResult(&quot;Calling mul(): &quot; + a + &quot; * &quot; + b);
</ins><span class="cx">     return a * b;
</span><span class="cx"> }
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIChangeLog"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/ChangeLog (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/ChangeLog        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/Source/WebInspectorUI/ChangeLog        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,5 +1,56 @@
</span><span class="cx"> 2015-08-19  Brian Burg  &lt;bburg@apple.com&gt;
</span><span class="cx"> 
</span><ins>+        Web Inspector: InspectorTest should be a subclass of TestHarness
+        https://bugs.webkit.org/show_bug.cgi?id=148079
+
+        Reviewed by Timothy Hatcher.
+
+        Extract the frontend test harness into a subclass. Delete some code that
+        is now redundant. Sprinkle some ES6 syntax where possible.
+
+        Rewrite the code that redirects the Inspector page's console messages to
+        the test page, since it didn't appear to work any more.
+
+        * UserInterface/Test.html: Add debug options here, and a wiki link.
+        * UserInterface/Test/FrontendTestHarness.js: Added.
+        (FrontendTestHarness):
+        (FrontendTestHarness.prototype.completeTest):
+        (FrontendTestHarness.prototype.addResult):
+        (FrontendTestHarness.prototype.debugLog):
+        (FrontendTestHarness.prototype.evaluateInPage):
+        (FrontendTestHarness.prototype.expectNoError):
+        (FrontendTestHarness.prototype.testPageDidLoad):
+        (FrontendTestHarness.prototype.reloadPage):
+        (FrontendTestHarness.prototype.redirectConsoleToTestOutput.createProxyConsoleHandler):
+        (FrontendTestHarness.prototype.redirectConsoleToTestOutput):
+        (FrontendTestHarness.prototype.reportUncaughtException):
+        (FrontendTestHarness.prototype._resendResults):
+        * UserInterface/Test/Test.js:
+        (WebInspector.loaded):
+        (WebInspector.UIString): Arrow it.
+        (WebInspector.updateDockedState): Arrow it.
+        (WebInspector.updateDockingAvailability): Arrow it.
+        (InspectorTest.EventDispatcher.prototype.dispatchEvent): Deleted.
+        (InspectorTest.EventDispatcher): Deleted.
+        (InspectorTest.log): Deleted.
+        (InspectorTest.assert): Deleted.
+        (InspectorTest.expectThat): Deleted.
+        (InspectorTest.debugLog): Deleted.
+        (InspectorTest.expectNoError): Deleted.
+        (InspectorTest.completeTest): Deleted.
+        (InspectorTest.evaluateInPage): Deleted.
+        (InspectorTest.addResult): Deleted.
+        (InspectorTest._resendResults): Deleted.
+        (InspectorTest.testPageDidLoad): Deleted.
+        (InspectorTest.reloadPage): Deleted.
+        (InspectorTest.reportUncaughtException): Deleted.
+        * UserInterface/Test/TestSuite.js: Clean an unnecessary self = this.
+        (SyncTestSuite.prototype.runTestCases):
+        (SyncTestSuite):
+        * UserInterface/TestStub.html: Add matching link to wiki.
+
+2015-08-19  Brian Burg  &lt;bburg@apple.com&gt;
+
</ins><span class="cx">         Web Inspector: split TestStub.js into multiple files and modernize it
</span><span class="cx">         https://bugs.webkit.org/show_bug.cgi?id=148077
</span><span class="cx"> 
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTestFrontendTestHarnessjs"></a>
<div class="addfile"><h4>Added: trunk/Source/WebInspectorUI/UserInterface/Test/FrontendTestHarness.js (0 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Test/FrontendTestHarness.js                                (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/FrontendTestHarness.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -0,0 +1,173 @@
</span><ins>+/*
+ * Copyright (C) 2013-2015 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 AND ITS CONTRIBUTORS &quot;AS IS&quot; 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 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.
+ */
+
+FrontendTestHarness = class FrontendTestHarness extends TestHarness
+{
+    constructor()
+    {
+        super();
+
+        this._results = [];
+        this._shouldResendResults = true;
+    }
+
+    // TestHarness Overrides
+
+    completeTest()
+    {
+        if (this.forceSyncDebugLogging)
+            InspectorFrontendHost.unbufferedLog(&quot;FrontendTestHarness.completeTest()&quot;);
+
+        // Wait for results to be resent before requesting completeTest(). Otherwise, messages will be
+        // queued after pending dispatches run to zero and the test page will quit before processing them.
+        if (this._testPageIsReloading) {
+            this._completeTestAfterReload = true;
+            return;
+        }
+
+        InspectorBackend.runAfterPendingDispatches(this.evaluateInPage.bind(this, &quot;TestPage.completeTest()&quot;));
+    }
+
+    addResult(message)
+    {
+        this._results.push(message);
+
+        if (this.forceSyncDebugLogging)
+            InspectorFrontendHost.unbufferedLog(&quot;addResult: &quot; + message);
+
+        if (!this._testPageIsReloading)
+            this.evaluateInPage(`TestPage.addResult(unescape(&quot;${escape(message)}&quot;))`);
+    }
+
+    debugLog(message)
+    {
+        let stringifiedMessage = typeof message !== &quot;string&quot; ? JSON.stringify(message) : message;
+        this.evaluateInPage(`TestPage.debugLog(unescape(&quot;${escape(stringifiedMessage)}&quot;));`);
+    }
+
+    evaluateInPage(expression, callback)
+    {
+        // If we load this page outside of the inspector, or hit an early error when loading
+        // the test frontend, then defer evaluating the commands (indefinitely in the former case).
+        if (this._originalConsole &amp;&amp; !window.RuntimeAgent) {
+            this._originalConsole[&quot;error&quot;](&quot;Tried to evaluate in test page, but connection not yet established:&quot;, expression);
+            return;
+        }
+
+        RuntimeAgent.evaluate.invoke({expression, objectGroup: &quot;test&quot;, includeCommandLineAPI: false}, callback);
+    }
+
+    // Frontend test-specific methods.
+
+    expectNoError(error)
+    {
+        if (error) {
+            InspectorTest.log(&quot;PROTOCOL ERROR: &quot; + error);
+            InspectorTest.completeTest();
+            throw &quot;PROTOCOL ERROR&quot;;
+        }
+    }
+
+    testPageDidLoad()
+    {
+        this._testPageIsReloading = false;
+        this._resendResults();
+
+        this.dispatchEventToListeners(FrontendTestHarness.Event.TestPageDidLoad);
+
+        if (this._completeTestAfterReload)
+            this.completeTest();
+    }
+
+    reloadPage(shouldIgnoreCache)
+    {
+        console.assert(!this._testPageIsReloading);
+        console.assert(!this._testPageReloadedOnce);
+
+        this._testPageIsReloading = true;
+
+        return PageAgent.reload(!!shouldIgnoreCache)
+            .then(() =&gt; {
+                this._shouldResendResults = true;
+                this._testPageReloadedOnce = true;
+
+                return Promise.resolve(null);
+            });
+    }
+
+    redirectConsoleToTestOutput()
+    {
+        // We can't use arrow functions here because of 'arguments'. It might
+        // be okay once rest parameters work.
+        let self = this;
+        function createProxyConsoleHandler(type) {
+            return function() {
+                self.addResult(`${type}: ` + Array.from(arguments).join(&quot; &quot;)); 
+            };
+        }
+
+        let redirectedMethods = {};
+        for (let key in window.console) 
+            redirectedMethods[key] = window.console[key].bind(window.console);
+
+        for (let type of [&quot;log&quot;, &quot;error&quot;, &quot;info&quot;])
+            redirectedMethods[type] = createProxyConsoleHandler(type.toUpperCase());
+
+        this._originalConsole = window.console;
+        window.console = redirectedMethods;
+    }
+
+    reportUncaughtException(message, url, lineNumber, columnNumber)
+    {
+        let result = `Uncaught exception in inspector page: ${message} [${url}:${lineNumber}:${columnNumber}]`;
+
+        // If the connection to the test page is not set up, then just dump to console and give up.
+        // Errors encountered this early can be debugged by loading Test.html in a normal browser page.
+        if (this._originalConsole &amp;&amp; (!InspectorFrontendHost || !InspectorBackend)) {
+            this._originalConsole[&quot;error&quot;](result);
+            return false;
+        }
+
+        this.addResult(result);
+        this.completeTest();
+        // Stop default handler so we can empty InspectorBackend's message queue.
+        return true;
+    }
+
+    // Private
+
+    _resendResults()
+    {
+        console.assert(this._shouldResendResults);
+        this._shouldResendResults = false;
+
+        for (let result of this._results)
+            this.evaluateInPage(`TestPage.addResult(unescape(&quot;${escape(result)}&quot;))`);
+    }
+};
+
+FrontendTestHarness.Event = {
+    TestPageDidLoad: &quot;frontend-test-test-page-did-load&quot;
+};
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTestTestjs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Test/Test.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Test/Test.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/Test.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -1,5 +1,5 @@
</span><span class="cx"> /*
</span><del>- * Copyright (C) 2013, 2014 Apple Inc. All rights reserved.
</del><ins>+ * Copyright (C) 2013-2015 Apple Inc. All rights reserved.
</ins><span class="cx">  *
</span><span class="cx">  * Redistribution and use in source and binary forms, with or without
</span><span class="cx">  * modification, are permitted provided that the following conditions
</span><span class="lines">@@ -62,7 +62,7 @@
</span><span class="cx">     // Global controllers.
</span><span class="cx">     this.quickConsole = {executionContextIdentifier: undefined};
</span><span class="cx"> 
</span><del>-    document.addEventListener(&quot;DOMContentLoaded&quot;, this.contentLoaded.bind(this));
</del><ins>+    document.addEventListener(&quot;DOMContentLoaded&quot;, this.contentLoaded);
</ins><span class="cx"> 
</span><span class="cx">     // Enable agents.
</span><span class="cx">     InspectorAgent.enable();
</span><span class="lines">@@ -85,195 +85,12 @@
</span><span class="cx">     InspectorFrontendHost.loaded();
</span><span class="cx"> }
</span><span class="cx"> 
</span><del>-WebInspector.UIString = function(string)
-{
-    return string;
-}
</del><ins>+WebInspector.UIString = (string) =&gt; string;
</ins><span class="cx"> 
</span><span class="cx"> // Add stubs that are called by the frontend API.
</span><del>-WebInspector.updateDockedState = function() {};
-WebInspector.updateDockingAvailability = function() {};
</del><ins>+WebInspector.updateDockedState = () =&gt; {};
+WebInspector.updateDockingAvailability = () =&gt; {};
</ins><span class="cx"> 
</span><del>-// InspectorTest contains extra methods that are only available to test code running
-// in the Web Inspector page. They rely on equivalents in the actual test page
-// which are provided by `inspector-test.js`.
-InspectorTest = {};
</del><ins>+window.InspectorTest = new FrontendTestHarness();
</ins><span class="cx"> 
</span><del>-// This is useful for debugging Inspector tests by synchronously logging messages.
-InspectorTest.dumpMessagesToConsole = false;
-
-// This is a workaround for the fact that it would be hard to set up a constructor,
-// prototype, and prototype chain for the singleton InspectorTest.
-InspectorTest.EventDispatcher = class EventDispatcher extends WebInspector.Object
-{
-    dispatchEvent(event)
-    {
-        this.dispatchEventToListeners(event);
-    }
-};
-
-InspectorTest.EventDispatcher.Event = {
-    TestPageDidLoad: &quot;inspector-test-test-page-did-load&quot;
-};
-
-InspectorTest.eventDispatcher = new InspectorTest.EventDispatcher;
-
-// Note: Additional InspectorTest methods are included on a per-test basis from
-// files like `debugger-test.js`.
-
-// Appends a log message in the test document.
-InspectorTest.log = function(message)
-{
-    var stringifiedMessage = typeof message !== &quot;object&quot; ? message : JSON.stringify(message);
-    InspectorTest.addResult(stringifiedMessage);
-}
-
-// Appends a message in the test document only if the condition is false.
-InspectorTest.assert = function(condition, message)
-{
-    if (condition)
-        return;
-
-    var stringifiedMessage = typeof message !== &quot;object&quot; ? message : JSON.stringify(message);
-    InspectorTest.addResult(&quot;ASSERT: &quot; + stringifiedMessage);
-}
-
-// Appends a message in the test document whether the condition is true or not.
-InspectorTest.expectThat = function(condition, message)
-{
-    var prefix = condition ? &quot;PASS&quot; : &quot;FAIL&quot;;
-    var stringifiedMessage = typeof message !== &quot;object&quot; ? message : JSON.stringify(message);
-    InspectorTest.addResult(prefix + &quot;: &quot; + stringifiedMessage);
-}
-
-// This function should only be used to debug tests and not to produce normal test output.
-InspectorTest.debugLog = function(message)
-{
-    if (InspectorTest.dumpMessagesToConsole)
-        InspectorFrontendHost.unbufferedLog(&quot;debugLog: &quot; + message);
-
-    this.evaluateInPage(&quot;InspectorTestProxy.debugLog(unescape('&quot; + escape(JSON.stringify(message)) + &quot;'))&quot;);
-}
-
-// Appends a message in the test document if there was an error, and attempts to complete the test.
-InspectorTest.expectNoError = function(error)
-{
-    if (error) {
-        InspectorTest.log(&quot;PROTOCOL ERROR: &quot; + error);
-        InspectorTest.completeTest();
-        throw &quot;PROTOCOL ERROR&quot;;
-    }
-}
-
-InspectorTest.completeTest = function()
-{
-    if (InspectorTest.dumpMessagesToConsole)
-        InspectorFrontendHost.unbufferedLog(&quot;InspectorTest.completeTest()&quot;);
-
-    // Wait for results to be resent before requesting completeTest(). Otherwise, messages will be
-    // queued after pending dispatches run to zero and the test page will quit before processing them.
-    if (this._testPageIsReloading) {
-        this._completeTestAfterReload = true;
-        return;
-    }
-
-    InspectorBackend.runAfterPendingDispatches(this.evaluateInPage.bind(this, &quot;InspectorTestProxy.completeTest()&quot;));
-}
-
-InspectorTest.evaluateInPage = function(codeString, callback)
-{
-    // If we load this page outside of the inspector, or hit an early error when loading
-    // the test frontend, then defer evaluating the commands (indefinitely in the former case).
-    if (!window.RuntimeAgent) {
-        this._originalConsoleMethods[&quot;error&quot;](&quot;Tried to evaluate in test page, but connection not yet established:&quot;, codeString);
-        return;
-    }
-
-    RuntimeAgent.evaluate.invoke({expression: codeString, objectGroup: &quot;test&quot;, includeCommandLineAPI: false}, callback);
-}
-
-InspectorTest.addResult = function(text)
-{
-    this._results.push(text);
-
-    if (InspectorTest.dumpMessagesToConsole)
-        InspectorFrontendHost.unbufferedLog(&quot;addResult: &quot; + text);
-
-    if (!this._testPageIsReloading)
-        this.evaluateInPage(&quot;InspectorTestProxy.addResult(unescape('&quot; + escape(text) + &quot;'))&quot;);
-}
-
-InspectorTest._resendResults = function()
-{
-    console.assert(this._shouldResendResults);
-    this._shouldResendResults = false;
-
-    for (var result of this._results)
-        this.evaluateInPage(&quot;InspectorTestProxy.addResult(unescape('&quot; + escape(result) + &quot;'))&quot;);
-}
-
-InspectorTest.testPageDidLoad = function()
-{
-    this._testPageIsReloading = false;
-    this._resendResults();
-
-    this.eventDispatcher.dispatchEvent(InspectorTest.EventDispatcher.Event.TestPageDidLoad);
-
-    if (this._completeTestAfterReload)
-        InspectorTest.completeTest();
-}
-
-InspectorTest.reloadPage = function(shouldIgnoreCache)
-{
-    console.assert(!this._testPageIsReloading);
-    console.assert(!this._testPageReloadedOnce);
-
-    this._testPageIsReloading = true;
-
-    return PageAgent.reload(!!shouldIgnoreCache)
-        .then(function() {
-            this._shouldResendResults = true;
-            this._testPageReloadedOnce = true;
-
-            return Promise.resolve(null);
-        }.bind(this));
-}
-
-InspectorTest.reportUncaughtException = function(message, url, lineNumber)
-{
-    var result = &quot;Uncaught exception in inspector page: &quot; + message + &quot; [&quot; + url + &quot;:&quot; + lineNumber + &quot;]&quot;;
-
-    // If the connection to the test page is not set up, then just dump to console and give up.
-    // Errors encountered this early can be debugged by loading Test.html in a normal browser page.
-    if (!InspectorFrontendHost || !InspectorBackend) {
-        this._originalConsoleMethods[&quot;error&quot;](result);
-        return false;
-    }
-
-    this.addResult(result);
-    this.completeTest();
-    // Stop default handler so we can empty InspectorBackend's message queue.
-    return true;
-}
-
-// Initialize reporting mechanisms before loading the rest of the inspector page.
-InspectorTest._results = [];
-InspectorTest._shouldResendResults = true;
-InspectorTest._originalConsoleMethods = {};
-
-// Catch syntax errors, type errors, and other exceptions.
-window.onerror = InspectorTest.reportUncaughtException.bind(InspectorTest);
-
-// Redirect frontend console methods to log messages into the test result.
-(function() {
-    function createProxyConsoleHandler(type) {
-        return function() {
-            InspectorTest.addResult(type + &quot;: &quot; + Array.from(arguments).join(&quot; &quot;));
-        };
-    }
-
-    for (var type of [&quot;log&quot;, &quot;error&quot;, &quot;info&quot;]) {
-        InspectorTest._originalConsoleMethods[type] = console[type].bind(console);
-        console[type] = createProxyConsoleHandler(type.toUpperCase());
-    }
-})();
</del><ins>+InspectorTest.redirectConsoleToTestOutput();
</ins></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTestTestSuitejs"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Test/TestSuite.js (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Test/TestSuite.js        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/TestSuite.js        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -155,7 +155,6 @@
</span><span class="cx">         this._harness.log(&quot;== Running test suite: &quot; + this.name);
</span><span class="cx"> 
</span><span class="cx">         let priorLogCount = this._harness.logCount;
</span><del>-        let self = this;
</del><span class="cx">         for (let i = 0; i &lt; this.testcases.length; i++) {
</span><span class="cx">             let testcase = this.testcases[i];
</span><span class="cx">             if (i &gt; 0 &amp;&amp; priorLogCount + 1 &lt; this._harness.logCount)
</span><span class="lines">@@ -164,15 +163,15 @@
</span><span class="cx">             priorLogCount = this._harness.logCount;
</span><span class="cx"> 
</span><span class="cx">             this._harness.log(&quot;-- Running test case: &quot; + testcase.name);
</span><del>-            self.runCount++;
</del><ins>+            this.runCount++;
</ins><span class="cx">             try {
</span><span class="cx">                 let result = testcase.test.call(null);
</span><span class="cx">                 if (result === false) {
</span><del>-                    self.failCount++;
</del><ins>+                    this.failCount++;
</ins><span class="cx">                     return false;
</span><span class="cx">                 }
</span><span class="cx">             } catch (e) {
</span><del>-                self.failCount++;
</del><ins>+                this.failCount++;
</ins><span class="cx">                 let message = e;
</span><span class="cx">                 if (e instanceof Error)
</span><span class="cx">                     message = e.message;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTesthtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/Test.html        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -32,6 +32,10 @@
</span><span class="cx">     &lt;script src=&quot;Base/WebInspector.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script src=&quot;Base/Object.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> 
</span><ins>+    &lt;script src=&quot;Test/TestHarness.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;Test/FrontendTestHarness.js&quot;&gt;&lt;/script&gt;
+    &lt;script src=&quot;Test/TestSuite.js&quot;&gt;&lt;/script&gt;
+
</ins><span class="cx">     &lt;script src=&quot;Test/Test.js&quot;&gt;&lt;/script&gt;
</span><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Base/DOMUtilities.js&quot;&gt;&lt;/script&gt;
</span><span class="lines">@@ -142,6 +146,13 @@
</span><span class="cx"> 
</span><span class="cx">     &lt;script type=&quot;text/javascript&quot;&gt;
</span><span class="cx">         WebInspector.loaded();
</span><ins>+
+        // Not reliable unless console messages are dumped to stderr.
+        // See wiki for details &lt;https://http://trac.webkit.org/wiki/WebInspectorDebugging&gt;.
+        InspectorBackend.dumpInspectorProtocolMessages = false;
+
+        // Synchronous logging may produce more output prior to a timeout.
+        InspectorTest.forceSyncDebugLogging = false;
</ins><span class="cx">     &lt;/script&gt;
</span><span class="cx"> &lt;/head&gt;
</span><span class="cx"> &lt;body&gt;
</span></span></pre></div>
<a id="trunkSourceWebInspectorUIUserInterfaceTestStubhtml"></a>
<div class="modfile"><h4>Modified: trunk/Source/WebInspectorUI/UserInterface/TestStub.html (188643 => 188644)</h4>
<pre class="diff"><span>
<span class="info">--- trunk/Source/WebInspectorUI/UserInterface/TestStub.html        2015-08-19 18:37:02 UTC (rev 188643)
+++ trunk/Source/WebInspectorUI/UserInterface/TestStub.html        2015-08-19 19:09:34 UTC (rev 188644)
</span><span class="lines">@@ -40,7 +40,8 @@
</span><span class="cx"> 
</span><span class="cx">     &lt;script src=&quot;Test/TestStub.js&quot;&gt;&lt;/script&gt;
</span><span class="cx">     &lt;script&gt;
</span><del>-        // Not reliable unless console messages are dumped to console. See wiki for details.
</del><ins>+        // Not reliable unless console messages are dumped to console.
+        // See wiki for details &lt;https://http://trac.webkit.org/wiki/WebInspectorDebugging&gt;.
</ins><span class="cx">         ProtocolTest.dumpInspectorProtocolMessages = false;
</span><span class="cx"> 
</span><span class="cx">         // Synchronous logging may produce more output prior to a timeout.
</span></span></pre>
</div>
</div>

</body>
</html>