Showing posts with label Scripting. Show all posts
Showing posts with label Scripting. Show all posts

Wednesday, February 28, 2018

Selenium Webdriver Scripts Using Jmeter

1.     Introduction

Modern day websites and the web applications are using and a lot of advanced features to make the client experience better and AJAX and JavaScript based logic plays a vital role in developing such features. Companies are also trying to make the websites prettier by using some cool graphics. However, this demands an increased level of processing at the browser end and using some rich graphic content that could make the application performing slowly if the enhanced features are not handled properly.

Most of the leading performance testing tools capture the response time on the protocol level which doesn’t include the client side rendering time. In addition, it requires advanced level of scripting skills in simulating AJAX calls using conventional load testing tool. Selenium webdriver scripts are a good choice to test the E2E performance of the web applications and to capture the response time inclusive of client-side rendering time.

To use Selenium Webdriver with Jmeter simply install the Webdriver set of plugins using the Plugins Manager which is available at https://jmeter-plugins.org/wiki/PluginsManager/

Simply follow the given steps:
-       Download the Plugins Manager JAR file
-       Put the file in the lib/ext directory
-       Restart JMeter
-       Click “Options” and then “Plugins Manager”



2.     Download Webdriver Plugins

Once you have “Plugins Manager” installed, you can simply go to available Plugins section and down download “Selenium/Webdriver Support” plugin. This will require a restart of Jmeter.

In the following diagram “Selenium/Webdriver Support” plugin is already downloaded and available under Available Plugins section.


After the Jmeter restart, you can find the “Webdriver Sampler” under the sampler section

 
 Webdriver set of plugins support Firefox browser out of the box. However, if you like to use Chrome or Internet Explorer then it will require some additional setup.

To use Chrome or Internet Explorer browser, simply download Chrome or IE driver using the below link and provide the path if the driver under the driver Config Element



Chrome driver config can be download from https://jmeter-plugins.org/wiki/ChromeDriverConfig/ and place the .exe file under the Bin folder of Jmeter or set the path of the EXE file under driver config.



We are ready to begin with the scripting now. All you need to add in your test plan is the Chrome Driver Config Element, Web Driver Sampler (Number of samplers depends on the testing needs), Cookie Manager, Cache Manager and View Results Tree.


3.     Webdriver Sampler Scripting

In this example, we are going to script a simple flow of opening the duckduckgo.com website, Searching Load testing Keyword and clicking on one the results link.
Here is the code you will require to do this:

//Common Code in all the Samplers

var pkg = JavaImporter(org.openqa.selenium); //Import Java Selenium Pacage
var support_ui = JavaImporter(org.openqa.selenium.support.ui.WebDriverWait); //WebDriver wait package classes
var wait = new support_ui.WebDriverWait(WDS.browser, 5000); //Wait 5 seconds until page loads

WDS.sampleResult.sampleStart(); //Sampler starting point
WDS.log.info("Sample started"); // This will log the information for us

// Transaction related code

WDS.sampleResult.sampleEnd();

//Transaction-1 Launch Website

WDS.browser.get('http://duckduckgo.com'); //opens website specified in 'http://duckduckgo.com'
WDS.log.info("navigated to duckduckgo.com");

//Transaction-2 Search Keyword

var searchField = WDS.browser.findElement(pkg.By.id('search_form_input_homepage')); //saves search field into searchField
searchField.click(); //clicks search field
searchField.sendKeys(['Load testing']); //types word "blazemeter" in field
WDS.log.info("Searched for Load testing");

var button = WDS.browser.findElement(pkg.By.id('search_button_homepage')); //Find Search button
button.click(); //Click Search Button
WDS.log.info("Clicked on the search button");

//Transaction-3 Open Link

var link = WDS.browser.findElement(pkg.By.id('r1-0')); // Clicks on the first link.
link.click(); //Click the search result's Link

var link = WDS.browser.findElement(pkg.By.id('firstHeading')); // wait for the page to be loaded

The script would look like this:



4.     Selenium IDE Chrome Extension Plugin

To use the selectors we can use the “Selenium IDE” Add-on, which is available at https://docs.seleniumhq.org/download/ . Selenium IDE is a Firefox add-on with a recording option for actions in the browser. To get similar selectors for other browsers, download and install the add-on.

In this example, I have downloaded the Selenium IDE extension for Chrome. Once it is successfully installed, you can see the icon in the browser



