I was trying to write some javascript unit tests, using requirejs and jsTestDriver intellij plugin. When I run them in the IDE I have no error even when there are some. I only see them when opening my browser console.
Did someone manage to make IDE plugin displays failures into a require function ?
My code below and some screen shots illustrating my problem.
TestCase("Collections", {
"test User Collection": function () {
require(['lib/underscore', 'lib/backbone', 'app/user', 'app/collections'],
function (_, Backbone, user, appCollections) {
assertNotUndefined('Users must be defined', appCollections.users);
assertTypeOf('Users must be backbone collection', typeof Backbone.Collection, appCollections.users);
assertTypeOf("Users' model must be a user", typeof Backbone.Model, appCollections.users.model);
});
}
});
I haven't tested this, but it might get you started:
var CollectionsTest = AsyncTestCase('Collections');
CollectionsTest.prototype.testIt = function(queue) {
queue.call('Step 1', function(callbacks) {
function test1(_, Backbone, user, appCollections) {
assertNotUndefined('Users must be defined', appCollections.users);
assertTypeOf('Users must be backbone collection', typeof Backbone.Collection, appCollections.users);
assertTypeOf("Users' model must be a user", typeof Backbone.Model, appCollections.users.model);
}
var onModulesLoaded = callbacks.add(test1);
require(['lib/underscore', 'lib/backbone', 'app/user', 'app/collections'], onModulesLoaded);
});
};
Related
I seem to have broken something in the Firebase Phone Auth. I am using my own backend system and Firebase with React Native only for Phone Auth and FCM.
The background is that I had an old project which I was using for auth. Later there had to be another app, so instead of having multiple apps under the same project, I created two new projects for each of the apps. Then I removed all apps from the old project.
Now when I use the real phone numbers which were used with the old project, they no longer seem to work. Test numbers set up under the new projects are all fine.
I can't afford to "waste" any more real numbers in case they become unusable too for further testing.
Using the React Native Firebase module, it looks something like:
auth()
.signInWithPhoneNumber(phoneNumber)
.then(confirmation => {
dispatch({
type: PHONENUMBER_SIGNIN_SUBMIT_SUCCESS,
payload: confirmation,
});
})
.catch(error => {
console.log('received error from firebase auth', JSON.stringify(error));
dispatch({
type: PHONENUMBER_SIGNIN_SUBMIT_FAIL,
payload: error,
});
});
With the phone numbers which were used with the old project, it ends up in the catch block, with a cryptic error message {"line":7186,"column":64,"sourceURL":"http://localhost:8081/index.bundle?platform=android&dev=true&minify=false&app=com.xxx.yyy&modulesOnly=false&runModule=true"}
This line 7186 is in a code block that looks like this
7172 module.exports = _wrapNativeSuper = function _wrapNativeSuper(Class) {
7173 if (Class === null || !_$$_REQUIRE(_dependencyMap[0], "./isNativeFunction.js")(Class)) return Class;
7174
7175 if (typeof Class !== "function") {
7176 throw new TypeError("Super expression must either be null or a function");
7177 }
7178
7179 if (typeof _cache !== "undefined") {
7180 if (_cache.has(Class)) return _cache.get(Class);
7181
7182 _cache.set(Class, Wrapper);
7183 }
7184
7185 function Wrapper() {
7186 return _$$_REQUIRE(_dependencyMap[1], "./construct.js")(Class, arguments, _$$_REQUIRE(_dependencyMap[2], "./getPrototypeOf.js")(this).constructor);
7187 }
7188
7189 Wrapper.prototype = Object.create(Class.prototype, {
7190 constructor: {
7191 value: Wrapper,
7192 enumerable: false,
7193 writable: true,
7194 configurable: true
7195 }
7196 });
7197 return _$$_REQUIRE(_dependencyMap[3], "./setPrototypeOf.js")(Wrapper, Class);
7198 };
Since I have no clue what could be causing this problem, any help and solution approach will be very appreciated.
I am trying to work on a custom jasmine reporter and get a list of all the failed specs in the specDone function:
specDone: function(result) {
if(result.status == 'failed') {
failedExpectations.push(result.fullName);
console.log(failedExpectations);
}
}
where failedExpectations will store an entire list of the failed specs and i need to access this in the afterLaunch function in the protractor config file. But due to the fact that the config file loads everytime a new spec runs it basically gets overwritten and scoping is such that I cannot access it in the afterLaunch function, that is where I am making the call to the slack api. Is there a way to achieve this?
This is what i have it based on : http://jasmine.github.io/2.1/custom_reporter.html
I think the best way is to post the results asynchronously after each spec (*or every "it" and "describe") using #slack/web-api. This way you don't have to worry about overwriting. Basically you "collect" all the results during the test run and send it before the next suite starts.
Keep in mind all of this should be done as a class.
First you prepare your you '#slack/web-api', so install it (https://www.npmjs.com/package/#slack/web-api).
npm i -D '#slack/web-api'
Then import it in your reporter:
import { WebClient } from '#slack/web-api';
And initialize it with your token. (https://slack.com/intl/en-pl/help/articles/215770388-Create-and-regenerate-API-tokens):
this.channel = yourSlackChannel;
this.slackApp = new WebClient(yourAuthToken);
Don't forget to invite your slack app to the channel.
Then prepare your result "interface" according to your needs and possibilities. For example:
this.results = {
title: '',
status: '',
color: '',
successTests: [],
fails: [],
};
Then prepare a method / function for posting your results:
postResultOnSlack = (res) => {
try {
this.slackApp.chat.postMessage({
text: `Suit name: ${res.title}`,
icon_emoji: ':clipboard:',
attachments: [
{
color: res.color,
fields: [
{
title: 'Successful tests:',
value: ` ${res.successTests}`,
short: false
},
{
title: 'Failed tests:',
value: ` ${res.fails}`,
short: false
},
]
}
],
channel: this.channel
});
console.log('Message posted!');
} catch (error) {
console.log(error);
}
When you got all of this ready it's time to "collect" your results.
So on every 'suitStart' remember to "clear" the results:
suiteStarted(result) {
this.results.title = result.fullName;
this.results.status = '';
this.results.color = '';
this.results.successTests = [];
this.results.fails = [];
}
Then collect success and failed tests:
onSpecDone(result) {
this.results.status = result.status
// here you can push result messages or whole stack or do both:
this.results.successTests.push(`${test.passedExpectations}`);
for(var i = 0; i < result.failedExpectations.length; i++) {
this.results.fails.push(test.failedExpectations[i].message);
}
// I'm not sure what is the type of status but I guess it's like this:
result.status==1 ? this.results.color = #DC143C : this.results.color = #048a04;
}
And finally send them:
suiteDone() {
this.postResultOnSlack(this.results);
}
NOTE: It is just a draft based on reporter of mine. I just wanted to show you the flow. I was looking at Jasmine custom reporter but this was based on WDIO custom reporter based on 'spec reporter'. They are all very similar but you probably have to adjust it. The main point is to collect the results during the test and send them after each part of test run.
*You can look up this explanation: https://webdriver.io/docs/customreporter.html
I highly recommend this framework, you can use it with Jasmine on top.
Is there remotely any way to mock any SSE (Server Sent Event) from a Protractor test ?
That means mocking EventSource
Angular controller :
angular.module('app').controller('HomeController', function() {
var monitoringEvents = new window.EventSource('/streams/jobserveur');
monitoringEvents.addEventListener('monitoring-event', function(e) {
var json = JSON.parse(e.data);
...
});
});
Thank you for any insight
I managed to mock EventSource by the solution I mentionned (angular module/protractor addMockModule).
Externalize EventSource calls into a dedicated angular module
angular.module('app.sse', [])
.value('$sse', {
sources : [],
addEventSource : function(name, url) {
this.sources[name] = new window.EventSource(url);
},
addEventListener : function(name, eventName, callback) {
this.sources[name].addEventListener(eventName, callback);
}
});
Referencing the module in the app
angular.module('app', ['app.sse', ...])
Use the $sse module in the app
angular.module('app').controller('HomeController', ['$sse' , function($sse) {
$sse.addEventSource('jobserveur', '/streams/jobserveur');
$sse.addEventListener('jobserveur', 'monitoring-event', function(e) {
var js = JSON.parse(e.data);
}
}]);
From here, make sure your app still work before moving onto the testing
Mock the app.sse module in your test
describe('SSE Fixture', function() {
beforeEach(function() {
browser.addMockModule('app.sse', function() {
angular.module('app.sse', []).value('$sse', {
addEventSource: function(name, url) {
},
addEventListener: function(name, event, callback) {
}
});
});
}
And you're done ! Obviously, the two methods are not implemented here nor is the app.sse module in anyway robust but you get the picture.
Hope it helps anyone
Cheers
i got a problem with my meteor app and i don't know why.
My meteor version is 1.1.0.3 and here is a list of my packages:
accounts-password 1.1.1 Password support for accounts
alanning:roles 1.2.13 Role-based authorization
chrismbeckett:toastr 2.1.2_1 Gnome / Growl type non-blocking notifications
coffeescript 1.0.6 Javascript dialect with fewer braces and semi...
email 1.0.6 Send email messages
fortawesome:fontawesome 4.4.0 Font Awesome (official): 500+ scalable vector...
fourseven:scss 3.2.0 Style with attitude. Sass and SCSS support fo...
insecure 1.0.3 Allow all database writes by default
iron:router 1.0.9 Routing specifically designed for Meteor
jquery 1.11.3_2 Manipulate the DOM using CSS selectors
meteor-platform 1.2.2 Include a standard set of Meteor packages in ...
Alright... now we talk about my problem. i would like to protect some routes for users who don't have the "admin" role, that works find. The System checks my role right, but they don't render the view.
Error msg in console
Exception in delivering result of invoking 'accounts/hasAdminRole': TypeError: me.next is not a function
at http://localhost:3000/lib/controllers/admin_controller.js?843e8c9edbf0891b773aa63a9ad004d1afcbfb19:28:9
at Meteor.bindEnvironment [as _callback] (http://localhost:3000/packages/meteor.js?43b7958c1598803e94014f27f5f622b0bddc0aaf:983:22)
at _.extend._maybeInvokeCallback (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:3860:12)
at _.extend.receiveResult (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:3880:10)
at _.extend._livedata_result (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:4970:9)
at onMessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:3725:12)
at http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:2717:11
at Array.forEach (native)
at Function._.each._.forEach (http://localhost:3000/packages/underscore.js?0a80a8623e1b40b5df5a05582f288ddd586eaa18:156:11)
at _.extend._launchConnection.self.socket.onmessage (http://localhost:3000/packages/ddp.js?d1840d3ba04c65ffade261f362e26699b7509706:2716:11)
app/lib/controllers/admin_controller.js
onBeforeAction: function () {
var me = this;
if(!Meteor.userId()) {
Router.go('signin');
} else {
Meteor.call('accounts/hasAdminRole', function(err, r) {
if(!err && r) {
console.log('success');
console.log(me);
me.next()
} else {
toastr.error('Not Authorized.', 'Error!');
Router.go('home');
}
});
}
},
app/server/methods.js
'accounts/hasAdminRole': function() {
return Roles.userIsInRole( Meteor.user() , ['admin'] );
}
thanks for your answers!
You can directly store the this.next function in your me variable and call it as such:
onBeforeAction: function () {
var me = this.next;
if(!Meteor.userId()) {
Router.go('signin');
} else {
Meteor.call('accounts/hasAdminRole', function(err, r) {
if(!err && r) {
console.log('success');
me();
} else {
toastr.error('Not Authorized.', 'Error!');
Router.go('home');
}
});
}
},
I'm using Jasmine, Karma, and PhantomJS to automate my tests, but I'm hitting a problem: Phantom doesn't seem to parse my JS correctly. For example, I'm using this mock:
var App = function() {
return {
pageController : {
currentPage : {
on : function() {},
toJSON : function() {},
get : function() {
return dark;
}
}
},
mainLayout : {
header : {
show : function() {},
$el : {}
}
}
};
};
console.log("in test", App());
...which logs out as:
PhantomJS 1.9 (Mac) LOG: [ 'in test',
{ pageController: {},
mainLayout: { header: [Object] } } ]
app.pageController has been emptied here, which causes my tests to fail. Why is this happening & how I can fix it?
The problem seems directly related to the function definitions. For example:
console.log("this is a function:", function() { return 'wat'; });
yields
PhantomJS 1.9 (Mac) LOG: [ 'this is a function:', null ]
The error also occurs in Chrome. It squashes created jasmine spies as well, so I'm guessing it's to do with Karma?
Karma's logging reports all functions as null. (Tests were failing for unrelated reasons).