"No one is harder on a talented person than the person themselves" - Linda Wilkinson ; "Trust your guts and don't follow the herd" ; "Validate direction not destination" ;

May 23, 2011

Automation Assignment - Selenium, TestNG

[You may also like - Selenium Automation Tricks From Selenium Wiki]
Next Post in Series - Automation Assignment - Selenium, TestNG - Improvements Post II

Couple of weeks back I did an automation exercise. Below is the code I developed. Would love to hear feedback on this. Any improvements/suggestions for this welcome.

Task - Automation for cleartrip.com - Home page

Test Automation Approach
  • Page object approach, All tests and verifiers for home page in single class created for homepage
  • Covers cross browser testing IE and Firefox
  • Implements data driven testing (ex-One way flight tests)
  • Test listener implemented to log results after running each test
  • Standard coding practices (try-catch, comments for each methods implemented)
  • Console output, TestNG output, Email report generated in folder attached
Java project code
HomePageTest.java
import com.thoughtworks.selenium.DefaultSelenium;
import com.thoughtworks.selenium.Selenium;
import org.testng.Assert;
import org.testng.annotations.*;

public class HomePageTest {
      Selenium selenium;

      @Parameters( { "browserpath", "appurl" })
      @BeforeTest(alwaysRun = true)
      public void init(String browserpath, String appurl) {
            selenium = new DefaultSelenium("localhost", 4444, browserpath, appurl);
            selenium.start();
            selenium.deleteAllVisibleCookies();
            selenium.refresh();
      }

      @AfterTest
      public void tearDown() {
            selenium.stop();
      }

      /* Test for 1 way flight  */
      @Test(dataProvider = "dataProviderSearchFlightsOneWay")
      public void SearchFlightsOneWay(String from, String to) {
            try {
                  selenium.open("/");
                  selenium.type("//input[@id='origin_autocomplete']", from);
                  selenium.type("//input[@id='destination_autocomplete']", to);
                  selenium.click("//img[@alt='Calendar']");
                  selenium.click("link=20");
                  selenium.click("button_flight_search");
                  try {
                        Thread.sleep(10000);
                  } catch (InterruptedException e) {
                  }
                  selenium.waitForPageToLoad("25000");
                  verifyResults("1");
            } catch (Exception e) {
                  System.out.println("Exception Occurred " + e.toString());
            }

      }

      /* Test for round trip flight  */
      @Test
      public void SearchFlightsRoundTrip() {
            try {
                  selenium.open("/");
                  selenium.type("//input[@id='origin_autocomplete']", "MAA");
                  selenium.type("//input[@id='destination_autocomplete']", "BLR");
                  selenium.click("//img[@alt='Calendar']");
                  selenium.click("link=17");
                  selenium.click("id=rnd_trip");
                  selenium.click("//*[@id='rtn_date']");
                  selenium.click("link=30");
                  selenium.click("button_flight_search");
                  try {
                        Thread.sleep(10000);
                  } catch (InterruptedException e) {
                  }
                  selenium.waitForPageToLoad("15000");
                  verifyResults("2");
            } catch (Exception e) {
                  System.out.println("Exception Occurred " + e.toString());
            }
      }

      /* verifier for search results  */
      public void verifyResults(String Filter) {
            Assert.assertTrue(selenium.isElementPresent("mod_link"));
            Assert.assertTrue(selenium.isElementPresent("facebookLink"));
      }

