selenium-webdriver 3.0.0-beta-1 → 3.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/CHANGES.md +109 -0
  2. package/LICENSE +1 -1
  3. package/README.md +7 -6
  4. package/chrome.js +31 -128
  5. package/edge.js +13 -91
  6. package/example/chrome_android.js +18 -13
  7. package/example/chrome_mobile_emulation.js +19 -15
  8. package/example/google_search.js +11 -11
  9. package/example/google_search_generator.js +23 -18
  10. package/example/google_search_test.js +31 -17
  11. package/example/logging.js +9 -17
  12. package/example/parallel_flows.js +3 -0
  13. package/firefox/binary.js +17 -0
  14. package/firefox/index.js +198 -101
  15. package/firefox/profile.js +24 -3
  16. package/http/util.js +95 -59
  17. package/ie.js +6 -10
  18. package/index.js +636 -2
  19. package/lib/actions.js +18 -10
  20. package/lib/atoms/getAttribute.js +11 -0
  21. package/lib/atoms/isDisplayed.js +106 -0
  22. package/lib/firefox/amd64/libnoblur64.so +0 -0
  23. package/lib/firefox/i386/libnoblur.so +0 -0
  24. package/lib/firefox/webdriver.xpi +0 -0
  25. package/lib/http.js +159 -46
  26. package/lib/logging.js +7 -1
  27. package/lib/promise.js +602 -358
  28. package/lib/proxy.js +28 -0
  29. package/lib/session.js +1 -1
  30. package/lib/test/build.js +26 -28
  31. package/lib/test/data/formPage.html +1 -0
  32. package/lib/test/fileserver.js +12 -10
  33. package/lib/test/httpserver.js +4 -6
  34. package/lib/test/index.js +18 -11
  35. package/lib/test/promise.js +79 -0
  36. package/lib/webdriver.js +587 -479
  37. package/opera.js +12 -88
  38. package/package.json +13 -14
  39. package/phantomjs.js +7 -14
  40. package/remote/index.js +201 -30
  41. package/safari.js +62 -416
  42. package/test/actions_test.js +9 -11
  43. package/test/chrome/options_test.js +8 -8
  44. package/test/chrome/service_test.js +2 -2
  45. package/test/cookie_test.js +57 -57
  46. package/test/element_finding_test.js +201 -185
  47. package/test/execute_script_test.js +108 -111
  48. package/test/fingerprint_test.js +16 -11
  49. package/test/firefox/firefox_test.js +75 -49
  50. package/test/firefox/profile_test.js +1 -3
  51. package/test/http/util_test.js +21 -27
  52. package/test/io_test.js +2 -5
  53. package/test/lib/http_test.js +8 -6
  54. package/test/lib/promise_aplus_test.js +48 -44
  55. package/test/lib/promise_error_test.js +687 -611
  56. package/test/lib/promise_flow_test.js +1810 -1806
  57. package/test/lib/promise_generator_test.js +227 -225
  58. package/test/lib/promise_test.js +864 -835
  59. package/test/lib/until_test.js +1 -1
  60. package/test/lib/webdriver_test.js +520 -424
  61. package/test/logging_test.js +43 -45
  62. package/test/net/portprober_test.js +23 -24
  63. package/test/page_loading_test.js +84 -78
  64. package/test/phantomjs/execute_phantomjs_test.js +11 -25
  65. package/test/proxy_test.js +23 -23
  66. package/test/remote_test.js +22 -22
  67. package/test/safari_test.js +108 -0
  68. package/test/session_test.js +11 -10
  69. package/test/stale_element_test.js +18 -16
  70. package/test/tag_name_test.js +7 -5
  71. package/test/testing/assert_test.js +2 -3
  72. package/test/testing/index_test.js +163 -117
  73. package/test/upload_test.js +13 -13
  74. package/test/window_test.js +94 -70
  75. package/testing/index.js +176 -37
  76. package/builder.js +0 -553
  77. package/lib/safari/client.js +0 -56
@@ -29,6 +29,8 @@ const Key = require('../../lib/input').Key;
29
29
  const logging = require('../../lib/logging');
30
30
  const Session = require('../../lib/session').Session;
31
31
  const promise = require('../../lib/promise');
32
+ const {enablePromiseManager, promiseManagerSuite} = require('../../lib/test/promise');
33
+ const until = require('../../lib/until');
32
34
  const Alert = require('../../lib/webdriver').Alert;
33
35
  const AlertPromise = require('../../lib/webdriver').AlertPromise;
34
36
  const UnhandledAlertError = require('../../lib/webdriver').UnhandledAlertError;
@@ -73,6 +75,9 @@ describe('WebDriver', function() {
73
75
  });
74
76
 
