Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1210)

Side by Side Diff: third_party/WebKit/Source/devtools/front_end/console_test_runner/ConsoleTestRunner.js

Issue 2975523002: DevTools: add console test helpers to new test runner & migrate a console test (Closed)
Patch Set: fix Created 3 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
1 // Copyright 2017 The Chromium Authors. All rights reserved. 1 // Copyright 2017 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 /** 5 /**
6 * @fileoverview using private properties isn't a Closure violation in tests. 6 * @fileoverview using private properties isn't a Closure violation in tests.
7 * @suppress {accessControls} 7 * @suppress {accessControls}
8 */ 8 */
9 9
10 /** @typedef {function(!Element, !ConsoleModel.ConsoleMessage=):string} */
11 ConsoleTestRunner.Formatter;
12
10 /** 13 /**
11 * @param {boolean} printOriginatingCommand 14 * @param {boolean=} printOriginatingCommand
12 * @param {boolean} dumpClassNames 15 * @param {boolean=} dumpClassNames
13 * @param {function(!Element, !ConsoleModel.ConsoleMessage):string=} formatter 16 * @param {!ConsoleTestRunner.Formatter=} formatter
14 */ 17 */
15 ConsoleTestRunner.dumpConsoleMessages = function(printOriginatingCommand, dumpCl assNames, formatter) { 18 ConsoleTestRunner.dumpConsoleMessages = function(printOriginatingCommand, dumpCl assNames, formatter) {
16 TestRunner.addResults( 19 TestRunner.addResults(
17 ConsoleTestRunner.dumpConsoleMessagesIntoArray(printOriginatingCommand, du mpClassNames, formatter)); 20 ConsoleTestRunner.dumpConsoleMessagesIntoArray(printOriginatingCommand, du mpClassNames, formatter));
18 }; 21 };
19 22
20 /** 23 /**
21 * @param {boolean} printOriginatingCommand 24 * @param {boolean=} printOriginatingCommand
22 * @param {boolean} dumpClassNames 25 * @param {boolean=} dumpClassNames
23 * @param {function(!Element, !ConsoleModel.ConsoleMessage):string=} formatter 26 * @param {!ConsoleTestRunner.Formatter=} formatter
24 * @return {!Array<string>} 27 * @return {!Array<string>}
25 */ 28 */
26 ConsoleTestRunner.dumpConsoleMessagesIntoArray = function(printOriginatingComman d, dumpClassNames, formatter) { 29 ConsoleTestRunner.dumpConsoleMessagesIntoArray = function(printOriginatingComman d, dumpClassNames, formatter) {
27 formatter = formatter || ConsoleTestRunner.prepareConsoleMessageText; 30 formatter = formatter || ConsoleTestRunner.prepareConsoleMessageText;
28 var result = []; 31 var result = [];
29 ConsoleTestRunner.disableConsoleViewport(); 32 ConsoleTestRunner.disableConsoleViewport();
30 var consoleView = Console.ConsoleView.instance(); 33 var consoleView = Console.ConsoleView.instance();
31 if (consoleView._needsFullUpdate) 34 if (consoleView._needsFullUpdate)
32 consoleView._updateMessageList(); 35 consoleView._updateMessageList();
33 var viewMessages = consoleView._visibleViewMessages; 36 var viewMessages = consoleView._visibleViewMessages;
(...skipping 23 matching lines...) Expand all
57 } 60 }
58 61
59 if (printOriginatingCommand && uiMessage.consoleMessage().originatingMessage ()) 62 if (printOriginatingCommand && uiMessage.consoleMessage().originatingMessage ())
60 result.push('Originating from: ' + uiMessage.consoleMessage().originatingM essage().messageText); 63 result.push('Originating from: ' + uiMessage.consoleMessage().originatingM essage().messageText);
61 } 64 }
62 return result; 65 return result;
63 }; 66 };
64 67
65 /** 68 /**
66 * @param {!Element} messageElement 69 * @param {!Element} messageElement
67 * @param {!ConsoleModel.ConsoleMessage} consoleMessage
68 * @return {string} 70 * @return {string}
69 */ 71 */
70 ConsoleTestRunner.prepareConsoleMessageText = function(messageElement, consoleMe ssage) { 72 ConsoleTestRunner.prepareConsoleMessageText = function(messageElement) {
71 var messageText = messageElement.deepTextContent().replace(/\u200b/g, ''); 73 var messageText = messageElement.deepTextContent().replace(/\u200b/g, '');
72 // Replace scriptIds with generic scriptId string to avoid flakiness. 74 // Replace scriptIds with generic scriptId string to avoid flakiness.
73 messageText = messageText.replace(/VM\d+/g, 'VM'); 75 messageText = messageText.replace(/VM\d+/g, 'VM');
74 // Remove line and column of evaluate method. 76 // Remove line and column of evaluate method.
75 messageText = messageText.replace(/(at eval \(eval at evaluate) \(:\d+:\d+\)/, '$1'); 77 messageText = messageText.replace(/(at eval \(eval at evaluate) \(:\d+:\d+\)/, '$1');
76 78
77 if (messageText.startsWith('Navigated to')) { 79 if (messageText.startsWith('Navigated to')) {
78 var fileName = messageText.split(' ').pop().split('/').pop(); 80 var fileName = messageText.split(' ').pop().split('/').pop();
79 messageText = 'Navigated to ' + fileName; 81 messageText = 'Navigated to ' + fileName;
80 } 82 }
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
136 /** 138 /**
137 * @param {number} width 139 * @param {number} width
138 * @param {number} height 140 * @param {number} height
139 */ 141 */
140 ConsoleTestRunner.fixConsoleViewportDimensions = function(width, height) { 142 ConsoleTestRunner.fixConsoleViewportDimensions = function(width, height) {
141 var viewport = Console.ConsoleView.instance()._viewport; 143 var viewport = Console.ConsoleView.instance()._viewport;
142 viewport.element.style.width = width + 'px'; 144 viewport.element.style.width = width + 'px';
143 viewport.element.style.height = height + 'px'; 145 viewport.element.style.height = height + 'px';
144 viewport.element.style.position = 'absolute'; 146 viewport.element.style.position = 'absolute';
145 viewport.invalidate(); 147 viewport.invalidate();
146 }; 148 };
149
150 ConsoleTestRunner.selectMainExecutionContext = function() {
151 var executionContexts = TestRunner.runtimeModel.executionContexts();
152 for (var context of executionContexts) {
153 if (context.isDefault) {
154 UI.context.setFlavor(SDK.ExecutionContext, context);
155 return;
156 }
157 }
158 };
159
160 /**
161 * @param {string} code
162 * @param {!Function=} callback
163 * @param {boolean=} dontForceMainContext
164 */
165 ConsoleTestRunner.evaluateInConsole = function(code, callback, dontForceMainCont ext) {
166 if (!dontForceMainContext)
167 ConsoleTestRunner.selectMainExecutionContext();
168 callback = TestRunner.safeWrap(callback);
169
170 var consoleView = Console.ConsoleView.instance();
171 consoleView._prompt._appendCommand(code, true);
172 ConsoleTestRunner.addConsoleViewSniffer(function(commandResult) {
173 callback(commandResult.toMessageElement().deepTextContent());
174 });
175 };
176
177 /**
178 * @param {!Function} override
179 * @param {boolean=} opt_sticky
180 */
181 ConsoleTestRunner.addConsoleViewSniffer = function(override, opt_sticky) {
182 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
183 override(viewMessage);
184 };
185
186 TestRunner.addSniffer(Console.ConsoleView.prototype, '_consoleMessageAddedForT est', sniffer, opt_sticky);
187 };
188
189 /**
190 * @param {string} code
191 * @param {!Function=} callback
192 * @param {boolean=} dontForceMainContext
193 */
194 ConsoleTestRunner.evaluateInConsoleAndDump = function(code, callback, dontForceM ainContext) {
195 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.
196
197 /**
198 * @param {string} text
199 */
200 function mycallback(text) {
201 text = text.replace(/\bVM\d+/g, 'VM');
202 TestRunner.addResult(code + ' = ' + text);
203 callback(text);
204 }
205 ConsoleTestRunner.evaluateInConsole(code, mycallback, dontForceMainContext);
206 };
207
208 /**
209 * @return {number}
210 */
211 ConsoleTestRunner.consoleMessagesCount = function() {
212 var consoleView = Console.ConsoleView.instance();
213 return consoleView._consoleMessages.length;
214 };
215
216 /**
217 * @param {function(!Element):string} messageFormatter
218 * @param {!Element} node
219 * @return {string}
220 */
221 ConsoleTestRunner.formatterIgnoreStackFrameUrls = function(messageFormatter, nod e) {
222 /**
223 * @param {string} string
224 */
225 function isNotEmptyLine(string) {
226 return string.trim().length > 0;
227 }
228
229 /**
230 * @param {string} string
231 */
232 function ignoreStackFrameAndMutableData(string) {
233 var buffer = string.replace(/\u200b/g, '');
234 buffer = buffer.replace(/VM\d+/g, 'VM');
235 return buffer.replace(/^\s+at [^\]]+(]?)$/, '$1');
236 }
237
238 messageFormatter = messageFormatter || TestRunner.textContentWithLineBreaks;
239 var buffer = messageFormatter(node);
240 return buffer.split('\n').map(ignoreStackFrameAndMutableData).filter(isNotEmpt yLine).join('\n');
241 };
242
243 /**
244 * @param {!Element} element
245 * @param {!ConsoleModel.ConsoleMessage} message
246 * @return {string}
247 */
248 ConsoleTestRunner.simpleFormatter = function(element, message) {
249 return message.messageText + ':' + message.line + ':' + message.column;
250 };
251
252 /**
253 * @param {boolean=} printOriginatingCommand
254 * @param {boolean=} dumpClassNames
255 * @param {!ConsoleTestRunner.Formatter=} messageFormatter
256 */
257 ConsoleTestRunner.dumpConsoleMessagesIgnoreErrorStackFrames = function(
258 printOriginatingCommand, dumpClassNames, messageFormatter) {
259 TestRunner.addResults(ConsoleTestRunner.dumpConsoleMessagesIntoArray(
260 printOriginatingCommand, dumpClassNames,
261 messageFormatter ? ConsoleTestRunner.formatterIgnoreStackFrameUrls.bind(th is, messageFormatter) : undefined));
262 };
263
264 ConsoleTestRunner.dumpConsoleMessagesWithStyles = function() {
265 var messageViews = Console.ConsoleView.instance()._visibleViewMessages;
266 for (var i = 0; i < messageViews.length; ++i) {
267 var element = messageViews[i].element();
268 var messageText = ConsoleTestRunner.prepareConsoleMessageText(element);
269 TestRunner.addResult(messageText);
270 var spans = element.querySelectorAll('.console-message-text *');
271 for (var j = 0; j < spans.length; ++j)
272 TestRunner.addResult('Styled text #' + j + ': ' + (spans[j].style.cssText || 'NO STYLES DEFINED'));
273 }
274 };
275
276 /**
277 * @param {boolean=} sortMessages
278 */
279 ConsoleTestRunner.dumpConsoleMessagesWithClasses = function(sortMessages) {
280 var result = [];
281 var messageViews = Console.ConsoleView.instance()._visibleViewMessages;
282 for (var i = 0; i < messageViews.length; ++i) {
283 var element = messageViews[i].element();
284 var contentElement = messageViews[i].contentElement();
285 var messageText = ConsoleTestRunner.prepareConsoleMessageText(element);
286 result.push(messageText + ' ' + element.getAttribute('class') + ' > ' + cont entElement.getAttribute('class'));
287 }
288 if (sortMessages)
289 result.sort();
290 for (var i = 0; i < result.length; ++i)
291 TestRunner.addResult(result[i]);
caseq 2017/07/12 01:04:33 just TestRunner.addResults(result)?
chenwilliam 2017/07/12 22:02:58 Done.
292 };
293
294 ConsoleTestRunner.dumpConsoleClassesBrief = function() {
295 var messageViews = Console.ConsoleView.instance()._visibleViewMessages;
296 for (var i = 0; i < messageViews.length; ++i)
297 TestRunner.addResult(messageViews[i].toMessageElement().className);
298 };
299
300 ConsoleTestRunner.dumpConsoleCounters = function() {
301 var counter = Counters.WarningErrorCounter._instanceForTest;
302 for (var index = 0; index < counter._titles.length; ++index)
303 TestRunner.addResult(counter._titles[index]);
304 ConsoleTestRunner.dumpConsoleClassesBrief();
305 };
306
307 /**
308 * @param {!Function} callback
309 * @param {function(!Element):boolean} deepFilter
310 * @param {function(!ObjectUI.ObjectPropertiesSection):boolean} sectionFilter
311 */
312 ConsoleTestRunner.expandConsoleMessages = function(callback, deepFilter, section Filter) {
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.
313 Console.ConsoleView.instance()._invalidateViewport();
314 var messageViews = Console.ConsoleView.instance()._visibleViewMessages;
315
316 // Initiate round-trips to fetch necessary data for further rendering.
317 for (var i = 0; i < messageViews.length; ++i)
318 messageViews[i].element();
319
320 TestRunner.deprecatedRunAfterPendingDispatches(expandTreeElements);
321
322 function expandTreeElements() {
323 for (var i = 0; i < messageViews.length; ++i) {
324 var element = messageViews[i].element();
325 for (var node = element; node; node = node.traverseNextNode(element)) {
326 if (node.treeElementForTest)
327 node.treeElementForTest.expand();
328 if (node._expandStackTraceForTest)
329 node._expandStackTraceForTest();
330 if (!node._section)
331 continue;
332 if (sectionFilter && !sectionFilter(node._section))
333 continue;
334 node._section.expand();
335
336 if (!deepFilter)
337 continue;
338 var treeElements = node._section.rootElement().children();
339 for (var j = 0; j < treeElements.length; ++j) {
340 for (var treeElement = treeElements[j]; treeElement;
341 treeElement = treeElement.traverseNextTreeElement(true, null, tru e)) {
342 if (deepFilter(treeElement))
343 treeElement.expand();
344 }
345 }
346 }
347 }
348 TestRunner.deprecatedRunAfterPendingDispatches(callback);
349 }
350 };
351
352 /**
353 * @param {!Function} callback
354 */
355 ConsoleTestRunner.expandGettersInConsoleMessages = function(callback) {
356 var messageViews = Console.ConsoleView.instance()._visibleViewMessages;
357 var properties = [];
358 var propertiesCount = 0;
359 TestRunner.addSniffer(ObjectUI.ObjectPropertyTreeElement.prototype, '_updateEx pandable', propertyExpandableUpdated);
360 for (var i = 0; i < messageViews.length; ++i) {
361 var element = messageViews[i].element();
362 for (var node = element; node; node = node.traverseNextNode(element)) {
363 if (node.classList && node.classList.contains('object-value-calculate-valu e-button')) {
364 ++propertiesCount;
365 node.click();
366 properties.push(node.parentElement.parentElement);
367 }
368 }
369 }
370
371 function propertyExpandableUpdated() {
372 --propertiesCount;
373 if (propertiesCount === 0) {
374 for (var i = 0; i < properties.length; ++i)
375 properties[i].click();
376 TestRunner.deprecatedRunAfterPendingDispatches(callback);
377 } else {
378 TestRunner.addSniffer(
379 ObjectUI.ObjectPropertyTreeElement.prototype, '_updateExpandable', pro pertyExpandableUpdated);
380 }
381 }
382 };
383
384 /**
385 * @param {!Function} callback
386 */
387 ConsoleTestRunner.expandConsoleMessagesErrorParameters = function(callback) {
388 var messageViews = Console.ConsoleView.instance()._visibleViewMessages;
389 // Initiate round-trips to fetch necessary data for further rendering.
390 for (var i = 0; i < messageViews.length; ++i)
391 messageViews[i].element();
392 TestRunner.deprecatedRunAfterPendingDispatches(callback);
393 };
394
395 /**
396 * @param {!Function} callback
397 */
398 ConsoleTestRunner.waitForRemoteObjectsConsoleMessages = function(callback) {
399 var messages = Console.ConsoleView.instance()._visibleViewMessages;
400 for (var i = 0; i < messages.length; ++i)
401 messages[i].toMessageElement();
402 TestRunner.deprecatedRunAfterPendingDispatches(callback);
403 };
404
405 /**
406 * @return {!Promise}
407 */
408 ConsoleTestRunner.waitUntilConsoleEditorLoaded = function() {
409 var fulfill;
410 var promise = new Promise(x => (fulfill = x));
411 var editor = Console.ConsoleView.instance()._prompt._editor;
412 if (editor)
413 fulfill(editor);
414 else
415 TestRunner.addSniffer(Console.ConsolePrompt.prototype, '_editorSetForTest', _ => fulfill(editor));
416 return promise;
417 };
418
419 /**
420 * @param {!Function} callback
421 */
422 ConsoleTestRunner.waitUntilMessageReceived = function(callback) {
423 TestRunner.addSniffer(ConsoleModel.consoleModel, 'addMessage', callback, false );
424 };
425
426 /**
427 * @return {!Promise}
428 */
429 ConsoleTestRunner.waitUntilMessageReceivedPromise = function() {
430 var callback;
431 var promise = new Promise(fullfill => (callback = fullfill));
432 ConsoleTestRunner.waitUntilMessageReceived(callback);
433 return promise;
434 };
435
436 /**
437 * @param {number} count
438 * @param {!Function} callback
439 */
440 ConsoleTestRunner.waitUntilNthMessageReceived = function(count, callback) {
441 function override() {
442 if (--count === 0)
443 TestRunner.safeWrap(callback)();
444 else
445 TestRunner.addSniffer(ConsoleModel.consoleModel, 'addMessage', override, f alse);
446 }
447 TestRunner.addSniffer(ConsoleModel.consoleModel, 'addMessage', override, false );
448 };
449
450 /**
451 * @param {number} count
452 * @return {!Promise}
453 */
454 ConsoleTestRunner.waitUntilNthMessageReceivedPromise = function(count) {
455 var callback;
456 var promise = new Promise(fullfill => (callback = fullfill));
457 ConsoleTestRunner.waitUntilNthMessageReceived(count, callback);
458 return promise;
459 };
460
461 /**
462 * @param {string} namePrefix
463 */
464 ConsoleTestRunner.changeExecutionContext = function(namePrefix) {
465 var selector = Console.ConsoleView.instance()._consoleContextSelector;
466 for (var executionContext of selector._items) {
467 if (selector.titleFor(executionContext).startsWith(namePrefix)) {
468 UI.context.setFlavor(SDK.ExecutionContext, executionContext);
469 return;
470 }
471 }
472 TestRunner.addResult('FAILED: context with prefix: ' + namePrefix + ' not foun d in the context list');
473 };
474
475 /**
476 * @param {number} expectedCount
477 * @param {!Function} callback
478 */
479 ConsoleTestRunner.waitForConsoleMessages = function(expectedCount, callback) {
480 var consoleView = Console.ConsoleView.instance();
481 checkAndReturn();
482
483 function checkAndReturn() {
484 if (consoleView._visibleViewMessages.length === expectedCount) {
485 TestRunner.addResult('Message count: ' + expectedCount);
486 callback();
487 } else {
488 TestRunner.addSniffer(consoleView, '_messageAppendedForTests', checkAndRet urn);
489 }
490 }
491 };
492
493 /**
494 * @param {number} fromMessage
495 * @param {number} fromTextOffset
496 * @param {number} toMessage
497 * @param {number} toTextOffset
498 * @suppressGlobalPropertiesCheck
499 */
500 ConsoleTestRunner.selectConsoleMessages = function(fromMessage, fromTextOffset, toMessage, toTextOffset) {
501 var consoleView = Console.ConsoleView.instance();
502 var from = selectionContainerAndOffset(consoleView.itemElement(fromMessage).el ement(), fromTextOffset);
503 var to = selectionContainerAndOffset(consoleView.itemElement(toMessage).elemen t(), toTextOffset);
504 window.getSelection().setBaseAndExtent(from.container, from.offset, to.contain er, to.offset);
505
506 /**
507 * @param {!Node} container
508 * @param {number} offset
509 * @return {?{container: !Node, offset: number}}
510 */
511 function selectionContainerAndOffset(container, offset) {
512 /** @type {?Node} */
513 var node = container;
514 if (offset === 0 && container.nodeType !== Node.TEXT_NODE) {
515 container = /** @type {!Node} */ (container.traverseNextTextNode());
516 node = container;
517 }
518 var charCount = 0;
519 while ((node = node.traverseNextTextNode(container))) {
520 var length = node.textContent.length;
521 if (charCount + length >= offset)
522 return {container: node, offset: offset - charCount};
523
524 charCount += length;
525 }
526 return null;
527 }
528 };
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698