      /* Test for train search  */
      @Test
      public void testTrainSearch() {
            try {
                  selenium.open("/");
                  selenium.click("link=Trains");
                  selenium.waitForPageToLoad("30000");
                  selenium.type("from_station", "chennai");
                  selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + "");
                  selenium.type("to_station", "bangalore");
                  selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + "");
                  selenium.select("trainClass", "label=AC 2 Tier (2A)");
                  selenium.click("//img[@alt='Calendar']");
                  selenium
                              .click("//div[@id='datePickerWrapper']/table[2]/tbody/tr[5]/td[4]/a");
                  selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + "");
                  selenium.click("//input[@type='image']");
                  try {
                        Thread.sleep(10000);
                  } catch (InterruptedException e) {
                  }
                  selenium.waitForCondition(
                              "selenium.isElementPresent('id=mod_link')", "60000");
            } catch (Exception e) {
                  System.out.println("Exception Occurred " + e.toString());
            }

      }

      /* Test for Hotels Search  */
      @Test
      public void searchHotels() {
            try {

                  selenium.open("/");
                  selenium.click("link=Hotels");
                  selenium.waitForPageToLoad("30000");
                  selenium.type("city", "chennai");
                  selenium.click("//img[@alt='Calendar']");
                  selenium.click("link=12");
                  selenium.keyPressNative(java.awt.event.KeyEvent.VK_TAB + "");
                  selenium.click("//img[@alt='Calendar']");
                  selenium.click("link=29");
                  selenium.click("//input[@type='image']");
                  selenium.waitForPageToLoad("30000");
                  try {
                        Thread.sleep(10000);
                  } catch (InterruptedException e) {
                  }
                  selenium.waitForCondition(
                              "selenium.isElementPresent('id=mod_link')", "60000");
            } catch (Exception e) {
                  System.out.println("Exception Occurred " + e.toString());
            }
      }

      /* Test to verify headers  */
      @Test
      public void verifyHeaders() {
            try {
                  selenium.open("/");
                  Assert.assertTrue(selenium.isElementPresent("link=Hotels"));
                  Assert.assertTrue(selenium.isTextPresent("Hotels"));
                  Assert.assertEquals("Trains", selenium.getText("link=Trains"));
                  Assert.assertTrue(selenium.isElementPresent("link=Trains"));
                  Assert.assertEquals("Small World", selenium
                              .getText("link=Small World"));
                  Assert.assertTrue(selenium.isElementPresent("link=Small World"));
                  Assert.assertEquals("more", selenium.getText("link=more"));
                  Assert.assertTrue(selenium.isElementPresent("link=more"));
                  Assert.assertTrue(selenium.isElementPresent("link=My Trips"));
                  Assert.assertTrue(selenium.isElementPresent("link=Sign in"));
                  Assert.assertTrue(selenium.isElementPresent("link=Register"));
                  Assert.assertTrue(selenium.isElementPresent("link=Register"));
                  Assert.assertTrue(selenium
                              .isElementPresent("//ul[@id='global']/li[5]/a/strong"));
                  Assert.assertEquals("Tell us what you think", selenium
                              .getText("//ul[@id='global']/li[5]/a/strong"));
                  Assert.assertTrue(selenium
                              .isElementPresent("//ul[@id='global']/li[5]/a/strong"));
                  Assert.assertEquals("India", selenium
                              .getText("//a[@id='SetDomain']/span"));
            } catch (Exception e) {
                  System.out.println("Exception Occurred " + e.toString());
            }

      }

      /* Test to verify footers  */
      @Test
      public void verifyFooter() {
            try {
                  selenium.open("/");
                  Assert.assertTrue(selenium
                              .isElementPresent("//a[@id='SetDomain']/span"));
                  Assert.assertTrue(selenium.isElementPresent("link=About Us"));
                  Assert.assertTrue(selenium.isElementPresent("link=FAQs"));
                  Assert.assertTrue(selenium.isElementPresent("link=FAQs"));
                  Assert.assertTrue(selenium.isElementPresent("link=Support"));
                  Assert.assertTrue(selenium.isElementPresent("link=Customer Forum"));
                  Assert.assertTrue(selenium.isElementPresent("link=Blog"));
                  Assert.assertTrue(selenium
                              .isElementPresent("link=Cleartrip for Business"));
                  Assert.assertTrue(selenium.isElementPresent("link=Privacy"));
                  Assert.assertTrue(selenium.isElementPresent("link=Security"));
                  Assert.assertEquals("Security", selenium.getText("link=Security"));
                  Assert.assertTrue(selenium.isElementPresent("link=API"));
                  Assert.assertEquals("API", selenium.getText("link=API"));
                  Assert.assertEquals("Mobile", selenium
                              .getText("//div[@id='Footer']/div/ul[2]/li[11]/a"));
                  Assert.assertTrue(selenium.isTextPresent("API"));
                  Assert.assertTrue(selenium.isTextPresent("Terms of Use"));
                  Assert.assertTrue(selenium.isTextPresent("Privacy"));
                  Assert.assertTrue(selenium.isTextPresent("Cleartrip for Business"));
                  Assert.assertTrue(selenium.isTextPresent("Blog"));
                  Assert.assertTrue(selenium.isTextPresent("Customer Forum"));
                  Assert.assertTrue(selenium.isTextPresent("Support"));
                  Assert.assertTrue(selenium.isTextPresent("About Us"));
            } catch (Exception e) {
                  System.out.println("Exception Occurred " + e.toString());
            }

      }

      /* Data Provider for oneway flight Search */
      @DataProvider(name = "dataProviderSearchFlightsOneWay")
      public Object[][] setDataforSearchFlightsOneWay() {
            System.out.println("Start Data Provider: SearchFlightsOneWay");
            Object[][] retkeyword = { { "MAA", "BLR" }, { "MAA", "BOM" } };
            System.out.println("End Data Provider: SearchFlightsOneWay");
            return (retkeyword);
      }

}
TestReporter.java
import org.testng.ITestContext;
import org.testng.ITestListener;
import org.testng.ITestResult;

