Search This Blog

Breaking

Wednesday, 26 August 2020

August 26, 2020

Fix: npm install fibers shows error while doing npm install for your webdriverio UI automation project

 This is one issue that irritates me every time when I try to do node js setup for webdriverIO automation project in my mac. This issue comes when you try to do npm install in your command prompt for installing the node packages specified in your package.json. 


So the issue is: When you try to run npm install, then it fails with below error:

npm ERR! code ELIFECYCLE

npm ERR! errno 1

npm ERR! fibers@3.1.1 install: `node build.js || nodejs build.js`

npm ERR! Exit status 1

npm ERR!

npm ERR! Failed at the fibers@3.1.1 install script.

npm ERR! This is probably not a problem with npm. There is likely additional logging output above.    

npm ERR! A complete log of this run can be found in:

npm ERR!     C:\Users\deepak\AppData\Roaming\npm-cache\_logs\2019-05-07T10_36_05_651Z-debug.log

or 

> fibers@1.0.1 install /usr/local/lib/node_modules/fibers

> node ./build.js


gyp ERR! build error 

gyp ERR! stack Error: not found: make

gyp ERR! stack     at F    (/usr/local/lib/node_modules/npm/node_modules/which/which.js:43:28)

gyp ERR! stack     at E    (/usr/local/lib/node_modules/npm/node_modules/which/which.js:46:29)

gyp ERR! stack     at /usr/local/lib/node_modules/npm/node_modules/which/which.js:57:16

gyp ERR! stack     at Object.oncomplete (fs.js:107:15)

gyp ERR! System Darwin 12.5.0

gyp ERR! command "node" "/usr/local/lib/node_modules/npm/node_modules/node-gyp/bin/node-             


gyp.js" "rebuild"

gyp ERR! cwd /usr/local/lib/node_modules/fibers

gyp ERR! node -v v0.10.29

gyp ERR! node-gyp -v v0.13.1

gyp ERR! not ok 

Build failed

npm ERR! fibers@1.0.1 install: `node ./build.js`

npm ERR! Exit status 1

npm ERR! 

npm ERR! Failed at the fibers@1.0.1 install script.

npm ERR! This is most likely a problem with the fibers package,

npm ERR! not with npm itself.

npm ERR! Tell the author that this fails on your system:

npm ERR!     node ./build.js

npm ERR! You can get their info via:

npm ERR!     npm owner ls fibers

npm ERR! There is likely additional logging output above.


npm ERR! System Darwin 12.5.0

npm ERR! command "/usr/local/bin/node" "/usr/local/bin/npm" "install" "fibers@1.0.1" "-g"

npm ERR! cwd /Users/mac/Documents/node/node-fibers

npm ERR! node -v v0.10.29

npm ERR! npm -v 1.4.14

npm ERR! code ELIFECYCLE

npm ERR!  

npm ERR! Additional logging details can be found in:

npm ERR!     /Users/mac/Documents/node/node-fibers/npm-debug.log

npm ERR! not ok code 0




To fix this issue, you need to check, which node version, you are running in your machine.

You can check it by doing:


node -v


In my case, it was showing some 12 versions of the node.


I googled and found that it was working with the node 11 version.


So, I try to keep both versions in my machine as some of my local projects were using node 12.


To do this, I used nvm. nvm helps you to keep different node packages and allow you to switch between them.


To install nvm in mac, you need to run this command in your terminal:


curl -o- https://raw.githubusercontent.com/creationix/nvm/v0.33.0/install.sh | bash


Check installed nvm version by:


nvm --version


Now install node 11 


nvm install 11.14.0


and use it in your project:


nvm use 11.14.0 


After this, run:


 npm install 


Now, it will install without giving any error.



Monday, 24 August 2020

August 24, 2020

[Karate Framework] Polling Scenario in API

 There are times when we observe that, we are receiving 500 or 400 responses or any other response which was not expected one from our API endpoint.  At that time, we try to hit that API multiple times, and sometimes, do not get that response. Because on re-run, it returns 200 or the desired response. 


To find out the actual root cause, we need to replicate this scenario. For replication, we will have to at least hit this endpoint more than 10, 20 times. At that time, if we will have some automation script which we can utilize to do this activity, becomes very handy.


