What is the Protractor way to test what is shown before Angular loads - angularjs

I believe that it's a good practice to inform users that an Angular-based application is loading. I mean, in case of Angular 2, it's e.g. <view>Loading...</view>. I am sure that there is a way to do the same in AngularJS (v1) as well. Thus I believe that there should be a way to use Protractor to test such aspect of the application since it is "an end-to-end test framework for AngularJS applications".
It was suggested to me that there is a way to do that and that I should ask here. So, can you please help me to find the approach which had Nick on his mind? It does no necessarily has to be compatible with Angular 2 already. AngularJS (v1) approach would be enough since I believe that it will be ported once they port Protractor.
This question seems to be similar to Protractor: test loading state but unlike OP I want to make sure that the Angular application is not loaded before the test finishes so I guess that there should be a way to suspend/stop loading of the application (but I may be wrong).

I typically avoid testing things like this because they tend to be very flakey. Unless there's some requirement to test the loader I would not do so.
You can use browser.ignoreSynchronization = true to not wait for angular to load on the page, and then assert that your loader is there.
The only issue with this is that you will struggle with ensuring that angular has not loaded. There's no great way of preventing your angular application from bootstrapping unless you manually bootstrap and build in some sort of delay or "no-bootstrap" trigger but that starts compromising your application just to test a loading state.

Just to add to #Nick's point, you would definitely need to turn the synchronization between protractor and angular off and set browser.ignoreSynchronization = true;.
Then, you can/should add an explicit wait to wait for the loading indicator (for instance, it may be a spinner image) to become visible:
var EC = protractor.ExpectedConditions;
browser.wait(EC.visibilityOf(element(by.id("#loading"))), 5000, "Loading indicator has not become visible");
A timeout error would mean that the loading element (in this case the element with id="loading") has not become visible in 5 seconds.
Don't forget to turn the sync back on after the test is completed:
browser.ignoreSynchronization = false;

Related

Force Reload of AngularJS Pages

Is there any way with AngularJS to force a page to refresh after it has been changed. What I mean by this is that I have multiple users actively working in the app but a change is required to the controller.js file. At this point the only way I'm aware of is for them to manually push refresh on the browser. Is there any code that I can use to make it "actively" watch that file for changes and reload when necessary without the users having to manually push refresh?
This isn't really an angular problem. You can do polling on the client side with setInterval, hitting the file on the server to trigger a refresh on the client.
If you're looking for something to speed up development, then you're probably looking for hot module loading. The solution depends on what version of angular and build tool you're using (e.g. grunt/webpack/npm).
Check out this article for angular 2, but you can find similar solutions for angular 1:
http://blog.mgechev.com/2015/10/26/angular2-hot-loader-hot-loading-tooling/
But if you just want to force a page refresh from the client side, you would just call: $window.location.reload()

Protractor browser.driver.getCurrentUrl vs browser.getCurrentUrl

I'm running an Angular app and I'm trying to get the current URL when testing on protractor. Which one to use?
browser.driver.getCurrentUrl() or browser.getCurrentUrl() ?
If this is an Angular application under test - use browser, otherwise - browser.driver.
To quote #jmr from a relevant github issue:
If you need to interact with a non-Angular page, you may access the wrapped webdriver instance directly with browser.driver.
Though, note that both are gonna work if this is Angular application under test. Some people even said that found browser.driver more reliable if it the sync time is longer than usual:
Just to add to this - I find that browser.driver works better on AngularJS apps that take time to sync. I have tried both and for some reason browser.driver is more reliable.
Though, I've personally used browser.getCurrentUrl() and cannot recall any problems.

Protractor: Polyfill Function.prototype.bind in PhantomJS. Can't make it work, is it even possible?

I've spent the afternoon on this and am making no progress, I'm really starting to wonder if it's even possible.
I'm using Angular with Headroom to handle a menu disappearing when scrolling down. My testing is done with Protractor, using PhantomJS, and this is where the fun begins.
PhantomJS does not support .bind() and Headroom uses it all over the place, which means I need to polyfill it. It should be no problem, but I can't make it work.
I think my problem is that no matter where I run the polyfill function, PhantomJS and the tested page are already loaded, so it's already too late, Headroom will have failed to load due to .bind() not being available.
Is there any way to run those methods before the page is loaded? I know I could add them to my application via a script tag in the head, but I'd rather not add something to the whole app that will only be used by the testing framework.
I think I have a workaround for that. (at least give it a shot and we'll see if it's working or not) The best u can do is to patch your phantomJS browser to have this method supported. Basically u should run a script before every specs, so that it can apply to the global scope and will be available to your specs.
Just try to extend your specs configurations. Here is an example:
...
specs: ['my_phantomjs_bind_patch.js', 'webtests/**/*.js']
...
You cant run scripts before the actual page load as they are a part of the dom tree .What you can do is : `
window.onload = function() {
//do something
};
but even when the onload event is fired the tag must be rendered. So you should try your idea and add one script tag before all other elements to your html and run the code there, if it's just for a test run.
`
`

With Protractor 1.0.0 rc2 + is the browser.waitForAngular() still required?

I was watching a youtube video and in that there was an example:
loginPage.userName.sendKeys ...
loginPage.password.sendKeys ...
loginPage.loginButton.click();
browser.waitForAngular();
expect( ...
I thought Protractor was coded in such a way that it would do the wait without the need for a browser.waitForAngular().
Can someone confirm if I need the waitForAngular() in this example?
I think that whether you need browser.waitForAngular() depends on the application you're testing.
Not 100% sure on what the conditions are, but I have found that I required this method when my test is performing a task that requires a response from a server, such as changing a user's password in a web app.
On another note, in my experience, browser.waitForAngular() is not robust enough to handle every type of wait condition I've needed to perform.
For example, I'm writing tests for a web application where the user logs in through a non-Angular page and is directed to an Angular page. If I want to make assertions to test the elements present on the login landing page, I can't use browser.waitForAngular() because non-angular pages do not have access to this method. I've found that a more reliable way to tell the driver "wait for the page to fully load, then check the text present on the page" is to use browser.wait to explicitly wait for the presence or visibility of an element on the next page that you know will take the longest to load.

Get the ExtJS Active Ajax call count

I am working in selenium to test the ExtJs application. My problem is, I need to ensure the page is completely rendered. I cant use selenium.waitForPageLoad. In normal Ajax application i can use "Ajax.activeRequestCount", which will give the Ajax call count. If it is '0' We can ensure the page is completly loaded. Is there any similar function available in ExtJs? Can any one pls help me on this
There is no such method in ExtJs. You can however create handlers for global Ext.Ajax events beforerequest and requestcomplete http://docs.sencha.com/ext-js/4-0/#!/api/Ext.Ajax-event-beforerequest and count active connections yourself.
Or, if the Selenium tests are to be run in modern browsers, you could try Progress Listeners (with these).
For Firefox, you could create a simple addon that would wait for async requests to complete, and ship that addon with your Selenium tests.

Resources