Web application automation using Ginger

Web application automation using Ginger

In this article, I will introduce the concept of codeless automation as an innovative and efficient solution for software testing with minimal coding. Performs to increase the importance of time-to-market in product success, codeless automation helps to reduce testing time in release cycles, making it a growing trend in software testing.

One of the most notable codeless automation frameworks is Ginger, an open-source tool created and published by Amdocs under an Apache 2.0 license.

Advantages of codeless automation over traditional code-based automation:

  • No programming skills are required
  • Test automation can start from day 1
  • Keep pace with the development cycle
  • Faster and more efficient test development

Ginger is a free and open-source automation framework with the following features:

  • AI-driven automation
  • Supports various platforms such as web, mobile, windows, APIs, etc.
  • Simple drag-and-drop approach for codeless automation
  • Dynamic Error handling with self-healing capabilities
  • Ability to reuse existing automation scripts
  • Reduced average repair time
  • Software reusability across the software lifecycle
  • Automates visual validations
  • Built-in integrations with popular open-source tools such as QC, Jira, CI/CD, Jenkins, Bambootools, and others.

Similarly, we will expand the Ginger to investigate and create a web application automation script:

Where can you find Ginger?

You need to Visit “ginger.amdocs.com” and download the latest version of the tool. Below you can see the dashboard.

How do you set up Ginger?

Once the Ginger is downloaded, now double-click on the application file, and a license agreement window will be displayed – select ‘I accept the agreement’, browse the destination location where you want it installed, and click on ‘Next’.

Now, select the default user type and terminology, and then click ‘Install’.

After successfully installing the application. Now, click on the created shortcut to access the Ginger homepage.

Your first Project in Ginger

Here, we will perform Web application automation using Ginger, let’s create a solution for the same. A solution in Ginger is a logical structure with complete automation-related files and only one solution can be loaded at a time. However, multiple target applications can be added to the same solution.

Click on ‘Create a new solution

  • ‘Add Solution’ window
  • Enter the solution name
  • Browse the location to be stored
  • Select the ‘main application platform (‘web’)
  •  Enter the ‘solution password encryption key’
  •  Click on the ‘Create’ button

The following diagram depicts the ‘Business Flow,’ which is an end-to-end (start-to-finish) logical flow of the project/business.

So, now the folder structure is automatically created. Once the project solution is created.

Here, multiple target applications can be added to the same solution.

Go to the ‘Configurations’ tab

  • Click on ‘add (+)’ button
  • Select the desired application from the window displayed

Accordingly, the target applications have been merged into the solution:

Go to the ‘Business Flows’ tab

  • Click on the ‘Edit’ tab
  •  Select the desired application in the solution

Configure the agent

Agents are the platform where the scripts will run. First, you select the driver type where you want to launch the application and click the ‘Agents’ tab.

Now, navigate to the ‘Resources’ tab and create an environment for the desired application. An environment stores application-related data such as login credentials, server connection information, and automation flow. One should use environment variables as much as possible to store any configurations that may change per environment.

Given that you have created a new environment, it will ask whether you want to share it with all or a subgroup of the target applications created under business flow.

Given that you have created a new environment, it will ask whether you want to share it with all or a subgroup of the target applications created under business flow. Therefore, you can also create a new environment by cloning one that already exists.

You can also create a new environment by cloning one that already exists.

Now, click on the environment created

  • A list of target applications assigned to this environment is displayed
  • Select the desired application and it will open displaying three environment-specific tabs:  Parameters, Databases, and Login Users.

Add a new Activity

Basically, you need to navigate to Business Flows and add a new activity. These activities are a collection of actions required to complete a function or intended task.

For example:

The user successfully logged in using valid credentials. Here logging in with valid credentials is a functional activity that can be completed using a set of actions.

Under this activity, multiple actions can be created. You can click on the ‘Automate’ tab in the top right corner of the page and add automation actions from the ‘Action Library’ in the toggle panel. Now on the top bar, the target application configured agent, and environment that you have chosen for the current business flow is displayed.

Essentially, the actions library is divided into four categories: plugin actions, legacy actions, platform actions, and general actions.

In the below image, a ‘Bowser Action’ is added, and double-click it to add a value, i.e. to add various operation settings.

This image has an empty alt attribute; its file name is image-13.png

First, go to Expression settings, navigate to the desired folder structure, and enter the URL value, which can be parameterized in the environment.

Now let’s add actions to the activity

We’ve launched the website in the driver; now we’ll locate the elements and log in with the appropriate credentials.

After that Select ‘UI Element Action’ from the Action Library in the toggle panel and provide details about the element to be located.

