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; | 7 import "dart:convert" show LineSplitter, UTF8; |
| 8 import "dart:core"; | 8 import "dart:core"; |
| 9 import "dart:io"; | 9 import "dart:io"; |
| 10 | 10 |
| (...skipping 13 matching lines...) Expand all Loading... | |
| 24 | 24 |
| 25 // This is called after the process is closed, before the done future | 25 // This is called after the process is closed, before the done future |
| 26 // is completed. | 26 // is completed. |
| 27 // Subclasses can use this to cleanup any browser specific resources | 27 // Subclasses can use this to cleanup any browser specific resources |
| 28 // (temp directories, profiles, etc). The function is expected to do | 28 // (temp directories, profiles, etc). The function is expected to do |
| 29 // it's work synchronously. | 29 // it's work synchronously. |
| 30 Function _cleanup; | 30 Function _cleanup; |
| 31 | 31 |
| 32 /** The version of the browser - normally set when starting a browser */ | 32 /** The version of the browser - normally set when starting a browser */ |
| 33 String version = ""; | 33 String version = ""; |
| 34 | |
| 35 String _binary; | |
| 36 | |
| 37 setBinary(String browserName, Map globalConfiguration) { | |
| 38 _binary = globalConfiguration[browserName]; | |
| 39 if (_binary == null || _binary == '') { | |
| 40 _binary = _getBinary(); | |
| 41 } | |
| 42 } | |
| 43 | |
| 44 String _getBinary(); | |
|
kustermann
2013/11/06 09:33:01
In effect, this method is used for getting the def
| |
| 45 | |
| 34 /** | 46 /** |
| 35 * The underlying process - don't mess directly with this if you don't | 47 * The underlying process - don't mess directly with this if you don't |
| 36 * know what you are doing (this is an interactive process that needs | 48 * know what you are doing (this is an interactive process that needs |
| 37 * special threatment to not leak). | 49 * special threatment to not leak). |
| 38 */ | 50 */ |
| 39 Process process; | 51 Process process; |
| 40 | 52 |
| 41 Function logger; | 53 Function logger; |
| 42 | 54 |
| 43 /** | 55 /** |
| 44 * Id of the browser | 56 * Id of the browser |
| 45 */ | 57 */ |
| 46 String id; | 58 String id; |
| 47 | 59 |
| 48 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ | 60 /** Print everything (stdout, stderr, usageLog) whenever we add to it */ |
| 49 bool debugPrint = false; | 61 bool debugPrint = false; |
| 50 | 62 |
| 51 // This future returns when the process exits. It is also the return value | 63 // This future returns when the process exits. It is also the return value |
| 52 // of close() | 64 // of close() |
| 53 Future done; | 65 Future done; |
| 54 | 66 |
| 55 Browser(); | 67 Browser(); |
| 56 | 68 |
| 57 factory Browser.byName(String name, | 69 factory Browser.byName(String name, |
| 58 [Map globalConfiguration = const {}, | 70 [bool checkedMode = false]) { |
| 59 bool checkedMode = false]) { | 71 if (name == 'firefox') { |
| 60 if (name == 'ff' || name == 'firefox') { | |
| 61 return new Firefox(); | 72 return new Firefox(); |
| 62 } else if (name == 'chrome') { | 73 } else if (name == 'chrome') { |
| 63 return new Chrome(); | 74 return new Chrome(); |
| 64 } else if (name == 'dartium') { | 75 } else if (name == 'dartium') { |
| 65 return new Dartium(globalConfiguration, checkedMode); | 76 return new Dartium(checkedMode); |
| 66 } else if (name == 'safari') { | 77 } else if (name == 'safari') { |
| 67 return new Safari(); | 78 return new Safari(); |
| 68 } else if (name.startsWith('ie')) { | 79 } else if (name.startsWith('ie')) { |
| 69 return new IE(); | 80 return new IE(); |
| 70 } else { | 81 } else { |
| 71 throw "Non supported browser"; | 82 throw "Non supported browser"; |
| 72 } | 83 } |
| 73 } | 84 } |
| 74 | 85 |
| 75 static const List<String> SUPPORTED_BROWSERS = | 86 static const List<String> SUPPORTED_BROWSERS = |
| (...skipping 110 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 186 _testBrowserOutput = new BrowserOutput(); | 197 _testBrowserOutput = new BrowserOutput(); |
| 187 } | 198 } |
| 188 | 199 |
| 189 String toString(); | 200 String toString(); |
| 190 | 201 |
| 191 /** Starts the browser loading the given url */ | 202 /** Starts the browser loading the given url */ |
| 192 Future<bool> start(String url); | 203 Future<bool> start(String url); |
| 193 } | 204 } |
| 194 | 205 |
| 195 class Safari extends Browser { | 206 class Safari extends Browser { |
| 196 /** | 207 String _getBinary() { |
| 197 * The binary used to run safari - changing this can be nececcary for | 208 if (Platform.isMacOS) { |
| 198 * testing or using non standard safari installation. | 209 return "/Applications/Safari.app/Contents/MacOS/Safari"; |
| 199 */ | 210 } else { |
| 200 static const String binary = "/Applications/Safari.app/Contents/MacOS/Safari"; | 211 throw "Safari browser not supported on ${Platform.operatingSystem}"; |
| 212 } | |
| 213 } | |
| 201 | 214 |
| 202 /** | 215 /** |
| 203 * We get the safari version by parsing a version file | 216 * We get the safari version by parsing a version file |
| 204 */ | 217 */ |
| 205 static const String versionFile = | 218 static const String versionFile = |
| 206 "/Applications/Safari.app/Contents/version.plist"; | 219 "/Applications/Safari.app/Contents/version.plist"; |
| 207 | 220 |
| 208 /** | 221 /** |
| 209 * Directories where safari stores state. We delete these if the deleteCache | 222 * Directories where safari stores state. We delete these if the deleteCache |
| 210 * is set | 223 * is set |
| (...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 311 _logEvent("Could not clear cache"); | 324 _logEvent("Could not clear cache"); |
| 312 return false; | 325 return false; |
| 313 } | 326 } |
| 314 // Get the version and log that. | 327 // Get the version and log that. |
| 315 return getVersion().then((version) { | 328 return getVersion().then((version) { |
| 316 _logEvent("Got version: $version"); | 329 _logEvent("Got version: $version"); |
| 317 return new Directory('').createTemp().then((userDir) { | 330 return new Directory('').createTemp().then((userDir) { |
| 318 _cleanup = () { userDir.deleteSync(recursive: true); }; | 331 _cleanup = () { userDir.deleteSync(recursive: true); }; |
| 319 _createLaunchHTML(userDir.path, url); | 332 _createLaunchHTML(userDir.path, url); |
| 320 var args = ["${userDir.path}/launch.html"]; | 333 var args = ["${userDir.path}/launch.html"]; |
| 321 return startBrowser(binary, args); | 334 return startBrowser(_binary, args); |
| 322 }); | 335 }); |
| 323 }).catchError((error) { | 336 }).catchError((error) { |
| 324 _logEvent("Running $binary --version failed with $error"); | 337 _logEvent("Running $_binary --version failed with $error"); |
| 325 return false; | 338 return false; |
| 326 }); | 339 }); |
| 327 }); | 340 }); |
| 328 }); | 341 }); |
| 329 } | 342 } |
| 330 | 343 |
| 331 String toString() => "Safari"; | 344 String toString() => "Safari"; |
| 332 | 345 |
| 333 // Delete the user specific browser cache and profile data. | 346 // Delete the user specific browser cache and profile data. |
| 334 // Safari only have one per user, and you can't specify one by command line. | 347 // Safari only have one per user, and you can't specify one by command line. |
| 335 static bool deleteCache = false; | 348 static bool deleteCache = false; |
| 336 | 349 |
| 337 } | 350 } |
| 338 | 351 |
| 339 | 352 |
| 340 class Chrome extends Browser { | 353 class Chrome extends Browser { |
| 341 String _binary; | |
| 342 String _version = "Version not found yet"; | 354 String _version = "Version not found yet"; |
| 343 | 355 |
| 344 Chrome() { | |
| 345 _binary = _getBinary(); | |
| 346 } | |
| 347 | |
| 348 String _getBinary() { | 356 String _getBinary() { |
| 349 if (Platform.isWindows) { | 357 if (Platform.isWindows) { |
| 350 return "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"; | 358 return "C:\\Program Files (x86)\\Google\\Chrome\\Application\\chrome.exe"; |
| 351 } else if (Platform.isMacOS) { | 359 } else if (Platform.isMacOS) { |
| 352 return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; | 360 return "/Applications/Google Chrome.app/Contents/MacOS/Google Chrome"; |
| 361 } else if (Platform.isLinux) { | |
| 362 return 'google-chrome'; | |
| 363 } else { | |
| 364 throw "Chrome is not supported on ${Platform.operatingSystem}"; | |
| 353 } | 365 } |
| 354 assert(Platform.isLinux); | |
| 355 return 'google-chrome'; | |
| 356 } | 366 } |
| 357 | 367 |
| 358 Map<String, String> _getEnvironment() => null; | 368 Map<String, String> _getEnvironment() => null; |
| 359 | 369 |
| 360 Future<bool> _getVersion() { | 370 Future<bool> _getVersion() { |
| 361 if (Platform.isWindows) { | 371 if (Platform.isWindows) { |
| 362 // The version flag does not work on windows. | 372 // The version flag does not work on windows. |
| 363 // See issue: | 373 // See issue: |
| 364 // https://code.google.com/p/chromium/issues/detail?id=158372 | 374 // https://code.google.com/p/chromium/issues/detail?id=158372 |
| 365 // The registry hack does not seem to work. | 375 // The registry hack does not seem to work. |
| (...skipping 37 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 403 }).catchError((e) { | 413 }).catchError((e) { |
| 404 _logEvent("Running $_binary --version failed with $e"); | 414 _logEvent("Running $_binary --version failed with $e"); |
| 405 return false; | 415 return false; |
| 406 }); | 416 }); |
| 407 } | 417 } |
| 408 | 418 |
| 409 String toString() => "Chrome"; | 419 String toString() => "Chrome"; |
| 410 } | 420 } |
| 411 | 421 |
| 412 class Dartium extends Chrome { | 422 class Dartium extends Chrome { |
| 413 final Map globalConfiguration; | |
| 414 final bool checkedMode; | 423 final bool checkedMode; |
| 415 | 424 |
| 416 Dartium(this.globalConfiguration, this.checkedMode); | 425 Dartium(this.checkedMode); |
| 417 | 426 |
| 418 String _getBinary() { | 427 String _getBinary() { |
| 419 return Locations.getDartiumLocation(globalConfiguration); | 428 if (Platform.operatingSystem == 'macos') { |
| 429 return 'client/tests/dartium/Chromium.app/Contents/MacOS/Chromium'; | |
| 430 } else { | |
| 431 return new Uri.file('client/tests/dartium/chrome').toFilePath(); | |
| 432 } | |
| 420 } | 433 } |
| 421 | 434 |
| 422 Map<String, String> _getEnvironment() { | 435 Map<String, String> _getEnvironment() { |
| 423 var environment = new Map<String,String>.from(Platform.environment); | 436 var environment = new Map<String,String>.from(Platform.environment); |
| 424 // By setting this environment variable, dartium will forward "print()" | 437 // By setting this environment variable, dartium will forward "print()" |
| 425 // calls in dart to the top-level javascript function "dartPrint()" if | 438 // calls in dart to the top-level javascript function "dartPrint()" if |
| 426 // available. | 439 // available. |
| 427 environment['DART_FORWARDING_PRINT'] = '1'; | 440 environment['DART_FORWARDING_PRINT'] = '1'; |
| 428 if (checkedMode) { | 441 if (checkedMode) { |
| 429 environment['DART_FLAGS'] = '--checked'; | 442 environment['DART_FLAGS'] = '--checked'; |
| 430 } | 443 } |
| 431 return environment; | 444 return environment; |
| 432 } | 445 } |
| 433 | 446 |
| 434 String toString() => "Dartium"; | 447 String toString() => "Dartium"; |
| 435 } | 448 } |
| 436 | 449 |
| 437 class IE extends Browser { | 450 class IE extends Browser { |
| 438 | 451 String _getBinary() => "C:\\Program Files\\Internet Explorer\\iexplore.exe"; |
| 439 static const String binary = | |
| 440 "c:\\Program Files\\Internet Explorer\\iexplore.exe"; | |
| 441 | 452 |
| 442 Future<String> getVersion() { | 453 Future<String> getVersion() { |
| 443 var args = ["query", | 454 var args = ["query", |
| 444 "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer", | 455 "HKEY_LOCAL_MACHINE\\Software\\Microsoft\\Internet Explorer", |
| 445 "/v", | 456 "/v", |
| 446 "version"]; | 457 "version"]; |
| 447 return Process.run("reg", args).then((result) { | 458 return Process.run("reg", args).then((result) { |
| 448 if (result.exitCode == 0) { | 459 if (result.exitCode == 0) { |
| 449 // The string we get back looks like this: | 460 // The string we get back looks like this: |
| 450 // HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer | 461 // HKEY_LOCAL_MACHINE\Software\Microsoft\Internet Explorer |
| 451 // version REG_SZ 9.0.8112.16421 | 462 // version REG_SZ 9.0.8112.16421 |
| 452 var findString = "REG_SZ"; | 463 var findString = "REG_SZ"; |
| 453 var index = result.stdout.indexOf(findString); | 464 var index = result.stdout.indexOf(findString); |
| 454 if (index > 0) { | 465 if (index > 0) { |
| 455 return result.stdout.substring(index + findString.length).trim(); | 466 return result.stdout.substring(index + findString.length).trim(); |
| 456 } | 467 } |
| 457 } | 468 } |
| 458 return "Could not get the version of internet explorer"; | 469 return "Could not get the version of internet explorer"; |
| 459 }); | 470 }); |
| 460 } | 471 } |
| 461 | 472 |
| 462 Future<bool> start(String url) { | 473 Future<bool> start(String url) { |
| 463 _logEvent("Starting ie browser on: $url"); | 474 _logEvent("Starting ie browser on: $url"); |
| 464 return getVersion().then((version) { | 475 return getVersion().then((version) { |
| 465 _logEvent("Got version: $version"); | 476 _logEvent("Got version: $version"); |
| 466 return startBrowser(binary, [url]); | 477 return startBrowser(_binary, [url]); |
| 467 }); | 478 }); |
| 468 } | 479 } |
| 469 String toString() => "IE"; | 480 String toString() => "IE"; |
| 470 } | 481 } |
| 471 | 482 |
| 472 | 483 |
| 473 class AndroidBrowserConfig { | 484 class AndroidBrowserConfig { |
| 474 final String name; | 485 final String name; |
| 475 final String package; | 486 final String package; |
| 476 final String activity; | 487 final String activity; |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 603 | 614 |
| 604 | 615 |
| 605 class Firefox extends Browser { | 616 class Firefox extends Browser { |
| 606 static const String enablePopUp = | 617 static const String enablePopUp = |
| 607 'user_pref("dom.disable_open_during_load", false);'; | 618 'user_pref("dom.disable_open_during_load", false);'; |
| 608 static const String disableDefaultCheck = | 619 static const String disableDefaultCheck = |
| 609 'user_pref("browser.shell.checkDefaultBrowser", false);'; | 620 'user_pref("browser.shell.checkDefaultBrowser", false);'; |
| 610 static const String disableScriptTimeLimit = | 621 static const String disableScriptTimeLimit = |
| 611 'user_pref("dom.max_script_run_time", 0);'; | 622 'user_pref("dom.max_script_run_time", 0);'; |
| 612 | 623 |
| 613 static String _binary = _getBinary(); | |
| 614 | |
| 615 Future _createPreferenceFile(var path) { | 624 Future _createPreferenceFile(var path) { |
| 616 var file = new File("${path.toString()}/user.js"); | 625 var file = new File("${path.toString()}/user.js"); |
| 617 var randomFile = file.openSync(mode: FileMode.WRITE); | 626 var randomFile = file.openSync(mode: FileMode.WRITE); |
| 618 randomFile.writeStringSync(enablePopUp); | 627 randomFile.writeStringSync(enablePopUp); |
| 619 randomFile.writeStringSync(disableDefaultCheck); | 628 randomFile.writeStringSync(disableDefaultCheck); |
| 620 randomFile.writeStringSync(disableScriptTimeLimit); | 629 randomFile.writeStringSync(disableScriptTimeLimit); |
| 621 randomFile.close(); | 630 randomFile.close(); |
| 622 } | 631 } |
| 623 | 632 |
| 624 // This is extracted to a function since we may need to support several | 633 String _getBinary() { |
| 625 // locations. | 634 if (Platform.isWindows) { |
| 626 static String _getWindowsBinary() { | 635 return "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"; |
| 627 return "C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"; | 636 } else if (Platform.isLinux) { |
| 628 } | 637 return 'firefox'; |
| 629 | 638 } else if (Platform.isWindows) { |
| 630 static String _getBinary() { | 639 throw 'No path to firefox browser supplied on Windows'; |
| 631 if (Platform.isWindows) return _getWindowsBinary(); | 640 } else { |
| 632 if (Platform.isLinux) return 'firefox'; | 641 throw 'Firefox not supported on ${Platform.operatingSystem}'; |
| 642 } | |
| 633 } | 643 } |
| 634 | 644 |
| 635 Future<bool> start(String url) { | 645 Future<bool> start(String url) { |
| 636 _logEvent("Starting firefox browser on: $url"); | 646 _logEvent("Starting firefox browser on: $url"); |
| 637 // Get the version and log that. | 647 // Get the version and log that. |
| 638 return Process.run(_binary, ["--version"]).then((var versionResult) { | 648 return Process.run(_binary, ["--version"]).then((var versionResult) { |
| 639 if (versionResult.exitCode != 0) { | 649 if (versionResult.exitCode != 0) { |
| 640 _logEvent("Failed to firefox get version"); | 650 _logEvent("Failed to firefox get version"); |
| 641 _logEvent("Make sure $_binary is a valid program for running firefox"); | 651 _logEvent("Make sure $_binary is a valid program for running firefox"); |
| 642 return new Future.value(false); | 652 return new Future.value(false); |
| (...skipping 386 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1029 } | 1039 } |
| 1030 return Future.wait(futures).then((values) { | 1040 return Future.wait(futures).then((values) { |
| 1031 testingServer.httpServer.close(); | 1041 testingServer.httpServer.close(); |
| 1032 testingServer.errorReportingServer.close(); | 1042 testingServer.errorReportingServer.close(); |
| 1033 printDoubleReportingTests(); | 1043 printDoubleReportingTests(); |
| 1034 return !values.contains(false); | 1044 return !values.contains(false); |
| 1035 }); | 1045 }); |
| 1036 } | 1046 } |
| 1037 | 1047 |
| 1038 Browser getInstance() { | 1048 Browser getInstance() { |
| 1039 var browser = | 1049 if (browserName == 'ff') browserName = 'firefox'; |
| 1040 new Browser.byName(browserName, globalConfiguration, checkedMode); | 1050 var browser = new Browser.byName(browserName, checkedMode); |
| 1051 browser.setBinary(browserName, globalConfiguration); | |
|
kustermann
2013/11/06 09:33:01
There's one thing I don't like about this:
If we c
| |
| 1041 browser.logger = logger; | 1052 browser.logger = logger; |
| 1042 return browser; | 1053 return browser; |
| 1043 } | 1054 } |
| 1044 } | 1055 } |
| 1045 | 1056 |
| 1046 class BrowserTestingServer { | 1057 class BrowserTestingServer { |
| 1047 final Map globalConfiguration; | 1058 final Map globalConfiguration; |
| 1048 /// Interface of the testing server: | 1059 /// Interface of the testing server: |
| 1049 /// | 1060 /// |
| 1050 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch | 1061 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch |
| (...skipping 308 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 1359 Dart test driver, number of tests: <div id="number"></div><br> | 1370 Dart test driver, number of tests: <div id="number"></div><br> |
| 1360 Currently executing: <div id="currently_executing"></div><br> | 1371 Currently executing: <div id="currently_executing"></div><br> |
| 1361 Unhandled error: <div id="unhandled_error"></div> | 1372 Unhandled error: <div id="unhandled_error"></div> |
| 1362 <iframe id="embedded_iframe"></iframe> | 1373 <iframe id="embedded_iframe"></iframe> |
| 1363 </body> | 1374 </body> |
| 1364 </html> | 1375 </html> |
| 1365 """; | 1376 """; |
| 1366 return driverContent; | 1377 return driverContent; |
| 1367 } | 1378 } |
| 1368 } | 1379 } |
| OLD | NEW |