Displaying Test Result Summary with Protractor - angularjs

I have an AngularJS app that I am using end-to-end testing on. This app relies on Protractor and Jasmine for testing. I'm running my tests via a Grunt task.
Does anyone know of a task or a way to display a summary of Protractor's test results in the command line? Currently, I have time-grunt to display a summary of how long each task took. I'd love to have the ability to show something like 'Ran [x] tests. [y] Succeeded. [z] Failed.'
Thank you

You can add a consoleReporter. It's a little more verbose, but it does give a summary at the end.
Using jasmine-reporters you can add several reporters. My favorite is the HtmlReporter that takes screenshots when the test fails. Below is an example of several reporters configured in the protractor.conf.js
onPrepare: function () {
require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmine.JUnitXmlReporter('reports', true, true));
jasmine.getEnv().addReporter(new jasmine.ConsoleReporter());
jasmine.getEnv().addReporter(new HtmlReporter({
baseDirectory: 'reports/screenshots' ,
takeScreenShotsOnlyForFailedSpecs: true
}));
},

If you want to tweak what you display in the console you can use jasmine-spec-reporter:

Related

Protractor Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds

I started with basic protractor test to test the title of the page. I am using angular 2.4.10 and "protractor": "^5.1.2" When I run the protractor, I get this error.
Failed: Timed out waiting for asynchronous Angular tasks to finish after 11 seconds. This may be because the current page is not an Angular application.
this is my sample code
//protractor.config.js
exports.config={
seleniumAddress: 'http://localhost:4444/wd/hub',
specs:['index.spec.js'],
capabilities: {
'browserName': 'chrome',
},
useAllAngular2AppRoots: true,
framework: 'jasmine',
};
//index.spec.js
describe('hello-protractor', function() {
it('title', function() {
browser.get('http://localhost:8100/#/');
var title = element(by.cssContainingText('My Dashboard Title'));
expect(title.getText()).toEqual('My Dashboard Title');
expect(title.getAttribute("text")).toEqual('My Dashboard Title');
});
});
I referred this link to fix https://github.com/angular/protractor/blob/master/docs/timeouts.md#waiting-for-angular
I set this attribute to allScriptsTimeout:30000 but it showed me **Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL**
From the information you have given it seems like either the page you are testing doens't contain the angular element or the timeout needs to be increased.
Ok here is the solution you have increased the Protractor specific time out.
But you can override the jasmine time out too.
try including this in the config.js file.
jasmineNodeOpts: {
isVerbose: true,
showColors: true,
defaultTimeoutInterval: 400000
},
Also i saw that you have mentioned the framework:jasmine.
Are you sure this is just jasmine or jasmine2?
If you are using jasmine2 version please change that to framework:'jasmine2'
Kinldy let me know if it works.
And if it works please consider accepting my answer and up voting it.

Loading ngMock only in testing context when using Protractor

I'm switching all of our protractor E2E tests of an angular app to ngMock, so that we can mock our resources/http calls. However, I can't find a recommended method for loading ngMock in that scenario.
I don't want to include the script itself in my live app of course, but I'm not seeing a clear method through protractor for injecting an extra script element, or dynamically loading it.
You can do is to use grunt-targethtml or gupl-targethtml so in your index.html you can add conditions of when to add an script or not:
<!--(if target mock || e2e)><!-->
<script src="dev-mocks/mock-utils.js"></script>
<script src="dev-mocks/modules/authentication-service-mock.js"></script>
<!--<!(endif)-->
First configure your grunt task to execute the targethtml task with the target e2e/mock
grunt.registerTask(
'e2e',
'Automated tests',
function(target) {
var tasks = [
'clean:server',
'targethtml:e2e',
'concurrent:server',
'autoprefixer',
'connect:e2e'
];
return grunt.task.run(tasks);
});
Here is a working template with all the tasks, packages and logic necessary to implement Protractor + CucumberJS + sugar-step (for easy sync-async steps executions), and also inject mock modules dinamically using the #Around method of CucumberJS

