Friday, July 12, 2019

Contact Us

If you would like to contact us, please fill in the form below. We aim to respond to email enquiries as quickly as possible but please allow two working days for a reply.

Contact Us

Required value*


With details email us: testerblog00@gmail.com

Technology and Science

We cannot imagine our usual life without some advancement, caused by Science and Technology progress. In fact, our existence changes in minutes now, something new appears each single day, what makes humans life easier and more comfortable in some aspects. So, the age we have chance to live in now is considered to be called the era of science and technology.
Actually, Science and Technology introduces us the foundation of up-to-date civilisation. This progress has contributed greatly to mainly each aspect of our everyday life. So, people have an opportunity now to enjoy its results, having their lives more comfortable and pleasurable.
Here are some facts, which show on the benefits of Science and Technology progress:
  • The morning daily paper, which helps people to always keep up-to-date and supply them with trustworthy information of everything what`s going on around the world, is a result of scientific progress.
  • Goods and devices people use in their daily deeds, such us electric light, refrigerator, electric oven, microwave etc. – all that is given to us by science.
  • Science and Technology has also affected greatly our means of transportation, by making it easy to travel from one place to another quickly. All buses, ships, aero-planes use the benefits of new advancements.
  • Thanks to the development of Science, men are now able to explore other planets.
  • Nowadays, newly created satellites are used to bring a light concerning outer space.
  • Many medicines, which are created to save million people lives, are also products of science.
  • Science and Technology provides us also with some things people cannot imagine their lives without: television, Internet, radio.
  • The latest technologies also help to increase the production of goods and different crops. The same is about work on factories, where manual work is replaced by new devices.
  • Urbanization, expansion of the villages, cities, factories, changes in economics and country`s well-being.
All these things mentioned above were possible only due to the rapid development of science and technology. So, no wonder that it plays a significant role in the modern life of people. Thanks to this development, we have entered another level of human civilization, having everything to arrange happy and comfortable living.  It can even be said that modern way of life and culture are dependent on some products of science and technology, as they have become an integral part of existence, taking into account needs and requirements of people.
Thanks to new technologies, people now have many opportunities and choices. For example, they can study online sitting at home by using Internet benefits and available sources of information. They can even study at university on distance learning basis. The same thing is about work. There are many freelance options, which help people to provide for the living without going to offices each morning. Scientists have made it possible to take the highest benefits from technologies.
In general, development of the country is strongly connected with the growth of the development in science and technology. These tree words, development, science and technology, always go together and are very necessary for people and their better living. We can say that our life depends on new inventions and scientific creations. As science and technology changes people life to a very great extent.
Alongside with many advantages, some people also consider science and technology to be harmful for humans. The deal is that it is also used for some destructive purposes. Scientifically created weapons like atom or hydrogen bombs are able to destroy the whole world in just few minutes. Some people also think that it is not environmentally friendly to use all the advantages of scientific progresses. People should just learn how to use everything in a proper way.
In conclusion, it must be admitted that science and technologies can lead human civilization to a perfection in living. At the same time, everything should be done in wise perspectives and to some extents, not to harm and destroy the world. Earth has sound for those, who listen.

Autor Note:


I am an engineer with 8 years of experience in software development and testing. I am blogger and innovator, I worked with reputed MNC company in different zonal. They helped me gain good experience in the Banking, Security,Oil&Gas and Telecom domains.  My QA career started in Manual Tester. I got exposure to various testing tools, processes and methodologies, got an opportunity to work on various technologies and testing tools like:
 SQL, No-SQL (Mongo DB), Java and VB, UNIX, PowerShell, Java Script, Python,QC, TFS, Zephyr, X-ray, MTM,QC, TFS, BMC Ready, JIRA,Toad, Putty, AppDynamics, Splunk, Nagios, Selenium, Cucumber-Java, TOSCA, QTP, Coded UI, Squish, Test- Complete, Katloan Studio, SOUP UI, SOA, TOSCA, Selenium, Web Service Testing, JMeter, Load Runner,JAWS, Appium, See-Test, TOSCA, SonarQube, Veracode, Black Duck, ESLint and good knowledge on ITIL Process, Agile Process.
My interests are social service, listening to music and reading books, mentoring juniors.


Auto-generate Locators using Python

In this post, we will present a way to auto-generate robust and short Locators/Xpaths for the two most common HTML elements automation interacts with – buttons and input elements. We have tested this against more than 50 commonly used websites like GoogleBinanceHDFCIRCTCCurrysPCWorld etc.






