tag:blogger.com,1999:blog-10422515855561970792024-03-05T12:54:30.548+05:30A Space for Software and Automation EnthusiastsVarun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.comBlogger35125tag:blogger.com,1999:blog-1042251585556197079.post-82377774633871780752015-02-13T12:08:00.000+05:302015-02-13T18:53:13.546+05:30The Undocumented documentation of Page Object Pattern<div dir="ltr" style="text-align: left;" trbidi="on">
If you are into automation testing using selenium, you may be knowing about the Page Object Pattern suggested by selenium forum available at url :<br />
<a href="https://code.google.com/p/selenium/wiki/PageObjects" target="_blank">https://code.google.com/p/selenium/wiki/PageObjects</a><br />
<br />
The documentation suggests the approach for implementing Page Object Pattern for automation and what are the advantages of it. In here I wont be writing about what the documentation suggests and talks about it. So lets directly jump onto the main subject and learn about what the documentation does not contain. Following are those points:<br />
<ul style="text-align: left;">
<li>Implementing a Page Object Pattern for a single page application</li>
<li>Approach towards defining methods for functionality</li>
</ul>
<br />
<h3 style="text-align: left;">
Implementing Page Object Pattern for a single page application</h3>
<br />
With new web application development technologies coming into play on a daily basis web applications has reduced to very few pages and even sometimes to one page url. This becomes a challenge while implementing Page Object Pattern. The question arises is, how to segregate the pages as there are only few pages in the application but there are lot of functionalities to cover in them. If we go ahead with the conventional segregation methodologies we will have very few page classes but with lot of functional methods defined in them. We will fall into the same problem of code management that we were trying to solve using Page Object Pattern.<br />
<br />
The solution to this is to enhance the Page Object Pattern guidelines. This includes segregating your page classes based on features, sub-features, functionality etc. and not by page urls. To explain this we have a perfect example of Gmail. Gmail is a single page but there are lot of functionalities available in the said page like navigation, hangouts, inbox, Search, compose and mail folders.<br />
If we go with the conventional method we will be forced to define all the functionalities of compose, hangouts contacts chat, inbox etc in a single class. With the enhanced model we will define separate classes for each of the feature ex. ComposePage, HangoutPage, InboxPage, NavigationPage etc. By using the enhanced model we can fully utilize the advantages of using the Page Object Pattern.<br />
<br />
<h3 style="text-align: left;">
Defining methods for Page functionality</h3>
<br />
The guideline suggests users to define functionalities as method inside page classes and it ends there. It does not talk much about the segregation, approach or anything of such sort. Anyways lets cover it here. When planning to define methods for the functionality try to follow following added guidelines:<br />
<ul style="text-align: left;">
<li>Segregate your functionality into smaller functionally executed methods. Lets take an example of login use case where user enters username, password and click on submit button. While writing a functional method for login you should think of having methods like enter username, enter password and clicking on submit button. This way you will have more control on the code and you can provide more utilities to user who is writing automation tests.</li>
<li>Think of functional as well as structural method declarations. Taking the above example. login method that accepts username and password arguments is a functional method whereas enter username, enter password and click on submit button methods are structural methods. As said in the first point structural methods makes code more readable and represents a flow of user actions. It also provide more power into the hands of end user who is using them for writing automation tests.</li>
<li>Think of positive and negative scenarios of a functionality while defining methods. I will again take the example of the login functionality. A login can be successful or it can be failure. try to support both kind of scenarios in a single method. This can be achieved in two ways:</li>
<ul>
<li>Allow a Boolean value to be passed as argument to the method that will decide whether the scenario for which the method is being used in positive or negative.</li>
<li>Another way is you written a Boolean or some other object as return type representing whether the method execution was success or a failure.</li>
</ul>
This way you are covering more ground in the functional methods and giving more power to the user writing automation tests to write different types of tests scenarios with the same given method.</ul>
<br />
The above suggestion helps in making tests more readable, manageable and in providing more functionality to the user who is automating. The initial time taken to write page class and page methods will be more but there will be very less time spent on writing automation test cases for the said functionality as the methods list will contain methods that supports all kind of related functionality from low level to high level as well as both positive and negative scenarios.<br />
<br />
This is a cross post from my company blog <a href="http://blog.imaginea.com/the-undocumented-documentation-of-page-object-pattern/" target="_blank">here</a>, where I had originally written it.<br />
<br /></div>
Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com1tag:blogger.com,1999:blog-1042251585556197079.post-23145851642179704072015-02-09T16:20:00.000+05:302015-02-09T17:00:31.625+05:30Selenium Exceptions why it occurs and how to resolve/avoid them<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
While using selenium for web automation many a time we face numerous kind of exceptions. Many of these exceptions are mainly selenium exceptions. In this blog I will write about few of those selenium exceptions, why they occur and how to resolve/avoid them.<br />
<br />
<ul style="text-align: left;">
<li><b><span style="font-family: inherit;">StaleElementReferenceException - </span></b><br />As the name suggests this exception occurs when the element stale, which means the element reference on which you are trying to take a action upon is no longer available on the page or has changed. <br />To avoid this exception, try to find the element as and when you need to take an action upon it rather than getting the element at some point of code and then reusing it at different places.</li>
<br />
<li><b>InvalidCoordinatesException - </b><br />This exception occurs when invalid co-ordinates are provided for an interaction operation like move, click, drag & drop etc.<br /> You can avoid this exception by identifying a Webelement on the page for interaction rather than providing a co-ordinates.</li>
<br />
<li><b>ElementNotVisibleException - </b><br />This exception occurs when an element may be available in the dom but not displayed on the page and hence not able to be interacted. This exception may also occurs if the element is unable to scroll onto the browser view. <br />You can avoid this exception by verifying that the element is visible and then taking action on the element. There are some methods present in "<i>ExpectedConditions</i>" class that can be used to wait for the element to be visible. These methods are "<i>visibilityOf(Webelement)</i>" and "<i>visibilityOfElementLocated(By)</i>".</li>
<br />
<li><b>InvalidSelectorException -</b><br />
This exception is thrown when the selector used to find the element is invalid or wrong, this may be a syntax error or a compound class name to be provided to "By.className" method.<br />
To avoid this exception verify that the selector that you are using are verified on the said page using jQuery or firebug or firepath.</li>
<br />
<li><b>NoSuchElementException -</b><br />
This is a common exception faced by selenium users and occurs when there is no element found on the current page by selenium based on the user provided selector to method "findElement". There can be multiple reasons for this exception to occur like selector being wrong, element taking time load(in case of ajax), earlier step execution failed etc.<br />
You can avoid this exception by implementation by waiting for element to be present using "<i>FluentWait</i>" with "<i>ExpectedConditions</i>" class methods "<i>presenceOfElementLocated(By)</i>" and "<i>visibilityOfElementLocated(By)</i>".</li>
<br />
<li><b>UnreachableBrowserException - </b><br />This exception mainly occurs due to two reasons first when the browser to which the selenium commands has died mid-test and second when the remote server address to which the RemoteWebDriver trying to contact is invalid. <br />There is no proper solution to this error you can only take precautionary measures in this cases and is more or less related to hardware.</li>
</ul>
</div>
</div>
Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com1tag:blogger.com,1999:blog-1042251585556197079.post-3616692647741170572015-01-27T10:44:00.001+05:302015-02-06T13:35:52.918+05:30Developing a Web Automation framework using GEB and Groovy<div dir="ltr" style="text-align: left;" trbidi="on">
<div class="MsoNormal">
<div class="MsoNormal">
I had extensively worked on Java and developed different types of frameworks depending upon the project requirements. I understand the pain points of developing the framework using Selenium and Java. I also understand it takes a lot of time to develop the framework to start supporting the automation for a particular application. So when I was given a responsibility of automating an application framework using Groovy I came across "GEB" which is a Web automation framework using groovy. It is a wrapper over selenium and provides a lot of in-built utilities that will allow the end user to jump into the job of automating their test-cases and validating their application within a short period.<br />
Geb provides a enhanced Page Object modelling to its users with the advantage of re-usability and maintainability of tests and framework. Page Object modelling/pattern as you may be knowing divides the areas on the UI under test as classes in the code. All the functionality related to the said area is put onto a class, hence reducing the probability of code duplicity.</div>
<div class="MsoNormal">
<o:p></o:p></div>
<div class="MsoNormal">
<br />
Following are few of the advantages of using Geb:<br />
- Uses webdriver as an internal web automation framework which is well tested and used worldwide<br />
<span style="font-size: xx-small;">- </span>Uses css as the locating strategy which makes it faster and easy to use.<br />
- Jquery like methods and usage<br />
- Extensive list of in-built utilities that reduces code and time.<br />
- In-built driver manager<br />
- Support for parallel execution.<br />
<br />
Its a complete automation framework package that reduces the automation framework development time by almost 2-3 months.<br />
More details on Geb can be found at <a href="http://www.gebish.org/" target="_blank">http://www.gebish.org/</a></div>
</div>
<div class="MsoListParagraphCxSpLast" style="mso-list: l0 level1 lfo1; text-indent: -18.0pt;">
<o:p></o:p></div>
</div>
Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com2tag:blogger.com,1999:blog-1042251585556197079.post-32359326251462282172013-10-02T13:25:00.002+05:302015-02-10T16:39:19.824+05:30Generate ReportNG report using Maven<div dir="ltr" style="text-align: left;" trbidi="on">
Earlier I had covered in my blog about generating TestNg-xslt report for your TestNG test execution using Maven. Following is the link to it:<br />
<div>
<br /></div>
<div>
<a href="http://blog.varunin.com/2012/05/generate-testng-xslt-report-using-maven.html">http://blog.varunin.com/2012/05/generate-testng-xslt-report-using-maven.html</a></div>
<div>
<br /></div>
<div>
In this blog I will write about how to generate a ReportNG report for your TestNG test execution using maven. Following is a pom.xml file that can be used to execute your tests in a maven project and also generate a ReportNG report after execution.</div>
<br />
<script src="https://gist.github.com/menonvarun/88a76d17fce0aba099a8.js"></script>
<div>
<br />
<br />
Run the following command to run your test cases and generate the ReportNG report.<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>mvn clean test
</code></pre>
<br />
Or just <br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>mvn test
</code></pre>
<br />
Once run by default the execution report can be found under the folder named "html" under the surefire report directory inside "target" folder of your project folder.
</div>
</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com24tag:blogger.com,1999:blog-1042251585556197079.post-86390951848752040622013-09-04T20:43:00.000+05:302015-02-10T16:43:59.890+05:30Page Object Pattern - What and Why?<div dir="ltr" style="text-align: left;" trbidi="on">
Today I will be writing about Page Objet pattern which became famous when details about it was mentioned in the selenium wiki.<br />
<br />
Page Object pattern solves one of the biggest problem that any automation framework face i.e Managing utils, managing methods, reducing code duplicity etc. It solves this by suggesting certain methodology for managing and modelling the code.<br />
<br />
Some of the main points that it suggests are:<br />
1.<span class="Apple-tab-span" style="white-space: pre;"> </span>Model your application UI pages as classes in your framework. (There is no hard-and-fast rule that the whole page on the UI should be represented by one class, you can also create classes for the sections of the page if they are used in other UI pages or sections.)<br />
2.<span class="Apple-tab-span" style="white-space: pre;"> </span>Each class will contain methods that perform the actual functionality provided on the page or section that the said class represents.<br />
3.<span class="Apple-tab-span" style="white-space: pre;"> </span>Each method in the Page class should return the object of the same page class or another page class if the said method/functionality navigate the UI to a new page.<br />
4.<span class="Apple-tab-span" style="white-space: pre;"> </span>Method names inside the page class should represent the actual functionality that it performs.<br />
<br />
Let’s take this by an example:<br />
We’ll take the same example as mentioned in the Selenium wiki, you have a login page where user enters username and password. If the login is successful user will get navigated to the home page else an error will be thrown on the UI.<br />
<br />
Now converting this use case to a Page Object pattern we’ll have two classes LoginPage and HomePage defined. LoginPage will contains functions related to entering username, entering password, login using a given username and password, clicking on submit button etc. HomePage will contain functionality related to the HomePage, in this case we will have the functionality to verify the HomePage. Below is a class representation of the Pages and their respective functionality defined as methods. There is also a sample test-class with name "SampleTest" which contains two test methods that makes the use of the Page Object Pattern defined using "LoginPage" and "HomePage" class<br />
<br />
<br />
<script src="https://gist.github.com/menonvarun/194956113f062d2ae7cf.js"></script>
As you can see from the above test-method in the above “SampleTest” class, there two different test-methods. Both the test-methods have the same flow defined in them , the only difference is the way they had been written. Also you can notice that the test are more readable when implemented by following the Page Object model. Without a Page Object Pattern the tests may have been more cluttered and non-readable.<br />
<br />
Advantages of using Page Object pattern:<br />
-<span class="Apple-tab-span" style="white-space: pre;"> </span>Better code management<br />
-<span class="Apple-tab-span" style="white-space: pre;"> </span>Reduced code duplicity<br />
-<span class="Apple-tab-span" style="white-space: pre;"> </span>In case of change in functionality very minimal changes required to be done. Change the respective page method and it will automatically take effect in all test-methods.<br />
-<span class="Apple-tab-span" style="white-space: pre;"> </span>Testcases are more readable.<br />
<div>
<br /></div>
</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com3tag:blogger.com,1999:blog-1042251585556197079.post-69441649234570839692012-08-15T17:02:00.000+05:302012-08-31T10:48:09.913+05:30CSS Locator / CSS Selector Tutorial<div dir="ltr" style="text-align: left;" trbidi="on">
CSS locating strategy is the fastest way to identify an element compared to any other locating strategy currently available. Many of the automation frameworks now uses CSS as a locating strategy for locating elements. In this blog I will explain about how to identify an element using CSS locators.<br />
<br />
1. Locate an element using id.<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 14px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><input id="textid" value="textid" type="text"/>
<button id="buttonid">Button wiht id</button>
</code></pre>
<br />
Consider the above html code of a text box and a button, you can locate the above elements in html using there "id" attribute value.<br />
In CSS an element with id is identified by appending "#" to the start of its id attribute value. For ex the above text element can be located as <b>"#textid"</b>. Similarly the button element can be identified as <b>"#buttonid"</b><br />
<b><br /></b>
<br />
2. Locate an element using class attribute.<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><input class="textusingcls" value="Text with single class" type="text"/>
<button class="btnusingcls">Button with single Class</button>
</code></pre>
<br />
Consider the above html code of a text box and a button, you can locate the above elements in html using there "class" attribute value.<br />
In CSS an element with class is identified by appending "." to the start of its class attribute value. For ex the above text element can be located as <b>".textusingcls"</b>. Similarly the button element can be identified as <b>".btnusingcls"</b><br />
<br />
Locating an element having more than one class, for ex. consider the following html code.<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 14px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><input class="textcls1 textcls2" value="Text with multiple class" type="text"/>
<button class="buttoncls1 buttoncls2">Button with multiple Class</button>
</code></pre>
The above element can be identified by replacing the spaces between the class values with "." . The above elements can be located as <b>".textcls1.textcls2"</b> and <b>".buttoncls1.buttoncls2" </b>respectively.<br />
<br />
3. Locate an element using html tag.<br />
<pre style="background-color: #eeeeee; border: 1px dashed rgb(153, 153, 153); font-family: 'Andale Mono', 'Lucida Console', Monaco, fixed, monospace; font-size: 14px; line-height: 14px; overflow: auto; padding: 5px; width: 653px;"><code><input id="textid" value="textid" type="text"/>
<button id="buttonid">Button wiht id</button>
</code></pre>
<br />
Consider the above html code of a text box and a button. To locate the above elements using there html tags in css, you just have to use the tag name. For ex. The above two elements can be located as <b>"input"</b> and <b>"button" </b>respectively.<br />
<br />
4. Locate an element using html tag, class, id all together.<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 14px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><input id="textidcls" class="textidcls" value="Text with id and class" type="text"/>
<button id="buttonidcls" class="buttonidcls">Button with id and Class</button>
</code></pre>
<br />
Consider the above html code of a text box and a button. You can locate the above element using a combination of html tag, id and class all together. To do that just append all the three independent locator together. For the above element the unique locators will be <b>"input#textidcls.textidcls"</b> and <b>"button#buttonidcls.buttonidcls" </b>respectively.<br />
<br />
5. Locate element based on Parent element:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><input class="textcls" value="Text" type="text"/>
<button class="buttoncls">Button</button>
<div id="parent">
<div id="project-label">4. Locate Child element:</div>
<input class="textcls" value="Text" type="text"/>
<button class="buttoncls">Button</button>
<div>
<input class="textcls" value="Text" type="text"/>
<button class="buttoncls">Button</button>
</div>
</div>
</code></pre>
<div>
<br />
Consider the above html code, if you try to find the text element using css locator <b>".textcls" </b>you will get 3 elements in return. In case you need to find the text box under the div element with id "parent" you can locate it using the locator <b>"#parent .textcls"</b>, but this also gives you 2 text box elements that are under the element with id "parent".<br />
To find the direct child element of the <b>"#parent"</b> element you can use the <b>">"</b> sign of css locator. So if you use the locator <b>"</b><b>#parent > .textcls</b><b>"</b> it will give you the direct child of "parent" element.<br />
In css if you use space between the parent and child element, it will return all the child elements under the said parent irrespective of the hierarchy.<br />
<br />
6. Identify an element using attribute value:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 14px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code><input test="excttxt" value="Text for exact attr. value" type="text"/> </br>
<input test="strttxt1234" value="Text for starts with option" type="text"/> </br>
<input test="1234endtxt" value="Text for ends with option" type="text"/> </br>
<input test="12cntntxt34" value="Text for contains option" type="text"/> </br>
</code></pre>
<br />
Consider the above html code, there are 4 text boxes each having a different value for attribute <b>"test"</b>.Each element can be uniquely identified by using the following strategies:<br />
<ul style="text-align: left;">
<li>By exact attribute value: '<b>input[test="excttxt"]</b> '</li>
<li>By using starts with: <b>'input[test^="strttxt"]'</b></li>
<li>By using ends with: <b>'input[test$="endtxt"]'</b></li>
<li>By using contains: <b>'input[test*="cntntxt"]'</b></li>
</ul>
</div>
<br />
I had created a dummy html page which can be download from the following link: <a href="https://docs.google.com/open?id=0B3OQaZlrVrdJRktKOUs1T0ZXVVk" target="_blank">CSS-Locator-demo</a><br />
To use the demo for identifying a locator:<br />
1. Unzip the downloaded zip and open the page "css_locator.html" in chrome or firefox.<br />
2. Now go to console in the browser. For Chrome: Right Click -> Inspect Element -> Console. For Firefox: Right Click ->Inspect with Firebug -> Console.<br />
3. Use the jquery way of identifying element in the cosole. To do that type <b>$('<Ur CSS locator>') </b>under console and press enter.<br />
Jquery will find the matching element for the said css locator and display it on the console as a link. If you hover on the said link it will highlight the said element.<br />
<br />
More info on CSS selector at W3C <a href="http://www.w3.org/TR/css3-selectors/" target="_blank">link</a></div>
Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com10tag:blogger.com,1999:blog-1042251585556197079.post-54170217609020115702012-07-18T14:13:00.000+05:302012-07-29T09:16:13.167+05:30Android automation tools/frameworks<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
As we all know the market of android based devices is increasing day by day. Due to this lot of companies are developing android based applications. These applications can be categorized as following:<br />
<div>
<ul style="text-align: left;">
<li><span style="background-color: white;"><b>Native apps</b> - Apps that are developed using native android classes and runs on the device android OS.</span></li>
<li><span style="background-color: white;"><b>Webapps</b> - These apps are actually web-applications that are customized to work with Android based mobile devices.</span></li>
<li><span style="background-color: white;"><b>Hybrid apps</b> - These apps are the mix of Native and Web based development. Such kinds of apps have some Native coding to interact with device hardware resources like camera,recorder, speaker etc. along with some web based components to directly serve the pages from a web-application itself.</span></li>
</ul>
<div>
With such a variety of apps in the market the QA will have a difficult task in hand, that is to automate such applications. There are a lot of tools and frameworks available in the market that can help you with automating the android apps. In this blog I will list a few of them and basic info about it. Following are some of the opensource apps available in the market:</div>
</div>
<div>
</div>
<div>
<ul style="text-align: left;">
<li><u><b>Robotium</b></u> - Android automation framework built over Android instrumentation testing provided by the Android itself. This is currently one of the major frameworks available that can be used a base for your android app automation. More info at: <a href="http://code.google.com/p/robotium/" target="_blank">http://code.google.com/p/robotium/</a></li>
<li><u><b>NativeDriver</b></u> - Extension of Selenium webdriver for Native android automation.This currently discontinued and no further support or development is being done on it. More info at: <a href="http://code.google.com/p/nativedriver/" target="_blank">http://code.google.com/p/nativedriver/</a></li>
<li><u><b>Bot-bot</b></u> - An Opensource android automation project built over Robotium and NativeDriver frameworks. Comes with recording features to record user actions and export them as test case. It currently supports recording user actions of native application elements and new work is going on to support recording on Web-based/Hybrid apps. More info at: <a href="http://imaginea.github.com/bot-bot/" target="_blank">http://imaginea.github.com/bot-bot/</a></li>
<li><u><b>MonkeyTalk</b></u> - Monkey talk is based on Android instrumentation testing provided by android. It have recorder which can be used as a eclipse plugin. The tool seems to be unstable and there is not much changes/ bug fixes that is seen.</li>
<li><u><b>Calabash </b></u>- Calabash is another android/ios automation tool available in the market which uses cucumber as its base. More info is available at: <a href="https://github.com/calabash/calabash-android" target="_blank">https://github.com/calabash/calabash-android</a></li>
</ul>
<div>
Will keep on updating the list whenever I find something new.</div>
</div>
</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com4tag:blogger.com,1999:blog-1042251585556197079.post-3654295858121665452012-05-12T15:06:00.000+05:302014-08-28T17:27:05.565+05:30Generate TestNG-xslt report using Maven<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
Earlier I had covered in my blog on how to generate a TestNG-xslt report for your TestNG test-case execution using Ant. Following is the link to it:<br />
<a href="http://blog.varunin.com/2010/05/generating-selenium-reports-using.html">http://blog.varunin.com/2010/05/generating-selenium-reports-using.html</a><br />
<br />
As many of the recent projects are now using maven as their build tool ,test-cases are also required to integrate itself to the existing build. In this blog I will mention about how to generate a TestNG-xslt report for your TestNG test-case execution using Maven.<br />
Following is the "pom.xml" file for executing TestNG test-cases and to generate a "TestNG-xslt" report for the same:<br />
<br /></div>
<script src="https://gist.github.com/menonvarun/4b3508d75ed56f763ebb.js"></script>
Run the following command in terminal/command prompt to run your test cases and generate the TestNG-xslt report. The report will be generated under folder named "testng-xslt-report" inside the "target" folder under your build directory. <br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>mvn clean test site org.reportyng:reporty-ng:1.2:reportyng
</code></pre>
<br />
<b>Note:</b> In case the "test" task of mvn fails the report task of xslt will not be executed.
You can apply any of the strategies mentioned in the following url to achieve the same as part of a single execution:
<br /><br />
<a href="http://stackoverflow.com/questions/4174696/making-maven-run-all-tests-even-when-some-fail">http://stackoverflow.com/questions/4174696/making-maven-run-all-tests-even-when-some-fail</a>
<br />
<br />
Else 2 different commands have be run for test execution and report generation separately.
<br />
<br />
To know more about the TestNG-xslt configuration parameters please refer to my earlier blog post:
<br />
<a href="http://blog.varunin.com/2010/05/generating-selenium-reports-using.html">http://blog.varunin.com/2010/05/generating-selenium-reports-using.html</a></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com29tag:blogger.com,1999:blog-1042251585556197079.post-7172954239691964402012-02-08T14:47:00.000+05:302012-02-08T14:47:32.996+05:30Native android application automation using bot-bot<div dir="ltr" style="text-align: left;" trbidi="on">
Its been long time that I had written a blog here. I was busy with writing an android automation tool for native android application testing, named as "bot-bot". Please take a look at it and let us know your comments. This is work-in-progress and there are lot-of features that still have to implement.<br />
<br />
Following are some of the links giving information on bot-bot:<br />
Webpage:<br />
<a href="http://imaginea.github.com/bot-bot/">http://imaginea.github.com/bot-bot/</a><br />
<br />
Github page:<br />
<a href="https://github.com/Imaginea/bot-bot">https://github.com/Imaginea/bot-bot</a><br />
<br />
Most of the things are covered in the webpage or in Github.<br />
In case of issues you can contact me or send a mail.</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com17tag:blogger.com,1999:blog-1042251585556197079.post-85014995888556725522011-10-25T11:01:00.002+05:302015-02-10T16:52:29.023+05:30Selenium Grid with WebDriver<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">I had earlier covered in my blog on how to execute your RC cases in selenium grid. But with the commencement of Selenium-2/Webdriver, grid setup has been changed. In the following blog I will cover how to set-up your grid and the changes that will be required for easy execution of cases.</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Following things are required:</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">1. Selenium 2.xx version server jar and Java library. The latest one can be downloaded from the link: <a href="http://code.google.com/p/selenium/downloads/list">Selenium-2</a></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">2. Java 1.6 and above</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">3. TestNg jar . You can download it from the link: <a href="http://testng.org/doc/download.html">TestNG</a></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">4. Eclipse with TestNG plugin installed(optional)</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">5. ChromeDriver. Can be downloaded from: <a href="http://code.google.com/p/chromium/downloads/list">ChromeDriver</a></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span><br />
<b><u><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The Test Code</span></u></b><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Following is an example of test-class that have a test case to search google for "testing" and verifying after clicking it on a link.</span><br />
<br />
<script src="https://gist.github.com/menonvarun/43c1ba15a8d46fb0da54.js"></script>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">In the above class I am using the TestNG "Parameter" property to provide different data set to the "BeforeClass" method "<span class="Apple-style-span" style="white-space: pre;">beforeClass</span>". The beforeClass method accepts two properties "browser" and a "port".</span><br />
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">These values are used for initialization of driver and in-turn for initialization of selenium object. In the above code I am using the "WebDriverBackedSelenium" class for creation of the selenium object, so that its easy for guys who had worked on Selenium-1 to understand the code. If you want the code to be purely WebDriver, you can directly use the "driver" object for defining your test-cases.</span></div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The main part in this test case is how the driver object is being created:</span><br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>DesiredCapabilities capability= new DesiredCapabilities();
capability.setBrowserName(browser);
WebDriver driver= new RemoteWebDriver(new URL("http://localhost:".concat(port).concat("/wd/hub")), capability);</code></pre>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The above code creates an object of DesiredCapability and then set the browser value to it. Now using this "capability" object I am creating the webdriver object using the "RemoteWebDriver" class. This tells the selenium on which browser the test-case needs to run and where the server is located. In this example I am assuming the server to be running locally. In case it is on different system the "localhost" needs to be re-placed with the ip of the said system.</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b><u>TestNG configuration</u></b></span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">For parallel execution you need to use the TestNG configuration. Following is an "testng.xml" file for the above said test class. The said configuration executes the test-cases across different browser.</span></div>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
<suite name="Selenium TestNG Suite" parallel="tests"
thread-count="5">
<test name="Selenium TestNG - 1">
<parameter name="browser" value="firefox" />
<parameter name="port" value="4444" />
<classes>
<class name="com.test.testng.Google" />
</classes>
</test>
<test name="Selenium TestNG - 2">
<parameter name="browser" value="chrome" />
<parameter name="port" value="4444" />
<classes>
<class name="com.test.testng.Google" />
</classes>
</test>
</suite>
</code></pre>
In the above configuration, I am configuring TestNG to run "tests" in parallel. Also there are two different tests inside a suite. For each test a different "browser" parameter value has been configured.<br />
<br />
<div style="text-align: justify;">
<b><u>Selenium-Grid server</u></b></div>
<div style="text-align: justify;">
Now start your grid using the following commands. Run each command in a seperate terminal or command prompt by going to the directory containing your selenium-server-standalone-2.x.x.jar. In the following example I am using the 2.7.0 version of selenium.</div>
<br />
For Hub:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
java -jar selenium-server-standalone-2.7.0.jar -role hub
</code></pre>
<br />
For a firefox based node:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
java -jar selenium-server-standalone-2.7.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5556 -browser browserName=firefox
</code></pre>
<br />
For google-chrome based node:<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>
java -Dwebdriver.chrome.driver=/path/to/chromedriver -jar selenium-server-standalone-2.7.0.jar -role webdriver -hub http://localhost:4444/grid/register -port 5555 -browser browserName=chrome
</code></pre>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Before running the above command you need to provide the chrome-driver path to the property "-Dwebdriver.chrome.driver".</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Now run your testng.xml from eclipse by selecting it -> Right click -> Run as -> TestNG suite(this will work only if you have TestNG plugin installed in your eclipse.)</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Or you can choose other ways to execute "testng.xml" like from command prompt, using ant or maven.</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Once you run the above testng.xml. TestNG will execute the cases from the Google class on grid across different browsers firefox and google-chrome as configured.</span></div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">You can do configurations for environment like OS (Linux,Windows), browser, browser-version and all and then you can run you cases on particular type of environment by configuring them accordingly. More details can be found at the following URL:</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><a href="http://code.google.com/p/selenium/wiki/Grid2">http://code.google.com/p/selenium/wiki/Grid2</a></span></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com53tag:blogger.com,1999:blog-1042251585556197079.post-39883691952942195812011-10-20T12:33:00.001+05:302015-02-10T16:59:41.996+05:30Data-Driven testing using Junit and TestNG<div dir="ltr" style="text-align: left;" trbidi="on">
<br />
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Most of the guys who are into
automation may be knowing the term Data-Driven testing. But the word
will still be new for some fresh faces in the field of automation. In this blog I will explain what is Data-Driven testing and will give an example of Data-driven testing using Junit and TestNG frameworks.</span></div>
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div>
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Data-Driven testing as the name
suggests is a test driven by the Data. For ex. You have a user detail
form where you need to enter details of multiple users and save them.
Here if you have 5 different user data available and you have to
write automation cases for these, you may end up writing 5 different
automation test cases(one for each user data).</span></div>
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">If you apply a Data-Driven approach you
will end up with only one test-case, that is filling the form with
user data and then submitting it. The test case will get executed
based on the data provided to it. In this case it will be 5 and hence
the test case will get executed 5 times with different data-set.</span></div>
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div>
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The advantage of using a
Data-driven approach is that you reduce your effort in writing/maintaing test-cases for your different type of data. In case of
additions or deletion of new/old entries , you just have to change the
data and not your actual test-case.</span></div>
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div>
<div style="margin-bottom: 0cm; text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Following I will mention a Data-Driven
approach for searching on google with different data using Junit and TestNg frameworks:</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Using Junit:</b></span><br />
<script src="https://gist.github.com/menonvarun/a35aca46adbcae488f95.js"></script>
<br />
<b>Using TestNg:</b><br />
<br />
<script src="https://gist.github.com/menonvarun/a30ff84ae631b7935fbd.js"></script>
</div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The main difference in the above two functions is that you provide a Paramaterized option to the class in Junit and supply data to the constructor of the said class. Where as in TestNG you do the same at the test-method level.</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Its simple to do data-driven testing in TestNG framework as you can provide a different data providing function for each test-method, but the same is not possible in Junit.</span></div>
<br /></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com10tag:blogger.com,1999:blog-1042251585556197079.post-41432038813079708052011-10-04T12:31:00.000+05:302015-02-10T17:20:25.209+05:30Running tests on Google Chrome using Webdriver<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
While automating your web-application using webdriver, many may have faced problems in executing your cases on Google-chrome. Whenever you try to use webdriver object for executing your cases on chrome using the following code:<br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>DesiredCapabilities capability = DesiredCapabilities.chrome();
</code></pre>
<br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">you most probably get the following error:</span><br />
<br />
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>The path to the chromedriver executable must be set by the webdriver.chrome.driver system property; for more information, see http://code.google.com/p/selenium/wiki/ChromeDriver. The latest version can be downloaded from http://code.google.com/p/chromium/downloads/list
</code></pre>
<br />
<div style="text-align: left;">
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The solution to this error that has been mentioned in the given URL "http://code.google.com/p/selenium/wiki/ChromeDriver" is to set the chromedriver path to the variable "<span class="Apple-style-span" style="background-color: white; line-height: 16px;">webdriver.chrome.driver</span></span>". B<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">ut how exactly to set the path and use it for your test execution is not given there. So I though to just document it here on my blog.</span></div>
</div>
<div style="text-align: left;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span></div>
<div style="text-align: left;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">For setting the </span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"> "<span class="Apple-style-span" style="background-color: white; line-height: 16px;">webdriver.chrome.driver</span></span>" <span class="Apple-style-span" style="font-family: Verdana, sans-serif;">value and for</span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"> using google-chrome to execute your automated tests, you can use one of the following methods:</span></div>
<div style="text-align: left;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Method - 1:</b></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Start the selenium server using the following command:</span></div>
<pre style="background-color: #eeeeee; border: 1px dashed #999999; color: black; font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; font-size: 12px; line-height: 14px; overflow: auto; padding: 5px; width: 100%;"><code>java -Dwebdriver.chrome.driver=/path/to/chromedriver -jar selenium-server-standalone-2.7.0.jar</code></pre>
</div>
<br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">And in your Java code you use the chrome driver in the following way:</span><br />
<br />
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>DesiredCapabilities capability = DesiredCapabilities.chrome();
WebDriver driver = new RemoteWebDriver(new URL("http://localhost:4444/wd/hub"), capability);
</code></pre>
<br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The advantage of using this method is that you can execute your test-cases in a remote machine and this is advantageous when you want to run it on grid.</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Method - 2:</b></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Set the system property "<span class="Apple-style-span" style="background-color: white; line-height: 16px;">webdriver.chrome.driver</span>" using System.setProperty() in your code and then try to execute your cases on Chrome.</span><br />
<br />
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>System.setProperty("webdriver.chrome.driver", "/path/to/chromedriver");
WebDriver driver = new ChromeDriver();
</code></pre>
<br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">This method works well when your tests are getting execute on a local machine and you are not starting any selenium server.</span><br />
<br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Following are some important links for Chrome driver:</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Webdriver Chromedriver page:</span><br />
<a href="http://code.google.com/p/selenium/wiki/ChromeDriver"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">http://code.google.com/p/selenium/wiki/ChromeDriver</span></a><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">ChromeDriver download page for downloading the ChromeDriver server:</span><br />
<a href="http://code.google.com/p/chromium/downloads/list"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">http://code.google.com/p/chromium/downloads/list</span></a></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com44tag:blogger.com,1999:blog-1042251585556197079.post-83971345399116805362011-09-29T17:37:00.001+05:302015-02-10T17:29:30.555+05:30Get list of files in a directory using Java<div dir="ltr" style="text-align: left;" trbidi="on">
While doing an automation I came up with a problem where I need to get a list of all files in a Directory.<br />
So just though to share the same with you the program to do so. I had made used of recursion in the following programs to get the list of files. Following are the two programs one will give you a ArrayList of files with their absolute path where as another will give you an ArrayList of File object of respective files.<br />
Following program will store the absolute path of all the files inside a directory to the fileList argument provided.<br />
<script src="https://gist.github.com/menonvarun/e0f61d5b1fda4d808287.js"></script>
<br />
Following program will store the File object of the files that are found into the respective fileList Array provided as an argument to the function<br />
<script src="https://gist.github.com/menonvarun/95d5e777176ef2326f68.js"></script>
</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com3tag:blogger.com,1999:blog-1042251585556197079.post-57188349295657659302011-09-23T18:55:00.001+05:302015-02-10T17:42:03.247+05:30Automating a Native android app using Selenium and NativeDriver<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">As there are more and more development happening on the android front, automation of the developed applications has also become a necessity. Android within its API supports a testing framework which can be used for testing applications, but writing and developing cases using that API is not easy. We may need a framework that makes it easy to write and develop test cases for our applications.</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">One of such framework is "NativeDriver". It is built over the Selenium webdriver automation framework.</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">As you must be knowing that selenium is vastly used open-source functional automation tool. </span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">In this write-up I will tell you on how to automate an android application using NativeDriver</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Following things are required before starting:</span></div>
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;"></span></span></div>
<ul style="max-width: 62em; padding-left: 25px;">
<li style="margin-bottom: 0.3em;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Android SDK 2.2 or later - <a href="http://developer.android.com/sdk/index.html" rel="nofollow" style="color: #0000cc;">download</a></span></li>
<li style="margin-bottom: 0.3em;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Eclipse version 3.5 or later (Eclipse IDE for Java Developers recommended) - <a href="http://www.eclipse.org/downloads/" rel="nofollow" style="color: #0000cc;">download</a></span></li>
<li style="margin-bottom: 0.3em;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Android Development Toolkit (ADT) plug-in - <a href="http://developer.android.com/sdk/eclipse-adt.html#installing" rel="nofollow" style="color: #0000cc;">Installing ADT</a></span></li>
<li style="margin-bottom: 0.3em;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Ant - <a href="http://ant.apache.org/bindownload.cgi" rel="nofollow" style="color: #0000cc;">download</a></span></li>
<li style="margin-bottom: 0.3em;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">JDK 1.6 or later - <a href="http://www.oracle.com/technetwork/java/javase/downloads/jdk-6u25-download-346242.html" rel="nofollow" style="color: #0000cc;">download</a></span></li>
</ul>
<div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Building the NativeDriver libraries:</b></span></div>
<div>
<ul>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Checkout the NativeDriver code:</span></li>
<li><pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="pln" style="color: black;">svn checkout https</span><span class="pun" style="color: #666600;">:</span><span class="com" style="color: #880000;">//nativedriver.googlecode.com/svn/trunk nativedriver --username {Google account e-mail address}</span></span></pre>
</li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Build the NativeDriver code:</span></li>
<li><pre class="prettyprint" style="background-color: #eeeeee; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="pln" style="color: black;">$ cd nativedriver</span><span class="pun" style="color: #666600;">/</span><span class="pln" style="color: black;">android
$ ant</span></span></pre>
</li>
</ul>
</div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;"></span></span><br />
<div style="line-height: 1.25em; max-width: 64em;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">The libraries are built and stored in the nativedriver/android/build directory:</span></span></div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">
</span></span><br />
<ul style="max-width: 62em; padding-left: 25px;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">
<li style="margin-bottom: 0.3em;"><strong>server-standalone.jar</strong> - this should be linked to your Android application, and runs on the Android device (or emulator). This is the NativeDriver server, and listens for requests to automate the application, such as “start an activity” or “click a UI element”</li>
<li style="margin-bottom: 0.3em;"><strong>client-standalone.jar</strong> - this should be linked to the test, which is the NativeDriver client. It implements a WebDriver API which communicates with the server.</li>
</span></span></ul>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">
</span></span><br />
<div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;"><b>Adding the NativeDriver jar to your application</b></span></span></div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">
</span></span><br />
<div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;"><b><br /></b></span></span></div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">
</span></span><br />
<div>
<ul style="text-align: left;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">
<li>Import your android application code into the eclipse by using the File -> Import functionality of eclipse.</li>
<li>Add the <b>server-standalone.jar</b> to the build-path of your android application by Right clicking on the Android application project -> Configure build path -> Add jars or Add external jars (browse to the server-standalone.jar file, select and add it).</li>
<li>To the application <b>AndroidMainfest.xml </b>file, add the following to the <manifest> element.</manifest></li>
</span></span></ul>
</div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;">
</span></span><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"></span><br />
<pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"><span class="tag" style="color: #000088;"><span class="pln" style="color: black;"> </span><span class="atn" style="color: #660066;"><instrumentation android:targetPackage</span><span class="pun" style="color: #666600;">=</span><span class="atv" style="color: #008800;">"{app_package_name}"</span><span class="pln" style="color: black;">
</span><span class="atn" style="color: #660066;">android:name</span><span class="pun" style="color: #666600;">=</span><span class="atv" style="color: #008800;">"com.google.android.testing.nativedriver.server.ServerInstrumentation"</span><span class="pln" style="color: black;"> </span><span class="tag" style="color: #000088;">/></span><span class="pln" style="color: black;">
</span><span class="tag" style="color: #000088;"><uses-permission< span=""><span class="pln" style="color: black;"> </span><span class="atn" style="color: #660066;">android:name</span><span class="pun" style="color: #666600;">=</span><span class="atv" style="color: #008800;">"android.permission.INTERNET"</span><span class="pln" style="color: black;"> </span><span class="tag" style="color: #000088;">/></span><span class="pln" style="color: black;">
</span><span class="tag" style="color: #000088;"><uses-permission< span=""><span class="pln" style="color: black;"> </span><span class="atn" style="color: #660066;">android:name</span><span class="pun" style="color: #666600;">=</span><span class="atv" style="color: #008800;">"android.permission.WAKE_LOCK"</span><span class="pln" style="color: black;"> </span><span class="tag" style="color: #000088;">/></span><span class="pln" style="color: black;">
</span><span class="tag" style="color: #000088;"><uses-permission< span=""><span class="pln" style="color: black;"> </span><span class="atn" style="color: #660066;">android:name</span><span class="pun" style="color: #666600;">=</span><span class="atv" style="color: #008800;">"android.permission.DISABLE_KEYGUARD"</span><span class="pln" style="color: black;"> </span><span class="tag" style="color: #000088;">/></span></uses-permission<></span></uses-permission<></span></uses-permission<></span></span></span></pre>
<span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;">
</span><span class="Apple-style-span" style="background-color: white; font-family: Verdana, sans-serif;"> Here {app_package_name} needs to be replaced with the name of the package as specified in the mainfest element's package attribute.</span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;"><div>
<ul style="text-align: left;">
<li>Build the application and install it on the device.</li>
<li>Now go to the commandline and start the instrumentation using the following line:</li>
</ul>
</div>
</span></span><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"><pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"><span class="pln" style="color: black;">adb shell am instrument </span><span class="pun" style="color: #666600;">{</span><span class="pln" style="color: black;">app_package_name</span><span class="pun" style="color: #666600;">}/</span><span class="pln" style="color: black;">com</span><span class="pun" style="color: #666600;">.</span><span class="pln" style="color: black;">google</span><span class="pun" style="color: #666600;">.</span><span class="pln" style="color: black;">android</span><span class="pun" style="color: #666600;">.</span><span class="pln" style="color: black;">testing</span><span class="pun" style="color: #666600;">.</span><span class="pln" style="color: black;">nativedriver</span><span class="pun" style="color: #666600;">.</span><span class="pln" style="color: black;">server</span><span class="pun" style="color: #666600;">.</span><span class="typ" style="color: #660066;">ServerInstrumentation</span></pre>
</span><span class="Apple-style-span" style="background-color: white; font-family: Verdana, sans-serif;">Here again the </span><span class="Apple-style-span" style="background-color: white; font-family: Verdana, sans-serif;">{app_package_name} needs to be replaced with the name of the package as specified in the mainfest element's package attribute.</span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;"><div>
<ul style="text-align: left;">
<li>Enable port forwarding by using the following command:</li>
</ul>
</div>
</span></span><span class="Apple-style-span" style="background-color: white; font-family: arial, sans-serif; font-size: 13px;"><pre class="prettyprint" style="background-color: #eeeeee; font-family: Monaco, 'DejaVu Sans Mono', 'Bitstream Vera Sans Mono', 'Lucida Console', monospace; font-size: 12px; max-width: 70em; overflow-x: auto; overflow-y: auto; padding-bottom: 0.5em; padding-left: 0.5em; padding-right: 0.5em; padding-top: 0.5em;"><span class="pln" style="color: black;">adb forward tcp</span><span class="pun" style="color: #666600;">:</span><span class="lit" style="color: #006666;">54129</span><span class="pln" style="color: black;"> tcp</span><span class="pun" style="color: #666600;">:</span><span class="lit" style="color: #006666;">54129</span></pre>
</span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><span class="Apple-style-span" style="background-color: white;"><div>
<br /></div>
<div>
<b>Writing your Test Cases</b></div>
<div>
For writing your test cases you just have to create a new Java project and start writing code for it. I will explain this using a code example. The following code is done to automate an opensource K9 mail application on android:</div>
<div>
<br /></div>
</span></span></div>
<script src="https://gist.github.com/menonvarun/0695757e878594e2af77.js"></script>
</div>
<br />
Important Notes:-<br />
<br />
<ul style="text-align: left;">
<li>As there is no recording feature available, we need to write the code manually for automating our scenarios. </li>
<li>For identifying the element id to interact on the UI, you can get the ID's of the elements from the R.java file generated inside your android application code.</li>
<li>Also as we are writing our cases in Java code we can use our own test framework and generate html reports for out automation execution.</li>
</ul>
<br />
<br />
Note: Most of the material in this blog has been taken from the original site of the NativeDriver. The credit for such material goes to the original author.<br />
Following is the link to it. <a href="http://code.google.com/p/nativedriver">http://code.google.com/p/nativedriver</a><br />
<br /></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com80tag:blogger.com,1999:blog-1042251585556197079.post-38388399887084660902011-08-17T13:59:00.000+05:302011-08-17T13:59:24.328+05:30Native android app automation – Nativedriver vs Robonium<div dir="ltr" style="text-align: left;" trbidi="on"><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Nowadays android is the latest thing in the market and many of the companies are working on android app development. With development comes the requirement to test an application too. As we all tester know that automation is one of the important part of testing, and is mainly used to reduce the time taken to execute the testcases. This gives time to testers to concentrate more on exploratory testing. Recently I was going through some group, and found out about some open-source frameworks that makes it possible to automate an Android native application. I went through two of such frameworks and will write about what I felt about them. The two frameworks I am going to talk about is Nativedriver and Robonium. </span></div><div><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Nativerdriver</b>- Is an opensource framework written over Selenium-2.0 Webdriver implementation. As we all know that selenium is a great functional automation tool for web-applications and gives you a cross-browser and cross-platform supports. The support for testing native application has enhanced the value of selenium. Nativedriver can be used when you are actually working along with the development team and has access to the source code of the andorid application that needs to be tested. </span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div><div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Robonium</b></span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"> – Is also a great tool and is written by extending the Internal Android testing framework. This framwork supports a lot of functions which can be used to auotmate your application test. The main advantage of this framework is that , you can automate any application using this without actully having the source code of the app.</span></div><pre class="western" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">
<b>Advantages of Nativedriver: </b></span><ul style="text-align: left;"><li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Built over the selenium webdriver hence can be easliy used by existing selenium users. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Test are run as a normal Java unit test. And hence other frameworks can also be used for test-case execution or reporting. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Ant or maven can also be used for execution of cases. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Fast execution and reporting of testing results</span></li>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"> </span></ul><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Disadvantages of Nativedriver:</b> </span><ul style="text-align: left;"><li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Need access to the source code of the application that needs to be tested. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Sometime difficult to find element as support for finding elements by index is not available</span></li>
</ul></pre><pre class="western" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><b><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">
</span></b></pre><pre class="western" style="margin-bottom: 0px; margin-left: 0px; margin-right: 0px; margin-top: 0px;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Advantages of Robonium: </b></span><ul style="text-align: left;"><li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Don't require the source code of the application for testing. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Elements are easy to identify and work on. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Tests are simple to write. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Setup is simple.</span></li>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"> </span></ul><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>Disadvantages of Robonium </b></span><ul style="text-align: left;"><li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Can only be executed suing eclipse. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Slow execution. </span></li>
<li><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Typing a normal text is not supported at this point. </span></li>
</ul><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"></span></pre></div></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com4tag:blogger.com,1999:blog-1042251585556197079.post-42738567523085147172011-08-08T18:29:00.004+05:302015-02-10T17:06:34.056+05:30Scrolling on pages using Selenium<div dir="ltr" style="text-align: left;" trbidi="on"><div dir="ltr" style="text-align: left;" trbidi="on"><div dir="ltr" style="text-align: left;" trbidi="on"><div dir="ltr" style="text-align: left;" trbidi="on"><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Somebody recently asked me on how to scroll a page which is dynamically loaded. Something like the Facebook page where the updates gets loaded as you scroll down the page. As I never had such a requirement , I didn't knew a solution to it. </span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">While searching I found people suggesting the "<i>selenium.focus</i>" function to be used as a solution, but that does not solve the problem I am talking about. The "<i>selenium.focus</i>" should be used when the element you are looking for gets loaded when the page gets loaded and not when you scroll through the page.</span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">After lot of searching I was unable to get a proper answer to my problem and finally got an idea for implementing it. Its just a 4 to 5 lines of code that can be used in your code for scrolling on the page.</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Following is the code:</span></div></div><br />
<script src="https://gist.github.com/menonvarun/98f72fc571f3c548ac55.js"></script>
<br />
<div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The above code uses the JavaScript method "<i>scrollBy</i>" to scroll on the page. The <i>for</i> loop runs for 60 sec and calls the <i>scrollBy</i> function every second. This makes the selenium to scroll on the page.</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">If you have a test where you need to scroll on the page and check whether an element is loaded dynamically or not you can put a <i>isElementPresent</i> like function after the "<i>driver.executeScript</i>" to check visibility of your element.</span></div><div style="text-align: justify;"><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">Following is a test method written in webdriver that you can use to test the above function on the Facebook page:</span></div><br />
<script src="https://gist.github.com/menonvarun/eb328f99d2132cfff1e4.js"></script>
</div></div><br />
The following code is written for Selenium-1.0 users:<br />
<script src="https://gist.github.com/menonvarun/735a7ad5d3daed1c9fcb.js"></script>
</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com17tag:blogger.com,1999:blog-1042251585556197079.post-80469058922740790882011-07-28T16:45:00.002+05:302015-02-11T16:55:39.955+05:30isElementPresent in Selenium-2.0<div dir="ltr" style="text-align: left;" trbidi="on">
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">While going through Selenium-2.0 I found out that WebDriver does not have a function called isElementPresent(). This was one of the important functions that was used in Selenium-1.0. It was mainly used for waiting for an element to be available to take an action on it. To implement this in WebDriver you just need to write a method as mentioned below. You can then use this function with any type of <i>"By"(By.id, BY.name, etc.)</i></span>
</div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><i><br />
</i></span><br />
<script src="https://gist.github.com/menonvarun/8b4fd939237a8d721a88.js"></script>
<br />
<div style="text-align: justify;">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">The above function will return <i>true</i> in case the element is found on the page, else it will return <i>false. </i></span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br /> In case your want to wait for a element to be present you can implement it in the following way.</span>
<script src="https://gist.github.com/menonvarun/557fceae9010e025cc7f.js"></script>
</div>
</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com2tag:blogger.com,1999:blog-1042251585556197079.post-87180787270739724902011-07-25T15:14:00.003+05:302015-02-10T17:55:57.374+05:30Sending an E-mail with your Test Execution Reports<div dir="ltr" style="text-align: left;" trbidi="on">
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">While doing automation testing many of us had thought that it is good to send the excetuion report mail after your test execution. In this blog I am going to tell two ways using which you can send a mail with to multiple E-mail addresses with your execution report attached. <br />
<br />
<b>Using ant: </b><br />
Ant supports a mail task which can be used as one of your ways for sending a mail. Following target can be used to send a mail using ant:</span><br />
<div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div>
<script src="https://gist.github.com/menonvarun/6103d31914b55597dc51.js"></script>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
<br />
In the above target you need to mention the following things: <br />
<b>mailhost</b> – this the sender host of your mail box. You can this from your outgoing configuration of account in you mail client. For gmail it is “smtp.gmail.com” <br />
<br />
<b>port</b> – this is the port at which the above mailhost support sending of email. This configuration also you can check in your mailbox configuration. By default it is “25” but for SSL and TLS support it will be different for different hosts. <br />
<br />
<b>User/password</b> – some mail hosts need the username and password of the account mail box to authenticate the user while sending a mail. You need to provide this in the “user” & “password” attributes. <br />
<br />
<b>ssl</b> – if you want to use ssl for contacting the mailbox you need to set this attribute value to “true”</span><br />
<div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b><br />
</b></span><br />
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><b>subject</b> – Subject of the mail you want to give. <br />
<br />
<b>to</b> – you need provide the address of the email recepients here using the “address” attribute. You use a property also here. This property you can setusing the properties file and then importing to the build.xml <br />
<br />
<b>attachments</b> – this can be used to attach your report as part of the mail and then send it. <br />
<br />
Please note: If you get a MIME error or java mail error while running the above target. Please download a jar of “java mail” and put it to the lib folder of your ant installation.</span></div>
<div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"> <b>Using Java code: </b><br />
When I had this problem of sending the execution report as mail, I did it in a hard way by writing the following java code. In the following code I had used the javax mail API for composing and sending the mail.</span><br />
<script src="https://gist.github.com/menonvarun/f03f91119adb63053b81.js"></script>
<div>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;"><br />
</span></div>
</div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com15tag:blogger.com,1999:blog-1042251585556197079.post-16819109195784091932011-07-21T18:07:00.009+05:302015-02-10T18:03:42.781+05:30Getting the width and height of an Image using Selenium<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-size: 100%;"><span style="font-family: verdana;">People has kept asking me how to capture the width and height of an image/element using selenium. I tried to get an answer to it and the solution is very simple. The solution comes with Selenium itself.<br />
</span><br />
<span style="font-family: verdana;">Selenium-1 consists of certain functions for storing element values like getElementHeight, getElementWidth, getElementPositionLeft, getElementPositionRight, getElementPositionTop.<br /><br />
Similarly in Selenium-2(WebDriver) you can use the getSize() function which will return a "Dimension" class object. You can then use the getHeight() and getWidth() functions over it for getting the width and height of the element.
</span><br />
<br />
<span style="font-family: verdana;">We can use these functions to get the position of the element and also its width and height.</span><br />
<span style="font-family: verdana;">Following is an example for getting the height and width of an image/element on the browser using Selenium-1.</span><br />
</span><br />
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>
height = selenium.getElementHeight("locaton to the image on the browser.(xpath or id)")
width = selenium.getElementWidth("location to the image on the browser.(xpath or id)")
</code></pre>
<br />
<span style="font-family: verdana;">Following is an example for getting the height and width of an image/element on the browser using Selenium-2(WebDriver).</span><br />
<pre style="font-family: Andale Mono, Lucida Console, Monaco, fixed, monospace; color: #000000; background-color: #eee;font-size: 12px;border: 1px dashed #999999;line-height: 14px;padding: 5px; overflow: auto; width: 100%"><code>
height = driver.findElement("location to the image on the browser.(xpath or id)").getSize().getHeight();
width = driver.findElement("location to the image on the browser.(xpath or id)").getSize().getWidth()
</code></pre>
<br /></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com2tag:blogger.com,1999:blog-1042251585556197079.post-47945666295531801242011-07-20T13:06:00.001+05:302011-07-25T15:10:56.255+05:30Comparing and re-sizing images using Selenium<div dir="ltr" style="text-align: left;" trbidi="on">While automating a web application some of us have to deal with the test to check that an image has been successfully uploaded or not.And that the uploaded image matches with the actual one or not. To automate this test, there are certain things that we need to achieve:<br />
<br />
<ol style="text-align: left;"><li>Saving the image that has been uploaded for comparison with the original image.</li>
<li>Handling the re-sizing and re-formatting of the image by the web application itself.</li>
<li>Logic to compare images.</li>
</ol><br />
<b>1. Saving the image.</b><br />
Selenium does not support any direct way to actually store/get an image. But there are other ways like "right-click" and "Save as" option using which you can save the image on firefox and chrome. Once you get an image you can move further with the second step that is checking size of the image.<br />
<br />
<b>2. Handling the re-sizing and re-formatting of the image by the web application itself.</b><br />
Whenever we upload an Image to a web-app it internally re-size and re-format the image while storing or rendering to save space and improve performance. So if you save an uploaded image from your web-app and want to compare it with the original image, it will fail. The reason being the image that you had downloaded from the web-app has been modified and may not match with the original image in terms of format, size and clarity. The solution to it can be achieved by getting the logic from the development team for re-sizing or re-formatting of image that they use inside their code. You can use then use the same code in you automation test to re-size and re-format your original image and then compare it with the downloaded image to check whether both matches or not.<br />
Following code will give you a general idea on how to re-size an image.<br />
<br />
<pre class="brush: js">public BufferedImage resize(BufferedImage img, int newW, int newH) {
//Getting the width and height of the given image.
int w = img.getWidth();
int h = img.getHeight();
//Creating a new image object with the new width and height and with the old image type
BufferedImage dimg = new BufferedImage(newW, newH, img.getType());
Graphics2D g = dimg.createGraphics();
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
//Creating a graphics image for the new Image.
g.drawImage(img, 0, 0, newW, newH, 0, 0, w, h, null);
g.dispose();
return dimg;
}
</pre><br />
<b>3. Logic to compare images.</b><br />
Once you had completed the above two steps you can go ahead with comparison of the images.<br />
Following is a java code using which you can actually match two images pixel by pixel.<br />
<br />
<br />
<pre class="brush: js">import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.awt.image.Raster;
import java.io.File;
import java.io.IOException;
public void compareImage() {
boolean ret = true;
try {
original = ImageIO.read(new File(
"originalFile"));
copy = ImageIO.read(new File("copyFile"));
ras1 = original.getData();
ras2 = copy.getData();
//Comparing the the two images for number of bands,width & height.
if (ras1.getNumBands() != ras2.getNumBands()
|| ras1.getWidth() != ras2.getWidth()
|| ras1.getHeight() != ras2.getHeight()) {
ret=false;
}else{
// Once the band ,width & height matches, comparing the images.
search: for (int i = 0; i < ras1.getNumBands(); ++i) {
for (int x = 0; x < ras1.getWidth(); ++x) {
for (int y = 0; y < ras1.getHeight(); ++y) {
if (ras1.getSample(x, y, i) != ras2.getSample(x, y, i)) {
// If one of the result is false setting the result as false and breaking the loop.
ret = false;
break search;
}
}
}
}
}
if (ret == true) {
System.out.println("Image matches");
} else {
System.out.println("Image does not matches");
}
} catch (IOException e) {
System.out.println(e);
}
}
</pre></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com11tag:blogger.com,1999:blog-1042251585556197079.post-38856214289037746942011-07-18T18:06:00.008+05:302011-07-26T08:07:29.338+05:30Running Selenium Tests on different browsers using Junit<div dir="ltr" style="text-align: left;" trbidi="on"><div><span class="Apple-style-span">Many people has asked me on how to run a test on different browsers using Junit without actually changing the value of browser after one test execution. For which I had always kept answering that it may not be possible with Junit. But recently while trying to find a solution for it I came across with the Parameterization option that is available with latest changes of Junit. This was not possible in earlier versions of Junit but now Junit has come up with lot of added options in the latest version of Junit 4.8. Following is a way by which you can execute your automation tests in multiple browsers without actually waiting to finish your tests and then passing the second browser value. See the example below:</span></div><pre class="brush: js">import com.thoughtworks.selenium.*;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.junit.runners.Parameterized;
import org.junit.runners.Parameterized.Parameters;
import java.util.Arrays;
import java.util.List;
@RunWith(Parameterized.class)
public class TestGoogleBase extends SeleneseTestBase {
private String browser;
public TestGoogleBase(String browser){
this.browser=browser;
}
@Parameters
public static List data() {
return Arrays.asList(new Object[][]{{"*chrome"},{"*googlechrome"}});
}
@Before
public void setUp() throws Exception {
selenium = new DefaultSelenium("localhost", 4444, browser, "http://www.google.co.in/");
selenium.start();
}
@Test
public void testUntitled() throws Exception {
selenium.open("/");
selenium.type("id=lst-ib", "testing");
selenium.click("//input[@value='Google Search']");
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (selenium.isElementPresent("link=Software testing - Wikipedia, the free encyclopedia")) break; } catch (Exception e) {}
Thread.sleep(1000);
}
selenium.click("link=Software testing - Wikipedia, the free encyclopedia");
for (int second = 0;; second++) {
if (second >= 60) fail("timeout");
try { if (selenium.isTextPresent("Software testing")) break; } catch (Exception e) {}
Thread.sleep(1000);
}
}
@After
public void tearDown() throws Exception {
selenium.stop();
}
}
</pre><div><span class="Apple-style-span"><br />
</span></div><div><span class="Apple-style-span">In the above class I am using the <i>@RunWith(Parametrized.class)</i> option that will tell Junit that this class is run as a parametrized class. A parameter value providing method is added to the class by denoting <i>@Parameter</i> annotation which returns a <i>List< Object[]><object[]></object[]></i> array. This array consists of the browser names on which the test needs to be executed, like “*chrome”(Firefox) and “*googlechrome” in this case.</span></div><div><span class="Apple-style-span">The constructor of the said class is modified to accept a “<i>browser</i>” string that is set when the said parameter function return the browser value.</span></div><div><span class="Apple-style-span">This “browser” value is then used by the “<i>setup</i>” and inturn by the “<i>Test</i>” method while execution.</span></div><div><br />
</div></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com12tag:blogger.com,1999:blog-1042251585556197079.post-56568526443869922022011-07-01T12:07:00.001+05:302011-07-26T08:10:16.580+05:30Factory Class in TestNg<div dir="ltr" style="text-align: left;" trbidi="on"><div><span class="Apple-style-span">There are many functions provided by TestNG and you can use them in different ways I will mention in this blog about the @Factory implementation.</span></div><div><span class="Apple-style-span"><br />
</span></div><div><span class="Apple-style-span"><b>@ Factory</b></span></div><div><span class="Apple-style-span">A Factory will allow to create test dynamically. And whenever we define a Factory it should always return an object array “Object[]”. All the test methods under the Class object which is created and returned using the Factory method is automatically executed by the Factory method. For ex.</span></div><pre class="brush: js">public class FactoryClass {
@Factory
public Object[] createTest(){
Object[] res = new Object[3];
for(int i=1;i<=3;i++){
res[i-1]=new main.java.FactoryImplementation(i);
}
return res;
}
}
public class FactoryImplementation {
int c_instance;
public FactoryImplementation(int instance){
this.c_instance=instance;
}
@Test
public void printMethod(){
System.out.println("Instance Num is "+ c_instance);
}
}
</pre><div><span class="Apple-style-span"><br />
</span></div><div><span class="Apple-style-span"><span class="Apple-style-span">Whenever you execute the above two classes together as a TestNg test, t</span><span class="Apple-style-span">he Output will be as follows:</span></span></div><div><span class="Apple-style-span">Instance Num is 1</span></div><div><span class="Apple-style-span">Instance Num is 2</span></div><div><span class="Apple-style-span">Instance Num is 3</span></div><div><span class="Apple-style-span"><br />
</span></div><div><span class="Apple-style-span">You only have to execute the Class named “FactoryClass”. Test-NG will find the Factory method inside it and will execute it. For each loop inside the Factory method an object of FactoryImplementation Class is created. On creation of the FactoryImplementation object and Instance value is set using the constructor. While creation of FactoryImplementation object the Test-NG automatically searches for all the “Test” methods inside the FactoryImplementation class and add them to its test execution list.</span></div><div><span class="Apple-style-span">Another thing for you to notice is that each object created have a unique “c_instance” value set while object creation and the same value is used in the “printMethod”.</span></div><div><span class="Apple-style-span"><br />
</span></div><div><span class="Apple-style-span">The Factory method can be used in different ways. One of the case may be when you want to execute a certain number of test inside a class for different values that can increase or decrease based on a condition.</span></div><div><span class="Apple-style-span">This can be achieved by creation of the object of test class based on the number of values.</span></div><div><span class="Apple-style-span">In the above class I am creating the object of the <b>FactoryImplementation</b> class inside a "for" loop. In a similar way you can iterate the for loop for number of different values for which the test needs to be run. And then initializing the test class object with such values and returning the Object array after storing them in the array. Something like the following:</span></div><pre class="brush: js">@Factory
public Object[] createInstance(){
ArrayList ar = new ArrayList< Object>();
Object[] res =null;
for(int i=1;i<=5;i++){
ar.add(new main.java.FactoryImplementation(i+10));
}
res= new Object[ar.size()];
res=ar.toArray();
return res;
}
</pre><div><span class="Apple-style-span" style="font-size: 13px; white-space: pre;"><br />
</span></div><span class="Apple-style-span">In the above method I am initializing the ArrayList which is dynamic in nature so depending on the no. of iterations I can increase the Array size and then store the same to the Object array and return it for execution.</span></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com4tag:blogger.com,1999:blog-1042251585556197079.post-11063089893498994692010-10-13T22:02:00.008+05:302011-07-26T08:14:24.710+05:30DataProvider in TestNG<div dir="ltr" style="text-align: left;" trbidi="on"><pre style="color: black; font-family: arial; font-family: courier new;"><span style="font-size: 85%;">
</span></pre><div style="font-family: arial; font-family: courier new; text-align: justify;"><span style="font-size: 85%;"><span style="color: black;">There are many functions provided by TestNG and you can use them in different ways one of them I will mention in this blog.</span><br />
</span></div><pre style="color: black; font-family: arial; font-family: courier new;"><span style="font-size: 85%;">
<span style="color: #000099;">@<span style="color: #990000;">DataProvider</span></span>
</span></pre><div style="font-family: arial; font-family: courier new; text-align: justify;"><span style="font-size: 85%;"><span style="color: black;">A DataProvider provide data to the function which depends on it. And whenever we define a DataProvider it should always return a double object array “Object[][]”. The function which calls dataprovider will be executed based on no. of array returned from the DataProvider. For ex.</span><br />
</span></div><pre class="brush: js">@Test(dataProvider="data")
public void printMethod(String s){
System.out.println(s);
}
@DataProvider(name="data")
public Object[][] dataProviderTest(){
return new Object[][]{{"Test Data 1"},{"Test Data 2"},{"Test Data 3"}};
}
</pre><pre style="font-family: 'courier new';"><span style="font-size: 85%;">
</span></pre><pre style="color: black; font-family: arial; font-family: courier new;"><span style="font-size: 85%;"><span style="color: black;">The Output will be:</span>
<span style="color: black;">Test Data 1</span>
<span style="color: black;">Test Data 2</span>
<span style="color: black;">Test Data 3</span>
</span></pre><div style="font-family: arial; font-family: courier new; text-align: justify;"><span style="color: black; font-size: 85%;">As you can see that the Test method “printMethod ” gets called 3 times depending upon the data that was provided by the DataProvider.<br />
</span><span style="font-size: 85%;"><span style="color: black;">The DataProvider can be used for getting data from some file or database according to test requirements.</span><br />
<br />
</span><span style="color: black; font-size: 85%;">Following I will mention two ways to use DataProvider:<br />
</span><span style="color: black; font-size: 85%;">For ex.<br />
</span><span style="color: black; font-size: 85%;">You need to get data from a file and print each line to the console. For doing that you had written some File Processing API that will return a List of the data read from file.<br />
</span><span style="color: black; font-size: 85%;">You can iterate on the List at the DataProvider level as well as at the test method level. Both I am mentioning below.<br />
</span></div><pre style="color: black; font-family: arial; font-family: courier new;"><span style="font-size: 85%;"><span style="color: black;">1.</span>
<pre class="brush: js">@DataProvider(name = "data")
public Object[][] init1() {
List list = fileObject.getData();
Object[][] result=new Object[list.size()][];
int i=0;
for(String s:list){
result[i]=new Object[]{new String(s)};
i++;
}
return result;
}
@Test(dataProvider="data")
public void runTest1(String s){
System.out.println("Data "+s);
}
</pre><string style="font-family: courier new;">
</string></span></pre><div style="font-family: arial; font-family: courier new; text-align: justify;"><span style="color: black; font-size: 85%;"><string>In this Implementation we are iterating over the List at the DataProvider level and storing it to another Object[][] result and returning the result.</string><br />
</span><span style="font-size: 85%;"><string face="courier new" style="color: black;">This implementation will call the test method depending upon the List size.</string><br />
</span><span style="font-size: 85%;"><string style="font-family: courier new;"></string></span></div><pre style="font-family: 'courier new';"><span style="font-size: 85%;"><string face="courier new">
2.<string><string>
</string></string></string></span></pre><pre class="brush: js">@DataProvider(name = "data")
public Object[][] init() {
List list = fileObject.getData();
return new Object[][]{{list}};
}
@Test(dataProvider="data")
public void runTest(List list){
for(String s:list){
System.out.println(“Data” + s);
}
}
</pre><div style="color: black; font-family: arial; font-family: courier new; text-align: justify;"><span style="font-size: 85%;"><string face="courier new"><string><string>In this Implementation we are returning the List itself to the test method and method will iterate over the List data. Both implementation can be used based upon test requirements.</string></string></string><br />
</span><span style="font-size: 85%;"><string face="courier new"><string><string></string></string></string><br />
</span><span style="font-size: 85%;"><string face="courier new"><string><string>Output of both the implementation shown above remains the same. The only thing that changes is the way you return the data and Iterate.</string></string></string><br />
</span><span style="font-size: 85%;"><string face="courier new"><string><string></string></string></string></span></div><pre style="color: black; font-family: arial; font-family: courier new;"><span style="font-size: 85%;"><string face="courier new"><string><string>
</string></string></string>
</span></pre></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com4tag:blogger.com,1999:blog-1042251585556197079.post-81922696915112349862010-06-17T17:38:00.005+05:302011-07-26T10:49:05.403+05:30Generating a Junit Report for TestNG execution<div dir="ltr" style="text-align: left;" trbidi="on"><span style="font-size: 100%;"><span style="font-family: verdana; font-size: 85%;">Now a days everyone is using TestNG in place of Junit and as part of Selenium execution.</span><span style="font-family: verdana; font-size: 85%;"><br />
<br />
TestNg provides a lot of added features. One of the good thing it provides is test execution results in the form of XML. We can use this XML file for other type of report format generation. One of them is Junit reporting.</span><span style="font-size: 85%;"><br />
<br />
</span><span style="font-family: verdana; font-size: 85%;">In this blog I will mention how to generate a Junit report for a TestNG execution.</span><span style="font-size: 85%;"><br />
</span><span style="font-family: verdana; font-size: 85%;">Below ant target will generate the Junit report for the TestNG execution results.</span><span style="font-size: 85%;"><br />
</span><span style="font-family: verdana;"></span></span><br />
<pre><span class="Apple-style-span" style="font-family: verdana;"><span class="Apple-style-span" style="font-size: 14px;">
</span></span></pre><pre class="brush: js"><target name="junit-report">
<delete dir="${REPORT}/Junit"></delete>
<mkdir dir="${REPORT}/Junit"></mkdir>
<junitreport todir="${REPORT}/Junit">
<fileset dir="${REPORT}/TestNG-report">
<include name="*/*.xml">
</include></fileset>
<report format="noframes" todir="${REPORT}/Junit">
</report>
</junitreport>
</target></pre><span style="font-size: 100%;"><span style="font-family: verdana;"><span style="font-size: 85%;"> In the above ant target you need to specify the path to the TestNG results xml file in the "dir" attribute under the "fileset" tag.<br />
<br />
You need to mention the path where you want to generate the Junit report in the "todir" attribute under the "report" tag.<br />
<br />
Also you can mention whether you want the Junit report with frames or without frames in the "format" attribute under the "report" tag.</span><br />
</span></span></div>Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com0tag:blogger.com,1999:blog-1042251585556197079.post-24774079172741342492010-05-13T14:31:00.013+05:302013-05-03T17:05:44.094+05:30Generating selenium reports using TestNG-xslt through Ant<div dir="ltr" style="text-align: left;" trbidi="on">
<span style="font-family: Verdana, sans-serif;">TestNG-xslt generates user friendly reports using the TestNG results output (testng-results.xml). Its uses the pure XSL for report generation and Saxon as an XSL2.0 implementation.<br />
<br />
Most of the material is taken from the original site.<br />
http://code.google.com/p/testng-xslt/</span><br />
<span style="font-family: Verdana, sans-serif;"><br /></span>
<span style="font-family: Verdana, sans-serif;"><a href="https://docs.google.com/file/d/0B3OQaZlrVrdJZUtSMWJseGVzVGs/edit?usp=sharing" target="_blank">Alternative link to download</a>. Please open the said link and download it by going to File -> Download option.<br />
<br />
I will tell in this blog how to implement this report for your project. This implementation will tell you how to generate the testng-xslt report using ant. If your current project does not use ant build then you can use ant only for the report generation purpose.<br />
<br />
If you dont know <span style="font-weight: bold;">ant </span>please check the Apache ant website http://ant.apache.org/.<br />
<br />
For generating testng-xslt report for your project do the following:<br />
1. Download the testng-xslt<br />
2. Unzip and copy the testng-results.xsl from the testng-xslt folder(testng-xslt-1.1\src\main\resources) to your own project folder.<br />
3. Now copy the saxon library from (testng-xslt-1.1\lib\saxon-8.7.jar)to your project lib folder.<br />
4. Modify your build.xml of ant and add the following target to it.<br />
<br />
</span><br />
<pre class="brush: xml"><project name="test" basedir=".">
<property name="LIB" value="${basedir}/libs" />
<property name="BIN" value="${basedir}/bin" />
<path id="master-classpath">
<pathelement location="${BIN}" />
<fileset dir="${LIB}">
<include name="**/*.jar" />
</fileset>
</path>
<target name="testng-xslt-report">
<delete dir="${basedir}/testng-xslt">
</delete>
<mkdir dir="${basedir}/testng-xslt">
</mkdir>
<xslt in="${basedir}/test-output/testng-results.xml" style="${basedir}/testng-results.xsl" out="${basedir}/testng-xslt/index.html">
<param expression="${basedir}/testng-xslt/" name="testNgXslt.outputDir" />
<param expression="true" name="testNgXslt.sortTestCaseLinks" />
<param expression="FAIL,SKIP,PASS,CONF,BY_CLASS" name="testNgXslt.testDetailsFilter" />
<param expression="true" name="testNgXslt.showRuntimeTotals" />
<classpath refid="master-classpath">
</classpath>
</xslt>
</target>
</project>
</pre>
<span style="font-family: Verdana, sans-serif;"><br />
<br />
The XSL transformation can be configured using the parameters described below.<br />
</span><br />
<ul>
<li><span style="font-family: Verdana, sans-serif;"><span style="font-weight: bold;">testNgXslt.outputDir</span> - Sets the target output directory for the HTML content. This is mandatory and must be an absolute path. If you are using the Maven plugin this is set automatically so you don't have to provide it.</span></li>
<li><span style="font-family: Verdana, sans-serif;"><span style="font-weight: bold;">testNgXslt.cssFile</span> - Specifies and alternative style sheet file overriding the default settings. This parameter is not required.</span></li>
<li><span style="font-family: Verdana, sans-serif;"><span style="font-weight: bold;">testNgXslt.showRuntimeTotals</span> - Boolean flag indicating if the report should display the aggregated information about the methods durations. The information is displayed for each test case and aggregated for the whole suite. Non-mandatory parameter, defaults to false.</span></li>
<li><span style="font-family: Verdana, sans-serif;"><span style="font-weight: bold;">testNgXslt.reportTitle</span> - Use this setting to specify a title for your HTML reports. This is not a mandatory parameter and defaults to "TestNG Results".</span></li>
<li><span style="font-family: Verdana, sans-serif;"><span style="font-weight: bold;">testNgXslt.sortTestCaseLinks </span>- Indicates whether the test case links (buttons) in the left frame should be sorted alphabetically. By default they are rendered in the order they are generated by TestNG so you should set this to true to change this behavior.</span></li>
<li><span style="font-family: Verdana, sans-serif;"><span style="font-weight: bold;">testNgXslt.chartScaleFactor</span> - A scale factor for the SVG pie chart in case you want it larger or smaller. Defaults to 1.</span></li>
<li><span style="font-family: Verdana, sans-serif;"><span style="font-weight: bold;">testNgXslt.testDetailsFilter </span>- Specified the default settings for the checkbox filters at the top of the test details page. Can be any combination (comma-separated) of: FAIL,PASS,SKIP,CONF,BY_CLASS </span></li>
</ul>
<span class="Apple-style-span" style="font-family: Verdana, sans-serif;">You need to provide the testng-xslt stylesheet the TestNG results xml(testng-results.xml) , the path to the style sheet testng-results.xsl and the output index.html path.<br />
<br />
Also dont forget to add the saxon library to your target classpath else you will get an error. In my case it is the master-classpath.<br />
<br />
Noe run the ant target for report generation (in my case "testng-xslt-report</span><span class="Apple-style-span" style="font-family: Verdana, sans-serif;">") and check the ouput folder configured by you for testng-xslt report.</span></div>
Varun Menonhttp://www.blogger.com/profile/13264248996322627285noreply@blogger.com150