Chromium Code Reviews| 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 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 45 String id; | 45 String id; |
| 46 | 46 |
| 47 /** Callback that will be executed when the browser has closed */ | 47 /** Callback that will be executed when the browser has closed */ |
| 48 Function onClose; | 48 Function onClose; |
| 49 | 49 |
| 50 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ | 50 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ |
| 51 bool debugPrint = false; | 51 bool debugPrint = false; |
| 52 | 52 |
| 53 // We use this to gracefully handle double calls to close. | 53 // We use this to gracefully handle double calls to close. |
| 54 bool underTermination = false; | 54 bool underTermination = false; |
| 55 | 55 |
| 56 Browser(); | 56 Browser(); |
| 57 | 57 |
| 58 factory Browser.byName(String name) { | 58 factory Browser.byName(String name) { |
| 59 if (name == 'ff' || name == 'firefox') { | 59 if (name == 'ff' || name == 'firefox') { |
| 60 return new Firefox(); | 60 return new Firefox(); |
| 61 } else if (name == 'chrome') { | 61 } else if (name == 'chrome') { |
| 62 return new Chrome(); | 62 return new Chrome(); |
| 63 } else if (name == 'safari') { | 63 } else if (name == 'safari') { |
| 64 return new Safari(); | 64 return new Safari(); |
| 65 } else { | 65 } else { |
| 66 throw "Non supported browser"; | 66 throw "Non supported browser"; |
| 67 } | 67 } |
| 68 } | 68 } |
| 69 | 69 |
| 70 static const List<String> SUPPORTED_BROWSERS = | 70 static const List<String> SUPPORTED_BROWSERS = |
| 71 const ['safari', 'ff', 'firefox', 'chrome']; | |
| 72 | |
| 73 static const List<String> BROWSERS_WITH_WINDOW_SUPPORT = | |
| 71 const ['safari', 'ff', 'firefox', 'chrome']; | 74 const ['safari', 'ff', 'firefox', 'chrome']; |
| 72 | 75 |
| 73 // TODO(kustermann): add standard support for chrome on android | 76 // TODO(kustermann): add standard support for chrome on android |
| 74 static bool supportedBrowser(String name) { | 77 static bool supportedBrowser(String name) { |
| 75 return SUPPORTED_BROWSERS.contains(name); | 78 return SUPPORTED_BROWSERS.contains(name); |
| 76 } | 79 } |
| 77 | 80 |
| 78 void _logEvent(String event) { | 81 void _logEvent(String event) { |
| 79 String toLog = "$this ($id) - ${new DateTime.now()}: $event \n"; | 82 String toLog = "$this ($id) - ${new DateTime.now()}: $event \n"; |
| 80 if (debugPrint) print("usageLog: $toLog"); | 83 if (debugPrint) print("usageLog: $toLog"); |
| (...skipping 444 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 525 // If we do we need to provide developers with this information. | 528 // If we do we need to provide developers with this information. |
| 526 // We don't add urls to the cache until we have run it. | 529 // We don't add urls to the cache until we have run it. |
| 527 Map<int, String> testCache = new Map<int, String>(); | 530 Map<int, String> testCache = new Map<int, String>(); |
| 528 List<int> doubleReportingTests = new List<int>(); | 531 List<int> doubleReportingTests = new List<int>(); |
| 529 | 532 |
| 530 BrowserTestingServer testingServer; | 533 BrowserTestingServer testingServer; |
| 531 | 534 |
| 532 BrowserTestRunner(this.local_ip, this.browserName, this.maxNumBrowsers); | 535 BrowserTestRunner(this.local_ip, this.browserName, this.maxNumBrowsers); |
| 533 | 536 |
| 534 Future<bool> start() { | 537 Future<bool> start() { |
| 535 testingServer = new BrowserTestingServer(local_ip); | 538 // If [browserName] doesn't support opening new windows, we use new iframes |
| 539 // instead. | |
| 540 bool useIframe = !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName) ; | |
|
ricow1
2013/05/30 11:50:20
long line
kustermann
2013/05/30 11:53:12
Done.
| |
| 541 testingServer = new BrowserTestingServer(local_ip, useIframe); | |
| 536 return testingServer.start().then((_) { | 542 return testingServer.start().then((_) { |
| 537 testingServer.testDoneCallBack = handleResults; | 543 testingServer.testDoneCallBack = handleResults; |
| 538 testingServer.nextTestCallBack = getNextTest; | 544 testingServer.nextTestCallBack = getNextTest; |
| 539 return getBrowsers().then((browsers) { | 545 return getBrowsers().then((browsers) { |
| 540 var futures = []; | 546 var futures = []; |
| 541 for (var browser in browsers) { | 547 for (var browser in browsers) { |
| 542 var url = testingServer.getDriverUrl(browser.id); | 548 var url = testingServer.getDriverUrl(browser.id); |
| 543 var future = browser.start(url).then((success) { | 549 var future = browser.start(url).then((success) { |
| 544 if (success) { | 550 if (success) { |
| 545 browserStatus[browser.id] = new BrowserTestingStatus(browser); | 551 browserStatus[browser.id] = new BrowserTestingStatus(browser); |
| (...skipping 208 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 754 | 760 |
| 755 const String driverPath = "/driver"; | 761 const String driverPath = "/driver"; |
| 756 const String nextTestPath = "/next_test"; | 762 const String nextTestPath = "/next_test"; |
| 757 const String reportPath = "/report"; | 763 const String reportPath = "/report"; |
| 758 const String waitSignal = "WAIT"; | 764 const String waitSignal = "WAIT"; |
| 759 const String terminateSignal = "TERMINATE"; | 765 const String terminateSignal = "TERMINATE"; |
| 760 | 766 |
| 761 var testCount = 0; | 767 var testCount = 0; |
| 762 var httpServer; | 768 var httpServer; |
| 763 bool underTermination = false; | 769 bool underTermination = false; |
| 770 bool useIframe = false; | |
| 764 | 771 |
| 765 Function testDoneCallBack; | 772 Function testDoneCallBack; |
| 766 Function nextTestCallBack; | 773 Function nextTestCallBack; |
| 767 | 774 |
| 768 BrowserTestingServer(this.local_ip); | 775 BrowserTestingServer(this.local_ip, this.useIframe); |
| 769 | 776 |
| 770 Future start() { | 777 Future start() { |
| 771 return HttpServer.bind(local_ip, 0).then((createdServer) { | 778 return HttpServer.bind(local_ip, 0).then((createdServer) { |
| 772 httpServer = createdServer; | 779 httpServer = createdServer; |
| 773 void handler(HttpRequest request) { | 780 void handler(HttpRequest request) { |
| 774 if (request.uri.path.startsWith(reportPath)) { | 781 if (request.uri.path.startsWith(reportPath)) { |
| 775 var browserId = request.uri.path.substring(reportPath.length + 1); | 782 var browserId = request.uri.path.substring(reportPath.length + 1); |
| 776 var testId = int.parse(request.queryParameters["id"].split("=")[1]); | 783 var testId = int.parse(request.queryParameters["id"].split("=")[1]); |
| 777 | 784 |
| 778 handleReport(request, browserId, testId); | 785 handleReport(request, browserId, testId); |
| (...skipping 64 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 843 return "http://$local_ip:${httpServer.port}/driver/$browserId"; | 850 return "http://$local_ip:${httpServer.port}/driver/$browserId"; |
| 844 } | 851 } |
| 845 | 852 |
| 846 | 853 |
| 847 String getDriverPage(String browserId) { | 854 String getDriverPage(String browserId) { |
| 848 String driverContent = """ | 855 String driverContent = """ |
| 849 <!DOCTYPE html><html> | 856 <!DOCTYPE html><html> |
| 850 <head> | 857 <head> |
| 851 <title>Driving page</title> | 858 <title>Driving page</title> |
| 852 <script type='text/javascript'> | 859 <script type='text/javascript'> |
| 853 var number_of_tests = 0; | |
| 854 var current_id; | |
| 855 var last_reported_id; | |
| 856 var testing_window; | |
| 857 // We use this to determine if we did actually get back a start event | |
| 858 // from the test we just loaded. | |
| 859 var did_start = false; | |
| 860 | 860 |
| 861 function newTaskHandler() { | 861 function startTesting() { |
| 862 if (this.readyState == this.DONE) { | 862 var number_of_tests = 0; |
| 863 if (this.status == 200) { | 863 var current_id; |
| 864 if (this.responseText == '$waitSignal') { | 864 var last_reported_id; |
| 865 setTimeout(getNextTask, 500); | 865 var testing_window; |
| 866 } else if (this.responseText == '$terminateSignal') { | 866 // We use this to determine if we did actually get back a start event |
| 867 // Don't do anything, we will be killed shortly. | 867 // from the test we just loaded. |
| 868 var did_start = false; | |
| 869 | |
| 870 var embedded_iframe = document.getElementById('embedded_iframe'); | |
| 871 var use_iframe = ${useIframe}; | |
| 872 | |
| 873 function newTaskHandler() { | |
| 874 if (this.readyState == this.DONE) { | |
| 875 if (this.status == 200) { | |
| 876 if (this.responseText == '$waitSignal') { | |
| 877 setTimeout(getNextTask, 500); | |
| 878 } else if (this.responseText == '$terminateSignal') { | |
| 879 // Don't do anything, we will be killed shortly. | |
| 880 } else { | |
| 881 // TODO(ricow): Do something more clever here. | |
| 882 if (nextTask != undefined) alert('This is really bad'); | |
| 883 // The task is send to us as: | |
| 884 // URL#ID | |
| 885 var split = this.responseText.split('#'); | |
| 886 var nextTask = split[0]; | |
| 887 current_id = split[1]; | |
| 888 did_start = false; | |
| 889 run(nextTask); | |
| 890 } | |
| 868 } else { | 891 } else { |
| 869 // TODO(ricow): Do something more clever here. | 892 // We are basically in trouble - do something clever. |
| 870 if (nextTask != undefined) alert('This is really bad'); | |
| 871 // The task is send to us as: | |
| 872 // URL#ID | |
| 873 var split = this.responseText.split('#'); | |
| 874 var nextTask = split[0]; | |
| 875 current_id = split[1]; | |
| 876 did_start = false; | |
| 877 run(nextTask); | |
| 878 } | |
| 879 } else { | |
| 880 // We are basically in trouble - do something clever. | |
| 881 } | |
| 882 } | |
| 883 } | |
| 884 | |
| 885 function getNextTask() { | |
| 886 var client = new XMLHttpRequest(); | |
| 887 client.onreadystatechange = newTaskHandler; | |
| 888 client.open('GET', '$nextTestPath/$browserId'); | |
| 889 client.send(); | |
| 890 } | |
| 891 | |
| 892 function run(url) { | |
| 893 number_of_tests++; | |
| 894 document.getElementById('number').innerHTML = number_of_tests; | |
| 895 if (testing_window == undefined) { | |
| 896 testing_window = window.open(url); | |
| 897 } else { | |
| 898 testing_window.location = url; | |
| 899 } | |
| 900 } | |
| 901 | |
| 902 function reportMessage(msg) { | |
| 903 if (msg == 'STARTING') { | |
| 904 did_start = true; | |
| 905 return; | |
| 906 } | |
| 907 var client = new XMLHttpRequest(); | |
| 908 function handleReady() { | |
| 909 if (this.readyState == this.DONE) { | |
| 910 if (last_reported_id != current_id && did_start) { | |
| 911 getNextTask(); | |
| 912 last_reported_id = current_id; | |
| 913 } | 893 } |
| 914 } | 894 } |
| 915 } | 895 } |
| 916 client.onreadystatechange = handleReady; | 896 |
| 917 // If did_start is false it means that we did actually set the url on | 897 function getNextTask() { |
| 918 // the testing_window, but this is a report left in the event loop or | 898 var client = new XMLHttpRequest(); |
| 919 // a callback because the page did not load yet. | 899 client.onreadystatechange = newTaskHandler; |
| 920 // In both cases this is a double report from the last test. | 900 client.open('GET', '$nextTestPath/$browserId'); |
| 921 var posting_id = did_start ? current_id : last_reported_id; | 901 client.send(); |
| 922 client.open('POST', '$reportPath/${browserId}?id=' + posting_id); | 902 } |
| 923 client.setRequestHeader('Content-type', | 903 |
| 924 'application/x-www-form-urlencoded'); | 904 function run(url) { |
| 925 client.send(msg); | 905 number_of_tests++; |
| 926 // TODO(ricow) add error handling to somehow report the fact that | 906 document.getElementById('number').innerHTML = number_of_tests; |
| 927 // we could not send back a result. | 907 if (use_iframe) { |
| 908 embedded_iframe.src = url; | |
| 909 } else { | |
| 910 if (testing_window == undefined) { | |
| 911 testing_window = window.open(url); | |
| 912 } else { | |
| 913 testing_window.location = url; | |
| 914 } | |
| 915 } | |
| 916 } | |
| 917 | |
| 918 function reportMessage(msg) { | |
| 919 if (msg == 'STARTING') { | |
| 920 did_start = true; | |
| 921 return; | |
| 922 } | |
| 923 var client = new XMLHttpRequest(); | |
| 924 function handleReady() { | |
| 925 if (this.readyState == this.DONE) { | |
| 926 if (last_reported_id != current_id && did_start) { | |
| 927 getNextTask(); | |
| 928 last_reported_id = current_id; | |
| 929 } | |
| 930 } | |
| 931 } | |
| 932 client.onreadystatechange = handleReady; | |
| 933 // If did_start is false it means that we did actually set the url on | |
| 934 // the testing_window, but this is a report left in the event loop or | |
| 935 // a callback because the page did not load yet. | |
| 936 // In both cases this is a double report from the last test. | |
| 937 var posting_id = did_start ? current_id : last_reported_id; | |
| 938 client.open('POST', '$reportPath/${browserId}?id=' + posting_id); | |
| 939 client.setRequestHeader('Content-type', | |
| 940 'application/x-www-form-urlencoded'); | |
| 941 client.send(msg); | |
| 942 // TODO(ricow) add error handling to somehow report the fact that | |
| 943 // we could not send back a result. | |
| 944 } | |
| 945 | |
| 946 function messageHandler(e) { | |
| 947 var msg = e.data; | |
| 948 if (typeof msg != 'string') return; | |
| 949 reportMessage(msg); | |
| 950 } | |
| 951 | |
| 952 window.addEventListener('message', messageHandler, false); | |
| 953 waitForDone = false; | |
| 954 | |
| 955 getNextTask(); | |
| 928 } | 956 } |
| 929 | 957 |
| 930 function messageHandler(e) { | |
| 931 var msg = e.data; | |
| 932 if (typeof msg != 'string') return; | |
| 933 reportMessage(msg); | |
| 934 } | |
| 935 | |
| 936 window.addEventListener('message', messageHandler, false); | |
| 937 waitForDone = false; | |
| 938 | |
| 939 getNextTask(); | |
| 940 | |
| 941 </script> | 958 </script> |
| 942 </head> | 959 </head> |
| 943 <body> | 960 <body onload="startTesting()"> |
| 944 Dart test driver, number of tests: <div id="number"></div> | 961 Dart test driver, number of tests: <div id="number"></div> |
| 962 <iframe id="embedded_iframe"></iframe> | |
| 945 </body> | 963 </body> |
| 946 </html> | 964 </html> |
| 947 """; | 965 """; |
| 948 return driverContent; | 966 return driverContent; |
| 949 } | 967 } |
| 950 } | 968 } |
| OLD | NEW |