/* Test listener class to log after running each test */
public class TestReporter implements ITestListener{
    public void onFinish(ITestContext arg0) {
    }

    public void onStart(ITestContext arg0) {
    }

    @Override
    public void onTestFailure(ITestResult arg0) {
        System.out.println("Finished Executing Test: "+arg0.getName()+"Status: Failed"+"\n Reason:"+arg0.getThrowable());
    }

    @Override
    public void onTestSkipped(ITestResult arg0) {
        System.out.println("Skipped test: "+arg0.getName()+".Reason"+arg0.getThrowable());
    }

   @Override
    public void onTestStart(ITestResult arg0) {
        System.out.println("Starting Test: "+arg0.getName());
    }
    @Override
    public void onTestSuccess(ITestResult arg0) {
        System.out.println("Finished Executing Test: "+arg0.getName()+"Status: Success.");
    }

   public void onTestFailedButWithinSuccessPercentage(ITestResult arg0) {
        System.out.println("Test failed but within success percentage");
    }
}

SuiteReporter.java
import org.testng.ISuite;
import org.testng.ISuiteListener;

public class SuiteReporter implements ISuiteListener{
    @Override
    public void onFinish(ISuite arg0) {
        System.out.println("Finished executing the suite");
        System.out.println("********Results*******");
    }

    @Override
    public void onStart(ISuite arg0) {
        System.out.println("Starting Execution");

        //Print suiteName
        System.out.println("Suite Name:"+arg0.getName());

        //Print HostName
        System.out.println("Host Name:"+arg0.getHost());//Returns null if it runs locally
    }
}

TestNG XML Code
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Suite" parallel="none" verbose="1">
      <listeners>
   <listener class-name="SuiteReporter" />
   <listener class-name="TestReporter" />
   </listeners>
   <test name="TestinInternetExplorer">
   <parameter name="browserpath" value="*iehta"/>
   <parameter name="appurl" value="http://www.cleartrip.com/"/>
   <classes>
      <class name="HomePageTest"/>
      <methods> 
        <include name="SearchFlightsOneWay" />
        <include name="SearchFlightsRoundTrip" /> 
        <include name="testTrainSearch" /> 
        <include name="searchHotels" /> 
        <include name="verifyHeaders" /> 
        <include name="verifyFooter" /> 
      </methods> 
    </classes> 
   </test>
   <test name="TestinFirefox">
   <parameter name="browserpath" value="*firefox C:\\Program Files (x86)\\Mozilla Firefox\\firefox.exe"/>
   <parameter name="appurl" value="http://www.cleartrip.com/"/>
   <classes>
      <class name="HomePageTest"/>
      <methods> 
        <include name="SearchFlightsOneWay" />
        <include name="SearchFlightsRoundTrip" /> 
        <include name="testTrainSearch" /> 
        <include name="searchHotels" /> 
        <include name="verifyHeaders" /> 
        <include name="verifyFooter" /> 
      </methods> 
    </classes> 
   </test>
</suite>

This is working Code. Developed this code in 2 days. This was a Good Learning Assignment.

Happy Reading!!

6 comments:

tarun k said...

Quick Review Comments -

1. Don't use Thread.sleep()
2. Don't hard code waitperiod, you could define a constant and use it instead
3. Is selenium.open command needed in each test?
4. Can you externalize app objects instead of hardcoding them in your test methods
5. You have used lots of assertions in test, notice that if any of the assertion fails,it would not continue with test execution. Do you really want this?

Siva said...

Thanks Tarun for your comments. I will modify the code. Appreciated :).

#1 - To increase wait time i used thread.sleep - Is it not a good practice ? any reasons ?

#2. Agreed waitperiod can be constant

#3. Valid Comment

#4. What Alternative would you suggest in this case, Please suggest.

Thank in Advance,
Siva

tarun k said...

Instead of Thread.sleep you could use waitForElement methods. As sleep injects static wait time in you tests and you are never sure after what amount of time you should execute next step.

Regarding Assertion, I am soon to post a blog for it, watch out my blog

HTH
Tarun K

Siva said...

Thanks Tarun :), Added your blog in my Selenium blog links. Will wait for your post.

tarun k said...

I made a post yesterday, hope you find it useful

Siva said...

Thanks Tarun. Mentioned your comments in my latest post. Found some alternatives for Soft Assertions. Will give it a try.