Protected by Copyscape
Powered By Blogger

Saturday, January 25, 2020

How to send an email using Javaxmail API in Selenium Webdriver?

Sending an email is an important activity as we always try to run the automation test suite during non-business hours.  We will get the test updates on email like Test has been completed or not, how many test cases have been passed, failed or skipped. So, all such information we can get very easily if you integrate the below code in your framework. The below code will give you the guidance that how you can send an email after completion of your test execution using Selenium API.

The very first thing that we should know about the Server & Port details. In case of Gmail the following details will be used.

Key
Value
mail.smtp.host
smtp.gmail.com
mail.smtp.socketFactory.port
465
mail.smtp.socketFactory.class
javax.net.ssl.SSLSocketFactory
mail.smtp.auth
true
mail.smtp.port
465

I have to pass the server details in Key, Value pairs using Properties object like below

public static Properties property;
property=new Properties();
property.put("mail.smtp.host","smtp.gmail.com");
property.put("mail.smtp.socketFactory.port", "465");
property.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
property.put("mail.smtp.auth","true");
property.put("mail.smtp.port", "465");


To support this we should have "javax.mail-api-1.6.2" jar file which can be downloaded from https://mvnrepository.com/artifact/javax.mail/javax.mail-api

Now, import this Jar file in your code and write the below code:



import java.util.Properties;

import javax.mail.BodyPart;
import javax.mail.Message;
import javax.mail.MessagingException;
import javax.mail.Multipart;
import javax.mail.PasswordAuthentication;
import javax.mail.Session;
import javax.mail.Transport;
import javax.mail.internet.InternetAddress;
import javax.mail.internet.MimeBodyPart;
import javax.mail.internet.MimeMessage;
import javax.mail.internet.MimeMultipart;

public class SendingReport {

public static Properties property;
public static Session session;


public static void setConnection()
{
property=new Properties();
property.put("mail.smtp.host","smtp.gmail.com");
property.put("mail.smtp.socketFactory.port", "465");
property.put("mail.smtp.socketFactory.class", "javax.net.ssl.SSLSocketFactory");
property.put("mail.smtp.auth","true");
property.put("mail.smtp.port", "465");
}


public static void CreateAuthenticSessions(String UserName, String Password)
{
               session=Session.getDefaultInstance(property, new javax.mail.Authenticator() {
protected PasswordAuthentication getPasswordAuthentication()
{
return new PasswordAuthentication(UserName,Password);
}});
}

public static void ComposeMessage(String strMsgTxt, String strRecepient_Email_Id) throws MessagingException
{
InternetAddress receientAddress=new InternetAddress(strRecepient_Email_Id);
Message msg=new MimeMessage(session);
msg.setFrom(receientAddress);
msg.setRecipients(Message.RecipientType.TO, receientAddress.parse(strRecepient_Email_Id));
msg.setSubject("This is my first email");


BodyPart msgBody=new MimeBodyPart();
msgBody.setText(strMsgTxt);

Multipart multi=new MimeMultipart();
multi.addBodyPart(msgBody);

msg.setContent(multi);

Transport.send(msg);

System.out.println("Mail sent succussfully");
}

public static void main(String[] args) throws MessagingException
{
setConnection();
CreateAuthenticSessions("Enter User Name", "Enter Password");

ComposeMessage("My First Email message","vikas_9264@yahoo.co.in");


}

}

The first time when you execute the above code then you will get the following exception:

Exception in thread "main" java.lang.NoClassDefFoundError: com/sun/mail/util/MailLogger
at javax.mail.Session.initLogger(Session.java:283)
at javax.mail.Session.<init>(Session.java:268)
at javax.mail.Session.getDefaultInstance(Session.java:378)
at SendingReport.CreateAuthenticSessions(SendingReport.java:34)
at SendingReport.main(SendingReport.java:60)
Caused by: java.lang.ClassNotFoundException: com.sun.mail.util.MailLogger
at java.net.URLClassLoader.findClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
at sun.misc.Launcher$AppClassLoader.loadClass(Unknown Source)
at java.lang.ClassLoader.loadClass(Unknown Source)
... 5 more


