How to revert override browser.waitforAngular in protractor

Viewed 158

I have a regression suite automated using Protractor & Jasmine. Application under test recently became hybrid application, bootstrapped with NgUpgrade. after the upgrade, scripts are timing out in accessing some of the elements. I have added below script to override the waitforAngular function which is the fix for time out issue. However this will not work for login (non angular page)I need to revert this override for non-angular page. wondering if anyone can provide any help on this

**var script = "var callback = arguments[arguments.length - 1];" +
"angular.element(document.querySelector(\"body\")).injector()" +
".get(\"$browser\").notifyWhenNoOutstandingRequests(callback)";
browser.waitForAngular =  ()=> {
return browser.executeAsyncScript(script);
}**
4 Answers

To override the default behaviour of Protractor to wait for Angular calls, you can disable the Angular wait by: browser.waitForAngularEnabled(false)

However, Protractor's Documentation recommends using wrapped driver directly instead of toggling the waitForAngularEnabled property which can lead to unstable script.

An alternative would be to use browser.driver.<whatever> instead of browser.<whatever>:

Example:

  • browser.get When the web page has Angular components
  • browser.driver.get When the web page doesn't have Angular components

I have tried the solution browser.waitForAngularEnabled(false) in below on a non angular page but it is still going into browser.executeAsyncScript(script) and throwing error "angular not defined"

 this.specStarted = function (result) {
      browser.executeScript("return !!(window.angular || window.ng);")
        .then(function(isAngular){
          if(isAngular) {
            console.log('angular page ');
            var script = "var callback = arguments[arguments.length - 1];" +
              "angular.element(document.querySelector(\"body\")).injector()" +
              ".get(\"$browser\").notifyWhenNoOutstandingRequests(callback)";
            browser.waitForAngular =  (test)=> {
              if(test){
                return browser.executeAsyncScript(script);
              }
            }
          }
          else {
            browser.waitForAngularEnabled(false);
            console.log('not an angular page');
          }
        });
    };

One solution can be modifying default angularEnabled behaviour. By default, waitForAngularEnabled is true. You need to modify this by-default behaviour by using waitForAngularEnabled(false). But keep in mind that it totally depands on the sequence of scripts running. i.e. If you are logged-in in app and now want to navigate to login page (non-angular page), You need to disable this by-default behaviour and whenever you enter another page i.e. Angular Page, You should enable its by-default behaviour.

Let me know if it helps!!!

Thank you all, this issue is resolved with the below code

browser.waitForAngular = function(){var script = "var callback = arguments[arguments.length -1]" +"angular.element(document.querySelector(\"body\")).injector()" +".get(\"$browser\").notifyWhenNoOutstandingRequests(callback)";
  if (!this.ignoreSynchronization) {
    return browser.executeAsyncScript(script);
  }
    else
  {
    return this.driver.controlFlow().execute(() => {
      return true;
    }, 
    'Ignore Synchronization Protractor.waitForAngular()')
  }
};

Related