Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(10)

Side by Side Diff: tools/testing/dart/browser_controller.dart

Issue 15567002: Added support for running dart2js tests on android devices (Closed) Base URL: https://dart.googlecode.com/svn/branches/bleeding_edge/dart
Patch Set: Created 7 years, 7 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « tools/testing/dart/android.dart ('k') | tools/testing/dart/http_server.dart » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 11
11 /** Class describing the interface for communicating with browsers. */ 12 /** Class describing the interface for communicating with browsers. */
12 class Browser { 13 abstract class Browser {
13 // Browsers actually takes a while to cleanup after itself when closing 14 // Browsers actually takes a while to cleanup after itself when closing
14 // Give it sufficient time to do that. 15 // Give it sufficient time to do that.
15 static final Duration killRepeatInternal = const Duration(seconds: 10); 16 static final Duration killRepeatInternal = const Duration(seconds: 10);
16 static final int killRetries = 5; 17 static final int killRetries = 5;
17 StringBuffer _stdout = new StringBuffer(); 18 StringBuffer _stdout = new StringBuffer();
18 StringBuffer _stderr = new StringBuffer(); 19 StringBuffer _stderr = new StringBuffer();
19 StringBuffer _usageLog = new StringBuffer(); 20 StringBuffer _usageLog = new StringBuffer();
20 // This function is called when the process is closed. 21 // This function is called when the process is closed.
21 // This is extracted to an external function so that we can do additional 22 // This is extracted to an external function so that we can do additional
22 // functionality when the process closes (cleanup and call onExit) 23 // functionality when the process closes (cleanup and call onExit)
(...skipping 131 matching lines...) Expand 10 before | Expand all | Expand 10 after
154 }); 155 });
155 156
156 process.exitCode.then((exitCode) { 157 process.exitCode.then((exitCode) {
157 _logEvent("Browser closed with exitcode $exitCode"); 158 _logEvent("Browser closed with exitcode $exitCode");
158 if (_processClosed != null) _processClosed(); 159 if (_processClosed != null) _processClosed();
159 if (_cleanup != null) _cleanup(); 160 if (_cleanup != null) _cleanup();
160 if (onClose != null) onClose(exitCode); 161 if (onClose != null) onClose(exitCode);
161 }); 162 });
162 return true; 163 return true;
163 }).catchError((error) { 164 }).catchError((error) {
164 _logEvent("Running $binary $arguments failed with $error"); 165 _logEvent("Running $command $arguments failed with $error");
165 return false; 166 return false;
166 }); 167 });
167 } 168 }
168 169
169 /** 170 /**
170 * Get any stdout that the browser wrote during execution. 171 * Get any stdout that the browser wrote during execution.
171 */ 172 */
172 String get stdout => _stdout.toString(); 173 String get stdout => _stdout.toString();
173 String get stderr => _stderr.toString(); 174 String get stderr => _stderr.toString();
174 String get usageLog => _usageLog.toString(); 175 String get usageLog => _usageLog.toString();
175 176
176 String toString(); 177 String toString();
177 /** Starts the browser loading the given url */ 178 /** Starts the browser loading the given url */
178 Future<bool> start(String url); 179 Future<bool> start(String url);
179 } 180 }
180 181
181
182 class Chrome extends Browser { 182 class Chrome extends Browser {
183 /** 183 /**
184 * The binary used to run chrome - changing this can be nececcary for 184 * The binary used to run chrome - changing this can be nececcary for
185 * testing or using non standard chrome installation. 185 * testing or using non standard chrome installation.
186 */ 186 */
187 const String binary = "google-chrome"; 187 const String binary = "google-chrome";
188 188
189 Future<bool> start(String url) { 189 Future<bool> start(String url) {
190 _logEvent("Starting chrome browser on: $url"); 190 _logEvent("Starting chrome browser on: $url");
191 // Get the version and log that. 191 // Get the version and log that.
(...skipping 16 matching lines...) Expand all
208 }); 208 });
209 }).catchError((e) { 209 }).catchError((e) {
210 _logEvent("Running $binary --version failed with $e"); 210 _logEvent("Running $binary --version failed with $e");
211 return false; 211 return false;
212 }); 212 });
213 } 213 }
214 214
215 String toString() => "Chrome"; 215 String toString() => "Chrome";
216 } 216 }
217 217
218 class AndroidChrome extends Browser {
219 const String viewAction = 'android.intent.action.VIEW';
220 const String mainAction = 'android.intent.action.MAIN';
221 const String chromePackage = 'com.android.chrome';
222 const String browserPackage = 'com.android.browser';
223 const String firefoxPackage = 'org.mozilla.firefox';
224 const String turnScreenOnPackage = 'com.google.dart.turnscreenon';
225
226 AndroidEmulator _emulator;
227 AdbDevice _adbDevice;
228
229 AndroidChrome(this._adbDevice);
230
231 Future<bool> start(String url) {
232 var browserIntent = new Intent(
233 viewAction, browserPackage, '.BrowserActivity', url);
234 var chromeIntent = new Intent(viewAction, chromePackage, '.Main', url);
235 var firefoxIntent = new Intent(viewAction, firefoxPackage, '.App', url);
236 var turnScreenOnIntent =
237 new Intent(mainAction, turnScreenOnPackage, '.Main');
238
239 var chromeAPK = new Path(
240 'third_party/android_testing_resources/com.android.chrome-1.apk');
241 var turnScreenOnAPK = new Path(
242 'third_party/android_testing_resources/TurnScreenOn.apk');
243 var chromeConfDir = new Path(
244 'third_party/android_testing_resources/chrome_configuration');
245 var chromeConfDirRemote = new Path(
246 '/data/user/0/com.android.chrome/');
247
248 return _adbDevice.waitForBootCompleted().then((_) {
249 return _adbDevice.forceStop(chromeIntent.package);
250 }).then((_) {
251 return _adbDevice.killAll();
252 }).then((_) {
253 return _adbDevice.adbRoot();
254 }).then((_) {
255 return _adbDevice.installApk(turnScreenOnAPK);
256 }).then((_) {
257 return _adbDevice.installApk(chromeAPK);
258 }).then((_) {
259 return _adbDevice.pushData(chromeConfDir, chromeConfDirRemote);
260 }).then((_) {
261 return _adbDevice.chmod('777', chromeConfDirRemote);
262 }).then((_) {
263 return _adbDevice.startActivity(turnScreenOnIntent).then((_) => true);
264 }).then((_) {
265 return _adbDevice.startActivity(chromeIntent).then((_) => true);
266 });
267 }
268
269 Future<bool> close() {
270 if (_adbDevice != null) {
271 return _adbDevice.forceStop(chromePackage).then((_) {
272 return _adbDevice.killAll().then((_) => true);
273 });
274 }
275 return new Future.immediate(true);
276 }
277
278 String toString() => "chromeOnAndroid";
279 }
280
218 class Firefox extends Browser { 281 class Firefox extends Browser {
219 /** 282 /**
220 * The binary used to run firefox - changing this can be nececcary for 283 * The binary used to run firefox - changing this can be nececcary for
221 * testing or using non standard firefox installation. 284 * testing or using non standard firefox installation.
222 */ 285 */
223 const String binary = "firefox"; 286 const String binary = "firefox";
224 287
225 const String enablePopUp = 288 const String enablePopUp =
226 "user_pref(\"dom.disable_open_during_load\", false);"; 289 "user_pref(\"dom.disable_open_during_load\", false);";
227 290
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
263 } 326 }
264 327
265 328
266 /** 329 /**
267 * Describes the current state of a browser used for testing. 330 * Describes the current state of a browser used for testing.
268 */ 331 */
269 class BrowserTestingStatus { 332 class BrowserTestingStatus {
270 // TODO(ricow): Add prefetching to the browsers. We spend a lot of time waiting 333 // TODO(ricow): Add prefetching to the browsers. We spend a lot of time waiting
271 // for the next test. Handling timeouts is the hard part of this! 334 // for the next test. Handling timeouts is the hard part of this!
272 335
273
274 Browser browser; 336 Browser browser;
275 BrowserTest currentTest; 337 BrowserTest currentTest;
276 // This is currently not used for anything except for error reporting. 338 // This is currently not used for anything except for error reporting.
277 // Given the usefulness of this in debugging issues this should not be 339 // Given the usefulness of this in debugging issues this should not be
278 // removed even when we have really stable system. 340 // removed even when we have really stable system.
279 BrowserTest lastTest; 341 BrowserTest lastTest;
280 bool timeout = false; 342 bool timeout = false;
281 BrowserTestingStatus(Browser this.browser); 343 BrowserTestingStatus(Browser this.browser);
282 } 344 }
283 345
(...skipping 21 matching lines...) Expand all
305 } 367 }
306 368
307 369
308 /** 370 /**
309 * Encapsulates all the functionality for running tests in browsers. 371 * Encapsulates all the functionality for running tests in browsers.
310 * The interface is rather simple. After starting the runner tests 372 * The interface is rather simple. After starting the runner tests
311 * are simply added to the queue and a the supplied callbacks are called 373 * are simply added to the queue and a the supplied callbacks are called
312 * whenever a test completes. 374 * whenever a test completes.
313 */ 375 */
314 class BrowserTestRunner { 376 class BrowserTestRunner {
377 String local_ip;
378 String browserName;
315 int maxNumBrowsers; 379 int maxNumBrowsers;
316 String browserName;
317 380
318 bool underTermination = false; 381 bool underTermination = false;
319 382
320 List<BrowserTest> testQueue = new List<BrowserTest>(); 383 List<BrowserTest> testQueue = new List<BrowserTest>();
321 Map<String, BrowserTestingStatus> browserStatus = 384 Map<String, BrowserTestingStatus> browserStatus =
322 new Map<String, BrowserTestingStatus>(); 385 new Map<String, BrowserTestingStatus>();
386
387 var adbDeviceMapping = new Map<String, AdbDevice>();
323 // This cache is used to guarantee that we never see double reporting. 388 // This cache is used to guarantee that we never see double reporting.
324 // If we do we need to provide developers with this information. 389 // If we do we need to provide developers with this information.
325 // We don't add urls to the cache until we have run it. 390 // We don't add urls to the cache until we have run it.
326 Map<int, String> testCache = new Map<int, String>(); 391 Map<int, String> testCache = new Map<int, String>();
327 List<int> doubleReportingTests = new List<int>(); 392 List<int> doubleReportingTests = new List<int>();
328 393
329 BrowserTestingServer testingServer; 394 BrowserTestingServer testingServer;
330 395
331 BrowserTestRunner(String this.browserName, int this.maxNumBrowsers); 396 BrowserTestRunner(this.local_ip, this.browserName, this.maxNumBrowsers);
332 397
333 Future<bool> start() { 398 Future<bool> start() {
334 testingServer = new BrowserTestingServer(); 399 testingServer = new BrowserTestingServer(local_ip);
335 return testingServer.start().then((_) { 400 return testingServer.start().then((_) {
336 testingServer.testDoneCallBack = handleResults; 401 testingServer.testDoneCallBack = handleResults;
337 testingServer.nextTestCallBack = getNextTest; 402 testingServer.nextTestCallBack = getNextTest;
338 var futures = []; 403 return getBrowsers().then((browsers) {
339 for (int i = 0; i < maxNumBrowsers; i++) { 404 var futures = [];
340 var browser = getInstance(); 405 for (var browser in browsers) {
341 var id = "BROWSER$i"; 406 var url = testingServer.getDriverUrl(browser.id);
342 // We store this in case we need to kill the browser. 407 var future = browser.start(url).then((success) {
343 browser.id = id; 408 if (success) {
344 var future = 409 browserStatus[browser.id] = new BrowserTestingStatus(browser);
345 browser.start(testingServer.getDriverUrl(id)).then((success) { 410 }
346 if (success) { 411 return success;
347 browserStatus[id] = new BrowserTestingStatus(browser); 412 });
348 } 413 futures.add(future);
349 return success; 414 }
350 }); 415 return Future.wait(futures).then((values) {
351 futures.add(future); 416 return !values.contains(false);
352 } 417 });
353 return Future.wait(futures).then((values) {
354 return !values.contains(false);
355 }); 418 });
356 }); 419 });
357 } 420 }
358 421
422 Future<List<Browser>> getBrowsers() {
423 // TODO(kustermann): This is a hackisch way to accomplish it and should
424 // be encapsulated
425 var browsersCompleter = new Completer();
426 if (browserName == 'chromeOnAndroid') {
427 AdbHelper.listDevices().then((deviceIds) {
428 if (deviceIds.length > 0) {
429 var browsers = [];
430 for (int i = 0; i < deviceIds.length; i++) {
431 var id = "BROWSER$i";
432 var device = new AdbDevice(deviceIds[i]);
433 adbDeviceMapping[id] = device;
434 var browser = new AndroidChrome(device);
435 browsers.add(browser);
436 // We store this in case we need to kill the browser.
437 browser.id = id;
438 }
439 browsersCompleter.complete(browsers);
440 } else {
441 throw new StateError("No android devices found.");
442 }
443 });
444 } else {
445 var browsers = [];
446 for (int i = 0; i < maxNumBrowsers; i++) {
447 var id = "BROWSER$i";
448 var browser = getInstance();
449 browsers.add(browser);
450 // We store this in case we need to kill the browser.
451 browser.id = id;
452 }
453 browsersCompleter.complete(browsers);
454 }
455 return browsersCompleter.future;
456 }
457
359 var timedOut = []; 458 var timedOut = [];
360 459
361 void handleResults(String browserId, String output, int testId) { 460 void handleResults(String browserId, String output, int testId) {
362 var status = browserStatus[browserId]; 461 var status = browserStatus[browserId];
363 if (testCache.containsKey(testId)) { 462 if (testCache.containsKey(testId)) {
364 doubleReportingTests.add(testId); 463 doubleReportingTests.add(testId);
365 return; 464 return;
366 } 465 }
367 466
368 if (status.timeout) { 467 if (status.timeout) {
(...skipping 28 matching lines...) Expand all
397 // We could be smarter here, but it does not seems like it is worth it. 496 // We could be smarter here, but it does not seems like it is worth it.
398 status.timeout = true; 497 status.timeout = true;
399 timedOut.add(status.currentTest.url); 498 timedOut.add(status.currentTest.url);
400 var id = status.browser.id; 499 var id = status.browser.id;
401 status.browser.close().then((closed) { 500 status.browser.close().then((closed) {
402 if (!closed) { 501 if (!closed) {
403 // Very bad, we could not kill the browser. 502 // Very bad, we could not kill the browser.
404 print("could not kill browser $id"); 503 print("could not kill browser $id");
405 return; 504 return;
406 } 505 }
407 // Start the new browser first 506 var browser;
408 var browser = getInstance(); 507 if (browserName == 'chromeOnAndroid') {
508 browser = new AndroidChrome(adbDeviceMapping[id]);
509 } else {
510 browser = getInstance();
511 }
409 browser.start(testingServer.getDriverUrl(id)).then((success) { 512 browser.start(testingServer.getDriverUrl(id)).then((success) {
410 // We may have started terminating in the mean time. 513 // We may have started terminating in the mean time.
411 if (underTermination) { 514 if (underTermination) {
412 browser.close().then((success) { 515 browser.close().then((success) {
413 // We should never hit this, print it out. 516 // We should never hit this, print it out.
414 if (!success) { 517 if (!success) {
415 print("Could not kill browser ($id) started due to timeout"); 518 print("Could not kill browser ($id) started due to timeout");
416 } 519 }
417 }); 520 });
418 return; 521 return;
(...skipping 73 matching lines...) Expand 10 before | Expand all | Expand 10 after
492 if (browserName == "chrome") { 595 if (browserName == "chrome") {
493 return new Chrome(); 596 return new Chrome();
494 } else if (browserName == "ff") { 597 } else if (browserName == "ff") {
495 return new Firefox(); 598 return new Firefox();
496 } 599 }
497 throw "Non supported browser for browser controller"; 600 throw "Non supported browser for browser controller";
498 } 601 }
499 } 602 }
500 603
501 class BrowserTestingServer { 604 class BrowserTestingServer {
502 const String server = "127.0.0.1";
503
504 /// Interface of the testing server: 605 /// Interface of the testing server:
505 /// 606 ///
506 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch 607 /// GET /driver/BROWSER_ID -- This will get the driver page to fetch
507 /// and run tests ... 608 /// and run tests ...
508 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id" 609 /// GET /next_test/BROWSER_ID -- returns "WAIT" "TERMINATE" or "url#id"
509 /// where url is the test to run, and id is the id of the test. 610 /// where url is the test to run, and id is the id of the test.
510 /// If there are currently no available tests the waitSignal is send 611 /// If there are currently no available tests the waitSignal is send
511 /// back. If we are in the process of terminating the terminateSignal 612 /// back. If we are in the process of terminating the terminateSignal
512 /// is send back and the browser will stop requesting new tasks. 613 /// is send back and the browser will stop requesting new tasks.
513 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed 614 /// POST /report/BROWSER_ID?id=NUM -- sends back the dom of the executed
514 /// test 615 /// test
515 616
617 final String local_ip;
516 618
517 const String driverPath = "/driver"; 619 const String driverPath = "/driver";
518 const String nextTestPath = "/next_test"; 620 const String nextTestPath = "/next_test";
519 const String reportPath = "/report"; 621 const String reportPath = "/report";
520 const String waitSignal = "WAIT"; 622 const String waitSignal = "WAIT";
521 const String terminateSignal = "TERMINATE"; 623 const String terminateSignal = "TERMINATE";
522 624
523 var testCount = 0; 625 var testCount = 0;
524 var httpServer; 626 var httpServer;
525 bool underTermination = false; 627 bool underTermination = false;
526 628
527 Function testDoneCallBack; 629 Function testDoneCallBack;
528 Function nextTestCallBack; 630 Function nextTestCallBack;
529 631
632 BrowserTestingServer(this.local_ip);
633
530 Future start() { 634 Future start() {
531 return HttpServer.bind(server, 0).then((createdServer) { 635 return HttpServer.bind(local_ip, 0).then((createdServer) {
532 httpServer = createdServer; 636 httpServer = createdServer;
533 void handler(HttpRequest request) { 637 void handler(HttpRequest request) {
534 if (request.uri.path.startsWith(reportPath)) { 638 if (request.uri.path.startsWith(reportPath)) {
535 var browserId = request.uri.path.substring(reportPath.length + 1); 639 var browserId = request.uri.path.substring(reportPath.length + 1);
536 var testId = int.parse(request.queryParameters["id"].split("=")[1]); 640 var testId = int.parse(request.queryParameters["id"].split("=")[1]);
537 641
538 handleReport(request, browserId, testId); 642 handleReport(request, browserId, testId);
539 // handleReport will asynchroniously fetch the data and will handle 643 // handleReport will asynchroniously fetch the data and will handle
540 // the closing of the streams. 644 // the closing of the streams.
541 return; 645 return;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
593 } 697 }
594 } 698 }
595 699
596 String getDriverUrl(String browserId) { 700 String getDriverUrl(String browserId) {
597 if (httpServer == null) { 701 if (httpServer == null) {
598 print("Bad browser testing server, you are not started yet. Can't " 702 print("Bad browser testing server, you are not started yet. Can't "
599 "produce driver url"); 703 "produce driver url");
600 exit(1); 704 exit(1);
601 // This should never happen - exit immediately; 705 // This should never happen - exit immediately;
602 } 706 }
603 return "http://$server:${httpServer.port}/driver/$browserId"; 707 return "http://$local_ip:${httpServer.port}/driver/$browserId";
604 } 708 }
605 709
606 710
607 String getDriverPage(String browserId) { 711 String getDriverPage(String browserId) {
608 String driverContent = """ 712 String driverContent = """
609 <!DOCTYPE html><html> 713 <!DOCTYPE html><html>
610 <head> 714 <head>
611 <title>Driving page</title> 715 <title>Driving page</title>
612 <script type='text/javascript'> 716 <script type='text/javascript'>
613 var number_of_tests = 0; 717 var number_of_tests = 0;
718 var processed_ids = {};
614 var current_id; 719 var current_id;
615 var testing_window; 720 var testing_window;
616 var last_reported_id;
617 721
618 function newTaskHandler() { 722 function newTaskHandler() {
619 if (this.readyState == this.DONE) { 723 if (this.readyState == this.DONE) {
620 if (this.status == 200) { 724 if (this.status == 200) {
621 if (this.responseText == '$waitSignal') { 725 if (this.responseText == '$waitSignal') {
622 setTimeout(getNextTask, 500); 726 setTimeout(getNextTask, 500);
623 } else if (this.responseText == '$terminateSignal') { 727 } else if (this.responseText == '$terminateSignal') {
624 // Don't do anything, we will be killed shortly. 728 // Don't do anything, we will be killed shortly.
625 } else { 729 } else {
626 // TODO(ricow): Do something more clever here. 730 // TODO(ricow): Do something more clever here.
627 if (nextTask != undefined) alert('This is really bad'); 731 if (nextTask != undefined) alert('This is really bad');
628 // The task is send to us as: 732 // The task is send to us as:
629 // URL#ID 733 // URL#ID
630 var split = this.responseText.split('#'); 734 var split = this.responseText.split('#');
631 var nextTask = split[0]; 735 var nextTask = split[0];
632 current_id = split[1]; 736 if (testing_window != undefined) {
633 run(nextTask); 737 testing_window.location = '_blank';
738 }
739 function doAfterEmptyEventLoop() {
740 current_id = split[1];
741 processed_ids[current_id] = 0;
742 run(nextTask);
743 }
744 setTimeout(doAfterEmptyEventLoop(), 0);
634 } 745 }
635 } else { 746 } else {
636 // We are basically in trouble - do something clever. 747 // We are basically in trouble - do something clever.
637 } 748 }
638 } 749 }
639 } 750 }
640 751
641 function getNextTask() { 752 function getNextTask() {
642 var client = new XMLHttpRequest(); 753 var client = new XMLHttpRequest();
643 client.onreadystatechange = newTaskHandler; 754 client.onreadystatechange = newTaskHandler;
644 client.open('GET', '$nextTestPath/$browserId'); 755 client.open('GET', '$nextTestPath/$browserId');
645 client.send(); 756 client.send();
646 } 757 }
647 758
648 function run(url) { 759 function run(url) {
649 number_of_tests++; 760 number_of_tests++;
650 document.getElementById('number').innerHTML = number_of_tests; 761 document.getElementById('number').innerHTML = number_of_tests;
651 if (testing_window == undefined) { 762 if (testing_window == undefined) {
652 testing_window = window.open(url); 763 testing_window = window.open(url);
653 } else { 764 } else {
654 testing_window.location = url; 765 testing_window.location = url;
655 } 766 }
656 } 767 }
657 768
658 function reportMessage(msg) { 769 function reportMessage(msg) {
659 var client = new XMLHttpRequest(); 770 var client = new XMLHttpRequest();
660 function handleReady() { 771 function handleReady() {
661 if (this.readyState == this.DONE) { 772 if (this.readyState == this.DONE) {
662 if (current_id != last_reported_id) { 773 if (processed_ids[current_id] == 0) {
663 getNextTask(); 774 getNextTask();
664 last_reported_id = current_id; 775 processed_ids[current_id] = 1;
665 } 776 }
666 } 777 }
667 } 778 }
668 client.onreadystatechange = handleReady; 779 client.onreadystatechange = handleReady;
669 client.open('POST', '$reportPath/${browserId}?id=' + current_id); 780 client.open('POST', '$reportPath/${browserId}?id=' + current_id);
670 client.setRequestHeader('Content-type', 781 client.setRequestHeader('Content-type',
671 'application/x-www-form-urlencoded'); 782 'application/x-www-form-urlencoded');
672 client.send(msg); 783 client.send(msg);
673 // TODO(ricow) add error handling to somehow report the fact that 784 // TODO(ricow) add error handling to somehow report the fact that
674 // we could not send back a result. 785 // we could not send back a result.
(...skipping 13 matching lines...) Expand all
688 </script> 799 </script>
689 </head> 800 </head>
690 <body> 801 <body>
691 Dart test driver, number of tests: <div id="number"></div> 802 Dart test driver, number of tests: <div id="number"></div>
692 </body> 803 </body>
693 </html> 804 </html>
694 """; 805 """;
695 return driverContent; 806 return driverContent;
696 } 807 }
697 } 808 }
OLDNEW
« no previous file with comments | « tools/testing/dart/android.dart ('k') | tools/testing/dart/http_server.dart » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698