Open Duck Duck Go and Selenium IDE. Set the Selenium IDE’s base URL https://duckduckgo.com/ and start recording. Type “Load testing” and click Search open the link after that. If you open Selenium IDE, you see the captured actions and selectors.



All the captured actions can be manually converted to the webdriver format


Action and Command
Webdriver Code
Launch Website
Open
WDS.browser.get('http://duckduckgo.com');
Click at Search Box
Click at id= id=search_form_input_homepage
var searchField = WDS.browser.findElement(pkg.By.id('search_form_input_homepage'));
searchField.click();
Type Keyword
Type id=search_form_input_homepage
searchField.sendKeys(['Load testing']);
Click Search Button
Click at id= search_button_homepage
var button = WDS.browser.findElement(pkg.By.id('search_button_homepage'));
button.click();

Sunday, January 24, 2016

JavaScript: String And Math Functions

Introduction of JAVAScript as an alternate scripting languages in Loadrunner version 12.50  gives the flexibility to the Performance Test Engineers to leverage the capabilities of existing JAVAScript functions to code various custom logics. 

I am going to describe couple of pre built JAVAScript String and Math functions which will make your life bit easier. 
Date.js
Working with dates are always tricky. So many dots, slashes and formats. Datejs is a stunning library for simple to complex date functions. It can parse dates like: “Next thursday”, “+2 years” and all formats like 2009.01.08, 12/6/2001 etc.
Sylvester
This is a JavaScript library for doing vector and matrix math easily, without using a lot of loops and getting lost between arrays. It includes classes for modelling vectors and matrices in any number of dimensions and for modelling infinite lines and planes in 3D space.
Pretty Date 
A smart JavaScript solution for displaying dates within the past month in a prettier and more user-friendly way. It displays dates relative to the current time; for example, “Yesterday,” “3 hours ago,” etc.
Pretty Date
XRegExp
Regular expressions can be already used in JavaScript with the RegExp object.XRegExp adds more power to RegExp with features that will be part of the browsers of tomorrow (according to proposals for ECMAScript 4 – ES4). Using the library, RegExp objects can be cached and reused, modifiers can be added to existing RegExp objects and more.
JavaScript URL Library
A library for handling and manipulating URLs more easily. It is possible to reach every part of a URL as a string and modify it when needed. This URL library is very new but already works as mentioned.

Friday, October 31, 2014

Pre-requisite for SAP GUI Protocol scripting in Loadrunner

The fundamental requirement of Loadrunner to record and run SAP GUI scripts requires few settings at client and server side. Here are the main settings you need to incorporate:
1. Enable scripting at client side:
  • Install SAP GUI client on Vugen
  • To ensure that scripting is available on the client-end, check that there is a Scripting directory located in the SAP GUI installation directory.  If this directory does not exist, then the SAP Scripting API is not installed and you must reinstall SAP GUI with the SAP Scripting API option.
  • Once you have script SAP GUI complete package installed, configure all the required systems in SAP GUI, You will require the details of servers like server name, system number etc.
  • Ensure you have connectivity between SAP GUI and SAP server, if not then request for necessary ports to be opened.
  • You need to enable Scripting as circled in the red colour in the screen shot below and disable all check boxes as shown in the screen shot shown below. In order to do this, log on to SAP server, select the “Rainbow” Icon and select “Options”. And you must disable the remaining two check boxes
    - Notify When a Script attaches to a Running GUI
    - Notify When a Script Opens a Connection

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2. Enable scripting at server side:
  • Logon to SAP with a user with required privileges, User ID need to have proper privilege to enable scripting at server side. Basis should be able to provide you administrative privilege to do the same.
  • Logon to SAP using SAP GUI, run the transaction rz11, and enter parameter name sapgui/user_script.
  • Enable the parameter with the Current value changed to TRUE.  Save it and enable the changes on all the servers and scripting will be enabled the next time you log on.  

Thursday, September 6, 2012

Function to replace a string in Loadrunner

Here is one Function which we can use for Replace a string:

As you know there Is no inbuilt function is available in C to replace a string, but it can be done using a manual function and here is the function.

And there are lot of manual functions are available to replace a string, but those are all not work all the time in Loadrunner, if it runs also we will get some irrelevant output and errors.
That’s why The following code will work in all the conditions of the Loadrunner.
And it is more useful for those who are getting the response of special characters in Binary or hexadecimal form..

