1 var initialize_InspectorTest = function() {
4 var resultsSynchronized = false;
6 function consoleOutputHook(messageType)
8 InspectorTest.addResult(messageType + ": " + Array.prototype.slice.call(arguments, 1));
11 console.log = consoleOutputHook.bind(InspectorTest, "log");
12 console.error = consoleOutputHook.bind(InspectorTest, "error");
13 console.info = consoleOutputHook.bind(InspectorTest, "info");
14 console.assert = function(condition, object)
18 var message = "Assertion failed: " + (typeof object !== "undefined" ? object : "");
19 InspectorTest.addResult(new Error(message).stack);
22 InspectorTest.Output = { // override in window.initialize_yourName
23 testComplete: function()
25 RuntimeAgent.evaluate("didEvaluateForTestInFrontend(" + InspectorTest.completeTestCallId + ", \"\")", "test");
28 addResult: function(text)
30 InspectorTest.evaluateInPage("output(unescape('" + escape(text) + "'))");
33 clearResults: function()
35 InspectorTest.evaluateInPage("clearOutput()");
39 InspectorTest.startDumpingProtocolMessages = function()
41 InspectorBackendClass.Connection.prototype._dumpProtocolMessage = testRunner.logToStderr.bind(testRunner);
42 InspectorBackendClass.Options.dumpInspectorProtocolMessages = 1;
45 InspectorTest.completeTest = function()
47 InspectorTest.Output.testComplete();
50 InspectorTest.evaluateInConsole = function(code, callback)
52 callback = InspectorTest.safeWrap(callback);
54 WebInspector.inspectorView.panel("console");
55 var consoleView = WebInspector.ConsolePanel._view();
56 consoleView.visible = true;
57 consoleView._prompt.text = code;
58 var event = document.createEvent("KeyboardEvent");
59 event.initKeyboardEvent("keydown", true, true, null, "Enter", "");
60 consoleView._prompt.proxyElement.dispatchEvent(event);
61 InspectorTest.addConsoleSniffer(
62 function(commandResult) {
63 callback(commandResult.toMessageElement().textContent);
67 InspectorTest.evaluateInConsoleAndDump = function(code, callback)
69 callback = InspectorTest.safeWrap(callback);
71 function mycallback(text)
73 InspectorTest.addResult(code + " = " + text);
76 InspectorTest.evaluateInConsole(code, mycallback);
79 InspectorTest.evaluateInPage = function(code, callback)
81 callback = InspectorTest.safeWrap(callback);
83 function mycallback(error, result, wasThrown)
86 callback(WebInspector.runtimeModel.createRemoteObject(result), wasThrown);
88 RuntimeAgent.evaluate(code, "console", false, mycallback);
91 InspectorTest.evaluateInPageWithTimeout = function(code)
93 InspectorTest.evaluateInPage("setTimeout(unescape('" + escape(code) + "'))");
97 var pendingEvalRequests = {};
99 InspectorTest.invokePageFunctionAsync = function(functionName, callback)
101 var id = ++lastEvalId;
102 pendingEvalRequests[id] = InspectorTest.safeWrap(callback);
103 var asyncEvalWrapper = function(callId, functionName)
105 function evalCallback(result)
107 testRunner.evaluateInWebInspector(evalCallbackCallId, "InspectorTest.didInvokePageFunctionAsync(" + callId + ", " + JSON.stringify(result) + ");");
109 eval(functionName + "(" + evalCallback + ")");
111 InspectorTest.evaluateInPage("(" + asyncEvalWrapper.toString() + ")(" + id + ", unescape('" + escape(functionName) + "'))");
114 InspectorTest.didInvokePageFunctionAsync = function(callId, value)
116 var callback = pendingEvalRequests[callId];
118 InspectorTest.addResult("Missing callback for async eval " + callId + ", perhaps callback invoked twice?");
121 delete pendingEvalRequests[callId];
125 InspectorTest.check = function(passCondition, failureText)
128 InspectorTest.addResult("FAIL: " + failureText);
131 InspectorTest.addResult = function(text)
134 if (resultsSynchronized)
135 InspectorTest.Output.addResult(text);
137 InspectorTest.Output.clearResults();
138 for (var i = 0; i < results.length; ++i)
139 InspectorTest.Output.addResult(results[i]);
140 resultsSynchronized = true;
144 InspectorTest.addResults = function(textArray)
148 for (var i = 0, size = textArray.length; i < size; ++i)
149 InspectorTest.addResult(textArray[i]);
152 window.onerror = function (message, filename, lineno, colno, error)
154 InspectorTest.addResult("Uncaught exception in inspector front-end: " + message + " [" + error.stack + "]");
155 InspectorTest.completeTest();
158 InspectorTest.formatters = {};
160 InspectorTest.formatters.formatAsTypeName = function(value)
162 return "<" + typeof value + ">";
165 InspectorTest.formatters.formatAsRecentTime = function(value)
167 if (typeof value !== "object" || !(value instanceof Date))
168 return InspectorTest.formatAsTypeName(value);
169 var delta = Date.now() - value;
170 return 0 <= delta && delta < 30 * 60 * 1000 ? "<plausible>" : value;
173 InspectorTest.formatters.formatAsURL = function(value)
177 var lastIndex = value.lastIndexOf("inspector/");
180 return ".../" + value.substr(lastIndex);
183 InspectorTest.addObject = function(object, customFormatters, prefix, firstLinePrefix)
185 prefix = prefix || "";
186 firstLinePrefix = firstLinePrefix || prefix;
187 InspectorTest.addResult(firstLinePrefix + "{");
188 var propertyNames = Object.keys(object);
189 propertyNames.sort();
190 for (var i = 0; i < propertyNames.length; ++i) {
191 var prop = propertyNames[i];
192 if (typeof object.hasOwnProperty === "function" && !object.hasOwnProperty(prop))
194 var prefixWithName = " " + prefix + prop + " : ";
195 var propValue = object[prop];
196 if (customFormatters && customFormatters[prop]) {
197 var formatterName = customFormatters[prop];
198 if (formatterName !== "skip") {
199 var formatter = InspectorTest.formatters[formatterName];
200 InspectorTest.addResult(prefixWithName + formatter(propValue));
203 InspectorTest.dump(propValue, customFormatters, " " + prefix, prefixWithName);
205 InspectorTest.addResult(prefix + "}");
208 InspectorTest.addArray = function(array, customFormatters, prefix, firstLinePrefix)
210 prefix = prefix || "";
211 firstLinePrefix = firstLinePrefix || prefix;
212 InspectorTest.addResult(firstLinePrefix + "[");
213 for (var i = 0; i < array.length; ++i)
214 InspectorTest.dump(array[i], customFormatters, prefix + " ");
215 InspectorTest.addResult(prefix + "]");
218 InspectorTest.dump = function(value, customFormatters, prefix, prefixWithName)
220 prefixWithName = prefixWithName || prefix;
221 if (prefixWithName && prefixWithName.length > 80) {
222 InspectorTest.addResult(prefixWithName + "was skipped due to prefix length limit");
226 InspectorTest.addResult(prefixWithName + "null");
227 else if (value instanceof Array)
228 InspectorTest.addArray(value, customFormatters, prefix, prefixWithName);
229 else if (typeof value === "object")
230 InspectorTest.addObject(value, customFormatters, prefix, prefixWithName);
231 else if (typeof value === "string")
232 InspectorTest.addResult(prefixWithName + "\"" + value + "\"");
234 InspectorTest.addResult(prefixWithName + value);
237 InspectorTest.assertGreaterOrEqual = function(a, b, message)
240 InspectorTest.addResult("FAILED: " + (message ? message + ": " : "") + a + " < " + b);
243 InspectorTest.registerModule = function(moduleName, loadImmediately)
245 runtime._registerModule(moduleName);
247 runtime.loadModule(moduleName);
250 InspectorTest.navigate = function(url, callback)
252 InspectorTest._pageLoadedCallback = InspectorTest.safeWrap(callback);
254 WebInspector.inspectorView.panel("network")._reset();
255 InspectorTest.evaluateInConsole("window.location = '" + url + "'");
258 InspectorTest.recordNetwork = function()
260 WebInspector.inspectorView.panel("network")._networkLogView._recordButton.toggled = true;
263 InspectorTest.hardReloadPage = function(callback, scriptToEvaluateOnLoad, scriptPreprocessor)
265 InspectorTest._innerReloadPage(true, callback, scriptToEvaluateOnLoad, scriptPreprocessor);
268 InspectorTest.reloadPage = function(callback, scriptToEvaluateOnLoad, scriptPreprocessor)
270 InspectorTest._innerReloadPage(false, callback, scriptToEvaluateOnLoad, scriptPreprocessor);
273 InspectorTest._innerReloadPage = function(hardReload, callback, scriptToEvaluateOnLoad, scriptPreprocessor)
275 InspectorTest._pageLoadedCallback = InspectorTest.safeWrap(callback);
277 if (WebInspector.panels.network)
278 WebInspector.panels.network._reset();
279 PageAgent.reload(hardReload, scriptToEvaluateOnLoad, scriptPreprocessor);
282 InspectorTest.pageLoaded = function()
284 resultsSynchronized = false;
285 InspectorTest.addResult("Page reloaded.");
286 if (InspectorTest._pageLoadedCallback) {
287 var callback = InspectorTest._pageLoadedCallback;
288 delete InspectorTest._pageLoadedCallback;
293 InspectorTest.runWhenPageLoads = function(callback)
295 var oldCallback = InspectorTest._pageLoadedCallback;
296 function chainedCallback()
302 InspectorTest._pageLoadedCallback = InspectorTest.safeWrap(chainedCallback);
305 InspectorTest.runAfterPendingDispatches = function(callback)
307 callback = InspectorTest.safeWrap(callback);
308 InspectorBackend.connection().runAfterPendingDispatches(callback);
311 InspectorTest.createKeyEvent = function(keyIdentifier, ctrlKey, altKey, shiftKey, metaKey)
313 var evt = document.createEvent("KeyboardEvent");
314 evt.initKeyboardEvent("keydown", true /* can bubble */, true /* can cancel */, null /* view */, keyIdentifier, "", ctrlKey, altKey, shiftKey, metaKey);
318 InspectorTest.runTestSuite = function(testSuite)
320 var testSuiteTests = testSuite.slice();
324 if (!testSuiteTests.length) {
325 InspectorTest.completeTest();
328 var nextTest = testSuiteTests.shift();
329 InspectorTest.addResult("");
330 InspectorTest.addResult("Running: " + /function\s([^(]*)/.exec(nextTest)[1]);
331 InspectorTest.safeWrap(nextTest)(runner);
336 InspectorTest.assertEquals = function(expected, found, message)
338 if (expected === found)
343 error = "Failure (" + message + "):";
346 throw new Error(error + " expected <" + expected + "> found <" + found + ">");
349 InspectorTest.assertTrue = function(found, message)
351 InspectorTest.assertEquals(true, !!found, message);
354 InspectorTest.safeWrap = function(func, onexception)
362 return func.apply(wrapThis, arguments);
364 InspectorTest.addResult("Exception while running: " + func + "\n" + (e.stack || e));
366 InspectorTest.safeWrap(onexception)();
368 InspectorTest.completeTest();
374 InspectorTest.addSniffer = function(receiver, methodName, override, opt_sticky)
376 override = InspectorTest.safeWrap(override);
378 var original = receiver[methodName];
379 if (typeof original !== "function")
380 throw ("Cannot find method to override: " + methodName);
382 receiver[methodName] = function(var_args) {
384 var result = original.apply(this, arguments);
387 receiver[methodName] = original;
389 // In case of exception the override won't be called.
391 Array.prototype.push.call(arguments, result);
392 override.apply(this, arguments);
394 throw ("Exception in overriden method '" + methodName + "': " + e);
400 InspectorTest.addConsoleSniffer = function(override, opt_sticky)
402 var sniffer = function (viewMessage) {
403 override(viewMessage);
406 WebInspector.inspectorView.panel("console");
407 InspectorTest.addSniffer(WebInspector.ConsoleView.prototype, "_showConsoleMessage", sniffer, opt_sticky);
410 InspectorTest.override = function(receiver, methodName, override, opt_sticky)
412 override = InspectorTest.safeWrap(override);
414 var original = receiver[methodName];
415 if (typeof original !== "function")
416 throw ("Cannot find method to override: " + methodName);
418 receiver[methodName] = function(var_args) {
421 var result = override.apply(this, arguments);
423 throw ("Exception in overriden method '" + methodName + "': " + e);
427 receiver[methodName] = original;
435 InspectorTest.textContentWithLineBreaks = function(node)
438 var currentNode = node;
439 while (currentNode = currentNode.traverseNextNode(node)) {
440 if (currentNode.nodeType === Node.TEXT_NODE)
441 buffer += currentNode.nodeValue;
442 else if (currentNode.nodeName === "LI")
444 else if (currentNode.classList.contains("console-message"))
450 InspectorTest.hideInspectorView = function()
452 WebInspector.inspectorView.element.setAttribute("style", "display:none !important");
455 InspectorTest.StringOutputStream = function(callback)
457 this._callback = callback;
461 InspectorTest.StringOutputStream.prototype = {
462 open: function(fileName, callback)
467 write: function(chunk, callback)
469 this._buffer += chunk;
476 this._callback(this._buffer);
480 InspectorTest.MockSetting = function(value)
485 InspectorTest.MockSetting.prototype = {
490 set: function(value) {
498 * @param {!string} dirPath
499 * @param {!string} name
500 * @param {!function(?WebInspector.TempFile)} callback
502 InspectorTest.TempFileMock = function(dirPath, name, callback)
506 setTimeout(callback.bind(this, this), 0);
509 InspectorTest.TempFileMock.prototype = {
511 * @param {!string} data
512 * @param {!function(boolean)} callback
514 write: function(data, callback)
516 this._chunks.push(data);
517 setTimeout(callback.bind(this, true), 0);
520 finishWriting: function() { },
523 * @param {function(?string)} callback
525 read: function(callback)
527 callback(this._chunks.join(""));
531 * @param {!WebInspector.OutputStream} outputStream
532 * @param {!WebInspector.OutputStreamDelegate} delegate
534 writeToOutputSteam: function(outputStream, delegate)
536 var name = this._name;
537 var text = this._chunks.join("");
538 var chunkedReaderMock = {
539 loadedSize: function()
554 cancel: function() { }
556 delegate.onTransferStarted(chunkedReaderMock);
557 outputStream.write(text);
558 delegate.onChunkTransferred(chunkedReaderMock);
559 outputStream.close();
560 delegate.onTransferFinished(chunkedReaderMock);
563 remove: function() { }
566 InspectorTest.dumpLoadedModules = function(next)
568 InspectorTest.addResult("Loaded modules:");
569 var modules = self.runtime._modules;
570 for (var i = 0; i < modules.length; ++i) {
571 if (modules[i]._loaded) {
572 InspectorTest.addResult(" " + modules[i]._descriptor.name);
579 InspectorTest.TimeoutMock = function()
582 this._timeoutIdToProcess = {};
583 this._timeoutIdToMillis = {};
584 this.setTimeout = this.setTimeout.bind(this);
585 this.clearTimeout = this.clearTimeout.bind(this);
587 InspectorTest.TimeoutMock.prototype = {
588 setTimeout: function(operation, timeout)
590 this._timeoutIdToProcess[++this._timeoutId] = operation;
591 this._timeoutIdToMillis[this._timeoutId] = timeout;
592 return this._timeoutId;
595 clearTimeout: function(timeoutId)
597 delete this._timeoutIdToProcess[timeoutId];
598 delete this._timeoutIdToMillis[timeoutId];
601 activeTimersTimeouts: function()
603 return Object.values(this._timeoutIdToMillis);
606 fireAllTimers: function()
608 for (var timeoutId in this._timeoutIdToProcess)
609 this._timeoutIdToProcess[timeoutId].call(window);
610 this._timeoutIdToProcess = {};
611 this._timeoutIdToMillis = {};
615 WebInspector.TempFile = InspectorTest.TempFileMock;
617 WebInspector.targetManager.observeTargets({
618 targetAdded: function(target)
620 if (!WebInspector.domModel)
621 WebInspector.domModel = target.domModel;
622 if (!WebInspector.consoleModel)
623 WebInspector.consoleModel = target.consoleModel;
624 if (!WebInspector.networkManager)
625 WebInspector.networkManager = target.networkManager;
626 if (!WebInspector.timelineManager)
627 WebInspector.timelineManager = target.timelineManager;
630 targetRemoved: function(target) { }
633 }; // initialize_InspectorTest
635 var initializeCallId = 0;
636 var runTestCallId = 1;
637 var completeTestCallId = 2;
638 var evalCallbackCallId = 3;
639 var frontendReopeningCount = 0;
641 function reopenFrontend()
643 closeFrontend(openFrontendAndIncrement);
646 function closeFrontend(callback)
648 // Do this asynchronously to allow InspectorBackendDispatcher to send response
649 // back to the frontend before it's destroyed.
650 setTimeout(function() {
651 testRunner.closeWebInspector();
656 function openFrontendAndIncrement()
658 frontendReopeningCount++;
659 testRunner.showWebInspector();
660 setTimeout(runTest, 0);
663 function runAfterIframeIsLoaded()
665 if (window.testRunner)
666 testRunner.waitUntilDone();
669 if (!window.iframeLoaded)
670 setTimeout(step, 100);
674 setTimeout(step, 100);
677 function runTest(enableWatchDogWhileDebugging)
679 if (!window.testRunner)
682 testRunner.dumpAsText();
683 testRunner.waitUntilDone();
685 function initializeFrontend(initializationFunctions)
687 if (window.InspectorTest) {
688 InspectorTest.pageLoaded();
694 for (var i = 0; i < initializationFunctions.length; ++i) {
696 initializationFunctions[i]();
698 console.error("Exception in test initialization: " + e);
699 InspectorTest.completeTest();
704 function runTestInFrontend(testFunction, completeTestCallId)
706 if (InspectorTest.completeTestCallId)
709 InspectorTest.completeTestCallId = completeTestCallId;
714 console.error("Exception during test execution: " + e, (e.stack ? e.stack : "") );
715 InspectorTest.completeTest();
719 var initializationFunctions = [ String(initialize_InspectorTest) ];
720 for (var name in window) {
721 if (name.indexOf("initialize_") === 0 && typeof window[name] === "function" && name !== "initialize_InspectorTest")
722 initializationFunctions.push(window[name].toString());
724 var parameters = ["[" + initializationFunctions + "]"];
725 var toEvaluate = "(" + initializeFrontend + ")(" + parameters.join(", ") + ");";
726 testRunner.evaluateInWebInspector(initializeCallId, toEvaluate);
728 parameters = [test, completeTestCallId];
729 toEvaluate = "(" + runTestInFrontend + ")(" + parameters.join(", ") + ");";
730 testRunner.evaluateInWebInspector(runTestCallId, toEvaluate);
732 if (enableWatchDogWhileDebugging) {
735 console.log("Internal watchdog triggered at 20 seconds. Test timed out.");
736 closeInspectorAndNotifyDone();
738 window._watchDogTimer = setTimeout(watchDog, 20000);
742 function runTestAfterDisplay(enableWatchDogWhileDebugging)
744 if (!window.testRunner)
747 testRunner.waitUntilDone();
748 requestAnimationFrame(runTest.bind(this, enableWatchDogWhileDebugging));
751 function didEvaluateForTestInFrontend(callId)
753 if (callId !== completeTestCallId)
755 delete window.completeTestCallId;
756 if (outputElement && window.quietUntilDone)
757 outputElementParent.appendChild(outputElement);
758 closeInspectorAndNotifyDone();
761 function closeInspectorAndNotifyDone()
763 if (window._watchDogTimer)
764 clearTimeout(window._watchDogTimer);
766 testRunner.closeWebInspector();
767 setTimeout(function() {
768 testRunner.notifyDone();
773 var outputElementParent;
776 function createOutputElement()
778 var intermediate = document.createElement("div");
779 document.body.appendChild(intermediate);
781 outputElementParent = document.createElement("div");
782 intermediate.appendChild(outputElementParent);
784 outputElement = document.createElement("div");
785 outputElement.className = "output";
786 outputElement.id = "output";
787 outputElement.style.whiteSpace = "pre";
788 if (!window.quietUntilDone)
789 outputElementParent.appendChild(outputElement);
792 function output(text)
795 createOutputElement();
796 outputElement.appendChild(document.createTextNode(text));
797 outputElement.appendChild(document.createElement("br"));
800 function clearOutput()
803 outputElement.remove();
804 outputElement = null;
808 function saveOutput()
810 savedOutput = outputElement ? outputElement.innerHTML : "";
813 function restoreOutput()
817 createOutputElement();
818 outputElement.innerHTML = savedOutput;
821 function StandaloneTestRunnerStub()
825 StandaloneTestRunnerStub.prototype = {
826 dumpAsText: function()
830 waitUntilDone: function()
834 closeWebInspector: function()
836 window.opener.postMessage(["closeWebInspector"], "*");
839 notifyDone: function()
841 var actual = document.body.innerText + "\n";
842 window.opener.postMessage(["notifyDone", actual], "*");
845 evaluateInWebInspector: function(callId, script)
847 window.opener.postMessage(["evaluateInWebInspector", callId, script], "*");
850 display: function() { }
853 if (!window.testRunner && window.opener)
854 window.testRunner = new StandaloneTestRunnerStub();