| 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 688 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 699 | 699 |
| 700 Future<bool> terminate() { | 700 Future<bool> terminate() { |
| 701 var futures = []; | 701 var futures = []; |
| 702 underTermination = true; | 702 underTermination = true; |
| 703 testingServer.underTermination = true; | 703 testingServer.underTermination = true; |
| 704 for (BrowserTestingStatus status in browserStatus.values) { | 704 for (BrowserTestingStatus status in browserStatus.values) { |
| 705 futures.add(status.browser.close()); | 705 futures.add(status.browser.close()); |
| 706 } | 706 } |
| 707 return Future.wait(futures).then((values) { | 707 return Future.wait(futures).then((values) { |
| 708 testingServer.httpServer.close(); | 708 testingServer.httpServer.close(); |
| 709 testingServer.errorReportingServer.close(); |
| 709 printDoubleReportingTests(); | 710 printDoubleReportingTests(); |
| 710 return !values.contains(false); | 711 return !values.contains(false); |
| 711 }); | 712 }); |
| 712 } | 713 } |
| 713 | 714 |
| 714 Browser getInstance() { | 715 Browser getInstance() { |
| 715 var browser = new Browser.byName(browserName); | 716 var browser = new Browser.byName(browserName); |
| 716 browser.logger = logger; | 717 browser.logger = logger; |
| 717 return browser; | 718 return browser; |
| 718 } | 719 } |
| (...skipping 15 matching lines...) Expand all Loading... |
| 734 final String local_ip; | 735 final String local_ip; |
| 735 | 736 |
| 736 const String driverPath = "/driver"; | 737 const String driverPath = "/driver"; |
| 737 const String nextTestPath = "/next_test"; | 738 const String nextTestPath = "/next_test"; |
| 738 const String reportPath = "/report"; | 739 const String reportPath = "/report"; |
| 739 const String waitSignal = "WAIT"; | 740 const String waitSignal = "WAIT"; |
| 740 const String terminateSignal = "TERMINATE"; | 741 const String terminateSignal = "TERMINATE"; |
| 741 | 742 |
| 742 var testCount = 0; | 743 var testCount = 0; |
| 743 var httpServer; | 744 var httpServer; |
| 745 var errorReportingServer; |
| 744 bool underTermination = false; | 746 bool underTermination = false; |
| 745 bool useIframe = false; | 747 bool useIframe = false; |
| 746 | 748 |
| 747 Function testDoneCallBack; | 749 Function testDoneCallBack; |
| 748 Function nextTestCallBack; | 750 Function nextTestCallBack; |
| 749 | 751 |
| 750 BrowserTestingServer(this.local_ip, this.useIframe); | 752 BrowserTestingServer(this.local_ip, this.useIframe); |
| 751 | 753 |
| 752 Future start() { | 754 Future start() { |
| 753 return HttpServer.bind(local_ip, 0).then((createdServer) { | 755 return HttpServer.bind(local_ip, 0).then((createdServer) { |
| (...skipping 24 matching lines...) Expand all Loading... |
| 778 if (!underTermination) { | 780 if (!underTermination) { |
| 779 print("URI ${request.uri}"); | 781 print("URI ${request.uri}"); |
| 780 print("Textresponse $textResponse"); | 782 print("Textresponse $textResponse"); |
| 781 throw "Error returning content to browser: $error"; | 783 throw "Error returning content to browser: $error"; |
| 782 } | 784 } |
| 783 }); | 785 }); |
| 784 } | 786 } |
| 785 void errorHandler(e) { | 787 void errorHandler(e) { |
| 786 if (!underTermination) print("Error occured in httpserver: $e"); | 788 if (!underTermination) print("Error occured in httpserver: $e"); |
| 787 }; | 789 }; |
| 790 |
| 788 httpServer.listen(handler, onError: errorHandler); | 791 httpServer.listen(handler, onError: errorHandler); |
| 789 return true; | 792 |
| 793 // Set up the error reporting server that enables us to send back |
| 794 // errors from the browser. |
| 795 return HttpServer.bind(local_ip, 0).then((createdReportServer) { |
| 796 errorReportingServer = createdReportServer; |
| 797 void errorReportingHandler(HttpRequest request) { |
| 798 StringBuffer buffer = new StringBuffer(); |
| 799 request.transform(new StringDecoder()).listen((data) { |
| 800 buffer.write(data); |
| 801 }, onDone: () { |
| 802 String back = buffer.toString(); |
| 803 request.response.headers.set("Access-Control-Allow-Origin", "*"); |
| 804 |
| 805 request.response.close().then((_) {}, onError: (error) { |
| 806 DebugLogger.error("Error getting error from browser" |
| 807 "on uri ${request.uri.path}"); |
| 808 }); |
| 809 DebugLogger.error("Error from browser on : " |
| 810 "${request.uri.path}, data: $back"); |
| 811 }, onError: (error) { print(error); }); |
| 812 } |
| 813 errorReportingServer.listen(errorReportingHandler, |
| 814 onError: errorHandler); |
| 815 return true; |
| 816 }); |
| 790 }); | 817 }); |
| 791 } | 818 } |
| 792 | 819 |
| 793 void handleReport(HttpRequest request, String browserId, var testId) { | 820 void handleReport(HttpRequest request, String browserId, var testId) { |
| 794 StringBuffer buffer = new StringBuffer(); | 821 StringBuffer buffer = new StringBuffer(); |
| 795 request.transform(new StringDecoder()).listen((data) { | 822 request.transform(new StringDecoder()).listen((data) { |
| 796 buffer.write(data); | 823 buffer.write(data); |
| 797 }, onDone: () { | 824 }, onDone: () { |
| 798 String back = buffer.toString(); | 825 String back = buffer.toString(); |
| 799 request.response.close(); | 826 request.response.close(); |
| (...skipping 20 matching lines...) Expand all Loading... |
| 820 print("Bad browser testing server, you are not started yet. Can't " | 847 print("Bad browser testing server, you are not started yet. Can't " |
| 821 "produce driver url"); | 848 "produce driver url"); |
| 822 exit(1); | 849 exit(1); |
| 823 // This should never happen - exit immediately; | 850 // This should never happen - exit immediately; |
| 824 } | 851 } |
| 825 return "http://$local_ip:${httpServer.port}/driver/$browserId"; | 852 return "http://$local_ip:${httpServer.port}/driver/$browserId"; |
| 826 } | 853 } |
| 827 | 854 |
| 828 | 855 |
| 829 String getDriverPage(String browserId) { | 856 String getDriverPage(String browserId) { |
| 857 var errorReportingUrl = |
| 858 "http://$local_ip:${errorReportingServer.port}/$browserId"; |
| 830 String driverContent = """ | 859 String driverContent = """ |
| 831 <!DOCTYPE html><html> | 860 <!DOCTYPE html><html> |
| 832 <head> | 861 <head> |
| 833 <title>Driving page</title> | 862 <title>Driving page</title> |
| 834 <script type='text/javascript'> | 863 <script type='text/javascript'> |
| 835 | 864 |
| 836 function startTesting() { | 865 function startTesting() { |
| 837 var number_of_tests = 0; | 866 var number_of_tests = 0; |
| 838 var current_id; | 867 var current_id; |
| 839 var last_reported_id; | 868 var last_reported_id; |
| (...skipping 17 matching lines...) Expand all Loading... |
| 857 if (nextTask != undefined) alert('This is really bad'); | 886 if (nextTask != undefined) alert('This is really bad'); |
| 858 // The task is send to us as: | 887 // The task is send to us as: |
| 859 // URL#ID | 888 // URL#ID |
| 860 var split = this.responseText.split('#'); | 889 var split = this.responseText.split('#'); |
| 861 var nextTask = split[0]; | 890 var nextTask = split[0]; |
| 862 current_id = split[1]; | 891 current_id = split[1]; |
| 863 did_start = false; | 892 did_start = false; |
| 864 run(nextTask); | 893 run(nextTask); |
| 865 } | 894 } |
| 866 } else { | 895 } else { |
| 867 // We are basically in trouble - do something clever. | 896 reportError('Could not contact the server and get a new task'); |
| 868 } | 897 } |
| 869 } | 898 } |
| 870 } | 899 } |
| 871 | 900 |
| 872 function getNextTask() { | 901 function getNextTask() { |
| 873 var client = new XMLHttpRequest(); | 902 var client = new XMLHttpRequest(); |
| 874 client.onreadystatechange = newTaskHandler; | 903 client.onreadystatechange = newTaskHandler; |
| 875 client.open('GET', '$nextTestPath/$browserId'); | 904 client.open('GET', '$nextTestPath/$browserId'); |
| 876 client.send(); | 905 client.send(); |
| 877 } | 906 } |
| 878 | 907 |
| 879 function run(url) { | 908 function run(url) { |
| 880 number_of_tests++; | 909 number_of_tests++; |
| 881 document.getElementById('number').innerHTML = number_of_tests; | 910 document.getElementById('number').innerHTML = number_of_tests; |
| 882 if (use_iframe) { | 911 if (use_iframe) { |
| 883 embedded_iframe.src = url; | 912 embedded_iframe.src = url; |
| 884 } else { | 913 } else { |
| 885 if (testing_window == undefined) { | 914 if (testing_window == undefined) { |
| 886 testing_window = window.open(url); | 915 testing_window = window.open(url); |
| 887 } else { | 916 } else { |
| 888 testing_window.location = url; | 917 testing_window.location = url; |
| 889 } | 918 } |
| 890 } | 919 } |
| 891 } | 920 } |
| 892 | 921 |
| 922 window.onerror = function (message, url, lineNumber) { |
| 923 if (url) { |
| 924 reportError(url + ':' + lineNumber + ':' + message); |
| 925 } else { |
| 926 reportError(message); |
| 927 } |
| 928 } |
| 929 |
| 930 function reportError(msg) { |
| 931 var client = new XMLHttpRequest(); |
| 932 function handleReady() { |
| 933 if (this.readyState == this.DONE && this.status != 200) { |
| 934 // We could not report, pop up to notify if running interactively. |
| 935 alert(this.status); |
| 936 } |
| 937 } |
| 938 client.onreadystatechange = handleReady; |
| 939 client.open('POST', '$errorReportingUrl?test=1'); |
| 940 client.setRequestHeader('Content-type', |
| 941 'application/x-www-form-urlencoded'); |
| 942 client.send(msg); |
| 943 } |
| 944 |
| 893 function reportMessage(msg) { | 945 function reportMessage(msg) { |
| 894 if (msg == 'STARTING') { | 946 if (msg == 'STARTING') { |
| 895 did_start = true; | 947 did_start = true; |
| 896 return; | 948 return; |
| 897 } | 949 } |
| 898 var client = new XMLHttpRequest(); | 950 var client = new XMLHttpRequest(); |
| 899 function handleReady() { | 951 function handleReady() { |
| 900 if (this.readyState == this.DONE) { | 952 if (this.readyState == this.DONE) { |
| 901 if (last_reported_id != current_id && did_start) { | 953 if (this.status == 200) { |
| 902 getNextTask(); | 954 if (last_reported_id != current_id && did_start) { |
| 903 last_reported_id = current_id; | 955 getNextTask(); |
| 956 last_reported_id = current_id; |
| 957 } |
| 958 } else { |
| 959 reportError('Error sending result to server'); |
| 904 } | 960 } |
| 905 } | 961 } |
| 906 } | 962 } |
| 907 client.onreadystatechange = handleReady; | 963 client.onreadystatechange = handleReady; |
| 908 // If did_start is false it means that we did actually set the url on | 964 // If did_start is false it means that we did actually set the url on |
| 909 // the testing_window, but this is a report left in the event loop or | 965 // the testing_window, but this is a report left in the event loop or |
| 910 // a callback because the page did not load yet. | 966 // a callback because the page did not load yet. |
| 911 // In both cases this is a double report from the last test. | 967 // In both cases this is a double report from the last test. |
| 912 var posting_id = did_start ? current_id : last_reported_id; | 968 var posting_id = did_start ? current_id : last_reported_id; |
| 913 client.open('POST', '$reportPath/${browserId}?id=' + posting_id); | 969 client.open('POST', '$reportPath/${browserId}?id=' + posting_id); |
| 914 client.setRequestHeader('Content-type', | 970 client.setRequestHeader('Content-type', |
| 915 'application/x-www-form-urlencoded'); | 971 'application/x-www-form-urlencoded'); |
| 916 client.send(msg); | 972 client.send(msg); |
| 917 // TODO(ricow) add error handling to somehow report the fact that | |
| 918 // we could not send back a result. | |
| 919 } | 973 } |
| 920 | 974 |
| 921 function messageHandler(e) { | 975 function messageHandler(e) { |
| 922 var msg = e.data; | 976 var msg = e.data; |
| 923 if (typeof msg != 'string') return; | 977 if (typeof msg != 'string') return; |
| 924 reportMessage(msg); | 978 reportMessage(msg); |
| 925 } | 979 } |
| 926 | 980 |
| 927 window.addEventListener('message', messageHandler, false); | 981 window.addEventListener('message', messageHandler, false); |
| 928 waitForDone = false; | 982 waitForDone = false; |
| 929 | 983 |
| 930 getNextTask(); | 984 getNextTask(); |
| 931 } | 985 } |
| 932 | 986 |
| 933 </script> | 987 </script> |
| 934 </head> | 988 </head> |
| 935 <body onload="startTesting()"> | 989 <body onload="startTesting()"> |
| 936 Dart test driver, number of tests: <div id="number"></div> | 990 Dart test driver, number of tests: <div id="number"></div> |
| 937 <iframe id="embedded_iframe"></iframe> | 991 <iframe id="embedded_iframe"></iframe> |
| 938 </body> | 992 </body> |
| 939 </html> | 993 </html> |
| 940 """; | 994 """; |
| 941 return driverContent; | 995 return driverContent; |
| 942 } | 996 } |
| 943 } | 997 } |
| OLD | NEW |