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
@@ -34,34 +34,34 @@ test.suite(function(env) {
34
34
 
35
35
  var driver;
36
36
 
37
- test.before(function() {
38
- driver = env.builder().build();
37
+ test.before(function*() {
38
+ driver = yield env.builder().build();
39
39
  });
40
40
 
41
- test.after(function() {
42
- driver.quit();
41
+ after(function() {
42
+ return driver.quit();
43
43
  });
44
44
 
45
45
  describe('finding elements', function() {
46
46
  test.it(
47
47
  'should work after loading multiple pages in a row',
48
- function() {
49
- driver.get(Pages.formPage);
50
- driver.get(Pages.xhtmlTestPage);
51
- driver.findElement(By.linkText('click me')).click();
52
- driver.wait(until.titleIs('We Arrive Here'), 5000);
48
+ function*() {
49
+ yield driver.get(Pages.formPage);
50
+ yield driver.get(Pages.xhtmlTestPage);
51
+ yield driver.findElement(By.linkText('click me')).click();
52
+ yield driver.wait(until.titleIs('We Arrive Here'), 5000);
53
53
  });
54
54
 
55
55
  describe('By.id()', function() {
56
- test.it('should work', function() {
57
- driver.get(Pages.xhtmlTestPage);
58
- driver.findElement(By.id('linkId')).click();
59
- driver.wait(until.titleIs('We Arrive Here'), 5000);
56
+ test.it('should work', function*() {
57
+ yield driver.get(Pages.xhtmlTestPage);
58
+ yield driver.findElement(By.id('linkId')).click();
59
+ yield driver.wait(until.titleIs('We Arrive Here'), 5000);
60
60
  });
61
61
 
62
- test.it('should fail if ID not present on page', function() {
63
- driver.get(Pages.formPage);
64
- driver.findElement(By.id('nonExistantButton')).
62
+ test.it('should fail if ID not present on page', function*() {
63
+ yield driver.get(Pages.formPage);
64
+ return driver.findElement(By.id('nonExistantButton')).
65
65
  then(fail, function(e) {
66
66
  assert(e).instanceOf(error.NoSuchElementError);
67
67
  });
@@ -70,182 +70,178 @@ test.suite(function(env) {
70
70
  test.it(
71
71
  'should find multiple elements by ID even though that is ' +
72
72
  'malformed HTML',
73
- function() {
74
- driver.get(Pages.nestedPage);
75
- driver.findElements(By.id('2')).then(function(elements) {
76
- assert(elements.length).equalTo(8);
77
- });
73
+ function*() {
74
+ yield driver.get(Pages.nestedPage);
75
+
76
+ let elements = yield driver.findElements(By.id('2'));
77
+ assert(elements.length).equalTo(8);
78
78
  });
79
79
  });
80
80
 
81
81
  describe('By.linkText()', function() {
82
- test.it('should be able to click on link identified by text', function() {
83
- driver.get(Pages.xhtmlTestPage);
84
- driver.findElement(By.linkText('click me')).click();
85
- driver.wait(until.titleIs('We Arrive Here'), 5000);
82
+ test.it('should be able to click on link identified by text', function*() {
83
+ yield driver.get(Pages.xhtmlTestPage);
84
+ yield driver.findElement(By.linkText('click me')).click();
85
+ yield driver.wait(until.titleIs('We Arrive Here'), 5000);
86
86
  });
87
87
 
88
88
  test.it(
89
89
  'should be able to find elements by partial link text',
90
- function() {
91
- driver.get(Pages.xhtmlTestPage);
92
- driver.findElement(By.partialLinkText('ick me')).click();
93
- driver.wait(until.titleIs('We Arrive Here'), 5000);
90
+ function*() {
91
+ yield driver.get(Pages.xhtmlTestPage);
92
+ yield driver.findElement(By.partialLinkText('ick me')).click();
93
+ yield driver.wait(until.titleIs('We Arrive Here'), 5000);
94
94
  });
95
95
 
96
- test.it('should work when link text contains equals sign', function() {
97
- driver.get(Pages.xhtmlTestPage);
98
- var id = driver.findElement(By.linkText('Link=equalssign')).
99
- getAttribute('id');
96
+ test.it('should work when link text contains equals sign', function*() {
97
+ yield driver.get(Pages.xhtmlTestPage);
98
+ let el = yield driver.findElement(By.linkText('Link=equalssign'));
99
+
100
+ let id = yield el.getAttribute('id');
100
101
  assert(id).equalTo('linkWithEqualsSign');
101
102
  });
102
103
 
103
104
  test.it('matches by partial text when containing equals sign',
104
- function() {
105
- driver.get(Pages.xhtmlTestPage);
106
- var id = driver.findElement(By.partialLinkText('Link=')).
107
- getAttribute('id');
105
+ function*() {
106
+ yield driver.get(Pages.xhtmlTestPage);
107
+ let link = yield driver.findElement(By.partialLinkText('Link='));
108
+
109
+ let id = yield link.getAttribute('id');
108
110
  assert(id).equalTo('linkWithEqualsSign');
109
111
  });
110
112
 
111
113
  test.it('works when searching for multiple and text contains =',
112
- function() {
113
- driver.get(Pages.xhtmlTestPage);
114
- driver.findElements(By.linkText('Link=equalssign')).
115
- then(function(elements) {
116
- assert(elements.length).equalTo(1);
117
- return elements[0].getAttribute('id');
118
- }).
119
- then(function(id) {
120
- assert(id).equalTo('linkWithEqualsSign');
121
- });
114
+ function*() {
115
+ yield driver.get(Pages.xhtmlTestPage);
116
+ let elements =
117
+ yield driver.findElements(By.linkText('Link=equalssign'));
118
+
119
+ assert(elements.length).equalTo(1);
120
+
121
+ let id = yield elements[0].getAttribute('id');
122
+ assert(id).equalTo('linkWithEqualsSign');
122
123
  });
123
124
 
124
125
  test.it(
125
126
  'works when searching for multiple with partial text containing =',
126
- function() {
127
- driver.get(Pages.xhtmlTestPage);
128
- driver.findElements(By.partialLinkText('Link=')).
129
- then(function(elements) {
130
- assert(elements.length).equalTo(1);
131
- return elements[0].getAttribute('id');
132
- }).
133
- then(function(id) {
134
- assert(id).equalTo('linkWithEqualsSign');
135
- });
136
- });
127
+ function*() {
128
+ yield driver.get(Pages.xhtmlTestPage);
129
+ let elements =
130
+ yield driver.findElements(By.partialLinkText('Link='));
131
+
132
+ assert(elements.length).equalTo(1);
133
+
134
+ let id = yield elements[0].getAttribute('id');
135
+ assert(id).equalTo('linkWithEqualsSign');
136
+ });
137
137
 
138
138
  test.it('should be able to find multiple exact matches',
139
- function() {
140
- driver.get(Pages.xhtmlTestPage);
141
- driver.findElements(By.linkText('click me')).
142
- then(function(elements) {
143
- assert(elements.length).equalTo(2);
144
- });
139
+ function*() {
140
+ yield driver.get(Pages.xhtmlTestPage);
141
+ let elements = yield driver.findElements(By.linkText('click me'));
142
+ assert(elements.length).equalTo(2);
145
143
  });
146
144
 
147
145
  test.it('should be able to find multiple partial matches',
148
- function() {
149
- driver.get(Pages.xhtmlTestPage);
150
- driver.findElements(By.partialLinkText('ick me')).
151
- then(function(elements) {
152
- assert(elements.length).equalTo(2);
153
- });
146
+ function*() {
147
+ yield driver.get(Pages.xhtmlTestPage);
148
+ let elements =
149
+ yield driver.findElements(By.partialLinkText('ick me'));
150
+ assert(elements.length).equalTo(2);
154
151
  });
155
152
 
156
- // See https://github.com/mozilla/geckodriver/issues/137
157
- test.ignore(browsers(Browser.FIREFOX)).
158
- it('works on XHTML pages', function() {
159
- driver.get(test.whereIs('actualXhtmlPage.xhtml'));
153
+ test.ignore(browsers(Browser.SAFARI)).
154
+ it('works on XHTML pages', function*() {
155
+ yield driver.get(test.whereIs('actualXhtmlPage.xhtml'));
160
156
 
161
- var el = driver.findElement(By.linkText('Foo'));
162
- assert(el.getText()).equalTo('Foo');
157
+ let el = yield driver.findElement(By.linkText('Foo'));
158
+ return assert(el.getText()).equalTo('Foo');
163
159
  });
164
160
  });
165
161
 
166
162
  describe('By.name()', function() {
167
- test.it('should work', function() {
168
- driver.get(Pages.formPage);
163
+ test.it('should work', function*() {
164
+ yield driver.get(Pages.formPage);
169
165
 
170
- var el = driver.findElement(By.name('checky'));
171
- assert(el.getAttribute('value')).equalTo('furrfu');
166
+ let el = yield driver.findElement(By.name('checky'));
167
+ yield assert(el.getAttribute('value')).equalTo('furrfu');
172
168
  });
173
169
 
174
- test.it('should find multiple elements with same name', function() {
175
- driver.get(Pages.nestedPage);
176
- driver.findElements(By.name('checky')).then(function(elements) {
177
- assert(elements.length).greaterThan(1);
178
- });
170
+ test.it('should find multiple elements with same name', function*() {
171
+ yield driver.get(Pages.nestedPage);
172
+
173
+ let elements = yield driver.findElements(By.name('checky'));
174
+ assert(elements.length).greaterThan(1);
179
175
  });
180
176
 
181
177
  test.it(
182
178
  'should be able to find elements that do not support name property',
183
- function() {
184
- driver.get(Pages.nestedPage);
185
- driver.findElement(By.name('div1'));
179
+ function*() {
180
+ yield driver.get(Pages.nestedPage);
181
+ yield driver.findElement(By.name('div1'));
186
182
  // Pass if this does not return an error.
187
183
  });
188
184
 
189
- test.it('shoudl be able to find hidden elements by name', function() {
190
- driver.get(Pages.formPage);
191
- driver.findElement(By.name('hidden'));
185
+ test.it('shoudl be able to find hidden elements by name', function*() {
186
+ yield driver.get(Pages.formPage);
187
+ yield driver.findElement(By.name('hidden'));
192
188
  // Pass if this does not return an error.
193
189
  });
194
190
  });
195
191
 
196
192
  describe('By.className()', function() {
197
- test.it('should work', function() {
198
- driver.get(Pages.xhtmlTestPage);
193
+ test.it('should work', function*() {
194
+ yield driver.get(Pages.xhtmlTestPage);
199
195
 
200
- var el = driver.findElement(By.className('extraDiv'));
201
- assert(el.getText()).startsWith('Another div starts here.');
196
+ let el = yield driver.findElement(By.className('extraDiv'));
197
+ yield assert(el.getText()).startsWith('Another div starts here.');
202
198
  });
203
199
 
204
- test.it('should work when name is first name among many', function() {
205
- driver.get(Pages.xhtmlTestPage);
200
+ test.it('should work when name is first name among many', function*() {
201
+ yield driver.get(Pages.xhtmlTestPage);
206
202
 
207
- var el = driver.findElement(By.className('nameA'));
208
- assert(el.getText()).equalTo('An H2 title');
203
+ let el = yield driver.findElement(By.className('nameA'));
204
+ yield assert(el.getText()).equalTo('An H2 title');
209
205
  });
210
206
 
211
- test.it('should work when name is last name among many', function() {
212
- driver.get(Pages.xhtmlTestPage);
207
+ test.it('should work when name is last name among many', function*() {
208
+ yield driver.get(Pages.xhtmlTestPage);
213
209
 
214
- var el = driver.findElement(By.className('nameC'));
215
- assert(el.getText()).equalTo('An H2 title');
210
+ let el = yield driver.findElement(By.className('nameC'));
211
+ yield assert(el.getText()).equalTo('An H2 title');
216
212
  });
217
213
 
218
- test.it('should work when name is middle of many', function() {
219
- driver.get(Pages.xhtmlTestPage);
214
+ test.it('should work when name is middle of many', function*() {
215
+ yield driver.get(Pages.xhtmlTestPage);
220
216
 
221
- var el = driver.findElement(By.className('nameBnoise'));
222
- assert(el.getText()).equalTo('An H2 title');
217
+ let el = yield driver.findElement(By.className('nameBnoise'));
218
+ yield assert(el.getText()).equalTo('An H2 title');
223
219
  });
224
220
 
225
- test.it('should work when name surrounded by whitespace', function() {
226
- driver.get(Pages.xhtmlTestPage);
221
+ test.it('should work when name surrounded by whitespace', function*() {
222
+ yield driver.get(Pages.xhtmlTestPage);
227
223
 
228
- var el = driver.findElement(By.className('spaceAround'));
229
- assert(el.getText()).equalTo('Spaced out');
224
+ let el = yield driver.findElement(By.className('spaceAround'));
225
+ yield assert(el.getText()).equalTo('Spaced out');
230
226
  });
231
227
 
232
- test.it('should fail if queried name only partially matches', function() {
233
- driver.get(Pages.xhtmlTestPage);
234
- driver.findElement(By.className('nameB')).
228
+ test.it('should fail if queried name only partially matches', function*() {
229
+ yield driver.get(Pages.xhtmlTestPage);
230
+ return driver.findElement(By.className('nameB')).
235
231
  then(fail, function(e) {
236
232
  assert(e).instanceOf(error.NoSuchElementError);
237
233
  });
238
234
  });
239
235
 
240
- test.it('should implicitly wait', function() {
236
+ test.it('should implicitly wait', function*() {
241
237
  var TIMEOUT_IN_MS = 1000;
242
238
  var EPSILON = TIMEOUT_IN_MS / 2;
243
239
 
244
- driver.manage().timeouts().implicitlyWait(TIMEOUT_IN_MS);
245
- driver.get(Pages.formPage);
240
+ yield driver.manage().timeouts().implicitlyWait(TIMEOUT_IN_MS);
241
+ yield driver.get(Pages.formPage);
246
242
 
247
243
  var start = new Date();
248
- driver.findElement(By.id('nonExistantButton')).
244
+ return driver.findElement(By.id('nonExistantButton')).
249
245
  then(fail, function(e) {
250
246
  var end = new Date();
251
247
  assert(e).instanceOf(error.NoSuchElementError);
@@ -253,11 +249,11 @@ test.suite(function(env) {
253
249
  });
254
250
  });
255
251
 
256
- test.it('should be able to find multiple matches', function() {
257
- driver.get(Pages.xhtmlTestPage);
258
- driver.findElements(By.className('nameC')).then(function(elements) {
259
- assert(elements.length).greaterThan(1);
260
- });
252
+ test.it('should be able to find multiple matches', function*() {
253
+ yield driver.get(Pages.xhtmlTestPage);
254
+
255
+ let elements = yield driver.findElements(By.className('nameC'));
256
+ assert(elements.length).greaterThan(1);
261
257
  });
262
258
 
263
259
  test.it('permits compound class names', function() {
@@ -269,133 +265,136 @@ test.suite(function(env) {
269
265
  });
270
266
 
271
267
  describe('By.xpath()', function() {
272
- test.it('should work with multiple matches', function() {
273
- driver.get(Pages.xhtmlTestPage);
274
- driver.findElements(By.xpath('//div')).then(function(elements) {
275
- assert(elements.length).greaterThan(1);
276
- });
268
+ test.it('should work with multiple matches', function*() {
269
+ yield driver.get(Pages.xhtmlTestPage);
270
+ let elements = yield driver.findElements(By.xpath('//div'));
271
+ assert(elements.length).greaterThan(1);
277
272
  });
278
273
 
279
- test.it('should work for selectors using contains keyword', function() {
280
- driver.get(Pages.nestedPage);
281
- driver.findElement(By.xpath('//a[contains(., "hello world")]'));
274
+ test.it('should work for selectors using contains keyword', function*() {
275
+ yield driver.get(Pages.nestedPage);
276
+ yield driver.findElement(By.xpath('//a[contains(., "hello world")]'));
282
277
  // Pass if no error.
283
278
  });
284
279
  });
285
280
 
286
281
  describe('By.tagName()', function() {
287
- test.it('works', function() {
288
- driver.get(Pages.formPage);
282
+ test.it('works', function*() {
283
+ yield driver.get(Pages.formPage);
289
284
 
290
- var el = driver.findElement(By.tagName('input'));
291
- assert(el.getTagName()).equalTo('input');
285
+ let el = yield driver.findElement(By.tagName('input'));
286
+ yield assert(el.getTagName()).equalTo('input');
292
287
  });
293
288
 
294
- test.it('can find multiple elements', function() {
295
- driver.get(Pages.formPage);
296
- driver.findElements(By.tagName('input')).then(function(elements) {
297
- assert(elements.length).greaterThan(1);
298
- });
289
+ test.it('can find multiple elements', function*() {
290
+ yield driver.get(Pages.formPage);
291
+
292
+ let elements = yield driver.findElements(By.tagName('input'));
293
+ assert(elements.length).greaterThan(1);
299
294
  });
300
295
  });
301
296
 
302
297
  describe('By.css()', function() {
303
- test.it('works', function() {
304
- driver.get(Pages.xhtmlTestPage);
305
- driver.findElement(By.css('div.content'));
298
+ test.it('works', function*() {
299
+ yield driver.get(Pages.xhtmlTestPage);
300
+ yield driver.findElement(By.css('div.content'));
306
301
  // Pass if no error.
307
302
  });
308
303
 
309
- test.it('can find multiple elements', function() {
310
- driver.get(Pages.xhtmlTestPage);
311
- driver.findElements(By.css('p')).then(function(elements) {
312
- assert(elements.length).greaterThan(1);
313
- });
304
+ test.it('can find multiple elements', function*() {
305
+ yield driver.get(Pages.xhtmlTestPage);
306
+
307
+ let elements = yield driver.findElements(By.css('p'));
308
+ assert(elements.length).greaterThan(1);
314
309
  // Pass if no error.
315
310
  });
316
311
 
317
312
  test.it(
318
313
  'should find first matching element when searching by ' +
319
314
  'compound CSS selector',
320
- function() {
321
- driver.get(Pages.xhtmlTestPage);
322
- var el = driver.findElement(By.css('div.extraDiv, div.content'));
323
- assert(el.getAttribute('class')).equalTo('content');
315
+ function*() {
316
+ yield driver.get(Pages.xhtmlTestPage);
317
+
318
+ let el =
319
+ yield driver.findElement(By.css('div.extraDiv, div.content'));
320
+ yield assert(el.getAttribute('class')).equalTo('content');
324
321
  });
325
322
 
326
323
  test.it('should be able to find multiple elements by compound selector',
327
- function() {
328
- driver.get(Pages.xhtmlTestPage);
329
- driver.findElements(By.css('div.extraDiv, div.content')).
330
- then(function(elements) {
331
- assertClassIs(elements[0], 'content');
332
- assertClassIs(elements[1], 'extraDiv');
333
-
334
- function assertClassIs(el, expected) {
335
- assert(el.getAttribute('class')).equalTo(expected);
336
- }
337
- });
324
+ function*() {
325
+ yield driver.get(Pages.xhtmlTestPage);
326
+ let elements =
327
+ yield driver.findElements(By.css('div.extraDiv, div.content'));
328
+
329
+ return Promise.all([
330
+ assertClassIs(elements[0], 'content'),
331
+ assertClassIs(elements[1], 'extraDiv')
332
+ ]);
333
+
334
+ function assertClassIs(el, expected) {
335
+ return assert(el.getAttribute('class')).equalTo(expected);
336
+ }
338
337
  });
339
338
 
340
339
  // IE only supports short version option[selected].
341
340
  test.ignore(browsers(Browser.IE)).
342
- it('should be able to find element by boolean attribute', function() {
343
- driver.get(test.whereIs(
341
+ it('should be able to find element by boolean attribute', function*() {
342
+ yield driver.get(test.whereIs(
344
343
  'locators_tests/boolean_attribute_selected.html'));
345
344
 
346
- var el = driver.findElement(By.css('option[selected="selected"]'));
347
- assert(el.getAttribute('value')).equalTo('two');
345
+ let el = yield driver.findElement(By.css('option[selected="selected"]'));
346
+ yield assert(el.getAttribute('value')).equalTo('two');
348
347
  });
349
348
 
350
349
  test.it(
351
350
  'should be able to find element with short ' +
352
351
  'boolean attribute selector',
353
- function() {
354
- driver.get(test.whereIs(
352
+ function*() {
353
+ yield driver.get(test.whereIs(
355
354
  'locators_tests/boolean_attribute_selected.html'));
356
355
 
357
- var el = driver.findElement(By.css('option[selected]'));
358
- assert(el.getAttribute('value')).equalTo('two');
356
+ let el = yield driver.findElement(By.css('option[selected]'));
357
+ yield assert(el.getAttribute('value')).equalTo('two');
359
358
  });
360
359
 
361
360
  test.it(
362
361
  'should be able to find element with short boolean attribute ' +
363
362
  'selector on HTML4 page',
364
- function() {
365
- driver.get(test.whereIs(
363
+ function*() {
364
+ yield driver.get(test.whereIs(
366
365
  'locators_tests/boolean_attribute_selected_html4.html'));
367
366
 
368
- var el = driver.findElement(By.css('option[selected]'));
369
- assert(el.getAttribute('value')).equalTo('two');
367
+ let el = yield driver.findElement(By.css('option[selected]'));
368
+ yield assert(el.getAttribute('value')).equalTo('two');
370
369
  });
371
370
  });
372
371
 
373
372
  describe('by custom locator', function() {
374
- test.it('handles single element result', function() {
375
- driver.get(Pages.javascriptPage);
373
+ test.it('handles single element result', function*() {
374
+ yield driver.get(Pages.javascriptPage);
376
375
 
377
- let link = driver.findElement(function(driver) {
376
+ let link = yield driver.findElement(function(driver) {
378
377
  let links = driver.findElements(By.tagName('a'));
379
378
  return promise.filter(links, function(link) {
380
379
  return link.getAttribute('id').then(id => id === 'updatediv');
381
380
  }).then(links => links[0]);
382
381
  });
383
382
 
384
- assert(link.getText()).isEqualTo('Update a div');
383
+ yield assert(link.getText()).matches(/Update\s+a\s+div/);
385
384
  });
386
385
 
387
- test.it('uses first element if locator resolves to list', function() {
388
- driver.get(Pages.javascriptPage);
386
+ test.it('uses first element if locator resolves to list', function*() {
387
+ yield driver.get(Pages.javascriptPage);
389
388
 
390
- let link = driver.findElement(function() {
389
+ let link = yield driver.findElement(function() {
391
390
  return driver.findElements(By.tagName('a'));
392
391
  });
393
392
 
394
- assert(link.getText()).isEqualTo('Change the page title!');
393
+ yield assert(link.getText()).isEqualTo('Change the page title!');
395
394
  });
396
395
 
397
- test.it('fails if locator returns non-webelement value', function() {
398
- driver.get(Pages.javascriptPage);
396
+ test.it('fails if locator returns non-webelement value', function*() {
397
+ yield driver.get(Pages.javascriptPage);
399
398
 
400
399
  let link = driver.findElement(function() {
401
400
  return driver.getTitle();
@@ -406,5 +405,22 @@ test.suite(function(env) {
406
405
  (e) => assert(e).instanceOf(TypeError));
407
406
  });
408
407
  });
408
+
409
+ describe('switchTo().activeElement()', function() {
410
+ // SAFARI's new session response does not identify it as a W3C browser,
411
+ // so the command is sent in the unsupported wire protocol format.
412
+ test.ignore(browsers(Browser.SAFARI)).
413
+ it('returns document.activeElement', function*() {
414
+ yield driver.get(Pages.formPage);
415
+
416
+ let email = yield driver.findElement(By.css('#email'));
417
+ yield driver.executeScript('arguments[0].focus()', email);
418
+
419
+ let ae = yield driver.switchTo().activeElement();
420
+ let equal = yield driver.executeScript(
421
+ 'return arguments[0] === arguments[1]', email, ae);
422
+ assert(equal).isTrue();
423
+ });
424
+ });
409
425
  });
410
426
  });