Taking screenshots in BrowserStack running Protractor

Hello!
I'm trying to take screenshots in protractor and browserstack, I've the following conf.js file:
var HtmlReporter = require('protractor-html-screenshot-reporter');
var reporter=new HtmlReporter({
baseDirectory: './protractor-result', // a location to store screen shots.
docTitle: 'Report Test Summary',
docName: 'protractor-tests-report.html'
});
// An example configuration file.
exports.config = {
// The address of a running selenium server.
seleniumAddress: 'http://hub.browserstack.com/wd/hub',
// Capabilities to be passed to the webdriver instance.
capabilities: {
'browserName': 'chrome',
'version': '22.0',
'browserstack.user' : 'user_name',
'browserstack.key' : 'user_key',
'browserstack.debug' : 'true'
},
// Spec patterns are relative to the current working directly when
// protractor is called.
specs: ['./specs/home_page_spec.js'],
// Options to be passed to Jasmine-node.
jasmineNodeOpts: {
showColors: true,
defaultTimeoutInterval: 30000
},
onPrepare: function() {
jasmine.getEnv().addReporter(reporter);
}
};
And the browserstack help says that I need to add the following lines:
var fs = require('fs');
webdriver.WebDriver.prototype.saveScreenshot = function(filename) {
return driver.takeScreenshot().then(function(data) {
fs.writeFile(filename, data.replace(/^data:image\/png;base64,/,''), 'base64', function(err) {
if(err) throw err;
});
})
};
driver.saveScreenshot('snapshot1.png');
Does any one could point me to where to add these lines? and how? (I'm also using PageObject pattern)
I think you are talking about two things, one is the plugin for making screenshots and the second is a creating screeshots manually within your test code regardless a plugin.
In theory, the plugin should make screenshots for you. If not you can create them manually with the code provided from browserstack, just put in anywhere in your test code after some expects.
Anyway, to make screenshots from protractor I recommend use protractor-screenshoter-plugin
(disclaimer: I am the author), also you can have a look at Protractor-Screenshots-Alernatives
Now in one of the branches I have a new support for parallelization. Have a look at https://github.com/azachar/protractor-screenshoter-plugin/tree/feat-parallel-support.
To install the unstable version that contains the parallelization support use
npm install azachar/protractor-screenshoter-plugin#feat-parallel-support
to install stable version without parallel support, just type as usual:
npm install protractor-screenshoter-plugin
Let me know if it works as expected!
Cheers,
Andrej

Any easy way to add build version info to coverage test results

I am using karma-coverage to measure the unit test coverage in my project and everything works in that regard just fine. I use HTML reporter into default directory.
However, I would need to "stamp" the coverage report with the build version information that I do have available using grunt-git-describe, which is currently used in the AngularJS app footer that loads the resulting version.json file. I didn't find any direct way to use this version.json file in the html reports from karma-coverage. So if anybody has a good idea how to do it, I would appreciate a lot.
Thanks in advance!
I did manage to implement this with a sort-of work around. I use text-replace module in grunt after running karma to do this. If some one has a better solution, please share as this is a bit of a hack, but it works ok. As karma-coverage's html reports in my environment goes to the projects' root /coverage/ folder, I made a recursive text replace into every .html file there looking for the default footer and adding my version info there...
First, installed grunt-text-replace
$ npm install grunt-text-replace --save-dev
Then I made a following replace function in gruntfile.js:
grunt.initConfig({
replace: {
coverage: {
src: ['coverage/**/*.html'],
overwrite: true,
replacements: [
{
from: '<div class="meta">Generated by',
to: function(){return grunt.config.get('task.replace.versionString');}
}
]
}
},
// and your other stuff in initConfig()
And I added a new task into grunt for this:
grunt.registerTask('coverage', 'Adds version info to coverage results', function(){
grunt.task.requires('version'); // The 'version' task creates a 'version.json' file
var vers = grunt.file.readJSON('version.json');
// Set the desired string to be used in text-replace -function
grunt.config.set('task.replace.versionString', '<div class="meta">Version ' + vers.version + ', Tag "' + vers.revision[0] + '"<br>Generated by');
grunt.task.run(['replace']);
});
A bit ugly but works like a charm ;-)

Protractor: timed out after 10000 msec waiting for spec to complete

I have several protractor tests and sometimes I get a error saying:
Message:
timeout: timed out after 10000 msec waiting for spec to complete
Stacktrace:
undefined
It can be randomly happening on some tests.
I usually test on BrowserStack and it shows the error once in 3-5 builds. But recently I tried SauceLabs and almost every (every!) but not all the tests fail with that error. Probably, SauceLabs are just significantly slower so I get the error more often...
So here are the questions:
Is there a way in Protractor/Selenium to change test running timeout? It needs to be changed on BrowserStack/Saucelabs as well.
Why am I getting the error so often? Is there anything wrong with my tests? Most of the doesn't seem complicated or long running. Again, on local machine it's almost always fine.
Here is the example:
it('should check that login gives error on empty or incorrect email', function () {
p.get('/#/login');
p.findElement(protractor.By.css('button[type="submit"]')).click();
expect(p.findElement(protractor.By.css('.alert-danger')).getText()).toEqual('E-mailadres is niet geldig');
p.findElement(protractor.By.model('user.email')).sendKeys('test-1xtc.vc');
p.findElement(protractor.By.css('button[type="submit"]')).click();
expect(p.findElement(protractor.By.css('.alert-danger')).getText()).toEqual('E-mailadres is niet geldig');
p.findElement(protractor.By.model('user.email')).clear();
});
The app is using
AngularJS, selenium 2.20, protractor 0.20.1
Is there a way in Protractor/Selenium to change test running timeout?
Yes :) You can do it via the allScriptsTimeout in your Protractor config (from Protractor FAQ)
You can also set the defaultTimeoutInterval in jasmineNodeOpts option (from Protractor referenceConf.js)
Why am I getting the error so often? Is there anything wrong with my tests? Most of the doesn't seem complicated or long running. Again, on local machine it's almost always fine.
Hard to say without seeing your tests. The example you provided looks good to me.
Is your project an angularjs project? Are you using any $interval or $timeout service somewhere? If so, try to use $interval instead of $timeout and try to adjust the optional 'count' parameter to be 1, for example (https://docs.angularjs.org/api/ng/service/$interval#usage).
I had recently a similar problem and I solved it this way.
I solved it using a different property of config file, which I didn't see mentioned in answers above.
getPageTimeout : 100000 //in millis, i.e., 100 secs
the default time for saucelabs is 90 seconds I believe. it can be changed via your conf.js file using the idleTimeout variable which takes in a value of seconds. example
idleTimeout = 90; // equals 90 seconds
exports.config = {
//Includes test sub-sub-foldersbefore any tests in sub folders
specs: ['tests/*/*/*.js', 'tests/*/*.js', ],
// use jasmine 2
framework: 'jasmine2',
capabilities : {
browserName: "chrome",
// this takes seconds so 120 would be 120 seconds.
idleTimeout = 120;
},
},
Now if you need to change the value of a specific spec file you can use this inside your spec file, of course if your saucelabs idleTimeout is lower than this value than it will time out on saucelabs first. or if your saucelabs value is higher but the DEFAULT_TIMEOUT_INTERVAL is lower then it will time out.
// this takes in miliseconds so 1000 = 1 second
jasmine.DEFAULT_TIMEOUT_INTERVAL = 120000;
Jasmine has timeout for each spec i.e. each it in jasmine framework. so if any spec (it) exceeds jasmine spec's default timeout then it fails that spec.
Solution:
To override jasmine spec timeout for one individual spec, pass a third parameter to it:
it(description, testFn, timeout_in_millis)
it('description of test case', function() {
/*your test
steps
here*/
},120000);//120 seconds timeout for this spec
more information on timeouts is here

Resources