In one of my projects, We were using Karate for API automation. In Karate, there is a very nice feature of polling (retry-until) for such Use cases. 



To use this feature, we need to first set up the retry configuration as per our need:


* configure retry = { count: 5, interval: 5000 }


So with this configuration, we can hit the request 5 times with an interval of 5 sec.

Now we need to put the condition:

And retry until responseStatus == 500

That's It.

So, with this configuration, the API will be hit maximum 5 times, within an interval of 5 seconds.

If we get the response in 2nd attempt, it will not run further.

A complete scenario is here:

Feature: Test Retry Feature

  Background:

        Given url baseURL

        * configure retry = { count: 5, interval: 5000 }

  Scenario: Fetch all Employees

         Given path 'posts'

         And retry until responseStatus == 500

        When method GET


I liked this feature as sometimes, we just want to hit the endpoint until it gives some different response than expected. Moreover, if your setup is ready then it is very easy to use.


Monday, 17 August 2020

August 17, 2020

How I implemented Optional class in my java API automation framework to avoid null pointer exception ?

 "I call it my billion-dollar mistake. It was the invention of the null reference in 1965. At that time, I was designing the first comprehensive type system for references in an object-oriented language (ALGOL W). My goal was to ensure that all use of references should be absolutely safe, with checking performed automatically by the compiler. But I couldn't resist the temptation to put in a null reference, simply because it was so easy to implement. This has led to innumerable errors, vulnerabilities, and system crashes, which have probably caused a billion dollars of pain and damage in the last forty years."

—Sir Tony Hoare (Known for Quicksort, Quickselect, Hoare logic, Null reference, Communicating Sequential Processes, Structured programming) Speaking at a software conference called QCon LondonAfter reading the statement from Sir Tony Hoare, You can understand the importance of null pointer reference. If you are a Java programmer, you probably know that It is one of the worst nightmares for us. It is a source of the myriad problems. In the series of my blog with Java8 and Automation, today, I will show the use of class Optional introduced in Java8 and how we used it in our automation script. We have some scenarios in our automation script, where we are creating one folder in the beginning and using the Folder key in the rest of our test cases to avoid creating multiple Folders.

Below is the code for that:


capturing the folder key from the already created folder

String folderKey =repositoryMap.get(RepositoryParameterEnum.FOLDERKEY.getValue());

The problem with this code is that, if there is no folder created, it was returning Null value. 

Which I was handling the script with below logic:

if (folderKey.equals(null)) {

 String folderName = "AutoFolder_" + Utils.getUniqueId();

BaseScript.createFolderServiceMethod(folderName);

}

folderKey = repositoryMap.get(RepositoryParameterEnum.FOLDERDKEY.getValue());

So this is one area where I found I can use Java8 optional class and revamp this code with better null pointer handling.

Optional Class in Java8: The concept of Optional is not new and other programming languages have similar constructs. For example - Scala has Optional[T], Haskell has Maybe type. So if you are familiar with these languages, you can correlate it. For rest, who are neophyte for this concept, let's understand it with a simple explanation:

Optional is a container type for a value that may be absent. I know, I know, you don’t like theory, so let's get into the code. So in our previous example, the folder key is the value, which sometimes holds a value and sometimes returns null. So I put it in optional, keeping in mind that the output may be null or maybe not.

String folderKey =repositoryMap.get(RepositoryParameterEnum.FOLDERKEY.getValue());

Optional<String> opt = Optional.ofNullable(folderKey);

Now, with optional I have many methods, which will help me to play this folder key value without much thinking about the null pointer. I used isPresent() method. isPresent() method returns true if the Optional contains a non-null value, otherwise, it returns false.

So, I changed my code:

if(opt.isPresent()) //returns true or will execute if the folderKey contains a non-null value

{

  FrameworkLogger.logStep("Folder key is " +folderKey);

  }

  else {

  String folderName = "AutoFolder_" + Utils.getUniqueId();

  FrameworkLogger.logStep("Create a new Folder");

 BaseScript.createFolderServiceMethod(folderName);;

  folderKey = repositoryMap.get(RepositoryParameterEnum.FOLDERDKEY.getValue());

  FrameworkLogger.logStep("Newly created Folder key is " +folderKey);

}

