Debugging jasmine-node tests with node-inspector - debugging

Does anyone have any idea if this is possible? Most of the sample for node-inspector seemed geared toward debugging an invoked webpage. I'd like to be able to debug jasmine-node tests though.

In short, just debug jasmine-node:
node --debug-brk node_modules/jasmine-node/lib/jasmine-node/cli.js spec/my_spec.js
If you look at the source of the jasmine-node script, it just invokes cli.js, and I found I could debug that script just fine.
I wanted to use node-inspector to debug a CoffeeScript test. Just adding the --coffee switch worked nicely, e.g.
node --debug-brk node_modules/jasmine-node/lib/jasmine-node/cli.js --coffee spec/my_spec.coffee

I ended up writing a little util called toggle:
require('tty').setRawMode(true);
var stdin = process.openStdin();
exports.toggle = function(fireThis)
{
if (process.argv.indexOf("debug")!=-1)
{
console.log("debug flag found, press any key to start or rerun. Press 'ctrl-c' to cancel out!");
stdin.on('keypress', function (chunk, key) {
if (key.name == 'c' && key.ctrl == true)
{
process.exit();
}
fireThis();
});
}
else
{
console.log("Running, press any key to rerun or ctrl-c to exit.");
fireThis();
stdin.on('keypress', function (chunk, key) {
if (key.name == 'c' && key.ctrl == true)
{
process.exit();
}
fireThis();
});
}
}
You can drop it into your unit tests like:
var toggle = require('./toggle');
toggle.toggle(function(){
var vows = require('vows'),
assert = require('assert');
vows.describe('Redis Mass Data Storage').addBatch({
....
And then run your tests like: node --debug myfile.js debug. If you run debug toggle will wait until you anything but ctrl-c. Ctrl-c exits. You can also rerun, which is nice.
w0000t.

My uneducated guess is that you'd need to patch jasmine, I believe it spawns a new node process or something when running tests, and these new processes would need to be debug-enabled.
I had a similar desire and managed to get expressso working using Eclipse as a debugger:
http://groups.google.com/group/nodejs/browse_thread/thread/af35b025eb801f43
…but I realised: if I needed to step through my code to understand it, I probably need to refactor the code (probably to be more testable), or break my tests up into smaller units.
Your tests is your debugger.

Related

Can I get Protractor/Jasmine to hit a breakpoint when an element locator fails to find its target?

Every time a Protractor element locator fails, it prints an error and continues down a horrible path of endless cascading failures in my spec and suite. Every test that follows depends on the element locator finding its element, and depends on the current spec passing.
I would like to keep the web page under test open while I use the console. The goal is to debug the current state of the page and investigate why the element locator may have failed to find its target.
I'm not too concerned about failing the entire suite and exiting on the first spec failure (I've seen other answers on --fail-fast and stopping on first spec failure.) This is not the approach I would like to take. I want to set a breakpoint, and inspect the environment while the page is running.
Maybe there's something like a Jasmine option for doThisOnFailure: () => { debugger }, which would work for me I think.
I really do not like the solution of using a spec reporter to execute during afterEach and check the failed spec count on the Jasmine environment for the entire spec function. I want to immediately know when an element locator has failed and immediately break as soon as it has failed.
Maybe something really gross would work $('element').click().catch(() => { debugger }).
EDIT: Please, note that I am asking about breaking in a spec, not breaking at the end of the spec.
it('should execute deadly code', function () {
p.navigation.openStorageConfigTab()
$$('.bad-selector').get(0).click() /* IMPORTANT: I want to break here */
p.volume.navigateTo()
})
it('should not execute this spec', function () {
$$('.bad-selector').get(0).click()
})
And the output
✗ should execute deadly code
- Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(css selector, .bad-selector)
✗ should not execute this spec
- Failed: Index out of bound. Trying to access element at index: 0, but there are only 0 elements that match locator By(css selector, .bad-selector)
I can recommend you the approach I use, and I hope you can take it from here
Overall approach is to wait until until you type close/ command in browser url:
await browser.waitForAngularEnabled(false);
await browser.wait(
async () => {
let url = await browser.getCurrentUrl();
return url.includes('close/');
},
5 * 60 * 1000,
'Keep-alive timeout reached, closing the session...'
);
The question is when you want to call it. I use the advantage of onComplete callback function in config file. When it's called, the browser is still available. So once all tests are completed, it doesn't exit for 5 minutes unless I submit close/ to the url field. Obviously that can be conditional, by adding something like if (DEBUG === true)
A downside of this setup is it's called when all tests are completed, and it's possible your spec has navigated away from the page where there was error. So what you can also do is to use advantage of jasmine reporter (if you use jasmine). Roughly, you just need to add this to your onPrepare func:
jasmine.getEnv().addReporter({
jasmineStarted: function(suiteInfo) {},
suiteStarted: function(result) {},
specStarted: function(result) {},
specDone: async function(spec) {
if (spec.status === 'failed') {
await browser.waitForAngularEnabled(false);
await browser.wait(
async () => {
let url = await browser.getCurrentUrl();
return url.includes('close/');
},
5 * 60 * 1000,
'Keep-alive timeout reached, closing the session...'
);
await browser.close();
process.exit(35);
}
},
suiteDone: function(result) {},
jasmineDone: function(result) {},
});
So if any it block has failed status, then it'll stop. BUT, I have not tested it, I'll leave it up to you. And second, I didn't think about what will happen to the rest of queued specs since you're redirected to non existing url close/, but I believe it'll still work for you. Worst case scenario, you can play around and make it continue or close the browser instance, as long as you understood the concept
P.S.
I modified the code to close the browser when you type close/, by adding
await browser.close();
process.exit(35);
I tested this code with the following scenarios:
happy path: all 5 it are successful
first element finder of second it block fails
second element finder of second it block fails
All passed. The code works as expected

NightwatchJS: Custom Command not failing on error

Here is my custom command:
exports.command = function (element, time, debug) {
let waitTime = time || 10000
if (debug) {
return this
.log('waiting ' + waitTime + 'ms for: ' + element)
.waitForElementVisible(element, waitTime)
}
return this
.waitForElementVisible(element, waitTime)
}
I have also set this variable in the globalModules: abortOnFailure: true.
When I call this in a pageObject though like this:
findElement() {
this.waitFor('#driversLicenseNumbers');
return this
}
The object isn't found (which is expected and intended since I'm upgrading to Nightwatch v1.0.14) and the error message is logged to the console, but the test doesn't fail.
× Timed out while waiting for element <#driversLicenseNumbers> to be
present for 10000 milliseconds. - expected "visible" but got: "not
found"
Does anyone know what I'm doing wrong here?
There is already an open issue on the Nightwatch issues board regarding this specific problem. Here it is!
This behavior affects custom_commands in nightwatch#1.0.15 & nightwatch#0.9.21 (according to the BUG report, yet I am running nightwatch#0.9.21 & this behavior is not reproducible for me).
Basically your test fails, but it does so silently, at the end of the test, where you get the timeout error.
Proposed fix: Install a different version (npm install --save-dev nightwatch#0.9.x), or a suitable version that hasn't introduced the defect yet.
Cheers!

CasperJS test doesn't return after execution

I'm having a problem getting casperjs test to exit after execution, I have to hit CTL-C to exit execution. I'm on OSX 10.7 with casperjs 1.1 devel.
To test this wasn't my code I simply copied this sample from the docs:
var casper = require("casper").create();
function Cow() {
this.mowed = false;
this.moo = function moo() {
this.mowed = true; // mootable state: don't do that at home
return 'moo!';
};
}
casper.test.begin('Cow can moo', 2, function suite(test) {
var cow = new Cow();
test.assertEquals(cow.moo(), 'moo!');
test.assert(cow.mowed);
test.done();
});
And I get the following output
casperjs test cow-test.js
Test file: cow-test.js
# Cow can moo
PASS Subject equals the expected value
PASS Subject is strictly true
I then have to hit CTL-C to stop execution. Am I missing something to stop execution?
Per https://github.com/n1k0/casperjs/issues/593#issuecomment-23062361, the problem was that I had created a casper instance at the top of the file, which the documentation warns you not to do.
The solution was to remove the var casper = require("casper").create(); line.

Use Node.js command line debugger on child process?

I use the Node client debugger, like so:
node debug myscript.js
But this process spawns a child using:
var child = require("child_process").fork(cmd, args);
Is there a way for this child to ALSO be started in "debug" mode?
Yes. You have to spawn your process in a new port. There is a workaround to debug with clusters, in the same way you can do:
var debug = process.execArgv.indexOf('--debug') !== -1;
if(debug) {
//Set an unused port number.
process.execArgv.push('--debug=' + (5859));
}
var child = require("child_process").fork(cmd, args);
....
debugger listening on port 5859
Not a problem. All you need to do is to send the debugging Sig to the running process. Look at the node-inspector docs do a find for Enable debug mode
I can`t tell you how to do a debug-brk, I am not sure you can but you can always do something from code like
while(true){debugger}So you can catch the debug statement then step out of the loop manually. Dirty I know =)
Here's another way, this will make the child debuggable on a free port:
// Determine if in debug mode.
// If so, pass in a debug-brk option manually, without specifying port.
var startOpts = {};
var isInDebugMode = typeof v8debug === 'object';
if(isInDebugMode) {
startOpts = {execArgv: ['--debug-brk']};
}
child_process.fork('./some_module.js', startArgs, startOpts);

Getting profiling results with VS2010: C# API vs vsperfcmd

This post has the info about how to run profiler as the following batch file
vsperfcmd /start:coverage /output:run.coverage
hello
vsperfcmd /shutdown
into C# code
// A guid is used to keep track of the run
Guid myrunguid = Guid.NewGuid();
Monitor m = new Monitor();
m.StartRunCoverage(myrunguid, "run.coverage");
// TODO: Launch some tests or something
// that can exercise myassembly.exe
// Complete the run
m.FinishRunCoverage(myrunguid);
For the TODO: part, I used this code
p = new Process();
p.StartInfo.FileName = "hello.exe";
p.Start();
p.WaitForExit();
// Look at return code – 0 for success
if (p.ExitCode != 0) {
Console.Error.WriteLine("Error in profiling");
System.Environment.Exit( -3 );
}
The code runs fine, but I can't the profiled result I did with running batch file.
This is the result from running batch file which has all the info.
This is the result from C# code which doesn't have profiled info, but only schema
What might be wrong?
I asked the same question to MSDN Forums, and it seems like the method doesn't work.

Resources