Thursday, March 12, 2015

Selenium JUnit Testing

I recently put together a Selenium JUnit testing project to automate testing for a web project I am working on. Having never done or worked on a Selenium project before I did a little research into finding out how it works and what approach best suits me. The following describes a few things I decided upon.

Selenium is used to automate tests through a web browser. Jenkins was used to run the tests from this project after a successful build of and deploy of the web application.

Useful Resources

Here are a couple of useful links where you can find more information on Selenium:

I decided on the following design principles for the Selenium test project:

Each test should run in its own session

  • Starting a new session means closing the browser and opening it again. The disadvantage to this is that it takes longer to complete a test however the advantage means that any previously run tests don’t pollute the session for the currently running test.
  • The change to the above also means that within Eclipse you can choose to run all tests by running the test suite or you could also selectively choose an individual test to run as each test can be run independently from each other. You could do the same within Buildr or through the command line.

Spring Support

Spring support has been added to the test project classes so that we could take advantage of the following:
  • Dependency injection, example would be connection to the database
  • The ability to run the test cases for different environments based on a spring profile setting
  • Use of Spring support classes, example: jdbctemplate
Important notes to keep in mind:
  • Tests are NOT transactional. Selenium opens a browser and users the applications configured transaction manager.

DbUnit

DbUnit is a JUnit extension targeted at database-driven projects that puts your database into a known state between test runs. DbUnit has the ability to export and import your database data to and from XML datasets.

The tests should not rely on data already in the database since I did not have a dedicated test database and the state of the database is not guaranteed. In certain scenarios we could write tests that use data from the database where we know the data is not going to change. DbUnit is used to populate the database with test data before we run the test and then it removes the data from the database at the end of the test run.

Please refer to the following link in finding out the recommended best practices for DbUnit:
The test project is also using the Spring Test DbUnit project to integrated with the Spring testing framework. It allows you to setup and teardown database tables using simple annotations as well as checking expected table contents once a test completes.

Page Object Model Design Pattern

The Page Object Model is a design pattern to create Object Repository for web UI elements. The following principles apply:
  • Under this model, for each web page in the application there should be corresponding page class
  • This Page class will find the WebElements of that web page and also contains Page methods which perform operations on those WebElements
  • Name of these methods should be given as per the task they are performing i.e., if a loader is waiting for payment gateway to be appear, POM method name can be waitForPaymentScreenDisplay()
Here are some of the advantages of applying the Page Object Model Design Pattern:
  • Page Object Patten says operations and flows in the UI should be separated from verification. This concept makes our code clean and easy to understand
  • Second benefit is the object repository is independent of testcases, so we can use the same object repository for a different purpose with different tools. For example, we can integrate POM with TestNG/JUnit for functional testing and at the same time with JBehave/Cucumber for acceptance testing
  • The number of lines of code are reduced and optimized because of the reusable page methods in the POM classes
  • Methods get more realistic names which can easily be mapped to the operation happening in the UI, i.e. if after clicking on the button we land on the home page, the method name could be 'gotoHomePage()'
Some useful links:

PageFactory and Selenium Support Annotations

The PageFactory class provides a convenient way of initialising the Page Object fields:
  page = PageFactory.initElements(new FirefoxDriver(), TestPage.class);
It can be used to map Page Object properties to fields with matching ids or names. To make it even easier we can do this with the @FindBy annotation:
 @FindBy(id="myFieldId")
 private WebElement myField;
One problem is that every time we call a method on the WebElement the driver will go and find it on the current page again. In an AJAX-heavy application this is what you would like to happen, but in the some cases we know that the element is always going to be there and won't change. We also know that we won't be navigating away from the page and returning. It would be handy if we could "cache" the element once we'd looked it up:
  // The element is now looked up using the name attribute,
  // and we never look it up once it has been used the first time 
  @FindBy(name="myFieldId")
  @CacheLookup
  private WebElement myField;
For more information on the PageFactory please read the following link:

Waiting for an element to exist before looking it up

Selenium tests require a browser to open and a page to load before the code attempts to lookup the expected elements in the page. Selenium has a number of settings to try and cater for this scenario:

Implicit Wait

We can tell Selenium that we would like it to wait for a certain amount of time before throwing an exception when it cannot find the element on the page. Implicit waits will be in place for the entire time the browser is open. This means that any search for elements on the page could take the time the implicit wait is set for.
  WebDriver driver = new FirefoxDriver();
  driver.manage().timeouts().implicitlyWait(10, TimeUnit.SECONDS);
  driver.get("http://url_that_delays_loading");
  WebElement myDynamicElement = driver.findElement(By.id("myDynamicElement"));
During Implicit wait if the Web Driver cannot find it immediately because of its availability, the WebDriver will wait for the mentioned time and it will not try to find the element again during the specified time period. Once the specified time is over, it will try to search the element once again the last time before throwing exception. The default setting is zero. Once we set a time, the Web Driver waits for the period of the WebDriver object instance.