75
77
  afterEach(function tearDown() {
78
+ if (!promise.USE_PROMISE_MANAGER) {
79
+ return;
80
+ }
76
81
  return waitForIdle(flow).then(function() {
77
82
  assert.deepEqual([], uncaughtExceptions);
78
83
  flow.reset();
@@ -83,7 +88,19 @@ describe('WebDriver', function() {
83
88
  uncaughtExceptions.push(e);
84
89
  }
85
90
 
91
+ function defer() {
92
+ let d = {};
93
+ let promise = new Promise((resolve, reject) => {
94
+ Object.assign(d, {resolve, reject});
95
+ });
96
+ d.promise = promise;
97
+ return d;
98
+ }
99
+
86
100
  function waitForIdle(opt_flow) {
101
+ if (!promise.USE_PROMISE_MANAGER) {
102
+ return Promise.resolve();
103
+ }
87
104
  var theFlow = opt_flow || flow;
88
105
  return new Promise(function(fulfill, reject) {
89
106
  if (theFlow.isIdle()) {
@@ -300,19 +317,21 @@ describe('WebDriver', function() {
300
317
  return waitForIdle(driver.controlFlow());
301
318
  });
302
319
 
303
- it('canAttachInCustomFlow', function() {
304
- let executor = new FakeExecutor().
305
- expect(CName.DESCRIBE_SESSION).
306
- withParameters({'sessionId': SESSION_ID}).
307
- andReturnSuccess({}).
308
- end();
320
+ enablePromiseManager(() => {
321
+ it('canAttachInCustomFlow', function() {
322
+ let executor = new FakeExecutor().
323
+ expect(CName.DESCRIBE_SESSION).
324
+ withParameters({'sessionId': SESSION_ID}).
325
+ andReturnSuccess({}).
326
+ end();
309
327
 
310
- var otherFlow = new promise.ControlFlow();
311
- var driver = WebDriver.attachToSession(executor, SESSION_ID, otherFlow);
312
- assert.equal(otherFlow, driver.controlFlow());
313
- assert.notEqual(otherFlow, promise.controlFlow());
328
+ var otherFlow = new promise.ControlFlow();
329
+ var driver = WebDriver.attachToSession(executor, SESSION_ID, otherFlow);
330
+ assert.equal(otherFlow, driver.controlFlow());
331
+ assert.notEqual(otherFlow, promise.controlFlow());
314
332
 
315
- return waitForIdle(otherFlow);
333
+ return waitForIdle(otherFlow);
334
+ });
316
335
  });
317
336
  });
318
337
 
@@ -345,7 +364,7 @@ describe('WebDriver', function() {
345
364
  return driver.getSession().then(v => assert.strictEqual(v, aSession));
346
365
  });
347
366
 
348
- it('handles desired and requried capabilities', function() {
367
+ it('handles desired and required capabilities', function() {
349
368
  let aSession = new Session(SESSION_ID, {'browserName': 'firefox'});
350
369
  let executor = new FakeExecutor().
351
370
  expect(CName.NEW_SESSION).
@@ -374,6 +393,23 @@ describe('WebDriver', function() {
374
393
  return driver.getSession().then(fail, assertIsStubError);
375
394
  });
376
395
 
396
+ it('invokes quit callback if it fails to create a session', function() {
397
+ let called = false;
398
+ let executor = new FakeExecutor()
399
+ .expect(CName.NEW_SESSION)
400
+ .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
401
+ .andReturnError(new StubError())
402
+ .end();
403
+
404
+ var driver =
405
+ WebDriver.createSession(executor, {'browserName': 'firefox'},
406
+ null, null, () => called = true);
407
+ return driver.getSession().then(fail, err => {
408
+ assert.ok(called);
409
+ assertIsStubError(err);
410
+ });
411
+ });
412
+
377
413
  it('usesActiveFlowByDefault', function() {
378
414
  let executor = new FakeExecutor().
379
415
  expect(CName.NEW_SESSION).
@@ -387,26 +423,60 @@ describe('WebDriver', function() {
387
423
  return waitForIdle(driver.controlFlow());
388
424
  });
389
425
 
390
- it('canCreateInCustomFlow', function() {
391
- let executor = new FakeExecutor().
392
- expect(CName.NEW_SESSION).
393
- withParameters({'desiredCapabilities': {}}).
394
- andReturnSuccess({}).
395
- end();
426
+ enablePromiseManager(() => {
427
+ it('canCreateInCustomFlow', function() {
428
+ let executor = new FakeExecutor().
429
+ expect(CName.NEW_SESSION).
430
+ withParameters({'desiredCapabilities': {}}).
431
+ andReturnSuccess({}).
432
+ end();
396
433
 
397
- var otherFlow = new promise.ControlFlow();
398
- var driver = WebDriver.createSession(executor, {}, otherFlow);
399
- assert.equal(otherFlow, driver.controlFlow());
400
- assert.notEqual(otherFlow, promise.controlFlow());
434
+ var otherFlow = new promise.ControlFlow();
435
+ var driver = WebDriver.createSession(executor, {}, otherFlow);
436
+ assert.equal(otherFlow, driver.controlFlow());
437
+ assert.notEqual(otherFlow, promise.controlFlow());
438
+
439
+ return waitForIdle(otherFlow);
440
+ });
401
441
 
402
- return waitForIdle(otherFlow);
442
+ describe('creation failures bubble up in control flow', function() {
443
+ function runTest(...args) {
444
+ let executor = new FakeExecutor()
445
+ .expect(CName.NEW_SESSION)
446
+ .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
447
+ .andReturnError(new StubError())
448
+ .end();
449
+
450
+ WebDriver.createSession(
451
+ executor, {'browserName': 'firefox'}, ...args);
452
+ return waitForAbort().then(assertIsStubError);
453
+ }
454
+
455
+ it('no onQuit callback', () => runTest());
456
+ it('has onQuit callback', () => runTest(null, null, function() {}));
457
+
458
+ it('onQuit callback failure suppress creation failure', function() {
459
+ let e = new Error('hi!');
460
+ let executor = new FakeExecutor()
461
+ .expect(CName.NEW_SESSION)
462
+ .withParameters({'desiredCapabilities': {'browserName': 'firefox'}})
463
+ .andReturnError(new StubError())
464
+ .end();
465
+
466
+ WebDriver.createSession(
467
+ executor, {'browserName': 'firefox'}, null, null,
468
+ () => {throw e});
469
+ return waitForAbort().then(err => assert.strictEqual(err, e));
470
+ });
471
+ });
403
472
  });
404
473
  });
405
474
 
406
475
  it('testDoesNotExecuteCommandIfSessionDoesNotResolve', function() {
407
476
  var session = Promise.reject(new StubError);
408
- new FakeExecutor().createDriver(session).getTitle();
409
- return waitForAbort().then(assertIsStubError);
477
+ return new FakeExecutor().createDriver(session)
478
+ .getTitle()
479
+ .then(_ => assert.fail('should have failed'), assertIsStubError);
410
480
  });
411
481
 
412
482
  it('testCommandReturnValuesArePassedToFirstCallback', function() {
@@ -415,31 +485,36 @@ describe('WebDriver', function() {
415
485
  end();
416
486
 
417
487
  var driver = executor.createDriver();
418
- return driver.getTitle().then(function(title) {
419
- assert.equal('Google Search', title);
420
- });
488
+ return driver.getTitle()
489
+ .then(title => assert.equal('Google Search', title));
421
490
  });
422
491
 
423
492
  it('testStopsCommandExecutionWhenAnErrorOccurs', function() {
424
493
  let e = new error.NoSuchWindowError('window not found');
425
494
  let executor = new FakeExecutor().
426
495
  expect(CName.SWITCH_TO_WINDOW).
427
- withParameters({'name': 'foo'}).
496
+ withParameters({
497
+ 'name': 'foo',
498
+ 'handle': 'foo'
499
+ }).
428
500
  andReturnError(e).
429
501
  end();
430
502
 
431
- var driver = executor.createDriver();
432
- driver.switchTo().window('foo');
433
- driver.getTitle(); // mock should blow if this gets executed
434
-
435
- return waitForAbort().then(v => assert.strictEqual(v, e));
503
+ let driver = executor.createDriver();
504
+ return driver.switchTo().window('foo')
505
+ .then(
506
+ _ => driver.getTitle(), // mock should blow if this gets executed
507
+ v => assert.strictEqual(v, e));
436
508
  });
437
509
 
438
510
  it('testCanSuppressCommandFailures', function() {
439
511
  let e = new error.NoSuchWindowError('window not found');
440
512
  let executor = new FakeExecutor().
441
513
  expect(CName.SWITCH_TO_WINDOW).
442
- withParameters({'name': 'foo'}).
514
+ withParameters({
515
+ 'name': 'foo',
516
+ 'handle': 'foo'
517
+ }).
443
518
  andReturnError(e).
444
519
  expect(CName.GET_TITLE).
445
520
  andReturnSuccess('Google Search').
@@ -456,55 +531,47 @@ describe('WebDriver', function() {
456
531
  let e = new error.NoSuchWindowError('window not found');
457
532
  let executor = new FakeExecutor().
458
533
  expect(CName.SWITCH_TO_WINDOW).
459
- withParameters({'name':'foo'}).
534
+ withParameters({
535
+ 'name': 'foo',
536
+ 'handle': 'foo'
537
+ }).
460
538
  andReturnError(e).
461
539
  end();
462
540
 
463
- executor.createDriver().switchTo().window('foo');
464
- return waitForAbort().then(v => assert.strictEqual(v, e));
541
+ return executor.createDriver()
542
+ .switchTo().window('foo')
543
+ .then(_ => assert.fail(), v => assert.strictEqual(v, e));
465
544
  });
466
545
 
467
546
  it('testErrbacksThatReturnErrorsStillSwitchToCallbackChain', function() {
468
547
  let executor = new FakeExecutor().
469
548
  expect(CName.SWITCH_TO_WINDOW).
470
- withParameters({'name':'foo'}).
549
+ withParameters({
550
+ 'name': 'foo',
551
+ 'handle': 'foo'
552
+ }).
471
553
  andReturnError(new error.NoSuchWindowError('window not found')).
472
554
  end();
473
555
 
474
556
  var driver = executor.createDriver();
475
557
  return driver.switchTo().window('foo').
476
558
  catch(function() { return new StubError; });
477
- then(assertIsStubError);
559
+ then(assertIsStubError, () => assert.fail());
478
560
  });
479
561
 
480
562
  it('testErrbacksThrownCanOverrideOriginalError', function() {
481
563
  let executor = new FakeExecutor().
482
- expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}).
564
+ expect(CName.SWITCH_TO_WINDOW, {
565
+ 'name': 'foo',
566
+ 'handle': 'foo'
567
+ }).
483
568
  andReturnError(new error.NoSuchWindowError('window not found')).
484
569
  end();
485
570
 
486
571
  var driver = executor.createDriver();
487
- driver.switchTo().window('foo').catch(throwStubError);
488
-
489
- return waitForAbort().then(assertIsStubError);
490
- });
491
-
492
- it('testCannotScheduleCommandsIfTheSessionIdHasBeenDeleted', function() {
493
- var driver = new FakeExecutor().createDriver();
494
- delete driver.session_;
495
- assert.throws(() => driver.get('http://www.google.com'));
496
- });
497
-
498
- it('testDeletesSessionIdAfterQuitting', function() {
499
- var driver;
500
- let executor = new FakeExecutor().
501
- expect(CName.QUIT).
502
- end();
503
-
504
- driver = executor.createDriver();
505
- return driver.quit().then(function() {
506
- assert.equal(void 0, driver.session_);
507
- });
572
+ return driver.switchTo().window('foo')
573
+ .catch(throwStubError)
574
+ .then(assert.fail, assertIsStubError);
508
575
  });
509
576
 
510
577
  it('testReportsErrorWhenExecutingCommandsAfterExecutingAQuit', function() {
@@ -512,14 +579,15 @@ describe('WebDriver', function() {
512
579
  expect(CName.QUIT).
513
580
  end();
514
581
 
515
- var driver = executor.createDriver();
516
- driver.quit();
517
- driver.get('http://www.google.com');
518
- return waitForAbort().
519
- then(expectedError(
520
- error.NoSuchSessionError,
521
- 'This driver instance does not have a valid session ID ' +
522
- '(did you call WebDriver.quit()?) and may no longer be used.'));
582
+ let verifyError = expectedError(
583
+ error.NoSuchSessionError,
584
+ 'This driver instance does not have a valid session ID ' +
585
+ '(did you call WebDriver.quit()?) and may no longer be used.');
586
+
587
+ let driver = executor.createDriver();
588
+ return driver.quit()
589
+ .then(_ => driver.get('http://www.google.com'))
590
+ .then(assert.fail, verifyError);
523
591
  });
524
592
 
525
593
  it('testCallbackCommandsExecuteBeforeNextCommand', function() {
@@ -541,102 +609,29 @@ describe('WebDriver', function() {
541
609
  return waitForIdle();
542
610
  });
543
611
 
544
- it('testEachCallbackFrameRunsToCompletionBeforeTheNext', function() {
545
- let executor = new FakeExecutor().
546
- expect(CName.GET_TITLE).
547
- expect(CName.GET_CURRENT_URL).
548
- expect(CName.GET_CURRENT_WINDOW_HANDLE).
549
- expect(CName.CLOSE).
550
- expect(CName.QUIT).
551
- end();
552
-
553
- var driver = executor.createDriver();
554
- driver.getTitle().
555
- // Everything in this callback...
556
- then(function() {
557
- driver.getCurrentUrl();
558
- driver.getWindowHandle();
559
- }).
560
- // ...should execute before everything in this callback.
561
- then(function() {
562
- driver.close();
563
- });
564
- // This should execute after everything above
565
- driver.quit();
566
-
567
- return waitForIdle();
568
- });
569
-
570
- describe('nestedCommandFailures', function() {
571
- it('bubbleUpToGlobalHandlerIfUnsuppressed', function() {
572
- let e = new error.NoSuchWindowError('window not found');
573
- let executor = new FakeExecutor().
574
- expect(CName.GET_TITLE).
575
- expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}).
576
- andReturnError(e).
577
- end();
578
-
579
- var driver = executor.createDriver();
580
- driver.getTitle().then(function() {
581
- driver.switchTo().window('foo');
582
- });
583
-
584
- return waitForAbort().then(v => assert.strictEqual(v, e));
585
- });
586
-
587
- it('canBeSuppressWhenTheyOccur', function() {
612
+ enablePromiseManager(() => {
613
+ it('testEachCallbackFrameRunsToCompletionBeforeTheNext', function() {
588
614
  let executor = new FakeExecutor().
589
615
  expect(CName.GET_TITLE).
590
- expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
591
- andReturnError(new error.NoSuchWindowError('window not found')).
616
+ expect(CName.GET_CURRENT_URL).
617
+ expect(CName.GET_CURRENT_WINDOW_HANDLE).
592
618
  expect(CName.CLOSE).
593
- end();
594
-
595
- var driver = executor.createDriver();
596
- driver.getTitle().then(function() {
597
- driver.switchTo().window('foo').catch(function() {});
598
- });
599
- driver.close();
600
-
601
- return waitForIdle();
602
- });
603
-
604
- it('bubbleUpThroughTheFrameStack', function() {
605
- let e = new error.NoSuchWindowError('window not found');
606
- let executor = new FakeExecutor().
607
- expect(CName.GET_TITLE).
608
- expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
609
- andReturnError(e).
619
+ expect(CName.QUIT).
610
620
  end();
611
621
 
612
622
  var driver = executor.createDriver();
613
623
  driver.getTitle().
624
+ // Everything in this callback...
614
625
  then(function() {
615
- return driver.switchTo().window('foo');
626
+ driver.getCurrentUrl();
627
+ driver.getWindowHandle();
616
628
  }).
617
- catch(v => assert.strictEqual(v, e));
618
-
619
- return waitForIdle();
620
- });
621
-
622
- it('canBeCaughtAndSuppressed', function() {
623
- let executor = new FakeExecutor().
624
- expect(CName.GET_TITLE).
625
- expect(CName.GET_CURRENT_URL).
626
- expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
627
- andReturnError(new StubError()).
628
- expect(CName.CLOSE).
629
- end();
630
-
631
- var driver = executor.createDriver();
632
- driver.getTitle().then(function() {
633
- driver.getCurrentUrl().
634
- then(function() {
635
- return driver.switchTo().window('foo');
636
- }).
637
- catch(function() {});
638
- driver.close();
639
- });
629
+ // ...should execute before everything in this callback.
630
+ then(function() {
631
+ driver.close();
632
+ });
633
+ // This should execute after everything above
634
+ driver.quit();
640
635
 
641
636
  return waitForIdle();
642
637
  });
@@ -651,39 +646,33 @@ describe('WebDriver', function() {
651
646
  end();
652
647
 
653
648
  var driver = executor.createDriver();
654
- driver.getTitle().
649
+ return driver.getTitle().
655
650
  then(function() {
656
651
  return driver.getCurrentUrl();
657
652
  }).
658
653
  then(function(value) {
659
654
  assert.equal('http://www.google.com', value);
660
655
  });
661
- return waitForIdle();
662
656
  });
663
657
 
664
658
  it('fromAnErrbackSuppressesTheError', function() {
665
- var count = 0;
666
659
  let executor = new FakeExecutor().
667
- expect(CName.SWITCH_TO_WINDOW, {'name':'foo'}).
660
+ expect(CName.SWITCH_TO_WINDOW, {
661
+ 'name': 'foo',
662
+ 'handle': 'foo'
663
+ }).
668
664
  andReturnError(new StubError()).
669
665
  expect(CName.GET_CURRENT_URL).
670
666
  andReturnSuccess('http://www.google.com').
671
667
  end();
672
668
 
673
669
  var driver = executor.createDriver();
674
- driver.switchTo().window('foo').
670
+ return driver.switchTo().window('foo').
675
671
  catch(function(e) {
676
672
  assertIsStubError(e);
677
- count += 1;
678
673
  return driver.getCurrentUrl();
679
674
  }).
680
- then(function(url) {
681
- count += 1;
682
- assert.equal('http://www.google.com', url);
683
- });
684
- return waitForIdle().then(function() {
685
- assert.equal(2, count);
686
- });
675
+ then(url => assert.equal('http://www.google.com', url));
687
676
  });
688
677
  });
689
678
 
@@ -695,23 +684,25 @@ describe('WebDriver', function() {
695
684
  });
696
685
  });
697
686
 
698
- it('executionOrderWithCustomFunctions', function() {
699
- var msg = [];
700
- let executor = new FakeExecutor().
701
- expect(CName.GET_TITLE).andReturnSuccess('cheese ').
702
- expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty').
703
- end();
687
+ enablePromiseManager(() => {
688
+ it('executionOrderWithCustomFunctions', function() {
689
+ var msg = [];
690
+ let executor = new FakeExecutor().
691
+ expect(CName.GET_TITLE).andReturnSuccess('cheese ').
692
+ expect(CName.GET_CURRENT_URL).andReturnSuccess('tasty').
693
+ end();
704
694
 
705
- var driver = executor.createDriver();
695
+ var driver = executor.createDriver();
706
696
 
707
- var pushMsg = msg.push.bind(msg);
708
- driver.getTitle().then(pushMsg);
709
- driver.call(() => 'is ').then(pushMsg);
710
- driver.getCurrentUrl().then(pushMsg);
711
- driver.call(() => '!').then(pushMsg);
697
+ var pushMsg = msg.push.bind(msg);
698
+ driver.getTitle().then(pushMsg);
699
+ driver.call(() => 'is ').then(pushMsg);
700
+ driver.getCurrentUrl().then(pushMsg);
701
+ driver.call(() => '!').then(pushMsg);
712
702
 
713
- return waitForIdle().then(function() {
714
- assert.equal('cheese is tasty!', msg.join(''));
703
+ return waitForIdle().then(function() {
704
+ assert.equal('cheese is tasty!', msg.join(''));
705
+ });
715
706
  });
716
707
  });
717
708
 
@@ -726,7 +717,7 @@ describe('WebDriver', function() {
726
717
  });
727
718
 
728
719
  it('passingPromisedArgumentsToACustomFunction', function() {
729
- var promisedArg = promise.fulfilled(2);
720
+ var promisedArg = Promise.resolve(2);
730
721
  var add = function(a, b) {
731
722
  return a + b;
732
723
  };
@@ -791,8 +782,11 @@ describe('WebDriver', function() {
791
782
 
792
783
  it('hasANestedCommandThatFails', function() {
793
784
  let executor = new FakeExecutor().
794
- expect(CName.SWITCH_TO_WINDOW, {'name': 'foo'}).
795
- andReturnError(new StubError()).
785
+ expect(CName.SWITCH_TO_WINDOW, {
786
+ 'name': 'foo',
787
+ 'handle': 'foo'
788
+ }).
789
+ andReturnError(new StubError()).
796
790
  end();
797
791
 
798
792
  var driver = executor.createDriver();
@@ -801,30 +795,32 @@ describe('WebDriver', function() {
801
795
  }).then(fail, assertIsStubError);
802
796
  });
803
797
 
804
- it('doesNotCompleteUntilReturnedPromiseIsResolved', function() {
805
- var order = [];
806
- var driver = new FakeExecutor().createDriver();
798
+ enablePromiseManager(() => {
799
+ it('doesNotCompleteUntilReturnedPromiseIsResolved', function() {
800
+ var order = [];
801
+ var driver = new FakeExecutor().createDriver();
807
802
 
808
- var d = promise.defer();
809
- d.promise.then(function() {
810
- order.push('b');
811
- });
803
+ var d = promise.defer();
804
+ d.promise.then(function() {
805
+ order.push('b');
806
+ });
812
807
 
813
- driver.call(function() {
814
- order.push('a');
815
- return d.promise;
816
- });
817
- driver.call(function() {
818
- order.push('c');
819
- });
808
+ driver.call(function() {
809
+ order.push('a');
810
+ return d.promise;
811
+ });
812
+ driver.call(function() {
813
+ order.push('c');
814
+ });
820
815
 
821
- // timeout to ensure the first function starts its execution before we
822
- // trigger d's callbacks.
823
- return new Promise(f => setTimeout(f, 0)).then(function() {
824
- assert.deepEqual(['a'], order);
825
- d.fulfill();
826
- return waitForIdle().then(function() {
827
- assert.deepEqual(['a', 'b', 'c'], order);
816
+ // timeout to ensure the first function starts its execution before we
817
+ // trigger d's callbacks.
818
+ return new Promise(f => setTimeout(f, 0)).then(function() {
819
+ assert.deepEqual(['a'], order);
820
+ d.fulfill();
821
+ return waitForIdle().then(function() {
822
+ assert.deepEqual(['a', 'b', 'c'], order);
823
+ });
828
824
  });
829
825
  });
830
826
  });
@@ -845,36 +841,58 @@ describe('WebDriver', function() {
845
841
  });
846
842
 
847
843
  describe('nestedCommands', function() {
848
- it('commandExecutionOrder', function() {
849
- var msg = [];
850
- var driver = new FakeExecutor().createDriver();
851
- driver.call(msg.push, msg, 'a');
852
- driver.call(function() {
853
- driver.call(msg.push, msg, 'c');
844
+ enablePromiseManager(() => {
845
+ it('commandExecutionOrder', function() {
846
+ var msg = [];
847
+ var driver = new FakeExecutor().createDriver();
848
+ driver.call(msg.push, msg, 'a');
854
849
  driver.call(function() {
855
- driver.call(msg.push, msg, 'e');
856
- driver.call(msg.push, msg, 'f');
850
+ driver.call(msg.push, msg, 'c');
851
+ driver.call(function() {
852
+ driver.call(msg.push, msg, 'e');
853
+ driver.call(msg.push, msg, 'f');
854
+ });
855
+ driver.call(msg.push, msg, 'd');
856
+ });
857
+ driver.call(msg.push, msg, 'b');
858
+ return waitForIdle().then(function() {
859
+ assert.equal('acefdb', msg.join(''));
857
860
  });
858
- driver.call(msg.push, msg, 'd');
859
- });
860
- driver.call(msg.push, msg, 'b');
861
- return waitForIdle().then(function() {
862
- assert.equal('acefdb', msg.join(''));
863
861
  });
864
- });
865
862
 
866
- it('basicUsage', function() {
867
- var msg = [];
868
- var driver = new FakeExecutor().createDriver();
869
- var pushMsg = msg.push.bind(msg);
870
- driver.call(() => 'cheese ').then(pushMsg);
871
- driver.call(function() {
872
- driver.call(() => 'is ').then(pushMsg);
873
- driver.call(() => 'tasty').then(pushMsg);
863
+ it('basicUsage', function() {
864
+ var msg = [];
865
+ var driver = new FakeExecutor().createDriver();
866
+ var pushMsg = msg.push.bind(msg);
867
+ driver.call(() => 'cheese ').then(pushMsg);
868
+ driver.call(function() {
869
+ driver.call(() => 'is ').then(pushMsg);
870
+ driver.call(() => 'tasty').then(pushMsg);
871
+ });
872
+ driver.call(() => '!').then(pushMsg);
873
+ return waitForIdle().then(function() {
874
+ assert.equal('cheese is tasty!', msg.join(''));
875
+ });
874
876
  });
875
- driver.call(() => '!').then(pushMsg);
876
- return waitForIdle().then(function() {
877
- assert.equal('cheese is tasty!', msg.join(''));
877
+
878
+ it('normalCommandAfterNestedCommandThatReturnsAnAction', function() {
879
+ var msg = [];
880
+ let executor = new FakeExecutor().
881
+ expect(CName.CLOSE).
882
+ end();
883
+ var driver = executor.createDriver();
884
+ driver.call(function() {
885
+ return driver.call(function() {
886
+ msg.push('a');
887
+ return driver.call(() => 'foobar');
888
+ });
889
+ });
890
+ driver.close().then(function() {
891
+ msg.push('b');
892
+ });
893
+ return waitForIdle().then(function() {
894
+ assert.equal('ab', msg.join(''));
895
+ });
878
896
  });
879
897
  });
880
898
 
@@ -889,26 +907,6 @@ describe('WebDriver', function() {
889
907
  });
890
908
  });
891
909
 
892
- it('normalCommandAfterNestedCommandThatReturnsAnAction', function() {
893
- var msg = [];
894
- let executor = new FakeExecutor().
895
- expect(CName.CLOSE).
896
- end();
897
- var driver = executor.createDriver();
898
- driver.call(function() {
899
- return driver.call(function() {
900
- msg.push('a');
901
- return driver.call(() => 'foobar');
902
- });
903
- });
904
- driver.close().then(function() {
905
- msg.push('b');
906
- });
907
- return waitForIdle().then(function() {
908
- assert.equal('ab', msg.join(''));
909
- });
910
- });
911
-
912
910
  it('errorsBubbleUp_caught', function() {
913
911
  var driver = new FakeExecutor().createDriver();
914
912
  var result = driver.call(function() {
@@ -921,12 +919,12 @@ describe('WebDriver', function() {
921
919
 
922
920
  it('errorsBubbleUp_uncaught', function() {
923
921
  var driver = new FakeExecutor().createDriver();
924
- driver.call(function() {
922
+ return driver.call(function() {
925
923
  return driver.call(function() {
926
924
  return driver.call(throwStubError);
927
925
  });
928
- });
929
- return waitForAbort().then(assertIsStubError);
926
+ })
927
+ .then(_ => assert.fail('should have failed'), assertIsStubError);
930
928
  });
931
929
 
932
930
  it('canScheduleCommands', function() {
@@ -947,29 +945,27 @@ describe('WebDriver', function() {
947
945
  });
948
946
 
949
947
  describe('WebElementPromise', function() {
948
+ let driver = new FakeExecutor().createDriver();
949
+
950
950
  it('resolvesWhenUnderlyingElementDoes', function() {
951
- var el = new WebElement({}, {'ELEMENT': 'foo'});
952
- return new WebElementPromise({}, promise.fulfilled(el)).then(function(e) {
953
- assert.strictEqual(e, el);
954
- });
951
+ let el = new WebElement(driver, {'ELEMENT': 'foo'});
952
+ return new WebElementPromise(driver, Promise.resolve(el))
953
+ .then(e => assert.strictEqual(e, el));
955
954
  });
956
955
 
957
956
  it('resolvesBeforeCallbacksOnWireValueTrigger', function() {
958
- var el = new promise.Deferred();
957
+ var el = defer();
959
958
 
960
- var element = new WebElementPromise({}, el.promise);
959
+ var element = new WebElementPromise(driver, el.promise);
961
960
  var messages = [];
962
961
 
963
- element.then(function() {
964
- messages.push('element resolved');
965
- });
966
- element.getId().then(function() {
967
- messages.push('wire value resolved');
968
- });
962
+ let steps = [
963
+ element.then(_ => messages.push('element resolved')),
964
+ element.getId().then(_ => messages.push('wire value resolved'))
965
+ ];
969
966
 
970
- assert.deepEqual([], messages);
971
- el.fulfill(new WebElement({}, {'ELEMENT': 'foo'}));
972
- return waitForIdle().then(function() {
967
+ el.resolve(new WebElement(driver, {'ELEMENT': 'foo'}));
968
+ return Promise.all(steps).then(function() {
973
969
  assert.deepEqual([
974
970
  'element resolved',
975
971
  'wire value resolved'
@@ -978,7 +974,8 @@ describe('WebDriver', function() {
978
974
  });
979
975
 
980
976
  it('isRejectedIfUnderlyingIdIsRejected', function() {
981
- var element = new WebElementPromise({}, promise.rejected(new StubError));
977
+ let element =
978
+ new WebElementPromise(driver, Promise.reject(new StubError));
982
979
  return element.then(fail, assertIsStubError);
983
980
  });
984
981
  });
@@ -1174,7 +1171,7 @@ describe('WebDriver', function() {
1174
1171
  it('failsIfArgumentIsARejectedPromise', function() {
1175
1172
  let executor = new FakeExecutor();
1176
1173
 
1177
- var arg = promise.rejected(new StubError);
1174
+ var arg = Promise.reject(new StubError);
1178
1175
  arg.catch(function() {}); // Suppress default handler.
1179
1176
 
1180
1177
  var driver = executor.createDriver();
@@ -1185,7 +1182,7 @@ describe('WebDriver', function() {
1185
1182
 
1186
1183
  describe('executeAsyncScript', function() {
1187
1184
  it('failsIfArgumentIsARejectedPromise', function() {
1188
- var arg = promise.rejected(new StubError);
1185
+ var arg = Promise.reject(new StubError);
1189
1186
  arg.catch(function() {}); // Suppress default handler.
1190
1187
 
1191
1188
  var driver = new FakeExecutor().createDriver();
@@ -1203,9 +1200,8 @@ describe('WebDriver', function() {
1203
1200
  end();
1204
1201
 
1205
1202
  var driver = executor.createDriver();
1206
- var element = driver.findElement(By.id('foo'));
1207
- element.click(); // This should never execute.
1208
- return waitForAbort().then(assertIsStubError);
1203
+ return driver.findElement(By.id('foo'))
1204
+ .then(assert.fail, assertIsStubError);
1209
1205
  });
1210
1206
 
1211
1207
  it('elementNotFoundInACallback', function() {
@@ -1216,11 +1212,9 @@ describe('WebDriver', function() {
1216
1212
  end();
1217
1213
 
1218
1214
  var driver = executor.createDriver();
1219
- promise.fulfilled().then(function() {
1220
- var element = driver.findElement(By.id('foo'));
1221
- return element.click(); // Should not execute.
1222
- });
1223
- return waitForAbort().then(assertIsStubError);
1215
+ return Promise.resolve()
1216
+ .then(_ => driver.findElement(By.id('foo')))
1217
+ .then(assert.fail, assertIsStubError);
1224
1218
  });
1225
1219
 
1226
1220
  it('elementFound', function() {
@@ -1228,7 +1222,7 @@ describe('WebDriver', function() {
1228
1222
  expect(CName.FIND_ELEMENT,
1229
1223
  {using: 'css selector', value: '*[id="foo"]'}).
1230
1224
  andReturnSuccess(WebElement.buildId('bar')).
1231
- expect(CName.CLICK_ELEMENT, {'id': 'bar'}).
1225
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
1232
1226
  andReturnSuccess().
1233
1227
  end();
1234
1228
 
@@ -1243,7 +1237,7 @@ describe('WebDriver', function() {
1243
1237
  expect(CName.FIND_ELEMENT,
1244
1238
  {using: 'css selector', value: '*[id="foo"]'}).
1245
1239
  andReturnSuccess(WebElement.buildId('bar')).
1246
- expect(CName.CLICK_ELEMENT, {'id': 'bar'}).
1240
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
1247
1241
  andReturnSuccess().
1248
1242
  end();
1249
1243
 
@@ -1261,7 +1255,7 @@ describe('WebDriver', function() {
1261
1255
  'args': []
1262
1256
  }).
1263
1257
  andReturnSuccess(WebElement.buildId('bar')).
1264
- expect(CName.CLICK_ELEMENT, {'id': 'bar'}).
1258
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('bar')}).
1265
1259
  end();
1266
1260
 
1267
1261
  var driver = executor.createDriver();
@@ -1277,12 +1271,12 @@ describe('WebDriver', function() {
1277
1271
  end();
1278
1272
 
1279
1273
  var driver = executor.createDriver();
1280
- var element = driver.findElement(By.js('return 123'));
1281
- element.click(); // Should not execute.
1282
- return waitForAbort().then(function(e) {
1283
- assertIsInstance(TypeError, e);
1284
- assert.equal('Custom locator did not return a WebElement', e.message);
1285
- });
1274
+ return driver.findElement(By.js('return 123'))
1275
+ .then(assert.fail, function(e) {
1276
+ assertIsInstance(TypeError, e);
1277
+ assert.equal(
1278
+ 'Custom locator did not return a WebElement', e.message);
1279
+ });
1286
1280
  });
1287
1281
 
1288
1282
  it('byJs_canPassArguments', function() {
@@ -1292,7 +1286,7 @@ describe('WebDriver', function() {
1292
1286
  'script': script,
1293
1287
  'args': ['div']
1294
1288
  }).
1295
- andReturnSuccess({'ELEMENT':'one'}).
1289
+ andReturnSuccess(WebElement.buildId('one')).
1296
1290
  end();
1297
1291
  var driver = executor.createDriver();
1298
1292
  driver.findElement(By.js(script, 'div'));
@@ -1305,7 +1299,7 @@ describe('WebDriver', function() {
1305
1299
  andReturnSuccess([
1306
1300
  WebElement.buildId('foo'),
1307
1301
  WebElement.buildId('bar')]).
1308
- expect(CName.CLICK_ELEMENT, {'id': 'foo'}).
1302
+ expect(CName.CLICK_ELEMENT, {'id': WebElement.buildId('foo')}).
1309
1303
  andReturnSuccess().
1310
1304
  end();
1311
1305
 
@@ -1314,19 +1308,17 @@ describe('WebDriver', function() {
1314
1308
  assert.equal(driver, d);
1315
1309
  return d.findElements(By.tagName('a'));
1316
1310
  });
1317
- element.click();
1318
- return waitForIdle();
1311
+ return element.click();
1319
1312
  });
1320
1313
 
1321
1314
  it('customLocatorThrowsIfresultIsNotAWebElement', function() {
1322
1315
  var driver = new FakeExecutor().createDriver();
1323
- driver.findElement(function() {
1324
- return 1;
1325
- });
1326
- return waitForAbort().then(function(e) {
1327
- assertIsInstance(TypeError, e);
1328
- assert.equal('Custom locator did not return a WebElement', e.message);
1329
- });
1316
+ return driver.findElement(_ => 1)
1317
+ .then(assert.fail, function(e) {
1318
+ assertIsInstance(TypeError, e);
1319
+ assert.equal(
1320
+ 'Custom locator did not return a WebElement', e.message);
1321
+ });
1330
1322
  });
1331
1323
  });
1332
1324
 
@@ -1453,7 +1445,8 @@ describe('WebDriver', function() {
1453
1445
  it('convertsVarArgsIntoStrings_simpleArgs', function() {
1454
1446
  let executor = new FakeExecutor().
1455
1447
  expect(CName.SEND_KEYS_TO_ELEMENT,
1456
- {'id': 'one', 'value':'12abc3'.split('')}).
1448
+ {'id': WebElement.buildId('one'),
1449
+ 'value':'12abc3'.split('')}).
1457
1450
  andReturnSuccess().
1458
1451
  end();
1459
1452
 
@@ -1469,16 +1462,17 @@ describe('WebDriver', function() {
1469
1462
  {'using':'css selector', 'value':'*[id="foo"]'}).
1470
1463
  andReturnSuccess(WebElement.buildId('one')).
1471
1464
  expect(CName.SEND_KEYS_TO_ELEMENT,
1472
- {'id':'one', 'value':'abc123def'.split('')}).
1465
+ {'id':WebElement.buildId('one'),
1466
+ 'value':'abc123def'.split('')}).
1473
1467
  andReturnSuccess().
1474
1468
  end();
1475
1469
 
1476
1470
  var driver = executor.createDriver();
1477
1471
  var element = driver.findElement(By.id('foo'));
1478
- element.sendKeys(
1479
- promise.fulfilled('abc'), 123,
1480
- promise.fulfilled('def'));
1481
- return waitForIdle();
1472
+ return element.sendKeys(
1473
+ Promise.resolve('abc'),
1474
+ 123,
1475
+ Promise.resolve('def'));
1482
1476
  });
1483
1477
 
1484
1478
  it('sendKeysWithAFileDetector', function() {
@@ -1486,8 +1480,9 @@ describe('WebDriver', function() {
1486
1480
  expect(CName.FIND_ELEMENT,
1487
1481
  {'using':'css selector', 'value':'*[id="foo"]'}).
1488
1482
  andReturnSuccess(WebElement.buildId('one')).
1489
- expect(CName.SEND_KEYS_TO_ELEMENT, {'id': 'one',
1490
- 'value':['modified/path']}).
1483
+ expect(CName.SEND_KEYS_TO_ELEMENT,
1484
+ {'id': WebElement.buildId('one'),
1485
+ 'value':'modified/path'.split('')}).
1491
1486
  andReturnSuccess().
1492
1487
  end();
1493
1488
 
@@ -1495,25 +1490,56 @@ describe('WebDriver', function() {
1495
1490
  let handleFile = function(d, path) {
1496
1491
  assert.strictEqual(driver, d);
1497
1492
  assert.equal(path, 'original/path');
1498
- return promise.fulfilled('modified/path');
1493
+ return Promise.resolve('modified/path');
1499
1494
  };
1500
1495
  driver.setFileDetector({handleFile});
1501
1496
 
1502
- var element = driver.findElement(By.id('foo'));
1503
- element.sendKeys('original/', 'path');
1504
- return waitForIdle();
1497
+ return driver.findElement(By.id('foo')).sendKeys('original/', 'path');
1498
+ });
1499
+ });
1500
+
1501
+ describe("switchTo()", function() {
1502
+ describe("window", function() {
1503
+ it('should return a resolved promise when the window is found', function() {
1504
+ let executor = new FakeExecutor().
1505
+ expect(CName.SWITCH_TO_WINDOW).
1506
+ withParameters({
1507
+ 'name': 'foo',
1508
+ 'handle': 'foo'
1509
+ }).
1510
+ andReturnSuccess().
1511
+ end();
1512
+
1513
+ executor.createDriver().switchTo().window('foo');
1514
+ return waitForIdle();
1515
+ });
1516
+
1517
+ it('should propagate exceptions', function() {
1518
+ let e = new error.NoSuchWindowError('window not found');
1519
+ let executor = new FakeExecutor().
1520
+ expect(CName.SWITCH_TO_WINDOW).
1521
+ withParameters({
1522
+ 'name': 'foo',
1523
+ 'handle': 'foo'
1524
+ }).
1525
+ andReturnError(e).
1526
+ end();
1527
+
1528
+ return executor.createDriver()
1529
+ .switchTo().window('foo')
1530
+ .then(assert.fail, v => assert.strictEqual(v, e));
1531
+ });
1505
1532
  });
1506
1533
  });
1507
1534
 
1508
1535
  describe('elementEquality', function() {
1509
1536
  it('isReflexive', function() {
1510
- var a = new WebElement({}, 'foo');
1537
+ var a = new WebElement(new FakeExecutor().createDriver(), 'foo');
1511
1538
  return WebElement.equals(a, a).then(assert.ok);
1512
1539
  });
1513
1540
 
1514
1541
  it('failsIfAnInputElementCouldNotBeFound', function() {
1515
- var id = promise.rejected(new StubError);
1516
- id.catch(function() {}); // Suppress default handler.
1542
+ let id = Promise.reject(new StubError);
1517
1543
 
1518
1544
  var driver = new FakeExecutor().createDriver();
1519
1545
  var a = new WebElement(driver, 'foo');
@@ -1524,71 +1550,134 @@ describe('WebDriver', function() {
1524
1550
  });
1525
1551
 
1526
1552
  describe('waiting', function() {
1527
- it('waitSucceeds', function() {
1528
- let executor = new FakeExecutor().
1529
- expect(CName.FIND_ELEMENTS,
1530
- {using: 'css selector', value: '*[id="foo"]'}).
1531
- andReturnSuccess([]).
1532
- times(2).
1533
- expect(CName.FIND_ELEMENTS,
1534
- {using: 'css selector', value: '*[id="foo"]'}).
1535
- andReturnSuccess([WebElement.buildId('bar')]).
1536
- end();
1553
+ describe('supports custom wait functions', function() {
1554
+ it('waitSucceeds', function() {
1555
+ let executor = new FakeExecutor().
1556
+ expect(CName.FIND_ELEMENTS,
1557
+ {using: 'css selector', value: '*[id="foo"]'}).
1558
+ andReturnSuccess([]).
1559
+ times(2).
1560
+ expect(CName.FIND_ELEMENTS,
1561
+ {using: 'css selector', value: '*[id="foo"]'}).
1562
+ andReturnSuccess([WebElement.buildId('bar')]).
1563
+ end();
1537
1564
 
1538
- var driver = executor.createDriver();
1539
- driver.wait(function() {
1540
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
1541
- }, 200);
1542
- return waitForIdle();
1565
+ var driver = executor.createDriver();
1566
+ driver.wait(function() {
1567
+ return driver.findElements(By.id('foo')).then(els => els.length > 0);
1568
+ }, 200);
1569
+ return waitForIdle();
1570
+ });
1571
+
1572
+ it('waitTimesout_timeoutCaught', function() {
1573
+ let executor = new FakeExecutor().
1574
+ expect(CName.FIND_ELEMENTS,
1575
+ {using: 'css selector', value: '*[id="foo"]'}).
1576
+ andReturnSuccess([]).
1577
+ anyTimes().
1578
+ end();
1579
+
1580
+ var driver = executor.createDriver();
1581
+ return driver.wait(function() {
1582
+ return driver.findElements(By.id('foo')).then(els => els.length > 0);
1583
+ }, 25).then(fail, function(e) {
1584
+ assert.equal('Wait timed out after ',
1585
+ e.message.substring(0, 'Wait timed out after '.length));
1586
+ });
1587
+ });
1588
+
1589
+ enablePromiseManager(() => {
1590
+ it('waitTimesout_timeoutNotCaught', function() {
1591
+ let executor = new FakeExecutor().
1592
+ expect(CName.FIND_ELEMENTS,
1593
+ {using: 'css selector', value: '*[id="foo"]'}).
1594
+ andReturnSuccess([]).
1595
+ anyTimes().
1596
+ end();
1597
+
1598
+ var driver = executor.createDriver();
1599
+ driver.wait(function() {
1600
+ return driver.findElements(By.id('foo')).then(els => els.length > 0);
1601
+ }, 25);
1602
+ return waitForAbort().then(function(e) {
1603
+ assert.equal('Wait timed out after ',
1604
+ e.message.substring(0, 'Wait timed out after '.length));
1605
+ });
1606
+ });
1607
+ });
1543
1608
  });
1544
1609
 
1545
- it('waitTimesout_timeoutCaught', function() {
1546
- let executor = new FakeExecutor().
1547
- expect(CName.FIND_ELEMENTS,
1548
- {using: 'css selector', value: '*[id="foo"]'}).
1549
- andReturnSuccess([]).
1550
- anyTimes().
1551
- end();
1610
+ describe('supports condition objects', function() {
1611
+ it('wait succeeds', function() {
1612
+ let executor = new FakeExecutor()
1613
+ .expect(CName.FIND_ELEMENTS,
1614
+ {using: 'css selector', value: '*[id="foo"]'})
1615
+ .andReturnSuccess([])
1616
+ .times(2)
1617
+ .expect(CName.FIND_ELEMENTS,
1618
+ {using: 'css selector', value: '*[id="foo"]'})
1619
+ .andReturnSuccess([WebElement.buildId('bar')])
1620
+ .end();
1552
1621
 
1553
- var driver = executor.createDriver();
1554
- return driver.wait(function() {
1555
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
1556
- }, 25).then(fail, function(e) {
1557
- assert.equal('Wait timed out after ',
1558
- e.message.substring(0, 'Wait timed out after '.length));
1622
+ let driver = executor.createDriver();
1623
+ return driver.wait(until.elementLocated(By.id('foo')), 200);
1624
+ });
1625
+
1626
+ it('wait times out', function() {
1627
+ let executor = new FakeExecutor()
1628
+ .expect(CName.FIND_ELEMENTS,
1629
+ {using: 'css selector', value: '*[id="foo"]'})
1630
+ .andReturnSuccess([])
1631
+ .anyTimes()
1632
+ .end();
1633
+
1634
+ let driver = executor.createDriver();
1635
+ return driver.wait(until.elementLocated(By.id('foo')), 5)
1636
+ .then(fail, err => assert.ok(err instanceof error.TimeoutError));
1559
1637
  });
1560
1638
  });
1561
1639
 
1562
- it('waitTimesout_timeoutNotCaught', function() {
1563
- let executor = new FakeExecutor().
1564
- expect(CName.FIND_ELEMENTS,
1565
- {using: 'css selector', value: '*[id="foo"]'}).
1566
- andReturnSuccess([]).
1567
- anyTimes().
1568
- end();
1640
+ describe('supports promise objects', function() {
1641
+ it('wait succeeds', function() {
1642
+ let promise = new Promise(resolve => {
1643
+ setTimeout(() => resolve(1), 10);
1644
+ });
1569
1645
 
1570
- var driver = executor.createDriver();
1571
- driver.wait(function() {
1572
- return driver.findElements(By.id('foo')).then(els => els.length > 0);
1573
- }, 25);
1574
- return waitForAbort().then(function(e) {
1575
- assert.equal('Wait timed out after ',
1576
- e.message.substring(0, 'Wait timed out after '.length));
1646
+ let driver = new FakeExecutor().createDriver();
1647
+ return driver.wait(promise, 200).then(v => assert.equal(v, 1));
1648
+ });
1649
+
1650
+ it('wait times out', function() {
1651
+ let promise = new Promise(resolve => {/* never resolves */});
1652
+
1653
+ let driver = new FakeExecutor().createDriver();
1654
+ return driver.wait(promise, 5)
1655
+ .then(fail, err => assert.ok(err instanceof error.TimeoutError));
1656
+ });
1657
+
1658
+ it('wait fails if promise is rejected', function() {
1659
+ let err = Error('boom');
1660
+ let driver = new FakeExecutor().createDriver();
1661
+ return driver.wait(Promise.reject(err), 5)
1662
+ .then(fail, e => assert.strictEqual(e, err));
1577
1663
  });
1578
1664
  });
1665
+
1666
+ it('fails if not supported condition type provided', function() {
1667
+ let driver = new FakeExecutor().createDriver();
1668
+ assert.throws(() => driver.wait({}, 5), TypeError);
1669
+ });
1579
1670
  });
1580
1671
 
1581
1672
  describe('alert handling', function() {
1582
1673
  it('alertResolvesWhenPromisedTextResolves', function() {
1583
- var deferredText = new promise.Deferred();
1674
+ let driver = new FakeExecutor().createDriver();
1675
+ let deferredText = defer();
1584
1676
 
1585
- var alert = new AlertPromise({}, deferredText.promise);
1586
- assert.ok(alert.isPending());
1677
+ let alert = new AlertPromise(driver, deferredText.promise);
1587
1678
 
1588
- deferredText.fulfill(new Alert({}, 'foo'));
1589
- return alert.getText().then(function(text) {
1590
- assert.equal('foo', text);
1591
- });
1679
+ deferredText.resolve(new Alert(driver, 'foo'));
1680
+ return alert.getText().then(text => assert.equal(text, 'foo'));
1592
1681
  });
1593
1682
 
1594
1683
  it('cannotSwitchToAlertThatIsNotPresent', function() {
@@ -1598,32 +1687,33 @@ describe('WebDriver', function() {
1598
1687
  .andReturnError(e)
1599
1688
  .end();
1600
1689
 
1601
- var driver = executor.createDriver();
1602
- var alert = driver.switchTo().alert();
1603
- alert.dismiss(); // Should never execute.
1604
- return waitForAbort().then(v => assert.strictEqual(v, e));
1690
+ return executor.createDriver()
1691
+ .switchTo().alert()
1692
+ .then(assert.fail, v => assert.strictEqual(v, e));
1605
1693
  });
1606
1694
 
1607
- it('alertsBelongToSameFlowAsParentDriver', function() {
1608
- let executor = new FakeExecutor()
1609
- .expect(CName.GET_ALERT_TEXT).andReturnSuccess('hello')
1610
- .end();
1695
+ enablePromiseManager(() => {
1696
+ it('alertsBelongToSameFlowAsParentDriver', function() {
1697
+ let executor = new FakeExecutor()
1698
+ .expect(CName.GET_ALERT_TEXT).andReturnSuccess('hello')
1699
+ .end();
1611
1700
 
1612
- var driver = executor.createDriver();
1613
- var otherFlow = new promise.ControlFlow();
1614
- otherFlow.execute(function() {
1615
- driver.switchTo().alert().then(function() {
1616
- assert.strictEqual(
1617
- driver.controlFlow(), promise.controlFlow(),
1618
- 'Alert should belong to the same flow as its parent driver');
1701
+ var driver = executor.createDriver();
1702
+ var otherFlow = new promise.ControlFlow();
1703
+ otherFlow.execute(function() {
1704
+ driver.switchTo().alert().then(function() {
1705
+ assert.strictEqual(
1706
+ driver.controlFlow(), promise.controlFlow(),
1707
+ 'Alert should belong to the same flow as its parent driver');
1708
+ });
1619
1709
  });
1620
- });
1621
1710
 
1622
- assert.notEqual(otherFlow, driver.controlFlow);
1623
- return Promise.all([
1624
- waitForIdle(otherFlow),
1625
- waitForIdle(driver.controlFlow())
1626
- ]);
1711
+ assert.notEqual(otherFlow, driver.controlFlow);
1712
+ return Promise.all([
1713
+ waitForIdle(otherFlow),
1714
+ waitForIdle(driver.controlFlow())
1715
+ ]);
1716
+ });
1627
1717
  });
1628
1718
 
1629
1719
  it('commandsFailIfAlertNotPresent', function() {
@@ -1649,26 +1739,28 @@ describe('WebDriver', function() {
1649
1739
  });
1650
1740
  });
1651
1741
 
1652
- it('testWebElementsBelongToSameFlowAsParentDriver', function() {
1653
- let executor = new FakeExecutor()
1654
- .expect(CName.FIND_ELEMENT,
1655
- {using: 'css selector', value: '*[id="foo"]'})
1656
- .andReturnSuccess(WebElement.buildId('abc123'))
1657
- .end();
1742
+ enablePromiseManager(() => {
1743
+ it('testWebElementsBelongToSameFlowAsParentDriver', function() {
1744
+ let executor = new FakeExecutor()
1745
+ .expect(CName.FIND_ELEMENT,
1746
+ {using: 'css selector', value: '*[id="foo"]'})
1747
+ .andReturnSuccess(WebElement.buildId('abc123'))
1748
+ .end();
1658
1749
 
1659
- var driver = executor.createDriver();
1660
- var otherFlow = new promise.ControlFlow();
1661
- otherFlow.execute(function() {
1662
- driver.findElement({id: 'foo'}).then(function() {
1663
- assert.equal(driver.controlFlow(), promise.controlFlow());
1750
+ var driver = executor.createDriver();
1751
+ var otherFlow = new promise.ControlFlow();
1752
+ otherFlow.execute(function() {
1753
+ driver.findElement({id: 'foo'}).then(function() {
1754
+ assert.equal(driver.controlFlow(), promise.controlFlow());
1755
+ });
1664
1756
  });
1665
- });
1666
1757
 
1667
- assert.notEqual(otherFlow, driver.controlFlow);
1668
- return Promise.all([
1669
- waitForIdle(otherFlow),
1670
- waitForIdle(driver.controlFlow())
1671
- ]);
1758
+ assert.notEqual(otherFlow, driver.controlFlow);
1759
+ return Promise.all([
1760
+ waitForIdle(otherFlow),
1761
+ waitForIdle(driver.controlFlow())
1762
+ ]);
1763
+ });
1672
1764
  });
1673
1765
 
1674
1766
  it('testFetchingLogs', function() {
@@ -1697,7 +1789,7 @@ describe('WebDriver', function() {
1697
1789
  });
1698
1790
 
1699
1791
  it('testCommandsFailIfInitialSessionCreationFailed', function() {
1700
- var session = promise.rejected(new StubError);
1792
+ var session = Promise.reject(new StubError);
1701
1793
 
1702
1794
  var driver = new FakeExecutor().createDriver(session);
1703
1795
  var navigateResult = driver.get('some-url').then(fail, assertIsStubError);
@@ -1745,10 +1837,10 @@ describe('WebDriver', function() {
1745
1837
 
1746
1838
  describe('actions()', function() {
1747
1839
  it('failsIfInitialDriverCreationFailed', function() {
1748
- let session = promise.rejected(new StubError);
1749
- session.catch(function() {});
1750
- return new FakeExecutor().
1751
- createDriver(session).
1840
+ let session = Promise.reject(new StubError('no session for you'));
1841
+ let driver = new FakeExecutor().createDriver(session);
1842
+ driver.getSession().catch(function() {});
1843
+ return driver.
1752
1844
  actions().
1753
1845
  mouseDown().
1754
1846
  mouseUp().
@@ -1834,10 +1926,10 @@ describe('WebDriver', function() {
1834
1926
 
1835
1927
  describe('touchActions()', function() {
1836
1928
  it('failsIfInitialDriverCreationFailed', function() {
1837
- let session = promise.rejected(new StubError);
1838
- session.catch(function() {});
1839
- return new FakeExecutor().
1840
- createDriver(session).
1929
+ let session = Promise.reject(new StubError);
1930
+ let driver = new FakeExecutor().createDriver(session);
1931
+ driver.getSession().catch(function() {});
1932
+ return driver.
1841
1933
  touchActions().
1842
1934
  scroll({x: 3, y: 4}).
1843
1935
  perform().
@@ -1871,8 +1963,8 @@ describe('WebDriver', function() {
1871
1963
 
1872
1964
  it('canUseGeneratorsWithWebDriverCall', function() {
1873
1965
  return driver.call(function* () {
1874
- var x = yield promise.fulfilled(1);
1875
- var y = yield promise.fulfilled(2);
1966
+ var x = yield Promise.resolve(1);
1967
+ var y = yield Promise.resolve(2);
1876
1968
  return x + y;
1877
1969
  }).then(function(value) {
1878
1970
  assert.deepEqual(3, value);
@@ -1881,7 +1973,7 @@ describe('WebDriver', function() {
1881
1973
 
1882
1974
  it('canDefineScopeOnGeneratorCall', function() {
1883
1975
  return driver.call(function* () {
1884
- var x = yield promise.fulfilled(1);
1976
+ var x = yield Promise.resolve(1);
1885
1977
  return this.name + x;
1886
1978
  }, {name: 'Bob'}).then(function(value) {
1887
1979
  assert.deepEqual('Bob1', value);
@@ -1890,8 +1982,8 @@ describe('WebDriver', function() {
1890
1982
 
1891
1983
  it('canSpecifyArgsOnGeneratorCall', function() {
1892
1984
  return driver.call(function* (a, b) {
1893
- var x = yield promise.fulfilled(1);
1894
- var y = yield promise.fulfilled(2);
1985
+ var x = yield Promise.resolve(1);
1986
+ var y = yield Promise.resolve(2);
1895
1987
  return [x + y, a, b];
1896
1988
  }, null, 'abc', 123).then(function(value) {
1897
1989
  assert.deepEqual([3, 'abc', 123], value);
@@ -1926,6 +2018,8 @@ describe('WebDriver', function() {
1926
2018
  });
1927
2019
 
1928
2020
  describe('wire format', function() {
2021
+ const FAKE_DRIVER = new FakeExecutor().createDriver();
2022
+
1929
2023
  describe('can serialize', function() {
1930
2024
  function runSerializeTest(input, want) {
1931
2025
  let executor = new FakeExecutor().
@@ -1969,14 +2063,15 @@ describe('WebDriver', function() {
1969
2063
 
1970
2064
  it('WebElement', function() {
1971
2065
  return runSerializeTest(
1972
- new WebElement({}, 'fefifofum'),
2066
+ new WebElement(FAKE_DRIVER, 'fefifofum'),
1973
2067
  WebElement.buildId('fefifofum'));
1974
2068
  });
1975
2069
 
1976
2070
  it('WebElementPromise', function() {
1977
2071
  return runSerializeTest(
1978
2072
  new WebElementPromise(
1979
- {}, promise.fulfilled(new WebElement({}, 'fefifofum'))),
2073
+ FAKE_DRIVER,
2074
+ Promise.resolve(new WebElement(FAKE_DRIVER, 'fefifofum'))),
1980
2075
  WebElement.buildId('fefifofum'));
1981
2076
  });
1982
2077
 
@@ -1987,14 +2082,15 @@ describe('WebDriver', function() {
1987
2082
 
1988
2083
  it('with WebElement', function() {
1989
2084
  return runSerializeTest(
1990
- [new WebElement({}, 'fefifofum')],
2085
+ [new WebElement(FAKE_DRIVER, 'fefifofum')],
1991
2086
  [WebElement.buildId('fefifofum')]);
1992
2087
  });
1993
2088
 
1994
2089
  it('with WebElementPromise', function() {
1995
2090
  return runSerializeTest(
1996
2091
  [new WebElementPromise(
1997
- {}, promise.fulfilled(new WebElement({}, 'fefifofum')))],
2092
+ FAKE_DRIVER,
2093
+ Promise.resolve(new WebElement(FAKE_DRIVER, 'fefifofum')))],
1998
2094
  [WebElement.buildId('fefifofum')]);
1999
2095
  });
2000
2096
 
@@ -2004,7 +2100,7 @@ describe('WebDriver', function() {
2004
2100
  [123, {'foo': 'bar'}]
2005
2101
  ];
2006
2102
 
2007
- var element = new WebElement({}, 'fefifofum');
2103
+ var element = new WebElement(FAKE_DRIVER, 'fefifofum');
2008
2104
  var input = ['abc', 123, true, element, [123, {'foo': 'bar'}]];
2009
2105
  return runSerializeTest(input, expected);
2010
2106
  });
@@ -2048,7 +2144,7 @@ describe('WebDriver', function() {
2048
2144
  'sessionId': 'foo'
2049
2145
  };
2050
2146
 
2051
- var element = new WebElement({}, 'fefifofum');
2147
+ var element = new WebElement(FAKE_DRIVER, 'fefifofum');
2052
2148
  var parameters = {
2053
2149
  'script': 'return 1',
2054
2150
  'args':['abc', 123, true, element, [123, {'foo': 'bar'}]],