1 |
|
2 |
|
3 |
|
4 |
|
5 |
|
6 |
|
7 |
|
8 |
|
9 |
|
10 |
|
11 |
|
12 |
|
13 |
|
14 |
|
15 |
|
16 |
|
17 | var functions = {};
|
18 |
|
19 |
|
20 |
|
21 |
|
22 |
|
23 |
|
24 |
|
25 |
|
26 |
|
27 |
|
28 |
|
29 |
|
30 |
|
31 |
|
32 |
|
33 |
|
34 |
|
35 | function wrapWithHelpers(fun) {
|
36 | var helpers = Array.prototype.slice.call(arguments, 1);
|
37 | if (!helpers.length) {
|
38 | return fun;
|
39 | }
|
40 | var FunClass = Function;
|
41 | return new FunClass(
|
42 | helpers.join(';') + String.fromCharCode(59) +
|
43 | ' return (' + fun.toString() + ').apply(this, arguments);');
|
44 | }
|
45 |
|
46 |
|
47 |
|
48 |
|
49 |
|
50 |
|
51 |
|
52 |
|
53 |
|
54 |
|
55 | function repeaterMatch(ngRepeat, repeater, exact) {
|
56 | if (exact) {
|
57 | return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].
|
58 | split('=')[0].trim() == repeater;
|
59 | } else {
|
60 | return ngRepeat.indexOf(repeater) != -1;
|
61 | }
|
62 | }
|
63 |
|
64 |
|
65 |
|
66 |
|
67 |
|
68 |
|
69 |
|
70 |
|
71 |
|
72 |
|
73 |
|
74 |
|
75 | function getNg1Hooks(selector, injectorPlease) {
|
76 | function tryEl(el) {
|
77 | try {
|
78 | if (!injectorPlease && angular.getTestability) {
|
79 | var $$testability = angular.getTestability(el);
|
80 | if ($$testability) {
|
81 | return {$$testability: $$testability};
|
82 | }
|
83 | } else {
|
84 | var $injector = angular.element(el).injector();
|
85 | if ($injector) {
|
86 | return {$injector: $injector};
|
87 | }
|
88 | }
|
89 | } catch(err) {}
|
90 | }
|
91 | function trySelector(selector) {
|
92 | var els = document.querySelectorAll(selector);
|
93 | for (var i = 0; i < els.length; i++) {
|
94 | var elHooks = tryEl(els[i]);
|
95 | if (elHooks) {
|
96 | return elHooks;
|
97 | }
|
98 | }
|
99 | }
|
100 |
|
101 | if (selector) {
|
102 | return trySelector(selector);
|
103 | } else if (window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__) {
|
104 | var $injector = window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__;
|
105 | var $$testability = null;
|
106 | try {
|
107 | $$testability = $injector.get('$$testability');
|
108 | } catch (e) {}
|
109 | return {$injector: $injector, $$testability: $$testability};
|
110 | } else {
|
111 | return tryEl(document.body) ||
|
112 | trySelector('[ng-app]') || trySelector('[ng\\:app]') ||
|
113 | trySelector('[ng-controller]') || trySelector('[ng\\:controller]');
|
114 | }
|
115 | }
|
116 |
|
117 |
|
118 |
|
119 |
|
120 |
|
121 |
|
122 |
|
123 |
|
124 |
|
125 |
|
126 |
|
127 |
|
128 |
|
129 |
|
130 |
|
131 |
|
132 |
|
133 |
|
134 |
|
135 | functions.waitForAngular = function(rootSelector, callback) {
|
136 |
|
137 | try {
|
138 |
|
139 |
|
140 | var testCallback = callback;
|
141 |
|
142 |
|
143 | var waitForAngular1 = function(callback) {
|
144 |
|
145 | if (window.angular) {
|
146 | var hooks = getNg1Hooks(rootSelector);
|
147 | if (!hooks){
|
148 | callback();
|
149 | }
|
150 | else{
|
151 | if (hooks.$$testability) {
|
152 | hooks.$$testability.whenStable(callback);
|
153 | } else if (hooks.$injector) {
|
154 | hooks.$injector.get('$browser')
|
155 | .notifyWhenNoOutstandingRequests(callback);
|
156 | } else if (!rootSelector) {
|
157 | throw new Error(
|
158 | 'Could not automatically find injector on page: "' +
|
159 | window.location.toString() + '". Consider using config.rootEl');
|
160 | } else {
|
161 | throw new Error(
|
162 | 'root element (' + rootSelector + ') has no injector.' +
|
163 | ' this may mean it is not inside ng-app.');
|
164 | }
|
165 | }
|
166 | }
|
167 | else {callback();}
|
168 | };
|
169 |
|
170 |
|
171 | var waitForAngular2 = function() {
|
172 | if (window.getAngularTestability) {
|
173 | if (rootSelector) {
|
174 | var testability = null;
|
175 | var el = document.querySelector(rootSelector);
|
176 | try{
|
177 | testability = window.getAngularTestability(el);
|
178 | }
|
179 | catch(e){}
|
180 | if (testability) {
|
181 | testability.whenStable(testCallback);
|
182 | return;
|
183 | }
|
184 | }
|
185 |
|
186 |
|
187 |
|
188 |
|
189 | var testabilities = window.getAllAngularTestabilities();
|
190 | var count = testabilities.length;
|
191 |
|
192 |
|
193 |
|
194 | if (count === 0) {
|
195 | testCallback();
|
196 | return;
|
197 | }
|
198 |
|
199 | var decrement = function() {
|
200 | count--;
|
201 | if (count === 0) {
|
202 | testCallback();
|
203 | }
|
204 | };
|
205 | testabilities.forEach(function(testability) {
|
206 | testability.whenStable(decrement);
|
207 | });
|
208 |
|
209 | }
|
210 | else {testCallback();}
|
211 | };
|
212 |
|
213 | if (!(window.angular) && !(window.getAngularTestability)) {
|
214 |
|
215 | throw new Error(
|
216 | 'both angularJS testability and angular testability are undefined.' +
|
217 | ' This could be either ' +
|
218 | 'because this is a non-angular page or because your test involves ' +
|
219 | 'client-side navigation, which can interfere with Protractor\'s ' +
|
220 | 'bootstrapping. See http://git.io/v4gXM for details');
|
221 | } else {waitForAngular1(waitForAngular2);}
|
222 |
|
223 |
|
224 | } catch (err) {
|
225 | callback(err.message);
|
226 | }
|
227 |
|
228 | };
|
229 |
|
230 |
|
231 |
|
232 |
|
233 |
|
234 |
|
235 |
|
236 |
|
237 |
|
238 |
|
239 |
|
240 | functions.findBindings = function(binding, exactMatch, using, rootSelector) {
|
241 | using = using || document;
|
242 | if (angular.getTestability) {
|
243 | return getNg1Hooks(rootSelector).$$testability.
|
244 | findBindings(using, binding, exactMatch);
|
245 | }
|
246 | var bindings = using.getElementsByClassName('ng-binding');
|
247 | var matches = [];
|
248 | for (var i = 0; i < bindings.length; ++i) {
|
249 | var dataBinding = angular.element(bindings[i]).data('$binding');
|
250 | if (dataBinding) {
|
251 | var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
|
252 | if (exactMatch) {
|
253 | var matcher = new RegExp('({|\\s|^|\\|)' +
|
254 |
|
255 | binding.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') +
|
256 | '(}|\\s|$|\\|)');
|
257 | if (matcher.test(bindingName)) {
|
258 | matches.push(bindings[i]);
|
259 | }
|
260 | } else {
|
261 | if (bindingName.indexOf(binding) != -1) {
|
262 | matches.push(bindings[i]);
|
263 | }
|
264 | }
|
265 |
|
266 | }
|
267 | }
|
268 | return matches;
|
269 | };
|
270 |
|
271 |
|
272 |
|
273 |
|
274 |
|
275 |
|
276 |
|
277 |
|
278 |
|
279 |
|
280 |
|
281 |
|
282 |
|
283 |
|
284 | function findRepeaterRows(repeater, exact, index, using) {
|
285 | using = using || document;
|
286 |
|
287 | var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
|
288 | var rows = [];
|
289 | for (var p = 0; p < prefixes.length; ++p) {
|
290 | var attr = prefixes[p] + 'repeat';
|
291 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
292 | attr = attr.replace(/\\/g, '');
|
293 | for (var i = 0; i < repeatElems.length; ++i) {
|
294 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
295 | rows.push(repeatElems[i]);
|
296 | }
|
297 | }
|
298 | }
|
299 | |
300 |
|
301 | var multiRows = [];
|
302 | for (var p = 0; p < prefixes.length; ++p) {
|
303 | var attr = prefixes[p] + 'repeat-start';
|
304 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
305 | attr = attr.replace(/\\/g, '');
|
306 | for (var i = 0; i < repeatElems.length; ++i) {
|
307 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
308 | var elem = repeatElems[i];
|
309 | var row = [];
|
310 | while (elem.nodeType != 8 ||
|
311 | !repeaterMatch(elem.nodeValue, repeater)) {
|
312 | if (elem.nodeType == 1) {
|
313 | row.push(elem);
|
314 | }
|
315 | elem = elem.nextSibling;
|
316 | }
|
317 | multiRows.push(row);
|
318 | }
|
319 | }
|
320 | }
|
321 | var row = rows[index] || [], multiRow = multiRows[index] || [];
|
322 | return [].concat(row, multiRow);
|
323 | }
|
324 | functions.findRepeaterRows = wrapWithHelpers(findRepeaterRows, repeaterMatch);
|
325 |
|
326 | |
327 |
|
328 |
|
329 |
|
330 |
|
331 |
|
332 |
|
333 |
|
334 |
|
335 | function findAllRepeaterRows(repeater, exact, using) {
|
336 | using = using || document;
|
337 |
|
338 | var rows = [];
|
339 | var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
|
340 | for (var p = 0; p < prefixes.length; ++p) {
|
341 | var attr = prefixes[p] + 'repeat';
|
342 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
343 | attr = attr.replace(/\\/g, '');
|
344 | for (var i = 0; i < repeatElems.length; ++i) {
|
345 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
346 | rows.push(repeatElems[i]);
|
347 | }
|
348 | }
|
349 | }
|
350 | for (var p = 0; p < prefixes.length; ++p) {
|
351 | var attr = prefixes[p] + 'repeat-start';
|
352 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
353 | attr = attr.replace(/\\/g, '');
|
354 | for (var i = 0; i < repeatElems.length; ++i) {
|
355 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
356 | var elem = repeatElems[i];
|
357 | while (elem.nodeType != 8 ||
|
358 | !repeaterMatch(elem.nodeValue, repeater)) {
|
359 | if (elem.nodeType == 1) {
|
360 | rows.push(elem);
|
361 | }
|
362 | elem = elem.nextSibling;
|
363 | }
|
364 | }
|
365 | }
|
366 | }
|
367 | return rows;
|
368 | }
|
369 | functions.findAllRepeaterRows = wrapWithHelpers(findAllRepeaterRows, repeaterMatch);
|
370 |
|
371 |
|
372 |
|
373 |
|
374 |
|
375 |
|
376 |
|
377 |
|
378 |
|
379 |
|
380 |
|
381 |
|
382 |
|
383 | function findRepeaterElement(repeater, exact, index, binding, using, rootSelector) {
|
384 | var matches = [];
|
385 | using = using || document;
|
386 |
|
387 | var rows = [];
|
388 | var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
|
389 | for (var p = 0; p < prefixes.length; ++p) {
|
390 | var attr = prefixes[p] + 'repeat';
|
391 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
392 | attr = attr.replace(/\\/g, '');
|
393 | for (var i = 0; i < repeatElems.length; ++i) {
|
394 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
395 | rows.push(repeatElems[i]);
|
396 | }
|
397 | }
|
398 | }
|
399 | |
400 |
|
401 | var multiRows = [];
|
402 | for (var p = 0; p < prefixes.length; ++p) {
|
403 | var attr = prefixes[p] + 'repeat-start';
|
404 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
405 | attr = attr.replace(/\\/g, '');
|
406 | for (var i = 0; i < repeatElems.length; ++i) {
|
407 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
408 | var elem = repeatElems[i];
|
409 | var row = [];
|
410 | while (elem.nodeType != 8 || (elem.nodeValue &&
|
411 | !repeaterMatch(elem.nodeValue, repeater))) {
|
412 | if (elem.nodeType == 1) {
|
413 | row.push(elem);
|
414 | }
|
415 | elem = elem.nextSibling;
|
416 | }
|
417 | multiRows.push(row);
|
418 | }
|
419 | }
|
420 | }
|
421 | var row = rows[index];
|
422 | var multiRow = multiRows[index];
|
423 | var bindings = [];
|
424 | if (row) {
|
425 | if (angular.getTestability) {
|
426 | matches.push.apply(
|
427 | matches,
|
428 | getNg1Hooks(rootSelector).$$testability.findBindings(row, binding));
|
429 | } else {
|
430 | if (row.className.indexOf('ng-binding') != -1) {
|
431 | bindings.push(row);
|
432 | }
|
433 | var childBindings = row.getElementsByClassName('ng-binding');
|
434 | for (var i = 0; i < childBindings.length; ++i) {
|
435 | bindings.push(childBindings[i]);
|
436 | }
|
437 | }
|
438 | }
|
439 | if (multiRow) {
|
440 | for (var i = 0; i < multiRow.length; ++i) {
|
441 | var rowElem = multiRow[i];
|
442 | if (angular.getTestability) {
|
443 | matches.push.apply(
|
444 | matches,
|
445 | getNg1Hooks(rootSelector).$$testability.findBindings(rowElem,
|
446 | binding));
|
447 | } else {
|
448 | if (rowElem.className.indexOf('ng-binding') != -1) {
|
449 | bindings.push(rowElem);
|
450 | }
|
451 | var childBindings = rowElem.getElementsByClassName('ng-binding');
|
452 | for (var j = 0; j < childBindings.length; ++j) {
|
453 | bindings.push(childBindings[j]);
|
454 | }
|
455 | }
|
456 | }
|
457 | }
|
458 | for (var i = 0; i < bindings.length; ++i) {
|
459 | var dataBinding = angular.element(bindings[i]).data('$binding');
|
460 | if (dataBinding) {
|
461 | var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
|
462 | if (bindingName.indexOf(binding) != -1) {
|
463 | matches.push(bindings[i]);
|
464 | }
|
465 | }
|
466 | }
|
467 | return matches;
|
468 | }
|
469 | functions.findRepeaterElement =
|
470 | wrapWithHelpers(findRepeaterElement, repeaterMatch, getNg1Hooks);
|
471 |
|
472 |
|
473 |
|
474 |
|
475 |
|
476 |
|
477 |
|
478 |
|
479 |
|
480 |
|
481 |
|
482 |
|
483 | function findRepeaterColumn(repeater, exact, binding, using, rootSelector) {
|
484 | var matches = [];
|
485 | using = using || document;
|
486 |
|
487 | var rows = [];
|
488 | var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
|
489 | for (var p = 0; p < prefixes.length; ++p) {
|
490 | var attr = prefixes[p] + 'repeat';
|
491 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
492 | attr = attr.replace(/\\/g, '');
|
493 | for (var i = 0; i < repeatElems.length; ++i) {
|
494 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
495 | rows.push(repeatElems[i]);
|
496 | }
|
497 | }
|
498 | }
|
499 | |
500 |
|
501 | var multiRows = [];
|
502 | for (var p = 0; p < prefixes.length; ++p) {
|
503 | var attr = prefixes[p] + 'repeat-start';
|
504 | var repeatElems = using.querySelectorAll('[' + attr + ']');
|
505 | attr = attr.replace(/\\/g, '');
|
506 | for (var i = 0; i < repeatElems.length; ++i) {
|
507 | if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {
|
508 | var elem = repeatElems[i];
|
509 | var row = [];
|
510 | while (elem.nodeType != 8 || (elem.nodeValue &&
|
511 | !repeaterMatch(elem.nodeValue, repeater))) {
|
512 | if (elem.nodeType == 1) {
|
513 | row.push(elem);
|
514 | }
|
515 | elem = elem.nextSibling;
|
516 | }
|
517 | multiRows.push(row);
|
518 | }
|
519 | }
|
520 | }
|
521 | var bindings = [];
|
522 | for (var i = 0; i < rows.length; ++i) {
|
523 | if (angular.getTestability) {
|
524 | matches.push.apply(
|
525 | matches,
|
526 | getNg1Hooks(rootSelector).$$testability.findBindings(rows[i],
|
527 | binding));
|
528 | } else {
|
529 | if (rows[i].className.indexOf('ng-binding') != -1) {
|
530 | bindings.push(rows[i]);
|
531 | }
|
532 | var childBindings = rows[i].getElementsByClassName('ng-binding');
|
533 | for (var k = 0; k < childBindings.length; ++k) {
|
534 | bindings.push(childBindings[k]);
|
535 | }
|
536 | }
|
537 | }
|
538 | for (var i = 0; i < multiRows.length; ++i) {
|
539 | for (var j = 0; j < multiRows[i].length; ++j) {
|
540 | if (angular.getTestability) {
|
541 | matches.push.apply(
|
542 | matches,
|
543 | getNg1Hooks(rootSelector).$$testability.findBindings(
|
544 | multiRows[i][j], binding));
|
545 | } else {
|
546 | var elem = multiRows[i][j];
|
547 | if (elem.className.indexOf('ng-binding') != -1) {
|
548 | bindings.push(elem);
|
549 | }
|
550 | var childBindings = elem.getElementsByClassName('ng-binding');
|
551 | for (var k = 0; k < childBindings.length; ++k) {
|
552 | bindings.push(childBindings[k]);
|
553 | }
|
554 | }
|
555 | }
|
556 | }
|
557 | for (var j = 0; j < bindings.length; ++j) {
|
558 | var dataBinding = angular.element(bindings[j]).data('$binding');
|
559 | if (dataBinding) {
|
560 | var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;
|
561 | if (bindingName.indexOf(binding) != -1) {
|
562 | matches.push(bindings[j]);
|
563 | }
|
564 | }
|
565 | }
|
566 | return matches;
|
567 | }
|
568 | functions.findRepeaterColumn =
|
569 | wrapWithHelpers(findRepeaterColumn, repeaterMatch, getNg1Hooks);
|
570 |
|
571 |
|
572 |
|
573 |
|
574 |
|
575 |
|
576 |
|
577 |
|
578 |
|
579 |
|
580 | functions.findByModel = function(model, using, rootSelector) {
|
581 | using = using || document;
|
582 |
|
583 | if (angular.getTestability) {
|
584 | return getNg1Hooks(rootSelector).$$testability.
|
585 | findModels(using, model, true);
|
586 | }
|
587 | var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
|
588 | for (var p = 0; p < prefixes.length; ++p) {
|
589 | var selector = '[' + prefixes[p] + 'model="' + model + '"]';
|
590 | var elements = using.querySelectorAll(selector);
|
591 | if (elements.length) {
|
592 | return elements;
|
593 | }
|
594 | }
|
595 | };
|
596 |
|
597 |
|
598 |
|
599 |
|
600 |
|
601 |
|
602 |
|
603 |
|
604 |
|
605 |
|
606 | functions.findByOptions = function(optionsDescriptor, using) {
|
607 | using = using || document;
|
608 |
|
609 | var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];
|
610 | for (var p = 0; p < prefixes.length; ++p) {
|
611 | var selector = '[' + prefixes[p] + 'options="' + optionsDescriptor + '"] option';
|
612 | var elements = using.querySelectorAll(selector);
|
613 | if (elements.length) {
|
614 | return elements;
|
615 | }
|
616 | }
|
617 | };
|
618 |
|
619 |
|
620 |
|
621 |
|
622 |
|
623 |
|
624 |
|
625 |
|
626 |
|
627 | functions.findByButtonText = function(searchText, using) {
|
628 | using = using || document;
|
629 |
|
630 | var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
|
631 | var matches = [];
|
632 | for (var i = 0; i < elements.length; ++i) {
|
633 | var element = elements[i];
|
634 | var elementText;
|
635 | if (element.tagName.toLowerCase() == 'button') {
|
636 | elementText = element.textContent || element.innerText || '';
|
637 | } else {
|
638 | elementText = element.value;
|
639 | }
|
640 | if (elementText.trim() === searchText) {
|
641 | matches.push(element);
|
642 | }
|
643 | }
|
644 |
|
645 | return matches;
|
646 | };
|
647 |
|
648 |
|
649 |
|
650 |
|
651 |
|
652 |
|
653 |
|
654 |
|
655 |
|
656 | functions.findByPartialButtonText = function(searchText, using) {
|
657 | using = using || document;
|
658 |
|
659 | var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');
|
660 | var matches = [];
|
661 | for (var i = 0; i < elements.length; ++i) {
|
662 | var element = elements[i];
|
663 | var elementText;
|
664 | if (element.tagName.toLowerCase() == 'button') {
|
665 | elementText = element.textContent || element.innerText || '';
|
666 | } else {
|
667 | elementText = element.value;
|
668 | }
|
669 | if (elementText.indexOf(searchText) > -1) {
|
670 | matches.push(element);
|
671 | }
|
672 | }
|
673 |
|
674 | return matches;
|
675 | };
|
676 |
|
677 |
|
678 |
|
679 |
|
680 |
|
681 |
|
682 |
|
683 |
|
684 |
|
685 |
|
686 | functions.findByCssContainingText = function(cssSelector, searchText, using) {
|
687 | using = using || document;
|
688 |
|
689 | if (searchText.indexOf('__REGEXP__') === 0) {
|
690 | var match = searchText.split('__REGEXP__')[1].match(/\/(.*)\/(.*)?/);
|
691 | searchText = new RegExp(match[1], match[2] || '');
|
692 | }
|
693 | var elements = using.querySelectorAll(cssSelector);
|
694 | var matches = [];
|
695 | for (var i = 0; i < elements.length; ++i) {
|
696 | var element = elements[i];
|
697 | var elementText = element.textContent || element.innerText || '';
|
698 | var elementMatches = searchText instanceof RegExp ?
|
699 | searchText.test(elementText) :
|
700 | elementText.indexOf(searchText) > -1;
|
701 |
|
702 | if (elementMatches) {
|
703 | matches.push(element);
|
704 | }
|
705 | }
|
706 | return matches;
|
707 | };
|
708 |
|
709 |
|
710 |
|
711 |
|
712 |
|
713 |
|
714 |
|
715 |
|
716 |
|
717 |
|
718 |
|
719 |
|
720 | functions.testForAngular = function(attempts, ng12Hybrid, asyncCallback) {
|
721 | var callback = function(args) {
|
722 | setTimeout(function() {
|
723 | asyncCallback(args);
|
724 | }, 0);
|
725 | };
|
726 | var definitelyNg1 = !!ng12Hybrid;
|
727 | var definitelyNg2OrNewer = false;
|
728 | var check = function(n) {
|
729 | try {
|
730 |
|
731 | if (!definitelyNg1 && !definitelyNg2OrNewer) {
|
732 | if (window.angular && !(window.angular.version && window.angular.version.major > 1)) {
|
733 | definitelyNg1 = true;
|
734 | } else if (window.getAllAngularTestabilities) {
|
735 | definitelyNg2OrNewer = true;
|
736 | }
|
737 | }
|
738 |
|
739 | if (definitelyNg1) {
|
740 | if (window.angular && window.angular.resumeBootstrap) {
|
741 | return callback({ver: 1});
|
742 | }
|
743 | } else if (definitelyNg2OrNewer) {
|
744 | if (true ) {
|
745 | return callback({ver: 2});
|
746 | }
|
747 | }
|
748 |
|
749 | if (n < 1) {
|
750 | if (definitelyNg1 && window.angular) {
|
751 | callback({message: 'angular never provided resumeBootstrap'});
|
752 | } else if (ng12Hybrid && !window.angular) {
|
753 | callback({message: 'angular 1 never loaded' +
|
754 | window.getAllAngularTestabilities ? ' (are you sure this app ' +
|
755 | 'uses ngUpgrade? Try un-setting ng12Hybrid)' : ''});
|
756 | } else {
|
757 | callback({message: 'retries looking for angular exceeded'});
|
758 | }
|
759 | } else {
|
760 | window.setTimeout(function() {check(n - 1);}, 1000);
|
761 | }
|
762 | } catch (e) {
|
763 | callback({message: e});
|
764 | }
|
765 | };
|
766 | check(attempts);
|
767 | };
|
768 |
|
769 |
|
770 |
|
771 |
|
772 |
|
773 |
|
774 |
|
775 |
|
776 |
|
777 | functions.evaluate = function(element, expression) {
|
778 | return angular.element(element).scope().$eval(expression);
|
779 | };
|
780 |
|
781 | functions.allowAnimations = function(element, value) {
|
782 | var ngElement = angular.element(element);
|
783 | if (ngElement.allowAnimations) {
|
784 |
|
785 | return ngElement.allowAnimations(value);
|
786 | } else {
|
787 |
|
788 | var enabledFn = ngElement.injector().get('$animate').enabled;
|
789 | return (value == null) ? enabledFn() : enabledFn(value);
|
790 | }
|
791 | };
|
792 |
|
793 |
|
794 |
|
795 |
|
796 |
|
797 |
|
798 | functions.getLocationAbsUrl = function(selector) {
|
799 | var hooks = getNg1Hooks(selector);
|
800 | if (angular.getTestability) {
|
801 | return hooks.$$testability.getLocation();
|
802 | }
|
803 | return hooks.$injector.get('$location').absUrl();
|
804 | };
|
805 |
|
806 |
|
807 |
|
808 |
|
809 |
|
810 |
|
811 |
|
812 |
|
813 | functions.setLocation = function(selector, url) {
|
814 | var hooks = getNg1Hooks(selector);
|
815 | if (angular.getTestability) {
|
816 | return hooks.$$testability.setLocation(url);
|
817 | }
|
818 | var $injector = hooks.$injector;
|
819 | var $location = $injector.get('$location');
|
820 | var $rootScope = $injector.get('$rootScope');
|
821 |
|
822 | if (url !== $location.url()) {
|
823 | $location.url(url);
|
824 | $rootScope.$digest();
|
825 | }
|
826 | };
|
827 |
|
828 |
|
829 |
|
830 |
|
831 |
|
832 |
|
833 |
|
834 | functions.getPendingHttpRequests = function(selector) {
|
835 | var hooks = getNg1Hooks(selector, true);
|
836 | var $http = hooks.$injector.get('$http');
|
837 | return $http.pendingRequests;
|
838 | };
|
839 |
|
840 | ['waitForAngular', 'findBindings', 'findByModel', 'getLocationAbsUrl',
|
841 | 'setLocation', 'getPendingHttpRequests'].forEach(function(funName) {
|
842 | functions[funName] = wrapWithHelpers(functions[funName], getNg1Hooks);
|
843 | });
|
844 |
|
845 |
|
846 |
|
847 |
|
848 |
|
849 |
|
850 |
|
851 |
|
852 |
|
853 |
|
854 |
|
855 |
|
856 | var util = require('util');
|
857 | var scriptsList = [];
|
858 | var scriptFmt = (
|
859 | 'try { return (%s).apply(this, arguments); }\n' +
|
860 | 'catch(e) { throw (e instanceof Error) ? e : new Error(e); }');
|
861 | for (var fnName in functions) {
|
862 | if (functions.hasOwnProperty(fnName)) {
|
863 | exports[fnName] = util.format(scriptFmt, functions[fnName]);
|
864 | scriptsList.push(util.format('%s: %s', fnName, functions[fnName]));
|
865 | }
|
866 | }
|
867 |
|
868 | exports.installInBrowser = (util.format(
|
869 | 'window.clientSideScripts = {%s};', scriptsList.join(', ')));
|
870 |
|
871 |
|
872 |
|
873 |
|
874 |
|
875 |
|
876 |
|
877 |
|
878 | exports.protractorBaseModuleFn = function(trackOutstandingTimeouts) {
|
879 | var ngMod = angular.module('protractorBaseModule_', []).config([
|
880 | '$compileProvider',
|
881 | function($compileProvider) {
|
882 | if ($compileProvider.debugInfoEnabled) {
|
883 | $compileProvider.debugInfoEnabled(true);
|
884 | }
|
885 | }
|
886 | ]);
|
887 | if (trackOutstandingTimeouts) {
|
888 | ngMod.config([
|
889 | '$provide',
|
890 | function ($provide) {
|
891 | $provide.decorator('$timeout', [
|
892 | '$delegate',
|
893 | function ($delegate) {
|
894 | var $timeout = $delegate;
|
895 |
|
896 | var taskId = 0;
|
897 |
|
898 | if (!window['NG_PENDING_TIMEOUTS']) {
|
899 | window['NG_PENDING_TIMEOUTS'] = {};
|
900 | }
|
901 |
|
902 | var extendedTimeout= function() {
|
903 | var args = Array.prototype.slice.call(arguments);
|
904 | if (typeof(args[0]) !== 'function') {
|
905 | return $timeout.apply(null, args);
|
906 | }
|
907 |
|
908 | taskId++;
|
909 | var fn = args[0];
|
910 | window['NG_PENDING_TIMEOUTS'][taskId] =
|
911 | fn.toString();
|
912 | var wrappedFn = (function(taskId_) {
|
913 | return function() {
|
914 | delete window['NG_PENDING_TIMEOUTS'][taskId_];
|
915 | return fn.apply(null, arguments);
|
916 | };
|
917 | })(taskId);
|
918 | args[0] = wrappedFn;
|
919 |
|
920 | var promise = $timeout.apply(null, args);
|
921 | promise.ptorTaskId_ = taskId;
|
922 | return promise;
|
923 | };
|
924 |
|
925 | extendedTimeout.cancel = function() {
|
926 | var taskId_ = arguments[0] && arguments[0].ptorTaskId_;
|
927 | if (taskId_) {
|
928 | delete window['NG_PENDING_TIMEOUTS'][taskId_];
|
929 | }
|
930 | return $timeout.cancel.apply($timeout, arguments);
|
931 | };
|
932 |
|
933 | return extendedTimeout;
|
934 | }
|
935 | ]);
|
936 | }
|
937 | ]);
|
938 | }
|
939 | };
|