The code is more readable and handles the null value in a better way. So this is how, I implemented, another beautiful Java8 feature in our automation script. You can find a plethora of information about the Optional class on the Internet, so I am avoiding the part of creating the optional class and its methods. I hope, now when you handle, null value, you will use optional class and avoid the embarrassment of NullPointerException.

Thursday, 6 August 2020

August 06, 2020

Common Locators in UI Automation

There are some common ways to find locators that are used most of the time in UI Automation. I am listing some of them down so it will expedite the process of writing locators. 

1. So if you are looking for an XPath expression to search based on a class and text:
                        
Class is only "myclass":

//*[@class='myclass' and contains(text(),'deepak')]


Class contains "myclass":

//*[contains(@class,'myclass') and contains(text(),'deepak')] 

2. Select div that contains class AND whose specific child element contains text
                         
//div[contains(@class, 'measure-tab') and contains(.//span, 'someText')]

3. To determine if a checkbox is checked or not through xpath

//input[@type='checkbox' and @checked]

or

//input[@type='checkbox' and not(@checked)]


                 //div[contains(@class, 'measure-tab') and contains(.//span, 'someText')]

Wednesday, 5 August 2020

August 05, 2020

Find Integer from different objects

This was a question asked to me in one of my automation interviews. I liked this question. It was a little bit different than the traditional ones. 

So the question was :

We have some values with us. You need to find out the integer values from those values. 

Example : 1, a, 0.1 , "dsds", -1
The output should be 1 and -1



You are free to use any language.

I tried to do it with Java. 

So to implement it, first, I thought to put all these input values into a list. 
But what should be the type of list here? (That's why I liked this question) 

As it's all of the different types, so I created an ArrayList of the object type.

ArrayList<Object> list = new ArrayList();

Now, I need to add these values to this ArrayList.
So I used the add method and added all values to this list.

list.add(1);
list.add('a');
list.add(0.1);
list.add("dsds");
list.add(-1);

Now I created another list to hold all the integer values. 

ArrayList list1 = new ArrayList(list.size());

Now, I used the instanceOf method present in object class to check the type of the value preent inside
list.

for(int i = 0; i < list.size(); i++)
{
    if (list.get(i) instanceof Integer) {
        list1.add(list.get(i));
    }

}
In the end, I printed the new list;
System.out.println("New list" + list1); // [1, -1]

August 05, 2020

Find duplicate values from a string with Java8 features

This is another very common question. It can be done in one line through Java8.



String myString = "This is for test automation questions";
String distinctChar =  myString
                       .chars()
                       .mapToObj(c -> (char) c)
                       .collect(Collectors.toSet())
                       .stream()
                       .map(String::valueOf)
                        .collect(Collectors.joining());

System.out.println("String after duplicates removed: "
        +  String.valueOf(disticntChar));
August 05, 2020

Slow down the speed of typing in selenium Type/SendKeys/setValue method

Recently, I faced an issue in our current automation where when we were typing string value through selenium webdriverIo setValue method, then after a few words, the cursor jumps to the beginning of the document. This was clearly the issue with the customized froala editor we were using in the application. But I was not able to replicate it manually. 

So to fix this issue, I will need to slow down the speed of typing in the editor. And this speed was coming from the "setValue()" method from webdriverIO API. 

My sample Text was :

const value = "Auto- This note is created from automation at 09-05-2020 12:48 PM"

$(selector).setValue(value)

It was typing something like this in UI field:

 9-05-20is created from automAuto-This note tion at 020 12:48 PM

Which was completely a garage statement.

So to fix this issue, I changed my approach of typing. While earlier I was using setValue() method where I was passing the complete string.

Now, Instead of this, I passed each character of the string to keys() method and put a pause in between those character passing.

So the code now changed to:

const value = "Auto- This note is created from automation at 09-05-2020 12:48 PM"
const arrValue = [...value]; // This is for converting string to charArray

for(let i = 0 ; i< arrValue.length; i++) {
browser.keys(arrValue[i] );
browser.pause(200); // .5 milisecond pause
}

Output: Auto- This note is created from automation at 09-05-2020 12:48 PM

Now I got the desired output, little slow but correctly.

Note: The framework is built with webdriverIo and Typescript. But this approach can be used in any selenium based framework. 

#UIAutomation #SetValue