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:convert" show LineSplitter, UTF8, JSON; | 7 import "dart:convert" show LineSplitter, UTF8, JSON; |
| 8 import "dart:core"; | 8 import "dart:core"; |
| 9 import "dart:io"; | 9 import "dart:io"; |
| 10 import "dart:math" show max, min; | |
| 10 | 11 |
| 11 import 'android.dart'; | 12 import 'android.dart'; |
| 12 import 'http_server.dart'; | 13 import 'http_server.dart'; |
| 13 import 'path.dart'; | 14 import 'path.dart'; |
| 14 import 'utils.dart'; | 15 import 'utils.dart'; |
| 15 | 16 |
| 16 class BrowserOutput { | 17 class BrowserOutput { |
| 17 final StringBuffer stdout = new StringBuffer(); | 18 final StringBuffer stdout = new StringBuffer(); |
| 18 final StringBuffer stderr = new StringBuffer(); | 19 final StringBuffer stderr = new StringBuffer(); |
| 19 final StringBuffer eventLog = new StringBuffer(); | 20 final StringBuffer eventLog = new StringBuffer(); |
| (...skipping 116 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 136 } else { | 137 } else { |
| 137 _logEvent("The process is already dead."); | 138 _logEvent("The process is already dead."); |
| 138 return new Future.value(true); | 139 return new Future.value(true); |
| 139 } | 140 } |
| 140 } | 141 } |
| 141 | 142 |
| 142 /** | 143 /** |
| 143 * Start the browser using the supplied argument. | 144 * Start the browser using the supplied argument. |
| 144 * This sets up the error handling and usage logging. | 145 * This sets up the error handling and usage logging. |
| 145 */ | 146 */ |
| 146 Future<bool> startBrowser(String command, | 147 Future<bool> startBrowserProcess(String command, |
| 147 List<String> arguments, | 148 List<String> arguments, |
| 148 {Map<String,String> environment}) { | 149 {Map<String,String> environment}) { |
| 149 return Process.start(command, arguments, environment: environment) | 150 return Process.start(command, arguments, environment: environment) |
| 150 .then((startedProcess) { | 151 .then((startedProcess) { |
| 151 _logEvent("Started browser using $command ${arguments.join(' ')}"); | 152 _logEvent("Started browser using $command ${arguments.join(' ')}"); |
| 152 process = startedProcess; | 153 process = startedProcess; |
| 153 // Used to notify when exiting, and as a return value on calls to | 154 // Used to notify when exiting, and as a return value on calls to |
| 154 // close(). | 155 // close(). |
| 155 var doneCompleter = new Completer(); | 156 var doneCompleter = new Completer(); |
| 156 done = doneCompleter.future; | 157 done = doneCompleter.future; |
| (...skipping 218 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 375 _logEvent("Could not clear cache"); | 376 _logEvent("Could not clear cache"); |
| 376 return false; | 377 return false; |
| 377 } | 378 } |
| 378 // Get the version and log that. | 379 // Get the version and log that. |
| 379 return getVersion().then((version) { | 380 return getVersion().then((version) { |
| 380 _logEvent("Got version: $version"); | 381 _logEvent("Got version: $version"); |
| 381 return Directory.systemTemp.createTemp().then((userDir) { | 382 return Directory.systemTemp.createTemp().then((userDir) { |
| 382 _cleanup = () { userDir.deleteSync(recursive: true); }; | 383 _cleanup = () { userDir.deleteSync(recursive: true); }; |
| 383 _createLaunchHTML(userDir.path, url); | 384 _createLaunchHTML(userDir.path, url); |
| 384 var args = ["${userDir.path}/launch.html"]; | 385 var args = ["${userDir.path}/launch.html"]; |
| 385 return startBrowser(_binary, args); | 386 return startBrowserProcess(_binary, args); |
| 386 }); | 387 }); |
| 387 }).catchError((error) { | 388 }).catchError((error) { |
| 388 _logEvent("Running $_binary --version failed with $error"); | 389 _logEvent("Running $_binary --version failed with $error"); |
| 389 return false; | 390 return false; |
| 390 }); | 391 }); |
| 391 }); | 392 }); |
| 392 }); | 393 }); |
| 393 } | 394 } |
| 394 | 395 |
| 395 String toString() => "Safari"; | 396 String toString() => "Safari"; |
| (...skipping 39 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 435 // Get the version and log that. | 436 // Get the version and log that. |
| 436 return _getVersion().then((success) { | 437 return _getVersion().then((success) { |
| 437 if (!success) return false; | 438 if (!success) return false; |
| 438 _logEvent("Got version: $_version"); | 439 _logEvent("Got version: $_version"); |
| 439 | 440 |
| 440 return Directory.systemTemp.createTemp().then((userDir) { | 441 return Directory.systemTemp.createTemp().then((userDir) { |
| 441 _cleanup = () { userDir.deleteSync(recursive: true); }; | 442 _cleanup = () { userDir.deleteSync(recursive: true); }; |
| 442 var args = ["--user-data-dir=${userDir.path}", url, | 443 var args = ["--user-data-dir=${userDir.path}", url, |
| 443 "--disable-extensions", "--disable-popup-blocking", | 444 "--disable-extensions", "--disable-popup-blocking", |
| 444 "--bwsi", "--no-first-run"]; | 445 "--bwsi", "--no-first-run"]; |
| 445 return startBrowser(_binary, args, environment: _getEnvironment()); | 446 return startBrowserProcess(_binary, args, environment: _getEnvironment() ); |
| 446 }); | 447 }); |
| 447 }).catchError((e) { | 448 }).catchError((e) { |
| 448 _logEvent("Running $_binary --version failed with $e"); | 449 _logEvent("Running $_binary --version failed with $e"); |
| 449 return false; | 450 return false; |
| 450 }); | 451 }); |
| 451 } | 452 } |
| 452 | 453 |
| 453 String toString() => "Chrome"; | 454 String toString() => "Chrome"; |
| 454 } | 455 } |
| 455 | 456 |
| (...skipping 21 matching lines...) Expand all Loading... | |
| 477 if (!success) { | 478 if (!success) { |
| 478 _logEvent("Could not clear cache, exiting"); | 479 _logEvent("Could not clear cache, exiting"); |
| 479 return false; | 480 return false; |
| 480 } | 481 } |
| 481 var args = ["-SimulateApplication", | 482 var args = ["-SimulateApplication", |
| 482 "/Applications/Xcode.app/Contents/Developer/Platforms/" | 483 "/Applications/Xcode.app/Contents/Developer/Platforms/" |
| 483 "iPhoneSimulator.platform/Developer/SDKs/" | 484 "iPhoneSimulator.platform/Developer/SDKs/" |
| 484 "iPhoneSimulator7.1.sdk/Applications/MobileSafari.app/" | 485 "iPhoneSimulator7.1.sdk/Applications/MobileSafari.app/" |
| 485 "MobileSafari", | 486 "MobileSafari", |
| 486 "-u", url]; | 487 "-u", url]; |
| 487 return startBrowser(_binary, args) | 488 return startBrowserProcess(_binary, args) |
| 488 .catchError((e) { | 489 .catchError((e) { |
| 489 _logEvent("Running $_binary --version failed with $e"); | 490 _logEvent("Running $_binary --version failed with $e"); |
| 490 return false; | 491 return false; |
| 491 }); | 492 }); |
| 492 }); | 493 }); |
| 493 } | 494 } |
| 494 | 495 |
| 495 String toString() => "SafariMobileSimulator"; | 496 String toString() => "SafariMobileSimulator"; |
| 496 } | 497 } |
| 497 | 498 |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 549 .catchError((error) { | 550 .catchError((error) { |
| 550 _logEvent("Deleting recovery dir failed with $error"); | 551 _logEvent("Deleting recovery dir failed with $error"); |
| 551 return false; | 552 return false; |
| 552 }); | 553 }); |
| 553 } | 554 } |
| 554 | 555 |
| 555 Future<bool> start(String url) { | 556 Future<bool> start(String url) { |
| 556 _logEvent("Starting ie browser on: $url"); | 557 _logEvent("Starting ie browser on: $url"); |
| 557 return clearCache().then((_) => getVersion()).then((version) { | 558 return clearCache().then((_) => getVersion()).then((version) { |
| 558 _logEvent("Got version: $version"); | 559 _logEvent("Got version: $version"); |
| 559 return startBrowser(_binary, [url]); | 560 return startBrowserProcess(_binary, [url]); |
| 560 }); | 561 }); |
| 561 } | 562 } |
| 562 String toString() => "IE"; | 563 String toString() => "IE"; |
| 563 | 564 |
| 564 } | 565 } |
| 565 | 566 |
| 566 | 567 |
| 567 class AndroidBrowserConfig { | 568 class AndroidBrowserConfig { |
| 568 final String name; | 569 final String name; |
| 569 final String package; | 570 final String package; |
| (...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 639 | 640 |
| 640 | 641 |
| 641 class AndroidChrome extends Browser { | 642 class AndroidChrome extends Browser { |
| 642 static const String viewAction = 'android.intent.action.VIEW'; | 643 static const String viewAction = 'android.intent.action.VIEW'; |
| 643 static const String mainAction = 'android.intent.action.MAIN'; | 644 static const String mainAction = 'android.intent.action.MAIN'; |
| 644 static const String chromePackage = 'com.android.chrome'; | 645 static const String chromePackage = 'com.android.chrome'; |
| 645 static const String browserPackage = 'com.android.browser'; | 646 static const String browserPackage = 'com.android.browser'; |
| 646 static const String firefoxPackage = 'org.mozilla.firefox'; | 647 static const String firefoxPackage = 'org.mozilla.firefox'; |
| 647 static const String turnScreenOnPackage = 'com.google.dart.turnscreenon'; | 648 static const String turnScreenOnPackage = 'com.google.dart.turnscreenon'; |
| 648 | 649 |
| 649 AndroidEmulator _emulator; | |
| 650 AdbDevice _adbDevice; | 650 AdbDevice _adbDevice; |
| 651 | 651 |
| 652 AndroidChrome(this._adbDevice); | 652 AndroidChrome(this._adbDevice); |
| 653 | 653 |
| 654 Future<bool> start(String url) { | 654 Future<bool> start(String url) { |
| 655 var browserIntent = new Intent( | 655 var browserIntent = new Intent( |
| 656 viewAction, browserPackage, '.BrowserActivity', url); | 656 viewAction, browserPackage, '.BrowserActivity', url); |
| 657 var chromeIntent = new Intent(viewAction, chromePackage, '.Main', url); | 657 var chromeIntent = new Intent(viewAction, chromePackage, '.Main', url); |
| 658 var firefoxIntent = new Intent(viewAction, firefoxPackage, '.App', url); | 658 var firefoxIntent = new Intent(viewAction, firefoxPackage, '.App', url); |
| 659 var turnScreenOnIntent = | 659 var turnScreenOnIntent = |
| (...skipping 79 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 739 version = versionResult.stdout; | 739 version = versionResult.stdout; |
| 740 _logEvent("Got version: $version"); | 740 _logEvent("Got version: $version"); |
| 741 | 741 |
| 742 return Directory.systemTemp.createTemp().then((userDir) { | 742 return Directory.systemTemp.createTemp().then((userDir) { |
| 743 _createPreferenceFile(userDir.path); | 743 _createPreferenceFile(userDir.path); |
| 744 _cleanup = () { userDir.deleteSync(recursive: true); }; | 744 _cleanup = () { userDir.deleteSync(recursive: true); }; |
| 745 var args = ["-profile", "${userDir.path}", | 745 var args = ["-profile", "${userDir.path}", |
| 746 "-no-remote", "-new-instance", url]; | 746 "-no-remote", "-new-instance", url]; |
| 747 var environment = new Map<String,String>.from(Platform.environment); | 747 var environment = new Map<String,String>.from(Platform.environment); |
| 748 environment["MOZ_CRASHREPORTER_DISABLE"] = "1"; | 748 environment["MOZ_CRASHREPORTER_DISABLE"] = "1"; |
| 749 return startBrowser(_binary, args, environment: environment); | 749 return startBrowserProcess(_binary, args, environment: environment); |
| 750 | 750 |
| 751 }); | 751 }); |
| 752 }).catchError((e) { | 752 }).catchError((e) { |
| 753 _logEvent("Running $_binary --version failed with $e"); | 753 _logEvent("Running $_binary --version failed with $e"); |
| 754 return false; | 754 return false; |
| 755 }); | 755 }); |
| 756 } | 756 } |
| 757 | 757 |
| 758 String toString() => "Firefox"; | 758 String toString() => "Firefox"; |
| 759 } | 759 } |
| 760 | 760 |
| 761 | 761 |
| 762 /** | 762 /** |
| 763 * Describes the current state of a browser used for testing. | 763 * Describes the current state of a browser used for testing. |
| 764 */ | 764 */ |
| 765 class BrowserTestingStatus { | 765 class BrowserStatus { |
| 766 Browser browser; | 766 Browser browser; |
| 767 BrowserTest currentTest; | 767 BrowserTest currentTest; |
| 768 | 768 |
| 769 // This is currently not used for anything except for error reporting. | 769 // This is currently not used for anything except for error reporting. |
| 770 // Given the usefulness of this in debugging issues this should not be | 770 // Given the usefulness of this in debugging issues this should not be |
| 771 // removed even when we have a really stable system. | 771 // removed even when we have a really stable system. |
| 772 BrowserTest lastTest; | 772 BrowserTest lastTest; |
| 773 bool timeout = false; | 773 bool timeout = false; |
| 774 Timer nextTestTimeout; | 774 Timer nextTestTimeout; |
| 775 Stopwatch timeSinceRestart = new Stopwatch(); | 775 Stopwatch timeSinceRestart = new Stopwatch()..start(); |
| 776 | 776 |
| 777 BrowserTestingStatus(Browser this.browser); | 777 BrowserStatus(Browser this.browser); |
| 778 } | 778 } |
| 779 | 779 |
| 780 | 780 |
| 781 /** | 781 /** |
| 782 * Describes a single test to be run in the browser. | 782 * Describes a single test to be run in the browser. |
| 783 */ | 783 */ |
| 784 class BrowserTest { | 784 class BrowserTest { |
| 785 // TODO(ricow): Add timeout callback instead of the string passing hack. | 785 // TODO(ricow): Add timeout callback instead of the string passing hack. |
| 786 Function doneCallback; | 786 Function doneCallback; |
| 787 String url; | 787 String url; |
| (...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 837 final BrowserOutput browserOutput; | 837 final BrowserOutput browserOutput; |
| 838 final bool didTimeout; | 838 final bool didTimeout; |
| 839 | 839 |
| 840 BrowserTestOutput( | 840 BrowserTestOutput( |
| 841 this.delayUntilTestStarted, this.duration, this.lastKnownMessage, | 841 this.delayUntilTestStarted, this.duration, this.lastKnownMessage, |
| 842 this.browserOutput, {this.didTimeout: false}); | 842 this.browserOutput, {this.didTimeout: false}); |
| 843 } | 843 } |
| 844 | 844 |
| 845 /** | 845 /** |
| 846 * Encapsulates all the functionality for running tests in browsers. | 846 * Encapsulates all the functionality for running tests in browsers. |
| 847 * The interface is rather simple. After starting, the runner tests | 847 * The interface is rather simple. After starting, the runner tests |
|
ahe
2016/04/05 16:14:08
Remove "The interface is rather simple."
Bill Hesse
2016/04/07 15:24:10
Done.
Added info about starting browsers and star
| |
| 848 * are simply added to the queue and a the supplied callbacks are called | 848 * are simply added to the queue and a the supplied callbacks are called |
| 849 * whenever a test completes. | 849 * whenever a test completes. |
| 850 */ | 850 */ |
| 851 class BrowserTestRunner { | 851 class BrowserTestRunner { |
| 852 static const int MAX_NEXT_TEST_TIMEOUTS = 10; | 852 static const int MAX_NEXT_TEST_TIMEOUTS = 10; |
| 853 static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 60); | 853 static const Duration NEXT_TEST_TIMEOUT = const Duration(seconds: 60); |
| 854 static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60); | 854 static const Duration RESTART_BROWSER_INTERVAL = const Duration(seconds: 60); |
| 855 | 855 |
| 856 /// If the queue was recently empty, don't start another browser. | |
| 857 static const Duration MIN_NONEMPTY_QUEUE_TIME = const Duration(seconds: 1); | |
| 858 | |
| 856 final Map configuration; | 859 final Map configuration; |
| 860 BrowserTestingServer testingServer; | |
|
ahe
2016/04/05 16:14:07
What is a testingServer?
Bill Hesse
2016/04/07 15:24:10
Added to class documentation.
| |
| 857 | 861 |
| 858 final String localIp; | 862 final String localIp; |
| 859 String browserName; | 863 String browserName; |
| 860 final int maxNumBrowsers; | 864 int maxNumBrowsers; |
| 861 bool checkedMode; | 865 bool checkedMode; |
| 866 int numBrowsers = 0; | |
| 862 // Used to send back logs from the browser (start, stop etc) | 867 // Used to send back logs from the browser (start, stop etc) |
| 863 Function logger; | 868 Function logger; |
| 864 int browserIdCount = 0; | |
| 865 | 869 |
| 870 int browserIdCounter = 1; | |
| 871 | |
| 872 bool testServerStarted = false; | |
|
ahe
2016/04/05 16:14:08
What is a testServer? Is it the same as a testingS
Bill Hesse
2016/04/07 15:24:10
Changed to testingServerStarted.
| |
| 866 bool underTermination = false; | 873 bool underTermination = false; |
| 867 int numBrowserGetTestTimeouts = 0; | 874 int numBrowserGetTestTimeouts = 0; |
| 868 | 875 DateTime lastEmptyTestQueueTime = new DateTime.now(); |
| 876 String _currentStartingBrowserId; | |
| 869 List<BrowserTest> testQueue = new List<BrowserTest>(); | 877 List<BrowserTest> testQueue = new List<BrowserTest>(); |
| 870 Map<String, BrowserTestingStatus> browserStatus = | 878 Map<String, BrowserStatus> browserStatus = |
| 871 new Map<String, BrowserTestingStatus>(); | 879 new Map<String, BrowserStatus>(); |
| 872 | 880 |
| 873 var adbDeviceMapping = new Map<String, AdbDevice>(); | 881 var adbDeviceMapping = new Map<String, AdbDevice>(); |
| 882 List<AdbDevice> idleAdbDevices; | |
| 883 | |
| 874 // This cache is used to guarantee that we never see double reporting. | 884 // This cache is used to guarantee that we never see double reporting. |
| 875 // If we do we need to provide developers with this information. | 885 // If we do we need to provide developers with this information. |
| 876 // We don't add urls to the cache until we have run it. | 886 // We don't add urls to the cache until we have run it. |
| 877 Map<int, String> testCache = new Map<int, String>(); | 887 Map<int, String> testCache = new Map<int, String>(); |
| 888 | |
| 878 Map<int, String> doubleReportingOutputs = new Map<int, String>(); | 889 Map<int, String> doubleReportingOutputs = new Map<int, String>(); |
| 890 List<String> timedOut = []; | |
| 879 | 891 |
| 880 BrowserTestingServer testingServer; | 892 // We will start a new browser when the test queue hasn't been empty |
| 893 // recently, we have fewer than maxNumBrowsers browsers, and there is | |
| 894 // no other browser instance currently starting up. | |
|
ahe
2016/04/05 16:14:08
Let's say that the queue hasn't been empty recentl
Bill Hesse
2016/04/07 15:24:10
No, except that a new browser shouldn't start unti
| |
| 895 bool get queueWasEmptyRecently { | |
| 896 return testQueue.isEmpty || | |
| 897 new DateTime.now().difference(lastEmptyTestQueueTime) < | |
| 898 MIN_NONEMPTY_QUEUE_TIME; | |
| 899 } | |
| 900 | |
| 901 // While a browser is starting, but has not requested its first test, its | |
| 902 // browserId is stored in _currentStartingBrowserId. | |
| 903 // When no browser is currently starting, _currentStartingBrowserId is null. | |
| 904 bool get aBrowserIsCurrentlyStarting => _currentStartingBrowserId != null; | |
| 905 void markCurrentlyStarting(String id) { | |
| 906 _currentStartingBrowserId = id; | |
| 907 } | |
| 908 void markNotCurrentlyStarting(String id) { | |
| 909 if (_currentStartingBrowserId == id) _currentStartingBrowserId = null; | |
| 910 } | |
| 911 | |
| 912 // If [browserName] doesn't support opening new windows, we use new iframes | |
| 913 // instead. | |
| 914 bool get useIframe => | |
| 915 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); | |
| 881 | 916 |
| 882 /** | 917 /** |
| 883 * The TestRunner takes the testingServer in as a constructor parameter in | 918 * The TestRunner takes the testingServer in as a constructor parameter in |
| 884 * case we wish to have a testing server with different behavior (such as the | 919 * case we wish to have a testing server with different behavior (such as the |
| 885 * case for performance testing. | 920 * case for performance testing. Note that the testingServer handlers are |
| 921 * overwritten with handlers for this specific configuration, in that case. | |
|
ahe
2016/04/05 16:14:07
This comment is confusing and not balanced (missin
Bill Hesse
2016/04/07 15:24:10
Rewritten
| |
| 886 */ | 922 */ |
| 887 BrowserTestRunner(this.configuration, | 923 BrowserTestRunner(this.configuration, |
| 888 this.localIp, | 924 this.localIp, |
| 889 this.browserName, | 925 this.browserName, |
| 890 this.maxNumBrowsers, | 926 this.maxNumBrowsers, |
| 891 {BrowserTestingServer this.testingServer}) { | 927 {BrowserTestingServer this.testingServer}) { |
| 892 checkedMode = configuration['checked']; | 928 checkedMode = configuration['checked']; |
| 929 if (browserName == 'ff') browserName = 'firefox'; | |
|
ahe
2016/04/05 16:14:07
This looks like a hack.
Bill Hesse
2016/04/07 15:24:10
It is. I recall that there was a failure if we nor
| |
| 893 } | 930 } |
| 894 | 931 |
| 895 Future<bool> start() { | 932 Future start() async { |
| 896 // If [browserName] doesn't support opening new windows, we use new iframes | |
| 897 // instead. | |
| 898 bool useIframe = | |
| 899 !Browser.BROWSERS_WITH_WINDOW_SUPPORT.contains(browserName); | |
| 900 if (testingServer == null) { | 933 if (testingServer == null) { |
| 901 testingServer = new BrowserTestingServer( | 934 testingServer = new BrowserTestingServer( |
| 902 configuration, localIp, useIframe); | 935 configuration, localIp, useIframe); |
| 903 } | 936 } |
| 904 return testingServer.start().then((_) { | 937 await testingServer.start(); |
| 905 testingServer.testDoneCallBack = handleResults; | 938 testingServer |
| 906 testingServer.testStatusUpdateCallBack = handleStatusUpdate; | 939 ..testDoneCallBack = handleResults |
| 907 testingServer.testStartedCallBack = handleStarted; | 940 ..testStatusUpdateCallBack = handleStatusUpdate |
| 908 testingServer.nextTestCallBack = getNextTest; | 941 ..testStartedCallBack = handleStarted |
| 909 return getBrowsers().then((browsers) { | 942 ..nextTestCallBack = getNextTest; |
|
ahe
2016/04/05 16:14:07
Indent all .. lines by four.
Bill Hesse
2016/04/07 15:24:10
Done. Will be reformatted by the follow-up autofo
| |
| 910 var futures = []; | 943 if (browserName == 'chromeOnAndroid') { |
| 911 for (var browser in browsers) { | 944 var idbNames = await AdbHelper.listDevices(); |
| 912 var url = testingServer.getDriverUrl(browser.id); | 945 idleAdbDevices = new List.from(idbNames.map((id) => new AdbDevice(id))); |
| 913 var future = browser.start(url).then((success) { | 946 maxNumBrowsers = min(maxNumBrowsers, idleAdbDevices.length); |
| 914 if (success) { | 947 } |
| 915 var status = new BrowserTestingStatus(browser); | 948 testServerStarted = true; |
| 916 browserStatus[browser.id] = status; | 949 requestBrowser(); |
| 917 status.nextTestTimeout = createNextTestTimer(status); | |
| 918 status.timeSinceRestart.start(); | |
| 919 } | |
| 920 return success; | |
| 921 }); | |
| 922 futures.add(future); | |
| 923 } | |
| 924 return Future.wait(futures).then((values) { | |
| 925 return !values.contains(false); | |
| 926 }); | |
| 927 }); | |
| 928 }); | |
| 929 } | 950 } |
| 930 | 951 |
| 931 Future<List<Browser>> getBrowsers() { | 952 /// requestBrowser() is called whenever we might want to start an additional |
| 932 // TODO(kustermann): This is a hackisch way to accomplish it and should | 953 /// browser instance. |
| 933 // be encapsulated | 954 /// It is called when starting the BrowserTestRunner, and whenever a browser |
| 934 var browsersCompleter = new Completer(); | 955 /// is killed, whenever a new test is enqueued, or whenever a browser |
| 935 var androidBrowserCreationMapping = { | 956 /// finishes a test. |
| 936 'chromeOnAndroid' : (AdbDevice device) => new AndroidChrome(device), | 957 /// So we are guaranteed that this will always eventually be called, as long |
| 937 'ContentShellOnAndroid' : (AdbDevice device) => new AndroidBrowser( | 958 /// as the test queue isn't empty. |
| 938 device, | 959 void requestBrowser() { |
| 939 contentShellOnAndroidConfig, | 960 if (!testServerStarted) return; |
| 940 checkedMode, | 961 if (underTermination) return; |
| 941 configuration['drt']), | 962 if (numBrowsers == maxNumBrowsers) return; |
| 942 'DartiumOnAndroid' : (AdbDevice device) => new AndroidBrowser( | 963 if (aBrowserIsCurrentlyStarting) return; |
| 943 device, | 964 if (numBrowsers > 0 && queueWasEmptyRecently) return; |
| 944 dartiumOnAndroidConfig, | 965 createBrowser(); |
| 945 checkedMode, | |
| 946 configuration['dartium']), | |
| 947 }; | |
| 948 if (androidBrowserCreationMapping.containsKey(browserName)) { | |
| 949 AdbHelper.listDevices().then((deviceIds) { | |
| 950 if (deviceIds.length > 0) { | |
| 951 var browsers = []; | |
| 952 for (int i = 0; i < deviceIds.length; i++) { | |
| 953 var id = "BROWSER$i"; | |
| 954 var device = new AdbDevice(deviceIds[i]); | |
| 955 adbDeviceMapping[id] = device; | |
| 956 var browser = androidBrowserCreationMapping[browserName](device); | |
| 957 browsers.add(browser); | |
| 958 // We store this in case we need to kill the browser. | |
| 959 browser.id = id; | |
| 960 } | |
| 961 browsersCompleter.complete(browsers); | |
| 962 } else { | |
| 963 throw new StateError("No android devices found."); | |
| 964 } | |
| 965 }); | |
| 966 } else { | |
| 967 var browsers = []; | |
| 968 for (int i = 0; i < maxNumBrowsers; i++) { | |
| 969 var id = "BROWSER$browserIdCount"; | |
| 970 browserIdCount++; | |
| 971 var browser = getInstance(); | |
| 972 browsers.add(browser); | |
| 973 // We store this in case we need to kill the browser. | |
| 974 browser.id = id; | |
| 975 } | |
| 976 browsersCompleter.complete(browsers); | |
| 977 } | |
| 978 return browsersCompleter.future; | |
| 979 } | 966 } |
| 980 | 967 |
| 981 var timedOut = []; | 968 void createBrowser() { |
| 969 final id = "BROWSER$browserIdCounter"; | |
| 970 ++browserIdCounter; | |
|
ahe
2016/04/05 16:14:08
Convert to method:
String getNextBrowserId() => "
| |
| 971 final url = testingServer.getDriverUrl(id); | |
|
ahe
2016/04/05 16:14:08
Is this a String or a Uri? Add type to make it cle
Bill Hesse
2016/04/07 15:24:10
Done.
| |
| 972 Browser browser; | |
| 973 if (browserName == 'chromeOnAndroid') { | |
| 974 AdbDevice device = idleAdbDevices.removeLast(); | |
| 975 adbDeviceMapping[id] = device; | |
| 976 browser = new AndroidChrome(device); | |
| 977 } else { | |
| 978 var path = Locations.getBrowserLocation(browserName, configuration); | |
| 979 browser = new Browser.byName(browserName, path, checkedMode); | |
| 980 browser.logger = logger; | |
| 981 } | |
| 982 browser.id = id; | |
| 983 markCurrentlyStarting(id); | |
| 984 final status = new BrowserStatus(browser); | |
| 985 browserStatus[id] = status; | |
| 986 numBrowsers++; | |
| 987 status.nextTestTimeout = createNextTestTimer(status); | |
| 988 browser.start(url); | |
| 989 } | |
| 982 | 990 |
| 983 void handleResults(String browserId, String output, int testId) { | 991 void handleResults(String browserId, String output, int testId) { |
| 984 var status = browserStatus[browserId]; | 992 var status = browserStatus[browserId]; |
| 985 if (testCache.containsKey(testId)) { | 993 if (testCache.containsKey(testId)) { |
| 986 doubleReportingOutputs[testId] = output; | 994 doubleReportingOutputs[testId] = output; |
| 987 return; | 995 return; |
| 988 } | 996 } |
| 989 | 997 |
| 990 if (status == null || status.timeout) { | 998 if (status == null || status.timeout) { |
| 991 // We don't do anything, this browser is currently being killed and | 999 // We don't do anything, this browser is currently being killed and |
| (...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1043 | 1051 |
| 1044 if (status != null && !status.timeout && status.currentTest != null) { | 1052 if (status != null && !status.timeout && status.currentTest != null) { |
| 1045 status.currentTest.timeoutTimer.cancel(); | 1053 status.currentTest.timeoutTimer.cancel(); |
| 1046 status.currentTest.timeoutTimer = | 1054 status.currentTest.timeoutTimer = |
| 1047 createTimeoutTimer(status.currentTest, status); | 1055 createTimeoutTimer(status.currentTest, status); |
| 1048 status.currentTest.delayUntilTestStarted = | 1056 status.currentTest.delayUntilTestStarted = |
| 1049 status.currentTest.stopwatch.elapsed; | 1057 status.currentTest.stopwatch.elapsed; |
| 1050 } | 1058 } |
| 1051 } | 1059 } |
| 1052 | 1060 |
| 1053 void handleTimeout(BrowserTestingStatus status) { | 1061 void handleTimeout(BrowserStatus status) { |
| 1054 // We simply kill the browser and starts up a new one! | 1062 // We simply kill the browser and starts up a new one! |
| 1055 // We could be smarter here, but it does not seems like it is worth it. | 1063 // We could be smarter here, but it does not seems like it is worth it. |
| 1056 if (status.timeout) { | 1064 if (status.timeout) { |
| 1057 DebugLogger.error( | 1065 DebugLogger.error( |
| 1058 "Got test timeout for an already restarting browser"); | 1066 "Got test timeout for an already restarting browser"); |
| 1059 return; | 1067 return; |
| 1060 } | 1068 } |
| 1061 status.timeout = true; | 1069 status.timeout = true; |
| 1062 timedOut.add(status.currentTest.url); | 1070 timedOut.add(status.currentTest.url); |
| 1063 var id = status.browser.id; | 1071 var id = status.browser.id; |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 1077 status.currentTest.stopwatch.elapsed, | 1085 status.currentTest.stopwatch.elapsed, |
| 1078 lastKnownMessage, | 1086 lastKnownMessage, |
| 1079 status.browser.testBrowserOutput, | 1087 status.browser.testBrowserOutput, |
| 1080 didTimeout: true); | 1088 didTimeout: true); |
| 1081 status.currentTest.doneCallback(browserTestOutput); | 1089 status.currentTest.doneCallback(browserTestOutput); |
| 1082 status.lastTest = status.currentTest; | 1090 status.lastTest = status.currentTest; |
| 1083 status.currentTest = null; | 1091 status.currentTest = null; |
| 1084 | 1092 |
| 1085 // We don't want to start a new browser if we are terminating. | 1093 // We don't want to start a new browser if we are terminating. |
| 1086 if (underTermination) return; | 1094 if (underTermination) return; |
| 1087 restartBrowser(id); | 1095 removeBrowser(id); |
| 1096 requestBrowser(); | |
| 1088 }); | 1097 }); |
| 1089 } | 1098 } |
| 1090 | 1099 |
| 1091 void restartBrowser(String id) { | 1100 /// Remove a browser that has closed from our data structures that track |
| 1092 if (browserName.contains('OnAndroid')) { | 1101 /// open browsers. Check if we want to replace it with a new browser. |
| 1093 DebugLogger.info("Restarting browser $id"); | 1102 void removeBrowser(String id) { |
| 1103 if (browserName == 'chromeOnAndroid') { | |
| 1104 idleAdbDevices.add(adbDeviceMapping.remove(id)); | |
| 1094 } | 1105 } |
| 1095 var browser; | 1106 markNotCurrentlyStarting(id); |
| 1096 var new_id = id; | 1107 browserStatus.remove(id); |
| 1097 if (browserName == 'chromeOnAndroid') { | 1108 --numBrowsers; |
| 1098 browser = new AndroidChrome(adbDeviceMapping[id]); | |
| 1099 } else if (browserName == 'ContentShellOnAndroid') { | |
| 1100 browser = new AndroidBrowser(adbDeviceMapping[id], | |
| 1101 contentShellOnAndroidConfig, | |
| 1102 checkedMode, | |
| 1103 configuration['drt']); | |
| 1104 } else if (browserName == 'DartiumOnAndroid') { | |
| 1105 browser = new AndroidBrowser(adbDeviceMapping[id], | |
| 1106 dartiumOnAndroidConfig, | |
| 1107 checkedMode, | |
| 1108 configuration['dartium']); | |
| 1109 } else { | |
| 1110 browserStatus.remove(id); | |
| 1111 browser = getInstance(); | |
| 1112 new_id = "BROWSER$browserIdCount"; | |
| 1113 browserIdCount++; | |
| 1114 } | |
| 1115 browser.id = new_id; | |
| 1116 var status = new BrowserTestingStatus(browser); | |
| 1117 browserStatus[new_id] = status; | |
| 1118 status.nextTestTimeout = createNextTestTimer(status); | |
| 1119 status.timeSinceRestart.start(); | |
| 1120 browser.start(testingServer.getDriverUrl(new_id)).then((success) { | |
| 1121 // We may have started terminating in the mean time. | |
| 1122 if (underTermination) { | |
| 1123 if (status.nextTestTimeout != null) { | |
| 1124 status.nextTestTimeout.cancel(); | |
| 1125 status.nextTestTimeout = null; | |
| 1126 } | |
| 1127 browser.close().then((success) { | |
| 1128 // We should never hit this, print it out. | |
| 1129 if (!success) { | |
| 1130 print("Could not kill browser ($id) started due to timeout"); | |
| 1131 } | |
| 1132 }); | |
| 1133 return; | |
| 1134 } | |
| 1135 if (!success) { | |
| 1136 // TODO(ricow): Handle this better. | |
| 1137 print("This is bad, should never happen, could not start browser"); | |
| 1138 exit(1); | |
| 1139 } | |
| 1140 }); | |
| 1141 } | 1109 } |
| 1142 | 1110 |
| 1143 BrowserTest getNextTest(String browserId) { | 1111 BrowserTest getNextTest(String browserId) { |
| 1112 markNotCurrentlyStarting(browserId); | |
| 1144 var status = browserStatus[browserId]; | 1113 var status = browserStatus[browserId]; |
| 1145 if (status == null) return null; | 1114 if (status == null) return null; |
| 1146 if (status.nextTestTimeout != null) { | 1115 if (status.nextTestTimeout != null) { |
| 1147 status.nextTestTimeout.cancel(); | 1116 status.nextTestTimeout.cancel(); |
| 1148 status.nextTestTimeout = null; | 1117 status.nextTestTimeout = null; |
| 1149 } | 1118 } |
| 1150 if (testQueue.isEmpty) return null; | 1119 if (testQueue.isEmpty) return null; |
| 1151 | 1120 |
| 1152 // We are currently terminating this browser, don't start a new test. | 1121 // We are currently terminating this browser, don't start a new test. |
| 1153 if (status.timeout) return null; | 1122 if (status.timeout) return null; |
| 1154 | 1123 |
| 1155 // Restart content_shell and dartium on Android if they have been | 1124 // Restart Internet Explorer if it has been |
| 1156 // running for longer than RESTART_BROWSER_INTERVAL. The tests have | 1125 // running for longer than RESTART_BROWSER_INTERVAL. The tests have |
| 1157 // had flaky timeouts, and this may help. | 1126 // had flaky timeouts, and this may help. |
| 1158 if ((browserName == 'ContentShellOnAndroid' || | 1127 if ((browserName == 'ie10' || |
| 1159 browserName == 'DartiumOnAndroid' || | |
| 1160 browserName == 'ie10' || | |
| 1161 browserName == 'ie11') && | 1128 browserName == 'ie11') && |
| 1162 status.timeSinceRestart.elapsed > RESTART_BROWSER_INTERVAL) { | 1129 status.timeSinceRestart.elapsed > RESTART_BROWSER_INTERVAL) { |
| 1163 var id = status.browser.id; | 1130 var id = status.browser.id; |
| 1164 // Reset stopwatch so we don't trigger again before restarting. | 1131 // Reset stopwatch so we don't trigger again before restarting. |
| 1165 status.timeout = true; | 1132 status.timeout = true; |
| 1166 status.browser.close().then((_) { | 1133 status.browser.close().then((_) { |
| 1167 // We don't want to start a new browser if we are terminating. | 1134 // We don't want to start a new browser if we are terminating. |
| 1168 if (underTermination) return; | 1135 if (underTermination) return; |
| 1169 restartBrowser(id); | 1136 removeBrowser(id); |
| 1137 requestBrowser(); | |
| 1170 }); | 1138 }); |
| 1171 // Don't send a test to the browser we are restarting. | 1139 // Don't send a test to the browser we are restarting. |
| 1172 return null; | 1140 return null; |
| 1173 } | 1141 } |
| 1174 | 1142 |
| 1175 BrowserTest test = testQueue.removeLast(); | 1143 BrowserTest test = testQueue.removeLast(); |
|
ahe
2016/04/05 16:14:08
There's an opportunity to create a class that repr
| |
| 1144 // If our queue isn't empty, try starting more browsers | |
| 1145 if (testQueue.isEmpty) { | |
| 1146 lastEmptyTestQueueTime = new DateTime.now(); | |
| 1147 } else { | |
| 1148 requestBrowser(); | |
| 1149 } | |
| 1176 if (status.currentTest == null) { | 1150 if (status.currentTest == null) { |
| 1177 status.currentTest = test; | 1151 status.currentTest = test; |
| 1178 status.currentTest.lastKnownMessage = ''; | 1152 status.currentTest.lastKnownMessage = ''; |
| 1179 } else { | 1153 } else { |
| 1180 // TODO(ricow): Handle this better. | 1154 // TODO(ricow): Handle this better. |
| 1181 print("Browser requested next test before reporting previous result"); | 1155 print("Browser requested next test before reporting previous result"); |
| 1182 print("This happened for browser $browserId"); | 1156 print("This happened for browser $browserId"); |
| 1183 print("Old test was: ${status.currentTest.url}"); | 1157 print("Old test was: ${status.currentTest.url}"); |
| 1184 print("The test before that was: ${status.lastTest.url}"); | 1158 print("The test before that was: ${status.lastTest.url}"); |
| 1185 print("Timed out tests:"); | 1159 print("Timed out tests:"); |
| 1186 for (var v in timedOut) { | 1160 for (var v in timedOut) { |
| 1187 print(" $v"); | 1161 print(" $v"); |
| 1188 } | 1162 } |
| 1189 exit(1); | 1163 exit(1); |
| 1190 } | 1164 } |
| 1191 | 1165 |
| 1192 status.currentTest.timeoutTimer = createTimeoutTimer(test, status); | 1166 status.currentTest.timeoutTimer = createTimeoutTimer(test, status); |
| 1193 status.currentTest.stopwatch = new Stopwatch()..start(); | 1167 status.currentTest.stopwatch = new Stopwatch()..start(); |
| 1194 | 1168 |
| 1195 // Reset the test specific output information (stdout, stderr) on the | 1169 // Reset the test specific output information (stdout, stderr) on the |
| 1196 // browser, since a new test is being started. | 1170 // browser, since a new test is being started. |
| 1197 status.browser.resetTestBrowserOutput(); | 1171 status.browser.resetTestBrowserOutput(); |
| 1198 status.browser.logBrowserInfoToTestBrowserOutput(); | 1172 status.browser.logBrowserInfoToTestBrowserOutput(); |
| 1199 if (browserName.contains('OnAndroid')) { | |
| 1200 DebugLogger.info("Browser $browserId getting test ${test.url}"); | |
| 1201 } | |
| 1202 | |
| 1203 return test; | 1173 return test; |
| 1204 } | 1174 } |
| 1205 | 1175 |
| 1206 Timer createTimeoutTimer(BrowserTest test, BrowserTestingStatus status) { | 1176 /// This creates a timer that is active while a test is running on a browser. |
|
ahe
2016/04/05 16:14:07
Remove "this" which is implied.
Bill Hesse
2016/04/07 15:24:10
Done.
| |
| 1177 Timer createTimeoutTimer(BrowserTest test, BrowserStatus status) { | |
| 1207 return new Timer(new Duration(seconds: test.timeout), | 1178 return new Timer(new Duration(seconds: test.timeout), |
| 1208 () { handleTimeout(status); }); | 1179 () { handleTimeout(status); }); |
| 1209 } | 1180 } |
| 1210 | 1181 |
| 1211 Timer createNextTestTimer(BrowserTestingStatus status) { | 1182 /// This creates a timer that is active while no test is running on the |
|
ahe
2016/04/05 16:14:08
Ditto.
Bill Hesse
2016/04/07 15:24:10
Done.
| |
| 1183 /// browser. It has finished one test, and it has not requested a new test. | |
| 1184 Timer createNextTestTimer(BrowserStatus status) { | |
| 1212 return new Timer(BrowserTestRunner.NEXT_TEST_TIMEOUT, | 1185 return new Timer(BrowserTestRunner.NEXT_TEST_TIMEOUT, |
| 1213 () { handleNextTestTimeout(status); }); | 1186 () { handleNextTestTimeout(status); }); |
| 1214 } | 1187 } |
| 1215 | 1188 |
| 1216 void handleNextTestTimeout(status) { | 1189 void handleNextTestTimeout(status) { |
| 1217 DebugLogger.warning( | 1190 DebugLogger.warning( |
| 1218 "Browser timed out before getting next test. Restarting"); | 1191 "Browser timed out before getting next test. Restarting"); |
| 1219 if (status.timeout) return; | 1192 if (status.timeout) return; |
| 1220 numBrowserGetTestTimeouts++; | 1193 numBrowserGetTestTimeouts++; |
| 1221 if (numBrowserGetTestTimeouts >= MAX_NEXT_TEST_TIMEOUTS) { | 1194 if (numBrowserGetTestTimeouts >= MAX_NEXT_TEST_TIMEOUTS) { |
| 1222 DebugLogger.error( | 1195 DebugLogger.error( |
| 1223 "Too many browser timeouts before getting next test. Terminating"); | 1196 "Too many browser timeouts before getting next test. Terminating"); |
| 1224 terminate().then((_) => exit(1)); | 1197 terminate().then((_) => exit(1)); |
| 1225 } else { | 1198 } else { |
| 1226 status.timeout = true; | 1199 status.timeout = true; |
| 1227 status.browser.close().then((_) => restartBrowser(status.browser.id)); | 1200 status.browser.close().then((_) { |
| 1201 removeBrowser(status.browser.id); | |
| 1202 requestBrowser(); | |
| 1203 }); | |
| 1228 } | 1204 } |
| 1229 } | 1205 } |
| 1230 | 1206 |
| 1231 void queueTest(BrowserTest test) { | 1207 void queueTest(BrowserTest test) { |
|
ahe
2016/04/05 16:14:08
enqueueTest?
Bill Hesse
2016/04/07 15:24:10
Done.
| |
| 1232 testQueue.add(test); | 1208 testQueue.add(test); |
| 1209 requestBrowser(); | |
| 1233 } | 1210 } |
| 1234 | 1211 |
| 1235 void printDoubleReportingTests() { | 1212 void printDoubleReportingTests() { |
| 1236 if (doubleReportingOutputs.length == 0) return; | 1213 if (doubleReportingOutputs.length == 0) return; |
| 1237 // TODO(ricow): die on double reporting. | 1214 // TODO(ricow): die on double reporting. |
| 1238 // Currently we just report this here, we could have a callback to the | 1215 // Currently we just report this here, we could have a callback to the |
| 1239 // encapsulating environment. | 1216 // encapsulating environment. |
| 1240 print(""); | 1217 print(""); |
| 1241 print("Double reporting tests"); | 1218 print("Double reporting tests"); |
| 1242 for (var id in doubleReportingOutputs.keys) { | 1219 for (var id in doubleReportingOutputs.keys) { |
| 1243 print(" ${testCache[id]}"); | 1220 print(" ${testCache[id]}"); |
| 1244 } | 1221 } |
| 1245 | 1222 |
| 1246 DebugLogger.warning("Double reporting tests:"); | 1223 DebugLogger.warning("Double reporting tests:"); |
| 1247 for (var id in doubleReportingOutputs.keys) { | 1224 for (var id in doubleReportingOutputs.keys) { |
| 1248 DebugLogger.warning("${testCache[id]}, output: "); | 1225 DebugLogger.warning("${testCache[id]}, output: "); |
| 1249 DebugLogger.warning("${doubleReportingOutputs[id]}"); | 1226 DebugLogger.warning("${doubleReportingOutputs[id]}"); |
| 1250 DebugLogger.warning(""); | 1227 DebugLogger.warning(""); |
| 1251 DebugLogger.warning(""); | 1228 DebugLogger.warning(""); |
| 1252 } | 1229 } |
| 1253 } | 1230 } |
| 1254 | 1231 |
| 1255 Future<bool> terminate() { | 1232 // TODO(26191): Call a unified fatalError(), that shuts down all subprocesses. |
| 1233 // This just kills the browsers in this BrowserTestRunner instance. | |
| 1234 Future terminate() async { | |
| 1256 var browsers = []; | 1235 var browsers = []; |
| 1257 underTermination = true; | 1236 underTermination = true; |
| 1258 testingServer.underTermination = true; | 1237 testingServer.underTermination = true; |
| 1259 for (BrowserTestingStatus status in browserStatus.values) { | 1238 for (BrowserStatus status in browserStatus.values) { |
| 1260 browsers.add(status.browser); | 1239 browsers.add(status.browser); |
| 1261 if (status.nextTestTimeout != null) { | 1240 if (status.nextTestTimeout != null) { |
| 1262 status.nextTestTimeout.cancel(); | 1241 status.nextTestTimeout.cancel(); |
| 1263 status.nextTestTimeout = null; | 1242 status.nextTestTimeout = null; |
| 1264 } | 1243 } |
| 1265 } | 1244 } |
| 1266 // Success if all the browsers closed successfully. | 1245 for (Browser b in browsers) { |
| 1267 bool success = true; | 1246 await b.close(); |
| 1268 Future closeBrowser(Browser b) { | |
| 1269 return b.close().then((bool closeSucceeded) { | |
| 1270 if (!closeSucceeded) { | |
| 1271 success = false; | |
| 1272 } | |
| 1273 }); | |
| 1274 } | 1247 } |
| 1275 return Future.forEach(browsers, closeBrowser).then((_) { | 1248 testingServer.errorReportingServer.close(); |
| 1276 testingServer.errorReportingServer.close(); | 1249 printDoubleReportingTests(); |
| 1277 printDoubleReportingTests(); | |
| 1278 return success; | |
| 1279 }); | |
| 1280 } | |
| 1281 | |
| 1282 Browser getInstance() { | |
| 1283 if (browserName == 'ff') browserName = 'firefox'; | |
| 1284 var path = Locations.getBrowserLocation(browserName, configuration); | |
| 1285 var browser = new Browser.byName(browserName, path, checkedMode); | |
| 1286 browser.logger = logger; | |
| 1287 return browser; | |
| 1288 } | 1250 } |
| 1289 } | 1251 } |
| 1290 | 1252 |
| 1291 class BrowserTestingServer { | 1253 class BrowserTestingServer { |
| 1292 final Map configuration; | 1254 final Map configuration; |
| 1293 /// Interface of the testing server: | 1255 /// Interface of the testing server: |
| 1294 /// | 1256 /// |
| 1295 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 1257 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| 1296 /// and run tests ... | 1258 /// and run tests ... |
| 1297 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" | 1259 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" |
| (...skipping 498 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1796 </div> | 1758 </div> |
| 1797 <div id="embedded_iframe_div" class="test box"> | 1759 <div id="embedded_iframe_div" class="test box"> |
| 1798 <iframe style="width:100%;height:100%;" id="embedded_iframe"></iframe> | 1760 <iframe style="width:100%;height:100%;" id="embedded_iframe"></iframe> |
| 1799 </div> | 1761 </div> |
| 1800 </body> | 1762 </body> |
| 1801 </html> | 1763 </html> |
| 1802 """; | 1764 """; |
| 1803 return driverContent; | 1765 return driverContent; |
| 1804 } | 1766 } |
| 1805 } | 1767 } |
| OLD | NEW |