Intern.io Single Page Application Functional Testing - intern

I have a single page application that uses Dojo to navigate between pages.
I am writing some functional tests using intern and there are some niggly issues I am trying to weed out.
Specifically I am having trouble getting intern to behave with timeouts. None of the timeouts seem to have any effect for me. I am trying to set the initial load timeout using "setPageLoadTimeout(30000)" but this seems to get ignored. I also call "setImplicitWaitTimeout(10000)" but again this seems to have no effect.
The main problem I have is that it may take a couple of seconds in my test environment for the request to be sent and the response parsed and injected into the DOM. The only way I have been able to get around this is by explicitly calling "sleep(3000)" for example but this can be a bit hit & miss and sometimes the DOM elements are not ready by the time I query them. (as mentioned setImplicitWaitTimeout(10000) doesn't seem to have an effect for me)
With the application I fire an event when the DOM has been updated. I use dojo.subscribe to hook into this in the applictaion. Is it possible to use dojo.subscribe within intern to control the execution of my tests?
Heres a sample of my code. I should have also mentioned that I use Dijit so there is also a slight delay when the response comes back and the widgets are being created (via data-dojo-type declarations)...
define([
'intern!object',
'intern/chai!assert',
'require',
'intern/node_modules/dojo/topic'
], function (registerSuite, assert, require, topic) {
registerSuite({
name: 'Flow1',
// login to the application
'Login': function(remote) {
return remote
.setPageLoadTimeout(30000)
.setImplicitWaitTimeout(10000)
.get(require.toUrl('https://localhost:8080/'))
.elementById('username').clickElement().type('user').end()
.elementById('password').clickElement().type('password').end()
.elementByCssSelector('submit_button').clickElement().end();
},
// check the first page
'Page1':function() {
return this.remote
.setPageLoadTimeout(300000) // i've tried these calls in various places...
.setImplicitWaitTimeout(10000) // i've tried these calls in various places...
.title()
.then(function (text) {
assert.strictEqual(text, 'Page Title');})
.end()
.active().type('test').end()
.elementByCssSelector("[title='Click Here for Help']").clickElement().end()
.elementById('next_button').clickElement().end()
.elementByCssSelector("[title='First Name']").clear().type('test').end()
.elementByCssSelector("[title='Gender']").clear().type('Female').end()
.elementByCssSelector("[title='Date Of Birth']").type('1/1/1980').end()
.elementById('next_button').clickElement().end();
},
// check the second page
'Page2':function() {
return this.remote
.setImplicitWaitTimeout(10000)
.sleep(2000) // need to sleep here to wait for request & response injection and DOM parsing etc...
.source().then(function(source){
assert.isTrue(source.indexOf('test') > -1, 'Should contain First Name: "test"');
}).end()
// more tests etc...
}
});
});
I'm importing the relevant Dojo module from the intern dojo node module but I'm unsure of how to use it.
Thanks

Your test is timing out, because Intern tests have an explicit timeout set to 30s that is not accessible through their API. It can be changed by adding 'intern/lib/Test' to your define array, and then overwriting the timeout from the Test's object, e.g. Test.prototype.timeout = 60000;.
For example:
define([
'intern!object',
'intern/chai!assert',
'require',
'intern/node_modules/dojo/topic',
'intern/lib/Test'
], function (registerSuite, assert, require, topic, Test) {
Test.prototype.timeout = 60000;
...
}
This should change the timeout to one minute instead of 30s, to prevent your test timing out.

Related

State not being set properly - React Native

I am very confused by what I am getting from my code. I have the following which should log out data.points then set this.state.points to data.points and then log out this.state.points, however when it logs them out they are not equal. This is the exact code I am using, so I am sure it is what was outputted. I am probably overlooking something, but I have spent the past hour reading over and logging out this code, and I still cannot figure it out. Here is the code that I run:
console.log(data.points);
if (!this.state.hasPressed) {
this.setState({points: data.points})
console.log('in not hasPressed if');
}
console.log(this.state.points);
However in the chrome remote debugger I get this:
["114556548393525038426"]
in not hasPressed if
[]
setState is an asynchronous call. you have to use function callback to wait for setState complete.
console.log(data.points);
if (!this.state.hasPressed) {
this.setState({points: data.points}, () => {
console.log(this.state.points);
});
console.log('in not hasPressed if');
}
refer to react-native setState() API:
setState(updater, [callback])
setState() does not always immediately update the component. It may
batch or defer the update until later. This makes reading this.state
right after calling setState() a potential pitfall. Instead, use
componentDidUpdate or a setState callback (setState(updater,
callback)), either of which are guaranteed to fire after the update
has been applied. If you need to set the state based on the previous
state, read about the updater argument below.

sails js cannot change timeout load hook, for bootstrap

Hello i have some problem with the bootstrap of sails, i need run a function that take approximately a minute in finished, before sails initialize, so tried do, in the bootstrap hook, but i got this error:
warn: Bootstrap is taking unusually long to execute its callback (2000 milliseconds).
Perhaps you forgot to call it? The callback is the first argument of the function, `cb`.
and searching in internet a the solution of the people was that, i have to create:
config/hookTimeout.js
and put inside :
module.exports.hookTimeout = {
hookTimeout:120000
}
to override the time of load, but still i get the same error, but i figurethat the other hooks had the hookTimeout = 120000, just the bootstrap hook dont.
The field name is bootstrapTimeout instead of hookTimeout (see here for more details).
And your config file (with a name as you like) should be as follows (nothing after module.exports):
module.exports = {
bootstrapTimeout: 60000, // in millis
};
Check if you call callback in the bootstrap file.
The simples version of config/bootstrap.js should be like next:
module.exports.bootstrap = function(cb) {
cb();
};

Frisby Functional Test standards

I'm new to this and I have been searching for ways (or standards) to write proper functional tests but I still I have many unanswered questions. I'm using FrisbyJS to write functional tests for my NodeJS API application and jasmine-node to run them.
I have gone through Frisby's documentation, but it wasn't fruitful for me.
Here is a scenario:
A guest can create a User. (No username duplication allowed, obviously)
After creating a User, he can login. On successful login, he gets an Access-Token.
A User can create a Post. Then a Post can have Comment, and so on...
A User cannot be deleted once created. (Not from my NodeJS Application)
What Frisby documentation says is, I should write a test within a test.
For example (full-test.spec.js):
// Create User Test
frisby.create('Create a `User`')
.post('http://localhost/users', { ... }, {json: true})
.expectStatus(200)
.afterJSON(function (json) {
// User Login Test
frisby.create('Login `User`')
.post('http://localhost/users/login', { ... }, {json: true})
.expectStatus(200)
.afterJSON(function (json) {
// Another Test (For example, Create a post, and then comment)
})
.toss();
})
.toss();
Is this the right way to write a functional test? I don't think so... It looks dirty.
I want my tests to be modular. Separate files for each test.
If I create separate files for each test, then while writing a test for Create Post, I'll need a User's Access-Token.
To summarize, the question is: How should I write tests if things are dependent on each other?
Comment is dependent on Post. Post is dependent on User.
This is the by product to using NodeJS. This is a large reason I regret deciding on frisby. That and the fact I can't find a good way to load expected results out of a database in time to use them in the tests.
From what I understand - You basically want to execute your test cases in a sequence. One after the other.
But since this is javascript, the frisby test cases are asynchronous. Hence, to make them synchronous, the documentation suggested you to nest the test cases. Now that is probably OK for a couple of test cases. But nesting would go chaotic if there are hundreds of test cases.
Hence, we use sequenty - another nodejs module, which uses call back to execute functions(and test cases wrapped in these functions) in sequence. In the afterJSON block, after all the assertions, you have to do a call back - cb()[which is passed to your function by sequenty].
https://github.com/AndyShin/sequenty
var sequenty = require('sequenty');
function f1(cb){
frisby.create('Create a `User`')
.post('http://localhost/users', { ... }, {json: true})
.expectStatus(200)
.afterJSON(function (json) {
//Do some assertions
cb(); //call back at the end to signify you are OK to execute next test case
})
.toss();
}
function f2(cb){
// User Login Test
frisby.create('Login `User`')
.post('http://localhost/users/login', { ... }, {json: true})
.expectStatus(200)
.afterJSON(function (json) {
// Some assertions
cb();
})
.toss();
}
sequenty.run(f1,f2);

Write qUnit output to file via Grunt

I need to be able to report qUnit tests to a file so my build server can parse them.
I'm using qUnit (grunt-contrib-qunit) through Grunt along with the jUnit reporter found here.
I can get the report to write to the log just as it states but I'm having trouble getting it into a file. I've tried qunit callbacks in my gruntfile but none of them seem to get the xml info. I also tried to simply redirect stdout but it (of course) printed all of the non-xml command-line stuff along with the xml.
In short, I've got the XML echoing properly in the console.log statement. I just need to get this to a file somehow. Either through Grunt, phantomjs, or any other means.
Well, if you're running QUnit tests from Grunt, then you have the full power of Node at your disposal. I've never used that JUnit plugin, but if it just gives you callback in your QUnit HTML file, then you would need a browser solution (even if that is phantomjs).
Phantom uses QtWebKit, which has implemented the File API so you could implement a solution using that from JUnit's callback, but, of course, that would fail if you run the tests in certain other browsers (namely IE9 or under). Here's how that might look (no guarantees on this being exact, I have not run it):
QUnit.jUnitReport = function(report) {
function onInitFs(fs) {
fs.root.getFile('qunit_report.xml', {create: true}, function(fileEntry) {
fileEntry.createWriter(function(fileWriter) {
fileWriter.onwriteend = function(e) { /* if you need it */ };
fileWriter.onerror = function(e) { /* if you need it */ };
var blob = new Blob([report.xml], {type: 'application/xml'});
fileWriter.write(blob);
}, someErrorHandlerFunction);
}, someErrorHandlerFunction);
}
window.requestFileSystem(window.TEMPORARY, 1024*1024, onInitFs, someErrorHandlerFunction);
}
And again, if you need to do something to write the file in IE9 or under (or some mobile browsers) you'll need another solution, like kicking off an ajax request to upload the data to a server that stores the file. You could even run that "server" from within Grunt and have Node write the file.

Potentially vulnerability using setInterval in Firefox addon?

I've written a Firefox addon for the first time and it was reviewed and accepted a few month ago. This add-on calls frequently a third-party API. Meanwhile it was reviewed again and now the way it calls setInterval is criticized:
setInterval called in potentially dangerous manner. In order to prevent vulnerabilities, the setTimeout and setInterval functions should be called only with function expressions as their first argument. Variables referencing function names are acceptable but deprecated as they are not amenable to static source validation.
Here's some background about the »architecture« of my addon. It uses a global Object which is not much more than a namespace:
if ( 'undefined' == typeof myPlugin ) {
var myPlugin = {
//settings
settings : {},
intervalID : null,
//called once on window.addEventlistener( 'load' )
init : function() {
//load settings
//load remote data from cache (file)
},
//get the data from the API
getRemoteData : function() {
// XMLHttpRequest to the API
// retreve data (application/json)
// write it to a cache file
}
}
//start
window.addEventListener(
'load',
function load( event ) {
window.removeEventListener( 'load', load, false ); needed
myPlugin.init();
},
false
);
}
So this may be not the best practice, but I keep on learning. The interval itself is called inside the init() method like so:
myPlugin.intervalID = window.setInterval(
myPlugin.getRemoteData,
myPlugin.settings.updateMinInterval * 1000 //milliseconds!
);
There's another point setting the interval: an observer to the settings (preferences) clears the current interval and set it exactly the same way like mentioned above when a change to the updateMinInterval setting occures.
As I get this right, a solution using »function expressions« should look like:
myPlugin.intervalID = window.setInterval(
function() {
myPlugin.getRemoteData();
},
myPlugin.settings.updateMinInterval * 1000 //milliseconds!
);
Am I right?
What is a possible scenario of »attacking« this code, I've overlooked so far?
Should setInterval and setTimeout basically used in another way in Firefox addons then in »normal« frontend javascripts? Because the documentation of setInterval exactly shows the way using declared functions in some examples.
Am I right?
Yes, although I imagine by now you've tried it and found it works.
As for why you are asked to change the code, it's because of the part of the warning message saying "Variables referencing function names are acceptable but deprecated as they are not amenable to static source validation".
This means that unless you follow the recommended pattern for the first parameter it is impossible to automatically calculate the outcome of executing the setInterval call.
Since setInterval is susceptible to the same kind of security risks as eval() it is important to check that the call is safe, even more so in privileged code such as an add-on so this warning serves as a red flag to the add-on reviewer to ensure that they carefully evaluate the safety of this line of code.
Your initial code should be accepted and cause no security issues but the add-on reviewer will appreciate having one less red flag to consider.
Given that the ability to automatically determine the outcome of executing JavaScript is useful for performance optimisation as well as automatic security checks I would wager that a function expression is also going to execute more quickly.

Resources