Skip to main content

Selenium Tutorial - Verifiying Application Elements

Disclaimer: Objective of this post is to demonstrate how I use Selenium to do soft assertion over collection of element. I don't assert in any way that this is right approach and you are most welcome to prove me  wrong.

So you want to verify collection of elements on you web page. And I assume that you want tests to continue to execute even in the wake of error with some elements. For example you want to test whether text labels for - 'username', 'password' appear on web page. (Though you may like to stop the test execution if 'username', 'password' elements them selves are not there) The worse approach I could think of is to write all assertions in one test, something like -

public void testElements() {
Assert.assertTrue(selenium.isElementPresent("UserNameTextLabel"), 
"Username Text label is not available on page");
Assert.assertTrue(selenium.isElementPresent("PasswordTextLabel"), 
"Password Text label is not available on page");
Some more assertions here
}

Why is this worse approach, it is because any failure with one of the assertion will cause test to be aborted, and you definitely want to continue with test execution even if some text labels don't appear on page.
Now comes another way of doing assertion using Selenium. We can break each assertion in to their individual methods and check for one text label in each method. So you could do some thing like -



public void testUserNameText() {
Assert.assertTrue(selenium.isElementPresent("UserNameTextLabel"), 
"Username Text label is not available on page");
}
public void testPasswordText() {
Assert.assertTrue(selenium.isElementPresent("PasswordTextLabel"), 
"Password Text label is not available on page");

I believe that this is another bad approach because there would be too much of coding involved with this approach. And more code means more maintenance need. Would not it be nice if we could just have one method to test all labels and at the same time not have it cramped with assertions all around. And also be able to execute all the assertions even if a few of them fail.
This is where Soft Assertion comes for our rescue. Have a look at this post which details about how to use soft assertions with Selenium.

I do so by creating a template like following and not hard coding any of the element locator in test itself
Notice that template may also contain check for count of elements.

# Comment is written with ###
# Module format is - ElementName:::ElementIdentifier;CountOfNumberOfElements
# CountofNumberOfElements would be provided only if applicable 

NumberOfBlog:::h3.entry-title;5
PaginationLinks:::ol[class='ycric-pagination-numbers ycric-clrfix']
AuthorBio:::css=p.author-bio

And a file parser which could read it and supply them to verification methods, i.e.

    public Map  getObjectDefinition(String filePath) throws IOException {
        // Verification Element with no verification for XPath count.
        Map objectDefinition = new HashMap();
        
        // get page components.
        InputStream inputStream = PageObjectReader.class.getResourceAsStream(filePath);
        DataInputStream dataInputStream = new DataInputStream(inputStream);
        BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(dataInputStream));
        String line;
        while(((line = bufferedReader.readLine())!=null)) {
            if(!line.startsWith("#") && line.length() > 0) {
                String key = line.split(":::")[0];
                String[] value = line.split(":::")[1].split(";");                
                objectDefinition.put(key, value); 
            }
        }        
        dataInputStream.close();            
        return objectDefinition;        
    } 
 
And here is the verification method -

 public void verifyObjectDefinitions(Map objectDefinitions) {        

        // Check verification elements.
        for (String key:objectDefinitions.keySet()) {            
            // If Element count is to be checked
            if(objectDefinitions.get(key).length == 2) {
                
                int actualElementCount = WebUtils.getCSSCount(objectDefinitions.get(key)[0]);
                int expectedElementCount = Integer.valueOf(objectDefinitions.get(key)[1]);
                
                customVerification.verifyTrue(key, objectDefinitions.get(key)[0], selenium.isElementPresent(objectDefinitions.get(key)[0]), 
                        actualElementCount, expectedElementCount, selenium.getLocation());
            } else {
                customVerification.verifyTrue(key, objectDefinitions.get(key)[0], selenium.isElementPresent(objectDefinitions.get(key)[0]), 
                        selenium.getLocation());                 
            }            
        }
        customVerification.checkForVerificationErrors();
    }

And test would look as -

