Software blogs
Sunday, July 27, 2025
Reqnroll (Specflow) in Gherkin
Reqnroll (pronounced as [reknroĘŠl]) is an open-source Cucumber-style BDD test automation framework for .NET. It has been created as a reboot of the SpecFlow project.
Reqnroll enables writing executable specifications for BDD using Gherkin, the widely-accepted feature file specification format.
Saturday, April 27, 2024
Welcome to my software blogs!
I will start again to publish blogs on software development including test automation.
Thursday, April 4, 2019
How to use Protractor elementExplorer for simple debugging
The elementExplorer is a good tool to debug Protractor scripts. You need to have an appropriate Protractor version and npm version for this, because the newest versions are not supported.
First of all, check the version of npm installed in your system:
nvm list

The highest version of npm must be 6.11.0. If it is not the case, you have to choose this one:
nvm use 6.11.0
If you don't have nvm, you may download from here:
https://app.box.com/s/of2zldgjfpjjbggch3bknzshdh6fx1om
Second, check the version of Protractor:
protractor --version
It must be not higher than 5.4.2. If it is not the case, you may do the following:
npm -g install protractor@5.4.2
webdriver-manager update
There are two ways to start elementExplorer:
1. protractor --elementExplorer
2. node <..>/npm/node_modules/protractor/bin/elementexplorer.js
I prefer the second one because it is then possible to repeat your commands you typed by means of using arrows Up and Down.
First of all, check the version of npm installed in your system:
nvm list
The highest version of npm must be 6.11.0. If it is not the case, you have to choose this one:
nvm use 6.11.0
If you don't have nvm, you may download from here:
https://app.box.com/s/of2zldgjfpjjbggch3bknzshdh6fx1om
Second, check the version of Protractor:
protractor --version
It must be not higher than 5.4.2. If it is not the case, you may do the following:
npm -g install protractor@5.4.2
webdriver-manager update
There are two ways to start elementExplorer:
1. protractor --elementExplorer
2. node <..>/npm/node_modules/protractor/bin/elementexplorer.js
I prefer the second one because it is then possible to repeat your commands you typed by means of using arrows Up and Down.
Labels:
Protractor
Wednesday, March 20, 2019
How to use Azure pipeline variables in Protractor automatic tests
Nowadays Microsoft Azure DevOps is very popular for Software development with the Agile way of working.
Protractor (with Selenium) is widely used for UI automation testing. It is useful to add flexibility to the Protractor test setup. You can find a blog: here.
However, the module.exports in that blog does not work for me, maybe because of the fact that I use exports.config, as follows:
exports.config = {
framework: 'jasmine2',
SELENIUM_PROMISE_MANAGER: false,
suites: {
newStyle: [
'spec1.js',
],
},
The parameter block can be added inside the exports.config,
params: {
login: {
user: 'default',
password: 'default'
}
}
In the spec file, the params can be used as follows, e.g.
let usr =browser.params.login.user;
let pw = browser.params.login.password;
Locally, you may run the Protractor tests by using the command line,
Protractor conf_*.js --params.login.user=someUserName --params.login.password=somePassword
The values of default are replaced by "someUserName" and "somePassword" in the runtime.
It works fine! If you use npm module combined with the Azure DevOps, then the relevant part of the package.json looks like as follows:
"test": "protractor conf*.js --suite newStyle --params.login.user=__UserNameUITest__ --params.login.password=__PasswordUITest__",
Where the __UserNameUITest__, and __PasswordUITest__ are the tokens variables, which have to be replaced by the pipeline variables.
Then in the pipeline, you can just use:
npm run test
Last but not least, before this works you need to define two pipeline variables:
UserNameUITest someUserName (shown as ****** ) and
PasswordUITest somePassword (shown as ******), using the lock.
--- End of blog ----
Protractor (with Selenium) is widely used for UI automation testing. It is useful to add flexibility to the Protractor test setup. You can find a blog: here.
However, the module.exports in that blog does not work for me, maybe because of the fact that I use exports.config, as follows:
exports.config = {
framework: 'jasmine2',
SELENIUM_PROMISE_MANAGER: false,
suites: {
newStyle: [
'spec1.js',
],
},
The parameter block can be added inside the exports.config,
params: {
login: {
user: 'default',
password: 'default'
}
}
In the spec file, the params can be used as follows, e.g.
let usr =browser.params.login.user;
let pw = browser.params.login.password;
Locally, you may run the Protractor tests by using the command line,
Protractor conf_*.js --params.login.user=someUserName --params.login.password=somePassword
The values of default are replaced by "someUserName" and "somePassword" in the runtime.
It works fine! If you use npm module combined with the Azure DevOps, then the relevant part of the package.json looks like as follows:
"test": "protractor conf*.js --suite newStyle --params.login.user=__UserNameUITest__ --params.login.password=__PasswordUITest__",
Where the __UserNameUITest__, and __PasswordUITest__ are the tokens variables, which have to be replaced by the pipeline variables.
Then in the pipeline, you can just use:
npm run test
Last but not least, before this works you need to define two pipeline variables:
UserNameUITest someUserName (shown as ****** ) and
PasswordUITest somePassword (shown as ******), using the lock.
--- End of blog ----
Monday, October 31, 2016
Passing Command Line Parameters to a Autohotkey Script
Autohotkey is een scripting language designed for Test Automation. It is easy to use and the programs created are often very compact/light-weight. More info: http://ahkscript.org/
Between two or more scripts, command line parameters may be passed among them, like this:
the '0' is the number of parameters!
(used in a if closure!)
the number of parameters, values of the 4 parameters
This script will be called by another script shown as below:
Run the script callPara.ahk (or callPara.exe) will show the following results:
- Starting ...
- got 4, a, b, c, 20000
If we call paraTest.exe %p1% %p2%, we will get the following answer:
- Starting ...
- needed at least 3 params, got 2
Please note: in a If closure, it must not contain ( ), otherwise it will not work:
if (0 < 3) will always be true!
In the meantime, in a If closure with more conditions, the paramter must be at most left side:
line = blabla
if( line) and 0<3 ;will not work
if 0<3 and (line) ;seems to work, but not reliable! (a bug?)
It is safe to use nested If closures:
if 0<3
if(line)
;do something
Similarly, you may use '1', '2' or any other nubmer to replace '0',
if 1<3
msgbox the first paramter is less than 3: %1%
if 2<3
msgbox the second paramter is less than 3: %2%
When compared to a variable, like i = 3, then it must use %i% in the If closure,
i=3
if 3<%i%
msgbox the third paramter is less than %i%: %3%
More info: See Passing Command Line Parameters to a Script
Between two or more scripts, command line parameters may be passed among them, like this:
the '0' is the number of parameters!
(used in a if closure!)
the number of parameters, values of the 4 parameters
This script will be called by another script shown as below:
Run the script callPara.ahk (or callPara.exe) will show the following results:
- Starting ...
- got 4, a, b, c, 20000
If we call paraTest.exe %p1% %p2%, we will get the following answer:
- Starting ...
- needed at least 3 params, got 2
Please note: in a If closure, it must not contain ( ), otherwise it will not work:
if (0 < 3) will always be true!
In the meantime, in a If closure with more conditions, the paramter must be at most left side:
line = blabla
if( line) and 0<3 ;will not work
if 0<3 and (line) ;seems to work, but not reliable! (a bug?)
It is safe to use nested If closures:
if 0<3
if(line)
;do something
Similarly, you may use '1', '2' or any other nubmer to replace '0',
if 1<3
msgbox the first paramter is less than 3: %1%
if 2<3
msgbox the second paramter is less than 3: %2%
When compared to a variable, like i = 3, then it must use %i% in the If closure,
i=3
if 3<%i%
msgbox the third paramter is less than %i%: %3%
More info: See Passing Command Line Parameters to a Script
Friday, October 28, 2016
Using Protractor in a loop by means of Closure function or .filter()
All functions of Protrator return only promises that are hard to use in a loop. For example,
1. Using Closure function for the promise in a loop
var els = element.all(by.css('selector'));
for (var i = 0; i < 3; ++i) {
els.get(i).getText().then(function(text) {
if (text === 'should click') {
els.get(i).click(); //Index out of bound. Trying to access element at index:3, but there are only 3 elements"
}
})
}
The index i takes the values of 0, 1 and 2 and no code inside the .then() block is executed. It will be executed when i = 3 causing the error of Index out of bound!
There are two solutions to such a problem:
var els = element.all(by.css('selector')); function closureFunc(i){ return function(text){ if (text === 'should click') { els.get(i).click(); // i should take 0, 1 and 2 } }; } for (var i = 0; i < 3; ++i) { els.get(i).getText().then(closureFunc(i)); }2. Using the method .filter() of Protrator to avoind using .then() in a loop
var els = element.all(by.css('selector')); els.filter(function(elem) { return elem.getText().then(function(text) { return text === 'should click'; }); }).click(); // note here we first used a 'filter' to select the appropriate elements, // and used the fact that actions like `click` can act on an array to click all matching elements.
Tuesday, October 25, 2016
How to use Jasmine for Protractor
Jasmine is essential for Protractor test. The testscripts of Protractor are in the style of Jasmine. Google has modified the speccial expect() function of Jasmine to work with promises. All functions of Protractor return only promises!
The expect() function is usually used to resolve the returned promises of Protractor for testing. When not using the expect() function, You have to resolve the returned promises first through the so-called then() function!
In summary, Protractor uses the same syntaxes and styles of Jasmine, like this:
The expect() function is usually used to resolve the returned promises of Protractor for testing. When not using the expect() function, You have to resolve the returned promises first through the so-called then() function!
In summary, Protractor uses the same syntaxes and styles of Jasmine, like this:
describe('Angular App Test suite 1 -', function() { it('Testcase 1: should do xx job', function() { browser.get('I don't know "/some/some" comes from! (a bug in blogger self?)'); expect(element(by.xxx).getText()).toEqual(2); ... ... }); it('Testcase 2: should do xxx job', function() { ... ... }); }); describe('Angular App Test suite 2 -', function() { it('Testcase 1: should do xx job', function() { browser.get(' '); expect(element(by.xxx).getText()).toEqual(2); ... ... }); it('Testcase 2: should do xxx job', function() { ... ... }); });
Monday, October 24, 2016
How to use promise method .then() in Protractor
The hardest part of testing Angular apps using Protractor is promise! Protractor returns no other values than only promises So you may not use the returned value from webdriverJS unless you use .then() method to resolve them first. For example:
var rows = element.all(by.repeater('row in tabledata.display.body'));
You can only use the method expect() to check the value:
expect( rows.count()).toEqual(4);
But you cannot use the value '4' for e.g. in a loop! You have to use the so-called .then() method of promise to resolve, like this:
--- End of blog ---
var rows = element.all(by.repeater('row in tabledata.display.body'));
You can only use the method expect() to check the value:
expect( rows.count()).toEqual(4);
But you cannot use the value '4' for e.g. in a loop! You have to use the so-called .then() method of promise to resolve, like this:
var rows = element.all(by.repeater('row in tabledata.display.body')); rows.count().then( function(nrRows) { //nrRows=rows.count() for(var i=0; i<nrRows; i++){ // do somthing with your loop } })If you need more than one value, then you may nest the .then() method, like this:
var rows = element.all(by.repeater('row in tabledata.display.body')); var cells = element.all(by.repeater('cel in row')); row.count().then( function(nrRows) { //nrRows=rows.count() cells.count().then( function(nrCells){ //nrCells=cells.count() for (var i=0; i<nrRows; i++){ // do something with your loop } // call a function using nrRows and nrCells if( nrRows > 0){ func(nrRows, nrCells); } else{ console.log('No rows in the table!'); } }) })You may use the method .all() to simplify the code, like this:
var rows = element.all(by.repeater('row in tabledata.display.body')); var cells = element.all(by.repeater('cel in row')); q.all([row.count(), cells.count()]).spread(function(nrRows, nrCells){ for (var i=0; i<nrRows; i++){ // do something with your loop } // call a function using nrRows and nrCells if( nrRows > 0){ func(nrRows, nrCells); } else{ console.log('No rows in the table!'); } })Some similar ideas can be found here.
--- End of blog ---
Subscribe to:
Posts (Atom)