Why this post?

The foundation for robust GUI automated checks is writing good element locators. Xpath is one locator strategy used for selecting nodes from Document Object Models (DOM) like XML, HTML, etc. Generating XPaths manually is a routine and time-consuming task.
As part of simplifying our test writing process, we came up with a thought to write a utility script which will identify and auto-generate robust and simple XPaths. We started off with generating XPaths for Input and Button fields of a webpage using the general locators like id, name, class etc. The Python program in this post will demonstrate how to create XPath expressions automatically for input and button tags. Whenever there is a requirement to automate a webpage, the tester can simply run this script which would generate a bunch of XPaths without any human intervention.

What should be considered when writing an XPath?

Most of us rely on extracting the XPaths from browser plugins or tools. These tools have got limitations. One of the limitations is that they frequently produce absolute XPaths (meaning all the way from the HTML tag!) which are long and extremely flaky. Other smarter tools seem to have trouble producing unique XPaths in anything but the simplest conditions. Generally, we locate the elements using their unique attributes but some elements do not have unique attributes. Locating such elements is difficult because the XPath generated will have multiple matching elements. It is important to consider the following points while choosing an XPath. A good locator is:
  • Unique – XPath should have only one candidate element (Unique).
  • Descriptive – It is easy to identify the element easily when the XPath is descriptive.
  • Shorter in length – You will have multiple XPath options. A shorter XPath shall be selected to make it more readable.
  • Valid even after changes to a page – XPath should be selected in such a way it is valid even after changes in DOM.

Overview of our Python Utility script

We made an effort to write a script which will auto-generate XPaths for Input and Button elements in the webpage and also check for the uniqueness of the generated XPath. This will save the automation time and effort. In the coming sections, we will be talking about below items:
  • Accept a URL and parse the page content using BeautifulSoup
  • For each element, check for the existence of the attribute and guess the XPath
  • Check for uniqueness of the generated XPath
  • How we tested this utility
  • Putting it all together
Note:- If the XPath generated is not unique or if the HTML page does not have the attribute mentioned for the given tag then our script does not generate any XPaths.

Accept a URL and Parse the page content using BeautifulSoup

First, we need to import all the libraries that we are going to use. We used python module BeautifulSoup to extract and parse the HTML content.
from selenium import webdriver
from bs4 import BeautifulSoup
Our main method starts with declaring a variable which accepts the input URL of the page.
    #Get the URL and parse
    url = input("Enter URL: ")
The next step is to parse the page into a BeautifulSoup format. We used selenium’s execute_script() function to get the inner HTML of a page and return it as a string to the Python script. This method takes as a parameter a string of Javascript code that it executes inside of the browser.
    #Parsing a page with BeautifulSoup
    page = driver.execute_script("return document.body.innerHTML").encode('utf-8') #returns the inner HTML as a string
    soup = BeautifulSoup(page, 'html.parser')

For each element, check for existence of the attribute and guess the XPath

Now we have a variable, soup, containing the HTML of the page. Here’s where we can start coding the part that extracts the data. BeautifulSoup can help us get into these layers and extract the content with find_all() method. Using this method we are going to fetch all the Input and Button tags from the HTML page. We are passing the ‘soup’ as an argument for generate_xpath method.
    #execute generate_xpath
    if xpath_obj.generate_xpath(soup) is False:
        print ("No XPaths generated for the URL:%s"%url)
If the webpage doesn’t have any inputs and buttons it throws a print message saying that there are no tags to generate the Xpaths for this URL.
Now let us look into the generate_xpath() logic. We first initialized few list variables for element lists and attribute lists. guessable_elements lists consists of element lists and known_attribute_list consists of attribute lists. We are looping over element lists (as of now we are doing this only for input and button elements). Next for each element we will loop over the attribute lists and check for the attribute existence and then guess the XPath. Please note that we have declared the attribute lists based on the order of importance of attribute occurrence. For eg:- If ‘id‘ is not available for that element, next we are checking for ‘name‘ attribute and so on.

def __init__(self):
        self.elements = None
        self.guessable_elements = ['input','button','img','link','text','div']
        self.known_attribute_list = ['id','name','placeholder','value','title',
             'type','class','href','alt','img','text','link','real','property']
 
