Best JavaScript code snippet using protractor
clientsidescripts.js
Source:clientsidescripts.js  
...27 *28 * @return {string} The string which, when executed, will invoke fun in such a29 *   way that it has access to its helper functions30 */31function wrapWithHelpers(fun) {32  var helpers = Array.prototype.slice.call(arguments, 1);33  if (!helpers.length) {34    return fun;35  }36  var FunClass = Function; // Get the linter to allow this eval37  return new FunClass(38      helpers.join(';') + String.fromCharCode(59) +39      '  return (' + fun.toString() + ').apply(this, arguments);');40}41/* Tests if an ngRepeat matches a repeater42 *43 * @param {string} ngRepeat The ngRepeat to test44 * @param {string} repeater The repeater to test against45 * @param {boolean} exact If the ngRepeat expression needs to match the whole46 *   repeater (not counting any `track by ...` modifier) or if it just needs to47 *   match a substring48 * @return {boolean} If the ngRepeat matched the repeater49 */50function repeaterMatch(ngRepeat, repeater, exact) {51  if (exact) {52    return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].53        split('=')[0].trim() == repeater;54  } else {55    return ngRepeat.indexOf(repeater) != -1;56  }57}58/* Tries to find $$testability and possibly $injector for an ng1 app59 *60 * By default, doesn't care about $injector if it finds $$testability.  However,61 * these priorities can be reversed.62 *63 * @param {string=} selector The selector for the element with the injector.  If64 *   falsy, tries a variety of methods to find an injector65 * @param {boolean=} injectorPlease Prioritize finding an injector66 * @return {$$testability?: Testability, $injector?: Injector} Returns whatever67 *   ng1 app hooks it finds68 */69function getNg1Hooks(selector, injectorPlease) {70  function tryEl(el) {71    try {72      if (!injectorPlease && angular.getTestability) {73        var $$testability = angular.getTestability(el);74        if ($$testability) {75          return {$$testability: $$testability};76        }77      } else {78        var $injector = angular.element(el).injector();79        if ($injector) {80          return {$injector: $injector};81        }82      }83    } catch(err) {} 84  }85  function trySelector(selector) {86    var els = document.querySelectorAll(selector);87    for (var i = 0; i < els.length; i++) {88      var elHooks = tryEl(els[i]);89      if (elHooks) {90        return elHooks;91      }92    }93  }94  if (selector) {95    return trySelector(selector);96  } else if (window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__) {97    var $injector = window.__TESTABILITY__NG1_APP_ROOT_INJECTOR__;98    var $$testability = null;99    try {100      $$testability = $injector.get('$$testability');101    } catch (e) {}102    return {$injector: $injector, $$testability: $$testability};103  } else {104    return tryEl(document.body) ||105        trySelector('[ng-app]') || trySelector('[ng\\:app]') ||106        trySelector('[ng-controller]') || trySelector('[ng\\:controller]');107  }108}109///////////////////////////////////////////////////////110////                                               ////111////                    SCRIPTS                    ////112////                                               ////113///////////////////////////////////////////////////////114/**115 * Wait until Angular has finished rendering and has116 * no outstanding $http calls before continuing. The specific Angular app117 * is determined by the rootSelector.118 *119 * Asynchronous.120 *121 * @param {string} rootSelector The selector housing an ng-app122 * @param {function(string)} callback callback. If a failure occurs, it will123 *     be passed as a parameter.124 */125functions.waitForAngular = function(rootSelector, callback) {126  try {127    if (window.angular && !(window.angular.version &&128          window.angular.version.major > 1)) {129      /* ng1 */130      var hooks = getNg1Hooks(rootSelector);131      if (hooks.$$testability) {132        hooks.$$testability.whenStable(callback);133      } else if (hooks.$injector) {134        hooks.$injector.get('$browser').135            notifyWhenNoOutstandingRequests(callback);136      } else if (!!rootSelector) {137        throw new Error('Could not automatically find injector on page: "' +138            window.location.toString() + '".  Consider using config.rootEl');139      } else {140        throw new Error('root element (' + rootSelector + ') has no injector.' +141           ' this may mean it is not inside ng-app.');142      }143    } else if (rootSelector && window.getAngularTestability) {144      var el = document.querySelector(rootSelector);145      window.getAngularTestability(el).whenStable(callback);146    } else if (window.getAllAngularTestabilities) {147      var testabilities = window.getAllAngularTestabilities();148      var count = testabilities.length;149      var decrement = function() {150        count--;151        if (count === 0) {152          callback();153        }154      };155      testabilities.forEach(function(testability) {156        testability.whenStable(decrement);157      });158    } else if (!window.angular) {159      throw new Error('window.angular is undefined.  This could be either ' +160          'because this is a non-angular page or because your test involves ' +161          'client-side navigation, which can interfere with Protractor\'s ' +162          'bootstrapping.  See http://git.io/v4gXM for details');163    } else if (window.angular.version >= 2) {164      throw new Error('You appear to be using angular, but window.' +165          'getAngularTestability was never set.  This may be due to bad ' +166          'obfuscation.');167    } else {168      throw new Error('Cannot get testability API for unknown angular ' +169          'version "' + window.angular.version + '"');170    }171  } catch (err) {172    callback(err.message);173  }174};175/**176 * Find a list of elements in the page by their angular binding.177 *178 * @param {string} binding The binding, e.g. {{cat.name}}.179 * @param {boolean} exactMatch Whether the binding needs to be matched exactly180 * @param {Element} using The scope of the search.181 * @param {string} rootSelector The selector to use for the root app element.182 *183 * @return {Array.<Element>} The elements containing the binding.184 */185functions.findBindings = function(binding, exactMatch, using, rootSelector) {186  using = using || document;187  if (angular.getTestability) {188    return getNg1Hooks(rootSelector).$$testability.189        findBindings(using, binding, exactMatch);190  }191  var bindings = using.getElementsByClassName('ng-binding');192  var matches = [];193  for (var i = 0; i < bindings.length; ++i) {194    var dataBinding = angular.element(bindings[i]).data('$binding');195    if (dataBinding) {196      var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;197      if (exactMatch) {198        var matcher = new RegExp('({|\\s|^|\\|)' +199            /* See http://stackoverflow.com/q/3561711 */200            binding.replace(/[\-\[\]\/\{\}\(\)\*\+\?\.\\\^\$\|]/g, '\\$&') +201            '(}|\\s|$|\\|)');202        if (matcher.test(bindingName)) {203          matches.push(bindings[i]);204        }205      } else {206        if (bindingName.indexOf(binding) != -1) {207          matches.push(bindings[i]);208        }209      }210    }211  }212  return matches; /* Return the whole array for webdriver.findElements. */213};214/**215 * Find an array of elements matching a row within an ng-repeat.216 * Always returns an array of only one element for plain old ng-repeat.217 * Returns an array of all the elements in one segment for ng-repeat-start.218 *219 * @param {string} repeater The text of the repeater, e.g. 'cat in cats'.220 * @param {boolean} exact Whether the repeater needs to be matched exactly221 * @param {number} index The row index.222 * @param {Element} using The scope of the search.223 *224 * @return {Array.<Element>} The row of the repeater, or an array of elements225 *     in the first row in the case of ng-repeat-start.226 */227function findRepeaterRows(repeater, exact, index, using) {228  using = using || document;229  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];230  var rows = [];231  for (var p = 0; p < prefixes.length; ++p) {232    var attr = prefixes[p] + 'repeat';233    var repeatElems = using.querySelectorAll('[' + attr + ']');234    attr = attr.replace(/\\/g, '');235    for (var i = 0; i < repeatElems.length; ++i) {236      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {237        rows.push(repeatElems[i]);238      }239    }240  }241  /* multiRows is an array of arrays, where each inner array contains242     one row of elements. */243  var multiRows = [];244  for (var p = 0; p < prefixes.length; ++p) {245    var attr = prefixes[p] + 'repeat-start';246    var repeatElems = using.querySelectorAll('[' + attr + ']');247    attr = attr.replace(/\\/g, '');248    for (var i = 0; i < repeatElems.length; ++i) {249      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {250        var elem = repeatElems[i];251        var row = [];252        while (elem.nodeType != 8 ||253            !repeaterMatch(elem.nodeValue, repeater)) {254          if (elem.nodeType == 1) {255            row.push(elem);256          }257          elem = elem.nextSibling;258        }259        multiRows.push(row);260      }261    }262  }263  var row = rows[index] || [], multiRow = multiRows[index] || [];264  return [].concat(row, multiRow);265}266functions.findRepeaterRows = wrapWithHelpers(findRepeaterRows, repeaterMatch); 267 /**268 * Find all rows of an ng-repeat.269 *270 * @param {string} repeater The text of the repeater, e.g. 'cat in cats'.271 * @param {boolean} exact Whether the repeater needs to be matched exactly272 * @param {Element} using The scope of the search.273 *274 * @return {Array.<Element>} All rows of the repeater.275 */276function findAllRepeaterRows(repeater, exact, using) {277  using = using || document;278  var rows = [];279  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];280  for (var p = 0; p < prefixes.length; ++p) {281    var attr = prefixes[p] + 'repeat';282    var repeatElems = using.querySelectorAll('[' + attr + ']');283    attr = attr.replace(/\\/g, '');284    for (var i = 0; i < repeatElems.length; ++i) {285      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {286        rows.push(repeatElems[i]);287      }288    }289  }290  for (var p = 0; p < prefixes.length; ++p) {291    var attr = prefixes[p] + 'repeat-start';292    var repeatElems = using.querySelectorAll('[' + attr + ']');293    attr = attr.replace(/\\/g, '');294    for (var i = 0; i < repeatElems.length; ++i) {295      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {296        var elem = repeatElems[i];297        while (elem.nodeType != 8 ||298            !repeaterMatch(elem.nodeValue, repeater)) {299          if (elem.nodeType == 1) {300            rows.push(elem);301          }302          elem = elem.nextSibling;303        }304      }305    }306  }307  return rows;308}309functions.findAllRepeaterRows = wrapWithHelpers(findAllRepeaterRows, repeaterMatch);310/**311 * Find an element within an ng-repeat by its row and column.312 *313 * @param {string} repeater The text of the repeater, e.g. 'cat in cats'.314 * @param {boolean} exact Whether the repeater needs to be matched exactly315 * @param {number} index The row index.316 * @param {string} binding The column binding, e.g. '{{cat.name}}'.317 * @param {Element} using The scope of the search.318 * @param {string} rootSelector The selector to use for the root app element.319 *320 * @return {Array.<Element>} The element in an array.321 */322function findRepeaterElement(repeater, exact, index, binding, using, rootSelector) {323  var matches = [];324  using = using || document;325  var rows = [];326  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];327  for (var p = 0; p < prefixes.length; ++p) {328    var attr = prefixes[p] + 'repeat';329    var repeatElems = using.querySelectorAll('[' + attr + ']');330    attr = attr.replace(/\\/g, '');331    for (var i = 0; i < repeatElems.length; ++i) {332      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {333        rows.push(repeatElems[i]);334      }335    }336  }337  /* multiRows is an array of arrays, where each inner array contains338     one row of elements. */339  var multiRows = [];340  for (var p = 0; p < prefixes.length; ++p) {341    var attr = prefixes[p] + 'repeat-start';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        var elem = repeatElems[i];347        var row = [];348        while (elem.nodeType != 8 || (elem.nodeValue &&349            !repeaterMatch(elem.nodeValue, repeater))) {350          if (elem.nodeType == 1) {351            row.push(elem);352          }353          elem = elem.nextSibling;354        }355        multiRows.push(row);356      }357    }358  }359  var row = rows[index];360  var multiRow = multiRows[index];361  var bindings = [];362  if (row) {363    if (angular.getTestability) {364      matches.push.apply(365          matches,366          getNg1Hooks(rootSelector).$$testability.findBindings(row, binding));367    } else {368      if (row.className.indexOf('ng-binding') != -1) {369        bindings.push(row);370      }371      var childBindings = row.getElementsByClassName('ng-binding');372      for (var i = 0; i < childBindings.length; ++i) {373        bindings.push(childBindings[i]);374      }375    }376  }377  if (multiRow) {378    for (var i = 0; i < multiRow.length; ++i) {379      var rowElem = multiRow[i];380      if (angular.getTestability) {381        matches.push.apply(382            matches,383            getNg1Hooks(rootSelector).$$testability.findBindings(rowElem,384                binding));385      } else {386        if (rowElem.className.indexOf('ng-binding') != -1) {387          bindings.push(rowElem);388        }389        var childBindings = rowElem.getElementsByClassName('ng-binding');390        for (var j = 0; j < childBindings.length; ++j) {391          bindings.push(childBindings[j]);392        }393      }394    }395  }396  for (var i = 0; i < bindings.length; ++i) {397    var dataBinding = angular.element(bindings[i]).data('$binding');398    if (dataBinding) {399      var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;400      if (bindingName.indexOf(binding) != -1) {401        matches.push(bindings[i]);402      }403    }404  }405  return matches;406}407functions.findRepeaterElement =408    wrapWithHelpers(findRepeaterElement, repeaterMatch, getNg1Hooks);409/**410 * Find the elements in a column of an ng-repeat.411 *412 * @param {string} repeater The text of the repeater, e.g. 'cat in cats'.413 * @param {boolean} exact Whether the repeater needs to be matched exactly414 * @param {string} binding The column binding, e.g. '{{cat.name}}'.415 * @param {Element} using The scope of the search.416 * @param {string} rootSelector The selector to use for the root app element.417 *418 * @return {Array.<Element>} The elements in the column.419 */420function findRepeaterColumn(repeater, exact, binding, using, rootSelector) {421  var matches = [];422  using = using || document;423  var rows = [];424  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];425  for (var p = 0; p < prefixes.length; ++p) {426    var attr = prefixes[p] + 'repeat';427    var repeatElems = using.querySelectorAll('[' + attr + ']');428    attr = attr.replace(/\\/g, '');429    for (var i = 0; i < repeatElems.length; ++i) {430      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {431        rows.push(repeatElems[i]);432      }433    }434  }435  /* multiRows is an array of arrays, where each inner array contains436     one row of elements. */437  var multiRows = [];438  for (var p = 0; p < prefixes.length; ++p) {439    var attr = prefixes[p] + 'repeat-start';440    var repeatElems = using.querySelectorAll('[' + attr + ']');441    attr = attr.replace(/\\/g, '');442    for (var i = 0; i < repeatElems.length; ++i) {443      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {444        var elem = repeatElems[i];445        var row = [];446        while (elem.nodeType != 8 || (elem.nodeValue &&447            !repeaterMatch(elem.nodeValue, repeater))) {448          if (elem.nodeType == 1) {449            row.push(elem);450          }451          elem = elem.nextSibling;452        }453        multiRows.push(row);454      }455    }456  }457  var bindings = [];458  for (var i = 0; i < rows.length; ++i) {459    if (angular.getTestability) {460      matches.push.apply(461          matches,462          getNg1Hooks(rootSelector).$$testability.findBindings(rows[i],463              binding));464    } else {465      if (rows[i].className.indexOf('ng-binding') != -1) {466        bindings.push(rows[i]);467      }468      var childBindings = rows[i].getElementsByClassName('ng-binding');469      for (var k = 0; k < childBindings.length; ++k) {470        bindings.push(childBindings[k]);471      }472    }473  }474  for (var i = 0; i < multiRows.length; ++i) {475    for (var j = 0; j < multiRows[i].length; ++j) {476      if (angular.getTestability) {477        matches.push.apply(478            matches,479            getNg1Hooks(rootSelector).$$testability.findBindings(480                multiRows[i][j], binding));481      } else {482        var elem = multiRows[i][j];483        if (elem.className.indexOf('ng-binding') != -1) {484          bindings.push(elem);485        }486        var childBindings = elem.getElementsByClassName('ng-binding');487        for (var k = 0; k < childBindings.length; ++k) {488          bindings.push(childBindings[k]);489        }490      }491    }492  }493  for (var j = 0; j < bindings.length; ++j) {494    var dataBinding = angular.element(bindings[j]).data('$binding');495    if (dataBinding) {496      var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;497      if (bindingName.indexOf(binding) != -1) {498        matches.push(bindings[j]);499      }500    }501  }502  return matches;503}504functions.findRepeaterColumn =505    wrapWithHelpers(findRepeaterColumn, repeaterMatch, getNg1Hooks);506/**507 * Find elements by model name.508 *509 * @param {string} model The model name.510 * @param {Element} using The scope of the search.511 * @param {string} rootSelector The selector to use for the root app element.512 *513 * @return {Array.<Element>} The matching elements.514 */515functions.findByModel = function(model, using, rootSelector) {516  using = using || document;517  if (angular.getTestability) {518    return getNg1Hooks(rootSelector).$$testability.519        findModels(using, model, true);520  }521  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];522  for (var p = 0; p < prefixes.length; ++p) {523    var selector = '[' + prefixes[p] + 'model="' + model + '"]';524    var elements = using.querySelectorAll(selector);525    if (elements.length) {526      return elements;527    }528  }529};530/**531 * Find elements by options.532 *533 * @param {string} optionsDescriptor The descriptor for the option534 *     (i.e. fruit for fruit in fruits).535 * @param {Element} using The scope of the search.536 *537 * @return {Array.<Element>} The matching elements.538 */539functions.findByOptions = function(optionsDescriptor, using) {540  using = using || document;541  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];542  for (var p = 0; p < prefixes.length; ++p) {543    var selector = '[' + prefixes[p] + 'options="' + optionsDescriptor + '"] option';544    var elements = using.querySelectorAll(selector);545    if (elements.length) {546      return elements;547    }548  }549};550/**551 * Find buttons by textual content.552 *553 * @param {string} searchText The exact text to match.554 * @param {Element} using The scope of the search.555 *556 * @return {Array.<Element>} The matching elements.557 */558functions.findByButtonText = function(searchText, using) {559  using = using || document;560  var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');561  var matches = [];562  for (var i = 0; i < elements.length; ++i) {563    var element = elements[i];564    var elementText;565    if (element.tagName.toLowerCase() == 'button') {566      elementText = element.textContent || element.innerText || '';567    } else {568      elementText = element.value;569    }570    if (elementText.trim() === searchText) {571      matches.push(element);572    }573  }574  return matches;575};576/**577 * Find buttons by textual content.578 *579 * @param {string} searchText The exact text to match.580 * @param {Element} using The scope of the search.581 *582 * @return {Array.<Element>} The matching elements.583 */584functions.findByPartialButtonText = function(searchText, using) {585  using = using || document;586  var elements = using.querySelectorAll('button, input[type="button"], input[type="submit"]');587  var matches = [];588  for (var i = 0; i < elements.length; ++i) {589    var element = elements[i];590    var elementText;591    if (element.tagName.toLowerCase() == 'button') {592      elementText = element.textContent || element.innerText || '';593    } else {594      elementText = element.value;595    }596    if (elementText.indexOf(searchText) > -1) {597      matches.push(element);598    }599  }600  return matches;601};602/**603 * Find elements by css selector and textual content.604 *605 * @param {string} cssSelector The css selector to match.606 * @param {string} searchText The exact text to match.607 * @param {Element} using The scope of the search.608 *609 * @return {Array.<Element>} An array of matching elements.610 */611functions.findByCssContainingText = function(cssSelector, searchText, using) {612  using = using || document;613  var elements = using.querySelectorAll(cssSelector);614  var matches = [];615  for (var i = 0; i < elements.length; ++i) {616    var element = elements[i];617    var elementText = element.textContent || element.innerText || '';618    if (elementText.indexOf(searchText) > -1) {619      matches.push(element);620    }621  }622  return matches;623};624/**625 * Tests whether the angular global variable is present on a page. Retries626 * in case the page is just loading slowly.627 *628 * Asynchronous.629 *630 * @param {number} attempts Number of times to retry.631 * @param {boolean} ng12Hybrid Flag set if app is a hybrid of angular 1 and 2632 * @param {function({version: ?number, message: ?string})} asyncCallback callback633 *634 */635functions.testForAngular = function(attempts, ng12Hybrid, asyncCallback) {636  var callback = function(args) {637    setTimeout(function() {638      asyncCallback(args);639    }, 0);640  };641  var definitelyNg1 = !!ng12Hybrid;642  var definitelyNg2OrNewer = false;643  var check = function(n) {644    try {645      /* Figure out which version of angular we're waiting on */646      if (!definitelyNg1 && !definitelyNg2OrNewer) {647        if (window.angular && !(window.angular.version && window.angular.version.major > 1)) {648          definitelyNg1 = true;649        } else if (window.getAllAngularTestabilities) {650          definitelyNg2OrNewer = true;651        }652      }653      /* See if our version of angular is ready */654      if (definitelyNg1) {655        if (window.angular && window.angular.resumeBootstrap) {656          return callback({ver: 1});657        }658      } else if (definitelyNg2OrNewer) {659        if (true /* ng2 has no resumeBootstrap() */) {660          return callback({ver: 2});661        }662      }663      /* Try again (or fail) */664      if (n < 1) {665        if (definitelyNg1 && window.angular) {666          callback({message: 'angular never provided resumeBootstrap'});667        } else if (ng12Hybrid && !window.angular) { 668          callback({message: 'angular 1 never loaded' +669              window.getAllAngularTestabilities ? ' (are you sure this app ' +670              'uses ngUpgrade?  Try un-setting ng12Hybrid)' : ''});671        } else {672          callback({message: 'retries looking for angular exceeded'});673        }674      } else {675        window.setTimeout(function() {check(n - 1);}, 1000);676      }677    } catch (e) {678      callback({message: e});679    }680  };681  check(attempts);682};683/**684 * Evalute an Angular expression in the context of a given element.685 *686 * @param {Element} element The element in whose scope to evaluate.687 * @param {string} expression The expression to evaluate.688 *689 * @return {?Object} The result of the evaluation.690 */691functions.evaluate = function(element, expression) {692  return angular.element(element).scope().$eval(expression);693};694functions.allowAnimations = function(element, value) {695  var ngElement = angular.element(element);696  if (ngElement.allowAnimations) {697    // AngularDart: $testability API.698    return ngElement.allowAnimations(value);699  } else {700    // AngularJS701    var enabledFn = ngElement.injector().get('$animate').enabled;702    return (value == null) ? enabledFn() : enabledFn(value);703  }704};705/**706 * Return the current url using $location.absUrl().707 *708 * @param {string} selector The selector housing an ng-app709 */710functions.getLocationAbsUrl = function(selector) {711  var hooks = getNg1Hooks(selector);712  if (angular.getTestability) {713    return hooks.$$testability.getLocation();714  }715  return hooks.$injector.get('$location').absUrl();716};717/**718 * Browse to another page using in-page navigation.719 *720 * @param {string} selector The selector housing an ng-app721 * @param {string} url In page URL using the same syntax as $location.url(),722 *     /path?search=a&b=c#hash723 */724functions.setLocation = function(selector, url) {725  var hooks = getNg1Hooks(selector);726  if (angular.getTestability) {727    return hooks.$$testability.setLocation(url);728  }729  var $injector = hooks.$injector;730  var $location = $injector.get('$location');731  var $rootScope = $injector.get('$rootScope');732  if (url !== $location.url()) {733    $location.url(url);734    $rootScope.$digest();735  }736};737/**738 * Retrieve the pending $http requests.739 *740 * @param {string} selector The selector housing an ng-app741 * @return {!Array<!Object>} An array of pending http requests.742 */743functions.getPendingHttpRequests = function(selector) {744  var hooks = getNg1Hooks(selector, true);745  var $http = hooks.$injector.get('$http');746  return $http.pendingRequests;747};748['waitForAngular', 'findBindings', 'findByModel', 'getLocationAbsUrl',749  'setLocation', 'getPendingHttpRequests'].forEach(function(funName) {750    functions[funName] = wrapWithHelpers(functions[funName], getNg1Hooks);751});752/* Publish all the functions as strings to pass to WebDriver's753 * exec[Async]Script.  In addition, also include a script that will754 * install all the functions on window (for debugging.)755 *756 * We also wrap any exceptions thrown by a clientSideScripts function757 * that is not an instance of the Error type into an Error type.  If we758 * don't do so, then the resulting stack trace is completely unhelpful759 * and the exception message is just "unknown error."  These types of760 * exceptions are the common case for dart2js code.  This wrapping gives761 * us the Dart stack trace and exception message.762 */763var util = require('util');764var scriptsList = [];...ng-repeater.js
Source:ng-repeater.js  
...129 */130exactRepeater = byRepeaterInner(true);131/*132var functions = {};133function wrapWithHelpers(fun) {134  var helpers = Array.prototype.slice.call(arguments, 1);135  if (!helpers.length) {136    return fun;137  }138  var FunClass = Function; // Get the linter to allow this eval139  return new FunClass(140      helpers.join(';') + String.fromCharCode(59) +141      '  return (' + fun.toString() + ').apply(this, arguments);');142}143*/144function repeaterMatch(ngRepeat, repeater, exact) {145  if (exact) {146    return ngRepeat.split(' track by ')[0].split(' as ')[0].split('|')[0].147        split('=')[0].trim() == repeater;148  } else {149    return ngRepeat.indexOf(repeater) != -1;150  }151}152function findRepeaterRows(repeater, exact, index, using) {153  using = using || document;154  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];155  var rows = [];156  for (var p = 0; p < prefixes.length; ++p) {157    var attr = prefixes[p] + 'repeat';158    var repeatElems = using.querySelectorAll('[' + attr + ']');159    attr = attr.replace(/\\/g, '');160    for (var i = 0; i < repeatElems.length; ++i) {161      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {162        rows.push(repeatElems[i]);163      }164    }165  }166  /* multiRows is an array of arrays, where each inner array contains167     one row of elements. */168  var multiRows = [];169  for (var p = 0; p < prefixes.length; ++p) {170    var attr = prefixes[p] + 'repeat-start';171    var repeatElems = using.querySelectorAll('[' + attr + ']');172    attr = attr.replace(/\\/g, '');173    for (var i = 0; i < repeatElems.length; ++i) {174      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {175        var elem = repeatElems[i];176        var row = [];177        while (elem.nodeType != 8 ||178            !repeaterMatch(elem.nodeValue, repeater)) {179          if (elem.nodeType == 1) {180            row.push(elem);181          }182          elem = elem.nextSibling;183        }184        multiRows.push(row);185      }186    }187  }188  var row = rows[index] || [], multiRow = multiRows[index] || [];189  return [].concat(row, multiRow);190}191//functions.findRepeaterRows = wrapWithHelpers(findRepeaterRows, repeaterMatch); 192function findAllRepeaterRows(repeater, exact, using) {193  using = using || document;194  var rows = [];195  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];196  for (var p = 0; p < prefixes.length; ++p) {197    var attr = prefixes[p] + 'repeat';198    var repeatElems = using.querySelectorAll('[' + attr + ']');199    attr = attr.replace(/\\/g, '');200    for (var i = 0; i < repeatElems.length; ++i) {201      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {202        rows.push(repeatElems[i]);203      }204    }205  }206  for (var p = 0; p < prefixes.length; ++p) {207    var attr = prefixes[p] + 'repeat-start';208    var repeatElems = using.querySelectorAll('[' + attr + ']');209    attr = attr.replace(/\\/g, '');210    for (var i = 0; i < repeatElems.length; ++i) {211      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {212        var elem = repeatElems[i];213        while (elem.nodeType != 8 ||214            !repeaterMatch(elem.nodeValue, repeater)) {215          if (elem.nodeType == 1) {216            rows.push(elem);217          }218          elem = elem.nextSibling;219        }220      }221    }222  }223  return rows;224}225//functions.findAllRepeaterRows = wrapWithHelpers(findAllRepeaterRows, repeaterMatch);226function findRepeaterElement(repeater, exact, index, binding, using, rootSelector) {227  var matches = [];228  var root = document.querySelector(rootSelector || 'body');229  using = using || document;230  var rows = [];231  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];232  for (var p = 0; p < prefixes.length; ++p) {233    var attr = prefixes[p] + 'repeat';234    var repeatElems = using.querySelectorAll('[' + attr + ']');235    attr = attr.replace(/\\/g, '');236    for (var i = 0; i < repeatElems.length; ++i) {237      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {238        rows.push(repeatElems[i]);239      }240    }241  }242  /* multiRows is an array of arrays, where each inner array contains243     one row of elements. */244  var multiRows = [];245  for (var p = 0; p < prefixes.length; ++p) {246    var attr = prefixes[p] + 'repeat-start';247    var repeatElems = using.querySelectorAll('[' + attr + ']');248    attr = attr.replace(/\\/g, '');249    for (var i = 0; i < repeatElems.length; ++i) {250      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {251        var elem = repeatElems[i];252        var row = [];253        while (elem.nodeType != 8 || (elem.nodeValue &&254            !repeaterMatch(elem.nodeValue, repeater))) {255          if (elem.nodeType == 1) {256            row.push(elem);257          }258          elem = elem.nextSibling;259        }260        multiRows.push(row);261      }262    }263  }264  var row = rows[index];265  var multiRow = multiRows[index];266  var bindings = [];267  if (row) {268    //if (angular.getTestability) {269    //  matches.push.apply(270    //      matches,271    //      angular.getTestability(root).findBindings(row, binding));272    //} else {273      if (row.className.indexOf('ng-binding') != -1) {274        bindings.push(row);275      }276      var childBindings = row.getElementsByClassName('ng-binding');277      for (var i = 0; i < childBindings.length; ++i) {278        bindings.push(childBindings[i]);279      }280    //}281  }282  if (multiRow) {283    for (var i = 0; i < multiRow.length; ++i) {284      var rowElem = multiRow[i];285      //if (angular.getTestability) {286      //  matches.push.apply(287      //      matches,288      //      angular.getTestability(root).findBindings(rowElem, binding));289      //} else {290        if (rowElem.className.indexOf('ng-binding') != -1) {291          bindings.push(rowElem);292        }293        var childBindings = rowElem.getElementsByClassName('ng-binding');294        for (var j = 0; j < childBindings.length; ++j) {295          bindings.push(childBindings[j]);296        }297      //}298    }299  }300  for (var i = 0; i < bindings.length; ++i) {301    var dataBinding = angular.element(bindings[i]).data('$binding');302    if (dataBinding) {303      var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;304      if (bindingName.indexOf(binding) != -1) {305        matches.push(bindings[i]);306      }307    }308  }309  return matches;310}311//functions.findRepeaterElement = wrapWithHelpers(findRepeaterElement, repeaterMatch);312function findRepeaterColumn(repeater, exact, binding, using, rootSelector) {313  var matches = [];314  var root = document.querySelector(rootSelector || 'body');315  using = using || document;316  var rows = [];317  var prefixes = ['ng-', 'ng_', 'data-ng-', 'x-ng-', 'ng\\:'];318  for (var p = 0; p < prefixes.length; ++p) {319    var attr = prefixes[p] + 'repeat';320    var repeatElems = using.querySelectorAll('[' + attr + ']');321    attr = attr.replace(/\\/g, '');322    for (var i = 0; i < repeatElems.length; ++i) {323      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {324        rows.push(repeatElems[i]);325      }326    }327  }328  /* multiRows is an array of arrays, where each inner array contains329     one row of elements. */330  var multiRows = [];331  for (var p = 0; p < prefixes.length; ++p) {332    var attr = prefixes[p] + 'repeat-start';333    var repeatElems = using.querySelectorAll('[' + attr + ']');334    attr = attr.replace(/\\/g, '');335    for (var i = 0; i < repeatElems.length; ++i) {336      if (repeaterMatch(repeatElems[i].getAttribute(attr), repeater, exact)) {337        var elem = repeatElems[i];338        var row = [];339        while (elem.nodeType != 8 || (elem.nodeValue &&340            !repeaterMatch(elem.nodeValue, repeater))) {341          if (elem.nodeType == 1) {342            row.push(elem);343          }344          elem = elem.nextSibling;345        }346        multiRows.push(row);347      }348    }349  }350  var bindings = [];351  for (var i = 0; i < rows.length; ++i) {352    //if (angular.getTestability) {353    //  matches.push.apply(354    //      matches,355    //      angular.getTestability(root).findBindings(rows[i], binding));356    //} else {357      if (rows[i].className.indexOf('ng-binding') != -1) {358        bindings.push(rows[i]);359      }360      var childBindings = rows[i].getElementsByClassName('ng-binding');361      for (var k = 0; k < childBindings.length; ++k) {362        bindings.push(childBindings[k]);363      }364    //}365  }366  for (var i = 0; i < multiRows.length; ++i) {367    for (var j = 0; j < multiRows[i].length; ++j) {368      //if (angular.getTestability) {369      //  matches.push.apply(370      //      matches,371      //      angular.getTestability(root).findBindings(multiRows[i][j], binding));372      //} else {373        var elem = multiRows[i][j];374        if (elem.className.indexOf('ng-binding') != -1) {375          bindings.push(elem);376        }377        var childBindings = elem.getElementsByClassName('ng-binding');378        for (var k = 0; k < childBindings.length; ++k) {379          bindings.push(childBindings[k]);380        }381      //}382    }383  }384  for (var j = 0; j < bindings.length; ++j) {385    var dataBinding = angular.element(bindings[j]).data('$binding');386    if (dataBinding) {387      var bindingName = dataBinding.exp || dataBinding[0].exp || dataBinding;388      if (bindingName.indexOf(binding) != -1) {389        matches.push(bindings[j]);390      }391    }392  }393  return matches;394}395//functions.findRepeaterColumn = wrapWithHelpers(findRepeaterColumn, repeaterMatch);...wait.js
Source:wait.js  
...150 *151 * @return {string} The string which, when executed, will invoke fun in such a152 *   way that it has access to its helper functions153 */154function wrapWithHelpers(fun) {155  var helpers = Array.prototype.slice.call(arguments, 1);156  if (!helpers.length) {157    return fun;158  }159  var FunClass = Function; // Get the linter to allow this eval160  return new FunClass(161      helpers.join(';') + String.fromCharCode(59) +162      '  return (' + fun.toString() + ').apply(this, arguments);');163}...Using AI Code Generation
1const { wrapWithHelpers } = require('protractor-helper');2const { browser } = require('protractor');3const { wrapWithHelpers } = require('protractor-helper');4const { browser } = require('protractor');5wrapWithHelpers(browser);6const { wrapWithHelpers } = require('protractor-helper');7const { browser } = require('protractor');8wrapWithHelpers(browser);9const { wrapWithHelpers } = require('protractor-helper');10const { browser } = require('protractor');11wrapWithHelpers(browser);12const { wrapWithHelpers } = require('protractor-helper');13const { browser } = require('protractor');14wrapWithHelpers(browser);15const { wrapWithHelpers } = require('protractor-helper');16const { browser } = require('protractor');17wrapWithHelpers(browser);18const { wrapWithHelpers } = require('protractor-helper');19const { browser } = require('protractor');20wrapWithHelpers(browser);21const { wrapWithHelpers } = require('protractor-helper');22const { browser } = require('protractor');23wrapWithHelpers(browser);24const { wrapWithHelpers } = require('protractor-helper');25const { browser } = require('protractor');26wrapWithHelpers(browser);27const { wrapWithHelpers } = require('protractor-helper');28const { browser } = require('protractor');29wrapWithHelpers(browser);30const { wrapWithHelpers } = require('protractor-helper');31const { browser } = require('protractor');32wrapWithHelpers(browser);33const { wrapWithHelpers } = require('protractor-helper');34const { browser } = require('protractor');35wrapWithHelpers(browser);36const { wrapWithHelpers } = require('protractorUsing AI Code Generation
1var ProtractorHelper = require('protractor-helper');2var helper = new ProtractorHelper(browser);3var test = require('./test.js');4helper.wrapWithHelpers(test);5var helper = new ProtractorHelper(browser);6helper.clickWhenClickable(element(by.id('id')));7helper.clickWhenClickable(element(by.id('id')));8helper.fillFieldWithTextWhenVisible(element(by.id('id')), 'text');9helper.isElementVisible(element(by.id('id')));10helper.isElementNotVisible(element(by.id('id')));11helper.isElementPresent(element(by.id('id')));12helper.isElementNotPresent(element(by.id('id')));13helper.isElementWithTextPresent(element(by.id('id')), 'text');Using AI Code Generation
1var ProtractorHelper = require('protractor-helper');2var helper = new ProtractorHelper();3var test = function() {4  helper.wrapWithHelpers(function() {5  });6}7var ProtractorHelper = require('protractor-helper');8var helper = new ProtractorHelper();9exports.config = {10  onPrepare: function() {11    helper.wrapWithHelpers(function() {12    });13  }14}15var ProtractorHelper = require('protractor-helper');16var helper = new ProtractorHelper();17var test = function() {18  helper.clickWhenClickable(element(by.css('button')));19  helper.fillFieldWithTextWhenVisible(element(by.css('input')), 'Hello World!');20  helper.clearFieldWhenVisible(element(by.css('input')));21  helper.fillFieldWithTextWhenVisibleAndPressEnter(element(by.css('input')), 'Hello World!');22  helper.scrollTo(element(by.css('button')));23  helper.waitForElementVisibility(element(by.css('button')));24  helper.waitForElementNotToBeVisible(element(by.css('button')));25  helper.waitForElementPresence(element(by.css('button')));26  helper.waitForElementNotToBePresent(element(by.css('button')));27  helper.waitForTextToBePresentInElement(element(by.css('button')), 'Hello World!');28  helper.waitForTextNotToBePresentInElement(element(by.css('button')), 'Hello World!');29  helper.waitForUrlToContainString('google');30  helper.waitForUrlNotToContainString('google');31  helper.waitForAngularRequestsToFinish();32  helper.waitForElementToBeClickable(element(by.css('button')));33  helper.waitForElementToBeClickable(element(by.css('button')), 10000);34  helper.waitForElementToBeClickable(element(by.css('button')), 10000, 'Custom message');35  helper.waitForElementToBeClickable(element(by.css('button')), 10000, 'Custom message', 1000);Protractor is developed by Google Developers to test Angular and AngularJS code. Today, it is used to test non-Angular applications as well. It performs a real-world user-like test against your application in a real browser. It comes under an end-to-end testing framework. As of now, Selenium Protractor has proved to be a popular framework for end-to-end automation for AngularJS.
Let’s talk about what it does:
 Protractor is a JavaScript framework, end-to-end test automation framework for Angular and AngularJS applications.
Protractor Selenium provides new locator methods that actually make it easier to find elements in the DOM.
Two files are required to execute Protractor Selenium tests for end-to-end automation: Specs & Config. Go through the link above to understand in a better way.
To carry out extensive, automated cross browser testing, you can't imagine installing thousands of the available browsers on your own workstation. The only way to increase browser usage is through remote execution on the cloud. To execute your automation test scripts across a variety of platforms and browser versions, LambdaTest offers more than 3000 browsers.
We recommend Selenium for end-to-end automation for AngularJS because both are maintained and owned by Google, and they build JavaScript test automation framework to handle AngularJS components in a way that better matches how developers use it.
For scripting, selenium locators are essential since if they're off, your automation scripts won't run. Therefore, in any testing framework, these Selenium locators are the foundation of your Selenium test automation efforts.
To make sure that your Selenium automation tests function as intended, debugging can be an effective option. Check the blog to know more.
If you are not familiar with writing Selenium test automation on Protractor, here is a blog for you to get you understand in depth.
Selenium tests are asynchronous and there are various reasons for a timeout to occur in a Protractor test. Find out how to handle timeouts in this Protractor tutorial.
In this Protractor tutorial, learn how to handle frames or iframes in Selenium with Protractor for automated browser testing.
Handle alerts and popups in Protractor more efficiently. It can be confusing. Here's a simple guide to understand how to handle alerts and popups in Selenium.
Get 100 minutes of automation test minutes FREE!!
