Push against long polling test

I have an Angular web app that listens for notifications from the backend all the time via a long-poll:

scope.notification = $resource('/notification').get();

      

This request never completes in a test environment. This is a problem for Protractor because it wants to wait for all outstanding HTTP requests to complete.

I see a number of potential solutions, but I have some problems with all of them.

I see no way to tell Protractor to ignore this request. Giving it out $interval

(which itself is ignored) is not a solution. The protractor will not wait for the request to be sent, but after submitting it, it will still wait for completion.

So I try not to send this request when running tests. But how do I know if I have a test?

  • I can add a flag to the url ( ?protractor=true

    ). But my web app keeps changing the url so it clears up quickly.
  • I tried setting a variable: browser.executeScript('window.runningProtractorTests = true;');

    But it seems like Protractor will wait for the page to sync before launching executeScript

    . And I send the request right after the page loads.
  • I can set a cookie. But this is quite cumbersome, for example. I will have to load the page twice. (See question 341 for details .)
  • I can install user agent. It's not easy either. I need to set browser flags for each browser in a config file. I do not want to completely override the user agent (for example Protractor

    ) for fear that my libraries might rely on interpreting the user agent string, so I would need to define the correct string.
  • I can check if the server is running on a specific port. But after a year someone will try to start a production server on the same port and not understand why notifications are not working.
  • Creating the test backend completes the request immediately, it doesn't help because it is immediately dispatched again when it completes. But I think I could introduce a special notice "you are in trial" and stop polling when received. This would mean a (slight) change to our protocol, so I would rather avoid it if possible.

Is there no easy way to do this?

+3


source to share


2 answers


Can you place calls to $resource

the service you are mocking with Protractor browser.addMockModule()

? This way, Protractor will always override your original service before it can start.

It might look something like this:



// in your application
myModule.service('myNotificationService', function($resource) {
  this.notification = $resource('/notification').get();
});

// In your Protractor test
browser.addMockModule('notificatonOverride', function() {
  angular.module('notificationOverride').service('myNotificationService', function() {
    this.notification = {}; // or whatever you need here.
  });
});

      

+4


source


Try loading the view with browser.driver.get('http://myapp')

. Calling webdriver api directly will not wait for angular to be ready.

Then you can run your script.

browser.driver.executeScript('window.runningProtractorTests = true;');

      



And then keep using the protractor api.

You may need to add browser.waitForAngular () to make sure angular is ready before continuing testing.

+1


source







All Articles