<?xml version='1.0' encoding='UTF-8'?><?xml-stylesheet href="http://www.blogger.com/styles/atom.css" type="text/css"?><feed xmlns='http://www.w3.org/2005/Atom' xmlns:openSearch='http://a9.com/-/spec/opensearchrss/1.0/' xmlns:blogger='http://schemas.google.com/blogger/2008' xmlns:georss='http://www.georss.org/georss' xmlns:gd="http://schemas.google.com/g/2005" xmlns:thr='http://purl.org/syndication/thread/1.0'><id>tag:blogger.com,1999:blog-9032911300417711039</id><updated>2026-10-16T02:38:15.028-07:00</updated><category term="asp.net"/><category term="javascript"/><category term="ajax"/><category term="jquery"/><category term="sql"/><category term="browser"/><category term="control"/><category term="excel reading"/><category term="grunt"/><category term="html reporter"/><category term="javascript e2e testing"/><category term="javascript puzzle"/><category term="javascript testing"/><category term="js puzzle"/><category term="protractor"/><category term="protractor automation"/><category term="puzzle"/><category term="selenium"/><category term="updatepanel"/><category term="AngularJS"/><category term="AsyncFileUpload"/><category term="IIFE"/><category term="Interceptor"/><category term="Wizard Control"/><category term="advanced JS"/><category term="argentina"/><category term="assembly"/><category term="backbone"/><category term="browser rendering"/><category term="calling outer method"/><category term="certification"/><category term="console.log"/><category term="css"/><category term="css hack"/><category term="css3"/><category term="database"/><category term="datetime"/><category term="dll"/><category term="duff device"/><category term="email"/><category term="error"/><category term="finding control"/><category term="firebug"/><category term="functions"/><category term="germany"/><category term="http error 500"/><category term="ice candidate"/><category term="icecandidate"/><category term="ie7"/><category term="ie8"/><category term="ie9"/><category term="iis"/><category term="inetmgr"/><category term="internal server error"/><category term="loops"/><category term="money making"/><category term="multiview"/><category term="peer"/><category term="peer to peer"/><category term="performance"/><category term="performance improvement"/><category term="progressbar"/><category term="rendering"/><category term="rewritemodule"/><category term="socket"/><category term="speed"/><category term="stun"/><category term="turn"/><category term="validation"/><category term="viewstate"/><category term="viewstatemac"/><category term="web development"/><category term="webkit"/><category term="webrtc"/><category term="webrtc in backbone"/><category term="websocket"/><category term="windows7"/><category term="work at home"/><category term="worldcup"/><category term="worldcup 2010"/><title type='text'>Buddying Programmer</title><subtitle type='html'></subtitle><link rel='http://schemas.google.com/g/2005#feed' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/posts/default'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default?redirect=false'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/'/><link rel='hub' href='http://pubsubhubbub.appspot.com/'/><link rel='next' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default?start-index=26&amp;max-results=25&amp;redirect=false'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><generator version='7.00' uri='http://www.blogger.com'>Blogger</generator><openSearch:totalResults>47</openSearch:totalResults><openSearch:startIndex>1</openSearch:startIndex><openSearch:itemsPerPage>25</openSearch:itemsPerPage><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-4611281144722942868</id><published>2014-08-17T23:31:00.000-07:00</published><updated>2014-08-17T23:32:18.186-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ajax"/><category scheme="http://www.blogger.com/atom/ns#" term="AngularJS"/><category scheme="http://www.blogger.com/atom/ns#" term="Interceptor"/><title type='text'>How to cancel all the old XHR (http / ajax ) requests on state change (url change) - AngularJS Interceptor</title><content type='html'>I am working on an AngularJS app which earlier was a jquery based web app. Still some global utilities are using jquery and we haven&#39;t yet converted that fully to AngularJS.&lt;br /&gt;
&lt;br /&gt;
The whole app workflow is now handled with state changes using Angular UI Router. So, on state change, we will send the XHR requests for partial templates which will be filled on content area and also other functionalities required for the new state.&lt;br /&gt;
&lt;br /&gt;
Now, we face an issue. &amp;nbsp;If we switch the navigation fast.. ie. if we change state fast, the html of the old state is first showing on the content area, even though it is not relevant any more.&lt;br /&gt;
&lt;br /&gt;
So, I did some google search and found some useful posts.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://developer.rackspace.com/blog/cancelling-ajax-requests-in-angularjs-applications/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;Cancelling Ajax requests in AngularJS Applications&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.webdeveasy.com/interceptors-in-angularjs-and-useful-examples/&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;Interceptors in AngularJS and Useful Examples&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;http://www.bennadel.com/blog/2624-aborting-an-ajax-request-in-angularjs-using-httpi.htm&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;Aborting An AJAX Request In AngularJS Using httpi&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
Here is the summary of what I got from these posts and others:&lt;br /&gt;
&lt;br /&gt;
1. We can create a custom interceptor for AngularJS http requests. With this custom interceptor, we can add some custom functionalities for the following states:&lt;br /&gt;
a. &lt;b&gt;request&lt;/b&gt; -&amp;nbsp;On request success&lt;br /&gt;
b.&amp;nbsp;&lt;b&gt;requestError&lt;/b&gt; -&amp;nbsp;On request failure&lt;br /&gt;
c.&amp;nbsp;&lt;b&gt;response&lt;/b&gt; -&amp;nbsp;On response success&lt;br /&gt;
d.&amp;nbsp;&lt;b&gt;responseError&lt;/b&gt; -&amp;nbsp;On response failture&lt;br /&gt;
&lt;br /&gt;
2. Jquery Ajax has a ajaxSend function. In that we can get the xhr object.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, lets do this step by step. I am not going to tell how to create the interceptor because which is clearly given in the above posts.&lt;br /&gt;
&lt;br /&gt;
First we need to save all the requests so that we can cancel them later if needed.&lt;br /&gt;
&lt;br /&gt;
So, first lets create an empty object.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinAWMSgPLd9FZnn63Dv13CRD77AtH7Nq2d72J_sUHSdpSf0_TjpOi30RJQ9by0QsqMKqCNf6DSeMrfLdvakh8uCd5G8aVtndlQ60tdMkuDyMIvjODJXrL2NrpPgFw845jnJF8xQuCuhuI/s1600/1.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinAWMSgPLd9FZnn63Dv13CRD77AtH7Nq2d72J_sUHSdpSf0_TjpOi30RJQ9by0QsqMKqCNf6DSeMrfLdvakh8uCd5G8aVtndlQ60tdMkuDyMIvjODJXrL2NrpPgFw845jnJF8xQuCuhuI/s1600/1.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
In currentRequests, I have created two objects, http and ajax, for handling angular http requests, and jquery ajax requests respectively.&lt;br /&gt;
&lt;br /&gt;
First, we will save the jquery ajax requests using the ajaxSend function.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPyhvnRFhKEl45q9fXZ1zkI7WSImrpabYfSycuNnc1qVLWUlNAlzzuZ4vlsPpXjH5QVUoCW3TH_UlOT-t4gqsPCdzKrcjG1E9LkZA9eZP1m5Hl4yeBlgtrxM_oKnT9FBVFXMryC8xu8lE/s1600/2.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhPyhvnRFhKEl45q9fXZ1zkI7WSImrpabYfSycuNnc1qVLWUlNAlzzuZ4vlsPpXjH5QVUoCW3TH_UlOT-t4gqsPCdzKrcjG1E9LkZA9eZP1m5Hl4yeBlgtrxM_oKnT9FBVFXMryC8xu8lE/s1600/2.png&quot; height=&quot;65&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Here we will get xhr as a parameter. So, we just need to save it. I am saving url also as the key, in case it is required at a later point.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, we have to save the Angular http requests.For the we have to check the request property of our &amp;nbsp;custom Interceptor. request function has a config parameter which contains all the info for the http request. In that, &lt;b&gt;timeout&lt;/b&gt; property is the one we are interested in. If we check the angular code, we can see that, timeout is a promise which if resolved will do xhr abort. So, to use this, we we create a custom deferred object using $q and we will save the deferred object.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHTcDoPIoZsdSnw5XxCP1H8bZfq_ExaqxmithxG57TwNuJLwd5t3kHBHZHEv753-Kh_nO3acO0udQsZvkBeOKY9oUjkfIMhIk19efzoBW-r8jcLs5PDKfOpm-4rbvzmk1ZftKlpC3LhjA/s1600/3.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHTcDoPIoZsdSnw5XxCP1H8bZfq_ExaqxmithxG57TwNuJLwd5t3kHBHZHEv753-Kh_nO3acO0udQsZvkBeOKY9oUjkfIMhIk19efzoBW-r8jcLs5PDKfOpm-4rbvzmk1ZftKlpC3LhjA/s1600/3.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In this code, we are creating the deferred object,&amp;nbsp;&lt;b&gt;deferred&lt;/b&gt;. Promise object of the deferred is passed to config.timeout property. We will save our&amp;nbsp;&lt;b&gt;deferred&lt;/b&gt;&amp;nbsp;object in currentRequests object.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Now that we have saved all the requests, we just need to loop through each xhr objects and just abort it.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdsuXNrccyEtKUzeozxhMERvbUzHRjoDbKqeh4UDKKrOsLHYGCtNkSfyiGwcaNl6QPQfQeSgnwMsW2mYn1F4gpMvpJYVJtjvfDT9nF4Q93p0evukdcsVxBwOm3QLxsviUlMTlbuEVAiPo/s1600/4.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhdsuXNrccyEtKUzeozxhMERvbUzHRjoDbKqeh4UDKKrOsLHYGCtNkSfyiGwcaNl6QPQfQeSgnwMsW2mYn1F4gpMvpJYVJtjvfDT9nF4Q93p0evukdcsVxBwOm3QLxsviUlMTlbuEVAiPo/s1600/4.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
I haven&#39;t finalized on it. Please add your suggestions/corrections in the comments.&lt;br /&gt;
&lt;br /&gt;
You can see the gist here &amp;nbsp;-&amp;nbsp;&lt;a href=&quot;https://gist.github.com/jintoppy/5a5d2fe372b4aaa24dd4&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;&lt;span style=&quot;color: blue;&quot;&gt;GlobalAjaxInterceptor&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/4611281144722942868/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2014/08/how-to-cancel-all-old-xhr-http-ajax.html#comment-form' title='3 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4611281144722942868'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4611281144722942868'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2014/08/how-to-cancel-all-old-xhr-http-ajax.html' title='How to cancel all the old XHR (http / ajax ) requests on state change (url change) - AngularJS Interceptor'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEinAWMSgPLd9FZnn63Dv13CRD77AtH7Nq2d72J_sUHSdpSf0_TjpOi30RJQ9by0QsqMKqCNf6DSeMrfLdvakh8uCd5G8aVtndlQ60tdMkuDyMIvjODJXrL2NrpPgFw845jnJF8xQuCuhuI/s72-c/1.png" height="72" width="72"/><thr:total>3</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-4736869226487560496</id><published>2014-03-22T03:33:00.003-07:00</published><updated>2014-03-22T06:25:55.243-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="grunt"/><category scheme="http://www.blogger.com/atom/ns#" term="html reporter"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript e2e testing"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript testing"/><category scheme="http://www.blogger.com/atom/ns#" term="protractor"/><category scheme="http://www.blogger.com/atom/ns#" term="protractor automation"/><category scheme="http://www.blogger.com/atom/ns#" term="selenium"/><title type='text'>Full automation of Protractor E2E tests using Grunt - Part 2</title><content type='html'>This is a continuation of the article series on automating protractor tests using grunt. You can see the first part &lt;a href=&quot;http://programmerbuddy.blogspot.in/2014/03/full-automation-of-protractor-e2e-tests.html&quot;&gt;here&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
In this part we will be doing the following tasks.&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Adding the setup tasks to grunt to make the whole process easier to start.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;Adding an HTML reporter&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Adding the setup command tasks&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
When you create a repo, you may want to clone this repo on several machines. Or, when someone else wants to use your repo to use in his/her project. When they do that, they also have to go through all the basic setup that you have done like installing selenium, chromedriver etc. We don&#39;t want that.&amp;nbsp;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
We are doing all our setup on the command console. Then, why not automate it? Is there any grunt plugin for that? Yes. There is. We can use&amp;nbsp;&lt;b&gt;grunt-shell-spawn &lt;/b&gt;for running all the shell commands.&lt;br /&gt;
&lt;br /&gt;
Lets add grunt-shell-spawn module to our project.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekMXioTnrr4i4sQoI8sTYQGcp4FLmsVtTQWqcqwQ_bFw8wwA3XDwJmJpqJem8kWaCHqLNQdo5p7bKXkBCJ-axcvzeVKB92LrvsmH97WIjE3axKWpzaEEKKqpcEXmMZdWsCaHxJLXFzK4/s1600/shell-spawn-install.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekMXioTnrr4i4sQoI8sTYQGcp4FLmsVtTQWqcqwQ_bFw8wwA3XDwJmJpqJem8kWaCHqLNQdo5p7bKXkBCJ-axcvzeVKB92LrvsmH97WIjE3axKWpzaEEKKqpcEXmMZdWsCaHxJLXFzK4/s1600/shell-spawn-install.png&quot; height=&quot;76&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now, we will add the shell-spawn task to Gruntfile.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRsIpbBnlTgJ43qpk_uUok8AFEcfIewd_pwh7I_LPjhJ5hLZufiQZOBz-GvG2iq64TrLyJivqjx_HK4rqDkAJ3yVFBJB3tlitZVnISxzOSG2Hgo5QmrlWShYTBwnX4SDU0zMBpd8dGSg0/s1600/shell-options.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRsIpbBnlTgJ43qpk_uUok8AFEcfIewd_pwh7I_LPjhJ5hLZufiQZOBz-GvG2iq64TrLyJivqjx_HK4rqDkAJ3yVFBJB3tlitZVnISxzOSG2Hgo5QmrlWShYTBwnX4SDU0zMBpd8dGSg0/s1600/shell-options.png&quot; height=&quot;250&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;You can see that I have added two options. &#39;protractor_install&#39; and &#39;npm_install&#39;. It is better to add an npm install before we are installing chrome driver and selenium just to make sure that, everything is ready beforehand.&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; Now we will add the install task. I have added both &#39;npm_install&#39; and &#39;protractor_install&#39; to the install task.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV5mXXFkEJUweqBf7OGQ9r-V5NwL4T5hTaqDqJqeZUePt5smvmd3HiuCpqHbKgfHWZta6yvnt-x2CjyjhLCQXddg78SztZfItbwvw-znlGCPYpzfh2HP6haNKVVXLx5sAshgeUxZlWO8g/s1600/spawn-register-task.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhV5mXXFkEJUweqBf7OGQ9r-V5NwL4T5hTaqDqJqeZUePt5smvmd3HiuCpqHbKgfHWZta6yvnt-x2CjyjhLCQXddg78SztZfItbwvw-znlGCPYpzfh2HP6haNKVVXLx5sAshgeUxZlWO8g/s1600/spawn-register-task.png&quot; height=&quot;60&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;
Now, if we do a grunt install on the command console, it will show as everything uptodate, since we have already installed selenium and chromedriver in the current project folder.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha2E3ve4FaRE1y16a61luEknDF6yhuRsqZBws8BXF-EdqLALK527ZjfHAiIEocddVwwJ9f4yCfCpiq4kLTVrF4_L-qspnhExidEaF2qG_OVJYlBtWg95zFL0fJDeFb3WUTwj8er5vUNUU/s1600/chromeuptodate.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEha2E3ve4FaRE1y16a61luEknDF6yhuRsqZBws8BXF-EdqLALK527ZjfHAiIEocddVwwJ9f4yCfCpiq4kLTVrF4_L-qspnhExidEaF2qG_OVJYlBtWg95zFL0fJDeFb3WUTwj8er5vUNUU/s1600/chromeuptodate.png&quot; height=&quot;174&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
PS: You can see some warning. Please ignore that for now. This is because we haven&#39;t added the README.md file and repo to the project, which we will add at the end.&lt;br /&gt;
&lt;br /&gt;
To demonstrate the usefulness of what we did now, lets make a copy of our project folder. Make sure that, you are not copying the node_modules folder. I copied the files to &#39;exampleCopy&#39; folder. Go to this copy folder in the command console.&lt;br /&gt;
&lt;br /&gt;
Now, if we do the &lt;b&gt;grunt install&lt;/b&gt;, everything should work, right? Let&#39;s see.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHLbcPDMNUFdNtdXmZuZOvmFKLp9Cp0juGHHSUe0Mb3OGeol_3XghQluIe8mx2Jjb_HqS5LYWQ63hpBfrH4rSx4ZIuDw-4LvgfezmXJQOBv7ss1oBfkvSdONWcbVRWFnmCcGy724Y1mqg/s1600/nolocalgrunt.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHLbcPDMNUFdNtdXmZuZOvmFKLp9Cp0juGHHSUe0Mb3OGeol_3XghQluIe8mx2Jjb_HqS5LYWQ63hpBfrH4rSx4ZIuDw-4LvgfezmXJQOBv7ss1oBfkvSdONWcbVRWFnmCcGy724Y1mqg/s1600/nolocalgrunt.png&quot; height=&quot;144&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
It is saying that a local copy of grunt is required. So, we have to do an &lt;b&gt;npm install &lt;/b&gt;before we call any grunt tasks. Let&#39;s do that.&lt;br /&gt;
&lt;br /&gt;
1. npm install&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZbYE6zqDL6YwTn54Vo6_oK2nveKPVNkF2hx8HhOPvXjqUAursgwmkxRjDJcTZwiLEzgRV27WAgsR2kUVCl2Ir6FSYBcnKetOjpnd350Vm-axC9Df3eO1bhs1E8tdBtey0LoPANlJRZOw/s1600/npm+install.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjZbYE6zqDL6YwTn54Vo6_oK2nveKPVNkF2hx8HhOPvXjqUAursgwmkxRjDJcTZwiLEzgRV27WAgsR2kUVCl2Ir6FSYBcnKetOjpnd350Vm-axC9Df3eO1bhs1E8tdBtey0LoPANlJRZOw/s1600/npm+install.png&quot; height=&quot;96&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
2. grunt install&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVFNodxsNRHymUlZwXXnRknVJIantIR_AEgb68qwVhdtWJ4rEqrLDJ2Rzwh8aR68lcea7hG8jatUJ7aqLRkhU6ZCsHaPQrxb4UY5EThNUNuOf0csr_T-VYqvlySWa6jeBdBVCz7VIrMb0/s1600/grunt+install+success.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhVFNodxsNRHymUlZwXXnRknVJIantIR_AEgb68qwVhdtWJ4rEqrLDJ2Rzwh8aR68lcea7hG8jatUJ7aqLRkhU6ZCsHaPQrxb4UY5EThNUNuOf0csr_T-VYqvlySWa6jeBdBVCz7VIrMb0/s1600/grunt+install+success.png&quot; height=&quot;186&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Now you are ready to do the protractor tests. So, any other person using this repo only need to run two commands &quot;&lt;b&gt;npm install&lt;/b&gt;&quot; and &quot;&lt;b&gt;grunt install&lt;/b&gt;&quot; and they are ready to go.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Adding the HTML Reporter&lt;/span&gt;&lt;/h2&gt;
When we run the tests, we can see that tests are passing or failing in the command console. What if we have hundreds of tests and also want to keep a record of the test results &amp;nbsp;whenever we run the tests? We need test reporters for that.&lt;br /&gt;
&lt;br /&gt;
Protractor gives the options to add onPrepare function property on its configuration file. This onPrepare function will be called before each tests. Jasmine test framework(which we are using inside protractor) provides the option to add test reporter. We will get the metadata about each test by using these two configurations.&lt;br /&gt;
&lt;br /&gt;
There is a node module available for generating screenshots for each tests.&amp;nbsp;&lt;a href=&quot;https://github.com/swissmanu/protractor-screenshot-reporter&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;protractor-screenshot-reporter&lt;/a&gt;. However this doesn&#39;t process the meta data and gives us the result in a readable format.&lt;br /&gt;
&lt;br /&gt;
I couldn&#39;t find a node module doing this for protractor. So, I created a module for generating this HTML report, on top of protractor-screenshot reporter,&amp;nbsp;&lt;a href=&quot;https://www.npmjs.org/package/protractor-html-screenshot-reporter&quot; target=&quot;_blank&quot;&gt;protractor-html-screenshot-reporter&lt;/a&gt;. What it does is generate an HTML report with all the details of the test like status, browser used, message, link to screenshot etc.&amp;nbsp;(If you are finding some other modules which are doing the same, please add in the comments. )&lt;br /&gt;
&lt;br /&gt;
Lets install&amp;nbsp;&lt;a href=&quot;https://www.npmjs.org/package/protractor-html-screenshot-reporter&quot; target=&quot;_blank&quot;&gt;protractor-html-screenshot-reporter&lt;/a&gt;&amp;nbsp;module in our project.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUMnAhkH0jz6E8G7S2bcI0gh50Cq2z3K1ma2cUb0HR8VUjGmR4dhTZbXDy7dSTjerg0XObzAEBqH9RmMLhZupUJk49rZ_TYBk_uIC06nXKdQOvjh1-znpZodDpSJy-SS-YvuRuI0hrBWs/s1600/install-reporter.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjUMnAhkH0jz6E8G7S2bcI0gh50Cq2z3K1ma2cUb0HR8VUjGmR4dhTZbXDy7dSTjerg0XObzAEBqH9RmMLhZupUJk49rZ_TYBk_uIC06nXKdQOvjh1-znpZodDpSJy-SS-YvuRuI0hrBWs/s1600/install-reporter.png&quot; height=&quot;130&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
We need to add this reporter in the Protractor configuration file.&lt;br /&gt;
&lt;br /&gt;
1. require the&amp;nbsp;protractor-html-screenshot-reporter module and assign to a variable.&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj8PGLgxCP6TPWvLnuq32TgMEfNhWksaLHwxcVmjppqQ64IQiAZcrrEGfzsLlJSW6lmXyTldEA_lpGj0Qu5x7rK-bn7ew3IhOQaZhqq4GuBZj06z548AKwrtcFaFIVJ0YVCu2yFRwgKsQ/s1600/protractor-top.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhj8PGLgxCP6TPWvLnuq32TgMEfNhWksaLHwxcVmjppqQ64IQiAZcrrEGfzsLlJSW6lmXyTldEA_lpGj0Qu5x7rK-bn7ew3IhOQaZhqq4GuBZj06z548AKwrtcFaFIVJ0YVCu2yFRwgKsQ/s1600/protractor-top.png&quot; height=&quot;142&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
2. add this reporter on the onPrepare function.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;onPrepare: function() {
      // Add a reporter and store screenshots to `screnshots`:
      jasmine.getEnv().addReporter(new HtmlReporter({
         baseDirectory: &#39;screenshots&#39;
      }));
   },