To avoid the above exception then import this jar file "javax.mail-1.6.2". Download this jar from here https://mvnrepository.com/artifact/javax.mail/javax.mail-api/1.6.2


Now, when you run the code you will get rid from the above exception. Google has implemented security that no third party application can access your account for sending an email. You will get the below email in your gmail inbox:

Someone just used your password to try to sign in to your account from a non-Google app. Google blocked them, but you should check what happened. Review your account activity to make sure that no one else has access.

So, you have to change some security settings for your gmail account in order to work this code. I did change the status from Off to On for "Less Secure app access" settings in Gmail (https://myaccount.google.com/lesssecureapps). 

Now it's working for me. See the below output.







How we can keep track of execution with the help of execution logs in Selenium Test?

As I have explained that how we can get the data from property files and the same process is applied here as well but the way is little bit different. To achieve this follow the below steps:


  • Create a blank file under project like "AppLogs.txt"
  • Create a log4j.properties file and place the below code in it which defines the display format of the log file.
            log4j.rootLogger=INFO,Appender
            log4j.appender.Appender=org.apache.log4j.FileAppender
            log4j.appender.Appender.File=./Application Logs/AppLogs.txt
            log4j.appender.Appender.layout=org.apache.log4j.PatternLayout
            log4j.appender.Appender.layout.conversionPattern=%-7p %d [%t] %C %X -%m%n
            log4j.appender.File.maxFileSize=500KB
            log4j.appender.File.MaxBackupIndex=3
            log4j.appender.Appender.Append=false
                 public Logger log=Logger.getLogger(NewTest.class.getName());
  • Pass the reference of the log4j.properties file where the format of execution logs are given.
                     PropertyConfigurator.configure("./PropertyFIle/log4j.properties");


    Below code will show you how to write the logs.

    import java.io.FileInputStream;
    import java.io.IOException;
    import java.util.Properties;

    import org.apache.log4j.Logger;
    import org.apache.log4j.PropertyConfigurator;
    import org.testng.annotations.Test;

    public class NewTest 

    {
    public Properties configProp;
    public FileInputStream file;
    public Logger log=Logger.getLogger(NewTest.class.getName());
      @Test
      public void FetchData() throws IOException
      {
      
      PropertyConfigurator.configure("./PropertyFIle/log4j.properties");
      file=new FileInputStream("./PropertyFIle/Config.properties");
      
      configProp=new Properties();
      configProp.load(file);
      
      
      System.out.println("Value of Browser key is :"+ configProp.getProperty("Browser"));
      log.info("Chrome browser launched");
      System.out.println("Value of URL key is :"+ configProp.getProperty("URL"));
      log.info("URL opened");
      System.out.println("Value of Implicitwait key is :"+ configProp.getProperty("ImplicitWaitTime"));
      log.info("Implicitwait time implemented throughout the script");
      
      
      }
    }

    Output

    [RemoteTestNG] detected TestNG version 7.0.0
    Value of Browser key is :Chrome
    Value of URL key is :https://www.goggle.co.in
    Value of Implicitwait key is :20
    PASSED: FetchData

    ===============================================
        Default test
        Tests run: 1, Failures: 0, Skips: 0
    ===============================================


    ===============================================
    Default suite
    Total tests run: 1, Passes: 1, Failures: 0, Skips: 0

    ===============================================


    Output of log file which is AppLogs.txt




    Tuesday, January 21, 2020

    Why we should use property file in TestNG framework? How to use it?

    When you write a code with Selenium API then there are several places where you use the same value. For example you have "Delhi" as a value for "Place" variable in 10 different test cases and now you have to change the value of "Place" variable from "Delhi" to "Gurgaon" in all 10 test cases. To do the same you have to open each test case and make that required change and the same process will go on if some different value is required in future. So, to ease this work we can use Property file where you need to make a change at a single place only and the changes will reflect in each test case where we are calling that property file. Mainly, we use property file for configuration settings for your entire project like on which browser your code should be executed, how much synchronization wait time is required like below:

    #Confing file
    URL=https://www.goggle.co.in
    Browser=Chrome
    ImplicitWaitTime=20
    ExplicitWaitTime=20


    How to use it?
    • Create one Java project and then TestNG class under that project. I have already explained this process in my previous posts.
    • Create one folder with any name under project. In my case I have created folder 'PropertyFIles'.



    •  



      • Now Create a file under newly created folder i.e. "Config.properties" and place the below content in it. We store data in property file in "key=value" pair. To comment a line in property file we use "#" symbol.
                #Confing file
                  URL=https://www.goggle.co.in
                  Browser=Chrome
                  ImplicitWaitTime=20
                  ExplicitWaitTime=20









      • Let's see that how we can use this property file in TestNG framework.
        • Import this Jar in your TestNG Project "import java.util.Properties;"'
        • Create an object of "Properties" class i.e "public Properties configProp;"
        • To load that property file we have to create an object of "FileInputStream" class and for this we have to import Jar i.e. "import java.io.FileInputStream;".
      Look at the below code and their output after execution where I am extracting the values from the Property file.

      import java.io.FileInputStream;
      import java.io.IOException;
      import java.util.Properties;

      import org.testng.annotations.Test;

      public class NewTest

      {
      public Properties configProp;
      public FileInputStream file;

        @Test
        public void FetchData() throws IOException
        {
        file=new FileInputStream("./PropertyFIle/Config.properties");
        configProp=new Properties();
        configProp.load(file);

        System.out.println("Value of Browser key is :"+ configProp.getProperty("Browser"));
        System.out.println("Value of URL key is :"+ configProp.getProperty("URL"));
        System.out.println("Value of Implicitwait key is :"+ configProp.getProperty("ImplicitWaitTime"));
        }
      }

      Output

      [RemoteTestNG] detected TestNG version 7.0.0
      Value of Browser key is :Chrome
      Value of URL key is :https://www.goggle.co.in
      Value of Implicitwait key is :20
      PASSED: FetchData

      ===============================================
          Default test
          Tests run: 1, Failures: 0, Skips: 0
      ===============================================


      ===============================================
      Default suite
      Total tests run: 1, Passes: 1, Failures: 0, Skips: 0
      ===============================================


      Please comment if you have any doubts in it.

      Best of Luck!

      Sunday, January 19, 2020

      What is Authentication and Authorization in Rest Services? How you would be able to execute it using Selenium?

      This is very basic thing that in a corporate environment when you are dealing with Web Services then there would be some restriction over it like the same that you can not do login in your Gmail account without user name and password, which we call it Authentication.

      There can be a multiple types of login credentials for example Basic Access and Paid Access. Here,  with Basis Access means that you can do login into your account but you would be having very limited access over it. To get the full access of the web resources you have to buy a Premium access or paid access. So, this we call it Authorization.

      How you will be dealing with such Rest Services where you should have valid login credentials to access its services? 

      Below code will help you to provide the solution. 

      import io.restassured.RestAssured;
      import io.restassured.response.Response;
      import io.restassured.specification.RequestSpecification;

      public class Auth {

      public static void main(String[] args) {
      RestAssured.baseURI="Enter URI of any web service where Authentication is applied" ;
      RequestSpecification req=RestAssured.given();
      Response re=req.get();
      String txt=re.body().asString();
      System.out.println(txt);
      System.out.println(re.getStatusLine());
      }

      }


      Output of the above code if we don't have valid credentials to access the resources of the Web Service.

      {
          "StatusID": "FAULT_USER_INVALID_USER_PASSWORD",
          "Status": "Invalid or expired Authentication key provided"
      }
      HTTP/1.1 401 Unauthorized


      If you add only one more line in the above code with valid login credentials then your probelm will get resolved.

      req.auth().preemptive().basic("Enter UserName", "Enter Password").when();


      Now the final code would be


      import io.restassured.RestAssured;
      import io.restassured.response.Response;
      import io.restassured.specification.RequestSpecification;

      public class Auth {

      public static void main(String[] args) {
      RestAssured.baseURI="Enter URI of any web service where Authentication is applied" ;
      RequestSpecification req=RestAssured.given();
      req.auth().preemptive().basic("Enter UserName", "Enter Password").when();
      Response re=req.get();
      String txt=re.body().asString();
      System.out.println(txt);
      System.out.println(re.getStatusLine());
      }

      }

      After execution of the above code see the output below:


      {
          "SuccessCode": "OPERATION_SUCCESS",
          "Message": "Operation completed successfully",
          "Username:Password": "User Name:Password",
          "Authentication Type": "Basic"
      }
      HTTP/1.1 200 OK



      To practice the above code look for the sample web services on google where authentication is required. I hope now you would be able to get the way that how you can access the web service where Authentication parameters need to be provided to access its resources.

      If you come across with any doubt then please comment and I will try to revert at the earliest.

      Best of Luck!
       




      Friday, January 17, 2020

      How to clear temporary files using VBS

      On Error Resume Next

      Dim objWsh

      Set objWsh=CreateObject("WScript.Shell")
      objWsh.Run "RunDll32.exe InetCpl.Cpl,ClearMyTracksByProcess 8"

      Set objWsh=Nothing


      Please save this code in notepad with .vbs extension and save under the available drive in your system and then access the saved file and then it will clear all the temporary files.

      How to count number of used rows in Excel without opening it?

      The below code will demonstrate how to count number of used rows in Excel without opening it - using vbscipt in QTP.


      Set objXls=CreateObject("Excel.Application")

      Set objWB=objXls.WorkBooks.Open("C:\a.xls")

      Set objSheet=objWB.WorkSheets(1)

      MsgBox objSheet.UsedRange.Rows.Count

      Set objXls=Nothing

      How to get the names of the sub-folders and sub-files with in a folder?

      We can achieve this through recursion(a function can call itself) as we don't know the depth of the main folder means we don't know how many sub-folders and files exists in a single folder but the below code will help us to resolve this.

      Dim objTxt
      Set objTxt=CreateObject("Scripting.FileSystemObject")

      Sub showSubFolder(Folder)
        For Each subfolder in Folder.SubFolders
        MsgBox "The path of the child folder is :"& subFolder.Path
        Set objFolder=objTxt.GetFolder(subfolder.Path)
         Set colFiles=objFolder.Files
         For Each objfiles in colFiles
           MsgBox objfiles.Name
         Next
         showSubFolder subfolder
       Next
      End Sub


      Call showSubFolders(objTxt.GetFolder("c:/abc"))


      set objTxt=Nothing

      How to count number of files in a folder?

      Assume there is a folder named 'abc' in C drive and we need to get the count of all the files with in the folder

      Dim objFso

      Set objFso=CreateObject("Scripting.FileSystemObject")
      Set Folder=objFso.GetFolder("C:/abc")
      Set NoOfFiles=Folder.Files
      Msgbox NoOfFiles.count

      Set objFso=Nothing

      How to identify an Object or Element using XPATH in Selenium?

      In my previous post, I have explained what other ways we have to identify a web element in selenium except XPATH and CSS Selectors.

      In above line I was referring to the below post.

      https://stapleautomationsolutions.blogspot.com/2020/01/how-to-identify-element-in-selenium_9.html


      In Automation, Identification of an object is an essential thing and without this automation is not possible. When you open any web page and you see whatever displayed on that page we call that Web Element or Object. For each web element or object there are some properties and methods are associated with it.

      For Example: Write the below code in notepad and save it with .html extension. After saving the file open the same in any browser like Chrome or IE.

      <Html>
        <Head>
          <Title>Welcome to StapleAutomationSolutions.com"</Title>
        </Head>
        <Body>
             Enter User Name <Input type="text" name="t1"><Br>
             Enter Password<Input type="text" name="t2"><Br>
             <Input type="button" name="b1" value="click">
      </Body>
      </Html>


      Output of the above code in browser is below:




      Now, I explain the above html code, I have created 2 Web Edit boxes like text boxes using <Input> tag. These 2 text boxes have some attributes (attributes means properties of that object) like "type" and "name" and their values. So, when you use Xpath to identify any web element using their attribute or property to identify it then we put @ symbol before the attribute or property name like @type or @name to uniquely identify an object.

      There are 2 types of Xpath syntax available:

      1. Absolute XPath

      This is the way to locate an element or object directly, but the drawback of the absolute XPath is that if there are any changes made in the path of the element then that XPath will get fail. Absolute XPath  begins with the single forward slash(/) ,which means you can select the element from the root node.

      Below is the Absolute XPath for Search text box on Google.com.

      /html/body/div/div[4]/form/div[2]/div[1]/div[1]/div/div[2]/input

      2. Relative XPath

      //input[@type='text']
      or
      //*[@type='text']

      When I use the above Xpath to inspect that element in chrome browser then it shows 2 matching elements found as per the description of the object given in the above XPath syntax. Look at the below snapshot.







      The reason is that the value of 'type' attribute is same for both the input boxes i.e. type="text". So, now we have look for some unique attribute or property so that we can identify that object uniquely. Now I use the below Xpath and the problem will get resolved as it will identify only one object now. See the below snapshot.


      //*[@name="t1"]





      You can also use multiple attributes while using XPath using logical operators like "or" & "and"

      //*[@name='t1' or @type='text']

      if you use the above XPath syntax then also it will identify both the objects as we are using logical "or" operator. The reason is that for both the input boxes have same value defined for type attribute i.e. "text". See the below snapshot.





      To avoid such issues in this present scenario we should use logical "and" operator to uniquely identify an object. Look at the syntax and snapshot.

      //*[@name='t1' and @type='text']







      But Sometimes you will come across a situation where no attributes or properties provided for an object then how will you identify an object. Look at the below HTML Code where I have removed the attributes for the input tag.


      <Html>
        <Head>
          <Title>Welcome to StapleAutomationSolutions.com"</Title>
        </Head>
        <Body>
            <lable> Enter User Name </lable><Input><Br>
             <label>Enter Password</label><Input><Br>
             <Input type="button" name="b1" value="click">
      </Body>
      </Html>


      So, in this case we will use some methods and XPath Axes to achieve the objective of object identification.

      Contains()- This method we can use in Xpath syntax when any dynamic changes are there in the attribute value or no attribute value given like below where I am going to give the reference of neighboring element to identify an object. In this Contains() method i am giving the Partial Label name i.e. "User" instead of "Enter User Name".

      //*[contains(text(),'User')]//following::input[1]




           
      Text()- If  I use this text() method in XPath expression then I have to use the complete label name or text instead of Partial Label name or text like in case of Contain() method.

      //*[text()=' Enter User Name ']//following::input[1]






             

      Starts-With()- When there is a scenario that the first few characters are same and rest all are dynamic(means changes at run time) for an attribute value. So, we can use Starts-with() method in XPath syntax like below.

      //*[starts-with(text(),' Enter')]//following::input[1]





      The Xpath Axes are as follows:


      ancestor
      Selects all ancestors (parent, grandparent, etc.) of the current node
      ancestor-or-self
      Selects all ancestors (parent, grandparent, etc.) of the current node and the current node itself
      attribute
      Selects all attributes of the current node
      child
      Selects all children of the current node
      descendant
      Selects all descendants (children, grandchildren, etc.) of the current node
      descendant-or-self
      Selects all descendants (children, grandchildren, etc.) of the current node and the current node itself
      following
      Selects everything in the document after the closing tag of the current node
      following-sibling
      Selects all siblings after the current node
      namespace
      Selects all namespace nodes of the current node
      parent
      Selects the parent of the current node
      preceding
      Selects all nodes that appear before the current node in the document, except ancestors, attribute nodes and namespace nodes
      preceding-sibling
      Selects all siblings before the current node
      ancestor
      Selects all ancestors (parent, grandparent, etc.) of the current node
      ancestor-or-self
      Selects all ancestors (parent, grandparent, etc.) of the current node and the current node itself
      attribute
      Selects all attributes of the current node





      Please comment if you have any doubt or issues while doing the same.

      Best of Luck!

      Thursday, January 16, 2020

      How you can make your first TestNG project in Selenium?

      The code which I have written so far, in my previous tutorials, all were in main() function from where the java execution starts. Through Selenium Web Driver we can automate browsers but web driver does not provide any inbuilt reporting feature. So, with TestNG framework we can generate test reports in good format.

      To start with TestNG Framework you have to perform the following steps:

      First, create the new Java project i.e. 'FirstTestNGProject' in eclipse like below.








      Now right click on src folder and select "New" option from the menu and click "Other". Find the below snapshot.




      Choose TestNG class like in the below snapshot



      If you are new to TestNG and not used earlier so might be you would not be able to see this TestNG as an option in your eclipse like in the above snapshot. So, you need to download the TestNG framework in your eclipse in order to get this option available for you. So, to download this you have to go to the Help Menu and select Eclipse Marketplace. See the below snapshot.







      Then search for TestNG and install it in your eclipse. In my case, it's already installed that is why it is showing Installed in the below snapshot.





      After installing this you will get the desired option to create a new TestNG class in eclipse. NOw after selecting the TestNG option we have to provide the source, package and name of the testNG class like below and click on Finish.





      The one last task is to add the TestNG library in your project to support all the features provided by TestNG framework. You can not proceed with this framework without adding this library. Please do the following steps which I am going to show in the form of snapshots for more clarity.
















      After click on "Next" button then click on "Apply and Close" button. Now you are done with this setup and start writing code like the below example which I have already given in my previous post.


      package Test;

      import org.testng.annotations.AfterTest;
      import org.testng.annotations.BeforeTest;
      import org.testng.annotations.Test;

      public class FirstTestNG {
        @BeforeTest
        public void makeDataBaseConnection()
        {
        System.out.println("Database connection established successfully");
        }
        @AfterTest
        public void closeDataBaseConnection()
        {
        System.out.println("Database connection closed successfully");
        }
        
        @Test(priority=1)
        public void doLogin()
        {
        System.out.println("Login done successfully");
        }
        
        @Test(priority=2)
        public void ValidateNewEmployeeData()
        {
        System.out.println("New Employee's data validated successfully");
        }
        
        @Test(priority=3)
        public void ValidateExistingEmployeeData()
        {
        System.out.println("Existing Employee's data validated successfully");
        }
        
        

      }


      *********************************************************************************

      Please comment if you have any issues or queries come up on your ways while doing this.

      Best of Luck!

      What is TestNG? Why & how we can use it with Selenium?

      TestNG stands for "Test Next Generation". TestNG is a framework which was designed by Cedric Beust and it covers all types of testing like Unit, Integration, functional and end to end testing.

      In real time scenario if you have to automate 10 business scenarios then might be you would have the following expectations:

      1. Test Framework should be user friendly and easy to understand.
      2. We should have the facility of grouping of the test cases like for Smoke and Regression Testing.
      3. We should get to know instantly that how many test cases passed or failed or skipped.
      4. We should have the provision to execute the failed test cases separately.
      5. We should have something that at same time we can run our test cases on multiple browsers i.e. Parallel testing.
      6. After completion of the execution test report should be generated in an interactive format which can be used to showcase the execution of test report.

      All of the above expectations we can achieve by using TestNG framework. In TestNG framework, there is no main method instead we use below annotations which defines the flow of execution. We always put '@' symbol before any TestNG annotation.

      Please find below annotations along with description which we implement while using TestNG framework.

      @BeforeSuite: The annotated method will be run before all tests in this suite have run.
      @AfterSuite: The annotated method will be run after all tests in this suite have run.
      @BeforeTest: The annotated method will be run before any test method belonging to the classes inside the <test> tag is run.
      @AfterTest: The annotated method will be run after all the test methods belonging to the classes inside the <test> tag have run.
      @BeforeGroups: The list of groups that this configuration method will run before. This method is guaranteed to run shortly before the first test method that belongs to any of these groups is invoked.
      @AfterGroups: The list of groups that this configuration method will run after. This method is guaranteed to run shortly after the last test method that belongs to any of these groups is invoked.
      @BeforeClass: The annotated method will be run before the first test method in the current class is invoked.
      @AfterClass: The annotated method will be run after all the test methods in the current class have been run.
      @BeforeMethod: The annotated method will be run before each test method.
      @AfterMethod: The annotated method will be run after each test method.
      @DataProvider: Marks a method as supplying data for a test method. The annotated method must return an Object[][] where each Object[] can be assigned the parameter list of the test method. The @Test method that wants to receive data from this DataProvider needs to use a dataProvider name equals to the name of this annotation.
      @Factory: Marks a method as a factory that returns objects that will be used by TestNG as Test classes. The method must return Object[].
      @Listeners: Define listeners on a test class.
      @Parameters: Define how to pass parameters to a @Test method.
      @Test: Marks a class or a method as part of the test.


      @Test is the most commonly used annotation as through this you define your each test case. Without this annotation your program will not run. Other annotations are equally important and gradually you will get to know about the use of it.

      I am taking one scenario so that you can understand when you should use which annotation. There is a website which contains employee data like employee's id, salary, position, age etc. We have to validate that we should do login in to the application, enter new employee data and validate that employee data has stored in the database successfully and check the existing employee data and then do log-off from the application. This scenario contains mainly 3 below flows
      • Launch employee web site in any browser and do login.
      • Enter new Employee data and validate
      • Fetch existing employee data and validate.
      Above each flow we can count as a test case where we can use @Test annotation. But before execution of the above 3 test cases we have to make sure that database connection should get established first and after execution of the 3 test cases we have to close the data base connection. To achieve this task we will use @BeforeTest @AfterTest annotations. 

      See the below example.

      package Test;

      import org.testng.annotations.AfterTest;
      import org.testng.annotations.BeforeTest;
      import org.testng.annotations.Test;

      public class FirstTestNG 
      {
        @BeforeTest
        public void makeDataBaseConnection()
        {
        System.out.println("Database connection established successfully");
        }
        @AfterTest
        public void closeDataBaseConnection()
        {
        System.out.println("Database connection closed successfully");
        }
        
        @Test(priority=1)
        public void doLogin()
        {
        System.out.println("Login done successfully");
        }
        
        @Test(priority=2)
        public void ValidateNewEmployeeData()
        {
        System.out.println("New Employee's data validated successfully");
        }
        
        @Test(priority=3)
        public void ValidateExistingEmployeeData()
        {
        System.out.println("Existing Employee's data validated successfully");
        }
      }


      Below is the output of the above code after execution and do notice that in outcome database connection established before execution of any test case and closed after done the execution of all the test cases are over.
      *********************************************************************************

      [RemoteTestNG] detected TestNG version 6.14.3
      Database connection established successfully
      Login done successfully
      New Employee's data validated successfully
      Existing Employee's data validated successfully
      Database connection closed successfully
      PASSED: doLogin
      PASSED: ValidateNewEmployeeData
      PASSED: ValidateExistingEmployeeData

      ===============================================
          Default test
          Tests run: 3, Failures: 0, Skips: 0
      ===============================================


      ===============================================
      Default suite
      Total tests run: 3, Failures: 0, Skips: 0
      ===============================================

      *********************************************************************************


      While using annotations we use pre-defined parameters like in the above example I have used 'priority' as a parameter, which tells that which @Test method will be executed first and lowest priority value will be executed first like @Test(priority=1) will be executed first and then so on. Execution done will be based on the alphabetic order if we don't define the priority of the @Test method. Now, I am removing the priority parameter from my test and then see the outcome:

      *********************************************************************************

      [RemoteTestNG] detected TestNG version 6.14.3
      Database connection established successfully
      Existing Employee's data validated successfully
      New Employee's data validated successfully
      Login done successfully
      Database connection closed successfully
      PASSED: ValidateExistingEmployeeData
      PASSED: ValidateNewEmployeeData
      PASSED: doLogin

      ===============================================
          Default test
          Tests run: 3, Failures: 0, Skips: 0
      ===============================================


      ===============================================
      Default suite
      Total tests run: 3, Failures: 0, Skips: 0
      ===============================================

      *********************************************************************************

      Wednesday, January 15, 2020

      What are the ways to validate the response body of Rest APIs using RestAssured?

      Generally, we use below 2 ways to validate the response body of any RestAPI using RestAssured.
      • Using Contains method of Collection class.
      • Using JsonPath
      If  I take the previous example from my post where I showed the use of HTTP GET method for extraction of weather information. Please use the below example

      import io.restassured.RestAssured;
      import io.restassured.http.Header;
      import io.restassured.http.Headers;
      import io.restassured.response.Response;
      import io.restassured.specification.RequestSpecification;

      public class RestGet
      {
      public static void main(String args[])
      {
      RestAssured.baseURI="http://restapi.demoqa.com/utilities/weather/city";
      RequestSpecification req=RestAssured.given();
      Response res=req.get("/Noida");

      System.out.println(res.body().asString());
      }

      }

      The output of the above code is as below where we are getting the weather information for Noida.

      {
          "City": "Noida",
          "Temperature": "10 Degree celsius",
          "Humidity": "100 Percent",
          "WeatherDescription": "mist",
          "WindSpeed": "2.57 Km per hour",
          "WindDirectionDegree": "343 Degree"
      }

      Now we have to validate that whether "Noida" as a text available in the response or not. So, if i go with the 1st way then we have to include the follwing line in the above java code, which return a boolean value like True or False.

      System.out.println(res.getBody().asString().contains("Noida"));

      If I add the above line in the code then the output would be 

      {
          "City": "Noida",
          "Temperature": "10 Degree celsius",
          "Humidity": "100 Percent",
          "WeatherDescription": "mist",
          "WindSpeed": "1.96 Km per hour",
          "WindDirectionDegree": "342 Degree"
      }
      true 


      But what happens if you want to extract the individual value in {key,value} pair from response code then we can use the 2nd way i.e. JsonPath.  Also, need to import the below Jar file.

      import io.restassured.path.json.JsonPath;

      Find the below code for the same.

      import io.restassured.RestAssured;
      import io.restassured.path.json.JsonPath;
      import io.restassured.response.Response;
      import io.restassured.specification.RequestSpecification;

      public class Rest1
      {
      public static void main(String args[])
      {
      RestAssured.baseURI="http://restapi.demoqa.com/utilities/weather/city";
      RequestSpecification req=RestAssured.given();
      Response res=req.get("/Noida");

      System.out.println(res.body().asString());
      JsonPath j=res.jsonPath();
      System.out.println("City value is :"+j.get("City").toString());
      System.out.println("Temperature is :"+j.get("Temperature").toString());
      if(j.get("City").equals("Noida"))
      {
      System.out.println("Test case passed");
      }
      else
      {
      System.out.println("Test case failed");
      }
      }

      }


      Output for the above code:

      {
          "City": "Noida",
          "Temperature": "9 Degree celsius",
          "Humidity": "100 Percent",
          "WeatherDescription": "mist",
          "WindSpeed": "1.96 Km per hour",
          "WindDirectionDegree": "342 Degree"
      }
      City value is :Noida
      Temperature is :9 Degree celsius
      Test case passed


      '**********************************************************************

      Please comment if you have any questions on this.

      Best Of Luck!