Index: third_party/WebKit/Source/devtools/front_end/console_test_runner/ConsoleTestRunner.js |
diff --git a/third_party/WebKit/Source/devtools/front_end/console_test_runner/ConsoleTestRunner.js b/third_party/WebKit/Source/devtools/front_end/console_test_runner/ConsoleTestRunner.js |
index 1f84b8738f8794a4c78c9a1915beaf1af1e46a52..119ee5c3191650f123c9c3a1836b3ccd1195c835 100644 |
--- a/third_party/WebKit/Source/devtools/front_end/console_test_runner/ConsoleTestRunner.js |
+++ b/third_party/WebKit/Source/devtools/front_end/console_test_runner/ConsoleTestRunner.js |
@@ -7,10 +7,13 @@ |
* @suppress {accessControls} |
*/ |
+/** @typedef {function(!Element, !ConsoleModel.ConsoleMessage=):string} */ |
+ConsoleTestRunner.Formatter; |
+ |
/** |
- * @param {boolean} printOriginatingCommand |
- * @param {boolean} dumpClassNames |
- * @param {function(!Element, !ConsoleModel.ConsoleMessage):string=} formatter |
+ * @param {boolean=} printOriginatingCommand |
+ * @param {boolean=} dumpClassNames |
+ * @param {!ConsoleTestRunner.Formatter=} formatter |
*/ |
ConsoleTestRunner.dumpConsoleMessages = function(printOriginatingCommand, dumpClassNames, formatter) { |
TestRunner.addResults( |
@@ -18,9 +21,9 @@ ConsoleTestRunner.dumpConsoleMessages = function(printOriginatingCommand, dumpCl |
}; |
/** |
- * @param {boolean} printOriginatingCommand |
- * @param {boolean} dumpClassNames |
- * @param {function(!Element, !ConsoleModel.ConsoleMessage):string=} formatter |
+ * @param {boolean=} printOriginatingCommand |
+ * @param {boolean=} dumpClassNames |
+ * @param {!ConsoleTestRunner.Formatter=} formatter |
* @return {!Array<string>} |
*/ |
ConsoleTestRunner.dumpConsoleMessagesIntoArray = function(printOriginatingCommand, dumpClassNames, formatter) { |
@@ -64,10 +67,9 @@ ConsoleTestRunner.dumpConsoleMessagesIntoArray = function(printOriginatingComman |
/** |
* @param {!Element} messageElement |
- * @param {!ConsoleModel.ConsoleMessage} consoleMessage |
* @return {string} |
*/ |
-ConsoleTestRunner.prepareConsoleMessageText = function(messageElement, consoleMessage) { |
+ConsoleTestRunner.prepareConsoleMessageText = function(messageElement) { |
var messageText = messageElement.deepTextContent().replace(/\u200b/g, ''); |
// Replace scriptIds with generic scriptId string to avoid flakiness. |
messageText = messageText.replace(/VM\d+/g, 'VM'); |
@@ -143,4 +145,384 @@ ConsoleTestRunner.fixConsoleViewportDimensions = function(width, height) { |
viewport.element.style.height = height + 'px'; |
viewport.element.style.position = 'absolute'; |
viewport.invalidate(); |
-}; |
+}; |
+ |
+ConsoleTestRunner.selectMainExecutionContext = function() { |
+ var executionContexts = TestRunner.runtimeModel.executionContexts(); |
+ for (var context of executionContexts) { |
+ if (context.isDefault) { |
+ UI.context.setFlavor(SDK.ExecutionContext, context); |
+ return; |
+ } |
+ } |
+}; |
+ |
+/** |
+ * @param {string} code |
+ * @param {!Function=} callback |
+ * @param {boolean=} dontForceMainContext |
+ */ |
+ConsoleTestRunner.evaluateInConsole = function(code, callback, dontForceMainContext) { |
+ if (!dontForceMainContext) |
+ ConsoleTestRunner.selectMainExecutionContext(); |
+ callback = TestRunner.safeWrap(callback); |
+ |
+ var consoleView = Console.ConsoleView.instance(); |
+ consoleView._prompt._appendCommand(code, true); |
+ ConsoleTestRunner.addConsoleViewSniffer(function(commandResult) { |
+ callback(commandResult.toMessageElement().deepTextContent()); |
+ }); |
+}; |
+ |
+/** |
+ * @param {!Function} override |
+ * @param {boolean=} opt_sticky |
+ */ |
+ConsoleTestRunner.addConsoleViewSniffer = function(override, opt_sticky) { |
+ var sniffer = function(viewMessage) { |
caseq
2017/07/12 01:04:33
why not just pass override directly? Also, perhaps
chenwilliam
2017/07/12 22:02:58
I passed the override directly.
See earlier comme
|
+ override(viewMessage); |
+ }; |
+ |
+ TestRunner.addSniffer(Console.ConsoleView.prototype, '_consoleMessageAddedForTest', sniffer, opt_sticky); |
+}; |
+ |
+/** |
+ * @param {string} code |
+ * @param {!Function=} callback |
+ * @param {boolean=} dontForceMainContext |
+ */ |
+ConsoleTestRunner.evaluateInConsoleAndDump = function(code, callback, dontForceMainContext) { |
+ callback = TestRunner.safeWrap(callback); |
caseq
2017/07/12 01:04:33
No need for this, you already wrap in evalueteInCo
chenwilliam
2017/07/12 22:02:58
Done.
|
+ |
+ /** |
+ * @param {string} text |
+ */ |
+ function mycallback(text) { |
+ text = text.replace(/\bVM\d+/g, 'VM'); |
+ TestRunner.addResult(code + ' = ' + text); |
+ callback(text); |
+ } |
+ ConsoleTestRunner.evaluateInConsole(code, mycallback, dontForceMainContext); |
+}; |
+ |
+/** |
+ * @return {number} |
+ */ |
+ConsoleTestRunner.consoleMessagesCount = function() { |
+ var consoleView = Console.ConsoleView.instance(); |
+ return consoleView._consoleMessages.length; |
+}; |
+ |
+/** |
+ * @param {function(!Element):string} messageFormatter |
+ * @param {!Element} node |
+ * @return {string} |
+ */ |
+ConsoleTestRunner.formatterIgnoreStackFrameUrls = function(messageFormatter, node) { |
+ /** |
+ * @param {string} string |
+ */ |
+ function isNotEmptyLine(string) { |
+ return string.trim().length > 0; |
+ } |
+ |
+ /** |
+ * @param {string} string |
+ */ |
+ function ignoreStackFrameAndMutableData(string) { |
+ var buffer = string.replace(/\u200b/g, ''); |
+ buffer = buffer.replace(/VM\d+/g, 'VM'); |
+ return buffer.replace(/^\s+at [^\]]+(]?)$/, '$1'); |
+ } |
+ |
+ messageFormatter = messageFormatter || TestRunner.textContentWithLineBreaks; |
+ var buffer = messageFormatter(node); |
+ return buffer.split('\n').map(ignoreStackFrameAndMutableData).filter(isNotEmptyLine).join('\n'); |
+}; |
+ |
+/** |
+ * @param {!Element} element |
+ * @param {!ConsoleModel.ConsoleMessage} message |
+ * @return {string} |
+ */ |
+ConsoleTestRunner.simpleFormatter = function(element, message) { |
+ return message.messageText + ':' + message.line + ':' + message.column; |
+}; |
+ |
+/** |
+ * @param {boolean=} printOriginatingCommand |
+ * @param {boolean=} dumpClassNames |
+ * @param {!ConsoleTestRunner.Formatter=} messageFormatter |
+ */ |
+ConsoleTestRunner.dumpConsoleMessagesIgnoreErrorStackFrames = function( |
+ printOriginatingCommand, dumpClassNames, messageFormatter) { |
+ TestRunner.addResults(ConsoleTestRunner.dumpConsoleMessagesIntoArray( |
+ printOriginatingCommand, dumpClassNames, |
+ messageFormatter ? ConsoleTestRunner.formatterIgnoreStackFrameUrls.bind(this, messageFormatter) : undefined)); |
+}; |
+ |
+ConsoleTestRunner.dumpConsoleMessagesWithStyles = function() { |
+ var messageViews = Console.ConsoleView.instance()._visibleViewMessages; |
+ for (var i = 0; i < messageViews.length; ++i) { |
+ var element = messageViews[i].element(); |
+ var messageText = ConsoleTestRunner.prepareConsoleMessageText(element); |
+ TestRunner.addResult(messageText); |
+ var spans = element.querySelectorAll('.console-message-text *'); |
+ for (var j = 0; j < spans.length; ++j) |
+ TestRunner.addResult('Styled text #' + j + ': ' + (spans[j].style.cssText || 'NO STYLES DEFINED')); |
+ } |
+}; |
+ |
+/** |
+ * @param {boolean=} sortMessages |
+ */ |
+ConsoleTestRunner.dumpConsoleMessagesWithClasses = function(sortMessages) { |
+ var result = []; |
+ var messageViews = Console.ConsoleView.instance()._visibleViewMessages; |
+ for (var i = 0; i < messageViews.length; ++i) { |
+ var element = messageViews[i].element(); |
+ var contentElement = messageViews[i].contentElement(); |
+ var messageText = ConsoleTestRunner.prepareConsoleMessageText(element); |
+ result.push(messageText + ' ' + element.getAttribute('class') + ' > ' + contentElement.getAttribute('class')); |
+ } |
+ if (sortMessages) |
+ result.sort(); |
+ for (var i = 0; i < result.length; ++i) |
+ TestRunner.addResult(result[i]); |
caseq
2017/07/12 01:04:33
just TestRunner.addResults(result)?
chenwilliam
2017/07/12 22:02:58
Done.
|
+}; |
+ |
+ConsoleTestRunner.dumpConsoleClassesBrief = function() { |
+ var messageViews = Console.ConsoleView.instance()._visibleViewMessages; |
+ for (var i = 0; i < messageViews.length; ++i) |
+ TestRunner.addResult(messageViews[i].toMessageElement().className); |
+}; |
+ |
+ConsoleTestRunner.dumpConsoleCounters = function() { |
+ var counter = Counters.WarningErrorCounter._instanceForTest; |
+ for (var index = 0; index < counter._titles.length; ++index) |
+ TestRunner.addResult(counter._titles[index]); |
+ ConsoleTestRunner.dumpConsoleClassesBrief(); |
+}; |
+ |
+/** |
+ * @param {!Function} callback |
+ * @param {function(!Element):boolean} deepFilter |
+ * @param {function(!ObjectUI.ObjectPropertiesSection):boolean} sectionFilter |
+ */ |
+ConsoleTestRunner.expandConsoleMessages = function(callback, deepFilter, sectionFilter) { |
caseq
2017/07/12 01:04:33
Let's switch all these to promises!
chenwilliam
2017/07/12 22:02:58
See earlier comment about promisifying the API.
|
+ Console.ConsoleView.instance()._invalidateViewport(); |
+ var messageViews = Console.ConsoleView.instance()._visibleViewMessages; |
+ |
+ // Initiate round-trips to fetch necessary data for further rendering. |
+ for (var i = 0; i < messageViews.length; ++i) |
+ messageViews[i].element(); |
+ |
+ TestRunner.deprecatedRunAfterPendingDispatches(expandTreeElements); |
+ |
+ function expandTreeElements() { |
+ for (var i = 0; i < messageViews.length; ++i) { |
+ var element = messageViews[i].element(); |
+ for (var node = element; node; node = node.traverseNextNode(element)) { |
+ if (node.treeElementForTest) |
+ node.treeElementForTest.expand(); |
+ if (node._expandStackTraceForTest) |
+ node._expandStackTraceForTest(); |
+ if (!node._section) |
+ continue; |
+ if (sectionFilter && !sectionFilter(node._section)) |
+ continue; |
+ node._section.expand(); |
+ |
+ if (!deepFilter) |
+ continue; |
+ var treeElements = node._section.rootElement().children(); |
+ for (var j = 0; j < treeElements.length; ++j) { |
+ for (var treeElement = treeElements[j]; treeElement; |
+ treeElement = treeElement.traverseNextTreeElement(true, null, true)) { |
+ if (deepFilter(treeElement)) |
+ treeElement.expand(); |
+ } |
+ } |
+ } |
+ } |
+ TestRunner.deprecatedRunAfterPendingDispatches(callback); |
+ } |
+}; |
+ |
+/** |
+ * @param {!Function} callback |
+ */ |
+ConsoleTestRunner.expandGettersInConsoleMessages = function(callback) { |
+ var messageViews = Console.ConsoleView.instance()._visibleViewMessages; |
+ var properties = []; |
+ var propertiesCount = 0; |
+ TestRunner.addSniffer(ObjectUI.ObjectPropertyTreeElement.prototype, '_updateExpandable', propertyExpandableUpdated); |
+ for (var i = 0; i < messageViews.length; ++i) { |
+ var element = messageViews[i].element(); |
+ for (var node = element; node; node = node.traverseNextNode(element)) { |
+ if (node.classList && node.classList.contains('object-value-calculate-value-button')) { |
+ ++propertiesCount; |
+ node.click(); |
+ properties.push(node.parentElement.parentElement); |
+ } |
+ } |
+ } |
+ |
+ function propertyExpandableUpdated() { |
+ --propertiesCount; |
+ if (propertiesCount === 0) { |
+ for (var i = 0; i < properties.length; ++i) |
+ properties[i].click(); |
+ TestRunner.deprecatedRunAfterPendingDispatches(callback); |
+ } else { |
+ TestRunner.addSniffer( |
+ ObjectUI.ObjectPropertyTreeElement.prototype, '_updateExpandable', propertyExpandableUpdated); |
+ } |
+ } |
+}; |
+ |
+/** |
+ * @param {!Function} callback |
+ */ |
+ConsoleTestRunner.expandConsoleMessagesErrorParameters = function(callback) { |
+ var messageViews = Console.ConsoleView.instance()._visibleViewMessages; |
+ // Initiate round-trips to fetch necessary data for further rendering. |
+ for (var i = 0; i < messageViews.length; ++i) |
+ messageViews[i].element(); |
+ TestRunner.deprecatedRunAfterPendingDispatches(callback); |
+}; |
+ |
+/** |
+ * @param {!Function} callback |
+ */ |
+ConsoleTestRunner.waitForRemoteObjectsConsoleMessages = function(callback) { |
+ var messages = Console.ConsoleView.instance()._visibleViewMessages; |
+ for (var i = 0; i < messages.length; ++i) |
+ messages[i].toMessageElement(); |
+ TestRunner.deprecatedRunAfterPendingDispatches(callback); |
+}; |
+ |
+/** |
+ * @return {!Promise} |
+ */ |
+ConsoleTestRunner.waitUntilConsoleEditorLoaded = function() { |
+ var fulfill; |
+ var promise = new Promise(x => (fulfill = x)); |
+ var editor = Console.ConsoleView.instance()._prompt._editor; |
+ if (editor) |
+ fulfill(editor); |
+ else |
+ TestRunner.addSniffer(Console.ConsolePrompt.prototype, '_editorSetForTest', _ => fulfill(editor)); |
+ return promise; |
+}; |
+ |
+/** |
+ * @param {!Function} callback |
+ */ |
+ConsoleTestRunner.waitUntilMessageReceived = function(callback) { |
+ TestRunner.addSniffer(ConsoleModel.consoleModel, 'addMessage', callback, false); |
+}; |
+ |
+/** |
+ * @return {!Promise} |
+ */ |
+ConsoleTestRunner.waitUntilMessageReceivedPromise = function() { |
+ var callback; |
+ var promise = new Promise(fullfill => (callback = fullfill)); |
+ ConsoleTestRunner.waitUntilMessageReceived(callback); |
+ return promise; |
+}; |
+ |
+/** |
+ * @param {number} count |
+ * @param {!Function} callback |
+ */ |
+ConsoleTestRunner.waitUntilNthMessageReceived = function(count, callback) { |
+ function override() { |
+ if (--count === 0) |
+ TestRunner.safeWrap(callback)(); |
+ else |
+ TestRunner.addSniffer(ConsoleModel.consoleModel, 'addMessage', override, false); |
+ } |
+ TestRunner.addSniffer(ConsoleModel.consoleModel, 'addMessage', override, false); |
+}; |
+ |
+/** |
+ * @param {number} count |
+ * @return {!Promise} |
+ */ |
+ConsoleTestRunner.waitUntilNthMessageReceivedPromise = function(count) { |
+ var callback; |
+ var promise = new Promise(fullfill => (callback = fullfill)); |
+ ConsoleTestRunner.waitUntilNthMessageReceived(count, callback); |
+ return promise; |
+}; |
+ |
+/** |
+ * @param {string} namePrefix |
+ */ |
+ConsoleTestRunner.changeExecutionContext = function(namePrefix) { |
+ var selector = Console.ConsoleView.instance()._consoleContextSelector; |
+ for (var executionContext of selector._items) { |
+ if (selector.titleFor(executionContext).startsWith(namePrefix)) { |
+ UI.context.setFlavor(SDK.ExecutionContext, executionContext); |
+ return; |
+ } |
+ } |
+ TestRunner.addResult('FAILED: context with prefix: ' + namePrefix + ' not found in the context list'); |
+}; |
+ |
+/** |
+ * @param {number} expectedCount |
+ * @param {!Function} callback |
+ */ |
+ConsoleTestRunner.waitForConsoleMessages = function(expectedCount, callback) { |
+ var consoleView = Console.ConsoleView.instance(); |
+ checkAndReturn(); |
+ |
+ function checkAndReturn() { |
+ if (consoleView._visibleViewMessages.length === expectedCount) { |
+ TestRunner.addResult('Message count: ' + expectedCount); |
+ callback(); |
+ } else { |
+ TestRunner.addSniffer(consoleView, '_messageAppendedForTests', checkAndReturn); |
+ } |
+ } |
+}; |
+ |
+/** |
+ * @param {number} fromMessage |
+ * @param {number} fromTextOffset |
+ * @param {number} toMessage |
+ * @param {number} toTextOffset |
+ * @suppressGlobalPropertiesCheck |
+ */ |
+ConsoleTestRunner.selectConsoleMessages = function(fromMessage, fromTextOffset, toMessage, toTextOffset) { |
+ var consoleView = Console.ConsoleView.instance(); |
+ var from = selectionContainerAndOffset(consoleView.itemElement(fromMessage).element(), fromTextOffset); |
+ var to = selectionContainerAndOffset(consoleView.itemElement(toMessage).element(), toTextOffset); |
+ window.getSelection().setBaseAndExtent(from.container, from.offset, to.container, to.offset); |
+ |
+ /** |
+ * @param {!Node} container |
+ * @param {number} offset |
+ * @return {?{container: !Node, offset: number}} |
+ */ |
+ function selectionContainerAndOffset(container, offset) { |
+ /** @type {?Node} */ |
+ var node = container; |
+ if (offset === 0 && container.nodeType !== Node.TEXT_NODE) { |
+ container = /** @type {!Node} */ (container.traverseNextTextNode()); |
+ node = container; |
+ } |
+ var charCount = 0; |
+ while ((node = node.traverseNextTextNode(container))) { |
+ var length = node.textContent.length; |
+ if (charCount + length >= offset) |
+ return {container: node, offset: offset - charCount}; |
+ |
+ charCount += length; |
+ } |
+ return null; |
+ } |
+}; |