Friday 3 June 2016

Node Require and Exports

A module encapsulates related code into a single unit of code. When creating a module, this can be interpreted as moving all related functions into a file.

---misc.js------
var x = 5;
var addX = function(value) {
  return value + x;
};

Now, before we look at how to expose things out of a module, let's look at loading a module. This is where require comes in. require is used to load a module, which is why its return value is typically assigned to a variable:

var misc = require('./misc');

as long as our module doesn't expose anything, the above isn't very useful. To expose things we use module.exports and export everything we want:

---misc.js------
var x = 5;
var addX = function(value) {
  return value + x;
};
module.exports.x = x;
module.exports.addX = addX;

--usage--
var misc = require('./misc');
console.log("Adding %d to 10 gives us %d", misc.x, misc.addX(10));


There's another way to expose things in a module:

var User = function(name, email) {
  this.name = name;
  this.email = email;
};
module.exports = User;

the last thing to consider is what happens when you directly export a function:

var powerLevel = function(level) {
  return level > 9000 ? "it's over 9000!!!" : level;
};
module.exports = powerLevel;
When you require the above file, the returned value is the actual function. This means that you can do:

require('./powerlevel')(9050);
Which is really just a condensed version of:

var powerLevel = require('./powerlevel')
powerLevel(9050);
Hope that helps!

Setting Up WebStorm for Debugging

To set up WebStorm for Protractor, do the following:
  1. Open the Run/Debug Configurations dialog
  2. Add new Node.js configuration.
  3. On the Configuration tab set:
    • Node Interpreter: path to node executable
    • Working directory: your project base path
    • JavaScript file: path to Protractor cli.js file (e.g. node_modules\protractor\lib\cli.js)
    • Application parameters: path to your Protractor configuration file (e.g. protractorConfig.js)
  4. Click OK, place some breakpoints, and start debugging.

Can we use Protractor in a non-AngularJS app?


Yes, you can!

just add below code in your script file.


browser.ignoreSynchronization = true;

A selenium guy hacks to learn Protractor


1. Protractor global variables:

a. browser: Eg. browser.get()
b. element : Eg. element(by.model('yourName'))
c. by : Eg. element(by.model('yourName'))
d. protractor: Eg. protractor.Key

2.element() vs element.all()

Single element:
element( by.binding('appName') );

Collection of elements:
element.all( by.css('[ng-click="openPage()"]') ).get(2).click();


3. by.binding:

In your application:
<span ng-bind="myModel"></span>
<!-- or -->
<span>{{myModel}}</span>

In your test:
element( by.binding('myModel') );

4. by.model:

In your application:
<input ng-model="myModel" />

In your test:
element( by.model('myModel') );


5. by.repeater:

a. In your application
<ul>
  <li ng-repeat="user in users">
      <span>{{user.name}}</span>
  </li>
</ul>

b. In your test
element( by.repeater('user in users').row(0).column('name') );

6. by.css:

a. In your application
<button ng-click="sendMail()">Send mail!</button

b. In your test
element( by.css('[ng-click="sendMail()"]') );

7.Few  more
a. by.select()
b. by.partialButtonText()
c. elementArrayFinder.each()

Full list of available methods
http://www.protractortest.org/#/api

8.Promises based

All Protractor methods are "asynchronous" and return promises.

// Example of getText() promise
element( by.model('zipcode') ).getText()
  .then(function(val) {
    var num = val.substring(0, 4);
    var isNum = !isNaN(num);
    expect( isNum ).toBeTruthy();
  });

9. Simple Page objects

var AngularHomepage = function() {
  this.nameInput = element(by.model('yourName'));
  this.greeting = element(by.binding('yourName'));

  this.get = function() {
    browser.get('http://www.angularjs.org');
  };

  this.setName = function(name) {
    this.nameInput.sendKeys(name);
  };
};

10.Node.JS exports and require

a. Your Page Object file
var AngularHomepage = function() {
  this.nameInput = element(by.model('yourName'));
  this.greeting = element(by.binding('yourName'));
  // ...
};
module.exports = AngularHomepage;

