extending angular e2e testing - angularjs

I have been using the Angular Scenario Runner for performing End To End tests on our codebase.
I am following:
http://docs.angularjs.org/guide/dev_guide.e2e-testing
Compared to frameworks such as capybara etc, the supplied matchers seem quite limited.
What options are available to help in End To End testing Angular Applications?

The next tool for AngularJS will be Protractor

you can use Selenium, of course.
One good thing that E2E does is to record all outgoing requests, so that it continues only after all of them are back with responses. This way you dont need to set a timer to check when your page is fully loaded. Not sure if Selenium supports that.

Related

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.

Detect if the environment is Protractor

In an AngularJS application is it possible to detect if the environment is Protractor?
I would like to disable certain functionality such as Geolocation when running my tests. It's not something I want to test at the moment and I am pretty sure it is what is causing my tests to fail to run.
In my App I use window.jasmine to disable certain polling actions when running Jasmine tests so something similar would be good.
i.e.
if(!window.protractor) {
geoLocationRun()
}
This doesn't work and there doesn't appear to be anything I can use on Window.
Note: I know I can mock out the geolocation which I can do if this isn't possible. Perhaps this is the best approach in any case however it would be good to know if there is a suitable solution. How do I enable geolocation support in chromedriver for Selenium?
I would recommend you to move your geo location code into an angular module. Then you can mock the module in your protractor tests using browser.addMockModule
http://angular.github.io/protractor/#/api?view=Protractor.prototype.addMockModule

Can angularjs apps be automated with selenium? if yes, why should we use protractor?

I know that we can automate AngularJs apps with Selenium. But we have a separate E2E testing framework that is Protractor for AngularJs apps automation.
Can anyone help me understand why we should use Protractor? Why not Selenium?
Not sure I understand your question. Am I right to assume you'd rather use Selenium - but want to understand what you're missing?
Well - Selenium provides means to automate web browsers - and thus used for automated e2e tests. Selenium API has implementations in several major programming languages - allowing you to write your tests in Java, C#, python, ruby, JavaScript and more.
If you already have a selenium-based e2e testing framework in place - you can use it also for AngularJS web-apps. You can also write the necessary JavaScript scripts that, once ran using the webdriver - will let you do all that Protractor does - but you'll have to do it yourself (just borrow from Protractor source code).
Why is it doable? Because Protractor basically took the JavaScript implementation of Selenium Webdriver and wrapped it in a way that makes your life a bit easier when testing Angular JS web apps.
You can see specific explanations in this old post of mine:
http://testautomation.applitools.com/post/94994807787/protractor-vs-selenium-which-is-easier
I'd say that if you:
1. want to write your test code in JavaScript
2. are focused on mainly Angular JS apps
You might want to consider using Protractor. Again - no magic there. Everything they did is there in their source code - so you can just take your picks if you'd rather stick with selenium.
protractor is an end-to-end browser automation testing framework that works through WebDriverJs which is a javascript selenium webdriver.
Quote from How it works? documentation page:
Selenium is a browser automation framework. Selenium includes the
Selenium Server, the WebDriver APIs, and the WebDriver browser
drivers.
Protractor works in conjunction with Selenium to provide an automated
test infrastructure that can simulate a user’s interaction with an
Angular application running in a browser or mobile device.
Protractor is a wrapper around WebDriverJS, the JavaScript bindings
for the Selenium WebDriver API.
Also see:
Automated e2e testing- WebDriverJS, Jasmine and Protractor
With protractor, you can write e2e tests with JavaScript, the language you write with Angular app.
Also, it has Angular-specific features.
Its element finders wait for Angular's $digest loop and $http to finish. So you'll have less chance to struggle with sleep and timing issues.
You can select elements with some of common directives such as ng-model, ng-repeat, ng-bind and etc. This is somewhat handy because you may have relatively less ids and classes in Angular apps because you need them only for CSS.

Testing a websockets server with protractor

I have a custom WebSockets server that triggers route changes in a AngularJS client. I would like to carry out e2e integration tests using protractor. As the route change events are every 30 seconds and involve multiuser interactions, it seems like creating a mock of the service is the best approach. Is there a recommended way of doing this in protractor?
I am not sure if this is exactly what you are looking for, but you can define mock services in Protractor and then upload them to the browser using Protractors browser.addMockModule function. The uploaded module will replace the real one that the application would normally use. See the following blog post for more details.
http://eitanp461.blogspot.com/2014/01/advanced-protractor-features.html
I recently had a similar problem and solved it using addMockModule as stated above. I wrote a post about it describing my solution.
http://www.functionalimperative.com/2015/04/22/protractor-socket-mocks.html
I found organizing my code a certain way helped when mocking the socket modules.

PhantomJS integration testing with angular against live backend

I am trying to make my e2e test environment to be like the actual production environment. I discovered that when I take out the ngMockE2E from my app and run tests that actually hit the backend server then all my tests in PhantomJS fail. In all other browsers tests always pass.
I'm not sure what the cause of this is. All I know is that when I put the ngMockE2E back in then all tests pass in PhantomJS and when I take it out the tests that depend on the xhttp request fail.
One more thing the live backend is cross origin. But like I said it works fine in all other browsers. I'm wondering if PhantomJS doesn't have cors support.
Does anyone know how to remedy this? Am I supposed to always use the mocks?
For E2E testing with a real back end, I would consider using Protractor. As far as I know, ngMock and ngMockE2E are both made to fake a connection to a real server. With these libraries you can unit test your Angular project so that it works isolated.
Note that it is a bit more work to setup E2E testing with Protractor if you start from scratch. There are however also starter projects (Yeoman), which already have this setup for you. You could use generator-angular-gulp for example for your application, or you could have a look how they have set things up.

Resources