Tuesday 25 December 2018

New Selenium IDE supports Chrome & more features


       Selenium Integrated Development Environment best known as Selenium IDE, is the simplest and easiest tool in whole Selenium suite to install and get introduce to selenium environment for the beginners. This was initially released as a Firefox add-on that creates tests quickly through record-and-playback functionality. This was even being used by the Selenium advanced users to identify the objects on a page using locator techniques such as xpath, css, id etc. After the recent changes in Firefox browser, Selenium IDE has stopped working for a while now.

But Selenium team has just released new Selenium IDE. 

Let’s discuss the new features of latest Selenium IDE in this post.

    1. Built as Web Extension & Chrome Support:
The latest Selenium IDE is built as a web extension. Because of this, now we have  Selenium IDE support for chrome browser as well. The Sideex open source project was used as a base to build this IDE.
    Installation in chrome:
a.   Open this in your chrome browser and click on “Add to Chrome”


b.   Once you add it, you can seeicon on top of your browser, beside the address bar.
c.   If you click on the icon, Selenium IDE would open up as a popup,

d.   You can start using it, by clicking on “Record a new test in a project” and naming it.
    Installation in firefox:
a.   Open this in your firefox browser and click on “Add to Firefox”
b.   Once you add it, you can see  icon on top of your browser, beside the address bar.
          c. Other steps are same as above.

2. Improved locators:
 Now selenium IDE supports auto populated, improved, multiple fallback locators. Once you record any test, select a step where you want to change the object locator. Then click on the “Target” drop down. You can see multiple options like css, xpaths, name, id etc.

     3. Conditional & Control flows:
The latest Selenium IDE supports Conditional flows by using if, elseif, repeatif commands. With these commands, we can specify the conditions to make our recorded script more intelligent.
                        
IDE also supports control flow using while command. A condition can be specified to execute a specific step repeatedly.

4. In-built implicit wait:
Selenium IDE will now automatically wait for every command, every command will wait for the page to load. Commands which take a locator will wait for the element to appear. This way we no need to use explicit waits.

5. Adding assertion and verifications while recording itself:
Now users can add assertions and verifications in tests by using the context menu on the page. Once the page gets launched from IDE, select the element that needs to add as assertion. Now right click on that element. You can see a context menu, with multiple options.

    
6. Running in CI:
We can execute the selenium IDE scripts in CI now. If you click on 3 dots next to save icon in selenium IDE, you can see an option called “Running in CI”. Clicking on this option takes you to here. This page has very clear explanation on how to execute these .side scripts though CI. We can also use selenium server to run the tests in remote machines.


According to Webdriver creator Simon Stewart, below features are in pipeline for Selenium IDE team.

1. Exporting Selenium IDE Scripts to Programming languages (Java/JUnit/Python/PHP):
    Exporting the .side Scripts to programming languages is not supported yet in the latest IDE. But this will be supported in future starting with Java.

2. Data driven Testing:
    Even the old IDE was not supporting data driven testing. But it is being considered in the latest IDE. We may see this feature as well in future.

Thursday 6 December 2018

Useful tricks and tips for working with POSTMAN


      Postman is a powerful graphical HTTP client helpful when working with APIs. In our day to day work, we use postman for our REST Service tests a lot. In this post I am going to discuss about few tips and tricks while using postman.

1. Variables:
    We can use variables to replace certain fields such as the URL, URL parameters, headers, authorization, request body, and header presets etc. in postman. These variable names are enclosed with double curly braces – like {{variable name}}. Postman uses string substitution to replace the current value of this variable.


There are multiple ways to initialize, retrieve, and define the scope of these variables. Below is the practical usage of this feature.

How I used variables:
    The most annoying problem we face in our everyday usage of postman is, updating the Auth token. As the auth token has limited validity, we have to replace the token every time when it gets expired. This hack helps the users to include this token generation in the run time, so that we don't need to update every time.

    First, we need to add the below script under "Pre-request Script" tab. (The Pre-request Script is a tab where one can write javascript code to hit any endpoint and extract data from a response to use this data in a subsequent request. So, if you include any script in this tab, this will be executed even before making your REST Call. Thus it initializes & loads the variable even before making your actual Call.)


const echoPostRequest = {
  url: 'http://ur.access.token.endpoint',
  method: '<GET or POST>',
  header: 'Content-Type:application/json'
};

var getToken = true;
console.log(pm.sendRequest);

if (getToken === true) {
    pm.sendRequest(echoPostRequest, function (err, res) {
        console.log(err ? err : res.json());
        if (!err) {
            pm.globals.set("token", res.json()["<field name of the response where your token is stored>"]);
        }
    });
}


In the above script, we are storing the token value in the variable called “token”. Now we use this variable in the header as the value of “Authorization” like below (You may be using different key for authorization. Use the same key here).


That's it. Now you can run this collection, whenever you want without worrying about replacing latest token.

2. Dynamic Variables:
     Postman has a few dynamic variables you can use in your requests. We can use them in the request builder as unique IDs, timestamps, or random integers. The syntax will be {{$timestamp}}. Below are those variables and their purposes.

{{$guid}} : Adds a v4 style guid
{{$timestamp}} : Adds the current timestamp
{{$randomInt}} : Adds a random integer between 0 and 1000


3. Data Variables:
   Data variables are available when using a data file with the collection runner. You can import the data as a CSV or JSON file, and then use the values from the data file inside HTTP requests and scripts. Here's an example of Inside pre-request and test scripts. Let's say you have the pm.iterationData.get("username") method inside pre-request and test scripts. The method would let you access the value of the username variable from a data file.