FluentWait

Each FluentWait instance defines the maximum amount of time to wait for a condition, as well as the frequency with which to check the condition. Furthermore, the user may configure the wait to ignore specific types of exceptions whilst waiting, such as NoSuchElementExceptions when searching for an element on the page.

If you have an element which sometime appears in just 1 second and some time it takes minutes to appear than it is better to use fluent wait, as this will try to find the element again and again until it finds it or until the final timer runs out.
 // Waiting 30 seconds for an element to be present on the page, checking
 // for its presence once every 5 seconds.
 Wait wait = new FluentWait(driver)
   .withTimeout(30, SECONDS)
   .pollingEvery(5, SECONDS)
   .ignoring(NoSuchElementException.class);
 
 WebElement foo = wait.until(new Function() {
   public WebElement apply(WebDriver driver) {
     return driver.findElement(By.id("foo"));
   }
 });
Another case where FluentWait can and is used is when certain events on a page cause the DOM tree to be modified, you can end up with a StaleElementException to the reference you have of that element. When this happens you will need to reinitialise the element or look it up again after the DOM tree has been rebuilt. A StaleElementException is thrown when the element you were interacting is destroyed and then recreated. An example of where this happens in the Meterflow application is on showing a Modal dialog and trying to enter values in input texts to submit a form. Here is an example of code that you can use in this scenario:
 
 public MyPage waitForModalDialogToShow() {
   final Wait<WebDriver> wait = new FluentWait<WebDriver>(driver).withTimeout(30, TimeUnit.SECONDS)
     .pollingEvery(5, TimeUnit.SECONDS)
     .ignoring(NoSuchElementException.class, StaleElementReferenceException.class);
   
   wait.until(new Function<WebDriver, WebElement>() {
     public WebElement apply(WebDriver driver) {
       return driver.findElement(By.id("myModelDialog"));
     }
   });
   
   return this;
 }
In situations where you are using the FindBy annotations on a PO class and not explicitly calling driver.findElement and the DOM was changed due to some user events you may also need to reinitialise the PO object so that the fields are looked up again after the DOM has been recreated. To do this you can call the following static method on the PageFactory class:
 
 /**
  * Reinitialise a PageObject by replacing the fields of an already instantiated Page Object. 
  */
  public void initElements() {
    PageFactory.initElements(driver, this);
  }

Explicit WebDriverWait

The WebDriverWait is a specialization of FluentWait that uses WebDriver instances. It is more extendible in the means that you can set it up to wait for any condition you might like. Usually, you can use some of the prebuilt ExpectedConditions to wait for elements to become clickable, visible, invisible, etc.

There can be an instance when a particular element takes more than a minute to load. In that case you don't want to set a huge time to Implicit wait because then your browser will wait the same time for every element. To avoid that situation you can put a separate time on the required element.
  WebDriverWait wait = new WebDriverWait(driver, 10);
  WebElement element = wait.until(ExpectedConditions.elementToBeClickable(By.id("someid")));

Selenium Locator Strategies