def generate_xpath(self,soup):
        "generate the xpath"  
        result_flag = False
        try:
            for guessable_element in self.guessable_elements: #Print tag name
                             self.elements = soup.find_all(guessable_element)   #DoM tag of guessable_element                            
                for element in self.elements:                                   
                    if (not element.has_attr("type")) or (element.has_attr
                                    ("type") and element['type'] != "hidden"):
                        for attr in self.known_attribute_list:                                                      
                            if element.has_attr(attr):                                                             
                                locator = self.guess_xpath
                                (guessable_element,attr,element) #"Xpath created"                               
                                
                                    if len(driver.find_elements_by_xpath
                                                                  (locator))==1:
                                    result_flag = True                                   
                                    print (locator.encode('utf-8'))
                                    break
                            elif guessable_element == 'button' and 
                                                              element.getText():                                                                  
                                button_text = element.getText()
                                if element.getText() == button_text.strip():
                                    locator = xpath_obj.guess_xpath_button
                                   (guessable_element,"text()",element.getText())
                                else:
                                 locator = xpath_obj.guess_xpath_using_contains
                                 (guessable_element,"text()",button_text.strip())
                                if len(driver.find_elements_by_xpath(locator))==1:
                                    result_flag = True                                   
                                    print (locator.encode('utf-8'))
                                    break        
   except Exception as e:
      print ("Exception when trying to generate xpath for:%s"%guessable_element)
      print ("Python says:%s"%str(e))

Check for uniqueness of the generated Xpath

XPath should have only one candidate element which means the XPath should output one and only one element. To make sure that the given XPath returns a single element we are checking the length of the elements for each locator in the generate_xpath() method and if it is greater than 1 checking for another attribute. In this way we are making sure that the XPath is unique.
if len(driver.find_elements_by_xpath(locator))==1:
    result_flag = True                                   
    print (locator.encode('utf-8'))
    break

In the above generate_xpath() code, we are calling three different methods guess_xpath(), guess_xpath_button() and guess_xpath_using_contains(). We shall discuss in detail about these methods in below sections.
guess_xpath()
The method guess_xpath(), accepts three arguments namely tag, attr, element, and XPath is guessed based on these arguments. To handle Unicode errors due to foreign Unicode characters we used encode() and join() functions.
def guess_xpath(self,tag,attr,element):
        "Guess the xpath"
    #Class attribute returned as a unicodeded list, so removing 'u from the list and joining
        if type(element[attr]) is list:
            element[attr] = [i.encode('utf-8') for i in element[attr]]
            element[attr] = ' '.join(element[attr])
        self.xpath = "//%s[@%s='%s']"%(tag,attr,element[attr])
 
        return  self.xpath
guess_xpath_button()
We are using method guess_xpath_button() to check button.getText() condition. There will be situations, where you may not able to use any HTML property rather than text present in the element. text() function helps us to find the element based on the text present in the element. Since text() is a method, it does not need ‘@’ symbol as in case of an attribute.
def guess_xpath_button(self,tag,attr,element):
        "Guess the xpath for buttons"
        self.button_xpath = "//%s[%s='%s']"%(tag,attr,element)
 
        return  self.button_xpath
guess_xpath_using_contains()
In some cases, we may have to use ‘contains‘ function which helps the user to find the element with partial values, or dynamically changing values, ‘contains‘ verifies matches with the portion of the value for text for which we don’t need the complete text but need only part of the text. In our case, while we are testing our code with few URL’s we encountered few button tags with text having leading and trailing spaces in the text. In such cases, the XPath guessed using above guess_xpath() may not work. Hence we wrote another method called guess_xpath_using_contains() which uses ‘contains‘ function and generates XPath as shown below.
def guess_xpath_using_contains(self,tag,attr,element):
        "Guess the xpath using contains keyword"
        self.button_contains_xpath = "//%s[contains(%s,'%s')]"%(tag,attr,element)
 
        return self.button_contains_xpath

How we tested this utility

We tested this Utility with almost 50 different pages which have multiple input and button fields. We also tested with pages which don’t have any text or button fields. We came across few issues which we figured and fixed.
One of the issues we encountered is that when we ran the script in Windows, the input() command ran properly but when we ran it in Git Bash, we noticed there is a time gap in running input() command. The key to the problem is windows console prints text to the screen as soon as possible, while mingw (git bash) will wait until the application tells it to update the screen. To fix this, you can use -u flag interpreter command while running the script, which will stop python from buffering output in git bash as shown below.
 below.
    python -u AutoLocators_generator.py
  
                                                           Screenshot of result of AutoLocatorsgenarator.py


