The definitive method for resolving synchronization problems between Protractor and Angular

The Issue at Hand:

We recently encountered a common error while attempting to open a specific page in our application during a Protractor end-to-end test:

Error: We timed out waiting for asynchronous Angular tasks to complete after 50 seconds. This could be due to the current page not being recognized as an Angular application.

This error arises when we make a browser.get("/some/page/"); call in one of our test cases:

describe("Test", function () {
    beforeEach(function () {
        browser.get("/some/page/");
    });

    it("should test something", function () {
        // ...
    });
)};

What baffles us is that this error only occurs on this particular page within our Angular web application - Protractor seamlessly syncs with Angular on all other pages. The placement of ng-app is consistent throughout our site - it is defined on the root html tag:

<html class="ng-scope" lang="en-us" ng-app="myApp" ng-strict-di="">

This behavior remains consistent - each time we navigate to this problematic page using browser.get(), the error surfaces. When navigating to any other page, synchronization works flawlessly.

While we can disable sync for this page and treat it as non-angular, this is merely a temporary fix.

The Queries:

What other factors could lead to Protractor failing to synchronize with Angular? What steps should we take to troubleshoot?

Furthermore, what strategies are recommended for debugging sync issues in Protractor?

We are currently utilizing the latest versions of Protractor 5.5.1 and Angular 1.5.6.

Answer ā„–1

After being intrigued by that question, I delved into finding a programmatic solution to determine what Protractor is waiting for:

var _injector = angular.element(document).injector();
var _$browser = _injector.get('$browser');
var _$http = _injector.get('$http');
var pendingTimeout = true;

//this method resembles what Protractor uses while waiting to sync
//if the callback is called immediately, it indicates no $timeout or $http calls are pending
_$browser.notifyWhenNoOutstandingRequests(function callback () {
  pendingTimeout = false
});

setTimeout(function () {
  //this helps differentiate between $http and timeouts from the "notifyWhenNoOutstandingRequests" method
  if (_$http.pendingRequests.length) {
    console.log('Outstanding $http requests', _$http.pendingRequests.length)
  } else if (pendingTimeout) {
    console.log('Outstanding timeout')
  } else {
    console.log('All good in Angular, must be something else causing delay')
  }
}, 100)

Feel free to experiment with the timeout and $http call in this Plunker link. My delayed endpoint will wait for 10 seconds before resolving the call. Hopefully, this information proves helpful to you.

Answer ā„–2

My thoughts align with @maurycy's perspective that the issue stems from $http/$timeout interactions. One common solution is to substitute $timeout with $interval, which is well-documented here: https://github.com/angular/protractor/blob/master/docs/timeouts.md

Suggestions:


merge these reasonable defaults: 
  allScriptsTimeout: 60000, // 1 minute
  jasmineNodeOpts: {
    defaultTimeoutInterval: 300000 
    // 5 minutes. Allows for 5 commands spanning the full synchronization timeout.
  }

If pinpointing the root cause of the $http/$timeout problem is your goal, consider utilizing angular decorators to implement custom logic around these services. This can also be beneficial for mocking angular services that interact with third-party services. https://docs.angularjs.org/guide/decorators

//DISCLOSURE: Unlinted & Untested.
beforeAll(() => {
  browser.addMockModule('culpritMock', () => {
    angular.module('culpritMock', [])
      .config(['$httpProvider',
        $httpProvider => $httpProvider.interceptors.push('httpCounterInterceptor')
      ])
      .factory('httpCounterInterceptor', ['$q', '$window', ($q, $window) => {
        if ($window.httpCounterInterceptor == null) {
          $window.httpCounterInterceptor = {};
        }
        return {
          request: config => {
            $window.httpCounterInterceptor[config.url] = 'started';
            return config;
          },
          response: response => {
            $window.httpCounterInterceptor[response.config.url] = 'completed';
            return response;
          },
          responseError: rejection => {
            $window.httpCounterInterceptor[rejection.config.url] = 'error';
            return $q.reject(rejection);
          }
        };
      }])
      .decorator('$timeout', ['$delegate', $delegate => {
        const originalTimeout = $delegate;
        function modifiedTimeout() {
          console.log(arguments);
         return originalTimeout.apply(null, arguments);
        }
        modifiedTimeout.cancel = function(promise) {
          return $delegate.cancel(promise);
        }
        return modifiedTimeout;
      }]);
  });
});

Similar questions

If you have not found the answer to your question or you are interested in this topic, then look at other similar questions below or use the search

Record the success or failure of a Protractor test case to generate customized reports

Recently, I implemented Protractor testing for our Angular apps at the company and I've been searching for a straightforward method to record the pass/fail status of each scenario in the spec classes. Is there a simple solution for this? Despite my at ...

The constructor error in ng-serve signalizes an issue in

Currently, I am developing an AngularJS application. However, when attempting to start the dev server, I encountered an issue with my ng serve command: https://i.stack.imgur.com/QujSe.png ...