There are 8 locators that Selenium’s commands support:
  1. id - Ids are the most preferred way to locate elements on a page, fast and reliable way to locate elements
  2. name - An efficient way to locate an element but unlike Ids, name attributes don’t have to be unique in a page
  3. identifier - Combination of id and name, first checks the @id attribute and if no match is found it tries the @name attribute
  4. css - Locate an element by using CSS selectors to find the element in the page
  5. xpath - Locate an element using an XPath query
  6. link - Locate a link element ("a" tag) by the text used within the link tag
  7. dom - Locate elements that match the JavaScript expression referring to an element in the DOM of the page
  8. ui - Selenium IDE extension (http://ttwhy.org/code/ui-doc.html)

FindBy annotation support

The @FindBy annotation supports the following locators:
id
 My text
 
 @FindBy(id="elementId")
 private WebElement myElement;
name
 
 My text
 @FindBy(name="elementName")
 private WebElement myElement;
className
  
block
 
 @FindBy(className="element-css")
 private WebElement myElement;
css
 
block
block
Google
 @FindBy(css="div.element-css")
 private WebElement myElementEx1;

 @FindBy(css="div.element-css[id='myElementId']")
 private WebElement myElementEx2;

 @FindBy(css="input[name='textName'][type='text']")
 private WebElement myElementEx3;

 @FindBy(css="a[name='link']")  
 private WebElement myElementEx4;
linkText
 Google
 @FindBy(linkText="Google")
 private WebElement myElement;
partialLinkText
 Google
 @FindBy(partialLinkText="Goo")
 private WebElement myElement;
tagName
 
 Link1
 
 Link2

 Link3
 
 @FindBy(tagName = "a")
 private List myLinks;
xpath
  
block
 
 @FindBy(xpath="//span[@class='element-css']")
 private WebElement myElement;

A few examples

  • Finding a cell in a table generated by Primefaces, an example of what the generated html table would look like:
 <div id="myFormId:myTableId" class="ui-datatable ui-widget">
  <div class="ui-datatable-tablewrapper">
    <table role="grid">
      <thead id="myFormId:myTableId_head">
        <tr role="row">
          <th id="myFormId:myTableId:j_idt44" class="ui-state-default" role="columnheader">
            <span class="ui-column-title">Column 1</span>
          </th>
          <th id="myFormId:myTableId:j_idt45" class="ui-state-default" role="columnheader">
            <span class="ui-column-title">Column 2</span>
          </th>
        </tr>
      </thead>
      <tfoot id="myFormId:myTableId_foot"/>
      <tbody id="myFormId:myTableId_data" class="ui-datatable-data ui-widget-content">
        <tr class="ui-widget-content ui-datatable-even ui-datatable-selectable" role="row">
          <td role="gridcell">
            <span id="myFormId:myTableId:0:col1">Row 1 - Value of column 1</span>
          </td>
          <td role="gridcell">
            <span id="myFormId:myTableId:0:col2">Row 1 - Value of column 2</span>
          </td>
        </tr>
        <tr class="ui-widget-content ui-datatable-even ui-datatable-selectable" role="row">
          <td role="gridcell">
            <span id="myFormId:myTableId:2:col1">Row 2 - Value of column 1</span>
          </td>
          <td role="gridcell">
            <span id="myFormId:myTableId:2:col2">Row 2 - Value of column 2</span>
          </td>
        </tr>
      </tbody>
    </table>
  </div>
 </div>
 // find all the table cells that match the css selector
 @FindBy(css="div[id='myFormId:myTableId'] > div > table > tbody > tr > td > span")

 // same as above but won't only check the next element in tree and will keep searching until a match is found
 @FindBy(css="div[id='myFormId:myTableId'] table td span")

 // find all the table cells that match the xpath query
 @FindBy(xpath="//div[@id='myFormId:myTableId']/div/table/tbody/tr/td/span")

 // same as above but won't only check the next element in tree and will keep searching until a match is found
 @FindBy(xpath="//div[@id='myFormId:myTableId']//table//td//span")

 // to find a cell that contains text
 @FindBy(xpath="//div[@id='myFormId:myTableId']//table//td//span[contains(text(),'Row 1 - Value of column 1')]")
  • Find an element whose ID matches part of an expression, the following examples use an "a" link element but can be any valid html tag:
 <a id="j_idt38:myLink" href="/tmp.xhtml" class="ui-link ui-widget">Tmp</a>
 // css strategy to find an element whose ID starts with 'j_idt38'
 @FindBy(css="a[id^='j_idt38']")

 // css strategy to find an element whose ID ends with 'myLink'
 @FindBy(css="a[id$='myLink']")

 // css strategy to find an element whose ID contains 'myLink'
 @FindBy(css="a[id*='myLink']")

 // xpath query strategy to find an element whose ID contains 'myLink'
 @FindBy(xpath="//a[contains(@id, 'myLink')]")
  • Perform Javascript actions, the following example describes a javascript event being carried out when the mouse hovers over certain menu items:
 <li id="topNavFrm:adminSubmenu">
  <a href="#">
    <span />
    <span >Administration</span>
    <span />
  </a>
  <ul role="menu">
    <li id="topNavFrm:usersSubMenu">
      <a href="#">
        <span />
        <span>Users</span>
        <span />
      </a>
      <ul>
        <li>
          <a id="topNavFrm:userGroupMenuItem" href="/users/groups.xhtml">
            <span>User Groups</span>
          </a>
        </li>
        <li>
          <a href="/users/users.xhtml">
            <span>Users</span>
          </a>
        </li>
      </ul>
    </li>
  </ul>
 </li>
 @FindBy(id="topNavFrm:adminSubmenu")
 private WebElement adminMenu;

 public UsersAdminPage mouseOverUsersDetailMenu() {
   Actions action = new Actions(driver);
   action.moveToElement(adminMenu).perform();
       
   WebElement usersSubElement = adminMenu.findElement(By.cssSelector("li[id='topNavFrm:usersSubMenu'] a"));
   action.moveToElement(usersSubElement);
       
   WebElement usersAdminSubElement = adminMenu.findElement(By.id("topNavFrm:usersMenuItem"));
   action.moveToElement(usersAdminSubElement);
       
   action.click();
   action.perform();
  
   return this;
 }

XPath Query Testing

Testing XPath queries can be done within the browser, this sections shows examples of how you could do it with some of them:

Chrome

To type in an xpath to search a page:
  • Press F12 to open Chrome Developer Tool
  • In "Elements" panel, press Ctrl+F
  • In the search box, type in XPath or CSS Selector, if elements are found, they will be highlighted in yellow.
To copy an xpath from an element in the page (same can be done to retrieve CSS path):
  • Right click on element and select Inspect Element
  • In elements view right click on element line and select Copy XPath

Firefox

To type in an xpath to search a page:
  • Install Firebug
  • Install Firepath
  • Press F12 to open Firebug
  • Switch to FirePath panel
  • In dropdown, select XPathor CSS
  • Type in to locate
To copy an xpath from an element in the page:
  • Click on Inspect element button and place your tip of cursor on any element for which you want to find XPath
  • Right Click on highlighted code and Select Copy XPath

Wednesday, March 11, 2015

JSF2 Coding and Design Standards

The following details coding and design standards I have chosen for a web project I am currently working on.

Environment Details

  • Java 1.7
  • WebSphere Application Server 8.5 (with IBM SDK 1.7)
    • JEE 6
    • Servlet 3.0
    • JSP 2.2
    • JSF 2.0 (MyFaces 2.0)
    • el-api 2.2
  • JBoss EAP 6.3.0
    • JEE 6
    • Servlet 3.0
    • JSP 2.2
    • JSF 2.1 (Mojarra 2.1.28)
    • el-api 2.2, JSTL 1.2
  • PrimeFaces 5.1
  • SpringFramework 4.1.1
  • Relational database (Oracle 12c / Informix)
The web application is broken up into the following layers :

  • Service layer
    • Business logic layer
    • Data access layer
  • Presentation layer
    • JSF managed beans
    • XHTML pages

Business logic layer

The business logic layer responsibility is to:
  • Contain all business specific logic
  • Define transactional boundaries using Spring transaction management
  • Handle exceptions

Data access layer

Normally I would not have had a data access layer and just have the business logic layer handle all the DB transactions. However for this project we needed to support multiple databases so having the DB interactions in a separate layer enables us to choose which DB classes to use for a particular database. We made a decision to use Spring JDBC and not have any ORM library. The data access layer should contain methods that are only used query or to update the database, there should be no business logic code in them.

JSF Managed Beans

The JSF managed beans are Java objects managed by JSF and along with the Facelets XHTML pages they form part of the presentation layer of the web application.

Managed Bean Scope

Depending on your need a managed bean can have one of the following scopes:
  • Application Scoped
  • Session Scoped
  • View Scoped
  • Request Scoped
  • Custom Scoped
  • None 

Spring integration

You would need to add the following to your web.xml file:
    
        contextConfigLocation
        /WEB-INF/web-ctx.xml
    

    
        org.springframework.web.context.ContextLoaderListener
    
    
        org.springframework.web.context.request.RequestContextListener
    
 
And the Spring EL resolver to your faces-config.xml:
  
    org.springframework.web.jsf.el.SpringBeanFacesELResolver
  
In order to add Spring autowire capabilities to a JSF managed bean we made use of Springs WebApplicationContextUtils class:
 @PostConstruct
 private void init() {
   ExternalContext externalContext = FacesContext.getCurrentInstance().getExternalContext();
   ServletContext servletContext = (ServletContext) externalContext.getContext();
   WebApplicationContextUtils.getRequiredWebApplicationContext(servletContext).getAutowireCapableBeanFactory().autowireBean(this);
 }

A view scoped bean lives for as long as you interact with the same view. As soon as you navigate away to another view then the view scoped bean will not be available in the next request. View scoped beans need to implement the Serializable interface.

In order to have Spring autowiring capabilities available in view scoped beans you should make the autowired Spring managed beans transient so that they are not serialised and on deserialization you will need to autowire the Spring beans in the same way we did for the PostConstruct init method:
  
  private Object readResolve() {
   init();
   return this;
 }
Another issue with view scoped managed beans is that you won't be able to inject a resource bundle into a view scoped managed bean as the ResourceBundle class is not serializable. To get around this you can do one of the following:

Use a different scope for your bean and not view scoped
Make your resource bundle transient so that it doesn't get serialized and then manually reinitialise it on deserialisation:
 
 @ManagedProperty("#{msg}")
 private transient ResourceBundle msgBundle;

 private Object readResolve() {
   msgBundle = Faces.getApplication().evaluateExpressionGet(Faces.getContext(), "#{msg}", ResourceBundle.class);
   return this;
 }

XHTML web view pages

What files need to be put in the /WEB-INF directory?

The following file types should be saved under the /WEB-INF directory
  • Templates
  • Includes
  • Error pages
Having these files in the /WEB-INF directory prevents the end user from being able to open them directly by entering its URL in the browser address bar. The normal pages and template clients which are intended to be accessed directly must not be placed in /WEB-INF folder.

The composite component files are also not supposed to be publicly accessible, however they are by specification required to be placed in /resources folder which is by default publicly accessible. If you make sure that you access all resources using the provided components so that they are never accessed by /resources in URL (but instead by /javax.faces.resource), then you can add a security constraint to the web.xml to block all public access to the /resources folder. However doing this blocks access from 3rd party libraries like DHTMLX that use javascript to set paths to image locations.

Avoid using the bindings attribute

In JSF 2 it is considered bad practice to use the bindings attribute to bind UI components to bean properties and is recommended to avoid doing this. There are careful considerations to take into account if you do decide to use a binding attribute in particular the scope of the bean should be request scope and not anything more broader than that. The following links have more detail on this topic:

preRenderView

In JSF 2 you can attach a javax.faces.event.PreRenderViewEvent system event to perform custom task before a view root (JSF page) is displayed. The following JSF snippet shows an example of this event being declared:
   <f:event listener="#{myBean.myMethod}" type="preRenderView" />
Use the preRenderView event when you want to execute a method during the beginning of the render response phase, right before the HTML is been rendered. This is particularly useful if you want to perform actions based on model values set by during update model values phase. The preRenderView event is invoked on every HTTP request including ajax requests. You can if necessary add a check on FacesContext#isPostback() to perform the action on initial request only.

Exception handling and Error pages

Service layer

Any exception thrown inside the business logic layer should be caught and handled accordingly and if necessary wrapped in a custom exception and thrown back to the presentation layer. Although try to handle the exception in the service layer otherwise there is extra work for the presentation layer to do in order to to catch all exceptions and to send a meaningful message back to the user.

A common Spring JDBC exception is the EmptyResultDataAccessException runtime exception, this should be caught and handled in the data access layer. This exception is thrown when a result was expected to have at least one row (or element) but zero rows (or elements) were actually returned. The DAO class should catch the EmptyResultDataAccessException exception, wrap it in a custom exception and throw it back to the service class. The service class can do one of the following:
  • Catch the custom exception and using Guava's API return an absent Optional of the type that is expected in the return. 
  • Throw the custom exception back to the GUI. Preferably avoid doing this, it just means the GUI has to catch the exception and decide what to do with it.
  • Return null. This should be the last resort and preferably you should never do this. The calling class would have to handle cases where there is null and since it is a runtime exception it won't always be apparent. Read the article mentioned above for more detail.

Presentation layer

The methods within the JSF managed beans should not throw any exceptions but should catch and handle all checked exceptions so that an appropriate message or response is sent back to the user. Although in some cases it may be necessary to throw an exception, a typical example would be when the IOException is thrown by the FacesContext when redirecting to a page.

FullAjaxExceptionHandlerFactory

  • The FullAjaxExceptionHandler will transparently handle exceptions during ajax requests exactly the same way as exceptions during synchronous (non-ajax) requests.
  • The FullAjaxExceptionHandler does not deal with normal (non-ajax) requests at all. To properly handle JSF and EL exceptions on normal requests as well, you need an additional FacesExceptionFilter.
  • Read this blog entry for more detail on handling exceptions during JSF ajax request.

FacesExceptionFilter

The FacesExceptionFilter will solve 2 problems with exceptions thrown in JSF methods.
  1. Mojarra's FacesFileNotFoundException needs to be interpreted as 404. We are using MyFaces so this shouldn't apply to us.
  2. Root cause needs to be unwrapped from FacesException and ELException to utilize standard Servlet API error page handling. Without this filter RuntimeExceptions would end up in an generic HTTP 500 error page instead of the one specific to the exception.

Session expiry

  • Managed beans (especially Session and Application scoped beans) should handle scenarios where a user tries to access a page that hasn't been fully initialised. This could happen if the user navigated to the page by another means other than its intended one, example by entering in the URL to the page directly in the browser and by-passing any initialisation methods, or when the users session has expired and they are forced to log back into the application. In this case they will be redirected back to the page they were currently working on.
  • One way to handle this scenario is to add a preRenderView event to the page that checks whether or not the page has been initialised correctly. If not you can redirect to another page that will be or if possible you can initialise the variable that need to be initialised.
  public void preRenderView() throws IOException {
   if (myObject == null) {
     LOG.debug("Expected variable to be initialised, possibly cleared from session on expiry. Redirecting to home page");
     Faces.redirect("home.xhtml");
   }
 }

Caching

Spring Caching

The Spring caching abstraction applies caching to Java methods, reducing the number of executions based on the information available in the cache. That is, each time a targeted method is invoked, the abstraction will apply a caching behavior checking whether the method has been already executed for the given arguments. If it has, then the cached result is returned without having to execute the actual method, if it has not, then the method is executed, the result cached and returned to the user so that the next time the method is invoked, the cached result is returned. This way, expensive methods (whether CPU or IO bound) can be executed only once for a given set of parameters and the result reused without having to actually execute the method again. The caching logic is applied transparently without any interference to the invoker.

Ehcache

Ehcache is an open source, standards-based cache for boosting performance, offloading your database, and simplifying scalability. It's the most widely-used Java-based cache because it's robust, proven, and full-featured. I configured the Spring cache to use Ehcache to cache static data that is often requested by the UI. Annotations are used on the DAO methods in order to cache the results or to clear out the elements stored in a cache.
  
    <cache:annotation-driven cache-manager="ehCacheManager" />

    <bean id="ehCacheManager" class="org.springframework.cache.ehcache.EhCacheCacheManager" 
        p:cache-manager-ref="ehcache"/>
        
    <bean id="ehcache" class="org.springframework.cache.ehcache.EhCacheManagerFactoryBean" 
        p:config-location="classpath:service-ehcache.xml"/>

Browser Caching

CacheControlFilter

If you have turned off caching in the browser for your web application than you will notice that the back button in a browser would request the page from the server.
  • If the page was stored in the session than JSF will return whatever is in the session otherwise it would fetch a new page. 
  • If the page was cached the browser would fetch the page from the browsers cache.
If you had a view scoped bean and caching was enabled you would notice that ajax calls won't be remembered in a browsers back button history. If you want that page added to the browsers cache you would need to use a non-ajax request.

I use OmniFaces CacheControlFilter which is has more control over how cache-related headers of the response are handled, web.xml:
 <filter>
  <filter-name>cache30min</filter-name>
  <filter-class>org.omnifaces.filter.CacheControlFilter</filter-class>
  <init-param>
    <param-name>expires</param-name>
    <param-value>30m</param-value>
  </init-param>
</filter>

<filter-mapping>
  <filter-name>cache30min</filter-name>
  <url-pattern>/*</url-pattern>
</filter-mapping>

Static Resource Caching

The JSF resource handler automatically caches resources (placed in the /resources directory and referenced via , and and thus not via the plain HTML way). To satisfy Google recommendations you could set the Expires date a bit further in the future. It defaults to 7 days (604800000 milliseconds) while performance testing tools like Google Page Speed and Yahoo YSlow recommends a minimum of 30 days (2592000000 milliseconds). In MyFaces you can do this by adding the following context parameter to your web.xml file:
  
  <context-param>
   <param-name>org.apache.myfaces.RESOURCE_MAX_TIME_EXPIRES</param-name>
   <param-value>2592000000</param-value>   
 </context-param>
If you'd like to force reloading by resources because you changed them, then use resource library versioning. While developing you may set the cache headers to have no cache but in production you would want to cache resources. In this case when resources have changed you would want to increment the version in the resource folder. Development environment could either set the RESOURCE_MAX_TIME_EXPIRES parameter to 0 or it should have the following head meta attributes defined in the Facelets template:
 <meta http-equiv="Pragma" content="no-cache" />
 <meta http-equiv="Expires" content="0" />
 <meta http-equiv="cache-control" content="no-cache, no-store, must-revalidate" />

JSF Component Caching (OmniFaces o:cache)

The OmniFaces component allows to cache a fragment of rendered markup. The first request for a page that has this component on it will cause this markup to be put into the cache. Then for subsequent requests the cached content is used directly and none of the components, backing beans and services that were used to generate this content in the first place will be consulted.

UnmappedResourceHandler

This ResourceHandler implementation allows the developer to map JSF resources on an URL pattern of /javax.faces.resource/* (basically, the value of ResourceHandler.RESOURCE_IDENTIFIER) without the need for an additional FacesServlet prefix or suffix URL pattern in the default produced resource URLs, such as /javax.faces.resource/faces/css/style.css or /javax.faces.resource/css/style.css.xhtml. The OmniFaces resource handler UnmappedResourceHandler will produce unmapped URLs like /javax.faces.resource/css/style.css. This has the major advantage that the developer don't need the #{resource} EL expression anymore in order to properly reference relative URLs to images in CSS files.

Our web project is using 3rd party libraries (like DHTMLX) that reference images without the #{resource} EL expression the UnmappedResourceHandler comes in handy as we don't have to edit these 3rd party libraries to get them to work.

The UnmappedResourceHandler does not support the library attribute, therefore this:
  <h:outputStylesheet library="css" name="style.css" />
Would now be:
  <h:outputStylesheet name="css/style.css" />
Because the library attribute is not supported neither is library versioning. 

UI dropdown menus

Since JSF 2.0 there's no need anymore to provide a SelectItem[] or List, a T[] and List are accepted as well and you can access the current item by var attribute). Here is an example of how you could use Enums for the dropdowns:
Enum class (should be in its own a separate file):
 public enum Language {
  ENGLISH("english"),
  SPANISH("spanish");

  private String label;

  private Language(final String label) {
    this.label = label;
  }

  public String getLabel() {
    return label;
  }
}
Xhtml page (notice the label is being read from the resource bundle):
 <p:selectOneMenu id="languageSel" value="#{userDetails.language}">
  <f:selectItems value="#{userDetails.languages}" var="lang" itemValue="#{lang}" itemLabel="#{msg[lang.label]}" />
 </p:selectOneMenu>
JSF managed bean:
private Language language;

public Language getLanguage() {
  return language;
}

public void setLanguage(final Language language) {
  this.language = language;
}

public Language[] getLanguages() {
  return Language.values();
}

Choosing between action and actionListener

actionListener

Use actionListener if you want have a hook before the real business action gets executed, e.g. to log it, and/or to set an additional property (by ), and/or to have access to the component which invoked the action (which is available by ActionEvent argument). So, purely for preparing purposes before the real business action gets invoked. The actionListener method has by default the following signature:
import javax.faces.event.ActionEvent;
// ...
public void actionListener(ActionEvent event) {
  // ...
}
And it's supposed to be declared as follows, without any method parentheses:
 <h:commandXxx ... actionListener="#{bean.actionListener}" />
Note that you can't pass additional arguments by EL 2.2. You can however override the ActionEvent argument altogether by passing and specifying custom argument(s). The following examples are valid:
<h:commandXxx ... actionListener="#{bean.methodWithoutArguments()}" />
<h:commandXxx ... actionListener="#{bean.methodWithOneArgument(arg1)}" />
<h:commandXxx ... actionListener="#{bean.methodWithTwoArguments(arg1, arg2)}" />
(note the importance of the parentheses in the argumentless method, if they were absent, JSF would still expect a method with ActionEvent argument)

action

Use action if you want to execute a business action and if necessary handle navigation. The action method can (thus, not must) return a String which will be used as navigation case outcome (the target view). A return value of null or void will let it return to the same page and keep the current view scope alive. A return value of an empty string or the same view ID will also return to the same page, but recreate the view scope and thus destroy any currently active view scoped beans and, if applicable, recreate them.

The action method can be any valid MethodExpression, also the ones which uses EL 2.2 arguments, for example:
 <h:commandLink value="submit" action="#{bean.edit(item)}" />
With this method:
 public void edit(Item item) {
  // ...
 } 
Note that when your action method solely returns a string, then you can also just specify exactly that string in the action attribute. Thus, this is totally clumsy:
 <h:commandLink value="Go to next page" action="#{bean.goToNextpage}" />
With this senseless method returning a hardcoded string:
 public String goToNextpage() {
  return "nextpage";
 }
Instead, just put that hardcoded string directly in the attribute:

 <h:commandLink value="Go to next page" action="nextpage" />
Please note that this in turn indicates a bad design: navigating by POST. This is not user nor SEO friendly and is supposed to be solved as:
 
 <h:link value="Go to next page" outcome="nextpage" />

Invocation order

The actionListeners are always invoked before the action in the same order as they are been declared in the view and attached to the component. The following example will invoke Bean#listener1(), SomeActionListener#processAction(), Bean#setProperty() and Bean#submit() in this order:
 <h:commandLink value="submit" actionListener="#{bean.listener1}" action="#{bean.submit}">
   <f:actionListener type="com.example.SomeActionListener" />
   <f:setPropertyActionListener target="#{bean.property}" value="some" />
 </h:commandLink>

Exception handling

The actionListener supports a special exception called AbortProcessingException. If this exception is thrown from an actionListener method, then JSF will skip any remaining action listeners and the action method and proceed to render response directly. You won't see an error/exception page, JSF will however log it. This will also implicitly be done whenever any other exception is being thrown from an actionListener. So, if you intend to block the page by an error page as result of a business exception, then you should definitely be performing the job in the action method.

If the sole reason to use an actionListener is to have a void method returning to the same page, then that's a bad one. The action methods can perfectly also return void, on the contrary to what some IDEs let you believe via EL validation. Note that the PrimeFaces showcase examples are littered with this kind of actionListeners over all place. This is indeed wrong. Don't use this as an excuse to also do that yourself.

Client-side vs Server side State saving

HTTP is stateless and JSF is stateful. The JSF component tree is subject to dynamic (programmatic) changes. JSF simply needs to know the exact state as it was when the form had been displayed to the enduser, so that it can successfully process the whole JSF lifecycle based on the information provided by the original JSF component tree when the form has been submitted back to the server. The component tree provides information about the request parameter names, the necessary converters/validators, the bound managed bean properties and action methods.

Saving state on the client results in less of a load on the server at the expense of additional network traffic. This is because by default, client side is stored as a large hidden (javax.faces.ViewState) input field in web browsers. Saving state on the client also works better in failover situations because even if the server is down, the state won't be lost. Setting to client increases the network bandwidth usage but decreases the server memory usage, it also prevents ViewExpiredExceptions when the session has expired or when the client opens too many views. Using HTTP compression like gzip reduces the size of the HTTP message. When the state saving is set to client, then JSF won't store anything in session. You can do that by the following context param in web.xml:
 <context-param>
   <param-name>javax.faces.STATE_SAVING_METHOD</param-name>
   <param-value>client</param-value>
 </context-param>
It will then be serialized to an encrypted string in a hidden input field with the name javax.faces.ViewState of the form.

Resource bundle

The following snippets of code can be used to access a resource bundle property from a JSF managed bean.

faces-config.xml:
 <resource-bundle>
   <base-name>com.mydomain.jsf.messages.ApplicationResources</base-name>
   msg
 </resource-bundle>

Request, Session, Application Scoped Managed Bean

 @ManagedProperty("#{msg}") // bundle
 private ResourceBundle text; // +setter
 
 @ManagedProperty("#{msg['some.key']}") // key
 private String someKey; // +setter
 
 public void someAction() {
   String someKeyInBundle = text.getString("some.key");
   // ... 
 }

View Scoped Managed Bean

 @ManagedProperty("#{msg}") // bundle
 private transient ResourceBundle text; // +setter
 
 @ManagedProperty("#{msg['some.key']}") // key
 private transient String someKey; // +setter
 
 public void someAction() {
   String someKeyInBundle = text.getString("some.key");
   // ... 
 }
 private Object readResolve() {
   FacesContext context = FacesContext.getCurrentInstance();    
   myBundle = context.getApplication().evaluateExpressionGet(context, "#{text}", ResourceBundle.class);
   return this;
 }

Alternative means without injection and can be used in all scopes

  public void someAction() {
   FacesContext context = FacesContext.getCurrentInstance();
   
   // bundle
   ResourceBundle text = context.getApplication().evaluateExpressionGet(context, "#{msg}", ResourceBundle.class);
   String someKeyInBundle = text.getString("some.key");
 
   // specific key
   String someKey = context.getApplication().evaluateExpressionGet(context, "#{msg['some.key']}", String.class);
 
   // ... 
 }

OmniFaces Messages helper

The message resolver is registered in a custom web listener:
  @WebListener
  public class MyWebListener implements ServletContextListener {

    @Override
    public void contextDestroyed(ServletContextEvent arg0) {
      // empty method
    }

    @Override
    public void contextInitialized(ServletContextEvent arg0) {
      setMessageResolver();
    }

   /**
    * Set the message resolver to the ApplicationResources resource bundle. The
    * resolver can only be set once which is why it is done in this listener
    * class triggered by the contextInitialized method
    */
    private void setMessageResolver() {
      Messages.setResolver(new Messages.Resolver() {
        private static final String BASE_NAME = "com.mydomain.jsf.messages.ApplicationResources";

        public String getMessage(final String message, final Object... params) {
            final ResourceBundle bundle = ResourceBundle.getBundle(BASE_NAME, Faces.getLocale());
            if (bundle.containsKey(message)) {
                return MessageFormat.format(bundle.getString(message), params);
            }
            return MessageFormat.format(message, params);
        }
      });
    }
  }
