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 

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,
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:
1. Using Closure function for the promise in a loop
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:
describe('Angular App Test suite 1 -', 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() {
    ...
    ...
  });
});
 
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() {
    ...
    ...
  });
});
I don't know "/some/some" comes from! (a bug in blogger self?)

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:
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 ---