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

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.

Related

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

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;

Asserting $http request payloads without mocking them

I'm writing Protractor tests to verify the successful creation of reports in our application. A report is created via a series of complex UI interactions within a dialog and saved via an AJAX POST request to a REST API.
I've written tests for the complex UI interactions within the modal, but I'm at a loss for how to test the POST request within the same Protractor tests. Ideally, I'd like to be able to make assertions against the payload of the POST request to verify that the UI is sending the correct data to the API.
It's important to note that I do not want to mock the HTTP call--I need it to go through, since subsequent protractor tests navigate to the report and perform additional checks. My first thought was to somehow hook into the $httpBackend.passThrough() method, but I haven't had any success with that.
Any ideas how to accomplish this?
since subsequent protractor tests navigate to the report and perform additional checks
If you check that the report contains data to that matches which was submitted, you are, albeit indirectly, testing that the POST went through successfully. There is a reasonable argument that this is enough for the E2E test: it tests that the application behaves as he user would want. The user doesn't care how it's achieved: POST, websockets, carrier pigeon ;-)
Keep in mind that the usual aim of such tests is for them to fail if something is broken. If the POST isn't done correctly, then the subsequent tests that verify the displayed report would fail.
The downside is that you would have a bit less information about what has gone wrong than if you managed to test the POST as well. However, unit tests can help. If you have a failing unit test that localises the issue, you write a fix that makes it pass. If you don't have a failing unit test, you can investigate the issue by debugging, add a failing test that highlights the issue, and fix the code so it passes.

Single Server request per page vs SPA Application

I had the idea to make a SPA application using angularJS and then just sending AJAX updates to the server when I need.
My initial idea would be make the client application fly, but if I have to do an AJAX round trip to the server, I think the time would be approximately the same as to request a single web page.
Requesting a page just has more bytes of data, is not like I'm requesting 20 resources like in this article: https://community.compuwareapm.com/community/display/PUB/Best+Practices+on+Network+Requests+and+Roundtrips
I would be requesting a page or resource per request.
So in the end even if I create my client side application as a SPA using angularJS, these requests (would have to be synchronous and show a please wait message while they don't return, as I don't want to user to take more actions before I make sure his request passes validation and is processed correctly) would take some time and make user wait, just about the same time as requesting a full page.
I think SPA pages would be very useful if I have like a wizard on my app with multiple pages/steps and at the end, submit the results of wizard, to the server, which I don't.
Also found this article:
https://help.optimizely.com/hc/en-us/articles/203326524-AngularJS-Backbone-js-and-other-Single-Page-Applications
One of the biggest advantages of Single Page Apps is that they reduce
data transfer. As a result, pages after the initial loading usually
can be displayed faster and seem more interactive.
But I don't believe this last quote is really true.
Am I right, or is there a way that I'm not seeing to build an application that would look like it's executing locally?
I know how guys will start saying "depends on what you want", but lets focus on this scenario where there's no wizards.
What ever you said is right. But most of the frameworks(Angular,BackBone) you take they are going to cache the templates of html on the browser so the rendering would be pretty fast compared to the normal applications. Traditional apps will have to fetch the html from the server for each request which is a time consuming one.
Hope this helps you!!!
If you are wanting to go through that syncronous server side validation step for each page request, then there is probably no big advantage to using AngularJS.
If you are requesting a page and then manipulating that page's contents once it's loaded you might want to consider AngularJS. A good example would be requesting a page that displays a list of items. Now let's say we want to search that list or order it in different ways. Rather than using AJAX to call the server to filter the list and then re-render it, it could be much faster to user AngularJS to filter and re-render the list without making any further requests to the server.

AngularJS e2e tests hang when changing between two separate angular apps

I have a frustrating problem: I want to write end to end tests for a complex angular app. The problem is that the login screen is a separate app. The initial idea was that it would branch out to separate other angular apps in our ecosystem based on the login credentials. It works like a charm. For the tests it is a nightmare though.
The tests work as expected but as soon as correct credentials are entered and the main angular app is loaded the tests just time out. No error message or debug output whatsoever, its just waiting. I can see the page is loading correctly.
Now I thought I would skip this part and test right on the target app but thats not working either since I need to initialize the server with the right credentials first (= go through the login screen).
I tried this with the karma scenario runner and protractor, both show the exact same behavior. Can I tell them to reinitialize after the target page is loaded?
So when protractor times out, the error message shows a link to the faq. Right on top there's the explanation for this problem. Apparently the app sends continuous requests (maybe because I am using socket.io), so Angular is never finished.
This problem has nothing to do with the separate apps.
The issue link was very helpful. Since I am not willing to touch any of the pages code I settled with
browser.ignoreSynchronization = true;
and
browser.sleep( ... );
The tests now work as expected.

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