Probably the most elegant solution would be to change protractor's code. But it might be problematic if needed to upgrade the library.
I came up with a working solution by decorating protractor's describe instead. The only caveat is that it requires the spec code to be indented correctly. Actually this limitation may be considered as a feature, as for sure it is a good practice to have the code indented correctly and with current IDEs it is just a 2-sec-task. You can reset the counter (e.g. at the beginning of each spec) by calling require('./protractor-decorator').resetCounter();
.
UPDATE
If you want to decorate the it
just call it = require('./protractor-decorator.js').decorateUsingErrorStack(it);
or refactor it into a single method.
protractor-decorator.js module:
var stack = [];
var lastIndentColumn = 1;
function decorateUsingErrorStack(origDescribe){
function describe(){
var callerIndent, args;
if(stack.length === 0){
stack.push(0);
}
// from current stack we get the information about indentation of the code
callerIndent = new Error().stack.split('\n')[2].split(':');
callerIndent = parseInt(callerIndent[callerIndent.length-1]);
if(callerIndent == lastIndentColumn){
stack[stack.length-1] += 1;
}
else {
if(callerIndent < lastIndentColumn){
stack.pop();
stack[stack.length-1] += 1;
}
else {
stack.push(1);
}
}
lastIndentColumn = callerIndent;
args = Array.prototype.slice.call(arguments, 0);
origDescribe.call(null, stack.join('.') + '. ' + args[0], args[1]);
}
return describe;
}
module.exports = {
decorateUsingErrorStack : decorateUsingErrorStack,
resetCounter : function(){
// this function should be called to start counting from 1.
stack = [];
lastIndentColumn = 1;
}
}
spec.js file:
describe = require('./protractor-decorator.js').decorateUsingErrorStack(describe);
describe(' should be 1.', function(){
describe('should be 1.1.', function(){
it('xxx', function(){
});
describe('should be 1.1.1.', function(){
it('xxx', function(){
});
describe('should be 1.1.1.1', function(){
it('xxx', function(){
});
});
describe('should be 1.1.1.2', function(){
it('xxx', function(){
});
});
});
describe('should be 1.1.2.', function(){
it('xxx', function(){
});
});
});
describe('should be 1.2.', function(){
it('xxx', function(){
});
});
describe('should be 1.3.', function(){
it('xxx', function(){
});
});
});
// same as above but all starts with 2.
describe(' should be 2.', function(){...});