For example:
If you are getting a response of address like this “37\x20WALNUT\x20DRIVE\x2C\x20LARNE\x2C\x20BT40\x202WQ” and if you are passing this value as “37 WALNUT DRIVE, LARNE, BT40 2WQ” it is necessary to convert the all hexadecimal values into normal form, but if you know the real values of hexadecimal response like “\x20=  “ and “\x2C = ,” then you can replace the whole string with the new string.

And incase if you are getting the date as “2012\x2D02\x2D09” and the real date format you are passing is like “2012-02-09”, it is more headache to convert this date type with the normal C replace string functions in Loadrunner;
Because when you are doing with the C code, if you are assigning any values like “2012\x2D02\x2D09”  to a variable it will directly convert these hexadecimal value into “2012-02-09” without any replace function while assigning to a variable, But it will not happen with the Loadrunner response data, because the response will be stored in a register variable as a whole string format and if we assign this value to another variable also will not convert the string into normal form.

That’s why the Below function is very useful for those who wants to replace their hexadecimal response string to as they want.

Note:
This will Not work with normal ‘C-User’ Protocol But it will Work in ‘HTTP/HTML’ Protocol because here we are using a Web protocol function” web_conver_parm();”.
If you want to work this code in other protocols means some slight changes required.
And This Function can still Optimized depending on your need.

Here is the Function:

char *strReplace(const char *src, const char *from, const char *to) 
 { 
   char *value; 
   char *dst; 
   char *match; 
   int size; 
   int fromlen; 
   int tolen; 

   size = strlen(src) + 1; 
   fromlen = strlen(from); 
   tolen = strlen(to); 
    
   value = (char *)malloc(size); 
    
   dst = value; 
    
   if ( value != NULL ) 
   { 
     for ( ;; ) 
     { 
       match = (char *) strstr(src, from); 
       if ( match != NULL ) 
       { 
         size_t count = match - src; 
                                 char *temp; 
                                 size += tolen - fromlen; 
                                 temp = (char *)realloc(value, size); 
    
         if ( temp == NULL ) 
         { 
          free(value); 
           return NULL; 
         } 
    
         dst = temp + (dst - value); 
         value = temp; 
    
         memmove(dst, src, count); 
         src += count; 
         dst += count; 
    
         memmove(dst, to, tolen); 
         src += fromlen; 
         dst += tolen; 
       } 
       else
       { 
         strcpy(dst, src); 
         break; 
       } 
     }
   } 
   return value; 
 } 

 int lr_replace( const char *lrparam, char *findstr, char *replacestr ) 
 { 
   int res = 0; 
   char *result_str; 
   char lrp[1024]; 
    
   sprintf( lrp, "{%s}", lrparam); 
    
   result_str = strReplace( lr_eval_string(lrp), findstr, replacestr ); 
    
   if (result_str != NULL ) 
   { 
     lr_save_string( result_str, lrparam ); 
     free( result_str ); 
     res = 1; 
   } 
   return res; 
 }

Action()
{
                char *SetUpDt;
SetUpDt=lr_eval_string("{ParamSetUpDt}");
lr_output_message(" The Original String = %s", SetUpDt); 

lr_save_string(SetUpDt, "MyPar"); 
web_convert_param( "MyPar", 
                "SourceEncoding=PLAIN", 
                 "TargetEncoding=URL",
                LAST);

lr_output_message(" The Converted String = %s", lr_eval_string("{MyPar}")); 

lr_replace("MyPar", "%5Cx2D", "-" ); 

lr_output_message("The Replaced String = %s", lr_eval_string("{MyPar}"));

Return 0;
}

Output:
The original String =2012\x2D02\x2D09
The Converted String = 2011%5Cx2D04%5Cx2D11
The Replaced String = 2012-02-09

Friday, May 11, 2012

Base-64 encoding in loadrunner

During one of my project I observed that that the application is sending the query string (with dynamic values) in base-64 encoding format and Subsequent pages will be loaded based on this query string parameter values.
There are lots of applications exists which use some encryption/decryption technique to protect the data when send/receive over the network.
Base 60 encoding is one the the way to protect data over the network by encoding it in Base-64 from plain text and then decoding it from Base-64 to plain text.

Base-64 encoding converts plain text into Base-64 converted data

//Plain Text
action=INIT&state=Bank_Transfer&RefNumber=198518Routing_Numberr=172118
//Base-64 encoded data
YWN0aW9uPUlOSVQmc3RhdGU9QmFua19UcmFuc2ZlciZSZWZOdW1iZXI9MTk4NTE4Um91dG
luZ19OdW1iZXJyPTE3MjExOA==

