tizen beta release
[profile/ivi/webkit-efl.git] / Source / WebKit / chromium / src / js / Tests.js
1 /*
2  * Copyright (C) 2010 Google Inc. All rights reserved.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  *     * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *     * Redistributions in binary form must reproduce the above
11  * copyright notice, this list of conditions and the following disclaimer
12  * in the documentation and/or other materials provided with the
13  * distribution.
14  *     * Neither the name of Google Inc. nor the names of its
15  * contributors may be used to endorse or promote products derived from
16  * this software without specific prior written permission.
17  *
18  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
19  * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
20  * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
21  * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
22  * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
23  * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
24  * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
25  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
26  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
27  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
28  * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
29  */
30
31
32 /**
33  * @fileoverview This file contains small testing framework along with the
34  * test suite for the frontend. These tests are a part of the continues build
35  * and are executed by the devtools_sanity_unittest.cc as a part of the
36  * Interactive UI Test suite.
37  * FIXME: change field naming style to use trailing underscore.
38  */
39
40 if (window.domAutomationController) {
41
42 var ___interactiveUiTestsMode = true;
43
44 /**
45  * Test suite for interactive UI tests.
46  * @constructor
47  */
48 TestSuite = function()
49 {
50     this.controlTaken_ = false;
51     this.timerId_ = -1;
52 };
53
54
55 /**
56  * Reports test failure.
57  * @param {string} message Failure description.
58  */
59 TestSuite.prototype.fail = function(message)
60 {
61     if (this.controlTaken_)
62         this.reportFailure_(message);
63     else
64         throw message;
65 };
66
67
68 /**
69  * Equals assertion tests that expected === actual.
70  * @param {Object} expected Expected object.
71  * @param {Object} actual Actual object.
72  * @param {string} opt_message User message to print if the test fails.
73  */
74 TestSuite.prototype.assertEquals = function(expected, actual, opt_message)
75 {
76     if (expected !== actual) {
77         var message = "Expected: '" + expected + "', but was '" + actual + "'";
78         if (opt_message)
79             message = opt_message + "(" + message + ")";
80         this.fail(message);
81     }
82 };
83
84 /**
85  * True assertion tests that value == true.
86  * @param {Object} value Actual object.
87  * @param {string} opt_message User message to print if the test fails.
88  */
89 TestSuite.prototype.assertTrue = function(value, opt_message)
90 {
91     this.assertEquals(true, !!value, opt_message);
92 };
93
94
95 /**
96  * Contains assertion tests that string contains substring.
97  * @param {string} string Outer.
98  * @param {string} substring Inner.
99  */
100 TestSuite.prototype.assertContains = function(string, substring)
101 {
102     if (string.indexOf(substring) === -1)
103         this.fail("Expected to: '" + string + "' to contain '" + substring + "'");
104 };
105
106
107 /**
108  * Takes control over execution.
109  */
110 TestSuite.prototype.takeControl = function()
111 {
112     this.controlTaken_ = true;
113     // Set up guard timer.
114     var self = this;
115     this.timerId_ = setTimeout(function() {
116         self.reportFailure_("Timeout exceeded: 20 sec");
117     }, 20000);
118 };
119
120
121 /**
122  * Releases control over execution.
123  */
124 TestSuite.prototype.releaseControl = function()
125 {
126     if (this.timerId_ !== -1) {
127         clearTimeout(this.timerId_);
128         this.timerId_ = -1;
129     }
130     this.reportOk_();
131 };
132
133
134 /**
135  * Async tests use this one to report that they are completed.
136  */
137 TestSuite.prototype.reportOk_ = function()
138 {
139     window.domAutomationController.send("[OK]");
140 };
141
142
143 /**
144  * Async tests use this one to report failures.
145  */
146 TestSuite.prototype.reportFailure_ = function(error)
147 {
148     if (this.timerId_ !== -1) {
149         clearTimeout(this.timerId_);
150         this.timerId_ = -1;
151     }
152     window.domAutomationController.send("[FAILED] " + error);
153 };
154
155
156 /**
157  * Runs all global functions starting with "test" as unit tests.
158  */
159 TestSuite.prototype.runTest = function(testName)
160 {
161     try {
162         this[testName]();
163         if (!this.controlTaken_)
164             this.reportOk_();
165     } catch (e) {
166         this.reportFailure_(e);
167     }
168 };
169
170
171 /**
172  * @param {string} panelName Name of the panel to show.
173  */
174 TestSuite.prototype.showPanel = function(panelName)
175 {
176     // Open Scripts panel.
177     var toolbar = document.getElementById("toolbar");
178     var button = toolbar.getElementsByClassName(panelName)[0];
179     button.click();
180     this.assertEquals(WebInspector.panels[panelName], WebInspector.inspectorView.currentPanel());
181 };
182
183
184 /**
185  * Overrides the method with specified name until it's called first time.
186  * @param {Object} receiver An object whose method to override.
187  * @param {string} methodName Name of the method to override.
188  * @param {Function} override A function that should be called right after the
189  *     overriden method returns.
190  * @param {boolean} opt_sticky Whether restore original method after first run
191  *     or not.
192  */
193 TestSuite.prototype.addSniffer = function(receiver, methodName, override, opt_sticky)
194 {
195     var orig = receiver[methodName];
196     if (typeof orig !== "function")
197         this.fail("Cannot find method to override: " + methodName);
198     var test = this;
199     receiver[methodName] = function(var_args) {
200         try {
201             var result = orig.apply(this, arguments);
202         } finally {
203             if (!opt_sticky)
204                 receiver[methodName] = orig;
205         }
206         // In case of exception the override won't be called.
207         try {
208             override.apply(this, arguments);
209         } catch (e) {
210             test.fail("Exception in overriden method '" + methodName + "': " + e);
211         }
212         return result;
213     };
214 };
215
216
217 TestSuite.prototype.testEnableResourcesTab = function()
218 {
219     // FIXME once reference is removed downstream.
220 }
221
222 TestSuite.prototype.testCompletionOnPause = function()
223 {
224     // FIXME once reference is removed downstream.
225 }
226
227 // UI Tests
228
229
230 /**
231  * Tests that scripts tab can be open and populated with inspected scripts.
232  */
233 TestSuite.prototype.testShowScriptsTab = function()
234 {
235     this.showPanel("scripts");
236     var test = this;
237     // There should be at least main page script.
238     this._waitUntilScriptsAreParsed(["debugger_test_page.html"],
239         function() {
240             test.releaseControl();
241         });
242     // Wait until all scripts are added to the debugger.
243     this.takeControl();
244 };
245
246
247 /**
248  * Tests that scripts tab is populated with inspected scripts even if it
249  * hadn't been shown by the moment inspected paged refreshed.
250  * @see http://crbug.com/26312
251  */
252 TestSuite.prototype.testScriptsTabIsPopulatedOnInspectedPageRefresh = function()
253 {
254     var test = this;
255     this.assertEquals(WebInspector.panels.elements, WebInspector.inspectorView.currentPanel(), "Elements panel should be current one.");
256
257     WebInspector.debuggerPresentationModel.addEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerReset, waitUntilScriptIsParsed);
258
259     // Reload inspected page. It will reset the debugger agent.
260     test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});
261
262     function waitUntilScriptIsParsed()
263     {
264         WebInspector.debuggerPresentationModel.removeEventListener(WebInspector.DebuggerPresentationModel.Events.DebuggerReset, waitUntilScriptIsParsed);
265         test.showPanel("scripts");
266         test._waitUntilScriptsAreParsed(["debugger_test_page.html"],
267             function() {
268                 test.releaseControl();
269             });
270     }
271
272     // Wait until all scripts are added to the debugger.
273     this.takeControl();
274 };
275
276
277 /**
278  * Tests that scripts list contains content scripts.
279  */
280 TestSuite.prototype.testContentScriptIsPresent = function()
281 {
282     this.showPanel("scripts");
283     var test = this;
284
285     test._waitUntilScriptsAreParsed(
286         ["page_with_content_script.html", "simple_content_script.js"],
287         function() {
288           test.releaseControl();
289         });
290
291     // Wait until all scripts are added to the debugger.
292     this.takeControl();
293 };
294
295
296 /**
297  * Tests that scripts are not duplicaed on Scripts tab switch.
298  */
299 TestSuite.prototype.testNoScriptDuplicatesOnPanelSwitch = function()
300 {
301     var test = this;
302
303     // There should be two scripts: one for the main page and another
304     // one which is source of console API(see
305     // InjectedScript._ensureCommandLineAPIInstalled).
306     var expectedScriptsCount = 2;
307     var parsedScripts = [];
308
309     this.showPanel("scripts");
310
311
312     function switchToElementsTab() {
313         test.showPanel("elements");
314         setTimeout(switchToScriptsTab, 0);
315     }
316
317     function switchToScriptsTab() {
318         test.showPanel("scripts");
319         setTimeout(checkScriptsPanel, 0);
320     }
321
322     function checkScriptsPanel() {
323         test.assertTrue(!!WebInspector.panels.scripts.visibleView, "No visible script view.");
324         test.assertTrue(test._scriptsAreParsed(["debugger_test_page.html"]), "Some scripts are missing.");
325         checkNoDuplicates();
326         test.releaseControl();
327     }
328
329     function checkNoDuplicates() {
330         var scriptSelect = document.getElementById("scripts-files");
331         var options = scriptSelect.options;
332         for (var i = 0; i < options.length; i++) {
333             var scriptName = options[i].text;
334             for (var j = i + 1; j < options.length; j++)
335                 test.assertTrue(scriptName !== options[j].text, "Found script duplicates: " + test.optionsToString_(options));
336         }
337     }
338
339     test._waitUntilScriptsAreParsed(
340         ["debugger_test_page.html"],
341         function() {
342             checkNoDuplicates();
343             setTimeout(switchToElementsTab, 0);
344         });
345
346
347     // Wait until all scripts are added to the debugger.
348     this.takeControl();
349 };
350
351
352 // Tests that debugger works correctly if pause event occurs when DevTools
353 // frontend is being loaded.
354 TestSuite.prototype.testPauseWhenLoadingDevTools = function()
355 {
356     this.showPanel("scripts");
357
358     // Script execution can already be paused.
359     if (WebInspector.debuggerModel.debuggerPausedDetails)
360         return;
361
362     this._waitForScriptPause(this.releaseControl.bind(this));
363     this.takeControl();
364 };
365
366
367 // Tests that pressing "Pause" will pause script execution if the script
368 // is already running.
369 TestSuite.prototype.testPauseWhenScriptIsRunning = function()
370 {
371     this.showPanel("scripts");
372
373     this.evaluateInConsole_(
374         'setTimeout("handleClick()" , 0)',
375         didEvaluateInConsole.bind(this));
376
377     function didEvaluateInConsole(resultText) {
378         this.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText);
379         // Wait for some time to make sure that inspected page is running the
380         // infinite loop.
381         setTimeout(testScriptPause.bind(this), 300);
382     }
383
384     function testScriptPause() {
385         // The script should be in infinite loop. Click "Pause" button to
386         // pause it and wait for the result.
387         WebInspector.panels.scripts.pauseButton.click();
388
389         this._waitForScriptPause(this.releaseControl.bind(this));
390     }
391
392     this.takeControl();
393 };
394
395
396 /**
397  * Tests network size.
398  */
399 TestSuite.prototype.testNetworkSize = function()
400 {
401     var test = this;
402
403     function finishResource(resource, finishTime)
404     {
405         test.assertEquals(219, resource.transferSize, "Incorrect total encoded data length");
406         test.assertEquals(25, resource.resourceSize, "Incorrect total data length");
407         test.releaseControl();
408     }
409     
410     this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishResource", finishResource);
411
412     // Reload inspected page to sniff network events
413     test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});
414     
415     this.takeControl();
416 };
417
418
419 /**
420  * Tests network sync size.
421  */
422 TestSuite.prototype.testNetworkSyncSize = function()
423 {
424     var test = this;
425
426     function finishResource(resource, finishTime)
427     {
428         test.assertEquals(219, resource.transferSize, "Incorrect total encoded data length");
429         test.assertEquals(25, resource.resourceSize, "Incorrect total data length");
430         test.releaseControl();
431     }
432     
433     this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishResource", finishResource);
434
435     // Send synchronous XHR to sniff network events
436     test.evaluateInConsole_("var xhr = new XMLHttpRequest(); xhr.open(\"GET\", \"chunked\", false); xhr.send(null);", function() {});
437     
438     this.takeControl();
439 };
440
441
442 /**
443  * Tests network raw headers text.
444  */
445 TestSuite.prototype.testNetworkRawHeadersText = function()
446 {
447     var test = this;
448     
449     function finishResource(resource, finishTime)
450     {
451         if (!resource.responseHeadersText)
452             test.fail("Failure: resource does not have response headers text");
453         test.assertEquals(164, resource.responseHeadersText.length, "Incorrect response headers text length");
454         test.releaseControl();
455     }
456     
457     this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishResource", finishResource);
458
459     // Reload inspected page to sniff network events
460     test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});
461     
462     this.takeControl();
463 };
464
465
466 /**
467  * Tests network timing.
468  */
469 TestSuite.prototype.testNetworkTiming = function()
470 {
471     var test = this;
472
473     function finishResource(resource, finishTime)
474     {
475         // Setting relaxed expectations to reduce flakiness. 
476         // Server sends headers after 100ms, then sends data during another 100ms.
477         // We expect these times to be measured at least as 70ms.  
478         test.assertTrue(resource.timing.receiveHeadersEnd - resource.timing.connectStart >= 70, 
479                         "Time between receiveHeadersEnd and connectStart should be >=70ms, but was " +
480                         "receiveHeadersEnd=" + resource.timing.receiveHeadersEnd + ", connectStart=" + resource.timing.connectStart + ".");
481         test.assertTrue(resource.responseReceivedTime - resource.startTime >= 0.07, 
482                 "Time between responseReceivedTime and startTime should be >=0.07s, but was " +
483                 "responseReceivedTime=" + resource.responseReceivedTime + ", startTime=" + resource.startTime + ".");
484         test.assertTrue(resource.endTime - resource.startTime >= 0.14, 
485                 "Time between endTime and startTime should be >=0.14s, but was " +
486                 "endtime=" + resource.endTime + ", startTime=" + resource.startTime + ".");
487         
488         test.releaseControl();
489     }
490     
491     this.addSniffer(WebInspector.NetworkDispatcher.prototype, "_finishResource", finishResource);
492     
493     // Reload inspected page to sniff network events
494     test.evaluateInConsole_("window.location.reload(true);", function(resultText) {});
495
496     this.takeControl();
497 };
498
499
500 TestSuite.prototype.testConsoleOnNavigateBack = function()
501 {
502     if (WebInspector.console.messages.length === 1)
503         firstConsoleMessageReceived.call(this);
504     else
505         WebInspector.console.addEventListener(WebInspector.ConsoleModel.Events.MessageAdded, firstConsoleMessageReceived, this);
506
507     function firstConsoleMessageReceived() {
508         this.evaluateInConsole_("clickLink();", didClickLink.bind(this));
509     }
510
511     function didClickLink() {
512         // Check that there are no new messages(command is not a message).
513         this.assertEquals(1, WebInspector.console.messages.length);
514         this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
515         this.evaluateInConsole_("history.back();", didNavigateBack.bind(this));
516     }
517
518     function didNavigateBack()
519     {
520         // Make sure navigation completed and possible console messages were pushed.
521         this.evaluateInConsole_("void 0;", didCompleteNavigation.bind(this));
522     }
523
524     function didCompleteNavigation() {
525         this.assertEquals(1, WebInspector.console.messages.length);
526         this.assertEquals(1, WebInspector.console.messages[0].totalRepeatCount);
527         this.releaseControl();
528     }
529
530     this.takeControl();
531 };
532
533
534 TestSuite.prototype.testReattachAfterCrash = function()
535 {
536     this.evaluateInConsole_("1+1;", this.releaseControl.bind(this));
537     this.takeControl();
538 };
539
540
541 TestSuite.prototype.testSharedWorker = function()
542 {
543     function didEvaluateInConsole(resultText) {
544         this.assertEquals("2011", resultText);
545         this.releaseControl();
546     }
547     this.evaluateInConsole_("globalVar", didEvaluateInConsole.bind(this));
548     this.takeControl();
549 };
550
551
552 TestSuite.prototype.testPauseInSharedWorkerInitialization = function()
553 {
554     if (WebInspector.debuggerModel.debuggerPausedDetails)
555         return;
556     this._waitForScriptPause(this.releaseControl.bind(this));
557     this.takeControl();
558 };
559
560
561 /**
562  * Serializes options collection to string.
563  * @param {HTMLOptionsCollection} options
564  * @return {string}
565  */
566 TestSuite.prototype.optionsToString_ = function(options)
567 {
568     var names = [];
569     for (var i = 0; i < options.length; i++)
570         names.push('"' + options[i].text + '"');
571     return names.join(",");
572 };
573
574
575 /**
576  * Ensures that main HTML resource is selected in Scripts panel and that its
577  * source frame is setup. Invokes the callback when the condition is satisfied.
578  * @param {HTMLOptionsCollection} options
579  * @param {function(WebInspector.SourceView,string)} callback
580  */
581 TestSuite.prototype.showMainPageScriptSource_ = function(scriptName, callback)
582 {
583     var test = this;
584
585     var scriptSelect = document.getElementById("scripts-files");
586     var options = scriptSelect.options;
587
588     test.assertTrue(options.length, "Scripts list is empty");
589
590     // Select page's script if it's not current option.
591     var scriptResource;
592     if (options[scriptSelect.selectedIndex].text === scriptName)
593         scriptResource = options[scriptSelect.selectedIndex].representedObject;
594     else {
595         var pageScriptIndex = -1;
596         for (var i = 0; i < options.length; i++) {
597             if (options[i].text === scriptName) {
598                 pageScriptIndex = i;
599                 break;
600             }
601         }
602         test.assertTrue(-1 !== pageScriptIndex, "Script with url " + scriptName + " not found among " + test.optionsToString_(options));
603         scriptResource = options[pageScriptIndex].representedObject;
604
605         // Current panel is "Scripts".
606         WebInspector.inspectorView.currentPanel()._showScriptOrResource(scriptResource);
607         test.assertEquals(pageScriptIndex, scriptSelect.selectedIndex, "Unexpected selected option index.");
608     }
609
610     test.assertTrue(scriptResource instanceof WebInspector.Resource,
611                     "Unexpected resource class.");
612     test.assertTrue(!!scriptResource.url, "Resource URL is null.");
613     test.assertTrue(scriptResource.url.search(scriptName + "$") !== -1, "Main HTML resource should be selected.");
614
615     var scriptsPanel = WebInspector.panels.scripts;
616
617     var view = scriptsPanel.visibleView;
618     test.assertTrue(view instanceof WebInspector.SourceView);
619
620     if (!view.sourceFrame._loaded) {
621         test.addSniffer(view, "_sourceFrameSetupFinished", function(event) {
622             callback(view, scriptResource.url);
623         });
624     } else
625         callback(view, scriptResource.url);
626 };
627
628
629 /*
630  * Evaluates the code in the console as if user typed it manually and invokes
631  * the callback when the result message is received and added to the console.
632  * @param {string} code
633  * @param {function(string)} callback
634  */
635 TestSuite.prototype.evaluateInConsole_ = function(code, callback)
636 {
637     WebInspector.showConsole();
638     WebInspector.consoleView.prompt.text = code;
639     WebInspector.consoleView.promptElement.dispatchEvent(TestSuite.createKeyEvent("Enter"));
640
641     this.addSniffer(WebInspector.ConsoleView.prototype, "_appendConsoleMessage",
642         function(commandResult) {
643             callback(commandResult.toMessageElement().textContent);
644         });
645 };
646
647
648 /**
649  * Checks that all expected scripts are present in the scripts list
650  * in the Scripts panel.
651  * @param {Array.<string>} expected Regular expressions describing
652  *     expected script names.
653  * @return {boolean} Whether all the scripts are in "scripts-files" select
654  *     box
655  */
656 TestSuite.prototype._scriptsAreParsed = function(expected)
657 {
658     var scriptSelect = document.getElementById("scripts-files");
659     var options = scriptSelect.options;
660
661     // Check that at least all the expected scripts are present.
662     var missing = expected.slice(0);
663     for (var i = 0 ; i < options.length; i++) {
664         for (var j = 0; j < missing.length; j++) {
665             if (options[i].text.search(missing[j]) !== -1) {
666                 missing.splice(j, 1);
667                 break;
668             }
669         }
670     }
671     return missing.length === 0;
672 };
673
674
675 /**
676  * Waits for script pause, checks expectations, and invokes the callback.
677  * @param {function():void} callback
678  */
679 TestSuite.prototype._waitForScriptPause = function(callback)
680 {
681     function pauseListener(event) {
682         WebInspector.debuggerModel.removeEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, pauseListener, this);
683         callback();
684     }
685     WebInspector.debuggerModel.addEventListener(WebInspector.DebuggerModel.Events.DebuggerPaused, pauseListener, this);
686 };
687
688
689 /**
690  * Waits until all the scripts are parsed and asynchronously executes the code
691  * in the inspected page.
692  */
693 TestSuite.prototype._executeCodeWhenScriptsAreParsed = function(code, expectedScripts)
694 {
695     var test = this;
696
697     function executeFunctionInInspectedPage() {
698         // Since breakpoints are ignored in evals' calculate() function is
699         // execute after zero-timeout so that the breakpoint is hit.
700         test.evaluateInConsole_(
701             'setTimeout("' + code + '" , 0)',
702             function(resultText) {
703                 test.assertTrue(!isNaN(resultText), "Failed to get timer id: " + resultText + ". Code: " + code);
704             });
705     }
706
707     test._waitUntilScriptsAreParsed(expectedScripts, executeFunctionInInspectedPage);
708 };
709
710
711 /**
712  * Waits until all the scripts are parsed and invokes the callback.
713  */
714 TestSuite.prototype._waitUntilScriptsAreParsed = function(expectedScripts, callback)
715 {
716     var test = this;
717
718     function waitForAllScripts() {
719         if (test._scriptsAreParsed(expectedScripts))
720             callback();
721         else
722             test.addSniffer(WebInspector.panels.scripts, "_addOptionToFilesSelect", waitForAllScripts);
723     }
724
725     waitForAllScripts();
726 };
727
728
729 /**
730  * Key event with given key identifier.
731  */
732 TestSuite.createKeyEvent = function(keyIdentifier)
733 {
734     var evt = document.createEvent("KeyboardEvent");
735     evt.initKeyboardEvent("keydown", true /* can bubble */, true /* can cancel */, null /* view */, keyIdentifier, "");
736     return evt;
737 };
738
739
740 /**
741  * Test runner for the test suite.
742  */
743 var uiTests = {};
744
745
746 /**
747  * Run each test from the test suit on a fresh instance of the suite.
748  */
749 uiTests.runAllTests = function()
750 {
751     // For debugging purposes.
752     for (var name in TestSuite.prototype) {
753         if (name.substring(0, 4) === "test" && typeof TestSuite.prototype[name] === "function")
754             uiTests.runTest(name);
755     }
756 };
757
758
759 /**
760  * Run specified test on a fresh instance of the test suite.
761  * @param {string} name Name of a test method from TestSuite class.
762  */
763 uiTests.runTest = function(name)
764 {
765     if (uiTests._populatedInterface)
766         new TestSuite().runTest(name);
767     else
768         uiTests._pendingTestName = name;
769 };
770
771 (function() {
772
773 function runTests()
774 {
775     uiTests._populatedInterface = true;
776     var name = uiTests._pendingTestName;
777     delete uiTests._pendingTestName;
778     if (name)
779         new TestSuite().runTest(name);
780 }
781
782 var oldShowElementsPanel = WebInspector.showElementsPanel;
783 WebInspector.showElementsPanel = function()
784 {
785     oldShowElementsPanel.call(this);
786     runTests();
787 }
788
789 var oldShowPanel = WebInspector.showPanel;
790 WebInspector.showPanel = function(name)
791 {
792     oldShowPanel.call(this, name);
793     runTests();
794 }
795
796 })();
797
798 }