Using async/await in a for loop | The await keyword can only be used inside an asynchronous function

I've been attempting to execute the following code: async function verifyExistingUsers(db, users) { return new Promise((resolve, reject) => { var companies = [] for (const [index, user] of users.entries()) { let comp ...

Steps for choosing an option in MUI select list using jest

I am looking for a way to automate tests for a Material UI select component using Jest. Is there a way to select an option from the list of options in the Material UI component and confirm that its value has been successfully populated in Jest? I have se ...

Issue with Firefox compatibility in Backbone.js

Greetings! I am currently utilizing Backbone.js and require.js for my application, experiencing difficulty with template rendering in Firefox. Interestingly, it works without issues in both Chrome and IE. Allow me to present the code responsible for rende ...

Utilizing jQuery to submit the form

After clicking the search icon, it displays an alert with the message ok, but not h. Based on the code snippet below, it is intended to display alerts for both ok and h. <?php if(isset($_POST['search'])){ echo "<script type='text/ ...

What techniques can I employ to ensure that withLatestFrom() effectively interacts with itself?

In my program, I have an intermediate stream that is connected to a source, but it can also trigger events from other sources (such as user input). In another part of my code, there is a derived stream that needs to compare new data from the intermediate w ...

Using Jquery to toggle the visibility of divs based on radio button selections

I am struggling to hide the divs with the radio buttons until their title is clicked on. However, I am facing issues as they are not showing up when their title is clicked on. Any assistance would be greatly appreciated. SPIKE <!DOCTYPE html> &l ...

Trigger the click event on the ul element instead of the li element using jQuery

Is there a way to make the click event only affect ul tags and not all li elements using jQuery? <!-- HTML --> <ul class="wrap"> <li>test1</li> <li>test2</li> <li>test3</li> </ul> I attemp ...

Express JS encountering Firebase Google Sign-In glitch

Whenever a user clicks a button on the HTML page, this function is triggered. The function resides in auth.js and it is called from the server.js page. auth.js const firebase = require("firebase"); static googleSignIn(req,res){ firebase.aut ...

ReserveYourSpot: Effortless Seat Reservation with AngularJS at the Click of a Button [GIF]

ReserveYourSpot: An innovative AngularJS application designed to streamline the process of reserving seats for a movie show, similar to popular platforms like BookMyShow. https://i.stack.imgur.com/PZk1I.gif Interactive User Functions (Use Cases): A ...

Retrieving the value of a JavaScript variable using Selenium with Java

Struggling with extracting data using JavaScriptExecutor: JavascriptExecutor js = (JavascriptExecutor) driver; System.out.println(js.executeScript("return myArray;")); Encountering an exception message: org.openqa.selenium.WebDriverException: unknown ...

Can we retrieve the CSS of an element?

Using Selenium's webdriverJS, I have automated tasks on an HTML5 page. To incorporate a CSS selector into a function, I had to rely on XPath for selecting elements: var complexXpath = "//*/div/a"; /* This is just an example */ var element = mydri ...

Working with numerous query parameters within AngularJS

When interfacing with an external service, Iā€™m receiving query parameters in the following format: url/?error=someError&error_description=someErrorDescription In my app.js file, I have attempted to handle this using the routeProvider as shown below ...

What is the best way to choose a specific row with Enzyme?

We have chosen Jest for doing UI Test-Driven Development on our React application. Our component rendering structure looks like this: <Div> <Row> </Row> <ROW> <Row> <ROW> <Link> <Link> ...

Selenium Python can seamlessly bypass explicit waits without any errors

I've been working on a bot that logs into my account. Once I enter the username and password, my bot is supposed to click on the "I'm not a robot" reCAPTCHA checkbox. However, sometimes after clicking the reCaptcha checkbox, another reCaptcha wi ...

What could be causing redux.props.reducer to return undefined?

I recently encountered an issue with my code. I have a function in the actions folder that successfully fetches a URL using axios. However, there seems to be a problem when trying to retrieve the data from the reducer. I have a mapStateToProps function set ...

Click on a regular key on the Selenium/Python website

Is there a way to send keystrokes like "Q", "W", "E", or "R" without targeting a specific element on the website? I attempted using send_keys on a random element, but it didn't work and Selenium reported that it couldn't interact with the element ...

How to Pause or Temporarily Halt in Jquery?

Looking to lift the object up, wait 1000ms, and then hide it. I found this snippet of code: $("#test").animate({"top":"-=80px"},1500) .animate({"top":"-=0px"},1000) .animate({"opacity":"0"},500); However, using ".animate({"to ...

Having difficulty uploading an image to Facebook through the graph API

I have a requirement to upload a photo to Facebook using the Javascript SDK, but I am experiencing some difficulties: Firstly, FB.login(function (response) { if (response.authResponse) { va ...