&lt;/pre&gt;
&lt;br /&gt;
3. Run the test using grunt command. It will run the default task in the Gruntfile.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAmKp3kT_-xjxtQkQN2slc0Li26_yLcJlWejnwYAH2fWYo2MCKhg-TrRt1xf1t_x4id8gyC5TgHpbC3cebmLGvDzKExb3nxu1Cl26BJJ8qpPaMKqTBuBgS1fecIIkpUKk2jIeroLOYKfs/s1600/test_running.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhAmKp3kT_-xjxtQkQN2slc0Li26_yLcJlWejnwYAH2fWYo2MCKhg-TrRt1xf1t_x4id8gyC5TgHpbC3cebmLGvDzKExb3nxu1Cl26BJJ8qpPaMKqTBuBgS1fecIIkpUKk2jIeroLOYKfs/s1600/test_running.png&quot; height=&quot;126&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&amp;nbsp; &amp;nbsp;We can see that the tests are passing. Lets see if the reports are generated.&lt;br /&gt;
&lt;br /&gt;
Screenshots folder is created.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRJJ-rKnVPAYS3kWAvBMqKJNe2In6Y5bTdpP4T8FkzWRP_8ASxB08ONujzE0JA7UBEPyEsXnwHcXwz5dUWcHnWMfCJ8aqLWu1xrqUvkyYJZ1l6Yyhr6W2OohoAR6ITHXSpKaTpmZikL6Q/s1600/screenshotsfolder.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhRJJ-rKnVPAYS3kWAvBMqKJNe2In6Y5bTdpP4T8FkzWRP_8ASxB08ONujzE0JA7UBEPyEsXnwHcXwz5dUWcHnWMfCJ8aqLWu1xrqUvkyYJZ1l6Yyhr6W2OohoAR6ITHXSpKaTpmZikL6Q/s1600/screenshotsfolder.png&quot; height=&quot;176&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Inside the screenshots folder, one json and png with a guid filename is available. This is the metadata and screenshot respectively for the single test. There is also a combined.json which combines all the metadata into a single file and a reporter.html file which shows all the test reports.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi88zNpcC_AZn37Ipu134gvagixJupkoCb18xAiofZ7yxOeC8TpavzOX3iIuyWyMW5PfgOwxbrVTQqZKhVQDrt2GGnyHWOFpUkxTnprh5vWTiVGhYfio38DBpRFW4aJpG2OUc2wfGKYERo/s1600/insidescreenshotsfolder.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEi88zNpcC_AZn37Ipu134gvagixJupkoCb18xAiofZ7yxOeC8TpavzOX3iIuyWyMW5PfgOwxbrVTQqZKhVQDrt2GGnyHWOFpUkxTnprh5vWTiVGhYfio38DBpRFW4aJpG2OUc2wfGKYERo/s1600/insidescreenshotsfolder.png&quot; height=&quot;202&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
Opening the reporter.html looks like below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAZUu1j-tDvIJgT82Hy2_jP3BOPdtI5QG6sVrr9K199-9YFI7SPzQlaBWXNd_TG3uhcjo_IJiZMF80GJ4ydb-TIin-jEqUh_hy__sCodyxQDPrBr64dIN_gUCoMviL8dS7P-My-9hO1wo/s1600/reporter_scrshot.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjAZUu1j-tDvIJgT82Hy2_jP3BOPdtI5QG6sVrr9K199-9YFI7SPzQlaBWXNd_TG3uhcjo_IJiZMF80GJ4ydb-TIin-jEqUh_hy__sCodyxQDPrBr64dIN_gUCoMviL8dS7P-My-9hO1wo/s1600/reporter_scrshot.png&quot; height=&quot;142&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
Clicking on View link opens the screenshot image also.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHVng_bdbjoRP7DzXOACKMCE45uK0CCCVlDAjOUcpUhEy4gaXN2knX1KFzRsSfq3ablrvxcdnSof5-6_eEST9CLPSA3iyKNpXR6t3uve1LXqtl6h7eXatgaCcZSNGvqdqMYU0cPvFOih4/s1600/screenshot_img.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiHVng_bdbjoRP7DzXOACKMCE45uK0CCCVlDAjOUcpUhEy4gaXN2knX1KFzRsSfq3ablrvxcdnSof5-6_eEST9CLPSA3iyKNpXR6t3uve1LXqtl6h7eXatgaCcZSNGvqdqMYU0cPvFOih4/s1600/screenshot_img.png&quot; height=&quot;258&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
So, now you have an html reporter ready. But, there is one issue though. Whenever you run the tests, the reporter files are getting overridden. If I want to keep a track of tests, this is not going to help.&lt;br /&gt;
&lt;br /&gt;
protractor-html-screenshot-reporter provides the option of pathBuilder function property to give your own dynamic paths. We will add this in Protractor configuration file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;  onPrepare: function() {
      // Add a reporter and store screenshots to `screnshots`:
      jasmine.getEnv().addReporter(new HtmlReporter({
         baseDirectory: &#39;screenshots&#39;,
         pathBuilder: function pathBuilder(spec, descriptions, results, capabilities) {
          
            var monthMap = {
              &quot;1&quot;: &quot;Jan&quot;,
              &quot;2&quot;: &quot;Feb&quot;,
              &quot;3&quot;: &quot;Mar&quot;,
              &quot;4&quot;: &quot;Apr&quot;,
              &quot;5&quot;: &quot;May&quot;,
              &quot;6&quot;: &quot;Jun&quot;,
              &quot;7&quot;: &quot;Jul&quot;,
              &quot;8&quot;: &quot;Aug&quot;,
              &quot;9&quot;: &quot;Sep&quot;,
              &quot;10&quot;: &quot;Oct&quot;,
              &quot;11&quot;: &quot;Nov&quot;,
              &quot;12&quot;: &quot;Dec&quot;
            };

            var currentDate = new Date(),
                currentHoursIn24Hour = currentDate.getHours(),
                currentTimeInHours = currentHoursIn24Hour&amp;gt;12? currentHoursIn24Hour-12: currentHoursIn24Hour,
                totalDateString = currentDate.getDate()+&#39;-&#39;+ monthMap[currentDate.getMonth()]+ &#39;-&#39;+(currentDate.getYear()+1900) + 
                                      &#39;-&#39;+ currentTimeInHours+&#39;h-&#39; + currentDate.getMinutes()+&#39;m&#39;;

            return path.join(totalDateString,capabilities.caps_.browserName, descriptions.join(&#39;-&#39;));
         }
      }));
   },

&lt;/pre&gt;
&lt;br /&gt;
I am just using a basic function to give the folder name as the current date and time and browser.&lt;br /&gt;
&lt;br /&gt;
Note that I am using the &lt;a href=&quot;http://nodejs.org/api/path.html&quot; rel=&quot;nofollow&quot; target=&quot;_blank&quot;&gt;path module&lt;/a&gt;&amp;nbsp;for creating the file path (path is a native node module for handling and tranforming file paths. ). Make sure that, you have required the path and assigned to a variable.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjMt1K4brMQDCCjm0XiPcvQ1uk7pHOhYH3wffpUdWFXQhHLHNjLY7rOQ51aSHzpfUk_Ks5hiattX1PofOZvoqrfMTQtY-3pUjcyJiqm3uFPr90EzRBwieE8xtjqcpV_-In7l8VTiMhdbA/s1600/protractor-top-with-path.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjMt1K4brMQDCCjm0XiPcvQ1uk7pHOhYH3wffpUdWFXQhHLHNjLY7rOQ51aSHzpfUk_Ks5hiattX1PofOZvoqrfMTQtY-3pUjcyJiqm3uFPr90EzRBwieE8xtjqcpV_-In7l8VTiMhdbA/s1600/protractor-top-with-path.png&quot; height=&quot;110&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
Lets run the test again using &lt;b&gt;grunt&lt;/b&gt; command in command console. As expected tests are running successfully.&lt;br /&gt;
&lt;br /&gt;
If we check the project folder we can see that, the report is now generated in the path &#39;screenshots/22-Feb-2014-5h-58m/chrome&#39;. Great. Now, on seeing the folder names itself, you know when the test was run and on which browser.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimAAN07TuL6bN_VVrLfH9pSSyZ1JSDKGm2SsfW-ncitKfWKuKIdvOhE_A1CPGdh-rOJjbXyhqv7b7w0Uo3UDJ3bNS8ub47XZfNkVMM_axkMbqP2NZqD7qbNPpxsgf40BpG56etq9VGpZg/s1600/folder-withdatetime.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEimAAN07TuL6bN_VVrLfH9pSSyZ1JSDKGm2SsfW-ncitKfWKuKIdvOhE_A1CPGdh-rOJjbXyhqv7b7w0Uo3UDJ3bNS8ub47XZfNkVMM_axkMbqP2NZqD7qbNPpxsgf40BpG56etq9VGpZg/s1600/folder-withdatetime.png&quot; height=&quot;190&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Finally, lets make this project ready to add as a git repo.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
1. It is not a good a good practice to push node_modules directory to the repo. In order to avoid node_modules to be pushed to git, we need to add it to .gitignore file.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Create a new file in the root folder with name as .gitignore.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHF-hZOxrIDiSxwzpcFpEKZ_LX7l8nmfoCVx1w8yfljSJqKgslMO6STd-y0a4HIwYPkT0QQPox2qz-gZkqW97FNgXV9-G1Cfo77yX3EOVSrKUuPSLgFaeaWvNsfIyiRSFmgvXSP2BSLk8/s1600/gitignore.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjHF-hZOxrIDiSxwzpcFpEKZ_LX7l8nmfoCVx1w8yfljSJqKgslMO6STd-y0a4HIwYPkT0QQPox2qz-gZkqW97FNgXV9-G1Cfo77yX3EOVSrKUuPSLgFaeaWvNsfIyiRSFmgvXSP2BSLk8/s1600/gitignore.png&quot; height=&quot;150&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
We don&#39;t want screenshots and node_modules folder to be added in git. So, I have added both names in .gitignore.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
2. We will also add the repository details to package.json.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmo1kJM6qBofB6AWXOG-JAMyHVnogduIot0VwYmATv_HaQNWKlRC8OI-WFpa60xczoJV3BknQjG-b0_DTXjc-4Pe8Lf6mGk6ZPQWex78VC0LJa9HT_Wj6ej2rl-UFAkSMSnqIjdmc_OnY/s1600/package.json.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhmo1kJM6qBofB6AWXOG-JAMyHVnogduIot0VwYmATv_HaQNWKlRC8OI-WFpa60xczoJV3BknQjG-b0_DTXjc-4Pe8Lf6mGk6ZPQWex78VC0LJa9HT_Wj6ej2rl-UFAkSMSnqIjdmc_OnY/s1600/package.json.png&quot; height=&quot;174&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
3. Also, create a README.md file in the root folder and add some description of your project.&amp;nbsp;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: left;&quot;&gt;
Finally, we are ready to push to the repo.&amp;nbsp;&lt;/div&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;More Requirements&lt;/span&gt;&lt;/h2&gt;
&amp;nbsp;Now that we are in a good state, we can check the further requirements.&lt;br /&gt;
&lt;br /&gt;
&lt;ol&gt;
&lt;li&gt;Generating tests based on style guide&lt;/li&gt;
&lt;li&gt;Doing CSS Regression testing&lt;/li&gt;
&lt;/ol&gt;
&lt;br /&gt;
We will cover that in the coming articles. Stay tuned.&lt;br /&gt;
&lt;br /&gt;
Please share your comments.&lt;br /&gt;
&lt;br /&gt;
All the changes are added on github repo -&amp;nbsp;&lt;a href=&quot;https://github.com/jintoppy/protractor-e2e-bootstrap&quot; target=&quot;_blank&quot;&gt;protractor-e2e-bootstrap&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;a href=&quot;http://programmerbuddy.blogspot.in/2014/03/full-automation-of-protractor-e2e-tests.html&quot;&gt;Previous&lt;/a&gt;&amp;nbsp;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/4736869226487560496/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2014/03/full-automation-of-protractor-e2e-tests_22.html#comment-form' title='44 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4736869226487560496'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4736869226487560496'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2014/03/full-automation-of-protractor-e2e-tests_22.html' title='Full automation of Protractor E2E tests using Grunt - Part 2'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjekMXioTnrr4i4sQoI8sTYQGcp4FLmsVtTQWqcqwQ_bFw8wwA3XDwJmJpqJem8kWaCHqLNQdo5p7bKXkBCJ-axcvzeVKB92LrvsmH97WIjE3axKWpzaEEKKqpcEXmMZdWsCaHxJLXFzK4/s72-c/shell-spawn-install.png" height="72" width="72"/><thr:total>44</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-4405032857538883446</id><published>2014-03-18T01:37:00.000-07:00</published><updated>2014-03-22T09:57:40.147-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="grunt"/><category scheme="http://www.blogger.com/atom/ns#" term="html reporter"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript e2e testing"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript testing"/><category scheme="http://www.blogger.com/atom/ns#" term="protractor"/><category scheme="http://www.blogger.com/atom/ns#" term="protractor automation"/><category scheme="http://www.blogger.com/atom/ns#" term="selenium"/><title type='text'>Full automation of Protractor E2E tests using Grunt - Part 1</title><content type='html'>Everyone now talking about Test Driven Development(TDD), Behaviour Driven Development(BDD) and all. I also got interested in the topic and tried to learn more about it. I tried several frameworks like Jasmine, Mocha, Siesta(for an ExtJS application), but couldn&#39;t go further on this. I always ended up in stopping after doing some sample tests&lt;br /&gt;
&lt;br /&gt;
I think one reason for that could be that, I didn&#39;t see the practical use of Test&lt;br /&gt;
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. &lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Half of the application is based on jQuery.&amp;nbsp;&lt;/li&gt;
&lt;li&gt;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&amp;nbsp;&lt;/li&gt;
&lt;/ul&gt;
&lt;div&gt;
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.&lt;br /&gt;
&lt;br /&gt;
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?&lt;br /&gt;
&lt;br /&gt;
Here comes the &lt;b&gt;Protractor &lt;/b&gt;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 &amp;nbsp;or MacOS, not windows. I found it difficult to setup the protractor.&lt;br /&gt;
&lt;br /&gt;
If we don&#39;t find it very easy to use, we will stop using and modifying the tests, &lt;b&gt;because we are all lazy :-).&amp;nbsp;&lt;/b&gt;&lt;br /&gt;
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 &lt;b&gt;Grunt&lt;/b&gt; was not there.&lt;br /&gt;
&lt;br /&gt;
So, &lt;b&gt;Protractor + Grunt&lt;/b&gt; 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.&lt;br /&gt;
&lt;br /&gt;
I will be also adding the samples to the following repository, so that, anyone can try it out.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/jintoppy/protractor-e2e-bootstrap&quot; target=&quot;_blank&quot;&gt;Protractor-e2e-bootstrap Repo&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;Setting up the project&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
Requirements:&lt;br /&gt;
1. Install Node.js&lt;br /&gt;
2. Install Grunt-cli (Get more details &lt;a href=&quot;http://gruntjs.com/getting-started&quot; target=&quot;_blank&quot;&gt;here&lt;/a&gt;)&lt;br /&gt;
&lt;br /&gt;
We will first setup a basic project by running the command &#39;npm init&#39;&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXlGXL9rsRmrO2d3JdKgyKsYbTHBW8kIr8gtwqzrdYZpXucjiS9IhckY92p63DqEK2cb-UTc8DnojeoCcx5424hqZB4RKaRBdJvvitgjEXEZLWsccyZ1iBq_x92MVkdb_DRWkNwR5w_W4/s1600/npm_init.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXlGXL9rsRmrO2d3JdKgyKsYbTHBW8kIr8gtwqzrdYZpXucjiS9IhckY92p63DqEK2cb-UTc8DnojeoCcx5424hqZB4RKaRBdJvvitgjEXEZLWsccyZ1iBq_x92MVkdb_DRWkNwR5w_W4/s1600/npm_init.png&quot; height=&quot;473&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
It will ask for a few questions and you will get a package.json created for you.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbTyjRKoKY3p6U1CKTtGIL12bCLPqkND8MwqYHBjXpYOMjHUWLib1i_iTc8FpiyDVYmShmeYE9Pl5gGYJoZKtOgweWzQbAUEsGJWq2kCutAykP6MVmj1GCWUCnx8elawLtjxiD06bt4Sw/s1600/package.json.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgbTyjRKoKY3p6U1CKTtGIL12bCLPqkND8MwqYHBjXpYOMjHUWLib1i_iTc8FpiyDVYmShmeYE9Pl5gGYJoZKtOgweWzQbAUEsGJWq2kCutAykP6MVmj1GCWUCnx8elawLtjxiD06bt4Sw/s1600/package.json.png&quot; height=&quot;266&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Create a folder &#39;specs&#39;. We will put all our tests in specs folder. (You can give any name you want)&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;b&gt;&lt;span style=&quot;font-size: x-large;&quot;&gt;Installing Protractor&lt;/span&gt;&lt;/b&gt;&lt;/h2&gt;
&lt;br /&gt;
Lets first install Protractor.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1-9I2YqkKQkaA_YQFvccXCxQWTVGdoCTCE0GwHHEc0gUwIU6kimxogRvMGPMFw_fKsaaXaC-XJ46qv4i8SiljMZy8plCZ3OHqAis7Mth-08yNYyLS696lfLpHXvs-jIwqGt5P8NXhF4/s1600/protractor-install.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgq1-9I2YqkKQkaA_YQFvccXCxQWTVGdoCTCE0GwHHEc0gUwIU6kimxogRvMGPMFw_fKsaaXaC-XJ46qv4i8SiljMZy8plCZ3OHqAis7Mth-08yNYyLS696lfLpHXvs-jIwqGt5P8NXhF4/s1600/protractor-install.png&quot; height=&quot;46&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
You can install protractor globally also. Then you can run test directly from the command line using &lt;b&gt;protractor&lt;/b&gt; command.&lt;br /&gt;
&lt;br /&gt;
But since our goal is to automate the process, global installation is not required.&lt;br /&gt;
&lt;br /&gt;
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 &#39;devDependencies&#39; automatically. (--save will add the module name under &#39;dependencies&#39; property)&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh_zo3TKXTuFw8ddTZVwxpbbpccX4Tnp6_rvFBUdE2Zto6-oZ9dRTk_lIZy_U2y1NE-lhl9pQ916-5lh_Vc1KBeuu08EpABy7wY_D2nK1x4QN7rinob9GSVPw-oo1pWTU14JBciAj_MyM/s1600/devdependencies.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjh_zo3TKXTuFw8ddTZVwxpbbpccX4Tnp6_rvFBUdE2Zto6-oZ9dRTk_lIZy_U2y1NE-lhl9pQ916-5lh_Vc1KBeuu08EpABy7wY_D2nK1x4QN7rinob9GSVPw-oo1pWTU14JBciAj_MyM/s1600/devdependencies.png&quot; height=&quot;310&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Adding Grunt&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;
Now we will add Gruntfile.js to our root folder. This file is required for grunt to run the tests.&lt;br /&gt;
&lt;br /&gt;
A minimum configuration Grunt file with &lt;a href=&quot;http://www.jshint.com/&quot;&gt;jshint&lt;/a&gt; task added is given below.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;module.exports = function(grunt) {

  grunt.initConfig({
    pkg: grunt.file.readJSON(&#39;package.json&#39;),

    jshint: {
      files: [&#39;Gruntfile.js&#39;, &#39;specs/*.js&#39;],
      options: {
        // options here to override JSHint defaults
        globals: {
          jQuery: true,
          console: true,
          module: true,
          document: true
        }
      }

    }
  });

  grunt.loadNpmTasks(&#39;grunt-contrib-jshint&#39;);

  grunt.registerTask(&#39;default&#39;, [&#39;jshint&#39;]);

};
&lt;/pre&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
For this to work, we need to install the jshint grunt plugin. 

&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3lU9i_EoqDBsv5j9fyaVWzwAYIF5nJGVYR_3SLnGixpyRTAy56nIU07khB1JJWuPFfkFNM5FRxCxcWA3DVszy_45KQdWBoA9JesYTwB3yA3mh-0v_5OpJ53RHKvtrBWVGsn6GchgxL4/s1600/jshint-install.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgN3lU9i_EoqDBsv5j9fyaVWzwAYIF5nJGVYR_3SLnGixpyRTAy56nIU07khB1JJWuPFfkFNM5FRxCxcWA3DVszy_45KQdWBoA9JesYTwB3yA3mh-0v_5OpJ53RHKvtrBWVGsn6GchgxL4/s1600/jshint-install.png&quot; height=&quot;28&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3dwcxpCGDIgxyKxn7bMPTE3EJLnlmTJWCp3vuL73-bxRoEwAIw3Vb9fmlO4K-Z-zmj0GQ3nK6uagSOm6duUTKRNDWmZ0qByglmhhDUHvej81K93h064ZAyHXRZFeQsNmQ7Eg2XjSawUc/s1600/grunt-first.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg3dwcxpCGDIgxyKxn7bMPTE3EJLnlmTJWCp3vuL73-bxRoEwAIw3Vb9fmlO4K-Z-zmj0GQ3nK6uagSOm6duUTKRNDWmZ0qByglmhhDUHvej81K93h064ZAyHXRZFeQsNmQ7Eg2XjSawUc/s1600/grunt-first.png&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
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, &#39;protracter-grunner&#39;. We will install that now.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCa95otullfuqZTA03rCsEV7LgXJjvfVYSNpZ1h-CYLRCEsuWUd16jKgPT6iclEkanVqGiF3ZlISMCyUO9PFbvRs69iDIo9wyDTDOitZbRnfxWRxVPp0_efsrKYrty4aXL-Ui8BnIdv9Y/s1600/protractor-runner.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgCa95otullfuqZTA03rCsEV7LgXJjvfVYSNpZ1h-CYLRCEsuWUd16jKgPT6iclEkanVqGiF3ZlISMCyUO9PFbvRs69iDIo9wyDTDOitZbRnfxWRxVPp0_efsrKYrty4aXL-Ui8BnIdv9Y/s1600/protractor-runner.png&quot; height=&quot;40&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Adding Protractor configuration to Grunt&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;
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.&lt;br /&gt;
&lt;br /&gt;
You can get a sample protractor configuration file from the Protractor repo&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/angular/protractor/blob/master/referenceConf.js&quot; target=&quot;_blank&quot;&gt;https://github.com/angular/protractor/blob/master/referenceConf.js&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
We are going to use the following configuration file with basic settings.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;// 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: &#39;node_modules/protractor/selenium/selenium-server-standalone-2.40.0.jar&#39;,
  // 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: &#39;node_modules/protractor/selenium/chromedriver&#39;,
  // Additional command line options to pass to selenium. For example,
  // if you need to change the browser timeout, use
  // seleniumArgs: [&#39;-browserTimeout=60&#39;],
  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: [
    &#39;./specs/*.js&#39;
  ],

  // ----- 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: {
    &#39;browserName&#39;: &#39;chrome&#39;
  },

  // A base URL for your application under test. Calls to protractor.get()
  // with relative paths will be prepended with this.
  baseUrl: &#39;http://localhost:9999&#39;,

  // Selector for the element housing the angular app - this defaults to
  // body, but is necessary if ng-app is on a descendant of

  rootElement: &#39;body&#39;,

  // ----- 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
  }
};

&lt;/pre&gt;
We will be modifying this file in a bit. For now, lets keep it like this.&lt;br /&gt;
&lt;br /&gt;
We need to add the protractor task in Gruntfile. 


&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt; },
    protractor: {
      options: {
        keepAlive: true,
        configFile: &quot;protractor.conf.js&quot;
      },
      singlerun: {},
      auto: {
        keepAlive: true,
        options: {
          args: {
            seleniumPort: 4444
          }
        }
      }
    }

  });


  grunt.loadNpmTasks(&#39;grunt-protractor-runner&#39;);
&lt;/pre&gt;
&lt;br /&gt;
You can see that, I have added two options. auto and singlerun. For &#39;auto&#39;, I am giving keepAlive as true. This setting can be run if we need to run tests on each modification. &#39;singlerun&#39; opiton will run just once and stop the task.&lt;br /&gt;
&lt;br /&gt;
Finally, register the &#39;singlerun&#39; task to grunt. 

&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;grunt.registerTask(&#39;default&#39;, [&#39;jshint&#39;, &#39;protractor:singlerun&#39;]);
&lt;/pre&gt;
&lt;br /&gt;
Now, that we have done the basic set up. For running protractor from grunt, lets add some test.&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Adding the tests&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;
Lets take a basic test which is given in Protractor &amp;nbsp;site and save in &#39;specs&#39; folder.&lt;br /&gt;
&lt;pre class=&quot;prettyprint linenums&quot;&gt;describe(&#39;angularjs homepage&#39;, function() {
  it(&#39;should greet the named user&#39;, function() {
    browser.get(&#39;http://www.angularjs.org&#39;);

    element(by.model(&#39;yourName&#39;)).sendKeys(&#39;Julie&#39;);

    var greeting = element(by.binding(&#39;yourName&#39;));

    expect(greeting.getText()).toEqual(&#39;Hello Julie!&#39;);
  });
});
&lt;/pre&gt;
&lt;br /&gt;
Most of it is self explanatory. Protractor is a wrapper around selenium Selenium WebdriverJS with its angular flavour.&lt;br /&gt;
&lt;br /&gt;
The runner exposes global variables &lt;b&gt;browser&lt;/b&gt;, &lt;b&gt;by&lt;/b&gt; and &lt;b&gt;element&lt;/b&gt;.

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.

&lt;b&gt;element&lt;/b&gt; and &lt;b&gt;by&lt;/b&gt; is used for selecting an HTML element, using various selectors. 

You can get more details on Protractor and WebdriverJS &lt;a href=&quot;https://github.com/angular/protractor/blob/master/docs/getting-started.md&quot;&gt;here&lt;/a&gt;

&lt;br /&gt;
&lt;br /&gt;
So, what this test does is given below:&lt;br /&gt;
&lt;br /&gt;
1. browser opens the url http://www.angularjs.org&lt;br /&gt;
2. Gets the input having ng-model=&quot;yourName&quot; and set the value as &#39;Julie&#39;&lt;br /&gt;
3. Gets the element which binds the same model.&lt;br /&gt;
4. The expectation is that, the binding value is changed to &#39;Hello Julie!&#39;




&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDA5_GbuQzNEX92G3g2cpDPmwQbpccPuDpFXOpAgibZ4DqEs-MLKUBd_fxL_aOYzwFF6z_JYd5jwmawp1UuQrz_O5DL885u3MBNzBkYZYNriKYQ1YcWBlqshUesw6RlcpvHeUuGQCGpxw/s1600/angularjs.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiDA5_GbuQzNEX92G3g2cpDPmwQbpccPuDpFXOpAgibZ4DqEs-MLKUBd_fxL_aOYzwFF6z_JYd5jwmawp1UuQrz_O5DL885u3MBNzBkYZYNriKYQ1YcWBlqshUesw6RlcpvHeUuGQCGpxw/s1600/angularjs.png&quot; height=&quot;204&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Installing Selenium and Chromedriver&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;
Ok... So the test is ready. Now, lets try running this. Wait a minute.. we haven&#39;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.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWpKrkLokNlFXA34qSAjhGmSK-qNURTXf6BvI1zirwVWTV6xnlewFwEbk7ktv27v5M77YrpOMMLV4yeWo5d-67qvBODBI6LfibZ5dC-Hcv__21Yevm_lzFNnhgLUBTDurTFWY7OnHCaHM/s1600/webdriver-manager.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgWpKrkLokNlFXA34qSAjhGmSK-qNURTXf6BvI1zirwVWTV6xnlewFwEbk7ktv27v5M77YrpOMMLV4yeWo5d-67qvBODBI6LfibZ5dC-Hcv__21Yevm_lzFNnhgLUBTDurTFWY7OnHCaHM/s1600/webdriver-manager.png&quot; height=&quot;216&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
&#39;webdriver-manager update&#39; will install Selenium and Chrome driver and chromedriver. .&lt;br /&gt;
&lt;br /&gt;
&#39;webdriver-manager start&#39; command will start the selenium server
&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Running Test&lt;/span&gt;&lt;/h2&gt;
&lt;br /&gt;
Keeping this command window open, open another console. Lets run the test using &#39;grunt&#39; and see what happens.&lt;br /&gt;
&lt;br /&gt;
You can see that browser is opening up and goes to angularjs.org.&lt;br /&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiShlDmRaenMLCfxIMfZF4hsAyzi24O9Cu7Astg8NLBR6dyhyVZGX9erps4xGDYeJHOmgOgBiwaXUktZow0g0Lrygj3J7q50dtGWjCLVCBqO-i2xdfJmaL7RW3B2b7sL_CILDwfjIsOKJw/s1600/test-running.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiShlDmRaenMLCfxIMfZF4hsAyzi24O9Cu7Astg8NLBR6dyhyVZGX9erps4xGDYeJHOmgOgBiwaXUktZow0g0Lrygj3J7q50dtGWjCLVCBqO-i2xdfJmaL7RW3B2b7sL_CILDwfjIsOKJw/s1600/test-running.png&quot; height=&quot;238&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhGLkJwJst-g3ppvnZH-4Nsz6mgjJfaUTbSOgFjIE6YfVRmm-I3oMy-HRnghALc8xgidDO_b9HSvCtGFzycoKrkiN8u5zEMa1nLJUONxr2mMoRfIS2tkGG0h5luppbGWmd9IF2L8IlBaw/s1600/test-success.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhhGLkJwJst-g3ppvnZH-4Nsz6mgjJfaUTbSOgFjIE6YfVRmm-I3oMy-HRnghALc8xgidDO_b9HSvCtGFzycoKrkiN8u5zEMa1nLJUONxr2mMoRfIS2tkGG0h5luppbGWmd9IF2L8IlBaw/s1600/test-success.png&quot; height=&quot;208&quot; width=&quot;640&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;
Test is passing!!!&lt;br /&gt;
&lt;br /&gt;
&lt;h2&gt;
&lt;span style=&quot;font-size: x-large;&quot;&gt;Improvements&lt;/span&gt;&lt;/h2&gt;
However, there are some still some improvements needed.&lt;br /&gt;
&lt;br /&gt;
1. I don&#39;t want to do the webmanager-update whenever I clone this project to another location. I want to make the installation easy.&lt;br /&gt;
2. The reports are just showing in command line. I want to see the reports in HTML with some screenshots also if possible.&lt;br /&gt;
3. And, some other improvements..&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
We will cover that in the next post. Stay tuned. &lt;br /&gt;
&lt;br /&gt;
All the files are available in &lt;a href=&quot;https://github.com/jintoppy/protractor-e2e-bootstrap&quot;&gt;https://github.com/jintoppy/protractor-e2e-bootstrap&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
&lt;h3&gt;
&lt;span style=&quot;font-size: large;&quot;&gt;Update: Part 2 of this article series is available &lt;a href=&quot;http://programmerbuddy.blogspot.in/2014/03/full-automation-of-protractor-e2e-tests_22.html&quot;&gt;here&lt;/a&gt;.&lt;/span&gt;&lt;/h3&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/4405032857538883446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2014/03/full-automation-of-protractor-e2e-tests.html#comment-form' title='14 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4405032857538883446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4405032857538883446'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2014/03/full-automation-of-protractor-e2e-tests.html' title='Full automation of Protractor E2E tests using Grunt - Part 1'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiXlGXL9rsRmrO2d3JdKgyKsYbTHBW8kIr8gtwqzrdYZpXucjiS9IhckY92p63DqEK2cb-UTc8DnojeoCcx5424hqZB4RKaRBdJvvitgjEXEZLWsccyZ1iBq_x92MVkdb_DRWkNwR5w_W4/s72-c/npm_init.png" height="72" width="72"/><thr:total>14</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-1910156117912967645</id><published>2013-12-18T00:33:00.002-08:00</published><updated>2013-12-18T00:33:44.038-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="js puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="puzzle"/><title type='text'>Javascript Puzzle - 2</title><content type='html'>Courtesy: A Javascript conference video. I forgot the name of the conference. Will update.&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;div&gt;
var name = &#39;Mr. Bond&#39;;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; (function(){&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; if(typeof name === &#39;undefined&#39;){&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; var name = &quot;Mr. Bond&quot;;&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; sayHello(name);&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; } else {&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;alert(name);&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; &amp;nbsp; &amp;nbsp;}&lt;/div&gt;
&lt;div&gt;
})();&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
function sayHello(name){&lt;/div&gt;
&lt;div&gt;
&amp;nbsp; &amp;nbsp; alert(&#39;hello, &#39; + typeof name !== &#39;undefined&#39;? name: &#39;Mr. Robert!&#39;);&lt;/div&gt;
&lt;div&gt;
}&lt;/div&gt;
&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
What this alerts? And, give me the reason for that.&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/1910156117912967645/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/12/javascript-puzzle-2.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1910156117912967645'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1910156117912967645'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/12/javascript-puzzle-2.html' title='Javascript Puzzle - 2'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-4596525671599096873</id><published>2013-12-18T00:29:00.002-08:00</published><updated>2013-12-18T00:29:53.031-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="js puzzle"/><category scheme="http://www.blogger.com/atom/ns#" term="puzzle"/><title type='text'>JavaScript Puzzle - 1</title><content type='html'>Courtesy: A Javascript conference video. I forgot the name of the conference. Will update.&lt;br /&gt;
&lt;br /&gt;
var END = 9007199254740992; //Math.pow(2,53)&lt;br /&gt;
&amp;nbsp; var START = END - 100;&lt;br /&gt;
&lt;br /&gt;
var count = 0;&lt;br /&gt;
for(var i = START; i&amp;lt;= END; i++){&lt;br /&gt;
&amp;nbsp; &amp;nbsp;count++;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
alert(count);&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
What this alerts? And, give me the reason for that.&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/4596525671599096873/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/12/javascript-puzzle-1.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4596525671599096873'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4596525671599096873'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/12/javascript-puzzle-1.html' title='JavaScript Puzzle - 1'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-7029453936588842064</id><published>2013-10-22T07:13:00.002-07:00</published><updated>2013-10-22T07:13:55.458-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="browser"/><category scheme="http://www.blogger.com/atom/ns#" term="browser rendering"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="jquery"/><category scheme="http://www.blogger.com/atom/ns#" term="rendering"/><title type='text'>Browser rendering performance testing - document.createfragment vs jquery-element</title><content type='html'>&lt;div style=&quot;background-color: #f5faf0; border: 0px; color: #3d3d3d; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, &#39;Lucida Grande&#39;, sans-serif; font-size: 13px; line-height: 19px; padding: 0px; vertical-align: baseline;&quot;&gt;
After reading the post on&amp;nbsp;&lt;a class=&quot;jive-link-external-small&quot; href=&quot;http://blog.korynunn.com/javascript/the-dom-isnt-slow-you-are/&quot; rel=&quot;nofollow&quot; style=&quot;border: 0px; color: #5073ad; font-family: inherit; font-style: inherit; margin: 0px; padding: 0px; text-decoration: none; vertical-align: baseline;&quot;&gt;browser rendering perforamnce&lt;/a&gt;, I tried some performance tests. You can see the test in the following url:&lt;/div&gt;
&lt;div style=&quot;background-color: #f5faf0; border: 0px; color: #3d3d3d; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, &#39;Lucida Grande&#39;, sans-serif; font-size: 13px; height: 8pt; line-height: 19px; min-height: 8pt; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f5faf0; border: 0px; color: #3d3d3d; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, &#39;Lucida Grande&#39;, sans-serif; font-size: 13px; line-height: 19px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;a class=&quot;jive-link-external-small&quot; href=&quot;http://jsperf.com/document-createfragment-vs-jquery-element&quot; rel=&quot;nofollow&quot; style=&quot;border: 0px; color: #5073ad; font-family: inherit; font-style: inherit; margin: 0px; padding: 0px; text-decoration: none; vertical-align: baseline;&quot;&gt;http://jsperf.com/document-createfragment-vs-jquery-element&lt;/a&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f5faf0; border: 0px; color: #3d3d3d; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, &#39;Lucida Grande&#39;, sans-serif; font-size: 13px; line-height: 19px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCtR_wuOEVSQekEl5oYvWm8JShqg15-MDP1vbUr4BrA6KWM4pqIc10wMi2jtv5AgdQDANPdIMfSdhypAwiX4NY0I8jyXYB6yYqIuvvaq5NYxlTfjW6aMwze5gDXZT1Oh1QEvEsbDt32t8/s1600/perforamnce_chrome.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;200&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCtR_wuOEVSQekEl5oYvWm8JShqg15-MDP1vbUr4BrA6KWM4pqIc10wMi2jtv5AgdQDANPdIMfSdhypAwiX4NY0I8jyXYB6yYqIuvvaq5NYxlTfjW6aMwze5gDXZT1Oh1QEvEsbDt32t8/s320/perforamnce_chrome.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgu_NRg3W8I6tgVF59lvL6sQ03Yf1oGGJqeu1ojSfFRoKpetDjI6b-9uYjfKavJePwveooDTkaxAiQa52sUyvZ6y6mrI0znOTS8BUEBnHggbBGc6yn0wNhvuUWi3-tl5psP-yDu2mPkhk/s1600/perforamnce_firefox.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;194&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhgu_NRg3W8I6tgVF59lvL6sQ03Yf1oGGJqeu1ojSfFRoKpetDjI6b-9uYjfKavJePwveooDTkaxAiQa52sUyvZ6y6mrI0znOTS8BUEBnHggbBGc6yn0wNhvuUWi3-tl5psP-yDu2mPkhk/s320/perforamnce_firefox.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfD_vfAPG9lNibyuLJZVybDqljC0Qiw3ysTQlJ9sMY6-sP9o92Xb4RaLANAM4uGx6PN3CrDu3RQL7hazoPMuFa7Du-b58qVsy9B_RTH80QmnKqFTonZhUE_9csuWGyr3QXLWXZfK5gzHU/s1600/perforamnce_ie.png&quot; imageanchor=&quot;1&quot; style=&quot;margin-left: 1em; margin-right: 1em;&quot;&gt;&lt;img border=&quot;0&quot; height=&quot;229&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgfD_vfAPG9lNibyuLJZVybDqljC0Qiw3ysTQlJ9sMY6-sP9o92Xb4RaLANAM4uGx6PN3CrDu3RQL7hazoPMuFa7Du-b58qVsy9B_RTH80QmnKqFTonZhUE_9csuWGyr3QXLWXZfK5gzHU/s320/perforamnce_ie.png&quot; width=&quot;320&quot; /&gt;&lt;/a&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;div class=&quot;separator&quot; style=&quot;clear: both; text-align: center;&quot;&gt;
&lt;span style=&quot;background-color: #f5faf0; color: #3d3d3d; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, &#39;Lucida Grande&#39;, sans-serif; font-size: 13px; line-height: 19px; text-align: left;&quot;&gt;See the chrome result. Doing with jquery element is faster than doing with document.createDocumentFragment. Surprising for me!!&lt;/span&gt;&lt;/div&gt;
&lt;div style=&quot;background-color: #f5faf0; border: 0px; color: #3d3d3d; font-family: &#39;Helvetica Neue&#39;, Helvetica, Arial, &#39;Lucida Grande&#39;, sans-serif; font-size: 13px; line-height: 19px; padding: 0px; vertical-align: baseline;&quot;&gt;
&lt;/div&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/7029453936588842064/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/10/browser-rendering-performance-testing.html#comment-form' title='5 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/7029453936588842064'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/7029453936588842064'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/10/browser-rendering-performance-testing.html' title='Browser rendering performance testing - document.createfragment vs jquery-element'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjCtR_wuOEVSQekEl5oYvWm8JShqg15-MDP1vbUr4BrA6KWM4pqIc10wMi2jtv5AgdQDANPdIMfSdhypAwiX4NY0I8jyXYB6yYqIuvvaq5NYxlTfjW6aMwze5gDXZT1Oh1QEvEsbDt32t8/s72-c/perforamnce_chrome.png" height="72" width="72"/><thr:total>5</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-5051779917219358704</id><published>2013-10-16T09:32:00.002-07:00</published><updated>2013-10-16T09:32:59.641-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="console.log"/><category scheme="http://www.blogger.com/atom/ns#" term="IIFE"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>Console is undefined error on console.log</title><content type='html'>I got error in my script on console.log(&#39;sample text&#39;). Only possibility I could think of is I am adding this in IIFE. Is this could be an issue? I will post the udpate</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/5051779917219358704/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/10/console-is-undefined-error-on-consolelog.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/5051779917219358704'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/5051779917219358704'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/10/console-is-undefined-error-on-consolelog.html' title='Console is undefined error on console.log'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-428992620198461083</id><published>2013-10-01T11:49:00.001-07:00</published><updated>2013-10-01T11:49:39.422-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="browser"/><category scheme="http://www.blogger.com/atom/ns#" term="css"/><category scheme="http://www.blogger.com/atom/ns#" term="css hack"/><category scheme="http://www.blogger.com/atom/ns#" term="css3"/><category scheme="http://www.blogger.com/atom/ns#" term="ie7"/><category scheme="http://www.blogger.com/atom/ns#" term="ie8"/><category scheme="http://www.blogger.com/atom/ns#" term="ie9"/><category scheme="http://www.blogger.com/atom/ns#" term="webkit"/><title type='text'>Browser specific CSS Hacks</title><content type='html'>1. Webkit browser&lt;br /&gt;
&lt;br /&gt;
@media screen and (-webkit-min-device-pixel-ratio:0) {&lt;br /&gt;
&lt;span style=&quot;color: lime;&quot;&gt;/* put your styles here */&lt;/span&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
2. IE8&lt;br /&gt;
&lt;br /&gt;
use the \0/ attribute&lt;br /&gt;
&lt;br /&gt;
.elementclass&lt;br /&gt;
{&lt;br /&gt;
width: 50px\0/; &lt;span style=&quot;color: lime;&quot;&gt;/* This will get only applied to IE8 */&lt;/span&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
3. IE7&lt;br /&gt;
&lt;br /&gt;
use the *&lt;br /&gt;
&lt;br /&gt;
.elementclass&lt;br /&gt;
{&lt;br /&gt;
*width: 50px; &lt;span style=&quot;color: lime;&quot;&gt;/* This will get only applied to IE7 */&lt;/span&gt;&lt;br /&gt;
}&lt;br /&gt;
&lt;br /&gt;
4. IE9&lt;br /&gt;
using the :root attribute&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
:root .elementclass&lt;br /&gt;
{&lt;br /&gt;
&lt;span style=&quot;color: cyan;&quot;&gt;/* this style will be applied to IE9 only */&lt;/span&gt;&lt;br /&gt;
&lt;span class=&quot;Apple-tab-span&quot; style=&quot;white-space: pre;&quot;&gt; &lt;/span&gt;padding-top: 5px;&lt;br /&gt;
}&lt;br /&gt;
&lt;div&gt;
&lt;br /&gt;&lt;/div&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/428992620198461083/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/10/browser-specific-css-hacks.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/428992620198461083'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/428992620198461083'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/10/browser-specific-css-hacks.html' title='Browser specific CSS Hacks'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-4882427906900567881</id><published>2013-09-29T02:24:00.001-07:00</published><updated>2013-09-29T02:24:53.536-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="backbone"/><category scheme="http://www.blogger.com/atom/ns#" term="ice candidate"/><category scheme="http://www.blogger.com/atom/ns#" term="icecandidate"/><category scheme="http://www.blogger.com/atom/ns#" term="peer"/><category scheme="http://www.blogger.com/atom/ns#" term="peer to peer"/><category scheme="http://www.blogger.com/atom/ns#" term="socket"/><category scheme="http://www.blogger.com/atom/ns#" term="stun"/><category scheme="http://www.blogger.com/atom/ns#" term="turn"/><category scheme="http://www.blogger.com/atom/ns#" term="webrtc"/><category scheme="http://www.blogger.com/atom/ns#" term="webrtc in backbone"/><category scheme="http://www.blogger.com/atom/ns#" term="websocket"/><title type='text'>Web RTC Project in Backbone</title><content type='html'>I have created a WebRTC project in backbone so that, the code will be easy to follow.&lt;br /&gt;
&lt;br /&gt;
&lt;a href=&quot;https://github.com/jintoppy/webrtc-backbone&quot;&gt;https://github.com/jintoppy/webrtc-backbone&lt;/a&gt;&lt;br /&gt;
&lt;br /&gt;
All web rtc related functions are given in the&amp;nbsp;webrtc-backbone / public / js / services / WebRTCService.js file.&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/4882427906900567881/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/09/web-rtc-project-in-backbone.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4882427906900567881'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4882427906900567881'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/09/web-rtc-project-in-backbone.html' title='Web RTC Project in Backbone'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-5738127712959080940</id><published>2013-09-18T07:20:00.001-07:00</published><updated>2013-09-18T07:20:41.526-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="advanced JS"/><category scheme="http://www.blogger.com/atom/ns#" term="duff device"/><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><category scheme="http://www.blogger.com/atom/ns#" term="loops"/><category scheme="http://www.blogger.com/atom/ns#" term="performance improvement"/><title type='text'>Duff’s Device pattern in JavaScript</title><content type='html'>Duff’s Device pattern in JavaScript&lt;br /&gt;
&lt;br /&gt;
Duff’s Device is a technique of unrolling loop bodies so that each iteration actually does&lt;br /&gt;
the job of many iterations. Jeff Greenberg is credited with the first published port of&lt;br /&gt;
Duff’s Device to JavaScript from its original implementation in C. A typical implementation&lt;br /&gt;
looks like this:&lt;br /&gt;
//credit: Jeff Greenberg&lt;br /&gt;
&lt;code&gt;
var iterations = Math.floor(items.length / 8),&lt;br /&gt;
startAt = items.length % 8,&lt;br /&gt;
i = 0;&lt;br /&gt;
do {&lt;br /&gt;
switch(startAt){&lt;br /&gt;
case 0: process(items[i++]);&lt;br /&gt;
case 7: process(items[i++]);&lt;br /&gt;
case 6: process(items[i++]);&lt;br /&gt;
case 5: process(items[i++]);&lt;br /&gt;
case 4: process(items[i++]);&lt;br /&gt;
case 3: process(items[i++]);&lt;br /&gt;
case 2: process(items[i++]);&lt;br /&gt;
case 1: process(items[i++]);&lt;br /&gt;
}&lt;br /&gt;
startAt = 0;&lt;br /&gt;
} while (iterations--);&lt;br /&gt;
&lt;/code&gt;

The basic idea behind this Duff’s Device implementation is that each trip through the&lt;br /&gt;
loop is allowed a maximum of eight calls to process(). The number of iterations&lt;br /&gt;
through the loop is determined by dividing the total number of items by eight. Because&lt;br /&gt;
not all numbers are evenly divisible by eight, the startAt variable holds the remainder&lt;br /&gt;
and indicates how many calls to process() will occur in the first trip through the loop.&lt;br /&gt;
If there were 12 items, then the first trip through the loop would call process() 4 times,&lt;br /&gt;
and then the second trip would call process() 8 times, for a total of two trips through&lt;br /&gt;
the loop instead of 12.&lt;br /&gt;
A slightly faster version of this algorithm removes the switch statement and separates&lt;br /&gt;
the remainder processing from the main processing:&lt;br /&gt;
//credit: Jeff Greenberg&lt;br /&gt;
&lt;code&gt;
var iterations = items.length % 8;&lt;br /&gt;
i = items.length -1;&lt;br /&gt;
while(iterations){&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
iterations--;&lt;br /&gt;
}&lt;br /&gt;
iterations = Math.floor(items.length / 8);&lt;br /&gt;
while(iterations){&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
process(items[i--]);&lt;br /&gt;
iterations--;&lt;br /&gt;
}
&lt;/code&gt;

&lt;br /&gt;
Even though this implementation is now two loops instead of one, it runs faster than&lt;br /&gt;
the original by removing the switch statement from the loop body.&lt;br /&gt;
&lt;br /&gt;
It can be useful for performance improvement if the number of iteration is more than 1000.&lt;br /&gt;
&lt;br /&gt;
courtesy: &lt;a href=&quot;http://shop.oreilly.com/product/9780596802806.do&quot;&gt;High Performance JavaScript&lt;/a&gt; by Nicholas Sakas</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/5738127712959080940/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/09/duffs-device-pattern-in-javascript.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/5738127712959080940'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/5738127712959080940'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/09/duffs-device-pattern-in-javascript.html' title='Duff’s Device pattern in JavaScript'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-961379496722691902</id><published>2013-09-11T22:31:00.001-07:00</published><updated>2013-09-11T22:31:14.716-07:00</updated><title type='text'>My WebRTC experiments</title><content type='html'>I am trying on WebRTC. I will update my progress here. Currently, I am stuck on the following issue.&lt;br /&gt;
&lt;br /&gt;
When &amp;nbsp;I am using RTCDataChannel.send method, I am getting the following error:&lt;br /&gt;
&lt;br /&gt;
&lt;span style=&quot;background-color: white; box-sizing: border-box; color: red; font-family: Consolas, &#39;Lucida Console&#39;, monospace; font-size: 12px; line-height: 12px; white-space: pre-wrap;&quot;&gt;Uncaught InvalidStateError: An attempt was made to use an object that is not, or is no longer, usable.&lt;/span&gt;&lt;span style=&quot;background-color: white; color: red; font-family: Consolas, &#39;Lucida Console&#39;, monospace; font-size: 12px; line-height: 12px; white-space: pre-wrap;&quot;&gt; &lt;/span&gt;&lt;br /&gt;
&lt;span style=&quot;background-color: white; color: red; font-family: Consolas, &#39;Lucida Console&#39;, monospace; font-size: 12px; line-height: 12px; white-space: pre-wrap;&quot;&gt;&lt;br /&gt;&lt;/span&gt;
I am checking if this is because of the createOffer issue.&lt;br /&gt;
&lt;br /&gt;
Those who are not familiar with webRTC, you can get idea from&amp;nbsp;&lt;a href=&quot;http://www.webrtc.org/&quot;&gt;webrtc.org&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/961379496722691902/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/09/my-webrtc-experiments.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/961379496722691902'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/961379496722691902'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/09/my-webrtc-experiments.html' title='My WebRTC experiments'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-2886234780017544096</id><published>2013-05-12T02:37:00.001-07:00</published><updated>2013-05-12T02:37:53.299-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>The superpowers of constructors</title><content type='html'>&lt;br /&gt;
&lt;h5 class=&quot;epub__notetitle&quot; id=&quot;ch03lev3sec6&quot; style=&quot;background-color: white; font-family: verdana, sans-serif; font-size: 0.75em; margin: 2px 0px 0px;&quot;&gt;
&lt;span style=&quot;font-size: 15px;&quot;&gt;Invoking a function as a constructor is a powerful feature of JavaScript, because when a constructor is invoked, the following special actions take place:&lt;/span&gt;&lt;/h5&gt;
&lt;div class=&quot;epub__calibre18&quot; style=&quot;background-color: white; font-family: verdana, sans-serif; font-size: 15px; margin-bottom: 1em; margin-top: 1em; padding: 0px;&quot;&gt;
&lt;/div&gt;
&lt;ul class=&quot;epub__calibre19&quot; style=&quot;background-color: white; font-family: verdana, sans-serif; font-size: 15px; margin-bottom: 1em; margin-right: 0px; margin-top: 1em;&quot;&gt;
&lt;li class=&quot;epub__calibre20&quot;&gt;&lt;a class=&quot;epub__calibre21&quot; href=&quot;&quot; id=&quot;iddle2057&quot; style=&quot;color: inherit; cursor: inherit; font-family: Times; text-decoration: inherit;&quot;&gt;&lt;/a&gt;&lt;a class=&quot;epub__calibre21&quot; href=&quot;&quot; id=&quot;iddle2162&quot; style=&quot;color: inherit; cursor: inherit; font-family: Times; text-decoration: inherit;&quot;&gt;&lt;/a&gt;A new empty object is created.&lt;/li&gt;
&lt;li class=&quot;epub__calibre20&quot;&gt;This object is passed to the constructor as the&amp;nbsp;&lt;kbd class=&quot;epub__calibre15&quot; style=&quot;font-family: &#39;Liberation Mono&#39;, monospace;&quot;&gt;this&lt;/kbd&gt;&amp;nbsp;parameter, and thus becomes the constructor’s function context.&lt;/li&gt;
&lt;li class=&quot;epub__calibre20&quot;&gt;In the absence of any explicit return value, the new object is returned as the constructor’s value.&lt;/li&gt;
&lt;/ul&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/2886234780017544096/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/05/the-superpowers-of-constructors.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/2886234780017544096'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/2886234780017544096'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/05/the-superpowers-of-constructors.html' title='The superpowers of constructors'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-3644714259317408556</id><published>2013-05-12T02:16:00.000-07:00</published><updated>2013-05-12T02:16:32.371-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="javascript"/><title type='text'>Scoping and functions</title><content type='html'>&lt;br /&gt;
In JavaScript, scopes are declared by functions, and not by blocks. The scope of a declaration that’s created inside a block isn’t terminated (as it is in other languages) by the end of the block.&lt;br /&gt;
&lt;br /&gt;
Consider the following code:&lt;br /&gt;
&lt;br /&gt;
&lt;code&gt;&lt;/code&gt;&lt;br /&gt;
if (window) {&lt;br /&gt;
&amp;nbsp; var x = 213;&lt;br /&gt;
}&lt;br /&gt;
alert(x);&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
In most other languages, one would expect the scope of the declaration for x to terminate at the end of the block created by the if statement, and for the alert to fail with an undefined value. But if we were to run the preceding code in a page, the value 213 would be alerted because JavaScript doesn’t terminate scopes at the end of blocks.&lt;br /&gt;
&lt;br /&gt;
That seems simple enough, but there are a few nuances to the scoping rules that depend upon what is being declared. Some of these nuances may come as a bit of a surprise:&lt;br /&gt;
&lt;br /&gt;
&lt;br /&gt;
&lt;ul&gt;
&lt;li&gt;Variable declarations are in scope from their point of declaration to the end of the function within which they’re declared, regardless of block nesting.&lt;/li&gt;
&lt;li&gt;Named functions are in scope within the entire function within which they’re declared, regardless of block nesting. (Some call this mechanism hoisting.)&lt;/li&gt;
&lt;li&gt;For the purposes of declaration scopes, the global context acts like one big function encompassing the code on the page.&lt;/li&gt;
&lt;/ul&gt;
&lt;br /&gt;
</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/3644714259317408556/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2013/05/scoping-and-functions.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/3644714259317408556'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/3644714259317408556'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2013/05/scoping-and-functions.html' title='Scoping and functions'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-250448185076812642</id><published>2011-08-11T23:12:00.001-07:00</published><updated>2011-08-11T23:13:07.051-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="sql"/><title type='text'>SQL Cascading  Query</title><content type='html'>with MessageList&lt;br /&gt;as&lt;br /&gt;(&lt;br /&gt;select MessageID_,ParentID_ from Messages_ where ParentID_=&#39;3529&#39;&lt;br /&gt;union all&lt;br /&gt;select m.MessageID_,m.ParentID_ from Messages_ m inner join MessageList ml on m.ParentID_= ml.MessageID_&lt;br /&gt;)&lt;br /&gt;SELECT distinct(MessageID_) FROM MessageList group by MessageID_</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/250448185076812642/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2011/08/sql-cascading-query.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/250448185076812642'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/250448185076812642'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2011/08/sql-cascading-query.html' title='SQL Cascading  Query'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-7624551283478964105</id><published>2011-06-28T22:54:00.000-07:00</published><updated>2011-06-28T22:55:10.048-07:00</updated><title type='text'>Testing mail locally</title><content type='html'>1. Create a temp folder. &lt;br /&gt;&lt;br /&gt;http://blog.divergencehosting.com/2010/01/27/testing-email-from-localhost-with-aspnet-without-smtp-server/&lt;br /&gt;&lt;br /&gt;2. The mails sent will be available at that temp folder.</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/7624551283478964105/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2011/06/testing-mail-locally.html#comment-form' title='1 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/7624551283478964105'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/7624551283478964105'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2011/06/testing-mail-locally.html' title='Testing mail locally'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>1</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-1863924913095323132</id><published>2011-04-16T23:13:00.000-07:00</published><updated>2011-04-16T23:35:44.891-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ajax"/><category scheme="http://www.blogger.com/atom/ns#" term="jquery"/><category scheme="http://www.blogger.com/atom/ns#" term="updatepanel"/><title type='text'>JavaScript in UpdatePanel</title><content type='html'>Javascript events don&#39;t work after the UpdatePanel does a partial page update.&lt;br /&gt;&lt;br /&gt;An UpdatePanel completely replaces the contents of the update panel on an update. This means that those events you subscribed to are no longer subscribed because there are new elements in that update panel.&lt;br /&gt;&lt;br /&gt;Soln1: Re-subscribe to the events I need after every update. I use $(document).ready() for the initial load, then this snippet below to re-subscribe every update.&lt;br /&gt;&lt;br /&gt;var prm = Sys.WebForms.PageRequestManager.getInstance();&lt;br /&gt;&lt;br /&gt;prm.add_endRequest(function() {&lt;br /&gt;  // re-bind your jquery events here&lt;br /&gt;});&lt;br /&gt;&lt;br /&gt;The &lt;span style=&quot;font-weight: bold;&quot;&gt;PageRequestManager&lt;/span&gt; is a javascript object which is automatically available if an update panel is on the page. You shouldn&#39;t need to do anything other than the code above in order to use it as long as the UpdatePanel is on the page.&lt;br /&gt;&lt;br /&gt;Soln2: Use jQuery&#39;s &lt;a href=&quot;http://docs.jquery.com/Events/live&quot; rel=&quot;nofollow&quot;&gt;&lt;code&gt;live()&lt;/code&gt;&lt;/a&gt; event subscriber&lt;br /&gt;$(document).ready(function () {&lt;br /&gt;              $(&quot;#Button2&quot;).live(&quot;click&quot;, function () {&lt;br /&gt;                  alert(&quot;test&quot;);&lt;br /&gt;              });&lt;br /&gt;&lt;br /&gt;          });&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;Soln3:  &lt;br /&gt;&lt;br /&gt;&lt;contenttemplate&gt;&lt;br /&gt;&lt;script type=&quot;text/javascript&quot;&gt; &lt;br/&gt;    Sys.Application.add_load(bind);&lt;br/&gt;&lt;/script&gt;&lt;/contenttemplate&gt;&lt;a href=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdkYYf7cU4ubOE6B8x7AEZPn2lgdpHu-j682SCI2JaPvqz1qsb0CfOQ9l_OlvI-9wp8QHq2AkdetLYr8Z-Z_f9bx1NNDitKBvtCLa5flMum34b-9Q4BgNgCDA679z4QVHN53BbaEJt0oE/s1600/code.png&quot;&gt;&lt;img style=&quot;display: block; margin: 0px auto 10px; text-align: center; cursor: pointer; width: 240px; height: 83px;&quot; src=&quot;https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdkYYf7cU4ubOE6B8x7AEZPn2lgdpHu-j682SCI2JaPvqz1qsb0CfOQ9l_OlvI-9wp8QHq2AkdetLYr8Z-Z_f9bx1NNDitKBvtCLa5flMum34b-9Q4BgNgCDA679z4QVHN53BbaEJt0oE/s320/code.png&quot; alt=&quot;&quot; id=&quot;BLOGGER_PHOTO_ID_5596436795283335746&quot; border=&quot;0&quot; /&gt;&lt;/a&gt;where bind is the jquery function&lt;br /&gt;&lt;contenttemplate&gt;&lt;br /&gt;Where bind is the jquery function&lt;/contenttemplate&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/1863924913095323132/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2011/04/javascript-in-updatepanel.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1863924913095323132'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1863924913095323132'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2011/04/javascript-in-updatepanel.html' title='JavaScript in UpdatePanel'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><media:thumbnail xmlns:media="http://search.yahoo.com/mrss/" url="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgdkYYf7cU4ubOE6B8x7AEZPn2lgdpHu-j682SCI2JaPvqz1qsb0CfOQ9l_OlvI-9wp8QHq2AkdetLYr8Z-Z_f9bx1NNDitKBvtCLa5flMum34b-9Q4BgNgCDA679z4QVHN53BbaEJt0oE/s72-c/code.png" height="72" width="72"/><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-1011097499526413229</id><published>2010-07-15T23:53:00.000-07:00</published><updated>2010-07-16T02:26:54.355-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="http error 500"/><category scheme="http://www.blogger.com/atom/ns#" term="internal server error"/><category scheme="http://www.blogger.com/atom/ns#" term="rewritemodule"/><title type='text'>Cannot add duplicate collection entry of type &#39;add&#39; with unique key attribute &#39;name&#39; set to &#39;RewriteModule&#39;  - HTTP Error 500.19 - Internal Server Err</title><content type='html'>When I uploaded the site to the server, I got an HTTP Error 500.19 - Internal Server Error which says &quot;Cannot add duplicate collection entry of type &#39;add&#39; with  unique key attribute &#39;name&#39; set to &#39;RewriteModule&#39;&quot;. Error was in the following line in web.config&lt;br /&gt;&lt;pre&gt;&lt;code&gt;&lt;span class=&quot;highlight-code&quot;&gt;&lt;add name=&quot;RewriteModule&quot; type=&quot;RewriteModule.RewriteModule, RewriteModule&quot;&gt;&lt;br /&gt;&lt;br /&gt;I got the solution to change the application config file from the following link:&lt;br /&gt;http://support.microsoft.com/kb/942055&lt;br /&gt;&lt;br /&gt;But, hosting providers won&#39;t allow that on server.&lt;br /&gt;&lt;br /&gt;I added the following under &lt;modules&gt; where the RewriteModule is added&lt;br /&gt;&lt;remove name=&quot;RewriteModule&quot;&gt;&lt;br /&gt;Also, there were some virtual directory issues. Hosting provider&lt;br /&gt;changed that. Now it is working.&lt;br /&gt;&lt;/remove&gt;&lt;/modules&gt;&lt;/add&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/1011097499526413229/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/cannot-add-duplicate-collection-entry.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1011097499526413229'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1011097499526413229'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/cannot-add-duplicate-collection-entry.html' title='Cannot add duplicate collection entry of type &#39;add&#39; with unique key attribute &#39;name&#39; set to &#39;RewriteModule&#39;  - HTTP Error 500.19 - Internal Server Err'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-8694158898496058584</id><published>2010-07-09T04:14:00.000-07:00</published><updated>2010-07-09T04:25:34.286-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="ajax"/><category scheme="http://www.blogger.com/atom/ns#" term="AsyncFileUpload"/><category scheme="http://www.blogger.com/atom/ns#" term="multiview"/><title type='text'>Issue when using AsyncFileUpload control</title><content type='html'>I tried to use AsyncFileUpload control in a page. The AsyncFileUpload control was placed inside the first view of a multiview control. The page required a querystring parameter, and if the parameter is not present, the second view of the multiviewcontrol will be shown. This check is made on the Page Load event. This causes issue on the fileupload process. It was giving error, since on the postback, it gets another view. So, I did like this. &lt;span class=&quot;code-attribute&quot;&gt;&lt;span style=&quot;font-family:monospace;&quot;&gt;&lt;br /&gt;&lt;/span&gt;&lt;br /&gt;on the event &quot;OnClientUploadStarted&lt;/span&gt;&quot;, I gave a value to a hidden element, and on page load, a checking is made, to see, if the value is given for the hidden element. If the value is given, the view1 itself will be shown without checking the availability of querystring parameter.&lt;br /&gt;&lt;br /&gt;Don&#39;t know if that is the correct method. Anyhow, it worked.</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/8694158898496058584/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/issue-when-using-asyncfileupload.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/8694158898496058584'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/8694158898496058584'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/issue-when-using-asyncfileupload.html' title='Issue when using AsyncFileUpload control'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-3734392899735749791</id><published>2010-07-07T21:40:00.000-07:00</published><updated>2010-07-07T21:45:37.050-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="argentina"/><category scheme="http://www.blogger.com/atom/ns#" term="excel reading"/><category scheme="http://www.blogger.com/atom/ns#" term="germany"/><category scheme="http://www.blogger.com/atom/ns#" term="worldcup"/><category scheme="http://www.blogger.com/atom/ns#" term="worldcup 2010"/><title type='text'>Germans also are gone :-(</title><content type='html'>My two favorite teams are out from WorldCup 2010, Germany and Argentina. :-( Spain really deserve that victory over Germany.&lt;br /&gt;&lt;br /&gt;I know, it is bit late. But, I just came to a contribution from Microsoft for World Cup. So, I thought, I should share with you.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://blogs.msdn.com/b/excel/archive/2010/05/24/track-the-soccer-world-cup-scores-with-excel-174.aspx&quot;&gt;Track&lt;/a&gt; world cup scores with excel.</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/3734392899735749791/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/germans-also-are-gone.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/3734392899735749791'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/3734392899735749791'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/germans-also-are-gone.html' title='Germans also are gone :-('/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-5610848785147394984</id><published>2010-07-06T23:39:00.000-07:00</published><updated>2010-07-07T00:36:30.525-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="sql"/><title type='text'>Generate sql script with data from database</title><content type='html'>How can we copy data as well the structure and schema as sql query? We need database publishing wizard for that.&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://www.codeplex.com/sqlhost/Wiki/View.aspx?title=Database%20Publishing%20Wizard&quot;&gt;Download&lt;/a&gt; the database publishing wizard.&lt;br /&gt;It will be installed at following location :  C:\Program Files\Microsoft  SQL Server\90\Tools\Publishing\&lt;br /&gt;&lt;br /&gt;run the exe and you can get the sql file with all the data, schema and structure of the database you select.</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/5610848785147394984/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/generate-sql-script-with-data-from.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/5610848785147394984'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/5610848785147394984'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/generate-sql-script-with-data-from.html' title='Generate sql script with data from database'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-8286877289613950446</id><published>2010-07-01T20:02:00.000-07:00</published><updated>2010-07-01T20:04:09.734-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="asp.net"/><category scheme="http://www.blogger.com/atom/ns#" term="error"/><category scheme="http://www.blogger.com/atom/ns#" term="viewstate"/><category scheme="http://www.blogger.com/atom/ns#" term="viewstatemac"/><title type='text'>Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that  configuration specifies the same</title><content type='html'>When this error comes, put enableViewStateMac=&quot;false&quot; in the &lt;pages&gt; tag either in the web.config or in the page where you get this error.</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/8286877289613950446/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/validation-of-viewstate-mac-failed-if.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/8286877289613950446'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/8286877289613950446'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/07/validation-of-viewstate-mac-failed-if.html' title='Validation of viewstate MAC failed. If this application is hosted by a Web Farm or cluster, ensure that &lt;machineKey&gt; configuration specifies the same'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-4674668598404486564</id><published>2010-05-19T22:52:00.000-07:00</published><updated>2010-05-19T22:59:18.436-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="asp.net"/><category scheme="http://www.blogger.com/atom/ns#" term="email"/><title type='text'>System.Net.Mail.SmtpFailedRecipientException: Mailbox unavailable. The server response was: 5.7.1 Unable to relay</title><content type='html'>I have got this issue many times, when I try to send email using smtp. There can be several causes for this. You have to allow relay for mail to be sent to outside servers like gmail.com. For sending mail within your server you don&#39;t have to do this. You can find some helps from the following links:&lt;br /&gt;&lt;a href=&quot;http://blogs.techrepublic.com.com/networking/?p=373&quot;&gt;&lt;span style=&quot;text-decoration: underline;&quot;&gt;Help1&lt;/span&gt;&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;http://technet.microsoft.com/en-us/library/bb232021%28EXCHG.80%29.aspx&quot;&gt;Help2&lt;/a&gt;&lt;br /&gt;&lt;a href=&quot;https://exchangepedia.com/blog/2007/01/exchange-server-2007-how-to-allow.html&quot;&gt;Help3&lt;/a&gt;&lt;br /&gt;&lt;br /&gt;The code I have used is given below:&lt;br /&gt;&lt;br /&gt;using System.Net.Mail;&lt;br /&gt;&lt;br /&gt;&lt;br /&gt;        SmtpClient smtpClient = new SmtpClient();&lt;br /&gt;        MailMessage message = new MailMessage();&lt;br /&gt;        smtpClient.Port = 25;&lt;br /&gt;        smtpClient.Host = &quot;smtp.domain.com&quot;;&lt;br /&gt;        smtpClient.UseDefaultCredentials = false;&lt;br /&gt;        smtpClient.Credentials = new System.Net.NetworkCredential(&quot;webmail username&quot;, &quot;webmail password&quot;);&lt;br /&gt;        message.From = new MailAddress(&quot;webmail username&quot;);&lt;br /&gt;        message.To.Add(&quot;test@gmail.com&quot;);&lt;br /&gt;        string emailBody = &quot;Hi,&lt;br/&gt;&lt;p&gt;Welcome&lt;/p&gt;&quot;;&lt;br /&gt;        message.Body = emailBody;&lt;br /&gt;        message.Subject = &quot;testing&quot;;&lt;br /&gt;        message.IsBodyHtml = true;&lt;br /&gt;        smtpClient.Send(message);&lt;br /&gt;&lt;br /&gt;But, after making the changes on the server, as specified on the above links, I was still getting the same error.  Then I added the following line in between the above code.&lt;br /&gt;    smtpClient.DeliveryMethod =  SmtpDeliveryMethod.PickupDirectoryFromIis;&lt;br /&gt;&lt;br /&gt;Then the error was gone.</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/4674668598404486564/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/05/systemnetmailsmtpfailedrecipientexcepti.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4674668598404486564'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4674668598404486564'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/05/systemnetmailsmtpfailedrecipientexcepti.html' title='System.Net.Mail.SmtpFailedRecipientException: Mailbox unavailable. The server response was: 5.7.1 Unable to relay'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-298650052482086811</id><published>2010-04-23T01:20:00.000-07:00</published><updated>2010-04-23T01:27:00.817-07:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="asp.net"/><category scheme="http://www.blogger.com/atom/ns#" term="iis"/><category scheme="http://www.blogger.com/atom/ns#" term="inetmgr"/><category scheme="http://www.blogger.com/atom/ns#" term="windows7"/><title type='text'>Login failed for user ‘IIS APPPOOL\DefaultAppPool’</title><content type='html'>I got this issue in my system using Windows 7 Ultimate when trying to run a site which is configured to run in IIS. You can get the solution for this from the following link&lt;br /&gt;&lt;br /&gt;&lt;a href=&quot;http://translate.google.com/translate?js=n&amp;amp;prev=_t&amp;amp;hl=en&amp;amp;ie=UTF-8&amp;amp;layout=1&amp;amp;eotf=1&amp;amp;u=http%3A%2F%2Fwww.codetoday.net%2Fdefault.aspx%3Fg%3Dposts%26t%3D1595&amp;amp;sl=auto&amp;amp;tl=en&quot;&gt;Read More&lt;/a&gt;</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/298650052482086811/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/04/login-failed-for-user-iis.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/298650052482086811'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/298650052482086811'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/04/login-failed-for-user-iis.html' title='Login failed for user ‘IIS APPPOOL\DefaultAppPool’'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-1633942771770830159</id><published>2010-03-31T19:31:00.000-07:00</published><updated>2010-03-31T19:33:56.418-07:00</updated><title type='text'>Grouping Gridview</title><content type='html'>Some times we want to group gridview. ZNet is a good control for this use.&lt;br /&gt;&lt;a href=&quot;http://znetcontrols.blogspot.com/2008/08/extended-gridview-for-aspnet-20-with.html&quot;&gt;ZNet&lt;/a&gt;&lt;br /&gt;We can use this for grouping and also for the comparison.</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/1633942771770830159/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/03/grouping-gridview.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1633942771770830159'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/1633942771770830159'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/03/grouping-gridview.html' title='Grouping Gridview'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry><entry><id>tag:blogger.com,1999:blog-9032911300417711039.post-4567428108555988362</id><published>2010-03-13T01:41:00.000-08:00</published><updated>2010-03-13T01:44:46.648-08:00</updated><category scheme="http://www.blogger.com/atom/ns#" term="asp.net"/><category scheme="http://www.blogger.com/atom/ns#" term="validation"/><title type='text'>specifying ValidationGroup in Page_ClientValidate function</title><content type='html'>Hi,&lt;br /&gt;&lt;br /&gt;We know that, Page_ClientValidate function tests if all controls meet asp.net validation criteria. This function is provided by asp.net. But, if we use more than, one validation group in the page, we may have to specify the validation group, we want to validate. For that, give like given below:&lt;br /&gt;Page_ClientValidate(&#39;ValGroupName&#39;)&lt;br /&gt;&lt;br /&gt;Then, it will validate only for that validation group</content><link rel='replies' type='application/atom+xml' href='http://programmerbuddy.blogspot.com/feeds/4567428108555988362/comments/default' title='Post Comments'/><link rel='replies' type='text/html' href='http://programmerbuddy.blogspot.com/2010/03/specifying-validationgroup-in.html#comment-form' title='0 Comments'/><link rel='edit' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4567428108555988362'/><link rel='self' type='application/atom+xml' href='http://www.blogger.com/feeds/9032911300417711039/posts/default/4567428108555988362'/><link rel='alternate' type='text/html' href='http://programmerbuddy.blogspot.com/2010/03/specifying-validationgroup-in.html' title='specifying ValidationGroup in Page_ClientValidate function'/><author><name>Anonymous</name><uri>http://www.blogger.com/profile/03626633586648521465</uri><email>noreply@blogger.com</email><gd:image rel='http://schemas.google.com/g/2005#thumbnail' width='16' height='16' src='https://img1.blogblog.com/img/b16-rounded.gif'/></author><thr:total>0</thr:total></entry></feed>