Is there a way to catch when a GruntJS task fails and act upon it?
The --force flag doesn't help, because I need to know if something broke along the way, and do something about it.
I tried some arrangement similar to a try-catch, however it doesn't work. That is because grunt.registerTask pushes tasks into a queue - the execution is not synchronous.
grunt.registerTask('foo', "My foo task.", function() {
try {
grunt.task.run('bar');
} catch (ex) {
// Handle the failure without breaking the task queue
}
});
Creative javascript ideas are welcome as well as GruntJS know-how.
This ugly beast should work for you:
grunt.registerMultiTask('foo-task', 'my foo task', function() {
try {
console.log(this.data);
throw new Error('something bad happened!');
} catch (e) {
console.log('Ooops:', e);
}
return true;
});
grunt.registerTask('foo', 'Runs foo.', function() {
grunt.config('foo-task', {
hello: 'world'
});
grunt.task.run('foo-task');
});
Run it via: grunt foo
Output:
Running "foo" task
Running "foo-task:hello" (foo-task) task
world
Ooops: Error: something bad happened!
at Object.<anonymous>
<stacktrace here>
Done, without errors.
I haven't tested it but like in any Javascript code you could add an Event Listener to grunt object and fire event from tasks when you need it...
Don't know if this could exactly fit your question but i would give it a try.
Hope it helps!
Related
We can stub any function or class like this,
class ErrorStub{
constructor(message){
// do whatever with 'message'
}
}
Error = ErrorStub
new Error('This will go to ErrorStub now')
Similar to this, is there any way we can intercept a 'throw' statement. So that whatever exception is thrown across whole website, can be handled in one place?
Wouldn't this satisfy your needs? You would need to listen to the error event, handle it the way you want and return false
function interceptError(exception) {
// Here you can write code which intercepts before
// the error gets triggered and printed in the console
alert(`Exception occured: ${exception.message}`)
}
window.addEventListener("error", function (e) {
interceptError(e);
return false;
})
throw new Error('Test exception');
I am running my tests and noticed:
18 passing (150ms)
1 pending
I haven't seen this before. Previously test either passed, or failed. Timeouts caused failures. I can see which test is failing because it's also blue. But it has a timeout on it. Here's a simplified version:
test(`Errors when bad thing happens`), function(){
try {
var actual = doThing(option)
} catch (err) {
assert(err.message.includes('invalid'))
}
throw new Error(`Expected an error and didn't get one!`)
}
What does 'pending' mean? How could a test be 'pending' when Mocha has exited and node is no longer running?
Why is this test not timing out?
How can I make the test pass or fail?
Thanks!
A test can end up being shown by Mocha as "pending" when you inadvertently closed the test's it method early, like:
// Incorrect -- arguments of the it method are closed early
it('tests some functionality'), () => {
// Test code goes here...
};
The it method's arguments should include the test function definition, like:
// Correct
it('tests some functionality', () => {
// Test code goes here...
});
when I facing with this issue, the pending error was when I define a describe test with skip, and forgot to remove it, like that:
describe.skip('padding test', function () {
it('good test', function () {
expect(true).to.equal(true);
})
});
and did run it, I got the output
Pending test 'good test'
and when I remove the skip flag on the describe test, it does work again..
A pending test in many test framework is test that the runner decided to not run. Sometime it's because the test is flagged to be skipped. Sometime because the test is a just a placeholder for a TODO.
For Mocha, the documentation says that a pending test is a test without any callback.
Are you sure you are looking at the good test ?
The test had a callback (ie, an actual function, not done) but refactoring the code solved the issue. The issue was how code that expects error should run:
test('Errors when bad thing happens', function() {
var gotExpectedError = false;
try {
var actual = doThing(option)
} catch (err) {
if ( err.message.includes('Invalid') ) {
gotExpectedError = true
}
}
if ( ! gotExpectedError ) {
throw new Error(`Expected an error and didn't get one!`)
}
});
It appears that my custom commands implemented for Nightwatch.js are getting executed asynchronously. A console.log message inside the custom command is showing up after a console.log message issued from after the command is invoked. I can't find any reference in the nightwatch documentation about how these commands are executed, but since they appear to be asynchronous, I'm not sure how I can wait to make sure one command has completed before the next one is executed (because this doesn't not appear to be the case).
Here is my custom command ("foo"):
exports.command = function () {
console.log('Command executed');
}
And my test function:
module.exports['my test'] = function(browser) {
browser.resizeWindow(400, 600);
browser.foo();
console.log('Test function returning');
};
When I run this, the logs show up as:
Test function returning
Command executed
Which is the opposite order of what I would expect if my custom function was getting executed synchronously.
If you want your custom command to work properly (and be synch), you need to call at least one Nightwatch.js command inside your custom command.
Try this:
exports.command = function () {
console.log('Command executed');
this.execute(function() {});
}
If you want more in-depth details, you can follow this issue:
https://github.com/nightwatchjs/nightwatch/issues/1123
Your command should take callback as argument:
exports.command = function (callback) {
console.log('Command executed');
if (callback) {
callback();
}
}
and execute like this:
browser.foo(function() {
console.log('Test function returning');
});
Another solution is to use the browser.perform method:
module.exports['my test'] = function(browser) {
browser.resizeWindow(400, 600);
browser.foo();
browser.perform(function()
console.log('Test function returning');
});
};
This is a horrible design by the Nightwatch team. I just spent hours trying to debug this issue and the only solution that worked for me was to use a perform(). This is ridiculous. Why in the world would the Nightwatch developers have custom commands run asynchronously.
I am developing a node.js application. I am using the webworker-threads package to spin off some CPU blocking tasks. However, uncaught errors in my thread code do not get sent to the console. Instead, the thread just fails silently. The simplest case illustrates this:
var Threads = require('webworker-threads');
this.testThread = new Threads.Worker( function() {
console.log("This is the test thread. The next line should throw an error.");
undefinedFunction();
} );
Since my actual application is calling an separate js file as the thread, I am also not seeing any syntax errors reported. Is there some undocumented error event I should be catching? Is there perhaps something wrong with my environment?
Try binding to the worker's onerror event:
var webpackWorker = new Worker(function() {
this.onmessage = function(event) {
throw ('test');
};
});
webpackWorker.onerror = function (event) {
console.log(event);
}
webpackWorker.postMessage("dummy");
Loggin the error in the worker.on('error') the method really worked for me.
worker.on('error', function (error) {
console.log(error);
})
I just rewrote backbone-mongodb to be really compatible with backbone. The original solution had nice vows for testing, and I would like my code to get tested as well, but simply have no idea how to do it.
Here is an example, I would like to test:
update: function(callback) {
var model = this.model;
this._withCollection(function(err, collection) {
if (err) callback(err);
else {
var attributes = _.clone(model.attributes);
delete attributes['_id'];
collection.update({ _id: new ObjectID(model.id) }, {$set: attributes}, {safe:true, upsert:false}, function(err) {
model.fetch();
callback(null, model.toJSON());
});
}
});
},
This code has nothing special in it. It uses the node-mongodb-native driver, and updates a record in the database. AFAIK, proper testing would mean to at least check that (1) collection.update was called with the given arguments, (2) callback is called when and how it should be, (3) model contains the new data.
With vows I can check (2), but have no idea at all how to check (1). Actually, the same holds for every unit testing framework I know about, qUnit, Jasmine. I'm sure that this can be done somehow, and I'm decided to learn at least one of them, but it's hard to make a choice when you got stuck at the beginning. :)
I know about sinon.js and think that everyting can be tested using mocking all the objects I have until I end up having the collection mocked as well, but this seems to be extremely clumsy. Could someone help me in writing the above tests please, and I'll happy to write out a tutorial of it?
I will use Jasmine for that purpose; I don't how familiar are you using that library, but they have a plugin to use jQuery for writing spec tests, you can load fixtures/templates and run tests on it.
for your particular case, assuming that function is part of MyObj "class", I will write something like:
describe("My object tests", function() {
it("Should update my obj", function () {
var noError, flag = false;
MyObj.update(function (err, model){
flag=true;
noError= err==null;
// or you can do other checks on the result
})
// we wait for 5 sec until get a response (flag==true)
waitsFor(function (){ return flag}, "Timeout on update", 5000);
// check if there are no errors
expect(noError).toBeTruthy();
});
});