First of all, I am using orange HRM demo website ( https://opensource-demo.orangehrmlive.com )

So, the element ‘Username’ is located using XPath to perform send keys operation.

The following shows the configuration for locating a button and clicking on it for successful login.

Because the configuration shown in the following figures is used to verify the element that appears on the page is successful login.

Variables – To validate the text retrieved after login, go to the expression editor and add the activity variable.

A variety of variables can be included, such as –

  • ‘Variable String’ – To verify a string on the page
  • ‘Variable Random Number’ – To verify a number randomly generated every time within a given range
  • ‘Variable List’ – To verify a variable from a list specified
  • ‘Variable Number’ – To generate a random number between the given   minimum and maximum range of number
  • ‘Variable Password String’ – To encrypt the entered password
  • ‘Variable Sequence’ – To give minimum and maximum range of numbers with a specified interval
  • ‘Variable Timer’ – To use as a timer

Similarly, other actions, as shown in the figure below, are added to browse other tabs.

From the ‘Execution Report’ tab, screenshot capture and log details can be enabled.

So here, all the actions of the test scenario are completed, Now click the ‘Run Activity’ button located at the top of the page.

Following is the execution, you can check the output values under ‘Actual Value’ and ‘Expected Value,’ as shown below.

The following image shows the execution in progress

The actual below image shows the execution is completed.

Adding run set

The Run Set is a real-time dashboard with a single complete end-to-end project flow comprised of various activities. It displays the entire Business flow, including actions, activities added and executed, and steps passed, pending, failed, or blocked.

First, you need to Set up the ‘Run Sets’ by adding the desired Business Flow and to start the execution, click on the runner tab button.

Also, you can get a complete execution history:

  • Navigate to ‘Run Sets
  • Executions History’ tab

Following are the Execution Results shown in the output of the execution.

Execution Report

The following section shows a failed scenario.

  • To start, we need to create a new Run Set.
  • Then add a new runner set, go to the ‘Run Sets’ tab, and click the ‘+’ button.

Now, Click on the ‘+’ button to add a Business flow to the runner.

After adding the business flow, you can see the number of activities and actions in the run set.

So, to run the run set, click the ‘run button’ shown in the image below.

Now, the execution is seen in progress

Here, the runner display number of failed actions, and clicking on the ‘Generate Run Set Report option’, will create a detailed execution report.

The following shows the execution report of the failed test scenario.

Formation of the Execution Reports displays a detailed execution that includes. The following information is an action name, and action type, So now execution – start, duration, and end time, number of retry iterations, status (passed/failed), Error details, and screenshots.

Therefore, we have completed Web application automation using Ginger successfully. Happy Testing!!

Conclusion: –

Ginger strikes me as a simple and modern automation tool that can be used to create test cases in natural language, making it a valuable platform for continuous testing, regression testing, and progressive testing.

Read more blogs here

XPath for Selenium, Playwright & Cypress Web Automation Testing

XPath for Selenium, Playwright & Cypress Web Automation Testing

For any web automation testing, the one and most important task is to identify and use robust locators to identify web elements so that your automated tests do not fail with “Unable to locate element”. In this article, we are providing you with the techniques that every tester should learn to create those robust locators. As we already know this can be done using different locator strategies. In this blog, we are going to learn about XPath. Before we dive into the topic of our discussion let’s just get more familiar with Xpaths. Let’s start with, 

What is XPath?

XPath (XML Path Language) is an expression language that allows the processing of values conforming to the data model defined in the XQuery and XPath Data models. Basically, it is a query language that we use to locate or find an element present on the webpage. It is defined by the World Wide Consortium (W3C). Now, let’s discuss why Xpaths are necessary.

Why is XPaths necessary?

Xpaths are the most widely used locators in automation though there are other locators like id, name, class name, tag name, and so on. Also, it is used when there are no unique attributes available to locate the web element. It allows identification with the help of the visible test present on the screen with the help of Xpath function text().

Before explaining the importance of XPath let’s just go through the different types of locators available for automation testing. 

In this blog, we will learn about the different types of Xpaths and how to implement them so that we can locate our web elements quickly using the selenium web driver. Basically, there are two types of Xpaths

1. Absolute XPath:

In this type, The XPath starts from the beginning or from the root node of the HTML DOM structure. It is a direct way to locate or find the web element but the disadvantage of absolute XPath is that as we are creating it from the start of the HTML DOM structure if there are any changes introduced in the created path of the web element then it gets failed. In this type of locator, we only use tags or nodes. The main advantage of this is that we can select a web element from the root node as it starts with the single forward slash “ / ”.

Example:

Here is an example of an absolute Xpath for an input field box. 

 example of an absolute Xpath for an input field box. 

The absolute XPath is: /html[1]/body[1]/div[1]/div[1]/div[1]/div[1]/div[1]/div[2]/div[2]/form[1]/div[1]/div[1]/div[2]/input[1]

2. Relative Xpath:

Compared to an absolute XPath the relative XPath does not start from the beginning of the HTML DOM structure. It starts from where the element is present e.g. from the middle of the HTML DOM structure if the element is located there. We don’t have to travel from the start of the HTML DOM structure. The relative Xpath starts with a double forward slash “ // “ and it can locate and search the web element anywhere on the webpage. Relative XPath directly jumps to elements on DOM. The other difference between absolute and relative XPath is that in absolute XPath we use tags or nodes but in relative XPath we use attributes. 

Example:

We are writing the relative XPath for the same input field for which earlier we created an absolute XPath. 

We are writing the relative XPath for the same input field for which earlier we created an absolute XPath.

Relative XPath is: 

//input[@name=’username’]

XPath Functions: 

Types of Xpath Functions

It is not always possible to locate a web element using relative XPath that is because at some times while locating a particular web element there is the possibility of elements that have similar properties, for example, the same id, name, or same class name. So, here the basic XPath won’t work efficiently for finding that web element. Xpath functions are used to write the efficient XPath by locating a web element with a unique value. Basically, there are three types of XPath functions as follows,

a. starts-with() Function:

starts-with() function is very useful in locating dynamic web elements. It is used to find the element in which the attribute value starts with some particular character or text. 

While working on the dynamic web page the starts-with function plays an important role. We can use it to match the starting value of a web element that remains static. 

It can also locate the web element whose attribute value is static.

Syntax:

Xpath = //tagname[starts-wtih(@attribute,’value’)]

Example:

//input[starts-with(@name,’username’)]

start-with() function is very useful in locating dynamic web elements. 

b. contains() Function:
  • Just like the start-with() function explained above, the contains() function is also used to create a unique expression to locate a web element. 
  • It is used when if a part of the value of an attribute changes dynamically the function can navigate to the web element with the partial text present. 
  • We can provide any partial attribute value to locate the web element.
  • It accepts two parameters the first one is the attribute of the tag must validate to locate the web element and the second one is the value of an attribute is a partial value that the attribute must contain. 
Syntax: 

Xpath = //tagname[contains(@attribute,’value’)]

Example:

//input[contains(@name,’username’)]

 Xpath contains() Function:
c. text() Function:

text() Function:

  • The text() function is used to locate web elements with exact text matches.
  • The function only works if the element contains the text. 
  • This method returns the text of the web element when identified by the tag name and compared it with the value provided on the right side. 
Syntax:

Xpath = //tagname[text()=’Actual text present’]

Example:

   //button[text()=’ Login ‘]

 Xpath text() Function:

How to use AND & OR in XPath:

AND & OR expressions can also be used in selenium Xpath expressions. Very useful if you want to use more than two attributes to find elements on a webpage. 

The OR expression requires two conditions and it will check whether the first condition in the statement is true if so then it will locate that web element and if not then it will go for the second condition and if that is true then also it will locate that web element. So, here the point we should remember is that when we are using the OR expression at least either of two of the conditions should be true then, and then only it will find and locate that web element. 

Syntax:

Xpath = //tagname[@attribute=’Value’ or @attribute=’Value’]

Example:

//input[@name=’username’ or @placeholder=’xyz’]     

Here the first condition is true and the second one is false still the web element got located. 

How to use AND & OR in Xpath

Just like the OR expression the AND expression also requires two conditions but the catch here is that both the provided condition must be true then and then only the web element will get located. If either of the conditions is false then it will not locate that web element. 

Syntax:

Xpath = //tagname[@attribute=’Value’ and @attribute=’Value’]

Example:

//input[@name=’username’ and @placeholder=’Username’]

In this case, both the condition provided for an AND expression is true hence the web element got located.

XPath Axis:

XPath Axis

It is a method to identify those dynamic elements that are impossible to find by normal XPath methods. All the elements are in a hierarchical structure and can be either located using absolute or relative Xpaths but it provides specific attributes called XPath axis to locate those elements with unique XPath expressions. The axes show a relationship to the current node and help locate the relative nodes concerning the tree’s current node. The dynamic elements are those elements on the webpage whose attributes dynamically change on refresh or any other operations. The HTML DOM structure contains one or more element nodes and they are known as trees of nodes. If an element contains the content, whether it is other elements or text, it must be declared with a start tag and an end tag. The text defined between the start tag and the end tag is the element content. 

Types of XPath Axis: 

XPath Axis selenium web driver

1. Parent Axis XPath:

With the help of the parent axis XPath, we can select the parent of the current node. Here, the parent node can be either a root node or an element node. The point to consider here is that for all the other element nodes the maximum node the parent axis contains is one. Also, the root node of the HTML DOM structure has no parent hence the parent axis is empty when the current node is the root node. 

Syntax:

Xpath = //tagname[@attribute=’value’]//parent::parent_tagname

Example:

//input[@name=’username’]//parent::div

This Screenshot is about Parent Axis Xpath

2. Child Axis XPath:

As we have seen using the parent axis XPath actually we are creating an XPath by the following bottom-up approach but here in the child axis case, we are going to follow the top-down approach to create an XPath. The child axis selects all the child elements present under the current node. We can easily locate a web element as a child of the current node. 

Syntax:

Xpath = //tagname[@attribute=’value’]//child::child_tagname

Example:

//div[@class=’oxd-form-actions orangehrm-login-action’]//child::button

The child axis selects all the child elements present under the current node. We can easily locate a web element as a child of the current node. 

3. Self Axix XPath:

This type of XPath uses its own current node and selects the web element belonging to that current node. You will always observe only one node that represents the self-web element. The tag name we provide at the start and at the end of XPath are the same as they are on the self-axis of the current node. However, this provides the confirmation of the element present when there is more than one element present having the same value and attribute. 

Syntax:

Xpath = //tagname[@attribute=’value’]//self::self_tagname

Example:

//input[@name=’username’]//self::input

This type of XPath uses its own current node and selects the web element belonging to that current node. You will always observe only one node that represents the self-web element.

4. Descendant Axis XPath:

It selects all the descendants i.e. child and grandchild of the current node. 

Syntax:

Xpath = //tagname[@attribute=’value’]//descendant::child or grandchild_tagname

Example:

//div[@class=’oxd-form-row’]//descendant::input[@name=’username’]

Username and Password
It selects all the descendants i.e. child and grandchild of the current node.

5. Descendant-or-self Axis XPath:

Using this axis we can select the current node and all its descendants i.e. child, grandchild, etc just like a descendant axis. The point to be noticed here is the tag name for descendants and self are the same. 

Syntax: 

Xpath = //tagname[@attribute=’value’]//descendant-or-self::tagname

Example:

//input[@name=’username’]//descendant-or-self::input

Using this axis we can select the current node and all its descendants i.e. child, grandchild, etc just like a descendant axis. The point to be noticed here is the tag name for descendants and self are the same. 

6. Ancestor Axis:

As we understand how the descendant axis works now, the ancestor axis works exactly opposite to that of the descendant axis. It will select or locate all ancestors elements i.e. parent, grandparent, etc of the current node. This axis contains the root node too. 

Syntax:

Xpath = //tagname[@attribute=’value’]//ancestor::ancestor_tagname

Example:

//input[@name=’username’]//ancestor::div[@class=’oxd-form-row’]

7. Ancestor-or-self Axis XPath:

Now, just like the descendant-or-self axis, the ancestor-or-self axis XPath will locate a web element having the same starting and ending tag name. 

Syntax:

Xpath = //tagname[@attribute=’value’]//ancestor-or-self::tagname

Example:

//input[@name=’username’]//ancestor-or-self::input

Now, just like the descendant-or-self axis, the ancestor-or-self axis XPath will locate a web element having the same starting and ending tag name.

8. Following Axis Path:

The following axis XPath selects all the web element that comes after the current node. 

Syntax:

Xpath = //tagname[@attribute=’value’]//following::following_tagname

Example:

//div[@class=’oxd-form-actions orangehrm-login-action’]//following::button

The following axis XPath selects all the web element that comes after the current node. 

9. Following-sibling Axis XPath

Using the following sibling axis method we can select all the nodes that have the same parent as that of the current node and that appear after the current node. 

Syntax:

Xpath = //tagname[@attribute=’value’]//following-sibling::following_tagname

Example:

//div[@class=’oxd-form-actions orangehrm-login-action’]//following-sibling::button

Using the following sibling axis method we can select all the nodes that have the same parent as that of the current node and that appear after the current node. 

10. Preceding Axis XPath

Using this axis method we can locate a web element that has the node that appears before the current node. 

Syntax:

Xpath = //tagname[@attribute=’value’]//preceding::tagname

Example:

//div[@class=’oxd-form-actions orangehrm-login-action’]//preceding::button

Example of Preceding Axis Xpath with username and Password
Using this axis method we can locate a web element that has the node that appears before the current node. 

11. Preceding-sibling Axis XPath:

Using the following sibling axis method we can select all the nodes that have the same parent as that of the current node and that appear before the current node. It works opposite to that of the following sibling axis XPath. 

Syntax:

Xpath = //tagname[@attribute=’value’]//preceding::tagname

Example:

//div[@class=’oxd-form-actions orangehrm-login-action’]//preceding::button

Example of Preceding-sibling Axis Xpath
Using the following sibling axis method we can select all the nodes that have the same parent as that of the current node and that appear before the current node. It works opposite to that of the following sibling axis XPath.

You can try all of these examples mentioned above with the Orange HRM Demo website here.

Conclusion:

In conclusion, XPath is an essential tool for web automation testing when using Selenium, Playwright, and Cypress. It allows for more flexibility and specificity in locating elements on a web page. Understanding the different types of XPath expressions and how to use them can greatly improve the efficiency and effectiveness of the automation testing process. It can be particularly useful in situations where elements do not have unique CSS selectors, or when the structure of the HTML changes frequently. With the knowledge of XPath, you can write more robust and stable automation tests.

Read more blogs here.

API Test Automation using Playwright and Java

API Test Automation using Playwright and Java

 Most of us are familiar with API testing tools like Postman, SoapUI, etc, and API automation libraries like RestAssured and Karate to automate API test cases. A recent entrant in this category is Playwright. The playwright is an Automation Tool provided by Microsoft. It provides cross-browser testing using which we can perform testing on multiple browsers like Chromium, Webkit, Firefox, etc. playwright supports cross-language testing (Java, Node.js, Python, .NET, etc.). However, very few of us know that it can actually do an API Test automation of methods GET, PUT, POST, and DELETE. Let’s see how it can be done.

Can we perform API testing using Playwright?

The playwright provides inbuilt support for API testing that’s why we don’t need any external libraries to handle API. The playwright doesn’t use any browser to call API. It sends requests using Node.js which provides faster execution.

In this tutorial, we will explore basic API methods with the help of Playwright- java. Below are the Four methods.

  1. GET
  2. POST
  3. PUT
  4. DELETE

Pre-requisite:

To get started with API automation with playwright-java first we need playwright to be installed in your system, to do this we can simply add the following dependency in the pom.xml file.

Along with the playwright, we have to add Testing and JSON dependencies.

<dependency>
  <groupId>com.microsoft.playwright</groupId>
  <artifactId>playwright</artifactId>
  <version>1.23.0</version>
</dependency>

<dependency>
   <groupId>org.testng</groupId>
   <artifactId>testng</artifactId>
   <version>7.1.0</version>
   <scope>test</scope>
</dependency>

<dependency>
   <groupId>com.googlecode.json-simple</groupId>
   <artifactId>json-simple</artifactId>
   <version>1.1.1</version>
</dependency>

Now let’s see how we can start API automation testing with Playwright-java.

1. GET:

By providing an API endpoint we can read data using a GET request. We must pass a few parameters to get the required data from the API.

We can verify the request by asserting the Response Code. The response code for a successful GET Request is 200. You can also assert a text inside the JSON body response.          

For Example, I am using postman here to send a GET request to ”  ‘/api/users/4’ endpoint of a sample API URL ‘https://reqres.in’

The below code shows the implementation of the GET method through Playwright.

@Test
public void get() throws IOException, ParseException {
   Playwright playwright = Playwright.create();
   String BaseURL="https://reqres.in";
   Map<String, String> headers = new HashMap<>();
   headers.put("content-type", "application/json");
   APIRequestContext apiRequestContext= playwright.request().newContext(new APIRequest.NewContextOptions()
           .setBaseURL(BaseURL).setExtraHTTPHeaders(headers));
   APIResponse response = apiRequestContext.get("/api/users/4");
   int responseCode=response.status();
   Assert.assertEquals(responseCode,200);

   String responseText= response.text();
   JSONParser j= new JSONParser();
   JSONObject json = (JSONObject) j.parse(responseText);

   String responseData= json.get("data").toString();
   JSONObject jsonData = (JSONObject) j.parse(responseData);
   Assert.assertEquals(jsonData.get("email"),"eve.holt@reqres.in");
   Assert.assertEquals(jsonData.get("first_name"), "Eve");
   Assert.assertEquals(jsonData.get("last_name"), "Holt");
   Assert.assertEquals(jsonData.get("avatar"), "https://reqres.in/img/faces/4-image.jpg");
   apiRequestContext.dispose();
   playwright.close();
}

To verify the response data we are parsing the response to JSON Object so that we can verify specific key-value pairs.

2. POST:

POST method is used to add a new record via API where we have to pass data as payload ex. first name, last name, etc. The response code for a successful POST Request is 201.

For example, I am sending a POST request to  ‘/api/users/’ endpoint with base URL ‘https://reqres.in‘ and the body as given below in the screenshot:

To pass the data payloads to the POST/PUT method, first, we have to create a POJO class which will help to create methods to get and set payloads.
below we have created a POJO class employee which will help to get and set data to both POST and PUT calls.

public class Employee {
// private variables or data members of pojo class
private String email;
private String first_name;
private String last_name;
private String avatar;

public String getEmail() {
   return email;
}
public void setEmail(String email) {
   this.email = email;
}
public String getFirstName() {
   return first_name;
}
public void setFirstName(String firstName) {
   this.first_name = firstName;
}
public String getLastName() {
   return last_name;
}
public void setLastName(String lastName) {
   this.last_name = lastName;
}
public String getAvatar() {
   return avatar;
}
public void setAvatar(String avatar) {
   this.avatar = avatar;
}
}

The below code will help you with the POST method through Playwright.

@Test
public void post() throws ParseException {
   employee employee = new employee();
   employee.setEmail("john@reqres.in");
   employee.setFirstName("john");
   employee.setLastName("Holt");
   employee.setAvatar("https://reqres.in/img/faces/4-image.jpg");

   Playwright playwright = Playwright.create();
   String BaseURL = "https://reqres.in";
   Map<String, String> headers = new HashMap<>();
   headers.put("content-type", "application/json");
   APIRequestContext apiRequestContext = playwright.request().newContext(new APIRequest.NewContextOptions()
           .setBaseURL(BaseURL).setExtraHTTPHeaders(headers));
   APIResponse response = apiRequestContext.post("/api/users/", RequestOptions.create().setData(employee));

   Assert.assertEquals(response.status(),201);
   String responseText= response.text();
   JSONParser j= new JSONParser();
   JSONObject json = (JSONObject) j.parse(responseText);
   Assert.assertEquals(json.get("email"), employee.getEmail());
   Assert.assertEquals(json.get("first_name"), employee.getFirstName());
   Assert.assertEquals(json.get("last_name"), employee.getLastName());
   Assert.assertEquals(json.get("avatar"), employee.getAvatar());
   apiRequestContext.dispose();
   playwright.close();
}

3. PUT:

PUT Request is used to update the existing records via the API. we have to pass the data we want to update as a payload ex. first name, last name, etc. The response code for a successful PUT Request is 200.

For example, I am sending a POST request to ‘/api/users/55’ endpoint with the base URL ‘https://reqres.in’ and the body as given below in the screenshot:

The below example shows the implementation of the PUT method. We need to use the above POJO class to pass the data as a payload to the PUT call.

 @Test
public void put() throws ParseException {
   employee employee = new employee();
   employee.setEmail("john@reqres.in");
   employee.setFirstName("Harry");
   employee.setLastName("Eve");
   employee.setAvatar("https://reqres.in/img/faces/4-image.jpg");

   Playwright playwright = Playwright.create();
   String BaseURL = "https://reqres.in";
   Map<String, String> headers = new HashMap<>();
   headers.put("content-type", "application/json");
   APIRequestContext apiRequestContext = playwright.request().newContext(new APIRequest.NewContextOptions()
           .setBaseURL(BaseURL).setExtraHTTPHeaders(headers));
   APIResponse response = apiRequestContext.put("/api/users/55", RequestOptions.create().setData(employee));

   Assert.assertEquals(response.status(),200);
   String responseText= response.text();
   JSONParser j= new JSONParser();
   JSONObject json = (JSONObject) j.parse(responseText);
   Assert.assertEquals(json.get("email"), employee.getEmail());
   Assert.assertEquals(json.get("first_name"), employee.getFirstName());
   Assert.assertEquals(json.get("last_name"), employee.getLastName());
   Assert.assertEquals(json.get("avatar"), employee.getAvatar());
}

4 DELETE:

We can delete existing records using the API by using DELETE Request. Ideally, you must have added a record before you delete it. Hence you would need to append an ID to the DELETE URL. To delete the record using API first we need to pass the record URI (Universal Resource Identifier). The response code for a successful DELETE Request is 200.

For example, I am sending a POST request to ‘https://retoolapi.dev’ endpoint with base URL ‘/3njSPM/calc/43’ and the body as given below in the screenshot:

Following is the code for the DELETE method in Playwright

@Test
public void delete()  {
   Playwright playwright = Playwright.create();
   String BaseURL = "https://retoolapi.dev";
   APIRequestContext apiRequestContext = playwright.request().newContext(new APIRequest.NewContextOptions()
           .setBaseURL(BaseURL));
   APIResponse response = apiRequestContext.delete("/3njSPM/calc/40");
   int responseCode = response.status();
   Assert.assertEquals(responseCode, 200);
   Assert.assertEquals(response.statusText(), "OK");
   apiRequestContext.dispose();
   playwright.close();

 

After performing a DELETE call we can perform a GET call on the same endpoint to verify data is actually deleted. For this GET call, we will get response code 204 as the content is not found.

For Reference: https://playwright.dev/java/docs/api-testing

Conclusion:-

GET, PUT, POST, and DELETE are the basic CRUD API methods used in any Web application. With the help of the inbuilt functionalities of Playwright, API Automation Testing became much easier and faster.

Read more blogs here

How to Automate tests using Taiko with Cucumber in JavaScript

How to Automate tests using Taiko with Cucumber in JavaScript

Hello! In this blog, I will be exploring how to automate tests using Taiko with Cucumber in JavaScript. The Taiko tool is easy to automate and is very reliable, and it works faster to execute and run test cases. It is a user-friendly tool as well. 

What is Takio?

A Taiko is an automation tool that is available for free and it is an open-source browser automation tool. It is built by the ThoughtWorks team. It uses the Node.js library to automate the chrome browser. Taiko is very useful to create maintainable and highly readable JavaScript tests.  

Taiko Features:

The Taiko was explicitly built to test modern web applications. 

The features of Taiko that set it apart from other browser automation solutions are listed below.

  1. Easy Installation
  2. Interactive Recorder
  3. Smart Selectors
  4. Handle XHR and dynamic content
  5. Request/Response stubbing and mocking

We can use Taiko on three platforms:

  1. Windows
  2. macOS
  3. Linux

How to install Taiko?

A Taiko is available on npm: You can use the following NPM command to install the taiko on your system.

npm install -g taiko

What is cucumber?

A Cucumber is a testing tool that allows BDD.  It offers a way to write tests that everyone, regardless of technical ability, can follow. Before developers build their code in BDD, users (business analysts, product owners) first write scenarios or acceptance tests that describe the system behavior from the perspective of the customer. Such scenarios and acceptance tests then are reviewed and approved by the product owners.

How to install Cucumber?

Basically, cucumber is available on npm: You can use the following NPM command to install the cucumber on your system.

npm install --save-dev @cucumber/cucumber

Getting Started 

We will be using Visual Studio code to write our test automation code in JavaScript. We will create a feature file first, then click on the left side of the panel and choose “new file” from the menu that appears. Give a file name after that, such as the Calculator. feature

I’ll start out by introducing the Taiko framework, which integrates BDD and Cucumber. You will be guided through the code in the next step.

Feature: Calculator operations
  @smoke
  Scenario: Addition of 2 numbers
    Given I launch calculator application
    When I click on number 2
    And I click on operator +
    And I click on number 2
    Then I verify the result is 4

I’ll describe how to automate the calculator page in this place. The code shown below builds calculator steps where we must import statements provided by cucumber before navigating to the support folder. 

After that, we can import the cucumber and assertion statements and that will build a page where all the steps are generally placed. 

Basically, this is the step definition file where we need to map the feature file steps and call methods declared in the page file.

After that, we have to import the page file in the step definition file.  And we need to call the methods declared in the page file. 

Following is the code snippet for the step definition file.

const { Given, When, Then } = require('@cucumber/cucumber')
const calculate = require('../../pages/calculatorPage')
Given('I launch calculator application', async function () {
  await new calculate().launch()
})
When('I click on number {string}', async function (num) {
  await new calculate().click_number(num)
})
When('I click on operator {string}', async function (num) {
  await new calculate().click_operator(num)
})
Then('I verify the result is {string}', async function (num) {
  await new calculate().verify_result(num)
})

Now let’s create a page(We are using Page Object Model (POM) structure here) file where we have to declare the class and all the methods cleaning in step definitions.

Following is the code snippet for the page file.

const { Before } = require('@cucumber/cucumber')
var { setDefaultTimeout } = require('@cucumber/cucumber')
setDefaultTimeout(60 * 1000)
const {
  openBrowser,
  goto,
  write,
  click,
  $,
  closeBrowser,
  setConfig,
  button,
  waitFor,
} = require('taiko')
const assert = require('assert')
setConfig({ observeTime: 30000, retryTimeout: 30000, navigationTimeout: 30000 })
class calculate {
  async launch() {
    await openBrowser({ headless: false })
    return goto('calculator.net')
  }
  async click_number(num) {
    waitFor(5000)
    await click($('span[onclick="r(' + num + ')"]'))
  }
  async click_operator(num) {
    await click($(`span[onclick="r('` + num + `')"]`))
  }
  async verify_result(num) {
    waitFor(5000)
    assert.equal(await $('#sciOutPut').text(), num)
    closeBrowser()
  }
}
module.exports = calculate

And, In the above code snippet, methods contain actions like opening the browser, visiting a website, CSS selectors and actions to be performed on it (click), and Assertions. You may notice that we are doing open browser and close browser actions into this page file itself which is not the best practice. You can move it to Before/After hooks and create a nice framework. However, that is for a later blog 🙂

So, to execute the test case, you can run the following command from the terminal.

npx cucumber-js --publish

Happy testing !!!

Conclusion:

We can automate tests using taiko with Cucumber with JavaScript very easily. Taiko is a very powerful tool and easy to implement. It will definitely compete with Selenium and Playwright in the coming years.

Read more blogs here

Capture screenshots and videos in java playwright

Capture screenshots and videos in java playwright

Any test automation report, without screenshots, would look dull and will not provide enough information on where the test failed. If you add only screenshots, it will make the report information-rich. Now, if your tool has the capability to record the video as well, then it will be cherry on the top. A playwright is an automation tool that has these features integrated in-built. Here we will cover various types of screenshots that can be attached and how to record the video. This blog will help you to learn the steps to include Capture screenshots and videos in java playwright.

  • Playwright contains the following inbuilt functionalities:

Here, we are exploring the functionality to capture the snapshots and how to attach them to the Cucumber report. You must have the Cucumber report set up in your framework in order to accomplish this.

Let’s, Understand first how to Capture screenshots and videos in java playwright.

1. Page Screenshot:

As you are all aware, we usually use this screenshot to attach what is visible on the screen for verification purposes.

public static List takeScreenShots() throws IOException 
    {
	public static byte[] array;
        long millisStart = Calendar.getInstance().getTimeInMillis();
        array = page.screenshot(new Page.ScreenshotOptions().setFullPage(false).setPath(Paths.get("test-output/ScreenShots/" + millisStart + ".png")));
        List output = new ArrayList();
        output.add(array);
        output.add(millisStart + ".png");
        return output;
    }

2. Full Page Screenshot:

If your test requires you to attach a screenshot of the entire page, top to bottom. So this method will guide you easily. The code below helps to take a snapshot of the entire page, no matter how long it is, because setFullPage is set to ‘true’.

public static List takeScreenShots() throws IOException
    {
	public static byte[] array;
        long millisStart = Calendar.getInstance().getTimeInMillis();
        array = page.screenshot(new Page.ScreenshotOptions().setFullPage(true).setPath(Paths.get("test-output/ScreenShots/" + millisStart + ".png")));
        List output = new ArrayList();
        output.add(array);
        output.add(millisStart + ".png");
        return output;
    }

However, now you can see that the full scrollable page has been captured in this step.

3. Element Screenshot:

So here, now you can also capture a screenshot of a specific element with the help of a playwright. In the below code, you can see that a locator path is sent as a parameter to the .screenshot() method.

page.locator("locator of that element").screenshot(new Locator.ScreenshotOptions().setPath(Paths.get("test-output/ScreenShots/screenshot.png")));

Here, we can see that the screenshot has captured only the element given in the locator.

4. Attaching Screenshot to Cucumber Report:

Now, we are going to discuss how to attach these screenshots to the cucumber report.

The first step is to set up your framework for the cucumber report, and this blog does a great job of explaining how to do that. This will allow you to add a screenshot to the Cucumber report using the code below. In general, this code is placed in your after hooks (AfterScenario, AfterStep, After). In the code below, I recently added a current millisecond time as the file name. However, you can customize the file names to your choice. 

public void screenshots(Scenario scenario) throws IOException 
    {
        WebUtil.takeScreenShots();
        long millisStart = Calendar.getInstance().getTimeInMillis();
        scenario.attach(array, "image/png",millisStart+".png" );
    }

Therefore, you can now view the Cucumber report with the screen attach to the report. while you click on the expand icon, You may see the screenshot as well.

5. Video Recording:

Now, here the playwright has the ability to record the video which will make it easier for the tester to understand their execution results. Then we’ll see how you fit that video into your report.

First, you must declare the context properties on your browser as shown in the below code. Or, you can simply update your context option where you can begin your context on the browser. Typically this method is called inside Before hooks.

public static BrowserContext RecordVideo() throws IOException 
    {
        return browserContext = browser.newContext(new Browser.NewContextOptions().setRecordVideoDir(Paths.get("test-output/RecordedTestCase/")));
    }

Now the above code will help you to record the video and it’s going to execute the test. After that, it will automatically be stored on the path which is shown in the code. Moreover, you must see that the context of your browser is closed after it will be stored.

The below lines of code demonstrate how to convert a recorded video into bytes. These bytes can then be used to attach the recorded video to a report or perform other operations.

public static byte[] encodeVideo(Path path) throws IOException {
    FileInputStream fis = new FileInputStream(String.valueOf(path));
    ByteArrayOutputStream bos = new ByteArrayOutputStream();
    byte[] b = new byte[1024];

    for (int readNum; (readNum = fis.read(b)) != -1; ) {
        bos.write(b, 0, readNum);
    }

    byte[] bytes = bos.toByteArray();
    return bytes;
}

After recording it from your project structure, you must use the following code to attach the video to the cucumber report. The tearDown method’s execution video attaching code is described below. This code will be easier to perform once the tearDown method has been completed and your video has been recorded and attached to the report. Normally, this teardown method is written using After hooks.

    public void tearDown(Scenario scenario) throws IOException 
    {
            browserContext.close();
            Path path = page.video().path();
            scenario.attach(WebUtil.encodeVideo(path),"video/webm", scenario.getName()+".webm");
	    browser.close();
            playwright.close();
    }

Now, the screenshots and videos will appear in the cucumber report as shown in the picture below. This video will be available as part of the report.

Conclusion:

Here, we see that the playwright automation tool allows us to take several screenshots as needed. How to record Capture screenshots and videos in java playwright which can help you to identify failures’ underlying causes without having to look at the report itself.

Read more blogs here

How to handle Windows popups using robot class in Selenium Automation?

How to handle Windows popups using robot class in Selenium Automation?

What is the Robot class? and why I must use robot class in my Selenium automation framework as a Selenium automation engineer.

Hello, my name is Vishal, and in this blog, I will explain why you should use robot class. I was working on a project for one of our clients, and I was asked to test the web-file application’s upload feature. There was a button, and once we click the button, a window pop-up appeared, and I was asked to upload the file to the server of that web application. I was able to automate up until the button clicking part through selenium, but I was unable to automate the window’s pop using Selenium. I tried almost everything to automate that pop-up but failed. After doing some research, I got to know that we cannot use the Selenium application to automate the windows pop-ups.

Then I did more research on the subject and got to know about the Robot class.

What is Robot Class?

Before we start talking about how to use the robot class, we will first learn the basics of the robot class.

We deal with popups and alert many times in the java selenium web automation, using a method like a driver.switchTo(). Most of them can be easily handled using submethods like a driver.switchTo().alert().dismiss() or driver.switchTo().alert().accept() methods. But what if the pop-ups are system-generated, as shown in the following image?

Windows pop ups

As these pop-ups are not related to the webpage or browser, selenium will not be able to handle these pop-ups. In that case, we use robot class to tackle these situations.

Selenium’s Robot Class is used to enable automated testing for Java platform implementations. It generates input events in native systems for Test Automation, Self-Running Demos, and other applications that require mouse and keyboard control. It is simple to implement and integrate with an automated framework.

So this was about the introduction. In the next section of this, we will learn how to use that.

How to use robot class in selenium?

To understand how to use robot class in selenium, I am using this website. This website allows you to upload sample files.

So, before we begin automating, we must first comprehend the operation that will be carried out on this application. My primary goal here is to upload a text file from my machine’s download folder to the server of that web application. On that webpage, there is a button, and when we click it, a window appears, and I am asked to select the file that I want to upload to the server.

As previously stated, we will be able to automate up to the button-clicking stage, but we will be unable to control the windows pop-up using Selenium.

So, to control that part, we’ll use the robot class. You can use the following code.

Code:

//import dev.failsafe.internal.util.Assert;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;

public class SeleniumExample {


    private static WebDriver driver = null;
   public static void main(String[] args) throws AWTException, InterruptedException {
        //Initialize the Web-driver
        driver = driverSetUpForChrome();
        driver.get("https://cgi-lib.berkeley.edu/ex/fup.html");
        String title = driver.getTitle();
        System.out.println("Title of the page is "+ title);
        // Locate the upload button
        WebElement uploadButton = driver.findElement(By.xpath("//form//input[@Name=\"upfile\"]"));
        StringSelection s = new StringSelection("C:\\Downloads\\SampleText.txt");
        // Clipboard copy
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s,null);
        Actions actions = new Actions(driver);
        actions.click(uploadButton).build().perform();
        WebElement noteFiled = driver.findElement(By.xpath("//form//input[@Name=\"note\"]"));
        actions.click(noteFiled).sendKeys("Uploading the text file.").build().perform();
        WebElement pressButton = driver.findElement(By.xpath("//form//input[@type=\"submit\"]"));
        actions.click(pressButton).build().perform();
    }

    public static WebDriver driverSetUpForChrome() {
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver();
        return driver;
    }

    public static void quitDriver() {
        driver.quit();
    }
}

When you run the above code, a pop-up window similar to the one shown below will appear on your screen. The system will prompt you for a file name here. In this case, we’ll use the robot class to select the file to upload to the server.

To do so, we must first copy the file to the clipboard. Which we can do with the following line of code.

StringSelection s = new StringSelection("C:\\Downloads\\SampleText.txt");
// Clipboard copy
Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s,null);