Putting it all together

"""
Author/Developer: Sadanand Biradr
Auto Locator script to generate XPaths for the given URL
* Take the input URL from the user
* Parse the HTML content using beautifilsoup
* Find all Input, Button. IMG, DIV and Link tags
* Guess the possible Locators/XPaths
* To run the script in Terminal/Command Pront use command 'python -u AutoLocatorsgenerator.py'
"""

from selenium import webdriver
from bs4 import BeautifulSoup
from selenium import webdriver
from webdriver_manager.chrome import ChromeDriverManager
import os

class Xpath_Util:
    "Class to generate the xpaths"
 
    def __init__(self):
        self.elements = None
        self.guessable_elements = ['input','button','img','link','text','div']
        self.known_attribute_list = ['id','name','placeholder','value','title','type','class','href','alt','img','text','link','real','property']

 
    def generate_xpath(self,soup):
        "generate the xpath"  
        result_flag = False
        try:
            for guessable_element in self.guessable_elements:
                print guessable_element, '='  #"Element fisrt name'
                self.elements = soup.find_all(guessable_element)
                print "DoM tag of guessable_element",self.elements
                for element in self.elements:
                    
                    if (not element.has_attr("type")) or (element.has_attr("type") and element['type'] != "hidden"):
                        for attr in self.known_attribute_list:
                            if element.has_attr(attr):                                                             
                                locator = self.guess_xpath(guessable_element,attr,element)
                                print locator #"Xpath created"
                                if len(driver.find_elements_by_xpath(locator))==1:
                                    result_flag = True                                   
                                    print (locator.encode('utf-8'))
                                    break
                                
                            elif guessable_element == 'button' and element.getText():
                                button_text = element.getText()
                                if element.getText() == button_text.strip():
                                    locator = xpath_obj.guess_xpath_button(guessable_element,"text()",element.getText())
                                else:
                                    locator = xpath_obj.guess_xpath_using_contains(guessable_element,"text()",button_text.strip())
                                    
                                            
                                if len(driver.find_elements_by_xpath(locator))==1:
                                    result_flag = True                                   
                                    print (locator.encode('utf-8'))
                                    break        
        except Exception,e:
            print ("Exception when trying to generate xpath for:%s"%guessable_element)
            print ("Python says:%s"%str(e))                                                 
 
        return result_flag
    
#    Input
    def guess_xpath(self,tag,attr,element):
        "Guess the xpath Input"
        #Class attribute returned as a unicodeded list, so removing 'u from the list and joining
        if type(element[attr]) is list:
            element[attr] = [i.encode('utf-8') for i in element[attr]]
            element[attr] = ' '.join(element[attr])
        self.xpath = "//%s[@%s='%s']"%(tag,attr,element[attr])
 
        return  self.xpath
    
#     Button
    def guess_xpath_button(self,tag,attr,element):
        "Guess the xpath for buttons"
        self.button_xpath = "//%s[%s='%s']"%(tag,attr,element)
        return  self.button_xpath

    def guess_xpath_using_contains(self,tag,attr,element):
        "Guess the xpath using contains function"
        self.button_contains_xpath = "//%s[contains(%s,'%s')]"%(tag,attr,element) 
        return self.button_contains_xpath
    
    #-------START OF SCRIPT--------
if __name__ == "__main__":
    print ("Start of %s"%__file__)
 
    #Initialize the xpath object
    xpath_obj = Xpath_Util()
 
    #Get the URL and parse
    url = input("Enter URL: ")
 
    #Create a chrome session
    driver = webdriver.Chrome(executable_path=os.popen('which chromedriver').read().strip())
    driver.get(url)
 
    #Parsing the HTML page with BeautifulSoup
    page = driver.execute_script("return document.body.innerHTML").encode('utf-8') #returns the inner HTML as a string
    soup = BeautifulSoup(page, 'html.parser')
 
    #execute generate_xpath
    if xpath_obj.generate_xpath(soup) is False:
        print ("No XPaths generated for the URL:%s"%url)
 
    driver.quit()
We hope this post helps you in building robust and simple XPaths/Locators using Python code for text and button fields without having to depend on any tools or browser plugins. We are also working on getting good human-friendly variable names for the generated XPaths. We will post about it shortly.
Shortly will post  and provide snippet on 'AutoLocatorInspector'  utility to find changed Xpath/Locators in your application/Web page.