@Test(groups="UI", alwaysRun=true)
    public void verifyBlogSection() throws InterruptedException, IOException { 
        
        homePage.getBlogsPage().getSecondBlog();
        
        Map firstBlogElements = pageObjectReader.getObjectDefinition("/conf/CricketNewsFirstBlogPageInfoFile.txt");
        pageTestManager.verifyObjectDefinitions(firstBlogElements);
        
        customVerification.checkForVerificationErrors();
        
    }    

Hence we have -
  •  Concise method to check elements on page, instead of having assertions/verifications scattered all over the method
  • Since we are using Selenium - Soft Assertion, test execution would continue even if one or more elements are not found while reporting errors on missing elements in test report
  • We have also externalized app object to external file, hence elements are not hard coded in tests.

So how do you do element verification using Selenium? Any thoughts?

Came across this post on soft assertion today and found it worth sharing -
http://seleniumexamples.com/blog/guide/using-soft-assertions-in-testng/

Comments

  1. Several comments:

    1. I don't normally write tests that verify the existence of a bunch of elements on a page. (Maybe I should, but I don't!) I prefer tests that verify the existence of an element (or group of elements) as a *side effect* of some real-world scenario testing. Thus, a negative test in which a valid username with the wrong password are entered, would obviously not pass if the username and password elements were not present. And hopefully, it would fail as elegantly as possible in this case. But the main point of the test would be to see if the site responded appropriately when the user made this error. Verification of the existence of the username and password elements would happen as a side effect. And this "side-effect testing" would happen numerous times with such important fields.

    2. Given the above, the third of your three summary points is of the most interest to me. I'd like to see this scheme used in a test such as I've described. I'm not a Java programmer so am not sure what the best way to handle the locator look-up would be. It seems that every test that needed firstBlogElements would have to first see if it was already defined, and if not, do the call to pageObjectReader.getObjectDefinition. No?

    3. How does this template scheme differ from using a resource file for storing locators, which is something I heard recommended recently?

    4. For people who do want to test that multiple elements are present on a page, I'd suggest improving the code re-use of verifyObjectDefinitions by reducing the five occurrences of "objectDefinitions.get(key)[0]" to one--just stick the result in a var and use the var from thereon.

    ReplyDelete
  2. Hey Mary,

    I would try to answer one by one -

    1. Agree about *side effect testing*, and this is what I think I would do. Two groups of tests "uiTest" and "functionalTest" for login scenario, where group "functionalTest" is dependent on success of group "uiTest". Though side effect testing would also give almost same result but yet I would prefer this approach. If you have heard of TestNG framework in java - it would mark "functionalTest" as skipped and "uiTest" failed

    2. Exactly, that's the whole idea

    3. "template scheme", that's a new word for me, let me see what I can find on this front

    4. Very valid code Review Comment :-). I am leaving my blog post as it is so other readers could see how deficiencies could be over come from the code snippets after reading your comments.

    ReplyDelete
  3. Hi,
    Assertion is not working in my code.
    here is my code:
    @Test
    public void testPeopleFinderPresent() {

    selenium.waitForPageToLoad("20000");

    Assert.assertTrue(selenium.isTextPresent("People Finder1"),"People Finder is not Present on the Page");

    }


    @Test
    public void testClickonLink() {

    selenium.click("link=People Finder");

    }

    now what my objective is:
    If the Link People Finder is present in the page,then only it will click on the link and continue,otherwise it will not continue.
    But here i mentioned the name as "PeopleFiner1",so it must not continue,but still the control is passing on testclickonLink() function. How can this be resolved?

    I want to stop execution after testPeopleFinderPresent(),if PeopleFinder is not found.

    ReplyDelete
  4. The execution continues because operation - "selenium.click("link=People Finder");"
    is happening in a different method and Assertion -
    "Assert.assertTrue(selenium.isTextPresent("People Finder1"),"People Finder is not Present on the Page");"
    is happening in a different method. You should keep both of them in one method and your issue would be solved

    ReplyDelete
  5. well,Tarun,thanks for the reply.
    But my query is:
    We can have two kind of Test Cases-Show-stopper and non-show stopper.
    For show-stopper scenario,if one test step fails then rest of the test steps will also fail.
    for non-show stopper,if one test step fails,then it will be skipped and rest will continue.Am I right?

    Now what I came to know that if we user Assert,then we can achieve first point and if we use verify then we can achieve second point.

    But for that we have to put all test steps in one method,which is a bit hectic,also it suppresses the modularity.
    If I have 10 steps,and if i want that if setp 3 fails then rest will also fail,then i have to keep step 3 to step 10 in one method!!!

    But if i want that even if step 3 fails,rest step will continue,then we have to use verifytrue?

    and one more point:
    here is mu code after modification:

    public void testPeopleFinderPresent() {

    selenium.waitForPageToLoad("20000");

    Assert.assertTrue(selenium.isTextPresent("People Finder1"));
    selenium.click("link=People Finder");

    }

    i have put selenium.click in the same method as of assertion.Though People finder1 is not present,but it is getting getting clicked.

    ReplyDelete
  6. Hi Tarun,would you mind to modify and modularize my code for one time only,if i paste the full code here?
    :-)))
    if i mention the functionality

    ReplyDelete
  7. You are right about this -

    "But if i want that even if step 3 fails,rest step will continue,then we have to use verifytrue?"

    You would have to use verification methods.

    Abhi - if

    Assert.assertTrue(selenium.isTextPresent("People Finder1"));

    fails then next statement would not be executed for sure. Is there a way for me to access your application?

    ReplyDelete
  8. yes tarun,assertion is working fine.I am sorry,it was my mistake.

    Also-
    Could u pls elaborate on verification method?i found one article of you containing custom verification method?can i go for that?


    and also,it will be very helpful if u can re-arrange/re structure my code for one time only,this is a very short one like adding setup code etc.
    actually i tried to add setup code mentioning browser etc,but just in a mess :-P,so left it.


    agian,thanks for all ur patiennce and reply dude!!!i have been able to produce a demo infront of our team,and w/o ur help that was never possbl :-))))

    ReplyDelete
  9. yes tarun,assertion is working fine.I am sorry,it was my mistake.

    Also-
    Could u pls elaborate on verification method?i found one article of you containing custom verification method?can i go for that?


    and also,it will be very helpful if u can re-arrange/re structure my code for one time only,this is a very short one like adding setup code etc.
    actually i tried to add setup code mentioning browser etc,but just in a mess :-P,so left it.


    agian,thanks for all ur patiennce and reply dude!!!i have been able to produce a demo infront of our team,and w/o ur help that was never possbl :-))))

    ReplyDelete
  10. Thanks for kind words Abhishek.
    See now you know to use Selenium as well as Blogspot :P

    Send me your code, I would try to review and modify asap.

    ReplyDelete
  11. And ya, forgot to mention that you can use custom verification method, Let me know if you face any issue with it.

    ReplyDelete
  12. many thanks Tarun.So before pasting my code,allow me to let you know about the functionality.
    _________________________________________________________________________________________________________________________________________________________________

    Test Case:

    In our company portal,there is a link to find people/employee inside the company.The name of the link is "PeopleFinde".
    Now if i click on the link,it goes to another page which asks for :
    FirstName and,
    LastName as Input.

    Now after entering the First and Last Name,there is a button named as "Find" and we need to click on the button.

    After that,the control goes to another page,where the details of the employee is shown including Signum of employee.(Signum is a just a unique identifier like

    employeeid.)

    now what i am trying to do is:

    I have created a data table in excel sheet,which containd ID,FirstName,LastName and Signum.
    Now using @dataprovider,i am retrieving all data.
    then-
    the retrieved firstname and last name is being typed by selenium and clicks on the Find button.In next page it is reading the Signum value from a html(hope u can

    remind how u helped me a lot in finding that using xpath).
    Now i am checking the value with the database value,which is d expected result.

    This overall functioanlity.

    Now for this scenario,i thought of 3 test cases.

    1.Company Home page is launching properly which is "http://internal.com/page/hub_south_east_asia_oceania/index.jsp".

    2.Then I have to check whether "PeopleFinder" button is present or not.
    If not,it will stop,else continue.

    3. Then it will click on the PeopleFinder button and read data from excel and check for Signum.

    here two points:

    a. Suppose there are 3 entries in the table.So even if for first entry,signum does not match,it should contninue for other entries.(Here probably i have to use

    customverify but not sure.)

    b.and after checking one recorde,control will go back to previous page,so that selenium can type name of next record which is working fine.

    This is the overall scenario.
    Now i am confused,which page i should use as setup page? my home page or other page like google.com? i noticed that if i use google.com as home page then two command

    windows are opening in the background while running.How to close the windows please?

    ______________________________
    i am mailing you the code as it crosees 4096 characters.
    is there any option of attachment here?

    ReplyDelete
  13. I saw your code which u mailed me a couple of suggestions -

    1. Yes you would have to us verify method. But I did not see call to checkForVerifircationErrors(), which should be last statement in your tests. If you don't use it then your test method would never fail, even if there were error.

    2. Don't hard code this path as it would work only in you system and not others - "C:\\Users\\ebanabh\\workspace\\PeopleFinder\\src\\Resources\\Data\\data1.xls"
    instead use getResourceAsStream. Google on it, you would find many resources.

    These methods are not used, so remove them -

    @BeforeTest
    public void beforeTest() {
    }

    @AfterTest
    public void afterTest() {
    }


    3. Your setup page should e your company page and not Google, I am not sure of command windows u get, can u provide me more details?

    4. To maximize the window you can us selenium.windowMaxmize, instead of using Robot class.

    Hope this helps you

    ReplyDelete