b. Your Test file
var AngularHomepage = require('./homepage.po.js');
describe('HomePage Tests', function() {
   var angularHomepage = new AngularHomepage();
   angularHomepage.nameInput.sendKeys('Rafael');
   //...
});

11.Separate your tests in various test suites

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',
  capabilities: { 'browserName': 'chrome' },

  suites: {
    homepage: 'tests/e2e/homepage/**/*Spec.js',
    search: ['tests/e2e/contact_search/**/*Spec.js']
  },

  jasmineNodeOpts: { showColors: true }
};

Running specific suite of tests
protractor protractor.conf.js --suite homepage

12.Enable multiCapabilities

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',

  multiCapabilities: [
{
 'browserName' : 'chrome'
},
{
 'browserName' : 'firefox'
}
  ],

  specs: ['example-spec.js'],

  jasmineNodeOpts: {
    showColors: true
  }
};


13.Using onPrepare

a. Set window size before starting the tests

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',

  capabilities: {
    'browserName': 'chrome'
  },

  onPrepare: function() {
     browser.driver.manage().window().setSize(1600, 800);
  },

  jasmineNodeOpts: {
    showColors: true
  }
};

b.Export xml results of your Automated Suites

First, install jasmine-reporters:

>>npm install jasmine-reporters
And to keep xml results in Timestamp directories, install mkdirp package:

>>npm install mkdirp

c.//config.js
exports.config = {
  onPrepare: function() {
    var folderName = (new Date()).toString().split(' ').splice(1, 4).join(' ');
    var mkdirp = require('mkdirp');
    var newFolder = "./reports/" + folderName;
    require('jasmine-reporters');

    mkdirp(newFolder, function(err) {
      if (err) {
        console.error(err);
      } else {
        jasmine.getEnv().addReporter(new jasmine.JUnitXmlReporter(newFolder, true, true));
      }
    });
  },
};

14.Using params

Your config.js

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',

  capabilities: { 'browserName': 'chrome' },

  // This can be changed via the command line as:
  // --params.login.user 'ngrocks'
  params: {
    login: {
      user: 'protractor-br',
      password: '#ng123#'
    }
  },

  jasmineNodeOpts: { showColors: true }
};

Your test:

describe('login page', function() {

  var params = browser.params;

  it('should login successfully', function() {
    element( by.model('username') ).sendKeys( params.login.user );
    element( by.model('password') ).sendKeys( params.login.password );
    element( by.css('[ng-click="login()"]') ).click();
    expect( element(by.binding('username') ).getText() ).toEqual( params.login.user );
  });

});

15.Using jasmineNodeOpts

exports.config = {
  seleniumAddress: 'http://localhost:4444/wd/hub',

  capabilities: { 'browserName': 'chrome' },

  jasmineNodeOpts: {
    showColors: true,
    defaultTimeoutInterval: 30000,
    isVerbose: true,
    includeStackTrace: true
  }
};

16.Protractor waits for Angular to finish its work

Though you can tell it not to be that smart about your non-Angular app:

beforeEach(function() {
   return browser.ignoreSynchronization = true;
});

works for Non anguler based apps too

In your config.js

onPrepare: function() {
   global.isAngularSite = function(flag) {
      browser.ignoreSynchronization = !flag;
   };
}
In your test

beforeEach(function() {
   isAngularSite(false); // isAngularSite(true), if it's an Angular app!
});



Hello World of Protractor


-----------SpecOne.js-------------------------

describe('angularjs homepage', function() {   it('should have a title', function() {     browser.get('http://angularjs.org/');     expect(browser.getTitle()).toContain('AngularJS');   }); });


------------Config.js--------------------------
exports.config = { //The address of a running selenium server.   seleniumAddress: 'http://localhost:4444/wd/hub', //Here we specify the name of the specs files.   specs: ['SpecOne.js'] }



For Running:

1. Start selenium Server

2. Run>protractor conf.js


Thats all.