I think one reason for that could be that, I didn't see the practical use of Test
Then came a requirement in our project to refactor an existing application. Before I start into details of testing, let me give you some insights of the current app structure.
- Half of the application is based on jQuery.
- Other half is the part which got converted to Angular recently, but still not completely. Some global jQuery plugins are still used as it is in Angular enabled pages
Now the requirement is we need to convert two pages to Angular without breaking any existing functionality or styles. So, the first time I am seeing a great need of Testing.
Since ours is a web application, we are now mostly interested in browser testing. We have got an automation testing in selenium available. But that is for testing in the production site. How do we do the browser testing in localhost (local environment), with the new changes?
Here comes the Protractor for our rescue. There are already some content available in net on Protractor, setting up and all. However, most of the tutorials are mainly focused on Linux or MacOS, not windows. I found it difficult to setup the protractor.
If we don't find it very easy to use, we will stop using and modifying the tests, because we are all lazy :-).
I was looking everywhere to find ways to make it as easy as possible to setup and start testing. So, we should automate it. What I would have done if Grunt was not there.
So, Protractor + Grunt combination seems perfect. So, I decided to try that. I am going to write about all the steps of setting up Protractor in Grunt and the issues I have faced.
I will be also adding the samples to the following repository, so that, anyone can try it out.
Protractor-e2e-bootstrap Repo
1. Install Node.js
2. Install Grunt-cli (Get more details here)
We will first setup a basic project by running the command 'npm init'
It will ask for a few questions and you will get a package.json created for you.
Create a folder 'specs'. We will put all our tests in specs folder. (You can give any name you want)
Lets first install Protractor.
You can install protractor globally also. Then you can run test directly from the command line using protractor command.
But since our goal is to automate the process, global installation is not required.
Notice the --save-dev argument given when we did the npm install. By giving an attribute like this, the installed module name will be added to package.json under 'devDependencies' automatically. (--save will add the module name under 'dependencies' property)
Now we will add Gruntfile.js to our root folder. This file is required for grunt to run the tests.
A minimum configuration Grunt file with jshint task added is given below.
Since ours is a web application, we are now mostly interested in browser testing. We have got an automation testing in selenium available. But that is for testing in the production site. How do we do the browser testing in localhost (local environment), with the new changes?
Here comes the Protractor for our rescue. There are already some content available in net on Protractor, setting up and all. However, most of the tutorials are mainly focused on Linux or MacOS, not windows. I found it difficult to setup the protractor.
If we don't find it very easy to use, we will stop using and modifying the tests, because we are all lazy :-).
I was looking everywhere to find ways to make it as easy as possible to setup and start testing. So, we should automate it. What I would have done if Grunt was not there.
So, Protractor + Grunt combination seems perfect. So, I decided to try that. I am going to write about all the steps of setting up Protractor in Grunt and the issues I have faced.
I will be also adding the samples to the following repository, so that, anyone can try it out.
Protractor-e2e-bootstrap Repo
Setting up the project
Requirements:1. Install Node.js
2. Install Grunt-cli (Get more details here)
We will first setup a basic project by running the command 'npm init'
It will ask for a few questions and you will get a package.json created for you.
Create a folder 'specs'. We will put all our tests in specs folder. (You can give any name you want)
Installing Protractor
Lets first install Protractor.
You can install protractor globally also. Then you can run test directly from the command line using protractor command.
But since our goal is to automate the process, global installation is not required.
Notice the --save-dev argument given when we did the npm install. By giving an attribute like this, the installed module name will be added to package.json under 'devDependencies' automatically. (--save will add the module name under 'dependencies' property)
Adding Grunt
Now we will add Gruntfile.js to our root folder. This file is required for grunt to run the tests.
A minimum configuration Grunt file with jshint task added is given below.
module.exports = function(grunt) { grunt.initConfig({ pkg: grunt.file.readJSON('package.json'), jshint: { files: ['Gruntfile.js', 'specs/*.js'], options: { // options here to override JSHint defaults globals: { jQuery: true, console: true, module: true, document: true } } } }); grunt.loadNpmTasks('grunt-contrib-jshint'); grunt.registerTask('default', ['jshint']); };
For the protractor to be run as a grunt task, we need to wrap it as a grunt plugin. There is already a grunt plugin for that, 'protracter-grunner'. We will install that now.
Adding Protractor configuration to Grunt
Now, we will add the protractor. We can put all the configuration of protractor in grunt file itself. But that will be very messy. So we will put all the configuration of protractor to a separate file.
You can get a sample protractor configuration file from the Protractor repo
https://github.com/angular/protractor/blob/master/referenceConf.js
We are going to use the following configuration file with basic settings.
// A reference configuration file. exports.config = { // ----- How to setup Selenium ----- // // There are three ways to specify how to use Selenium. Specify one of the // following: // // 1. seleniumServerJar - to start Selenium Standalone locally. // 2. seleniumAddress - to connect to a Selenium server which is already // running. // 3. sauceUser/sauceKey - to use remote Selenium servers via SauceLabs. // The location of the selenium standalone server .jar file. seleniumServerJar: 'node_modules/protractor/selenium/selenium-server-standalone-2.40.0.jar', // The port to start the selenium server on, or null if the server should // find its own unused port. seleniumPort: null, // Chromedriver location is used to help the selenium standalone server // find chromedriver. This will be passed to the selenium jar as // the system property webdriver.chrome.driver. If null, selenium will // attempt to find chromedriver using PATH. chromeDriver: 'node_modules/protractor/selenium/chromedriver', // Additional command line options to pass to selenium. For example, // if you need to change the browser timeout, use // seleniumArgs: ['-browserTimeout=60'], seleniumArgs: [], // If sauceUser and sauceKey are specified, seleniumServerJar will be ignored. // The tests will be run remotely using SauceLabs. sauceUser: null, sauceKey: null, // ----- What tests to run ----- // // Spec patterns are relative to the location of this config. specs: [ './specs/*.js' ], // ----- Capabilities to be passed to the webdriver instance ---- // // For a full list of available capabilities, see // https://code.google.com/p/selenium/wiki/DesiredCapabilities // and // https://code.google.com/p/selenium/source/browse/javascript/webdriver/capabilities.js capabilities: { 'browserName': 'chrome' }, // A base URL for your application under test. Calls to protractor.get() // with relative paths will be prepended with this. baseUrl: 'http://localhost:9999', // Selector for the element housing the angular app - this defaults to // body, but is necessary if ng-app is on a descendant of rootElement: 'body', // ----- Options to be passed to minijasminenode ----- jasmineNodeOpts: { // onComplete will be called just before the driver quits. onComplete: null, // If true, display spec names. isVerbose: false, // If true, print colors to the terminal. showColors: true, // If true, include stack traces in failures. includeStackTrace: true, // Default time to wait in ms before a test fails. defaultTimeoutInterval: 10000 } };We will be modifying this file in a bit. For now, lets keep it like this.
We need to add the protractor task in Gruntfile.
}, protractor: { options: { keepAlive: true, configFile: "protractor.conf.js" }, singlerun: {}, auto: { keepAlive: true, options: { args: { seleniumPort: 4444 } } } } }); grunt.loadNpmTasks('grunt-protractor-runner');
You can see that, I have added two options. auto and singlerun. For 'auto', I am giving keepAlive as true. This setting can be run if we need to run tests on each modification. 'singlerun' opiton will run just once and stop the task.
Finally, register the 'singlerun' task to grunt.
grunt.registerTask('default', ['jshint', 'protractor:singlerun']);
Now, that we have done the basic set up. For running protractor from grunt, lets add some test.
Adding the tests
Lets take a basic test which is given in Protractor site and save in 'specs' folder.
describe('angularjs homepage', function() { it('should greet the named user', function() { browser.get('http://www.angularjs.org'); element(by.model('yourName')).sendKeys('Julie'); var greeting = element(by.binding('yourName')); expect(greeting.getText()).toEqual('Hello Julie!'); }); });
Most of it is self explanatory. Protractor is a wrapper around selenium Selenium WebdriverJS with its angular flavour.
The runner exposes global variables browser, by and element. The browser variable is a wrapper around the WebDriver instance. We use the browser variable for any navigation or for grabbing any information off the page. element and by is used for selecting an HTML element, using various selectors. You can get more details on Protractor and WebdriverJS here
So, what this test does is given below:
1. browser opens the url http://www.angularjs.org
2. Gets the input having ng-model="yourName" and set the value as 'Julie'
3. Gets the element which binds the same model.
4. The expectation is that, the binding value is changed to 'Hello Julie!'
Installing Selenium and Chromedriver
Ok... So the test is ready. Now, lets try running this. Wait a minute.. we haven't installed Selenium. A standalone selenium server, and chromedriver is required to run Protractor. Luckily for us, Protractor npm module ships all the required items with it.
'webdriver-manager update' will install Selenium and Chrome driver and chromedriver. .
'webdriver-manager start' command will start the selenium server
Running Test
Keeping this command window open, open another console. Lets run the test using 'grunt' and see what happens.
You can see that browser is opening up and goes to angularjs.org.
Test is passing!!!
Improvements
However, there are some still some improvements needed.1. I don't want to do the webmanager-update whenever I clone this project to another location. I want to make the installation easy.
2. The reports are just showing in command line. I want to see the reports in HTML with some screenshots also if possible.
3. And, some other improvements..
We will cover that in the next post. Stay tuned.
All the files are available in https://github.com/jintoppy/protractor-e2e-bootstrap
Brilliant :)
ReplyDeleteGreat post! Very detailed and informative.
ReplyDeleteThanks @vikasgoyalgzs and @Sree :-)
ReplyDeleteHi Jinto,
ReplyDeleteCan u let me now the exact advantage/need of using grunt. Right now i am using Protractor + jasmine.
I can run single protractor tests using command protractor --grep="Simple_login_test", how can I include this option with grunt protractor in gruntfile.js?
ReplyDeleteAppreciate help!! Thanks.
This comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteThis comment has been removed by the author.
ReplyDeleteHi Jinto,
ReplyDeleteThankz for the great post.. Recently I started to use Protractor. By the way i tried the steps which you are stated here. While running the script, it showing an error as below. Could you please give me an idea how to fix this?
---------------------------------------------------------------------------------------
C:\Learning\Protractor\WithGrunt>grunt
Running "jshint:files" (jshint) task
>> 2 files lint free.
Running "protractor:singlerun" (protractor) task
[launcher] Process exited with error code 1
undefined:1190
vlog(2, () => this + ' scheduling notifications', this);
^
SyntaxError: Unexpected token )
at goog.loadModuleFromSource_ (C:\Learning\Protractor\WithGrunt\node_modules\protractor\node_modules\selenium-webdriver\lib\goog\base.js:1123:19)
at Object.goog.loadModule (C:\Learning\Protractor\WithGrunt\node_modules\protractor\node_modules\selenium-webdriver\lib\goog\base.js:1085:46)
at C:\Learning\Protractor\WithGrunt\node_modules\protractor\node_modules\selenium-webdriver\lib\webdriver\promise.js:1:6
at Object.exports.runInContext (vm.js:64:17)
at Object.Context.closure.goog.retrieveAndExecModule_ (C:\Learning\Protractor\WithGrunt\node_modules\protractor\node_modules\selenium-webdriver\_base.js:135:8)
at :1:6
at Object.exports.runInContext (vm.js:64:17)
at Context.closure.closure.vm.createContext.CLOSURE_IMPORT_SCRIPT (C:\Learning\Protractor\WithGrunt\node_modules\protractor\node_modules\selenium-webdriver\_base.js:104:12)
at Object.goog.importScript_ (C:\Learning\Protractor\WithGrunt\node_modules\protractor\node_modules\selenium-webdriver\lib\goog\base.js:879:9)
at Object.goog.importModule_ (C:\Learning\Protractor\WithGrunt\node_modules\protractor\node_modules\selenium-webdriver\lib\goog\base.js:900:14)
.
.
.
.
.
>> Test failed but keep the grunt process alive.
Done, without errors.
---------------------------------------------------------------------------------------
Waiting for your reply...!
Hey, I got the solution.. Actually its a issue with selenium update...
Deletehttp://stackoverflow.com/questions/33433914/error-using-selenium-js-chrome-webdriver
Now Its working fine...;)
What is the difference between running it from grunt and running it from protractor?
ReplyDeleteI mean if we run it using "protractor protractor.conf.js" .. whats the difference?
Hi people,
ReplyDeleteThank you so much for this wonderful article really!
If someone want to learn more about the product management methodology I think this is the right place for you!
Smm panel
ReplyDeletesmm panel
iş ilanları
instagram takipçi satın al
hirdavatciburada.com
Https://www.beyazesyateknikservisi.com.tr/
SERVİS
tiktok jeton hilesi
maltepe toshiba klima servisi
ReplyDeletekadıköy toshiba klima servisi
maltepe beko klima servisi
kadıköy beko klima servisi
çekmeköy bosch klima servisi
kartal arçelik klima servisi
beykoz alarko carrier klima servisi
üsküdar alarko carrier klima servisi
pendik toshiba klima servisi