Saturday, September 22, 2012

Dealing with web elements by different locators

Let’s consider the following sample HTML code snippet as a reference point.
  1. <!DOCTYPE HTML>
  2. <html>
  3.     <head>
  4.         <script type="text/javascript">
  5.             function jsFunction(){
  6.                 alert("Welcome to Selenium UI Automation Testing !");
  7.             }
  8.         </script>
  9.     </head>
  10.     <body>
  11.         <input type="submit" id="webButton" onclick="jsFunction()" value="Click It" />
  12.     <a href="http://aksahu.blogspot.in/">Go Home</a>
  13.     </body>
  14. </html>
Lets start by taking example of any of the selenium command say "click"
You can use same fashion for any of the selenium command like i am using for click.
The click command emulates a click operation for a link, button, checkbox or radio button. It takes a locator (an identifier for which HTML element the command refers to) as an argument.

Using Selectors with Click Command:

xpath

This allows clicking on an element using an XPath expression. Example

selenium.click("xpath=//input[@name=webButton' and @type='submit']");

css

CSS locator is used with Selenium commands to uniquely identify an object or element on a web page. Example,

selenium.click("css=input[name=webButton]”);

name

The name selector is used to click the first element with the specified @name attribute. Example,

selenium.click("name=webButton”);
or
selenium.click("webButton");

id

This allows click on an element with the specified @id attribute. Example,

selenium.click("id=webButton”);

link

This allows clicking on a link element which contains text matching the specified pattern. Example,

selenium.click("link=Go Home”);


Check if selenium server is running in background

When we run selenium RC test cases sometimes we faces this issue saying "java.net.BindException: Selenium is already running on port 4444. Or some other service is.
When you check the port 4444 no service is running. We change the port and run the program even that too is not working. 
In these cases we need to shutdown the selenium server on this port.
Use below command to shut down the server.

http://localhost:4444/selenium-server/driver/?cmd=shutDownSeleniumServer

If selenium server is already running on port 4444 then it will shut down the server and says
OKOK
if selenium is not running on this port 4444 then by hitting above url will give you 
"Unable to connect"
Now you can run your test cases i am sure will run smoothing.

You can also do an alternative way to handle this i.e you can and some code to check whether the selenium server in a specific port is running or not before starting the server like below:

//ServerControl.java
  1. package test.example;
  2. import java.net.HttpURLConnection;
  3. import java.net.URL;
  4. import org.openqa.selenium.server.RemoteControlConfiguration;
  5. import org.openqa.selenium.server.SeleniumServer;
  6. import org.testng.annotations.AfterClass;
  7. import org.testng.annotations.AfterSuite;
  8. import org.testng.annotations.BeforeClass;
  9. import org.testng.annotations.BeforeSuite;
  10. import com.thoughtworks.selenium.DefaultSelenium;
  11. import com.thoughtworks.selenium.Selenium;
  12. /**
  13.  * This class contains methods to control selenium server
  14.  *
  15.  * @author aksahu
  16.  */
  17. public class ServerControl {
  18.     protected Selenium selenium;
  19.     protected SeleniumServer seleniumServer;
  20.     private static String host = "localhost";
  21.     private static int port = 4444;
  22.     @BeforeSuite
  23.     public void startSeleniumServer() {
  24.         if (!isSeleniumServerRunning()) {
  25.             try {
  26.                 RemoteControlConfiguration rc = new RemoteControlConfiguration();
  27.                 seleniumServer = new SeleniumServer(rc);
  28.                 seleniumServer.start();
  29.             } catch (Exception e) {
  30.                 e.printStackTrace();
  31.             }
  32.         }
  33.     }
  34.     @BeforeClass
  35.     public void startSelenium() {
  36.         selenium = new DefaultSelenium("localhost"4444"*firefox""http://www.google.com");
  37.         selenium.start();
  38.         selenium.windowMaximize();
  39.     }
  40.    
  41.     @AfterClass
  42.     public void stopSelenium() {
  43.         selenium.stop();
  44.     }
  45.     @AfterSuite
  46.     public void stopSeleniumServer() throws Exception {
  47.         seleniumServer.stop();
  48.     }
  49.     /**
  50.      * Check whether the selenium server in the given port is running or not
  51.      * @return
  52.      */
  53.     public static boolean isSeleniumServerRunning() {
  54.         try {
  55.             String baseUrl = "http://" + host + ":" + port;
  56.             System.out.println("Checking selenium server status [" + baseUrl + "]");
  57.             URL url = new URL(baseUrl + "/selenium-server/driver/?cmd=testComplete");
  58.             HttpURLConnection connection = (HttpURLConnection) url.openConnection();
  59.             if (connection.getResponseCode() == HttpURLConnection.HTTP_OK)
  60.                 return true;
  61.         } catch (Exception e) {
  62.             System.err.println("Could not check selenium server status: " + e.getMessage());
  63.         }
  64.         return false;
  65.     }
  66. }

In the above the method isSeleniumServerRunning() returns a boolean value true if the server is running in the given port and host and returns false otherwise.

Saturday, July 14, 2012

Reading from properties file using Ant

Here is an example ant target which explains how to read from a properties file in ant.
//Build.xml
  1. <project name="Sample" default="delete-dir" basedir=".">
  2.     <!-- Read the properties file -->
  3.     <property file="config/config.properties" prefix="config"/>
  4.        
  5.     <!-- Using the property value(read from file) in ant's preperty attribute-->
  6.     <property name="build.loc" value="${config.build_dir_loc}" />
  7.    
  8.     <!-- Delete directories that are not needed -->
  9.     <target name="delete-dir" >
  10.         <delete dir="${build.loc}"/>
  11.         <echo> /* Directory deleted successfully ! */ </echo>
  12.     </target>
  13. </project>
In the above ant script the file from which we read data is 'config.properties' (present inside 'config' folder)which is shown below:
//config.properties
  1. username = aksahu
  2. password = aksahu123
  3. url = http://quickprotech.blogspot.in/
  4. port = 4444
  5. build_dir_loc = E:/temp/build

Saturday, April 07, 2012

Ant script for zipping report and sending mail

Below is the ant tasks showing how to zip reports generated after test run and sending the zip through mail.
//Build.xml
  1. <target name="sendMail" depends="junitreport,addZip">
  2.     <mail mailhost="smtp.gmail.com" mailport="465" user="my_user_name@gmail.com"
  3.         password="my_password" ssl="on" messagemimetype="text/html"
  4.         charset="ISO-8859-1" subject="Mail subject"
  5.         tolist="myfriend1@gmail.com,myfriend2@gmail.com">
  6.         <from address="my_user_name@gmail.com"/>
  7.         <message>
  8.             Please view index.html page for report in attached zip.
  9.         </message>
  10.         <fileset dir="${zip}"/>
  11.     </mail>
  12.     <echo> Mail is sent successfully </echo>
  13. </target>  
  14. <target name="addZip">
  15.     <zip destfile="${zip}/testReport.zip" duplicate="preserve">
  16.         <zipfileset dir="${reports.dir}" />
  17.     </zip>
  18.     <zip destfile="${zip}/logs.zip" duplicate="preserve">
  19.         <zipfileset dir="${log.dir}" />
  20.     </zip>
  21. </target>
In the above build file task 'addZip' ,it zips the all the reports that are in the ${reports.dir} and stores the content in a new zip file namely 'testReport.zip' inside ${zip} directory and also it zips all the logs generated in the ${log.dir} directory and stores in a new zip file namely logs.zip.

Then the 'sendMail' task sends these zip files as email attachment.
In the 'sendMail' target use your own valid credentials for login to mail server. Here i have used 
user id: my_user_name@gmail.com
password: my_password

Note:
 This task is specially for mail sending through gmail. You can change the attribute values for different mail servers as your requirement.

Sunday, March 25, 2012

Ant task/script for generating TestNg report

Here is an example explaining an ant task for generating TestNG report after execution of classes defined in TestNG xml file.
  1. <property name="src.dir" value="src" />
  2. <property name="lib.dir" value="lib" />
  3. <property name="log.dir" value="logs" />
  4. <property name="build.loc" value="build" />
  5. <property name="classes.dir" value="${build.loc}/classes" />
  6. <property name="reports.dir" value="${build.loc}/reports" />
  7. <property name="testNG.report" value="${reports.dir}/TestNG" />
  8. <property name="suite.dir" value="suite" />
  9. <!-- Class-Path -->
  10. <path id="classpath">
  11.     <pathelement location="${classes.dir}"/>
  12.     <fileset dir="${lib.dir}" includes="*.jar"/>
  13. </path>
  14. <!-- Delete directories that are not needed -->
  15. <target name="delete-dir" >
  16.         <delete dir="${build.loc}"/>
  17.         <echo> /* Deleted existing Compiled Directory Classes */ </echo>
  18. </target>
  19. <!-- Create Directories -->
  20. <target name="create-source-dir" depends="delete-dir">
  21.     <mkdir dir="${classes.dir}"/>
  22.     <mkdir dir="${testNG.report}"/>
  23.     <echo> /* Created Directories */ </echo>
  24. </target>
  25. <!-- Compiling Tests -->
  26. <target name="compile-classes" depends="create-source-dir">
  27.     <javac destdir="${classes.dir}" includeantruntime="false" debug="true" srcdir="${src.dir}">
  28.         <classpath refid="classpath"/>
  29.     </javac>
  30.     <echo> /* Compiled Directory Classes */ </echo>
  31. </target>
  32. <!-- Running Tests and TestNG report generation -->
  33. <target name="testNGreport" depends="compile-classes">
  34.     <taskdef resource="testngtasks" classpathref="classpath"/>
  35.     <testng classpathref="classpath" outputDir="${testNG.report}" haltOnfailure="true">
  36.           <xmlfileset dir="." includes="${suite.dir}/testng.xml" />
  37.     </testng>
  38.     <echo> /* Run Directory Classes */ </echo>
  39. </target>
By the above target 'testNGreport' you can load TestNG task in ant and execute you selenium tests. It is just that ant would access your testng.xml file to execute tests. This is same as how you be executing tests from with eclipse using TestNG - Eclipse plugin. 
Below is the testNG file that is used in the above build file.
//TestNG.xml
  1. <suite name="Suite1" verbose="1" >
  2.   <test name="Regression1">
  3.     <classes>
  4.       <class name="test.sample.ExampleTest1"/>
  5.       <class name="test.sample.ExampleTest2"/>
  6.     </classes>
  7.   </test>
  8. </suite>