So, using the toolkit class, we copied the path to a string, which we need to paste into the pop window’s file field. We already know that we can copy and paste the content into fields by pressing the keyboard’s control and V buttons. Using the robot class, we will do the same thing.

To paste the copied file path, use the code below.

r.keyPress(KeyEvent.VK_CONTROL);
r.keyPress(KeyEvent.VK_V);
//releasing ctrl+v
Thread.sleep(1000);
r.keyRelease(KeyEvent.VK_CONTROL);
r.keyRelease(KeyEvent.VK_V);

Now, after pasting the file path, we need to press the enter key to select the file. we can do with the code below.

r.keyPress(KeyEvent.VK_ENTER);
//releasing enter
r.keyRelease(KeyEvent.VK_ENTER);

We have successfully uploaded the file to the server in this manner.

So this is how we can use the robot class to handle window pop-ups.

The complete code is provided below.

//import dev.failsafe.internal.util.Assert;
import io.github.bonigarcia.wdm.WebDriverManager;
import org.openqa.selenium.By;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;
import org.openqa.selenium.chrome.ChromeDriver;
import org.openqa.selenium.interactions.Actions;

import java.awt.*;
import java.awt.datatransfer.StringSelection;
import java.awt.event.KeyEvent;

public class SeleniumExample {


