Diff
Modified: trunk/LayoutTests/ChangeLog (188543 => 188544)
--- trunk/LayoutTests/ChangeLog 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/ChangeLog 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,5 +1,36 @@
2015-08-17 Brian Burg <bb...@apple.com>
+ Web Inspector: split TestStub.js into multiple files and modernize it
+ https://bugs.webkit.org/show_bug.cgi?id=148077
+
+ Reviewed by Timothy Hatcher.
+
+ Add the prefix 'TestPage' to everything in protocol-test.js. Continue
+ exporting it to the global namespace for backwards compatibility, too.
+
+ Rename some things to match changes in the test harness. Tighten up
+ preconditions for test suite and test case names. Sprinkle some ES6.
+
+ * http/tests/inspector/dom/resources/InspectorDOMListener.js:
+ * http/tests/inspector/resources/console-test.js:
+ * http/tests/inspector/resources/probe-test.js:
+ * http/tests/inspector/resources/protocol-test.js:
+ (TestPage.registerInitializer):
+ (TestPage.debugLog.window.debugLog):
+ (TestPage.log.window.log):
+ (TestPage.closeTest.window.closeTest):
+ (TestPage.runTest.window.runTest):
+ (ProtocolTestProxy.registerInitializer): Deleted.
+ (debugLog): Deleted.
+ (log): Deleted.
+ (closeTest): Deleted.
+ (runTest): Deleted.
+ * inspector/dom/resources/dom-search-queries.js:
+ * inspector/unit-tests/async-test-suite.html:
+ * inspector/unit-tests/sync-test-suite.html:
+
+2015-08-17 Brian Burg <bb...@apple.com>
+
Web Inspector: load ProtocolTestStub from the WebInspectorUI bundle
https://bugs.webkit.org/show_bug.cgi?id=147955
Modified: trunk/LayoutTests/http/tests/inspector/dom/resources/InspectorDOMListener.js (188543 => 188544)
--- trunk/LayoutTests/http/tests/inspector/dom/resources/InspectorDOMListener.js 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/http/tests/inspector/dom/resources/InspectorDOMListener.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -27,7 +27,7 @@
* SUCH DAMAGE.
*/
-ProtocolTestProxy.registerInitializer(function(){
+TestPage.registerInitializer(function(){
window.createDOMListener = function()
{
Modified: trunk/LayoutTests/http/tests/inspector/resources/console-test.js (188543 => 188544)
--- trunk/LayoutTests/http/tests/inspector/resources/console-test.js 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/http/tests/inspector/resources/console-test.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,4 +1,4 @@
-ProtocolTestProxy.registerInitializer(function() {
+TestPage.registerInitializer(function() {
ProtocolTest.Console = {};
@@ -34,7 +34,7 @@
ProtocolTest.Console.addTestCase = function(suite, args)
{
- if (!(suite instanceof InjectedTestHarness.AsyncTestSuite))
+ if (!(suite instanceof AsyncTestSuite))
throw new Error("Console test cases must be added to an async test suite.");
var {name, description, _expression_, expected} = args;
Modified: trunk/LayoutTests/http/tests/inspector/resources/probe-test.js (188543 => 188544)
--- trunk/LayoutTests/http/tests/inspector/resources/probe-test.js 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/http/tests/inspector/resources/probe-test.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,4 +1,4 @@
-ProtocolTestProxy.registerInitializer(function() {
+TestPage.registerInitializer(function() {
ProtocolTest.Probe = {};
Modified: trunk/LayoutTests/http/tests/inspector/resources/protocol-test.js (188543 => 188544)
--- trunk/LayoutTests/http/tests/inspector/resources/protocol-test.js 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/http/tests/inspector/resources/protocol-test.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -25,33 +25,26 @@
*/
// This namespace is injected into every test page. Its functions are invoked by
-// ProtocolTest methods on the inspector page via InjectedTestHarness.
-ProtocolTestProxy = {};
-ProtocolTestProxy._initializers = [];
+// ProtocolTest methods on the inspector page via a TestHarness subclass.
+TestPage = {};
+TestPage._initializers = [];
// Helper scripts like `console-test.js` must register their initialization
// function with this method so it will be marshalled to the inspector page.
-ProtocolTestProxy.registerInitializer = function(initializer)
+TestPage.registerInitializer = function(initializer)
{
if (typeof initializer === "function")
this._initializers.push(initializer.toString());
-}
+};
let outputElement;
-/**
- * Logs message to process stdout via alert (hopefully implemented with immediate flush).
- * @param {string} text
- */
-function debugLog(text)
+TestPage.debugLog = window.debugLog = function(text)
{
alert(text);
-}
+};
-/**
- * @param {string} text
- */
-function log(text)
+TestPage.log = window.log = function(text)
{
if (!outputElement) {
let intermediate = document.createElement("div");
@@ -68,9 +61,9 @@
}
outputElement.appendChild(document.createTextNode(text));
outputElement.appendChild(document.createElement("br"));
-}
+};
-function closeTest()
+TestPage.closeTest = window.closeTest = function()
{
window.internals.closeDummyInspectorFrontend();
@@ -79,20 +72,21 @@
setTimeout(function() {
testRunner.notifyDone();
}, 0);
-}
+};
-function runTest()
+TestPage.runTest = window.runTest = function()
{
if (!window.testRunner) {
- console.error("This test requires DumpRenderTree");
+ console.error("This test must be run via DumpRenderTree or WebKitTestRunner.");
return;
}
+
testRunner.dumpAsText();
testRunner.waitUntilDone();
testRunner.setCanOpenWindows(true);
let testFunction = window.test;
- if (!(typeof testFunction === "function")) {
+ if (typeof testFunction !== "function") {
alert("Failed to send test() because it is not a function.");
testRunner.notifyDone();
}
@@ -127,10 +121,10 @@
let inspectorFrontend = window.internals.openDummyInspectorFrontend(url);
inspectorFrontend.addEventListener("load", function(event) {
- let initializationCodeString = `(${runInitializationMethodsInFrontend.toString()})([${ProtocolTestProxy._initializers}]);`;
+ let initializationCodeString = `(${runInitializationMethodsInFrontend.toString()})([${TestPage._initializers}]);`;
let testFunctionCodeString = `(${runTestMethodInFrontend.toString()})(${testFunction.toString()});`;
inspectorFrontend.postMessage(initializationCodeString, "*");
inspectorFrontend.postMessage(testFunctionCodeString, "*");
});
-}
+};
Modified: trunk/LayoutTests/inspector/dom/resources/dom-search-queries.js (188543 => 188544)
--- trunk/LayoutTests/inspector/dom/resources/dom-search-queries.js 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/inspector/dom/resources/dom-search-queries.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,4 +1,4 @@
-ProtocolTestProxy.registerInitializer(function() {
+TestPage.registerInitializer(function() {
// Having the queries in an external file, so that DOM search will not find the script when searching for values.
Modified: trunk/LayoutTests/inspector/unit-tests/async-test-suite-expected.txt (188543 => 188544)
--- trunk/LayoutTests/inspector/unit-tests/async-test-suite-expected.txt 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/inspector/unit-tests/async-test-suite-expected.txt 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,9 +1,11 @@
PASS: instantiating AsyncTestSuite requires name argument.
PASS: instantiating AsyncTestSuite requires string name argument.
+PASS: instantiating AsyncTestSuite requires non-whitespace name argument.
PASS: instantiating AsyncTestSuite requires test harness argument.
PASS: should not be able to add empty test case.
PASS: should not be able to add non-object test case.
PASS: test case should require string name.
+PASS: test case should require non-whitespace name.
PASS: test case should require test function.
PASS: should not be able to run empty test suite.
Modified: trunk/LayoutTests/inspector/unit-tests/async-test-suite.html (188543 => 188544)
--- trunk/LayoutTests/inspector/unit-tests/async-test-suite.html 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/inspector/unit-tests/async-test-suite.html 2015-08-17 21:51:45 UTC (rev 188544)
@@ -6,27 +6,34 @@
function test()
{
try {
- let result = new InjectedTestHarness.AsyncTestSuite(this);
+ let result = new AsyncTestSuite(this);
ProtocolTest.log("FAIL: instantiating AsyncTestSuite requires name argument.");
} catch (e) {
ProtocolTest.log("PASS: instantiating AsyncTestSuite requires name argument.");
}
try {
- let result = new InjectedTestHarness.AsyncTestSuite(this, {});
+ let result = new AsyncTestSuite(this, {});
ProtocolTest.log("FAIL: instantiating AsyncTestSuite requires string name argument.");
} catch (e) {
ProtocolTest.log("PASS: instantiating AsyncTestSuite requires string name argument.");
}
try {
- let result = new InjectedTestHarness.AsyncTestSuite("something", {});
+ let result = new AsyncTestSuite(this, " ");
+ ProtocolTest.log("FAIL: instantiating AsyncTestSuite requires non-whitespace name argument.");
+ } catch (e) {
+ ProtocolTest.log("PASS: instantiating AsyncTestSuite requires non-whitespace name argument.");
+ }
+
+ try {
+ let result = new AsyncTestSuite("something", {});
ProtocolTest.log("FAIL: instantiating AsyncTestSuite requires test harness argument.");
} catch (e) {
ProtocolTest.log("PASS: instantiating AsyncTestSuite requires test harness argument.");
}
- var badArgsSuite = ProtocolTest.createAsyncSuite("dummy");
+ let badArgsSuite = ProtocolTest.createAsyncSuite("dummy");
try {
badArgsSuite.addTestCase();
ProtocolTest.log("FAIL: should not be able to add empty test case.");
@@ -50,6 +57,15 @@
}
try {
badArgsSuite.addTestCase({
+ name: " ",
+ test: function() {},
+ });
+ ProtocolTest.log("FAIL: test case should require non-whitespace name.");
+ } catch (e) {
+ ProtocolTest.log("PASS: test case should require non-whitespace name.");
+ }
+ try {
+ badArgsSuite.addTestCase({
name: "foo",
test: null,
});
@@ -58,7 +74,7 @@
ProtocolTest.log("PASS: test case should require test function.");
}
- var runEmptySuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.RunEmptySuite");
+ let runEmptySuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.RunEmptySuite");
try {
runEmptySuite.runTestCases();
ProtocolTest.log("FAIL: should not be able to run empty test suite.");
@@ -66,7 +82,7 @@
ProtocolTest.log("PASS: should not be able to run empty test suite.");
}
- var runTwiceSuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.RunTwiceSuite");
+ let runTwiceSuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.RunTwiceSuite");
runTwiceSuite.addTestCase({
name: "DummyTest0",
description: "Check that a suite can't run more than once.",
@@ -75,7 +91,7 @@
}
});
- var result = runTwiceSuite.runTestCases();
+ let result = runTwiceSuite.runTestCases();
try {
// Test cases won't run in this event loop; this call should still throw.
// Later tests are chained to this suite to avoid nondeterminism.
@@ -85,10 +101,10 @@
ProtocolTest.log("PASS: should not be able to run a test suite twice.");
}
- var rejectToken = {"token": 666};
- var thrownError = new Error(rejectToken);
+ let rejectToken = {"token": 666};
+ let thrownError = new Error(rejectToken);
- var sequentialExecutionSuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.SequentialExecution");
+ let sequentialExecutionSuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.SequentialExecution");
sequentialExecutionSuite.addTestCase({
name: "DummyTest1",
description: "Check test case execution order.",
@@ -118,7 +134,7 @@
}
});
- var abortOnFailureSuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.AbortOnFailure");
+ let abortOnFailureSuite = ProtocolTest.createAsyncSuite("AsyncTestSuite.AbortOnFailure");
abortOnFailureSuite.addTestCase({
name: "PassingTest5",
description: "This test is a dummy.",
@@ -142,7 +158,7 @@
});
result = result.then(function() {
- var promise = sequentialExecutionSuite.runTestCases();
+ let promise = sequentialExecutionSuite.runTestCases();
ProtocolTest.expectThat(result instanceof Promise, "AsyncTestSuite.RunTestCases() should return a Promise.");
return promise;
});
Modified: trunk/LayoutTests/inspector/unit-tests/sync-test-suite-expected.txt (188543 => 188544)
--- trunk/LayoutTests/inspector/unit-tests/sync-test-suite-expected.txt 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/inspector/unit-tests/sync-test-suite-expected.txt 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,9 +1,11 @@
PASS: instantiating SyncTestSuite requires name argument.
PASS: instantiating SyncTestSuite requires string name argument.
+PASS: instantiating AsyncTestSuite requires non-whitespace name argument.
PASS: instantiating SyncTestSuite requires test harness argument.
PASS: should not be able to add empty test case.
PASS: should not be able to add non-object test case.
PASS: test case should require string name.
+PASS: test case should require non-whitespace name.
PASS: test case should require test function.
PASS: should not be able to run empty test suite.
Modified: trunk/LayoutTests/inspector/unit-tests/sync-test-suite.html (188543 => 188544)
--- trunk/LayoutTests/inspector/unit-tests/sync-test-suite.html 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/LayoutTests/inspector/unit-tests/sync-test-suite.html 2015-08-17 21:51:45 UTC (rev 188544)
@@ -6,27 +6,34 @@
function test()
{
try {
- let result = new ProtocolTest.SyncTestSuite(this);
+ let result = new SyncTestSuite(this);
ProtocolTest.log("FAIL: instantiating SyncTestSuite requires name argument.");
} catch (e) {
ProtocolTest.log("PASS: instantiating SyncTestSuite requires name argument.");
}
try {
- let result = new ProtocolTest.SyncTestSuite(this, {});
+ let result = new SyncTestSuite(this, {});
ProtocolTest.log("FAIL: instantiating SyncTestSuite requires string name argument.");
} catch (e) {
ProtocolTest.log("PASS: instantiating SyncTestSuite requires string name argument.");
}
try {
- let result = new ProtocolTest.SyncTestSuite("something", {});
+ let result = new syncTestSuite(this, " ");
+ ProtocolTest.log("FAIL: instantiating AsyncTestSuite requires non-whitespace name argument.");
+ } catch (e) {
+ ProtocolTest.log("PASS: instantiating AsyncTestSuite requires non-whitespace name argument.");
+ }
+
+ try {
+ let result = new SyncTestSuite("something", {});
ProtocolTest.log("FAIL: instantiating SyncTestSuite requires test harness argument.");
} catch (e) {
ProtocolTest.log("PASS: instantiating SyncTestSuite requires test harness argument.");
}
- var badArgsSuite = ProtocolTest.createSyncSuite("dummy");
+ let badArgsSuite = ProtocolTest.createSyncSuite("dummy");
try {
badArgsSuite.addTestCase();
ProtocolTest.log("FAIL: should not be able to add empty test case.");
@@ -50,6 +57,15 @@
}
try {
badArgsSuite.addTestCase({
+ name: " ",
+ test: function() {},
+ });
+ ProtocolTest.log("FAIL: test case should require non-whitespace name.");
+ } catch (e) {
+ ProtocolTest.log("PASS: test case should require non-whitespace name.");
+ }
+ try {
+ badArgsSuite.addTestCase({
name: "foo",
test: null,
});
@@ -58,7 +74,7 @@
ProtocolTest.log("PASS: test case should require test function.");
}
- var runEmptySuite = ProtocolTest.createSyncSuite("SyncTestSuite.RunEmptySuite");
+ let runEmptySuite = ProtocolTest.createSyncSuite("SyncTestSuite.RunEmptySuite");
try {
runEmptySuite.runTestCases();
ProtocolTest.log("FAIL: should not be able to run empty test suite.");
@@ -66,7 +82,7 @@
ProtocolTest.log("PASS: should not be able to run empty test suite.");
}
- var runTwiceSuite = ProtocolTest.createSyncSuite("SyncTestSuite.RunTwiceSuite");
+ let runTwiceSuite = ProtocolTest.createSyncSuite("SyncTestSuite.RunTwiceSuite");
runTwiceSuite.addTestCase({
name: "DummyTest0",
description: "Check that a suite can't run more than once.",
@@ -74,7 +90,7 @@
});
try {
- var result = runTwiceSuite.runTestCases();
+ let result = runTwiceSuite.runTestCases();
ProtocolTest.expectThat(result === true, "Return value of runTwiceSuite.runTestCases() should be true when all tests pass.");
runTwiceSuite.runTestCases(); // Try to trigger an error.
@@ -83,9 +99,9 @@
ProtocolTest.log("PASS: should not be able to run a test suite twice.");
}
- var thrownError = new Error({"token": 666});
+ let thrownError = new Error({"token": 666});
- var sequentialExecutionSuite = ProtocolTest.createSyncSuite("SyncTestSuite.SequentialExecution");
+ let sequentialExecutionSuite = ProtocolTest.createSyncSuite("SyncTestSuite.SequentialExecution");
sequentialExecutionSuite.addTestCase({
name: "DummyTest1",
description: "Check test case execution order.",
@@ -107,14 +123,14 @@
test: function() { throw thrownError; }
});
- var result = sequentialExecutionSuite.runTestCases();
+ let result = sequentialExecutionSuite.runTestCases();
ProtocolTest.expectThat(result === false, "Return value of sequentialExecutionSuite.runTestCases() should be false when a test case fails.");
ProtocolTest.expectThat(sequentialExecutionSuite.runCount === 4, "sequentialExecutionSuite should have executed four tests.");
ProtocolTest.expectThat(sequentialExecutionSuite.passCount === 3, "sequentialExecutionSuite should have passed three tests.");
ProtocolTest.expectThat(sequentialExecutionSuite.failCount === 1, "sequentialExecutionSuite should have failed 1 test.");
ProtocolTest.expectThat(sequentialExecutionSuite.skipCount === 0, "sequentialExecutionSuite should have skipped zero tests.");
- var abortOnFailureSuite = ProtocolTest.createSyncSuite("SyncTestSuite.AbortOnFailure");
+ let abortOnFailureSuite = ProtocolTest.createSyncSuite("SyncTestSuite.AbortOnFailure");
abortOnFailureSuite.addTestCase({
name: "PassingTest5",
description: "This test is a dummy.",
Modified: trunk/Source/WebInspectorUI/ChangeLog (188543 => 188544)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,5 +1,84 @@
2015-08-17 Brian Burg <bb...@apple.com>
+ Web Inspector: split TestStub.js into multiple files and modernize it
+ https://bugs.webkit.org/show_bug.cgi?id=148077
+
+ Reviewed by Timothy Hatcher.
+
+ Since we want to share files between the two harnesses, split some of the parts
+ into different files so not everything has to be included at once.
+
+ Rename InjectedTestHarness to just TestHarness. Update some code to use
+ ES6 features where appropriate. Put test classes into Test/ directory.
+
+ * UserInterface/Base/TestStub.js: Removed.
+ * UserInterface/Test.html:
+ * UserInterface/Test/InspectorProtocol.js: Added.
+ (InspectorProtocol.sendCommand):
+ (InspectorProtocol.awaitCommand):
+ (InspectorProtocol.awaitEvent.):
+ (InspectorProtocol.awaitEvent):
+ (InspectorProtocol.addEventListener):
+ (InspectorProtocol.sendMessage):
+ (InspectorProtocol.checkForError):
+ (InspectorProtocol.dispatchMessageFromBackend):
+ * UserInterface/Test/ProtocolTestHarness.js: Added.
+ (ProtocolTestHarness.prototype.completeTest):
+ (ProtocolTestHarness.prototype.addResult):
+ (ProtocolTestHarness.prototype.debugLog):
+ (ProtocolTestHarness.prototype.evaluateInPage):
+ (ProtocolTestHarness):
+ * UserInterface/Test/Test.js: Renamed from Source/WebInspectorUI/UserInterface/Base/Test.js.
+ (WebInspector.loaded):
+ (WebInspector.contentLoaded):
+ (WebInspector.UIString):
+ (WebInspector.updateDockedState):
+ (WebInspector.updateDockingAvailability):
+ (InspectorTest.EventDispatcher.prototype.dispatchEvent):
+ (InspectorTest.EventDispatcher):
+ (InspectorTest.log):
+ (InspectorTest.assert):
+ (InspectorTest.expectThat):
+ (InspectorTest.debugLog):
+ (InspectorTest.expectNoError):
+ (InspectorTest.completeTest):
+ (InspectorTest.evaluateInPage):
+ (InspectorTest.addResult):
+ (InspectorTest._resendResults):
+ (InspectorTest.testPageDidLoad):
+ (InspectorTest.reloadPage):
+ (InspectorTest.reportUncaughtException):
+ * UserInterface/Test/TestHarness.js: Added.
+ (TestHarness):
+ (TestHarness.prototype.completeTest):
+ (TestHarness.prototype.addResult):
+ (TestHarness.prototype.debugLog):
+ (TestHarness.prototype.evaluateInPage):
+ (TestHarness.prototype.createAsyncSuite):
+ (TestHarness.prototype.createSyncSuite):
+ (TestHarness.prototype.get logCount):
+ (TestHarness.prototype.log):
+ (TestHarness.prototype.assert):
+ (TestHarness.prototype.expectThat):
+ * UserInterface/Test/TestStub.js: Added.
+ * UserInterface/Test/TestSuite.js: Added.
+ (TestSuite):
+ (TestSuite.prototype.runTestCasesAndFinish):
+ (TestSuite.prototype.runTestCases):
+ (TestSuite.prototype.get passCount):
+ (TestSuite.prototype.get skipCount):
+ (TestSuite.prototype.addTestCase):
+ (AsyncTestSuite.prototype.runTestCasesAndFinish.finish):
+ (AsyncTestSuite.prototype.runTestCasesAndFinish):
+ (AsyncTestSuite.prototype.runTestCases):
+ (AsyncTestSuite):
+ (SyncTestSuite.prototype.runTestCasesAndFinish):
+ (SyncTestSuite.prototype.runTestCases):
+ (SyncTestSuite):
+ * UserInterface/TestStub.html:
+
+2015-08-17 Brian Burg <bb...@apple.com>
+
Web Inspector: load ProtocolTestStub from the WebInspectorUI bundle
https://bugs.webkit.org/show_bug.cgi?id=147955
Deleted: trunk/Source/WebInspectorUI/UserInterface/Base/Test.js (188543 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Base/Test.js 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/Test.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,279 +0,0 @@
-/*
- * Copyright (C) 2013, 2014 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
- * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
- * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
- * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * HOLDER OR 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.
- */
-
-WebInspector.DebuggableType = {
- Web: "web",
- _javascript_: "_javascript_"
-};
-
-WebInspector.loaded = function()
-{
- this.debuggableType = WebInspector.DebuggableType.Web;
- this.hasExtraDomains = false;
-
- // Register observers for events from the InspectorBackend.
- // The initialization order should match the same in Main.js.
- InspectorBackend.registerInspectorDispatcher(new WebInspector.InspectorObserver);
- InspectorBackend.registerPageDispatcher(new WebInspector.PageObserver);
- InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleObserver);
- InspectorBackend.registerDOMDispatcher(new WebInspector.DOMObserver);
- InspectorBackend.registerNetworkDispatcher(new WebInspector.NetworkObserver);
- InspectorBackend.registerDebuggerDispatcher(new WebInspector.DebuggerObserver);
- InspectorBackend.registerTimelineDispatcher(new WebInspector.TimelineObserver);
- InspectorBackend.registerCSSDispatcher(new WebInspector.CSSObserver);
- InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
- if (InspectorBackend.registerReplayDispatcher)
- InspectorBackend.registerReplayDispatcher(new WebInspector.ReplayObserver);
-
- // Instantiate controllers used by tests.
- this.frameResourceManager = new WebInspector.FrameResourceManager;
- this.domTreeManager = new WebInspector.DOMTreeManager;
- this.cssStyleManager = new WebInspector.CSSStyleManager;
- this.logManager = new WebInspector.LogManager;
- this.issueManager = new WebInspector.IssueManager;
- this.runtimeManager = new WebInspector.RuntimeManager;
- this.timelineManager = new WebInspector.TimelineManager;
- this.debuggerManager = new WebInspector.DebuggerManager;
- this.probeManager = new WebInspector.ProbeManager;
- this.replayManager = new WebInspector.ReplayManager;
-
- // Global controllers.
- this.quickConsole = {executionContextIdentifier: undefined};
-
- document.addEventListener("DOMContentLoaded", this.contentLoaded.bind(this));
-
- // Enable agents.
- InspectorAgent.enable();
- ConsoleAgent.enable();
-
- // Perform one-time tasks.
- WebInspector.CSSCompletions.requestCSSCompletions();
-
- // Global settings.
- this.showShadowDOMSetting = new WebInspector.Setting("show-shadow-dom", true);
-}
-
-WebInspector.contentLoaded = function()
-{
- // Signal that the frontend is now ready to receive messages.
- InspectorFrontendAPI.loadCompleted();
-
- // Tell the InspectorFrontendHost we loaded, which causes the window to display
- // and pending InspectorFrontendAPI commands to be sent.
- InspectorFrontendHost.loaded();
-}
-
-WebInspector.UIString = function(string)
-{
- return string;
-}
-
-// Add stubs that are called by the frontend API.
-WebInspector.updateDockedState = function() {};
-WebInspector.updateDockingAvailability = function() {};
-
-// 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 = {};
-
-// 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: "inspector-test-test-page-did-load"
-};
-
-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 !== "object" ? 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 !== "object" ? message : JSON.stringify(message);
- InspectorTest.addResult("ASSERT: " + stringifiedMessage);
-}
-
-// Appends a message in the test document whether the condition is true or not.
-InspectorTest.expectThat = function(condition, message)
-{
- var prefix = condition ? "PASS" : "FAIL";
- var stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
- InspectorTest.addResult(prefix + ": " + 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("debugLog: " + message);
-
- this.evaluateInPage("InspectorTestProxy.debugLog(unescape('" + escape(JSON.stringify(message)) + "'))");
-}
-
-// 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("PROTOCOL ERROR: " + error);
- InspectorTest.completeTest();
- throw "PROTOCOL ERROR";
- }
-}
-
-InspectorTest.completeTest = function()
-{
- if (InspectorTest.dumpMessagesToConsole)
- InspectorFrontendHost.unbufferedLog("InspectorTest.completeTest()");
-
- // 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, "InspectorTestProxy.completeTest()"));
-}
-
-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["error"]("Tried to evaluate in test page, but connection not yet established:", codeString);
- return;
- }
-
- RuntimeAgent.evaluate.invoke({_expression_: codeString, objectGroup: "test", includeCommandLineAPI: false}, callback);
-}
-
-InspectorTest.addResult = function(text)
-{
- this._results.push(text);
-
- if (InspectorTest.dumpMessagesToConsole)
- InspectorFrontendHost.unbufferedLog("addResult: " + text);
-
- if (!this._testPageIsReloading)
- this.evaluateInPage("InspectorTestProxy.addResult(unescape('" + escape(text) + "'))");
-}
-
-InspectorTest._resendResults = function()
-{
- console.assert(this._shouldResendResults);
- this._shouldResendResults = false;
-
- for (var result of this._results)
- this.evaluateInPage("InspectorTestProxy.addResult(unescape('" + escape(result) + "'))");
-}
-
-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 = "Uncaught exception in inspector page: " + message + " [" + url + ":" + lineNumber + "]";
-
- // 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["error"](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 + ": " + Array.from(arguments).join(" "));
- };
- }
-
- for (var type of ["log", "error", "info"]) {
- InspectorTest._originalConsoleMethods[type] = console[type].bind(console);
- console[type] = createProxyConsoleHandler(type.toUpperCase());
- }
-})();
Deleted: trunk/Source/WebInspectorUI/UserInterface/Base/TestStub.js (188543 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Base/TestStub.js 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/TestStub.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -1,480 +0,0 @@
-/*
- * Copyright (C) 2012 Samsung Electronics. All rights reserved.
- * Copyright (C) 2014, 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 "AS IS" AND ANY
- * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
- * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
- * DISCLAIMED. IN NO EVENT SHALL APPLE 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.
- */
-InspectorFrontendAPI = {};
-
-InjectedTestHarness = class InjectedTestHarness
-{
- constructor()
- {
- this._logCount = 0;
- this.forceSyncDebugLogging = false;
- }
-
- completeTest()
- {
- throw new Error("Must be implemented by subclasses.");
- }
-
- addResult()
- {
- throw new Error("Must be implemented by subclasses.");
- }
-
- debugLog()
- {
- throw new Error("Must be implemented by subclasses.");
- }
-
- evaluateInPage(string, callback)
- {
- throw new Error("Must be implemented by subclasses.");
- }
-
- createAsyncSuite(name)
- {
- return new InjectedTestHarness.AsyncTestSuite(this, name);
- }
-
- createSyncSuite(name)
- {
- return new InjectedTestHarness.SyncTestSuite(this, name);
- }
-
- get logCount()
- {
- return this._logCount;
- }
-
- log(message)
- {
- ++this._logCount;
-
- if (this.forceSyncDebugLogging)
- this.debugLog(message);
- else
- this.addResult(message);
- }
-
- assert(condition, message)
- {
- if (condition)
- return;
-
- let stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
- this.addResult("ASSERT: " + stringifiedMessage);
- }
-
- expectThat(condition, message)
- {
- let prefix = condition ? "PASS" : "FAIL";
- let stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
- this.addResult(prefix + ": " + stringifiedMessage);
- }
-}
-
-InjectedTestHarness.AsyncTestSuite = class AsyncTestSuite
-{
- constructor(harness, name) {
- if (!(harness instanceof InjectedTestHarness))
- throw new Error("Must pass the test's harness as the first argument.");
-
- if (!name || typeof name !== "string")
- throw new Error("Tried to create AsyncTestSuite without string suite name.");
-
- this.name = name;
- this._harness = harness;
-
- this.testcases = [];
- this.runCount = 0;
- this.failCount = 0;
- }
-
- get passCount()
- {
- return this.runCount - this.failCount;
- }
-
- get skipCount()
- {
- if (this.failCount)
- return this.testcases.length - this.runCount;
- else
- return 0;
- }
-
- addTestCase(testcase)
- {
- if (!testcase || !(testcase instanceof Object))
- throw new Error("Tried to add non-object test case.");
-
- if (typeof testcase.name !== "string")
- throw new Error("Tried to add test case without a name.");
-
- if (typeof testcase.test !== "function")
- throw new Error("Tried to add test case without `test` function.");
-
- this.testcases.push(testcase);
- }
-
- // Use this if the test file only has one suite, and no handling
- // of the promise returned by runTestCases() is needed.
- runTestCasesAndFinish()
- {
- function finish() {
- this._harness.completeTest();
- }
-
- this.runTestCases()
- .then(finish.bind(this))
- .catch(finish.bind(this));
- }
-
- runTestCases()
- {
- if (!this.testcases.length)
- throw new Error("Tried to call runTestCases() for suite with no test cases");
- if (this._startedRunning)
- throw new Error("Tried to call runTestCases() more than once.");
-
- this._startedRunning = true;
-
- this._harness.log("");
- this._harness.log("== Running test suite: " + this.name);
-
- // Avoid adding newlines if nothing was logged.
- var priorLogCount = this._harness.logCount;
- var suite = this;
- var result = this.testcases.reduce(function(chain, testcase, i) {
- return chain.then(function() {
- if (i > 0 && priorLogCount + 1 < suite._harness.logCount)
- suite._harness.log("");
-
- priorLogCount = suite._harness.logCount;
- suite._harness.log("-- Running test case: " + testcase.name);
- suite.runCount++;
- return new Promise(testcase.test);
- });
- }, Promise.resolve());
-
- return result.catch(function(e) {
- suite.failCount++;
- var message = e;
- if (e instanceof Error)
- message = e.message;
-
- if (typeof message !== "string")
- message = JSON.stringify(message);
-
- suite._harness.log("!! EXCEPTION: " + message);
- throw e; // Reject this promise by re-throwing the error.
- });
- }
-}
-
-InjectedTestHarness.SyncTestSuite = class SyncTestSuite
-{
- constructor(harness, name) {
- if (!(harness instanceof InjectedTestHarness))
- throw new Error("Must pass the test's harness as the first argument.");
-
- if (!name || typeof name !== "string")
- throw new Error("Tried to create SyncTestSuite without string suite name.");
-
- this.name = name;
- this._harness = harness;
-
- this.testcases = [];
- this.runCount = 0;
- this.failCount = 0;
- }
-
- get passCount()
- {
- return this.runCount - this.failCount;
- }
-
- get skipCount()
- {
- if (this.failCount)
- return this.testcases.length - this.runCount;
- else
- return 0;
- }
-
- addTestCase(testcase)
- {
- if (!testcase || !(testcase instanceof Object))
- throw new Error("Tried to add non-object test case.");
-
- if (typeof testcase.name !== "string")
- throw new Error("Tried to add test case without a name.");
-
- if (typeof testcase.test !== "function")
- throw new Error("Tried to add test case without `test` function.");
-
- this.testcases.push(testcase);
- }
-
- // Use this if the test file only has one suite.
- runTestCasesAndFinish()
- {
- this.runTestCases();
- this._harness.completeTest();
- }
-
- runTestCases()
- {
- if (!this.testcases.length)
- throw new Error("Tried to call runTestCases() for suite with no test cases");
- if (this._startedRunning)
- throw new Error("Tried to call runTestCases() more than once.");
-
- this._startedRunning = true;
-
- this._harness.log("");
- this._harness.log("== Running test suite: " + this.name);
-
- var priorLogCount = this._harness.logCount;
- var suite = this;
- for (var i = 0; i < this.testcases.length; i++) {
- var testcase = this.testcases[i];
- if (i > 0 && priorLogCount + 1 < this._harness.logCount)
- this._harness.log("");
-
- priorLogCount = this._harness.logCount;
-
- this._harness.log("-- Running test case: " + testcase.name);
- suite.runCount++;
- try {
- var result = testcase.test.call(null);
- if (result === false) {
- suite.failCount++;
- return false;
- }
- } catch (e) {
- suite.failCount++;
- var message = e;
- if (e instanceof Error)
- message = e.message;
- else
- e = new Error(e);
-
- if (typeof message !== "string")
- message = JSON.stringify(message);
-
- this._harness.log("!! EXCEPTION: " + message);
- return false;
- }
- }
-
- return true;
- }
-}
-
-class ProtocolTestHarness extends InjectedTestHarness
-{
- // InjectedTestHarness Overrides
-
- completeTest()
- {
- this.evaluateInPage("closeTest();");
- }
-
- addResult(message)
- {
- // Unfortunately, every string argument must be escaped because tests are not consistent
- // with respect to escaping with single or double quotes. Some exceptions use single quotes.
- var stringifiedMessage = typeof message !== "string" ? JSON.stringify(message) : message;
- this.evaluateInPage("log(unescape('" + escape(stringifiedMessage) + "'));");
- }
-
- debugLog(message)
- {
- var stringifiedMessage = typeof message !== "string" ? JSON.stringify(message) : message;
- this.evaluateInPage("debugLog(unescape('" + escape(stringifiedMessage) + "'));")
- }
-
- evaluateInPage(_expression_, callback)
- {
- let args = {
- method: "Runtime.evaluate",
- params: {_expression_}
- }
-
- if (typeof callback === "function")
- InspectorProtocol.sendCommand(args, callback);
- else
- return InspectorProtocol.awaitCommand(args);
- }
-}
-
-window.ProtocolTest = new ProtocolTestHarness();
-
-InspectorProtocol = {};
-InspectorProtocol._dispatchTable = [];
-InspectorProtocol._requestId = -1;
-InspectorProtocol.eventHandler = {};
-
-InspectorProtocol.dumpInspectorProtocolMessages = false;
-
-InspectorProtocol.sendCommand = function(methodOrObject, params, handler)
-{
- // Allow new-style arguments object, as in awaitCommand.
- var method = methodOrObject;
- if (typeof methodOrObject === "object")
- var {method, params, handler} = methodOrObject;
-
- this._dispatchTable[++this._requestId] = handler;
- var messageObject = {method, params, "id": this._requestId};
- this.sendMessage(messageObject);
-
- return this._requestId;
-}
-
-InspectorProtocol.awaitCommand = function(args)
-{
- var {method, params} = args;
- return new Promise(function(resolve, reject) {
- this._dispatchTable[++this._requestId] = {resolve, reject};
- var messageObject = {method, params, "id": this._requestId};
- this.sendMessage(messageObject);
- }.bind(this));
-}
-
-InspectorProtocol.awaitEvent = function(args)
-{
- var {event} = args;
- if (typeof event !== "string")
- throw new Error("Event must be a string.");
-
- return new Promise(function(resolve, reject) {
- InspectorProtocol.eventHandler[event] = function(message) {
- InspectorProtocol.eventHandler[event] = undefined;
- resolve(message);
- }
- });
-}
-
-InspectorProtocol.addEventListener = function(eventTypeOrObject, listener)
-{
- var event = eventTypeOrObject;
- if (typeof eventTypeOrObject === "object")
- var {event, listener} = eventTypeOrObject;
-
- if (typeof event !== "string")
- throw new Error("Event name must be a string.");
-
- if (typeof listener !== "function")
- throw new Error("Event listener must be callable.");
-
- // Convert to an array of listeners.
- var listeners = InspectorProtocol.eventHandler[event];
- if (!listeners)
- listeners = InspectorProtocol.eventHandler[event] = [];
- else if (typeof listeners === "function")
- listeners = InspectorProtocol.eventHandler[event] = [listeners];
-
- // Prevent registering multiple times.
- if (listeners.includes(listener))
- throw new Error("Cannot register the same listener more than once.");
-
- listeners.push(listener);
-}
-
-InspectorProtocol.sendMessage = function(messageObject)
-{
- // This matches the debug dumping in InspectorBackend, which is bypassed
- // by InspectorProtocol. Return messages should be dumped by InspectorBackend.
- if (InspectorProtocol.dumpInspectorProtocolMessages)
- console.log("frontend: " + JSON.stringify(messageObject));
-
- InspectorFrontendHost.sendMessageToBackend(JSON.stringify(messageObject));
-}
-
-InspectorProtocol.checkForError = function(responseObject)
-{
- if (responseObject.error) {
- ProtocolTest.log("PROTOCOL ERROR: " + JSON.stringify(responseObject.error));
- ProtocolTest.completeTest();
- throw "PROTOCOL ERROR";
- }
-}
-
-InspectorFrontendAPI.dispatchMessageAsync = function(messageObject)
-{
- // This matches the debug dumping in InspectorBackend, which is bypassed
- // by InspectorProtocol. Return messages should be dumped by InspectorBackend.
- if (InspectorProtocol.dumpInspectorProtocolMessages)
- console.log("backend: " + JSON.stringify(messageObject));
-
- // If the message has an id, then it is a reply to a command.
- var messageId = messageObject["id"];
- if (typeof messageId === "number") {
- var handler = InspectorProtocol._dispatchTable[messageId];
- if (!handler)
- return;
-
- if (typeof handler === "function")
- handler(messageObject);
- else if (typeof handler === "object") {
- var {resolve, reject} = handler;
- if ("error" in messageObject)
- reject(messageObject.error.message);
- else
- resolve(messageObject.result);
- }
- // Otherwise, it is an event.
- } else {
- var eventName = messageObject["method"];
- var handler = InspectorProtocol.eventHandler[eventName];
- if (!handler)
- return;
-
- if (typeof handler === "function")
- handler(messageObject);
- else if (handler instanceof Array) {
- handler.map(function(listener) {
- listener.call(null, messageObject);
- });
- } else if (typeof handler === "object") {
- var {resolve, reject} = handler;
- if ("error" in messageObject)
- reject(messageObject.error.message);
- else
- resolve(messageObject.result);
- }
- }
-}
-
-window.addEventListener("message", function(event) {
- try {
- eval(event.data);
- } catch (e) {
- alert(e.stack);
- ProtocolTest.completeTest();
- throw e;
- }
-});
\ No newline at end of file
Added: trunk/Source/WebInspectorUI/UserInterface/Test/InspectorProtocol.js (0 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Test/InspectorProtocol.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/InspectorProtocol.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -0,0 +1,159 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2014, 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 "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ */
+
+InspectorProtocol = {};
+InspectorProtocol._dispatchTable = [];
+InspectorProtocol._requestId = -1;
+InspectorProtocol.eventHandler = {};
+
+InspectorProtocol.sendCommand = function(methodOrObject, params, handler)
+{
+ // Allow new-style arguments object, as in awaitCommand.
+ let method = methodOrObject;
+ if (typeof methodOrObject === "object")
+ var {method, params, handler} = methodOrObject;
+
+ this._dispatchTable[++this._requestId] = handler;
+ let messageObject = {method, params, id: this._requestId};
+ this.sendMessage(messageObject);
+
+ return this._requestId;
+}
+
+InspectorProtocol.awaitCommand = function(args)
+{
+ let {method, params} = args;
+ return new Promise(function(resolve, reject) {
+ this._dispatchTable[++this._requestId] = {resolve, reject};
+ let messageObject = {method, params, id: this._requestId};
+ this.sendMessage(messageObject);
+ }.bind(this));
+}
+
+InspectorProtocol.awaitEvent = function(args)
+{
+ let event = args.event;
+ if (typeof event !== "string")
+ throw new Error("Event must be a string.");
+
+ return new Promise(function(resolve, reject) {
+ InspectorProtocol.eventHandler[event] = function(message) {
+ InspectorProtocol.eventHandler[event] = undefined;
+ resolve(message);
+ }
+ });
+}
+
+InspectorProtocol.addEventListener = function(eventTypeOrObject, listener)
+{
+ let event = eventTypeOrObject;
+ if (typeof eventTypeOrObject === "object")
+ var {event, listener} = eventTypeOrObject;
+
+ if (typeof event !== "string")
+ throw new Error("Event name must be a string.");
+
+ if (typeof listener !== "function")
+ throw new Error("Event listener must be callable.");
+
+ // Convert to an array of listeners.
+ let listeners = InspectorProtocol.eventHandler[event];
+ if (!listeners)
+ listeners = InspectorProtocol.eventHandler[event] = [];
+ else if (typeof listeners === "function")
+ listeners = InspectorProtocol.eventHandler[event] = [listeners];
+
+ // Prevent registering multiple times.
+ if (listeners.includes(listener))
+ throw new Error("Cannot register the same listener more than once.");
+
+ listeners.push(listener);
+}
+
+InspectorProtocol.sendMessage = function(messageObject)
+{
+ // This matches the debug dumping in InspectorBackend, which is bypassed
+ // by InspectorProtocol. Return messages should be dumped by InspectorBackend.
+ if (ProtocolTest.dumpInspectorProtocolMessages)
+ console.log("frontend: " + JSON.stringify(messageObject));
+
+ InspectorFrontendHost.sendMessageToBackend(JSON.stringify(messageObject));
+}
+
+InspectorProtocol.checkForError = function(responseObject)
+{
+ if (responseObject.error) {
+ ProtocolTest.log("PROTOCOL ERROR: " + JSON.stringify(responseObject.error));
+ ProtocolTest.completeTest();
+ throw "PROTOCOL ERROR";
+ }
+}
+
+InspectorProtocol.dispatchMessageFromBackend = function(messageObject)
+{
+ // This matches the debug dumping in InspectorBackend, which is bypassed
+ // by InspectorProtocol. Return messages should be dumped by InspectorBackend.
+ if (ProtocolTest.dumpInspectorProtocolMessages)
+ console.log("backend: " + JSON.stringify(messageObject));
+
+ // If the message has an id, then it is a reply to a command.
+ let messageId = messageObject.id;
+ if (typeof messageId === "number") {
+ let handler = InspectorProtocol._dispatchTable[messageId];
+ if (!handler)
+ return;
+
+ if (typeof handler === "function")
+ handler(messageObject);
+ else if (typeof handler === "object") {
+ let {resolve, reject} = handler;
+ if ("error" in messageObject)
+ reject(messageObject.error.message);
+ else
+ resolve(messageObject.result);
+ }
+ // Otherwise, it is an event.
+ } else {
+ let eventName = messageObject["method"];
+ let handler = InspectorProtocol.eventHandler[eventName];
+ if (!handler)
+ return;
+
+ if (typeof handler === "function")
+ handler(messageObject);
+ else if (handler instanceof Array) {
+ handler.map(function(listener) {
+ listener.call(null, messageObject);
+ });
+ } else if (typeof handler === "object") {
+ let {resolve, reject} = handler;
+ if ("error" in messageObject)
+ reject(messageObject.error.message);
+ else
+ resolve(messageObject.result);
+ }
+ }
+}
\ No newline at end of file
Added: trunk/Source/WebInspectorUI/UserInterface/Test/ProtocolTestHarness.js (0 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Test/ProtocolTestHarness.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/ProtocolTestHarness.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -0,0 +1,61 @@
+/*
+ * Copyright (C) 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 "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ */
+
+ProtocolTestHarness = class ProtocolTestHarness extends TestHarness
+{
+ // TestHarness Overrides
+
+ completeTest()
+ {
+ this.evaluateInPage("TestPage.closeTest();");
+ }
+
+ addResult(message)
+ {
+ // Unfortunately, every string argument must be escaped because tests are not consistent
+ // with respect to escaping with single or double quotes. Some exceptions use single quotes.
+ let stringifiedMessage = typeof message !== "string" ? JSON.stringify(message) : message;
+ this.evaluateInPage(`TestPage.log(unescape("${escape(stringifiedMessage)}"));`);
+ }
+
+ debugLog(message)
+ {
+ let stringifiedMessage = typeof message !== "string" ? JSON.stringify(message) : message;
+ this.evaluateInPage(`TestPage.debugLog(unescape("${escape(stringifiedMessage)}"));`);
+ }
+
+ evaluateInPage(_expression_, callback)
+ {
+ let args = {
+ method: "Runtime.evaluate",
+ params: {_expression_}
+ }
+
+ if (typeof callback === "function")
+ InspectorProtocol.sendCommand(args, callback);
+ else
+ return InspectorProtocol.awaitCommand(args);
+ }
+}
Copied: trunk/Source/WebInspectorUI/UserInterface/Test/Test.js (from rev 188542, trunk/Source/WebInspectorUI/UserInterface/Base/Test.js) (0 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Test/Test.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/Test.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -0,0 +1,279 @@
+/*
+ * Copyright (C) 2013, 2014 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 THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS
+ * IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
+ * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
+ * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * HOLDER OR 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.
+ */
+
+WebInspector.DebuggableType = {
+ Web: "web",
+ _javascript_: "_javascript_"
+};
+
+WebInspector.loaded = function()
+{
+ this.debuggableType = WebInspector.DebuggableType.Web;
+ this.hasExtraDomains = false;
+
+ // Register observers for events from the InspectorBackend.
+ // The initialization order should match the same in Main.js.
+ InspectorBackend.registerInspectorDispatcher(new WebInspector.InspectorObserver);
+ InspectorBackend.registerPageDispatcher(new WebInspector.PageObserver);
+ InspectorBackend.registerConsoleDispatcher(new WebInspector.ConsoleObserver);
+ InspectorBackend.registerDOMDispatcher(new WebInspector.DOMObserver);
+ InspectorBackend.registerNetworkDispatcher(new WebInspector.NetworkObserver);
+ InspectorBackend.registerDebuggerDispatcher(new WebInspector.DebuggerObserver);
+ InspectorBackend.registerTimelineDispatcher(new WebInspector.TimelineObserver);
+ InspectorBackend.registerCSSDispatcher(new WebInspector.CSSObserver);
+ InspectorBackend.registerRuntimeDispatcher(new WebInspector.RuntimeObserver);
+ if (InspectorBackend.registerReplayDispatcher)
+ InspectorBackend.registerReplayDispatcher(new WebInspector.ReplayObserver);
+
+ // Instantiate controllers used by tests.
+ this.frameResourceManager = new WebInspector.FrameResourceManager;
+ this.domTreeManager = new WebInspector.DOMTreeManager;
+ this.cssStyleManager = new WebInspector.CSSStyleManager;
+ this.logManager = new WebInspector.LogManager;
+ this.issueManager = new WebInspector.IssueManager;
+ this.runtimeManager = new WebInspector.RuntimeManager;
+ this.timelineManager = new WebInspector.TimelineManager;
+ this.debuggerManager = new WebInspector.DebuggerManager;
+ this.probeManager = new WebInspector.ProbeManager;
+ this.replayManager = new WebInspector.ReplayManager;
+
+ // Global controllers.
+ this.quickConsole = {executionContextIdentifier: undefined};
+
+ document.addEventListener("DOMContentLoaded", this.contentLoaded.bind(this));
+
+ // Enable agents.
+ InspectorAgent.enable();
+ ConsoleAgent.enable();
+
+ // Perform one-time tasks.
+ WebInspector.CSSCompletions.requestCSSCompletions();
+
+ // Global settings.
+ this.showShadowDOMSetting = new WebInspector.Setting("show-shadow-dom", true);
+}
+
+WebInspector.contentLoaded = function()
+{
+ // Signal that the frontend is now ready to receive messages.
+ InspectorFrontendAPI.loadCompleted();
+
+ // Tell the InspectorFrontendHost we loaded, which causes the window to display
+ // and pending InspectorFrontendAPI commands to be sent.
+ InspectorFrontendHost.loaded();
+}
+
+WebInspector.UIString = function(string)
+{
+ return string;
+}
+
+// Add stubs that are called by the frontend API.
+WebInspector.updateDockedState = function() {};
+WebInspector.updateDockingAvailability = function() {};
+
+// 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 = {};
+
+// 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: "inspector-test-test-page-did-load"
+};
+
+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 !== "object" ? 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 !== "object" ? message : JSON.stringify(message);
+ InspectorTest.addResult("ASSERT: " + stringifiedMessage);
+}
+
+// Appends a message in the test document whether the condition is true or not.
+InspectorTest.expectThat = function(condition, message)
+{
+ var prefix = condition ? "PASS" : "FAIL";
+ var stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
+ InspectorTest.addResult(prefix + ": " + 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("debugLog: " + message);
+
+ this.evaluateInPage("InspectorTestProxy.debugLog(unescape('" + escape(JSON.stringify(message)) + "'))");
+}
+
+// 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("PROTOCOL ERROR: " + error);
+ InspectorTest.completeTest();
+ throw "PROTOCOL ERROR";
+ }
+}
+
+InspectorTest.completeTest = function()
+{
+ if (InspectorTest.dumpMessagesToConsole)
+ InspectorFrontendHost.unbufferedLog("InspectorTest.completeTest()");
+
+ // 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, "InspectorTestProxy.completeTest()"));
+}
+
+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["error"]("Tried to evaluate in test page, but connection not yet established:", codeString);
+ return;
+ }
+
+ RuntimeAgent.evaluate.invoke({_expression_: codeString, objectGroup: "test", includeCommandLineAPI: false}, callback);
+}
+
+InspectorTest.addResult = function(text)
+{
+ this._results.push(text);
+
+ if (InspectorTest.dumpMessagesToConsole)
+ InspectorFrontendHost.unbufferedLog("addResult: " + text);
+
+ if (!this._testPageIsReloading)
+ this.evaluateInPage("InspectorTestProxy.addResult(unescape('" + escape(text) + "'))");
+}
+
+InspectorTest._resendResults = function()
+{
+ console.assert(this._shouldResendResults);
+ this._shouldResendResults = false;
+
+ for (var result of this._results)
+ this.evaluateInPage("InspectorTestProxy.addResult(unescape('" + escape(result) + "'))");
+}
+
+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 = "Uncaught exception in inspector page: " + message + " [" + url + ":" + lineNumber + "]";
+
+ // 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["error"](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 + ": " + Array.from(arguments).join(" "));
+ };
+ }
+
+ for (var type of ["log", "error", "info"]) {
+ InspectorTest._originalConsoleMethods[type] = console[type].bind(console);
+ console[type] = createProxyConsoleHandler(type.toUpperCase());
+ }
+})();
Added: trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js (0 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/TestHarness.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -0,0 +1,95 @@
+/*
+ * Copyright (C) 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 "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ */
+
+TestHarness = class TestHarness extends WebInspector.Object
+{
+ constructor()
+ {
+ super();
+
+ this._logCount = 0;
+ }
+
+ completeTest()
+ {
+ throw new Error("Must be implemented by subclasses.");
+ }
+
+ addResult()
+ {
+ throw new Error("Must be implemented by subclasses.");
+ }
+
+ debugLog()
+ {
+ throw new Error("Must be implemented by subclasses.");
+ }
+
+ evaluateInPage(string, callback)
+ {
+ throw new Error("Must be implemented by subclasses.");
+ }
+
+ createAsyncSuite(name)
+ {
+ return new AsyncTestSuite(this, name);
+ }
+
+ createSyncSuite(name)
+ {
+ return new SyncTestSuite(this, name);
+ }
+
+ get logCount()
+ {
+ return this._logCount;
+ }
+
+ log(message)
+ {
+ ++this._logCount;
+
+ if (this.forceSyncDebugLogging)
+ this.debugLog(message);
+ else
+ this.addResult(message);
+ }
+
+ assert(condition, message)
+ {
+ if (condition)
+ return;
+
+ let stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
+ this.addResult("ASSERT: " + stringifiedMessage);
+ }
+
+ expectThat(condition, message)
+ {
+ let prefix = condition ? "PASS" : "FAIL";
+ let stringifiedMessage = typeof message !== "object" ? message : JSON.stringify(message);
+ this.addResult(`${prefix}: ${stringifiedMessage}`);
+ }
+};
Added: trunk/Source/WebInspectorUI/UserInterface/Test/TestStub.js (0 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Test/TestStub.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/TestStub.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -0,0 +1,40 @@
+/*
+ * Copyright (C) 2012 Samsung Electronics. All rights reserved.
+ * Copyright (C) 2014, 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 "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ */
+
+InspectorFrontendAPI = {};
+InspectorFrontendAPI.dispatchMessageAsync = InspectorProtocol.dispatchMessageFromBackend;
+
+window.ProtocolTest = new ProtocolTestHarness();
+
+window.addEventListener("message", function(event) {
+ try {
+ eval(event.data);
+ } catch (e) {
+ alert(e.stack);
+ ProtocolTest.completeTest();
+ throw e;
+ }
+});
Added: trunk/Source/WebInspectorUI/UserInterface/Test/TestSuite.js (0 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Test/TestSuite.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Test/TestSuite.js 2015-08-17 21:51:45 UTC (rev 188544)
@@ -0,0 +1,195 @@
+/*
+ * Copyright (C) 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 "AS IS" AND ANY
+ * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
+ * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
+ * DISCLAIMED. IN NO EVENT SHALL APPLE 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.
+ */
+
+TestSuite = class TestSuite extends WebInspector.Object
+{
+ constructor(harness, name) {
+ if (!(harness instanceof TestHarness))
+ throw new Error("Must pass the test's harness as the first argument.");
+
+ if (typeof name !== "string" || !name.trim().length)
+ throw new Error("Tried to create TestSuite without string suite name.");
+
+ super();
+
+ this.name = name;
+ this._harness = harness;
+
+ this.testcases = [];
+ this.runCount = 0;
+ this.failCount = 0;
+ }
+
+ // Use this if the test file only has one suite, and no handling
+ // of the value returned by runTestCases() is needed.
+ runTestCasesAndFinish()
+ {
+ throw new Error("Must be implemented by subclasses.");
+ }
+
+ runTestCases()
+ {
+ throw new Error("Must be implemented by subclasses.");
+ }
+
+ get passCount()
+ {
+ return this.runCount - this.failCount;
+ }
+
+ get skipCount()
+ {
+ if (this.failCount)
+ return this.testcases.length - this.runCount;
+ else
+ return 0;
+ }
+
+ addTestCase(testcase)
+ {
+ if (!testcase || !(testcase instanceof Object))
+ throw new Error("Tried to add non-object test case.");
+
+ if (typeof testcase.name !== "string" || !testcase.name.trim().length)
+ throw new Error("Tried to add test case without a name.");
+
+ if (typeof testcase.test !== "function")
+ throw new Error("Tried to add test case without `test` function.");
+
+ this.testcases.push(testcase);
+ }
+};
+
+AsyncTestSuite = class AsyncTestSuite extends TestSuite
+{
+ runTestCasesAndFinish()
+ {
+ function finish() {
+ this._harness.completeTest();
+ }
+
+ this.runTestCases()
+ .then(finish.bind(this))
+ .catch(finish.bind(this));
+ }
+
+ runTestCases()
+ {
+ if (!this.testcases.length)
+ throw new Error("Tried to call runTestCases() for suite with no test cases");
+ if (this._startedRunning)
+ throw new Error("Tried to call runTestCases() more than once.");
+
+ this._startedRunning = true;
+
+ this._harness.log("");
+ this._harness.log("== Running test suite: " + this.name);
+
+ // Avoid adding newlines if nothing was logged.
+ let priorLogCount = this._harness.logCount;
+ let self = this;
+ let result = this.testcases.reduce(function(chain, testcase, i) {
+ return chain.then(function() {
+ if (i > 0 && priorLogCount + 1 < self._harness.logCount)
+ self._harness.log("");
+
+ priorLogCount = self._harness.logCount;
+ self._harness.log("-- Running test case: " + testcase.name);
+ self.runCount++;
+ return new Promise(testcase.test);
+ });
+ }, Promise.resolve());
+
+ return result.catch(function(e) {
+ self.failCount++;
+ let message = e;
+ if (e instanceof Error)
+ message = e.message;
+
+ if (typeof message !== "string")
+ message = JSON.stringify(message);
+
+ self._harness.log("!! EXCEPTION: " + message);
+ throw e; // Reject this promise by re-throwing the error.
+ });
+ }
+};
+
+SyncTestSuite = class SyncTestSuite extends TestSuite
+{
+ runTestCasesAndFinish()
+ {
+ this.runTestCases();
+ this._harness.completeTest();
+ }
+
+ runTestCases()
+ {
+ if (!this.testcases.length)
+ throw new Error("Tried to call runTestCases() for suite with no test cases");
+ if (this._startedRunning)
+ throw new Error("Tried to call runTestCases() more than once.");
+
+ this._startedRunning = true;
+
+ this._harness.log("");
+ this._harness.log("== Running test suite: " + this.name);
+
+ let priorLogCount = this._harness.logCount;
+ let self = this;
+ for (let i = 0; i < this.testcases.length; i++) {
+ let testcase = this.testcases[i];
+ if (i > 0 && priorLogCount + 1 < this._harness.logCount)
+ this._harness.log("");
+
+ priorLogCount = this._harness.logCount;
+
+ this._harness.log("-- Running test case: " + testcase.name);
+ self.runCount++;
+ try {
+ let result = testcase.test.call(null);
+ if (result === false) {
+ self.failCount++;
+ return false;
+ }
+ } catch (e) {
+ self.failCount++;
+ let message = e;
+ if (e instanceof Error)
+ message = e.message;
+ else
+ e = new Error(e);
+
+ if (typeof message !== "string")
+ message = JSON.stringify(message);
+
+ this._harness.log("!! EXCEPTION: " + message);
+ return false;
+ }
+ }
+
+ return true;
+ }
+};
Modified: trunk/Source/WebInspectorUI/UserInterface/Test.html (188543 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/Test.html 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/Source/WebInspectorUI/UserInterface/Test.html 2015-08-17 21:51:45 UTC (rev 188544)
@@ -32,7 +32,7 @@
<script src=""
<script src=""
- <script src=""
+ <script src=""
<script src=""
<script src=""
Modified: trunk/Source/WebInspectorUI/UserInterface/TestStub.html (188543 => 188544)
--- trunk/Source/WebInspectorUI/UserInterface/TestStub.html 2015-08-17 21:50:24 UTC (rev 188543)
+++ trunk/Source/WebInspectorUI/UserInterface/TestStub.html 2015-08-17 21:51:45 UTC (rev 188544)
@@ -22,8 +22,29 @@
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-->
+<!DOCTYPE html>
<html>
<head>
- <script type="text/_javascript_" src=""
+ <meta http-equiv="Content-Type" content="text/html; charset=utf-8">
+ <!--
+ These resources should match the order and groups used in Main.html and Test.html.
+ -->
+ <script src=""
+ <script src=""
+
+ <script src=""
+ <script src=""
+ <script src=""
+
+ <script src=""
+
+ <script src=""
+ <script>
+ // Not reliable unless console messages are dumped to console. See wiki for details.
+ ProtocolTest.dumpInspectorProtocolMessages = false;
+
+ // Synchronous logging may produce more output prior to a timeout.
+ ProtocolTest.forceSyncDebugLogging = false;
+ </script>
</head>
</html>