WebDriver a perfect API testing your JEE application

Overview

  • Selenium WebDriver marks a leap forward in terms of browser automation
  • WebDriver can be used by multiple Languages : Java, C#, PHP, Phyton, Perl, JS, …
  • Selenium-WebDriver makes direct calls to the browser and can issue Buttons clicks , ..
  • Selenium-WebDriver supports multiple Browers like Firefox , Chrome, HtmlUnitDriver,  …
  • HtmlUnitDriver is a  headless (GUI-less) browser simulator ( good for Load Testing )
  • Before switching to HtmlUnitDriver you may first use  a GUI based Driver like FirefoxDriver

Preparing Test Environment

For testing WebDriver we use 2 Wildfly instances :
Instance 1 (Port 8081 ) : Production  Server  
   publishes our Website to be tested - Session Scoped Bean using following annotations
      @Named("jPATestBean")
      @SessionScoped 
Instance 2 ( Port 8180) : Test Server 
   Simulates a Webbrowser - using following annotations   
      @RunAsClient annotation 
   This project only has a single Java test Class 


Note: The WFJPA2EL-1.0 Web application is deployed to both Server 

 

Testing the same Webapplication running on  different Application Servers

The main purpose of these tests [ test1() and test2() ] are:

  • Review the Page and verify the Page title
  • Dynamically click  the JSF button j_idt8:cBtn32
  • Use View Page Source from your firefox Browser  to find out your IDs for your Button.  Sample:
    <td><input id=“j_idt8:cBtn32” type=”submit” name=”j_idt8:cBtn32″ value=”Check running RAC Instances and JPA Version ” /></td>
  • Verify that we are connecting to the correct  RAC database named:  BANKA
  • Test  using different URLs
    http://localhost:8081/WFJPA2EL-1.0/     http://localhost:8180/WFJPA2EL-1.0/
  • Sleep between HTTP request to allow users to read the HTML page
Java Code
@Test
@RunAsClient
public void test1() throws InterruptedException
{
testJPARunAsClient("http://localhost:8081/WFJPA2EL-1.0/");
}

@Test
@RunAsClient
public void test2() throws InterruptedException
{
testJPARunAsClient("http://localhost:8180/WFJPA2EL-1.0/");
}

public void testJPARunAsClient(String URL) throws InterruptedException
{
String methodName = "testJPARunAsClient()";
System.out.println("Inside: " + methodName + "- URL: " + URL );
WebDriver driver = new FirefoxDriver();
driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
driver.get(URL);
String pageTitle = driver.getTitle();
System.out.println(" URL " + contextPath +  " - " +methodName + " - Found Page Title:  " + pageTitle);
Assert.assertEquals( "Testing RAC - J2EE JPA2 API!", pageTitle);
// Press the Check RAC instance Button
driver.findElement(By.id("j_idt8:cBtn32")).click();
String rtInfo = driver.findElement(By.id("j_idt8:optxt1")).getText();
if ( rtInfo != null )
{
System.out.println(rtInfo);
Assert.assertTrue(rtInfo.contains("DB Name:  BANKA"));
}
// Close brower window after 5 seconds
Thread.sleep(5000);
driver.quit();
System.out.println("Leaving: " + methodName);
}
}

Note our tested URL should return
Inside: testJPARunAsClient()- URL: http://localhost:8081/WFJPA2EL-1.0/
URL http://127.0.0.1:8180/testJPABeanUsingWebdriver/ - testJPARunAsClient() - Found Page Title:  Testing RAC - J2EE JPA2 API!
10:34:11.045 Calling  getRacInfo() in progress ...
10:34:11.046 EclipseLink Version: 2.5.2 - [ EclipseLink 2.5.2 == JPA 2.1]
10:34:11.047 Driver Name             : Oracle JDBC driver
10:34:11.047 Driver Version          : 12.1.0.2.0
10:34:11.048 Database Product Version: Oracle Database 12c Enterprise Edition Release 12.1.0.2.0 - 64bit Production
With the Partitioning, Real Application Clusters, Automatic Storage Management, OLAP,
Advanced Analytics and Real Application Testing options
10:34:11.056 DB Name:  BANKA
10:34:11.057 1. Instance Name: bankA_3 - Host: hract21.example.com
10:34:11.057 Leaving getRacInfo() without Exceptions !
Leaving: testJPARunAsClient()

Use View Page Source from firefox to find out our GUI IDs
<td><input id="j_idt8:cBtn32" type="submit" name="j_idt8:cBtn32" value="Check running RAC Instances and JPA Version " /></td>

Starting the test using Maven
$ mvn test

This tests should do the following
- Start 2 firfox browser session and execute the JSF function invoked by j_idt8:cBtn32 button
- After each test the browser should be  closed automatically

The above maven command should return
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 51.583 sec
Results :
Tests run: 3, Failures: 0, Errors: 0, Skipped: 0
[INFO] ------------------------------------------------------------------------
[INFO] BUILD SUCCESS
[INFO] ------------------------------------------------------------------------
[INFO] Total time: 1:06.197s
[INFO] Finished at: Thu Jun 18 15:23:00 CEST 2015
[INFO] Final Memory: 19M/55M
[INFO] ------------------------------------------------------------------------

 

Testing a quite complex JTA transaction application by using multiple Browsers