    private static WebDriver driver = null;

    public static void main(String[] args) throws AWTException, InterruptedException {
        //Initialize the Web-driver
        driver = driverSetUpForChrome();
        driver.get("https://cgi-lib.berkeley.edu/ex/fup.html");
        String title = driver.getTitle();
        System.out.println("Title of the page is "+ title);
        // Locate the upload button
        WebElement uploadButton = driver.findElement(By.xpath("//form//input[@Name=\"upfile\"]"));
        StringSelection s = new StringSelection("C:\\Downloads\\SampleText.txt");
        // Clipboard copy
        Toolkit.getDefaultToolkit().getSystemClipboard().setContents(s,null);
        Actions actions = new Actions(driver);
        actions.click(uploadButton).build().perform();
        Robot r = new Robot();
        //pressing enter
        //pressing ctrl+v
        Thread.sleep(1000);
        r.keyPress(KeyEvent.VK_CONTROL);
        r.keyPress(KeyEvent.VK_V);
        //releasing ctrl+v
        Thread.sleep(1000);
        r.keyRelease(KeyEvent.VK_CONTROL);
        r.keyRelease(KeyEvent.VK_V);
        //pressing enter
        r.keyPress(KeyEvent.VK_ENTER);
        //releasing enter
        r.keyRelease(KeyEvent.VK_ENTER);

        WebElement noteFiled = driver.findElement(By.xpath("//form//input[@Name=\"note\"]"));
        actions.click(noteFiled).sendKeys("Uploading the text file.").build().perform();

        WebElement pressButton = driver.findElement(By.xpath("//form//input[@type=\"submit\"]"));
        actions.click(pressButton).build().perform();
    }