In the Script you will see the data going in request in encoded form but this data can't be find in the previous steps response.
Here we can see in generation log and can figure it out that data is being converted into Base-64 by some technique or function.
Below request shows data (highlighted in Red) is going in encoded form

    web_submit_data("saveParams.jsp",
        "Action=http://www.WebServer.com/saveParams.jsp",
        "Method=POST",
        "TargetFrame=",
        "RecContentType=text/html",
        "Referer=http://www.WebServer.com/Example.do",
        "Snapshot=t24.inf",
        "Mode=HTML",
        ITEMDATA,
        "Name=params", "Value=
YWN0aW9uPUlOSVQmc3RhdGU9QmFua19UcmFuc2ZlciZSZWZOdW1iZXI9MTk4NTE4Um91dG
luZ19OdW1iZXJyPTE3MjExOA==
", ENDITEM,
        LAST);

Use the following steps to get this dynamic data

1. Decode this data and see what exact plain text is being sent to the server
For decoding you can use http://www.rbl.jp/base64.php 
in my example i decoded my encoded string and got the below plain text code

 action=INIT&state=Bank_Transfer&RefNumber=198518&Routing_Numberr=172118

2. Based on this we can generate the query string and then passing this query string to the Base-64 converter function can get the encode dstring.

Place the below functions in globals.h

#ifndef _GLOBALS_H
#define _GLOBALS_H

//--------------------------------------------------------------------
// Include Files
#include "lrun.h"
#include "web_api.h"
#include "lrw_custom_body.h"

//--------------------------------------------------------------------
// Global Variables
//Converting in Base-64 encoding

char *convert( char *src)
{
    int dest_size; 
    char *deststr;     
    // Allocate dest buffer 
     dest_size = 1 + ((strlen(src)+2)/3*4); 
     deststr = (char *)malloc(dest_size); 
     memset(deststr,0,dest_size); 
    base64encode(src, deststr, dest_size); 
     return deststr; 
}

void base64encode(char *src, char *dest, int len) 

// Encodes a buffer to base64 

 { 
 char base64encode_lut[] = { 
 'A','B','C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q', 
 'R','S','T','U','V','W','X','Y','Z','a','b','c','d','e','f','g','h', 
 'i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y', 
 'z','0','1','2','3','4','5','6','7','8','9','+','/','='}; 

   int i=0, slen=strlen(src); 

   for(i=0;i<slen && i<len;i+=3,src+=3) 
   { // Enc next 4 characters 
     *(dest++)=base64encode_lut[(*src&0xFC)>>0x2]; 
     *(dest++)=base64encode_lut[(*src&0x3)<<0x4|(*(src+1)&0xF0)>>0x4]; 
     *(dest++)=((i+1)<slen)?base64encode_lut[(*(src+1)&0xF)<<0x2|(*(src+2)&0xC0)>>0x6]:'='; 
     *(dest++)=((i+2)<slen)?base64encode_lut[*(src+2)&0x3F]:'='; 
   } 
   *dest='\0'; // Append terminator
    }

//Preparing the query string & passing to base-64 encoding

char *getParam(char *str, char *param1, char *param2)
{
    char *temp;
    char *src, *target;
    char param[2000];

    temp="";
    src="";
    target="";
    temp=str;
    strcpy(param,"");
    strcat(param,temp);

    strcat(param,"&RefNumber=");    strcat(param,param2);
    strcat(param,param1);
    strcat(param,"&Routing_Numberr="); 
    strcat(param, param2);

    src=(char *) param;
    target=convert(src);

    return target;
}
Call the function in the script as given below, This will prepare the query string as well as convert it into base-64

    lr_save_string( getParam("action=INIT&state=Bank_Transfer",
    lr_eval_string("{Ref_Number_Val}"),
    lr_eval_string("{Routing_Number_Val}")),
        "param" );

    web_submit_data("saveParams.jsp",
        "Action=http://www.WebServer.com/saveParams.jsp",
        "Method=POST",
        "TargetFrame=",
        "RecContentType=text/html",
        "Referer=http://www.WebServer.com/Example.do",
        "Snapshot=t24.inf",
        "Mode=HTML",
        ITEMDATA,
        "Name=params", "Value={param}
", ENDITEM,
        LAST);


// Note: Values for Ref_Number_Val and Routing_Number_Val will vary in each iteration and with the data.