Diff
Modified: trunk/LayoutTests/ChangeLog (188538 => 188539)
--- trunk/LayoutTests/ChangeLog 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/ChangeLog 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,3 +1,46 @@
+2015-08-17 Brian Burg <[email protected]>
+
+ Web Inspector: load ProtocolTestStub from the WebInspectorUI bundle
+ https://bugs.webkit.org/show_bug.cgi?id=147955
+
+ Reviewed by Timothy Hatcher.
+
+ Since the inspector stub cannot open files that live in the LayoutTests
+ directory, adopt the test helper marshalling approach used by inspector.js.
+ Each helper must register its code for marshalling and explicitly put globals
+ on the window object.
+
+ Use script tags rather than importScript to include helpers in a test.
+
+ * TestExpectations: For now, skip inspector http tests. These should be rewritten
+ to use inspector-test.js, which does not run into cross-origin problems.
+
+ Rebaseline some test results to account for shifted line numbers (yuck).
+
+ * 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:
+ (ProtocolTestProxy.registerInitializer):
+ (log):
+ (runTest.runInitializationMethodsInFrontend):
+ (runTest.runTestMethodInFrontend):
+ (runTest):
+ * inspector/console/console-message.html:
+ * inspector/console/css-source-locations-expected.txt:
+ * inspector/console/css-source-locations.html:
+ * inspector/console/js-source-locations-expected.txt:
+ * inspector/console/js-source-locations.html:
+ * inspector/console/x-frame-options-message-expected.txt:
+ * inspector/console/x-frame-options-message.html:
+ * inspector/debugger/didSampleProbe-multiple-probes.html:
+ * inspector/debugger/setBreakpoint-actions.html:
+ * inspector/debugger/setBreakpoint-options-exception.html:
+ * inspector/dom/dom-search-expected.txt:
+ * inspector/dom/dom-search-with-context.html:
+ * inspector/dom/dom-search.html:
+ * inspector/dom/resources/dom-search-queries.js:
+
2015-08-17 Simon Fraser <[email protected]>
will-change should sometimes trigger compositing
Modified: trunk/LayoutTests/TestExpectations (188538 => 188539)
--- trunk/LayoutTests/TestExpectations 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/TestExpectations 2015-08-17 20:33:48 UTC (rev 188539)
@@ -94,6 +94,9 @@
webkit.org/b/129057 media/controls-styling-strict.html [ Pass Failure ]
+# These tests will be rewritten, just skip them until that time.
+webkit.org/b/148036 http/tests/inspector/ [ Skip ]
+
webkit.org/b/129639 inspector/dom/dom-search-crash.html [ Skip ]
webkit.org/b/133761 inspector/debugger/breakpoint-action-detach.html [ Skip ]
Modified: trunk/LayoutTests/http/tests/inspector/dom/resources/InspectorDOMListener.js (188538 => 188539)
--- trunk/LayoutTests/http/tests/inspector/dom/resources/InspectorDOMListener.js 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/http/tests/inspector/dom/resources/InspectorDOMListener.js 2015-08-17 20:33:48 UTC (rev 188539)
@@ -27,7 +27,9 @@
* SUCH DAMAGE.
*/
-function createDOMListener()
+ProtocolTestProxy.registerInitializer(function(){
+
+window.createDOMListener = function()
{
var nodesById = {};
@@ -101,3 +103,5 @@
collectNode: collectNode
};
}
+
+});
Deleted: trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.html (188538 => 188539)
--- trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,30 +0,0 @@
-<!--
-Copyright (C) 2012 Samsung Electronics. All rights reserved.
-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.
--->
-<html>
-<head>
- <script type="text/_javascript_" src=""
-</head>
-</html>
Deleted: trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.js (188538 => 188539)
--- trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.js 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.js 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,498 +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);
- }
-
- importScript(scriptName)
- {
- var xhr = new XMLHttpRequest();
- var isAsyncRequest = false;
- xhr.open("GET", scriptName, isAsyncRequest);
- xhr.send(null);
- if (xhr.status !== 0 && xhr.status !== 200)
- throw new Error("Invalid script URL: " + scriptName);
- var script = `// From InjectedTestHarness.importScript(${scriptName})
-try {
- ${xhr.responseText}
-} catch (e) {
- alert(${JSON.stringify("Error in: " + scriptName)});
- throw e;
-}`;
- window.eval(script);
- }
-
- 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
Modified: trunk/LayoutTests/http/tests/inspector/resources/console-test.js (188538 => 188539)
--- trunk/LayoutTests/http/tests/inspector/resources/console-test.js 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/http/tests/inspector/resources/console-test.js 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,3 +1,5 @@
+ProtocolTestProxy.registerInitializer(function() {
+
ProtocolTest.Console = {};
ProtocolTest.Console.sanitizeConsoleMessage = function(messageObject)
@@ -73,3 +75,5 @@
}
});
}
+
+});
Modified: trunk/LayoutTests/http/tests/inspector/resources/probe-test.js (188538 => 188539)
--- trunk/LayoutTests/http/tests/inspector/resources/probe-test.js 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/http/tests/inspector/resources/probe-test.js 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,3 +1,5 @@
+ProtocolTestProxy.registerInitializer(function() {
+
ProtocolTest.Probe = {};
ProtocolTest.Probe.sanitizeProbeSample = function(messageObject)
@@ -125,3 +127,5 @@
InspectorTest.log("Probe set's probe count: " + probeSet.probes.length);
});
}
+
+});
Modified: trunk/LayoutTests/http/tests/inspector/resources/protocol-test.js (188538 => 188539)
--- trunk/LayoutTests/http/tests/inspector/resources/protocol-test.js 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/http/tests/inspector/resources/protocol-test.js 2015-08-17 20:33:48 UTC (rev 188539)
@@ -23,8 +23,22 @@
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
* THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-var outputElement;
+// This namespace is injected into every test page. Its functions are invoked by
+// ProtocolTest methods on the inspector page via InjectedTestHarness.
+ProtocolTestProxy = {};
+ProtocolTestProxy._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)
+{
+ 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
@@ -40,10 +54,10 @@
function log(text)
{
if (!outputElement) {
- var intermediate = document.createElement("div");
+ let intermediate = document.createElement("div");
document.body.appendChild(intermediate);
- var intermediate2 = document.createElement("div");
+ let intermediate2 = document.createElement("div");
intermediate.appendChild(intermediate2);
outputElement = document.createElement("div");
@@ -77,27 +91,46 @@
testRunner.waitUntilDone();
testRunner.setCanOpenWindows(true);
- var scriptTags = document.getElementsByTagName("script");
- var scriptUrlBasePath = "";
- for (var i = 0; i < scriptTags.length; ++i) {
- var index = scriptTags[i].src.lastIndexOf("/protocol-test.js");
- if (index > -1 ) {
- scriptUrlBasePath = scriptTags[i].src.slice(0, index);
- break;
+ let testFunction = window.test;
+ if (!(typeof testFunction === "function")) {
+ alert("Failed to send test() because it is not a function.");
+ testRunner.notifyDone();
+ }
+
+ let url = ""
+ if (!url) {
+ alert("Failed to obtain inspector test stub URL.");
+ testRunner.notifyDone();
+ }
+
+ function runInitializationMethodsInFrontend(initializers)
+ {
+ for (let initializer of initializers) {
+ try {
+ initializer();
+ } catch (e) {
+ ProtocolTest.log("Exception in test initialization: " + e, e.stack || "(no stack trace)");
+ ProtocolTest.completeTest();
+ }
}
}
- var url = "" + "/ProtocolTestStub.html";
- var inspectorFrontend = window.internals.openDummyInspectorFrontend(url);
+ function runTestMethodInFrontend(testFunction)
+ {
+ try {
+ testFunction();
+ } catch (e) {
+ ProtocolTest.log("Exception during test execution: " + e, e.stack || "(no stack trace)");
+ ProtocolTest.completeTest();
+ }
+ }
+
+ let inspectorFrontend = window.internals.openDummyInspectorFrontend(url);
inspectorFrontend.addEventListener("load", function(event) {
- // FIXME: rename this 'test' global field across all tests.
- var testFunction = window.test;
- if (typeof testFunction === "function") {
- inspectorFrontend.postMessage("(" + testFunction.toString() +")();", "*");
- return;
- }
- // Kill waiting process if failed to send.
- alert("Failed to send test function");
- testRunner.notifyDone();
+ let initializationCodeString = `(${runInitializationMethodsInFrontend.toString()})([${ProtocolTestProxy._initializers}]);`;
+ let testFunctionCodeString = `(${runTestMethodInFrontend.toString()})(${testFunction.toString()});`;
+
+ inspectorFrontend.postMessage(initializationCodeString, "*");
+ inspectorFrontend.postMessage(testFunctionCodeString, "*");
});
}
Modified: trunk/LayoutTests/inspector/console/console-message.html (188538 => 188539)
--- trunk/LayoutTests/inspector/console/console-message.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/console/console-message.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -2,6 +2,7 @@
<html>
<head>
<script src=""
+<script src=""
<script>
function generateSimpleConsoleMessages()
{
@@ -14,7 +15,6 @@
function test()
{
- ProtocolTest.importScript("console-test.js");
var suite = ProtocolTest.createAsyncSuite("Console.MessagesFromCommandLineAPI");
Modified: trunk/LayoutTests/inspector/console/css-source-locations-expected.txt (188538 => 188539)
--- trunk/LayoutTests/inspector/console/css-source-locations-expected.txt 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/console/css-source-locations-expected.txt 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,8 +1,8 @@
Tests that CSS parser warnings from inline style tags and external stylesheets are sent to the console with correct line and column information.
-{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:6:20"}
-{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:7:14"}
-{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:8:7"}
-{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:10:8"}
+{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:7:20"}
+{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:8:14"}
+{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:9:7"}
+{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"css-source-locations.html:11:8"}
{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"errors.css:1:7"}
{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"errors.css:1:29"}
{"source":"css","level":"warning","text":"Invalid CSS property declaration at: *","location":"errors.css:4:5"}
Modified: trunk/LayoutTests/inspector/console/css-source-locations.html (188538 => 188539)
--- trunk/LayoutTests/inspector/console/css-source-locations.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/console/css-source-locations.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -2,6 +2,7 @@
<html>
<head>
<script src=""
+<script src=""
<link rel="stylesheet" href=""
<style> div { * color: red; }</style>
<style>div { * color: red; }
@@ -15,8 +16,6 @@
<script>
function test()
{
- ProtocolTest.importScript("console-test.js");
-
var consoleMessageCount = 0;
const expectedConsoleMessageCount = 7;
Modified: trunk/LayoutTests/inspector/console/js-source-locations-expected.txt (188538 => 188539)
--- trunk/LayoutTests/inspector/console/js-source-locations-expected.txt 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/console/js-source-locations-expected.txt 2015-08-17 20:33:48 UTC (rev 188539)
@@ -2,17 +2,17 @@
CONSOLE MESSAGE: line 1: warn script
CONSOLE MESSAGE: line 5: error script
CONSOLE MESSAGE: line 6: warn script
-CONSOLE MESSAGE: line 6: TypeError: undefined is not an object (evaluating '[].x.x')
-CONSOLE MESSAGE: line 8: warn 1
-CONSOLE MESSAGE: line 8: error 1
-CONSOLE MESSAGE: line 9: error 2
+CONSOLE MESSAGE: line 7: TypeError: undefined is not an object (evaluating '[].x.x')
+CONSOLE MESSAGE: line 9: warn 1
+CONSOLE MESSAGE: line 9: error 1
+CONSOLE MESSAGE: line 10: error 2
Tests that _javascript_ errors and warnings from inline script tags and external files are sent to the console with correct line and column information.
{"source":"console-api","level":"error","text":"error script","location":"errors.js:1:14","parameters":[{"type":"string"}]}
{"source":"console-api","level":"warning","text":"warn script","location":"errors.js:1:44","parameters":[{"type":"string"}]}
{"source":"console-api","level":"error","text":"error script","location":"errors.js:5:18","parameters":[{"type":"string"}]}
{"source":"console-api","level":"warning","text":"warn script","location":"errors.js:6:17","parameters":[{"type":"string"}]}
-{"source":"_javascript_","level":"error","text":"TypeError: undefined is not an object (evaluating '[].x.x')","location":"js-source-locations.html:6:18"}
-{"source":"console-api","level":"warning","text":"warn 1","location":"js-source-locations.html:8:13","parameters":[{"type":"string"}]}
-{"source":"console-api","level":"error","text":"error 1","location":"js-source-locations.html:8:38","parameters":[{"type":"string"}]}
-{"source":"console-api","level":"error","text":"error 2","location":"js-source-locations.html:9:17","parameters":[{"type":"string"}]}
+{"source":"_javascript_","level":"error","text":"TypeError: undefined is not an object (evaluating '[].x.x')","location":"js-source-locations.html:7:18"}
+{"source":"console-api","level":"warning","text":"warn 1","location":"js-source-locations.html:9:13","parameters":[{"type":"string"}]}
+{"source":"console-api","level":"error","text":"error 1","location":"js-source-locations.html:9:38","parameters":[{"type":"string"}]}
+{"source":"console-api","level":"error","text":"error 2","location":"js-source-locations.html:10:17","parameters":[{"type":"string"}]}
Modified: trunk/LayoutTests/inspector/console/js-source-locations.html (188538 => 188539)
--- trunk/LayoutTests/inspector/console/js-source-locations.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/console/js-source-locations.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -2,6 +2,7 @@
<html>
<head>
<script src=""
+<script src=""
<script src=""
<script> [].x.x </script>
<script>
@@ -11,8 +12,6 @@
<script>
function test()
{
- ProtocolTest.importScript("console-test.js");
-
var consoleMessageCount = 0;
const expectedConsoleMessageCount = 8;
Modified: trunk/LayoutTests/inspector/console/x-frame-options-message-expected.txt (188538 => 188539)
--- trunk/LayoutTests/inspector/console/x-frame-options-message-expected.txt 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/console/x-frame-options-message-expected.txt 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,4 +1,4 @@
-CONSOLE MESSAGE: line 42: Refused to display 'x-frame-options-message.html' in a frame because it set 'X-Frame-Options' to 'deny'.
+CONSOLE MESSAGE: line 41: Refused to display 'x-frame-options-message.html' in a frame because it set 'X-Frame-Options' to 'deny'.
== Running test suite: Console.XFrameOptionsMessages
Modified: trunk/LayoutTests/inspector/console/x-frame-options-message.html (188538 => 188539)
--- trunk/LayoutTests/inspector/console/x-frame-options-message.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/console/x-frame-options-message.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -2,11 +2,10 @@
<html>
<head>
<script src=""
+<script src=""
<script>
function test()
{
- ProtocolTest.importScript("console-test.js");
-
let suite = ProtocolTest.createAsyncSuite("Console.XFrameOptionsMessages");
ProtocolTest.Console.addTestCase(suite, {
Modified: trunk/LayoutTests/inspector/debugger/didSampleProbe-multiple-probes.html (188538 => 188539)
--- trunk/LayoutTests/inspector/debugger/didSampleProbe-multiple-probes.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/debugger/didSampleProbe-multiple-probes.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,12 +1,11 @@
<html>
<head>
<script src=""
+<script src=""
<script src=""
<script>
function test()
{
- ProtocolTest.importScript("probe-test.js");
-
InspectorProtocol.sendCommand("Debugger.enable", {});
var samples = [];
Modified: trunk/LayoutTests/inspector/debugger/setBreakpoint-actions.html (188538 => 188539)
--- trunk/LayoutTests/inspector/debugger/setBreakpoint-actions.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/debugger/setBreakpoint-actions.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,13 +1,12 @@
<html>
<head>
<script src=""
+<script src=""
+<script src=""
<script src=""
<script>
function test()
{
- ProtocolTest.importScript("console-test.js");
- ProtocolTest.importScript("probe-test.js");
-
InspectorProtocol.sendCommand("Console.enable", {});
InspectorProtocol.sendCommand("Debugger.enable", {});
Modified: trunk/LayoutTests/inspector/debugger/setBreakpoint-options-exception.html (188538 => 188539)
--- trunk/LayoutTests/inspector/debugger/setBreakpoint-options-exception.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/debugger/setBreakpoint-options-exception.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,12 +1,11 @@
<html>
<head>
<script src=""
+<script src=""
<script src=""
<script>
function test()
{
- ProtocolTest.importScript("console-test.js");
-
InspectorProtocol.sendCommand("Console.enable", {});
InspectorProtocol.sendCommand("Debugger.enable", {});
Modified: trunk/LayoutTests/inspector/dom/dom-search-expected.txt (188538 => 188539)
--- trunk/LayoutTests/inspector/dom/dom-search-expected.txt 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/dom/dom-search-expected.txt 2015-08-17 20:33:48 UTC (rev 188539)
@@ -48,11 +48,13 @@
=== Query: ".body-inside-iframe" ===
Count: 0
=== Query: "*" ===
-Count: 12
+Count: 14
html
head
script
script
+script
+script
body.main-frame
p
iframe
Modified: trunk/LayoutTests/inspector/dom/dom-search-with-context.html (188538 => 188539)
--- trunk/LayoutTests/inspector/dom/dom-search-with-context.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/dom/dom-search-with-context.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,11 +1,11 @@
<html>
<head>
<script type="text/_javascript_" src=""
+<script type="text/_javascript_" src=""
<script>
function test()
{
// Create a DOM listener to convert nodeIds to tag names.
- ProtocolTest.importScript("../dom/resources/InspectorDOMListener.js");
var dom = createDOMListener();
// Caching the output to avoid searching through the log.
Modified: trunk/LayoutTests/inspector/dom/dom-search.html (188538 => 188539)
--- trunk/LayoutTests/inspector/dom/dom-search.html 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/dom/dom-search.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,14 +1,13 @@
<html>
<head>
<script type="text/_javascript_" src=""
+<script type="text/_javascript_" src=""
+<!-- Loading the queries from external file to avoid having them show up in the results. -->
+<script type="text/_javascript_" src=""
<script>
function test()
{
- // Loading the queries from external file to avoid having them show up in the results.
- ProtocolTest.importScript("../../../../inspector/dom/resources/dom-search-queries.js");
-
// Create a DOM listener to convert nodeIds to tag names.
- ProtocolTest.importScript("../dom/resources/InspectorDOMListener.js");
var dom = createDOMListener();
// Caching the output to avoid searching through the log.
Modified: trunk/LayoutTests/inspector/dom/resources/dom-search-queries.js (188538 => 188539)
--- trunk/LayoutTests/inspector/dom/resources/dom-search-queries.js 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/LayoutTests/inspector/dom/resources/dom-search-queries.js 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,6 +1,8 @@
+ProtocolTestProxy.registerInitializer(function() {
+
// Having the queries in an external file, so that DOM search will not find the script when searching for values.
-var domSearchQueries = [
+window.domSearchQueries = [
"body",
"<body",
"body>",
@@ -28,4 +30,6 @@
"/html/body",
"/html/body/@onload",
"/HTML/BODY"
-];
\ No newline at end of file
+];
+
+});
\ No newline at end of file
Modified: trunk/Source/WebInspectorUI/ChangeLog (188538 => 188539)
--- trunk/Source/WebInspectorUI/ChangeLog 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Source/WebInspectorUI/ChangeLog 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,3 +1,15 @@
+2015-08-17 Brian Burg <[email protected]>
+
+ Web Inspector: load ProtocolTestStub from the WebInspectorUI bundle
+ https://bugs.webkit.org/show_bug.cgi?id=147955
+
+ Reviewed by Timothy Hatcher.
+
+ Move ProtocolTestStub.{html,js} into the actual WebInspectorUI project.
+
+ * UserInterface/Base/TestStub.js: Renamed from LayoutTests/http/tests/inspector/resources/ProtocolTestStub.js.
+ * UserInterface/TestStub.html: Renamed from LayoutTests/http/tests/inspector/resources/ProtocolTestStub.html.
+
2015-08-17 Simon Fraser <[email protected]>
will-change should sometimes trigger compositing
Copied: trunk/Source/WebInspectorUI/UserInterface/Base/TestStub.js (from rev 188538, trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.js) (0 => 188539)
--- trunk/Source/WebInspectorUI/UserInterface/Base/TestStub.js (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/Base/TestStub.js 2015-08-17 20:33:48 UTC (rev 188539)
@@ -0,0 +1,480 @@
+/*
+ * 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
Copied: trunk/Source/WebInspectorUI/UserInterface/TestStub.html (from rev 188538, trunk/LayoutTests/http/tests/inspector/resources/ProtocolTestStub.html) (0 => 188539)
--- trunk/Source/WebInspectorUI/UserInterface/TestStub.html (rev 0)
+++ trunk/Source/WebInspectorUI/UserInterface/TestStub.html 2015-08-17 20:33:48 UTC (rev 188539)
@@ -0,0 +1,29 @@
+<!--
+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.
+-->
+<html>
+<head>
+ <script type="text/_javascript_" src=""
+</head>
+</html>
Modified: trunk/Tools/ChangeLog (188538 => 188539)
--- trunk/Tools/ChangeLog 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/ChangeLog 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1,3 +1,35 @@
+2015-08-17 Brian Burg <[email protected]>
+
+ Web Inspector: load ProtocolTestStub from the WebInspectorUI bundle
+ https://bugs.webkit.org/show_bug.cgi?id=147955
+
+ Reviewed by Timothy Hatcher.
+
+ To enable sharing of common test code between protocol and model tests,
+ start loading the protocol TestStub.js through the WebInspectorUI bundle.
+
+ This patch adds the read-only getter TestRunner.inspectorTestStubURL, which
+ protocol-test.js uses to load the inspector frontend stub into its iframe
+ from an arbitrary local file URL.
+
+ * DumpRenderTree/TestRunner.cpp:
+ (getInspectorTestStubURLCallback):
+ (TestRunner::staticValues):
+ * DumpRenderTree/TestRunner.h:
+ * DumpRenderTree/mac/TestRunnerMac.mm:
+ (SOFT_LINK_STAGED_FRAMEWORK):
+ (TestRunner::inspectorTestStubURL):
+ * DumpRenderTree/win/TestRunnerWin.cpp:
+ (TestRunner::inspectorTestStubURL):
+ * WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl:
+ * WebKitTestRunner/InjectedBundle/TestRunner.h:
+ * WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp:
+ (WTR::TestRunner::inspectorTestStubURL):
+ * WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp:
+ (WTR::TestRunner::inspectorTestStubURL):
+ * WebKitTestRunner/InjectedBundle/mac/TestRunnerMac.mm:
+ (WTR::TestRunner::inspectorTestStubURL):
+
2015-08-17 Saam barati <[email protected]>
Change email address from [email protected] to [email protected]
Modified: trunk/Tools/DumpRenderTree/TestRunner.cpp (188538 => 188539)
--- trunk/Tools/DumpRenderTree/TestRunner.cpp 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/DumpRenderTree/TestRunner.cpp 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1790,6 +1790,13 @@
return JSValueMakeString(context, titleDirection.get());
}
+static JSValueRef getInspectorTestStubURLCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef* exception)
+{
+ TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
+ JSRetainPtr<JSStringRef> url(Adopt, controller->inspectorTestStubURL());
+ return JSValueMakeString(context, url.get());
+}
+
static bool setGlobalFlagCallback(JSContextRef context, JSObjectRef thisObject, JSStringRef propertyName, JSValueRef value, JSValueRef* exception)
{
TestRunner* controller = static_cast<TestRunner*>(JSObjectGetPrivate(thisObject));
@@ -1983,6 +1990,7 @@
{ "titleTextDirection", getTitleTextDirectionCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ "databaseDefaultQuota", getDatabaseDefaultQuotaCallback, setDatabaseDefaultQuotaCallback, kJSPropertyAttributeNone },
{ "databaseMaxQuota", getDatabaseMaxQuotaCallback, setDatabaseMaxQuotaCallback, kJSPropertyAttributeNone },
+ { "inspectorTestStubURL", getInspectorTestStubURLCallback, 0, kJSPropertyAttributeReadOnly | kJSPropertyAttributeDontDelete },
{ 0, 0, 0, 0 }
};
return staticValues;
Modified: trunk/Tools/DumpRenderTree/TestRunner.h (188538 => 188539)
--- trunk/Tools/DumpRenderTree/TestRunner.h 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/DumpRenderTree/TestRunner.h 2015-08-17 20:33:48 UTC (rev 188539)
@@ -308,6 +308,8 @@
void showWebInspector();
void closeWebInspector();
void evaluateInWebInspector(JSStringRef script);
+ JSStringRef inspectorTestStubURL();
+
void evaluateScriptInIsolatedWorld(unsigned worldID, JSObjectRef globalObject, JSStringRef script);
void evaluateScriptInIsolatedWorldAndReturnValue(unsigned worldID, JSObjectRef globalObject, JSStringRef script);
Modified: trunk/Tools/DumpRenderTree/mac/TestRunnerMac.mm (188538 => 188539)
--- trunk/Tools/DumpRenderTree/mac/TestRunnerMac.mm 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/DumpRenderTree/mac/TestRunnerMac.mm 2015-08-17 20:33:48 UTC (rev 188539)
@@ -43,6 +43,7 @@
#import <_javascript_Core/JSStringRef.h>
#import <_javascript_Core/JSStringRefCF.h>
#import <WebCore/GeolocationPosition.h>
+#import <WebCore/SoftLinking.h>
#import <WebKit/DOMDocument.h>
#import <WebKit/DOMElement.h>
#import <WebKit/DOMHTMLInputElementPrivate.h>
@@ -88,6 +89,8 @@
#import <WebKit/WebDOMOperationsPrivate.h>
#endif
+SOFT_LINK_STAGED_FRAMEWORK(WebInspectorUI, PrivateFrameworks, A)
+
#if !PLATFORM(IOS)
@interface CommandValidationTarget : NSObject <NSValidatedUserInterfaceItem>
{
@@ -780,6 +783,23 @@
[[[mainFrame webView] inspector] evaluateInFrontend:nil script:scriptNS];
}
+JSStringRef TestRunner::inspectorTestStubURL()
+{
+ // Call the soft link framework function to dlopen it, then CFBundleGetBundleWithIdentifier will work.
+ WebInspectorUILibrary();
+
+ CFBundleRef inspectorBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebInspectorUI"));
+ if (!inspectorBundle)
+ return nullptr;
+
+ RetainPtr<CFURLRef> url = "" CFSTR("TestStub"), CFSTR("html"), NULL));
+ if (!url)
+ return nullptr;
+
+ CFStringRef urlString = CFURLGetString(url.get());
+ return JSStringCreateWithCFString(urlString);
+}
+
typedef HashMap<unsigned, RetainPtr<WebScriptWorld> > WorldMap;
static WorldMap& worldMap()
{
Modified: trunk/Tools/DumpRenderTree/win/TestRunnerWin.cpp (188538 => 188539)
--- trunk/Tools/DumpRenderTree/win/TestRunnerWin.cpp 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/DumpRenderTree/win/TestRunnerWin.cpp 2015-08-17 20:33:48 UTC (rev 188539)
@@ -1093,6 +1093,15 @@
inspectorPrivate->evaluateInFrontend(bstrT(script).GetBSTR());
}
+JSStringRef TestRunner::inspectorTestStubURL()
+{
+ // FIXME: Implement this to support Web Inspector tests using `protocol-test.js`.
+ // See https://bugs.webkit.org/show_bug.cgi?id=148025.
+ printf("ERROR: TestRunner::inspectorTestStubURL() not implemented\n");
+
+ return nullptr;
+}
+
typedef HashMap<unsigned, COMPtr<IWebScriptWorld> > WorldMap;
static WorldMap& worldMap()
{
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl (188538 => 188539)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/Bindings/TestRunner.idl 2015-08-17 20:33:48 UTC (rev 188539)
@@ -125,6 +125,7 @@
void showWebInspector();
void closeWebInspector();
void evaluateInWebInspector(DOMString script);
+ readonly attribute DOMString inspectorTestStubURL;
void setPOSIXLocale(DOMString locale);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h (188538 => 188539)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/TestRunner.h 2015-08-17 20:33:48 UTC (rev 188539)
@@ -199,6 +199,7 @@
void showWebInspector();
void closeWebInspector();
void evaluateInWebInspector(JSStringRef script);
+ JSRetainPtr<JSStringRef> inspectorTestStubURL();
void setPOSIXLocale(JSStringRef);
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp (188538 => 188539)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/efl/TestRunnerEfl.cpp 2015-08-17 20:33:48 UTC (rev 188539)
@@ -23,7 +23,9 @@
#include "InjectedBundle.h"
#include <Ecore.h>
#include <_javascript_Core/OpaqueJSString.h>
+#include <WebCore/EflInspectorUtilities.h>
#include <wtf/text/CString.h>
+#include <wtf/text/StringBuilder.h>
#include <wtf/text/WTFString.h>
namespace WTR {
@@ -82,4 +84,14 @@
return JSStringCreateWithUTF8CString(fullPathToUrl.utf8().data());
}
+JSRetainPtr<JSStringRef> TestRunner::inspectorTestStubURL()
+{
+ StringBuilder builder;
+ builder.append("file://");
+ builder.append(WebCore::inspectorResourcePath());
+ builder.appendLiteral("/TestStub.html");
+
+ return JSStringCreateWithUTF8CString(builder.toString().utf8().data());
+}
+
} // namespace WTR
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp (188538 => 188539)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/gtk/TestRunnerGtk.cpp 2015-08-17 20:33:48 UTC (rev 188539)
@@ -67,4 +67,9 @@
return JSStringCreateWithUTF8CString(testURI.get());
}
+JSRetainPtr<JSStringRef> TestRunner::inspectorTestStubURL()
+{
+ return JSStringCreateWithUTF8CString("resource:///org/webkitgtk/inspector/UserInterface/TestStub.html");
+}
+
} // namespace WTR
Modified: trunk/Tools/WebKitTestRunner/InjectedBundle/mac/TestRunnerMac.mm (188538 => 188539)
--- trunk/Tools/WebKitTestRunner/InjectedBundle/mac/TestRunnerMac.mm 2015-08-17 20:29:09 UTC (rev 188538)
+++ trunk/Tools/WebKitTestRunner/InjectedBundle/mac/TestRunnerMac.mm 2015-08-17 20:33:48 UTC (rev 188539)
@@ -26,7 +26,11 @@
#include "TestRunner.h"
#include "InjectedBundle.h"
+#include <_javascript_Core/JSStringRefCF.h>
+#include <WebCore/SoftLinking.h>
+SOFT_LINK_STAGED_FRAMEWORK(WebInspectorUI, PrivateFrameworks, A)
+
namespace WTR {
void TestRunner::platformInitialize()
@@ -62,4 +66,21 @@
return JSStringRetain(url); // Do nothing on mac.
}
+JSRetainPtr<JSStringRef> TestRunner::inspectorTestStubURL()
+{
+ // Call the soft link framework function to dlopen it, then CFBundleGetBundleWithIdentifier will work.
+ WebInspectorUILibrary();
+
+ CFBundleRef inspectorBundle = CFBundleGetBundleWithIdentifier(CFSTR("com.apple.WebInspectorUI"));
+ if (!inspectorBundle)
+ return nullptr;
+
+ RetainPtr<CFURLRef> url = "" CFSTR("TestStub"), CFSTR("html"), NULL));
+ if (!url)
+ return nullptr;
+
+ CFStringRef urlString = CFURLGetString(url.get());
+ return adopt(JSStringCreateWithCFString(urlString));
+}
+
} // namespace WTR