    public static WebDriver driverSetUpForChrome() {
        WebDriverManager.chromedriver().setup();
        WebDriver driver = new ChromeDriver();
        return driver;
    }

    public static void quitDriver() {
        driver.quit();
    }
}

More about Robot Class Methods and Use:

In this section, we will learn more about the feature and its uses.

Robot robot = new Robot();

At this line, we are initializing the robot class.

keyPress():

For example robot.keyPress(KeyEvent.VK DOWN): This function is one keyword and that keyword is the name of the button that you want to press. For example, if you want to press button V then you will have to pass the following object:

KeyEvent.VK_V

mousePress():

For example, robot.mousePress(InputEvent.BUTTON3 DOWN MASK) will perform a right mouse click.

mouseMove():

For example, robot.mouseMove(point.getX(), point.getY()) will move the mouse cursor to the X and Y coordinates supplied.

keyRelease():

For example, robot.keyRelease(KeyEvent.VK DOWN): This method releases the Keyboard’s down arrow key. If there are any keys that you have pressed using the KeyPress function, then you can use this function to release those keys. – mouseRelease(): For example, robot.mouseRelease(InputEvent.BUTTON3 DOWN MASK): This method will release your mouse’s right click.

Conclusion:

So, in this way, we learned about the robot class and its application in this blog. I hope you got the information you were looking for. please share it with your testing squad, and if you have any suggestions or questions, please leave them in the comment section.

Read more Blogs here