For running test3() and test4() we use a SessionScoped Web application.
This application runs  the following 5 HTTP request :
 - HTTP Request1: Request the initial page via HTTP GET request
 - HTTP Request2: Cleanup table records
 - HTTP Request3: Uses  a HTTP post request to START and SUSPEND a Transaction 
     - Start a JTA transaction
     - Run JPA flush [ == Insert a new db record )
     - Suspend the JTA transaction using the JEE TransactionManager API
     - Add JTA transaction object, Entity Manager object to our HTTPSession Object 
  - HTTP Request4: Uses  a HTTP post request to RESUME and COMMIT the Transaction      
     - retrieve JTA transaction object and Entity Manager object from our HTTPSession Object
     - Resume the Transaction and update the record
     - Commit the record -  in case of any errors rollback the transaction
     - Cleanup HTTP session object , clear the Entity Manager 
  - HTTP Request5: Uses  a HTTP post request to invalidate the HTTP session          
     - Invalidate the HTTP session 

-> This is a quite complex Transaction sample and we will see whether WebDriver 
   can handle this ! 

The main purpose of these tests [ test3() and test4() ]  are 
- Test a SessionScoped JEE application with different Browser [ Firefox and GUIless HtmlUnitDriver ]
- Track the JSESSIONID cookie 
- test3() uses Firefox Driver  
   - start a Firfox session
   - Display the HTML page 
   - Use wait times to display the HTTP pages 
 
- test4()  uses the GUIless HtmlUnitDriver 
   - don't start any browser and display any HTLM page  ( useful for GUI test )
   - Don't use any wait times between the HTTP requests ( useful for performance test ) 

JAVA Code 
  @Test 
     public void test3() throws InterruptedException
      {
         testJPARunAsClientTestSession("http://localhost:8180/WFJPA2EL-1.0/", true);
      }  
    
     @Test 
     public void test4() throws InterruptedException
      {
         testJPARunAsClientTestSession("http://localhost:8180/WFJPA2EL-1.0/", false);
      }  
      public void testJPARunAsClientTestSession(String URL , boolean useGUI) throws InterruptedException
      {
        WebDriver driver = null; 
        String methodName = "testJPARunAsClient()";
        System.out.println("Inside: " + methodName + "- URL: " + URL );
        if (useGUI)
            driver = new FirefoxDriver();
        else 
            driver = new HtmlUnitDriver();
        driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS); 
        driver.get(URL);  
            //driver.get("http://localhost:8081/WFJPA2EL-1.0/");
            // browser.get("http://localhost:8180/WFJPA2EL-1.0/");
        String pageTitle = driver.getTitle();        
        System.out.println(" URL " + contextPath +  " - " +methodName + " - Found Page Title:  " + pageTitle);
        Assert.assertEquals( "Testing RAC - J2EE JPA2 API!", pageTitle);  
       
            // Press Clean Table Button
        driver.findElement(By.id("j_idt8:cBtn15")).click();       
        String rtInfo = driver.findElement(By.id("j_idt8:optxt1")).getText();
        if ( rtInfo != null )
         {
            if (useGUI)
                System.out.println(rtInfo);
            Assert.assertTrue(rtInfo.contains("Leaving cleanTable() without Exceptions - Data commited"));
         }
        checkCookie(driver, "Action: Clean Table");
        if (useGUI)
            Thread.sleep(2000);
        
            // click Start and Resume Button
        driver.findElement(By.id("j_idt8:cBtn13")).click();       
        rtInfo = driver.findElement(By.id("j_idt8:optxt1")).getText();
        if ( rtInfo != null )
         {
            if (useGUI)
                System.out.println(rtInfo);
            Assert.assertTrue(rtInfo.contains("-> Suspend Transaction - Status: SUSPEND - Salary:1500"));
         }
        checkCookie(driver, "Action: Start and Suspend Transaction");
        if (useGUI)
            Thread.sleep(5000);
        
            // Click Resumee and Commit button
        driver.findElement(By.id("j_idt8:cBtn14")).click();       
        rtInfo = driver.findElement(By.id("j_idt8:optxt1")).getText();
        if ( rtInfo != null )
         {
            if (useGUI)
                    System.out.println(rtInfo);
            Assert.assertTrue(rtInfo.contains("-> Transaction Commited  -  Salary after update:1599"));
         }
        checkCookie(driver, "Action: Resume and Commit Transaction");
        if (useGUI)
            Thread.sleep(10000);
        
               // Click Session Invalidation button
        driver.findElement(By.id("j_idt8:cBtn31")).click();       
        rtInfo = driver.findElement(By.id("j_idt8:optxt1")).getText();
        if ( rtInfo != null )
         {
            System.out.println(rtInfo);          
         }
        checkCookie(driver, "Action: Invalidate JSF session");
        if (useGUI)
            Thread.sleep(1000);
        driver.quit();
      }
     
    private void checkCookie(WebDriver driver, String info)
      {
        Cookie cookie= driver.manage().getCookieNamed("JSESSIONID");
        System.out.println(info + " - JSESSIONID cookie: " + cookie.getValue());
      }
    

Let's verify the Output :  
Action: Clean Table - JSESSIONID cookie: 1ThmlTaJ_TQAqIeltEuixN23.wls1
Action: Start and Suspend Transaction - JSESSIONID cookie: 1ThmlTaJ_TQAqIeltEuixN23.wls1
Action: Resume and Commit Transaction - JSESSIONID cookie: 1ThmlTaJ_TQAqIeltEuixN23.wls1
Action: Invalidate JSF session - JSESSIONID cookie: E9uqbcDsgyCr5aTxu6bQxX26.wls1
Tests run: 2, Failures: 0, Errors: 0, Skipped: 0, Time elapsed: 42.93 sec

-> After invalidation of our JSF session we get a new JSESSIONID cookie - Perfect !

Summary:

  • WebDriver is an easy API for GUI testing and functional testing
  • WebDriver can be used with JMETER ( used for Multithreading testing )
  • WebDriver is able the run even complex JEE application
  • WebDriver perfect deals with the  JSESSIONID cookie

Reference

One thought on “WebDriver a perfect API testing your JEE application”

Leave a Reply

Your email address will not be published. Required fields are marked *