| OLD | NEW |
| 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file | 1 // Copyright (c) 2013, the Dart project authors. Please see the AUTHORS file |
| 2 // for details. All rights reserved. Use of this source code is governed by a | 2 // for details. All rights reserved. Use of this source code is governed by a |
| 3 // BSD-style license that can be found in the LICENSE file. | 3 // BSD-style license that can be found in the LICENSE file. |
| 4 library browser; | 4 library browser; |
| 5 | 5 |
| 6 import "dart:async"; | 6 import "dart:async"; |
| 7 import "dart:core"; | 7 import "dart:core"; |
| 8 import "dart:io"; | 8 import "dart:io"; |
| 9 | 9 |
| 10 import 'android.dart'; | 10 import 'android.dart'; |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 97 _processClosed = () { | 97 _processClosed = () { |
| 98 timer.cancel(); | 98 timer.cancel(); |
| 99 _logEvent("Proccess exited, cancel timer in kill loop"); | 99 _logEvent("Proccess exited, cancel timer in kill loop"); |
| 100 _processClosed = null; | 100 _processClosed = null; |
| 101 process = null; | 101 process = null; |
| 102 completer.complete(true); | 102 completer.complete(true); |
| 103 }; | 103 }; |
| 104 | 104 |
| 105 | 105 |
| 106 _logEvent("calling kill function"); | 106 _logEvent("calling kill function"); |
| 107 if (killFunction()) { | 107 if (process != null && killFunction()) { |
| 108 // We successfully sent the signal. | 108 // We successfully sent the signal. |
| 109 _logEvent("killing signal sent"); | 109 _logEvent("killing signal sent"); |
| 110 } else { | 110 } else { |
| 111 _logEvent("The process is already dead, kill signal could not be send"); | 111 _logEvent("The process is already dead, kill signal could not be send"); |
| 112 completer.complete(true); | 112 completer.complete(true); |
| 113 } | 113 } |
| 114 return completer.future; | 114 return completer.future; |
| 115 } | 115 } |
| 116 | 116 |
| 117 | 117 |
| (...skipping 16 matching lines...) Expand all Loading... |
| 134 * This sets up the error handling and usage logging. | 134 * This sets up the error handling and usage logging. |
| 135 */ | 135 */ |
| 136 Future<bool> startBrowser(String command, List<String> arguments) { | 136 Future<bool> startBrowser(String command, List<String> arguments) { |
| 137 return Process.start(command, arguments).then((startedProcess) { | 137 return Process.start(command, arguments).then((startedProcess) { |
| 138 process = startedProcess; | 138 process = startedProcess; |
| 139 process.stdout.transform(new StringDecoder()).listen((data) { | 139 process.stdout.transform(new StringDecoder()).listen((data) { |
| 140 _addStdout(data); | 140 _addStdout(data); |
| 141 }, onError: (error) { | 141 }, onError: (error) { |
| 142 // This should _never_ happen, but we really want this in the log | 142 // This should _never_ happen, but we really want this in the log |
| 143 // if it actually does due to dart:io or vm bug. | 143 // if it actually does due to dart:io or vm bug. |
| 144 _usageLog.add( | 144 _logEvent("An error occured in the process stdout handling: $error"); |
| 145 "An error occured in the process stdout handling: $error"); | |
| 146 }); | 145 }); |
| 147 | 146 |
| 148 process.stderr.transform(new StringDecoder()).listen((data) { | 147 process.stderr.transform(new StringDecoder()).listen((data) { |
| 149 _addStderr(data); | 148 _addStderr(data); |
| 150 }, onError: (error) { | 149 }, onError: (error) { |
| 151 // This should _never_ happen, but we really want this in the log | 150 // This should _never_ happen, but we really want this in the log |
| 152 // if it actually does due to dart:io or vm bug. | 151 // if it actually does due to dart:io or vm bug. |
| 153 _usageLog.add( | 152 _logEvent("An error occured in the process stderr handling: $error"); |
| 154 "An error occured in the process stderr handling: $error"); | |
| 155 }); | 153 }); |
| 156 | 154 |
| 157 process.exitCode.then((exitCode) { | 155 process.exitCode.then((exitCode) { |
| 158 _logEvent("Browser closed with exitcode $exitCode"); | 156 _logEvent("Browser closed with exitcode $exitCode"); |
| 159 if (_processClosed != null) _processClosed(); | 157 if (_processClosed != null) _processClosed(); |
| 160 if (_cleanup != null) _cleanup(); | 158 if (_cleanup != null) _cleanup(); |
| 161 if (onClose != null) onClose(exitCode); | 159 if (onClose != null) onClose(exitCode); |
| 162 }); | 160 }); |
| 163 return true; | 161 return true; |
| 164 }).catchError((error) { | 162 }).catchError((error) { |
| (...skipping 424 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 589 printDoubleReportingTests(); | 587 printDoubleReportingTests(); |
| 590 return !values.contains(false); | 588 return !values.contains(false); |
| 591 }); | 589 }); |
| 592 } | 590 } |
| 593 | 591 |
| 594 Browser getInstance() { | 592 Browser getInstance() { |
| 595 if (browserName == "chrome") { | 593 if (browserName == "chrome") { |
| 596 return new Chrome(); | 594 return new Chrome(); |
| 597 } else if (browserName == "ff") { | 595 } else if (browserName == "ff") { |
| 598 return new Firefox(); | 596 return new Firefox(); |
| 597 } else { |
| 598 throw "Non supported browser for browser controller"; |
| 599 } | 599 } |
| 600 throw "Non supported browser for browser controller"; | |
| 601 } | 600 } |
| 602 } | 601 } |
| 603 | 602 |
| 604 class BrowserTestingServer { | 603 class BrowserTestingServer { |
| 605 /// Interface of the testing server: | 604 /// Interface of the testing server: |
| 606 /// | 605 /// |
| 607 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 606 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| 608 /// and run tests ... | 607 /// and run tests ... |
| 609 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" | 608 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" |
| 610 /// where url is the test to run, and id is the id of the test. | 609 /// where url is the test to run, and id is the id of the test. |
| (...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 708 } | 707 } |
| 709 | 708 |
| 710 | 709 |
| 711 String getDriverPage(String browserId) { | 710 String getDriverPage(String browserId) { |
| 712 String driverContent = """ | 711 String driverContent = """ |
| 713 <!DOCTYPE html><html> | 712 <!DOCTYPE html><html> |
| 714 <head> | 713 <head> |
| 715 <title>Driving page</title> | 714 <title>Driving page</title> |
| 716 <script type='text/javascript'> | 715 <script type='text/javascript'> |
| 717 var number_of_tests = 0; | 716 var number_of_tests = 0; |
| 718 var processed_ids = {}; | |
| 719 var current_id; | 717 var current_id; |
| 718 var last_reported_id; |
| 720 var testing_window; | 719 var testing_window; |
| 720 // We use this to determine if we did actually get back a start event |
| 721 // from the test we just loaded. |
| 722 var did_start = false; |
| 721 | 723 |
| 722 function newTaskHandler() { | 724 function newTaskHandler() { |
| 723 if (this.readyState == this.DONE) { | 725 if (this.readyState == this.DONE) { |
| 724 if (this.status == 200) { | 726 if (this.status == 200) { |
| 725 if (this.responseText == '$waitSignal') { | 727 if (this.responseText == '$waitSignal') { |
| 726 setTimeout(getNextTask, 500); | 728 setTimeout(getNextTask, 500); |
| 727 } else if (this.responseText == '$terminateSignal') { | 729 } else if (this.responseText == '$terminateSignal') { |
| 728 // Don't do anything, we will be killed shortly. | 730 // Don't do anything, we will be killed shortly. |
| 729 } else { | 731 } else { |
| 730 // TODO(ricow): Do something more clever here. | 732 // TODO(ricow): Do something more clever here. |
| 731 if (nextTask != undefined) alert('This is really bad'); | 733 if (nextTask != undefined) alert('This is really bad'); |
| 732 // The task is send to us as: | 734 // The task is send to us as: |
| 733 // URL#ID | 735 // URL#ID |
| 734 var split = this.responseText.split('#'); | 736 var split = this.responseText.split('#'); |
| 735 var nextTask = split[0]; | 737 var nextTask = split[0]; |
| 736 if (testing_window != undefined) { | 738 current_id = split[1]; |
| 737 testing_window.location = '_blank'; | 739 did_start = false; |
| 738 } | 740 run(nextTask); |
| 739 function doAfterEmptyEventLoop() { | |
| 740 current_id = split[1]; | |
| 741 processed_ids[current_id] = 0; | |
| 742 run(nextTask); | |
| 743 } | |
| 744 setTimeout(doAfterEmptyEventLoop(), 0); | |
| 745 } | 741 } |
| 746 } else { | 742 } else { |
| 747 // We are basically in trouble - do something clever. | 743 // We are basically in trouble - do something clever. |
| 748 } | 744 } |
| 749 } | 745 } |
| 750 } | 746 } |
| 751 | 747 |
| 752 function getNextTask() { | 748 function getNextTask() { |
| 753 var client = new XMLHttpRequest(); | 749 var client = new XMLHttpRequest(); |
| 754 client.onreadystatechange = newTaskHandler; | 750 client.onreadystatechange = newTaskHandler; |
| 755 client.open('GET', '$nextTestPath/$browserId'); | 751 client.open('GET', '$nextTestPath/$browserId'); |
| 756 client.send(); | 752 client.send(); |
| 757 } | 753 } |
| 758 | 754 |
| 759 function run(url) { | 755 function run(url) { |
| 760 number_of_tests++; | 756 number_of_tests++; |
| 761 document.getElementById('number').innerHTML = number_of_tests; | 757 document.getElementById('number').innerHTML = number_of_tests; |
| 762 if (testing_window == undefined) { | 758 if (testing_window == undefined) { |
| 763 testing_window = window.open(url); | 759 testing_window = window.open(url); |
| 764 } else { | 760 } else { |
| 765 testing_window.location = url; | 761 testing_window.location = url; |
| 766 } | 762 } |
| 767 } | 763 } |
| 768 | 764 |
| 769 function reportMessage(msg) { | 765 function reportMessage(msg) { |
| 766 if (msg == 'STARTING') { |
| 767 did_start = true; |
| 768 return; |
| 769 } |
| 770 var client = new XMLHttpRequest(); | 770 var client = new XMLHttpRequest(); |
| 771 function handleReady() { | 771 function handleReady() { |
| 772 if (this.readyState == this.DONE) { | 772 if (this.readyState == this.DONE) { |
| 773 if (processed_ids[current_id] == 0) { | 773 if (last_reported_id != current_id && did_start) { |
| 774 getNextTask(); | 774 getNextTask(); |
| 775 processed_ids[current_id] = 1; | 775 last_reported_id = current_id; |
| 776 } | 776 } |
| 777 } | 777 } |
| 778 } | 778 } |
| 779 client.onreadystatechange = handleReady; | 779 client.onreadystatechange = handleReady; |
| 780 client.open('POST', '$reportPath/${browserId}?id=' + current_id); | 780 // If did_start is false it means that we did actually set the url on |
| 781 // the testing_window, but this is a report left in the event loop or |
| 782 // a callback because the page did not load yet. |
| 783 // In both cases this is a double report from the last test. |
| 784 var posting_id = did_start ? current_id : last_reported_id; |
| 785 client.open('POST', '$reportPath/${browserId}?id=' + posting_id); |
| 781 client.setRequestHeader('Content-type', | 786 client.setRequestHeader('Content-type', |
| 782 'application/x-www-form-urlencoded'); | 787 'application/x-www-form-urlencoded'); |
| 783 client.send(msg); | 788 client.send(msg); |
| 784 // TODO(ricow) add error handling to somehow report the fact that | 789 // TODO(ricow) add error handling to somehow report the fact that |
| 785 // we could not send back a result. | 790 // we could not send back a result. |
| 786 } | 791 } |
| 787 | 792 |
| 788 function messageHandler(e) { | 793 function messageHandler(e) { |
| 789 var msg = e.data; | 794 var msg = e.data; |
| 790 if (typeof msg != 'string') return; | 795 if (typeof msg != 'string') return; |
| 791 reportMessage(msg); | 796 reportMessage(msg); |
| 792 } | 797 } |
| 793 | 798 |
| 794 window.addEventListener('message', messageHandler, false); | 799 window.addEventListener('message', messageHandler, false); |
| 795 waitForDone = false; | 800 waitForDone = false; |
| 796 | 801 |
| 797 getNextTask(); | 802 getNextTask(); |
| 798 | 803 |
| 799 </script> | 804 </script> |
| 800 </head> | 805 </head> |
| 801 <body> | 806 <body> |
| 802 Dart test driver, number of tests: <div id="number"></div> | 807 Dart test driver, number of tests: <div id="number"></div> |
| 803 </body> | 808 </body> |
| 804 </html> | 809 </html> |
| 805 """; | 810 """; |
| 806 return driverContent; | 811 return driverContent; |
| 807 } | 812 } |
| 808 } | 813 } |
| OLD | NEW |