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 launchingexecuteScript
. 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?
source to share
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.
});
});
source to share
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.
source to share