You can get more details on how to use data variables from the below link


Friday 6 April 2018

Webservices Automation Framework

Today, a faster test cycle at lower cost is vital to stay competitive. Re-usable test automation frameworks coupled with open source tools and technologies is a key solution to shrink test cycle time and related costs. Here I have come up with a very robust Automation framework for automating RESTful webservices. I used Rest-Assured to build this framework. Below is the link to it:  https://github.com/nainappa/ConfianceAPIAutomationFramework

Thursday 22 March 2018

Replace Jenkins Logo and Text of your choice in JenkinsUI

Often times we have several Jenkins CI Servers and we always get confused to determine them. Some times we may need to change the Logo and text to customize Jenkins UI to reflect your organization details. This post helps to you to change the header and Logo on your Jenkins UI.

Custom styling can be applied via modification of the CSS structure being used by Jenkins.
Simple Theme Plugin is the most popular approach to customizing CSS outputs.

Below are the steps to customize your Logo and Header Text:
  • Install Simple Theme Plugin
  • Go to the <JENKINS_HOME>/userContent directory in your jenkins host machine.
  • Create the layout directory
  • Create the style.css file, copy the contents provided below.
  • Customize the “Sample Project” text
  • Put the logo of your instance to <JENKINS_HOME>/userContent/layout/logo.png. The logo should have 40px height.
  • Go to the global configuration of your CJP instance and find the Theme section there (Manage Jenkins--> Configure System)
  • In URL of Theme CSS specify the following path: <JENKINS_HOME>/userContent/layout/logo.png eg:http://localhost:8080/userContent/layout/logo.png

Below is the css code to be used. Make sure you make the required changes as mentioned above.

/* Custom style for Autobahn Jenkins Platform */
.logo img {
  content:url("<JENKINS_HOME>/userContent/layout/logo.jpg");
  /*change the path to your logo path*/
}

#jenkins-name-icon {
  display: none;
}


.logo:after {
content: 'Sample Project';
font-weight: bold;
font-size: 40px;
font-family:"Brush Script MT", cursive;
margin-left: 200px;
margin-right: 12px;
color: Aqua;
line-height: 40px;
}

Sunday 7 January 2018

Collections In-depth : Part 2: How Hash Map works internally?

HashMap works on the principle of Hashing. To understand Hashing, we should understand three terms.They are Hash Function , Hash Value and Bucket.

Hash Function , Hash Value and Bucket:
    When we try to add any value to the hashmap, Java internally calls this hashfunction in order to get unique integer value. This function generates the unique integer value based on the key that we pass. That Value is called as hash value. In java, every object has a method "public int hashcode()" which returns a hash value for a given object.

A bucket is used to store key value pairs. A bucket can have multiple key-value pairs. In hash map, bucket uses simple linked list to store objects.

When we create a hash map, it creates array of nodes. Each node contains hash code, key, value and next  node's reference as shown in the above picture.

Lets jump into its internal working mechanism. We will start will PUT.

PUT Functionality:

Lets consider we are storing the below values into hash map using PUT functionality.  

                   
marks.put("Ram", 100);
marks.put("Ravi", 89);
marks.put("Rajesh", 70);
marks.put("Ramesh", 99);
  
As we discussed earlier the hash map comprises of the table. The initial size of the table would be 0-15 slots.


Now lets see how we can fit our values into this table.


When we add "marks.put("Ram", 100);" entry to the map, Java internally calls hash function in order  to get hashcode.


put(K k,V v)
hash(k)
index=hash&(n-1)

In our case, hash code will be calculated for "Ram" which is our key. Based on the returned hash code, index will be calculated as shown in the above method. Lets consider index as 4. So, our key value pair will be stored in that table as a node with key, value, hash code and next node reference. If you observe here, our next node reference is null. We will discuss about it later.

Lets consider that index for the next entry is 3 and stored as shown in below.

For now all the entries has unique hash code and unique index value. What will happen, if hash() function returns the same value for two different entries. We call this scenario as hash collision.

Lets see, how hash map deals this situation.

For that consider, 3rd entry in our map has got the same hashcode and index as our first entry. In this case, our new entry would also be stored in index 4, but as a linked list of node as shown below.

As you see in the above picture, first entry got the reference of 3rd entry as its next node. So, when there is a collision in hash code, those entries would be stored as linked list of nodes. This is how we avoid hash collision.

Note: In Java hash map allows null keys and it is always stored index 0 as hash of null is 0.

GET Functionality:

V get(Object key)
hash(key)
index=hash&(n-1)

For GET functionality also, java performs the same kind of operations.

Lets get the first entry in our hash map. When we try to get the value for "Ram" (which is the key for our first entry), it finds the hash of the key, and will compute the index. It returns the index 4. Now will look up index 4 in the table. We have an entry there. At this point, it compares the hashcode returned in our GET functionality and the hashcode stored in that node. Both will match. After this, it also compares the Key that we are sending for GET functionality and Key stored in our node by using equals() method. Both will match. So, it returns the value 100 which is stored in the node.

Now lets try to get our 3rd entry value which is little complicated. When we pass "Rajesh"(our 3rd entry's key), it calculates both the hash code and index returned as 4. We will go to index 4. The first node in index 4 is "Ram". It will try to compare both the hashcode and key of the node. They will not match. But by using the reference of the next node, it will go to next node and try to compare both hashcode and key. So, it returns value 70, which is stored in the second node of that index.

The hashmap implementation provides constant time performance for (get and put) basic operations i.e the complexity of get() and put() is O(1) , assuming the hash function disperses the elements properly among the buckets.