After some time trying to figure out why the beginning of my tests fails (only for IE, with chrome works just fine), I found out that it is caused by the on-prepare function when comes to this part of the code:
jasmine.getEnv().addReporter({
specDone: function (result) {
browser.getCapabilities().then(function (caps)
{
var browserName = caps.get('browserName');
browser.takeScreenshot().then(function (png) {
var stream = fs.createWriteStream('./execution_results/reports/results/screenshots/' + browserName + '-' + result.fullName+ '.png');
stream.write(new Buffer.from(png, 'base64'));
stream.end();
});
});
}
});
If i comment this part, the tests goes smoothly.
My login page is not Angular, so I turn off the sync for the login and turn on again, not sure if this could be related.
How can I force protractor to wait for this part to finish before continuing with the run?
I already tried to add this code in a promise (in conf file) to make protractor wait but even with this i get the jasmine timeout 'TimeoutError: Wait timed out after 20000ms', so I believe I did it wrong.
The error I get is:
Failed: Unable to determine type from: E. Last 1 characters read: E
Build info: version: '3.141.59', revision: 'e82be7d358', time: '2018-11-14T08:25:53'
System info: host: 'xxxxx', ip: 'xx.xx.xx.xx', os.name: 'Windows 10', os.arch: 'amd64', os.version: '10.0', java.version: '10.0.2'
Driver info: driver.version: unknown
Full conf file:
var jasmineReporters = require('./lib/node_modules/jasmine-reporters');
var HTMLReport = require('./lib/node_modules/protractor-html-reporter-2');
var mkdirp = require('./lib/node_modules/mkdirp');
var fs = require('./lib/node_modules/fs-extra');
let date = require('./lib/node_modules/date-and-time');
var environmentToExecute = 'https://myportal'
exports.config = {
seleniumAddress: 'http://'+process.env.AUTOTEST_ADDRESS+'/wd/hub',
framework: 'jasmine2',
specs: ['all my specs'],
suites: {
//All my suites
},
allScriptsTimeout: 20000,
onPrepare: function () {
{
//Here I create the folders (removed to make it shorter)
}
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
savePath: './execution_results/reports/xml/',
filePrefix: 'xmlresults'
}));
jasmine.getEnv().addReporter({
specDone: function (result) {
browser.getCapabilities().then(function (caps)
{
var browserName = caps.get('browserName');
browser.takeScreenshot().then(function (png) {
var stream = fs.createWriteStream('./execution_results/reports/results/screenshots/' + browserName + '-' + result.fullName+ '.png');
stream.write(new Buffer.from(png, 'base64'));
stream.end();
});
});
}
});
},
//HTMLReport called once tests are finished
onComplete: function()
{
//I removed this to make it shorter, but basically it is the function
// that comverts the xml in html and build the report
},
jasmineNodeOpts: {
showColors: true, // Use colors in the command line report.
// If true, display spec names.
isVerbose: true,
defaultTimeoutInterval: 100000
},
params: {
//Other files like functions and so on...
},
login:{
//parameters to login
}
},
multiCapabilities:
[
{
'browserName': 'internet explorer',
'version': 11,
},
/*
//chrome, firefox...
*/
],
};//end of Conf.js
Thanks!
I also had issues with asynchronous actions in a Jasmine reporter recently and unfortunately could not figure out how to get them to await promise results properly before moving on. If anyone else has information on this I would greatly appreciate it also.
I did implement a work around using global variables and the AfterAll hook which is able to correctly await promises which may work for you.
I'm assuming that you only need the 'fullname' property of your result so you can try this.
Declare a global properties in your onPrepare and you can assigned this global variable values in your reporter. Assign it the spec fullname value inside of specStarted instead of specDone. Then you can create you screenshot inside you tests afterAll statements which are correctly able to await promise results.
onPrepare: function () {
global.currentlyExecutingSpec = 'tbd';
jasmine.getEnv().addReporter({
specStarted: function (result) {
currentlyExecutingSpec = result.fullName
}
})
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
savePath: './execution_results/reports/xml/',
filePrefix: 'xmlresults'
}));
}
Inside your testFiles
afterEach(function(){
browser.getCapabilities().then(function (caps)
{
var browserName = caps.get('browserName');
browser.takeScreenshot().then(function (png) {
var stream =
fs.createWriteStream('./execution_results/reports/results/screenshots/' + browserName + '-' + currentlyExecutingSpec + '.png');
stream.write(new Buffer.from(png, 'base64'));
stream.end();
});
};
});
Related
I tried to run a test suite with 2 .js test case files.
The report config is in onPrepare part of conf.js below:
onPrepare: function () {
var jasmineReporters = require('jasmine-reporters');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidate: true,
savePath: path = './Logs/' + dateFormat(new Date(), "dddd_mmmm_dS_yyyy_h_MM_ss_TT"),
filePrefix: result = 'xmlresults',
}));
var fs = require('fs-extra');
fs.emptyDir(path + '/screenshots/', function (err) {
console.log(err);
});
jasmine.getEnv().addReporter({
specDone: function () {
if (specs.status == 'failed') {
browser.getCapabilities().then(function (caps) {
var browserName = caps.get('browserName');
browser.takeScreenshot().then(function (png) {
var stream = fs.createWriteStream('screenshots/' + browserName + '-' + specs.fullName + '.png');
stream.write(new Buffer(png, 'base64'));
stream.end();
});
});
}
}
});
},
onComplete: function () {
var browserName, browserVersion;
var capsPromise = browser.getCapabilities();
capsPromise.then(function (caps) {
browserName = caps.get('browserName');
browserVersion = caps.get('version');
platform = caps.get('platform');
var HTMLReport = require('protractor-html-reporter-2');
testConfig = {
reportTitle: 'Protractor Test Execution Report',
outputPath: path,
outputFilename: 'htmlresult',
screenshotPath: './screenshots',
testBrowser: browserName,
browserVersion: browserVersion,
modifiedSuiteName: false,
screenshotsOnlyOnFailure: true,
testPlatform: platform
};
new HTMLReport().from(path + '/' + result + '.xml', testConfig);
});
},
After execution, the jasmine html reporter as picture:jasmine html reporter
Can anyone help me to make the reports gather into 1 test suite report?
Thank you very much
I'm using protractor html reporter 2 for my reporting. I need to get spec name as html report output file name.
i'm using the below code in my config file.
var today = new Date(),
timeStamp = today.getMonth() + 1 + '-' + today.getDate() + '-' + today.getFullYear();
onPrepare:
function ()
{
browser.driver.manage().window().maximize();
var fs = require('fs-extra');
scriptName=function(){
return browser.getProcessedConfig().then(function(config){
return config.specs;
});
};
fs.emptyDir('./target/htmlReports/'+scriptName+'-'+timeStamp+'/screenShots/', function (err) {
console.log(err);
});
jasmine.getEnv().addReporter({
specDone: function(result) {
//if (result.status == 'failed' || result.status == 'passed') {
if (1==1) {
browser.getCapabilities().then(function (caps) {
var browserName = userData.testUser.browser.toUpperCase();
browser.takeScreenshot().then(function (png) {
var stream = fs.createWriteStream('./target/htmlReports/'+scriptName+'-'+timeStamp+'/screenShots/'+ result.fullName+'.png');
stream.write(new Buffer(png, 'base64'));
stream.end();
});
});
}
}
});
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
savePath: 'target/XMLReports',
filePrefix: 'xmlresults'
}));
},
onComplete: function() {
var browserName, browserVersion;
var capsPromise = browser.getCapabilities();
capsPromise.then(function (caps) {
browserName = userData.testUser.browser.toUpperCase();
platform=caps.get('platform');
browserVersion = caps.get('version');
testConfig = {
reportTitle: 'Test Execution Report',
outputPath: './target/htmlReports/'+scriptName+'-'+timeStamp,
screenshotPath: './target/htmlReports/'+scriptName+'-'+timeStamp+'/screenShots',
testBrowser: browserName,
browserVersion: browserVersion,
outputFilename:'ProtractorTestReport',
testPlatform: platform,
//browserVersion: browserVersion,
modifiedSuiteName: true,
screenshotsOnlyOnFailure: false
};
new HTMLReport().from('./target/XMLReports/xmlresults.xml', testConfig);
});
},
plugins: [{
package: 'jasmine2-protractor-utils',
disableHTMLReport: true,
disableScreenshot: false,
screenshotPath:'./target/htmlReports/'+scriptName+'-'+timeStamp+'/screenShots',
screenshotOnExpectFailure:true,
screenshotOnSpecFailure:true,
clearFoldersBeforeTest: true,
htmlReportDir: './target/htmlReports'
}],
i tried with
browser.getProcessedConfig().then(function(config){
console.log(config.specs);
});
,it returns
[ 'D:\projects\HeartlandSSP\Automation\TenantManagement\Ssp.TenantManagement.Protractor_Test\specs\createTenantSpec.js',
'C:\Users\renusri.rajalingam\AppData\Roaming\npm\node_modules\protractor\built\frameworks\__protractor_internal_afterEach_setup_spec.js' ]
but the actual spec name createTenantSpec.js is not returning. I need only the filename of the spec and not the name of the describe or it functions. Since I have 5 specs, i need to generate separate report with its spec name. Can anyone please help me on this?
The value of config.specs is an array and according to output we have the file's absolute path is at index 0. So the file name can be extracted as follows.
browser.getProcessedConfig().then(function (config) {
var fullName = config.specs[0];
var fileName = fullName.substring(fullName.lastIndexOf('/')+1);
console.log('fileName:', fileName);
});
// output:
// fileName: createTenantSpec.js
Or if you would like to have all file names in this array you could use this:
browser.getProcessedConfig().then(function (config) {
var fileNames = config.specs.map(function(path) {
return path.substring(path.lastIndexOf('/')+1);
});
fileNames.forEach(function(fileName) {
console.log('fileName:', fileName);
});
});
// output:
// fileName: createTenantSpec.js
// __protractor_internal_afterEach_setup_spec.js
References:
array.prototype.map() => click me
array.prototype.forEach() => click me
Use this in on Complete:
browser.getProcessedConfig().then(function (config)
{
var fullName = config.specs[0];
console.log('fullName' ,fullName);
var start= fullName.lastIndexOf('\\');
var stop=fullName.length;
console.log('start:', start);
console.log('stop:', stop);
var fileName = fullName.substring(start+1,stop);
console.log('fileName:', fileName);
});
I'm receiving very strange test spec behavior when trying to run my jasmine specs with protractor.
I have two empty specs that both should pass, however my first spec passes then all proceeding specs fail. I believe this may have something to do with the version levels, as when I did an update it caused my jasmine test cases to break.
Protractor 3.3.0
Jasmine 2.4.1
Test specs
it('test spec 1', function () {
});
it('test spec 2', function () {
});
Error: Timeout - Async callback was not invoked within timeout specified by jasmine.DEFAULT_TIMEOUT_INTERVAL.
'use strict';
exports.config = {
seleniumAddress: 'http://127.0.0.1:4723/wd/hub',
baseUrl: 'http://10.0.2.2:' + (process.env.HTTP_PORT || '8000'),
specs: [
'./e2e-test.js'
],
framework: 'jasmine',
jasmineNodeOpts: {
showColors: true,
isVerbose: true,
defaultTimeoutInterval: 30000,
print: function() {}
},
capabilities: {
deviceName:"Samsung S7",
platformName: 'Android',
'appium-version': '1.4.16',
platformVersion:'23',
app: 'C:/Users/egreen/Desktop/Android/foo/platforms/android/build/outputs/apk/android-debug.apk',
browserName:'',
udid:'988627534e4c383848',
autoWebview: true
},
// A callback function called when tests are started
onPrepare: function () {
var wd = require('wd'),
protractor = require('protractor'),
wdBridge = require('wd-bridge')(protractor, wd);
wdBridge.initFromProtractor(exports.config);
require('jasmine-reporters');
var fs = require('fs'),
d = new Date(),
date = [
d.getFullYear(),
('0' + (d.getMonth() + 1)).slice(-2),
('0' + d.getDate()).slice(-2)
].join('-'),
time = [
('0'+d.getHours()).slice(-2),
(('0'+d.getMinutes()).slice(-2)),
('0'+d.getSeconds()).slice(-2)
].join('');
var Jasmine2HtmlReporter = require('protractor-jasmine2-html-reporter');
jasmine.getEnv().addReporter(
new Jasmine2HtmlReporter({
savePath: 'target/reports/mobile-app/'+date+'/'+time+'/',
screenshotsFolder: 'images'
})
);
var SpecReporter = require('jasmine-spec-reporter');
jasmine.getEnv().addReporter(new SpecReporter({displayStacktrace: 'all'}));
},
};
Error gist
Updated :
Try to eliminate Jasmine2HtmlReporter.
Try to add :
describe("long asynchronous specs", function() {
beforeEach(function(done) {
done();
}, 10000);
// Your code here
afterEach(function(done) {
done();
}, 10000);
}
You can also have a look into : Jasmine Asynchronous Support
Or try to add time out here :
it('test spec 1', function () {
},1000);
it('test spec 2', function () {
},1000);
I am really new with programming and developing (I know exactly 1 syntax) but I want to test a part of a website and also generate an output report. Protractor is working quite alright, but I cant seem to get the reporter to work.
exports.config = {
seleniumAddress: 'http://localhost:4444/wd/hub',
allScriptsTimeout: 15000,
//baseUrl: 'http://localhost:4444/wd/hub',
specs: ['x.js'],
framework: 'jasmine2',
rootElement: '.ocf-widget-savings',
multiCapabilities: [
{
'browserName': 'chrome',
},
],
onPrepare: function(){
var capsPromise = browser.getCapabilities();
capsPromise.then(function(caps){
var browserName = caps.caps_.browserName.toUpperCase();
var browserVersion = caps.caps_.version;
var prePendStr = browserName + "-" + browserVersion + "-";
var jasmineReporters = require('jasmine-reporters');
var htmlScreenshotReporter = require('protractor-jasmine2-screenshot-reporter');
jasmine.getEnv().addReporter(new jasmineReporters.JUnitXmlReporter({
consolidateAll: true,
filePrefix: prePendStr+'xmloutput',
savePath: 'Testing Protractor/testresults'
}));
jasmine.getEnv().addReporter(
new htmlScreenshotReporter({
dest: './screenshots',
captureOnlyFailedSpecs: true,
filename: prePendStr+'my-report.html'
})
);
});
},
Its now throwing the following error
var result = fn();
does anyone have any clue about what I am doing wrong here? Help would be greatly appreciated.
Sounds like an installation problem.
Do:
npm install --save-dev jasmine-reporters#^2.0.0
and try again.
I am trying to write unittests for a loopback model using jasmine. My model has the usual CRUD endpoints but I have defined a custom '/products/:id/upload' endpoint which expects a form with files.
My model looks like
'use strict';
var loopback = require('loopback');
var ProductSchema = {
location: {
type: String,
required: true
},
version: {
type: String,
required: true
},
id: { type: Number, id: 1, generated: true }
};
var opts = {
strict: true
};
var dataSource = loopback.createDataSource({
connector: loopback.Memory
});
var Product = dataSource.createModel('Product', ProductSchema, opts);
Product.beforeRemote('upload', function(ctx){
var uploader = function(req, res){
// parse a multipart form
res({
result:'success'
});
};
function createProduct(uploaderResult){
// create a product out of the uploaded file
ctx.res.send({
result: uploaderResult.result
});
}
uploader.upload(ctx.req, createProduct);
});
Product.upload = function () {
// empty function - all the logic takes place inside before remote
};
loopback.remoteMethod(
Product.upload,
{
accepts : [{arg: 'uploadedFiles', http: function(ctx){
return function() {
return { files : ctx.req.body.uploadedFiles, context : ctx };
};
}},
{arg: 'id', type: 'string'}],
returns : {arg: 'upload_result', type: String},
http: {path:'/:id/upload', verb: 'post'}
}
);
module.exports = Product;
My end goal is to test the logic of the "createProduct".
My test looks like
'use strict';
describe('Product Model', function(){
var app = require('../../app');
var loopback = require('loopback');
var ProductModel;
beforeEach(function(){
app = loopback();
app.boot(__dirname+'/../../'); // contains a 'models' folder
ProductModel = loopback.getModel('Product');
var dataSource = loopback.createDataSource({
connector: loopback.Memory
});
ProductModel.attachTo(dataSource);
});
it('should load file ', function(){
console.log(ProductModel.beforeRemote.toString());
console.log(ProductModel);
ProductModel.upload();
});
});
By calling ProductModel.upload(); I was hoping to trigger the before remote hook which would exercise the the createProduct. I could test "createProduct" in isolation but then I would omit the fact that createProduct ends up being called as a result of upload.
To be perfectly clear, the core question is:
How do I exercise remote method hooks inside unittests ?
It was suggested to use supertest as an http server. Below there is a code snippet illustrating how to do it in jasmine
describe('My product suite', function(){
var request = require('supertest');
var app;
beforeEach(function(){
app = loopback();
// don't forget to add REST to the app
app.use(app.rest());
});
it('should load file', function() {
request(app).post('/products/id-of-existing-product/upload')
.attach('file', 'path/to/local/file/to/upload.png')
.expect(200)
.end(function(err, res) {
if (err) return done(err);
// res is the HTTP response
// you can assert on res.body, etc.
});
});
});