Example to add a message:
  Messages.create("key").error().add();

Navigation

There are a number of options to choose from when navigating from one page to another using a link or a button. The below offers some guidelines to a few of them.

When navigating from one page to another using a link you would normally do this with an action or an URL. Whenever possible use a link that will issue a GET request and redirect the browser to the URL. At the very least these links will make the page bookmarkable.

h:link

Clicking on this link issues a bookmarkable GET request. It can also be achieved with the PrimeFaces p:link which is an extension to the h:link tag.

xhtml page:
<h:link value="Link 1" outcome="home-page">
Outcome maps to a navigation rule in the faces-config.xml file. You don't need to specify a redirect element in the navigation rule.

faces-config.xml:
<navigation-case>
 <from-outcome>home-page</from-outcome>
 <to-view-id>/home.xhtml</to-view-id>
 <redirect />
</navigation-case>

h:outputLink

Clicking on this link issues a bookmarkable GET request.

xhtml page:
 <h:outputLink value="#{request.contextPath}/home.xhtml">Link 2</h:outputLink>

h:commandLink

By default clicking on this link issues a non-bookmarkable POST request. It can also be achieved with the Primefaces p:commandLink which is an extension to the h:commandLink tag. The h:commandButton works in a similar way.

xhtml page
In this example notice how the action is not bound to a managed bean method but uses a URL instead:
<h:form>
  <h:commandLink value="Link 3" action="/home.xhtml" />
</h:form>
In order to make the above link bookmarkable you would either need to call an action method that returns a faces-config navigation mapping that has a redirect element on it or amend the code so that you append redirect to the end of the URL like the following:
<h:form>
  <h:commandLink value="Link 3" action="/home.xhtml?faces-redirect=true" />
</h:form>

p:menuitem

The Menuitem is used by various menu components of PrimeFaces. You can either specify a URL to a page you wish the user to be redirected to or you specify an action method on a managed bean that will redirect to a page based on the navigational rules defined in the faces-config file. Both mechanisms would generate bookmarkable links. The following example uses the URL attribute:

xhtml page:
<p:menuitem value="Link" url="/home.xhtml" />