capybara-ng 0.2.3 → 0.2.4

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.
@@ -1,899 +0,0 @@
1
- module Angular
2
- #
3
- # TODO KI NOT USED
4
- #
5
- # Build the helper 'element' function for a given instance of Protractor.
6
- #
7
- # @private
8
- # @param {Protractor} ptor
9
- # @return {function(webdriver.Locator): ElementFinder}
10
- class ElementHelper
11
- def by_binding
12
- end
13
- end
14
- end
15
-
16
- <<-JS
17
-
18
- var buildElementHelper = function(ptor) {
19
-
20
- /**
21
- * ElementArrayFinder is used for operations on an array of elements (as opposed
22
- * to a single element).
23
- *
24
- * The ElementArrayFinder is used to set up a chain of conditions that identify
25
- * an array of elements. In particular, you can call all(locator) and
26
- * filter(filterFn) to return a new ElementArrayFinder modified by the
27
- * conditions, and you can call get(index) to return a single ElementFinder at
28
- * position 'index'.
29
- *
30
- * Similar to jquery, ElementArrayFinder will search all branches of the DOM
31
- * to find the elements that satify the conditions (i.e. all, filter, get).
32
- * However, an ElementArrayFinder will not actually retrieve the elements until
33
- * an action is called, which means it can be set up in helper files (i.e.
34
- * page objects) before the page is available, and reused as the page changes.
35
- *
36
- * You can treat an ElementArrayFinder as an array of WebElements for most
37
- * purposes, in particular, you may perform actions (i.e. click, getText) on
38
- * them as you would an array of WebElements. The action will apply to
39
- * every element identified by the ElementArrayFinder. ElementArrayFinder
40
- * extends Promise, and once an action is performed on an ElementArrayFinder,
41
- * the latest result can be accessed using then, and will be returned as an
42
- * array of the results; the array has length equal to the length of the
43
- * elements found by the ElementArrayFinder and each result represents the
44
- * result of performing the action on the element. Unlike a WebElement, an
45
- * ElementArrayFinder will wait for the angular app to settle before
46
- * performing finds or actions.
47
- *
48
- * @alias element.all(locator)
49
- * @view
50
- * <ul class="items">
51
- * <li>First</li>
52
- * <li>Second</li>
53
- * <li>Third</li>
54
- * </ul>
55
- *
56
- * @example
57
- * element.all(by.css('.items li')).then(function(items) {
58
- * expect(items.length).toBe(3);
59
- * expect(items[0].getText()).toBe('First');
60
- * });
61
- *
62
- * @constructor
63
- * @param {function(): Array.<webdriver.WebElement>} getWebElements A function
64
- * that returns a list of the underlying Web Elements.
65
- * @param {webdriver.Locator} locator The most relevant locator. It is only
66
- * used for error reporting and ElementArrayFinder.locator.
67
- * @param {Array.<webdriver.promise.Promise>} opt_actionResults An array
68
- * of promises which will be retrieved with then. Resolves to the latest
69
- * action result, or null if no action has been called.
70
- * @return {ElementArrayFinder}
71
- */
72
- var ElementArrayFinder = function(getWebElements, locator, opt_actionResults) {
73
- this.getWebElements = getWebElements || null;
74
- this.actionResults_ = opt_actionResults;
75
- this.locator_ = locator;
76
-
77
- var self = this;
78
- WEB_ELEMENT_FUNCTIONS.forEach(function(fnName) {
79
- self[fnName] = function() {
80
- var callerError = new Error();
81
- var args = arguments;
82
- var actionFn = function(webElem) {
83
- return webElem[fnName].apply(webElem, args).then(null, function(e) {
84
- e.stack = e.stack + '\n' + callerError.stack;
85
- throw e;
86
- });
87
- };
88
- return self.applyAction_(actionFn);
89
- };
90
- });
91
- };
92
- util.inherits(ElementArrayFinder, webdriver.promise.Promise);
93
-
94
- /**
95
- * Calls to ElementArrayFinder may be chained to find an array of elements
96
- * using the current elements in this ElementArrayFinder as the starting point.
97
- * This function returns a new ElementArrayFinder which would contain the
98
- * children elements found (and could also be empty).
99
- *
100
- * @alias element.all(locator).all(locator)
101
- * @view
102
- * <div id='id1' class="parent">
103
- * <ul>
104
- * <li class="foo">1a</li>
105
- * <li class="baz">1b</li>
106
- * </ul>
107
- * </div>
108
- * <div id='id2' class="parent">
109
- * <ul>
110
- * <li class="foo">2a</li>
111
- * <li class="bar">2b</li>
112
- * </ul>
113
- * </div>
114
- *
115
- * @example
116
- * var foo = element.all(by.css('.parent')).all(by.css('.foo'))
117
- * expect(foo.getText()).toEqual(['1a', '2a'])
118
- * var baz = element.all(by.css('.parent')).all(by.css('.baz'))
119
- * expect(baz.getText()).toEqual(['1b'])
120
- * var nonexistent = element.all(by.css('.parent')).all(by.css('.NONEXISTENT'))
121
- * expect(nonexistent.getText()).toEqual([''])
122
- *
123
- * @param {webdriver.Locator} subLocator
124
- * @return {ElementArrayFinder}
125
- */
126
- ElementArrayFinder.prototype.all = function(locator) {
127
- var self = this;
128
- var getWebElements = function() {
129
- if (self.getWebElements === null) {
130
- // This is the first time we are looking for an element
131
- return ptor.waitForAngular().then(function() {
132
- if (locator.findElementsOverride) {
133
- return locator.findElementsOverride(ptor.driver);
134
- } else {
135
- return ptor.driver.findElements(locator);
136
- }
137
- });
138
- } else {
139
- return self.getWebElements().then(function(parentWebElements) {
140
- var childrenPromiseList = [];
141
- // For each parent web element, find their children and construct a
142
- // list of Promise<List<child_web_element>>
143
- parentWebElements.forEach(function(parentWebElement) {
144
- var childrenPromise = locator.findElementsOverride ?
145
- locator.findElementsOverride(ptor.driver, parentWebElement) :
146
- parentWebElement.findElements(locator);
147
- childrenPromiseList.push(childrenPromise);
148
- });
149
-
150
-
151
- // Resolve the list of Promise<List<child_web_elements>> and merge into
152
- // a single list
153
- return webdriver.promise.all(childrenPromiseList).then(
154
- function(resolved) {
155
- var childrenList = [];
156
- resolved.forEach(function(resolvedE) {
157
- childrenList = childrenList.concat(resolvedE);
158
- });
159
- return childrenList;
160
- });
161
- });
162
- }
163
- };
164
- return new ElementArrayFinder(getWebElements, locator);
165
- };
166
-
167
- /**
168
- * Apply a filter function to each element within the ElementArrayFinder. Returns
169
- * a new ElementArrayFinder with all elements that pass the filter function. The
170
- * filter function receives the ElementFinder as the first argument
171
- * and the index as a second arg.
172
- * This does not actually retrieve the underlying list of elements, so it can
173
- * be used in page objects.
174
- *
175
- * @alias element.all(locator).filter(filterFn)
176
- * @view
177
- * <ul class="items">
178
- * <li class="one">First</li>
179
- * <li class="two">Second</li>
180
- * <li class="three">Third</li>
181
- * </ul>
182
- *
183
- * @example
184
- * element.all(by.css('.items li')).filter(function(elem, index) {
185
- * return elem.getText().then(function(text) {
186
- * return text === 'Third';
187
- * });
188
- * }).then(function(filteredElements) {
189
- * filteredElements[0].click();
190
- * });
191
- *
192
- * @param {function(ElementFinder, number): webdriver.WebElement.Promise} filterFn
193
- * Filter function that will test if an element should be returned.
194
- * filterFn can either return a boolean or a promise that resolves to a boolean.
195
- * @return {!ElementArrayFinder} A ElementArrayFinder that represents an array
196
- * of element that satisfy the filter function.
197
- */
198
- ElementArrayFinder.prototype.filter = function(filterFn) {
199
- var self = this;
200
- var getWebElements = function() {
201
- return self.getWebElements().then(function(parentWebElements) {
202
- var list = [];
203
- parentWebElements.forEach(function(parentWebElement, index) {
204
- var elementFinder = self.get(index); // Wrap in ElementFinder
205
- var filterResults = filterFn(elementFinder, index);
206
- if (filterResults instanceof webdriver.promise.Promise) {
207
- filterResults.then(function(satisfies) {
208
- if (satisfies) {
209
- list.push(parentWebElements[index]);
210
- }
211
- });
212
- } else if (filterResults) {
213
- list.push(parentWebElements[index]);
214
- }
215
- });
216
- return list;
217
- });
218
- };
219
- return new ElementArrayFinder(getWebElements, this.locator_);
220
- };
221
-
222
- /**
223
- * Get an element within the ElementArrayFinder by index. The index starts at 0.
224
- * This does not actually retrieve the underlying element.
225
- *
226
- * @alias element.all(locator).get(index)
227
- * @view
228
- * <ul class="items">
229
- * <li>First</li>
230
- * <li>Second</li>
231
- * <li>Third</li>
232
- * </ul>
233
- *
234
- * @example
235
- * var list = element.all(by.css('.items li'));
236
- * expect(list.get(0).getText()).toBe('First');
237
- * expect(list.get(1).getText()).toBe('Second');
238
- *
239
- * @param {number} index Element index.
240
- * @return {ElementFinder} finder representing element at the given index.
241
- */
242
- ElementArrayFinder.prototype.get = function(index) {
243
- var self = this;
244
- var getWebElements = function() {
245
- return self.getWebElements().then(function(parentWebElements) {
246
- if (index === -1) {
247
- // -1 is special and means last
248
- index = parentWebElements.length - 1;
249
- }
250
- if (index >= parentWebElements.length) {
251
- throw new Error('Index out of bound. Trying to access element at ' +
252
- 'index:' + index + ', but there are only ' +
253
- parentWebElements.length + ' elements');
254
- }
255
- return [parentWebElements[index]];
256
- });
257
- };
258
- return new ElementArrayFinder(getWebElements, this.locator_).toElementFinder_();
259
- };
260
-
261
- /**
262
- * Get the first matching element for the ElementArrayFinder. This does not
263
- * actually retrieve the underlying element.
264
- *
265
- * @alias element.all(locator).first()
266
- * @view
267
- * <ul class="items">
268
- * <li>First</li>
269
- * <li>Second</li>
270
- * <li>Third</li>
271
- * </ul>
272
- *
273
- * @example
274
- * var first = element.all(by.css('.items li')).first();
275
- * expect(first.getText()).toBe('First');
276
- *
277
- * @return {ElementFinder} finder representing the first matching element
278
- */
279
- ElementArrayFinder.prototype.first = function() {
280
- return this.get(0);
281
- };
282
-
283
- /**
284
- * Get the last matching element for the ElementArrayFinder. This does not
285
- * actually retrieve the underlying element.
286
- *
287
- * @alias element.all(locator).last()
288
- * @view
289
- * <ul class="items">
290
- * <li>First</li>
291
- * <li>Second</li>
292
- * <li>Third</li>
293
- * </ul>
294
- *
295
- * @example
296
- * var last = element.all(by.css('.items li')).last();
297
- * expect(last.getText()).toBe('Third');
298
- *
299
- * @return {ElementFinder} finder representing the last matching element
300
- */
301
- ElementArrayFinder.prototype.last = function() {
302
- return this.get(-1);
303
- };
304
-
305
- /**
306
- * Shorthand function for finding arrays of elements by css.
307
- *
308
- * @type {function(string): ElementArrayFinder}
309
- */
310
- ElementArrayFinder.prototype.$$ = function(selector) {
311
- return this.all(webdriver.By.css(selector));
312
- };
313
-
314
- /**
315
- * Returns an ElementFinder representation of ElementArrayFinder. It ensures
316
- * that the ElementArrayFinder resolves to one and only one underlying element.
317
- *
318
- * @return {ElementFinder} An ElementFinder representation
319
- * @private
320
- */
321
- ElementArrayFinder.prototype.toElementFinder_ = function() {
322
- return new ElementFinder(this);
323
- };
324
-
325
- /**
326
- * Count the number of elements represented by the ElementArrayFinder.
327
- *
328
- * @alias element.all(locator).count()
329
- * @view
330
- * <ul class="items">
331
- * <li>First</li>
332
- * <li>Second</li>
333
- * <li>Third</li>
334
- * </ul>
335
- *
336
- * @example
337
- * var list = element.all(by.css('.items li'));
338
- * expect(list.count()).toBe(3);
339
- *
340
- * @return {!webdriver.promise.Promise} A promise which resolves to the
341
- * number of elements matching the locator.
342
- */
343
- ElementArrayFinder.prototype.count = function() {
344
- return this.getWebElements().then(function(arr) {
345
- return arr.length;
346
- }, function(err) {
347
- if (err.code == webdriver.error.ErrorCode.NO_SUCH_ELEMENT) {
348
- return 0;
349
- } else {
350
- throw err;
351
- }
352
- });
353
- };
354
-
355
- /**
356
- * Returns the most relevant locator.
357
- * i.e.
358
- * $('#ID1').locator() returns by.css('#ID1')
359
- * $('#ID1').$('#ID2').locator() returns by.css('#ID2')
360
- * $$('#ID1').filter(filterFn).get(0).click().locator() returns by.css('#ID1')
361
- * @return {webdriver.Locator}
362
- */
363
- ElementArrayFinder.prototype.locator = function() {
364
- return this.locator_;
365
- };
366
-
367
- /**
368
- * Apply an action function to every element in the ElementArrayFinder,
369
- * and return a new ElementArrayFinder that contains the results of the actions.
370
- *
371
- * @param {function(ElementFinder)} actionFn
372
- *
373
- * @return {ElementArrayFinder}
374
- * @private
375
- */
376
- ElementArrayFinder.prototype.applyAction_ = function(actionFn) {
377
- var actionResults = this.getWebElements().then(function(arr) {
378
- var list = [];
379
- arr.forEach(function(webElem) {
380
- list.push(actionFn(webElem));
381
- });
382
- return webdriver.promise.all(list);
383
- });
384
- return new ElementArrayFinder(this.getWebElements, this.locator_, actionResults);
385
- };
386
-
387
- /**
388
- * Represents the ElementArrayFinder as an array of ElementFinders.
389
- *
390
- * @return {Array.<ElementFinder>} Return a promise, which resolves to a list
391
- * of ElementFinders specified by the locator.
392
- */
393
- ElementArrayFinder.prototype.asElementFinders_ = function() {
394
- var self = this;
395
- return this.getWebElements().then(function(arr) {
396
- var list = [];
397
- arr.forEach(function(webElem, index) {
398
- list.push(self.get(index));
399
- });
400
- return list;
401
- });
402
- };
403
-
404
- /**
405
- * Retrieve the elements represented by the ElementArrayFinder. The input
406
- * function is passed to the resulting promise, which resolves to an
407
- * array of ElementFinders.
408
- *
409
- * @alias element.all(locator).then(thenFunction)
410
- * @view
411
- * <ul class="items">
412
- * <li>First</li>
413
- * <li>Second</li>
414
- * <li>Third</li>
415
- * </ul>
416
- *
417
- * @example
418
- * element.all(by.css('.items li')).then(function(arr) {
419
- * expect(arr.length).toEqual(3);
420
- * });
421
- *
422
- * @param {function(Array.<ElementFinder>)} fn
423
- * @param {function(Error)} errorFn
424
- *
425
- * @type {webdriver.promise.Promise} a promise which will resolve to
426
- * an array of ElementFinders represented by the ElementArrayFinder.
427
- */
428
- ElementArrayFinder.prototype.then = function(fn, errorFn) {
429
- if (this.actionResults_) {
430
- return this.actionResults_.then(fn, errorFn);
431
- } else {
432
- return this.asElementFinders_().then(fn, errorFn);
433
- }
434
- };
435
-
436
- /**
437
- * Calls the input function on each ElementFinder represented by the ElementArrayFinder.
438
- *
439
- * @alias element.all(locator).each(eachFunction)
440
- * @view
441
- * <ul class="items">
442
- * <li>First</li>
443
- * <li>Second</li>
444
- * <li>Third</li>
445
- * </ul>
446
- *
447
- * @example
448
- * element.all(by.css('.items li')).each(function(element) {
449
- * // Will print First, Second, Third.
450
- * element.getText().then(console.log);
451
- * });
452
- *
453
- * @param {function(ElementFinder)} fn Input function
454
- */
455
- ElementArrayFinder.prototype.each = function(fn) {
456
- return this.asElementFinders_().then(function(arr) {
457
- arr.forEach(function(elementFinder, index) {
458
- fn(elementFinder, index);
459
- });
460
- });
461
- };
462
-
463
- /**
464
- * Apply a map function to each element within the ElementArrayFinder. The
465
- * callback receives the ElementFinder as the first argument and the index as
466
- * a second arg.
467
- *
468
- * @alias element.all(locator).map(mapFunction)
469
- * @view
470
- * <ul class="items">
471
- * <li class="one">First</li>
472
- * <li class="two">Second</li>
473
- * <li class="three">Third</li>
474
- * </ul>
475
- *
476
- * @example
477
- * var items = element.all(by.css('.items li')).map(function(elm, index) {
478
- * return {
479
- * index: index,
480
- * text: elm.getText(),
481
- * class: elm.getAttribute('class')
482
- * };
483
- * });
484
- * expect(items).toEqual([
485
- * {index: 0, text: 'First', class: 'one'},
486
- * {index: 1, text: 'Second', class: 'two'},
487
- * {index: 2, text: 'Third', class: 'three'}
488
- * ]);
489
- *
490
- * @param {function(ElementFinder, number)} mapFn Map function that
491
- * will be applied to each element.
492
- * @return {!webdriver.promise.Promise} A promise that resolves to an array
493
- * of values returned by the map function.
494
- */
495
- ElementArrayFinder.prototype.map = function(mapFn) {
496
- return this.asElementFinders_().then(function(arr) {
497
- var list = [];
498
- arr.forEach(function(elementFinder, index) {
499
- var mapResult = mapFn(elementFinder, index);
500
- // All nested arrays and objects will also be fully resolved.
501
- webdriver.promise.fullyResolved(mapResult).then(function(resolved) {
502
- list.push(resolved);
503
- });
504
- });
505
- return list;
506
- });
507
- };
508
-
509
- /**
510
- * Apply a reduce function against an accumulator and every element found
511
- * using the locator (from left-to-right). The reduce function has to reduce
512
- * every element into a single value (the accumulator). Returns promise of
513
- * the accumulator. The reduce function receives the accumulator, current
514
- * ElementFinder, the index, and the entire array of ElementFinders,
515
- * respectively.
516
- *
517
- * @alias element.all(locator).reduce(reduceFn)
518
- * @view
519
- * <ul class="items">
520
- * <li class="one">First</li>
521
- * <li class="two">Second</li>
522
- * <li class="three">Third</li>
523
- * </ul>
524
- *
525
- * @example
526
- * var value = element.all(by.css('.items li')).reduce(function(acc, elem) {
527
- * return elem.getText().then(function(text) {
528
- * return acc + text + ' ';
529
- * });
530
- * });
531
- *
532
- * expect(value).toEqual('First Second Third ');
533
- *
534
- * @param {function(number, ElementFinder, number, Array.<ElementFinder>)}
535
- * reduceFn Reduce function that reduces every element into a single value.
536
- * @param {*} initialValue Initial value of the accumulator.
537
- * @return {!webdriver.promise.Promise} A promise that resolves to the final
538
- * value of the accumulator.
539
- */
540
- ElementArrayFinder.prototype.reduce = function(reduceFn, initialValue) {
541
- var valuePromise = webdriver.promise.fulfilled(initialValue);
542
- return this.asElementFinders_().then(function(arr) {
543
- arr.forEach(function(elementFinder, index) {
544
- valuePromise = valuePromise.then(function(value) {
545
- return reduceFn(value, elementFinder, index, arr);
546
- });
547
- });
548
- return valuePromise;
549
- });
550
- };
551
-
552
- /**
553
- * Evaluates the input as if it were on the scope of the current underlying
554
- * elements.
555
- * @param {string} expression
556
- *
557
- * @return {ElementArrayFinder} which resolves to the
558
- * evaluated expression for each underlying element.
559
- * The result will be resolved as in
560
- * {@link webdriver.WebDriver.executeScript}. In summary - primitives will
561
- * be resolved as is, functions will be converted to string, and elements
562
- * will be returned as a WebElement.
563
- */
564
- ElementArrayFinder.prototype.evaluate = function(expression) {
565
- var evaluationFn = function(webElem) {
566
- return webElem.getDriver().executeScript(
567
- clientSideScripts.evaluate, webElem, expression);
568
- };
569
- return this.applyAction_(evaluationFn);
570
- };
571
-
572
- /**
573
- * Determine if animation is allowed on the current underlying elements.
574
- * @param {string} value
575
- *
576
- * @return {ElementArrayFinder} which resolves to whether animation is allowed.
577
- */
578
- ElementArrayFinder.prototype.allowAnimations = function(value) {
579
- var allowAnimationsTestFn = function(webElem) {
580
- return webElem.getDriver().executeScript(
581
- clientSideScripts.allowAnimations, webElem, value);
582
- };
583
- return this.applyAction_(allowAnimationsTestFn);
584
- };
585
-
586
- /**
587
- * The ElementFinder simply represents a single element of an
588
- * ElementArrayFinder (and is more like a convenience object). As a result,
589
- * anything that can be done with an ElementFinder, can also be done using
590
- * an ElementArrayFinder.
591
- *
592
- * The ElementFinder can be treated as a WebElement for most purposes, in
593
- * particular, you may perform actions (i.e. click, getText) on them as you
594
- * would a WebElement. ElementFinders extend Promise, and once an action
595
- * is performed on an ElementFinder, the latest result from the chain can be
596
- * accessed using then. Unlike a WebElement, an ElementFinder will wait for
597
- * angular to settle before performing finds or actions.
598
- *
599
- * ElementFinder can be used to build a chain of locators that is used to find
600
- * an element. An ElementFinder does not actually attempt to find the element
601
- * until an action is called, which means they can be set up in helper files
602
- * before the page is available.
603
- *
604
- * @alias element(locator)
605
- * @view
606
- * <span>{{person.name}}</span>
607
- * <span ng-bind="person.email"></span>
608
- * <input type="text" ng-model="person.name"/>
609
- *
610
- * @example
611
- * // Find element with {{scopeVar}} syntax.
612
- * element(by.binding('person.name')).getText().then(function(name) {
613
- * expect(name).toBe('Foo');
614
- * });
615
- *
616
- * // Find element with ng-bind="scopeVar" syntax.
617
- * expect(element(by.binding('person.email')).getText()).toBe('foo@bar.com');
618
- *
619
- * // Find by model.
620
- * var input = element(by.model('person.name'));
621
- * input.sendKeys('123');
622
- * expect(input.getAttribute('value')).toBe('Foo123');
623
- *
624
- * @constructor
625
- * @param {ElementArrayFinder} elementArrayFinder The ElementArrayFinder
626
- * that this is branched from.
627
- * @return {ElementFinder}
628
- */
629
- var ElementFinder = function(elementArrayFinder) {
630
- if (!elementArrayFinder) {
631
- throw new Error('BUG: elementArrayFinder cannot be empty');
632
- }
633
- this.parentElementArrayFinder = elementArrayFinder;
634
-
635
- // This filter verifies that there is only 1 element returned by the
636
- // elementArrayFinder. It will warn if there are more than 1 element and
637
- // throw an error if there are no elements.
638
- var getWebElements = function() {
639
- return elementArrayFinder.getWebElements().then(function(webElements) {
640
- if (webElements.length === 0) {
641
- throw new webdriver.error.Error(
642
- webdriver.error.ErrorCode.NO_SUCH_ELEMENT,
643
- 'No element found using locator: ' +
644
- elementArrayFinder.locator_.toString());
645
- } else {
646
- if (webElements.length > 1) {
647
- console.log('warning: more than one element found for locator ' +
648
- elementArrayFinder.locator_.toString() +
649
- ' - you may need to be more specific');
650
- }
651
- return [webElements[0]];
652
- }
653
- });
654
- };
655
-
656
- // Store a copy of the underlying elementArrayFinder, but with the more
657
- // restrictive getWebElements (which checks that there is only 1 element).
658
- this.elementArrayFinder_ = new ElementArrayFinder(
659
- getWebElements, elementArrayFinder.locator_,
660
- elementArrayFinder.actionResults_);
661
-
662
- // Decorate ElementFinder with webdriver functions. Simply calls the
663
- // underlying elementArrayFinder to perform these functions.
664
- var self = this;
665
- WEB_ELEMENT_FUNCTIONS.forEach(function(fnName) {
666
- self[fnName] = function() {
667
- return self.elementArrayFinder_[fnName].
668
- apply(self.elementArrayFinder_, arguments).toElementFinder_();
669
- };
670
- });
671
- };
672
- util.inherits(ElementFinder, webdriver.promise.Promise);
673
-
674
- /**
675
- * See ElementArrayFinder.prototype.locator
676
- * @return {webdriver.Locator}
677
- */
678
- ElementFinder.prototype.locator = function() {
679
- return this.elementArrayFinder_.locator();
680
- };
681
-
682
- /**
683
- * Returns the WebElement represented by this ElementFinder.
684
- * Throws the WebDriver error if the element doesn't exist.
685
- *
686
- * @example
687
- * The following three expressions are equivalent.
688
- * - element(by.css('.parent')).getWebElement();
689
- * - browser.waitForAngular(); browser.driver.findElement(by.css('.parent'));
690
- * - browser.findElement(by.css('.parent'))
691
- *
692
- * @alias element(locator).getWebElement()
693
- * @return {webdriver.WebElement}
694
- */
695
- ElementFinder.prototype.getWebElement = function() {
696
- var id = this.elementArrayFinder_.getWebElements().then(
697
- function(parentWebElements) {
698
- return parentWebElements[0];
699
- });
700
- return new webdriver.WebElementPromise(ptor.driver, id);
701
- };
702
-
703
- /**
704
- * Access the underlying actionResult of ElementFinder. Implementation allows
705
- * ElementFinder to be used as a webdriver.promise.Promise
706
- * @param {function(webdriver.promise.Promise)} fn Function which takes
707
- * the value of the underlying actionResult.
708
- *
709
- * @return {webdriver.promise.Promise} Promise which contains the results of
710
- * evaluating fn.
711
- */
712
- ElementFinder.prototype.then = function(fn, errorFn) {
713
- return this.elementArrayFinder_.then(function(actionResults) {
714
- return fn(actionResults[0]);
715
- }, errorFn);
716
- };
717
-
718
- /**
719
- * Calls to element may be chained to find an array of elements within a parent.
720
- *
721
- * @alias element(locator).all(locator)
722
- * @view
723
- * <div class="parent">
724
- * <ul>
725
- * <li class="one">First</li>
726
- * <li class="two">Second</li>
727
- * <li class="three">Third</li>
728
- * </ul>
729
- * </div>
730
- *
731
- * @example
732
- * var items = element(by.css('.parent')).all(by.tagName('li'))
733
- *
734
- * @param {webdriver.Locator} subLocator
735
- * @return {ElementArrayFinder}
736
- */
737
- ElementFinder.prototype.all = function(subLocator) {
738
- return this.elementArrayFinder_.all(subLocator);
739
- };
740
-
741
- /**
742
- * Calls to element may be chained to find elements within a parent.
743
- *
744
- * @alias element(locator).element(locator)
745
- * @view
746
- * <div class="parent">
747
- * <div class="child">
748
- * Child text
749
- * <div>{{person.phone}}</div>
750
- * </div>
751
- * </div>
752
- *
753
- * @example
754
- * // Chain 2 element calls.
755
- * var child = element(by.css('.parent')).
756
- * element(by.css('.child'));
757
- * expect(child.getText()).toBe('Child text\n555-123-4567');
758
- *
759
- * // Chain 3 element calls.
760
- * var triple = element(by.css('.parent')).
761
- * element(by.css('.child')).
762
- * element(by.binding('person.phone'));
763
- * expect(triple.getText()).toBe('555-123-4567');
764
- *
765
- * @param {webdriver.Locator} subLocator
766
- * @return {ElementFinder}
767
- */
768
- ElementFinder.prototype.element = function(subLocator) {
769
- return this.all(subLocator).toElementFinder_();
770
- };
771
-
772
- /**
773
- * Shortcut for querying the document directly with css.
774
- *
775
- * @alias $$(cssSelector)
776
- * @view
777
- * <div class="count">
778
- * <span class="one">First</span>
779
- * <span class="two">Second</span>
780
- * </div>
781
- *
782
- * @example
783
- * // The following protractor expressions are equivalent.
784
- * var list = element.all(by.css('.count span'));
785
- * expect(list.count()).toBe(2);
786
- *
787
- * list = $$('.count span');
788
- * expect(list.count()).toBe(2);
789
- * expect(list.get(0).getText()).toBe('First');
790
- * expect(list.get(1).getText()).toBe('Second');
791
- *
792
- * @param {string} selector a css selector
793
- * @return {ElementArrayFinder} which identifies the
794
- * array of the located {@link webdriver.WebElement}s.
795
- */
796
- ElementFinder.prototype.$$ = function(selector) {
797
- return this.all(webdriver.By.css(selector));
798
- };
799
-
800
- /**
801
- * Shortcut for querying the document directly with css.
802
- *
803
- * @alias $(cssSelector)
804
- * @view
805
- * <div class="count">
806
- * <span class="one">First</span>
807
- * <span class="two">Second</span>
808
- * </div>
809
- *
810
- * @example
811
- * var item = $('.count .two');
812
- * expect(item.getText()).toBe('Second');
813
- *
814
- * @param {string} selector A css selector
815
- * @return {ElementFinder} which identifies the located
816
- * {@link webdriver.WebElement}
817
- */
818
- ElementFinder.prototype.$ = function(selector) {
819
- return this.element(webdriver.By.css(selector));
820
- };
821
-
822
- /**
823
- * Determine whether the element is present on the page.
824
- *
825
- * @view
826
- * <span>{{person.name}}</span>
827
- *
828
- * @example
829
- * // Element exists.
830
- * expect(element(by.binding('person.name')).isPresent()).toBe(true);
831
- *
832
- * // Element not present.
833
- * expect(element(by.binding('notPresent')).isPresent()).toBe(false);
834
- *
835
- * @return {ElementFinder} which resolves to whether
836
- * the element is present on the page.
837
- */
838
- ElementFinder.prototype.isPresent = function() {
839
- return this.parentElementArrayFinder.count().then(function(count) {
840
- return !!count;
841
- });
842
- };
843
-
844
- /**
845
- * Override for WebElement.prototype.isElementPresent so that protractor waits
846
- * for Angular to settle before making the check.
847
- *
848
- * @see ElementFinder.isPresent
849
- *
850
- * @param {webdriver.Locator} subLocator Locator for element to look for.
851
- * @return {ElementFinder} which resolves to whether
852
- * the element is present on the page.
853
- */
854
- ElementFinder.prototype.isElementPresent = function(subLocator) {
855
- return this.element(subLocator).isPresent();
856
- };
857
-
858
- /**
859
- * Evaluates the input as if it were on the scope of the current element.
860
- * @param {string} expression
861
- *
862
- * @return {ElementFinder} which resolves to the evaluated expression.
863
- */
864
- ElementFinder.prototype.evaluate = function(expression) {
865
- return this.elementArrayFinder_.evaluate(expression).toElementFinder_();
866
- };
867
-
868
- /**
869
- * See ElementArrayFinder.prototype.allowAnimations.
870
- * @param {string} value
871
- *
872
- * @return {ElementFinder} which resolves to whether animation is allowed.
873
- */
874
- ElementFinder.prototype.allowAnimations = function(value) {
875
- return this.elementArrayFinder_.allowAnimations(value).toElementFinder_();
876
- };
877
-
878
- /**
879
- * Webdriver relies on this function to be present on Promises, so adding
880
- * this dummy function as we inherited from webdriver.promise.Promise, but
881
- * this function is irrelevant to our usage
882
- *
883
- * @return {boolean} Always false as ElementFinder is never in pending state.
884
- */
885
- ElementFinder.prototype.isPending = function() {
886
- return false;
887
- };
888
-
889
- var element = function(locator) {
890
- return new ElementArrayFinder().all(locator).toElementFinder_();
891
- };
892
-
893
- element.all = function(locator) {
894
- return new ElementArrayFinder().all(locator);
895
- };
896
-
897
- return element;
898
- };
899
- JS