Post a Comment

No spam only genuine comments :)

Popular posts from this blog

Distributed Load Testing with JMeter

Distributed Testing with JMeter When one JMeter client is not able to offer amount of threads required for load testing then distributed testing is used. In distributed testing - One instance of JMeter client can control number of JMeter instances and collect data from them Test plan does not need to be copied to each server, the client sends it to all servers note - JMeter will run all the threads on all the servers, hence 100 threads on 5 JMeter server would pump 500 threads in total. If many server instances are used, the client JMeter can become overloaded and so the client network connection. This has been improved in latest versions of JMeter by switching to Stripped modes, but you should always check that your client is not overloaded When Client (master) and Server (slave) nodes are on same network (no SSH required) Configure Client Node Herein client is referred as the machine controlling test execution on other JMeter nodes. This is also referred

Appium and android mobile app automation

Next appium and Android mobile app automation video tutoria l is live. If you are new to appium then please check - appium-tutorial This video tutorial covers - Start vysor (Just for this session and not mobile automation :)) Start appium and start appium inspector Desired Capabilities platformName - Android deviceName - L2N0219828001013 (as seen on "adb devices") Saved Capability Sets Start Session Scan app elements using appium inspector Get appPackage and appActivity using "APK info" app Install "APK info" app and open app whose appPackage and appActivity are required i.e. calculator Check top section of app icon com.android.calculator2 is app package com.android.calculator2.Calculator is app activity testng.xml file settings for running Android app tests Test details com.seleniumtests.tests.mobile.AndroidAppTest and CalculatorScreen class View beautiful STF test report  

Verify email confirmation using Selenium

Note: If you are new to java and selenium then start with selenium java training videos .     Email confirmation seems to be integral part of any registration process. I came across an application which lets you provide your email address. You can follow the sign up link in you mail and then complete the registration process. Lets consider we provide GMail address for it. Now if were to use only Selenium then we would have to follow following steps - Launch GMail using Selenium; Some how search for new mail in the list of available mails; Some how click on it; Parse the mail message; Get the registration link; Follow up with registration process What do you think of an approach in which you can