Pages

Running Selenium Cucumber Tests in Jenkins

This article shows how to configure and run Selenium (+ Cucumber) Tests in Jenkins. Before we dive into more details we have to have Jenkins installed in a server. Here is a quick way to setup Jenkins in a linux server.

OK all done, lets go though with the steps,

Step 1
First you need to install google chrome. This is called as chrome in headless mode. Because you really can't see the chrome window when you are running tests in Jenkins.

 wget -qO - https://dl-ssl.google.com/linux/linux_signing_key.pub | sudo apt-key add -  
 sudo sh -c 'echo "deb http://dl.google.com/linux/chrome/deb/ stable main" >> /etc/apt/sources.list.d/google.list'  
 sudo apt-get update  
 sudo apt-get install google-chrome-stable  

Step 2
Then install xvfb. OK what is this xvfb ?
Based on Wikipedia,

Xvfb or X virtual framebuffer is a display server implementing the X11 display server protocol. In contrast to other display servers, Xvfb performs all graphical operations in memory without showing any screen output. From the point of view of the client, it acts exactly like any other X display server, serving requests and sending events and errors as appropriate. However, no output is shown. This virtual server does not require the computer it is running on to have a screen or any input device. Only a network layer is necessary.


 sudo apt-get install xvfb  

Then start xvfb
 Xvfb :1 -screen 5 1024x768x8 &  


Step 3
OK , server changes are done. Now its time to move into Jenkins configurations.

First Install this plugin, (Jenkins -> Manage Jenkins --> Manage Plugins)
https://wiki.jenkins-ci.org/display/JENKINS/Cucumber+Reports+Plugin

Why do you we need this ?
This plugin allows Jenkins to show Selenium + cucumber results as a graph with screenshots.

So in order to generate graphs this plugin need the report.json file that generated from Selenium + cucumber.

 @RunWith(Cucumber.class)  
 @Cucumber.Options(glue = {"classpath:com/rd/uat"}, strict = true, format = {  
     "pretty", "html:target/cukes", "json:target/cukes/report.json", "junit:target/cukes/junit.xml"})  
 public class RunCukes {  
 }  


Here is the plugin configuration in Jenkins.
Create Jenkins Job --> Then add this as "Post build Step"


Step 4
Add following environment variable to Jenkins. (Jenkins --> Manage Jenkins --> Configure System)

 DISPLAY=:1.5  

OK We just configure Jenkins to run selenium and Cucumber Tests.
Now run the Jenkins job and check the cucumber reports. :)
Here are some sample reports,



Secure your REST API using Spring Security Oauth2

This tutorial shows how to secure your REST API using spring security oauth2. If you don't know anything about oauth2 please followup the below tutorials,

Hold on, if you really don't know the basic concepts of spring please look at it first.

OK, we are fine now. No more prerequisites.

Not like other tutorials this implementation is using custom JDBCTokenStore to store client id/secrets and user authentication details in MySQL DB.
Source code : https://github.com/rajithd/spring-security-oauth2-rest

Here I'm going to implement 3-legged oauth flow and please check the below diagram in order to understand this.




Lets start,

Step 1
Create database as oauth and then use import.sql file to create tables and add some seed data.
Before running make sure to change the db properties located in resources folder. (https://github.com/rajithd/spring-security-oauth2-rest/blob/master/src/main/resources/database.properties)

 create database oauth;  
 use oauth;  
 source <path/to/resorce/folder>/import.sql;  

Step 2
Build the project using maven

 mvn clean install -DskipTests  

Step 3
copy the war file into tomcat/webapps then start the tomcat

Fetch request_token

 http://localhost:8080/oauth2/oauth/token?grant_type=password&client_id=rajith-client-id&client_secret=12345&username=rajith&password=password  

Response
 {  
  access_token: "f833a754-0d6c-4595-92c8-99b202ea6dd4"  
  token_type: "bearer"  
  refresh_token: "967068eb-13d1-4d18-8dd8-b89b2124d5d6"  
  expires_in: 4  
  scope: "read trust write"  
 }  

Fetch access_token by submitting request_token


 http://localhost:8080/oauth2/oauth/token?grant_type=refresh_token&client_id=rajith-client-id&refresh_token=967068eb-13d1-4d18-8dd8-b89b2124d5d6&client_secret=12345  

Response

 {  
 access_token: "d78dd4c7-41c3-443d-a85e-3716ceefc66f"  
 token_type: "bearer"  
 refresh_token: "967068eb-13d1-4d18-8dd8-b89b2124d5d6"  
 expires_in: 4  
 scope: "read trust write"  
 }  

Accessing protected resource


 http://localhost:8080/oauth2/test/ateam?access_token=d78dd4c7-41c3-443d-a85e-3716ceefc66f  

You can use Authorization header to send the access token for protected resources.

 Authorization Bearer d78dd4c7-41c3-443d-a85e-3716ceefc66f  


Main configuration file is located in under webapps (spring-security.xml)

 <?xml version="1.0" encoding="UTF-8" ?>  
 <beans xmlns="http://www.springframework.org/schema/beans"  
     xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"  
     xmlns:oauth="http://www.springframework.org/schema/security/oauth2"  
     xmlns:sec="http://www.springframework.org/schema/security"  
     xsi:schemaLocation="http://www.springframework.org/schema/security/oauth2 http://www.springframework.org/schema/security/spring-security-oauth2-1.0.xsd  
     http://www.springframework.org/schema/security http://www.springframework.org/schema/security/spring-security-3.2.xsd  
     http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd">  
   <http pattern="/oauth/token" create-session="stateless" authentication-manager-ref="clientAuthenticationManager"  
      xmlns="http://www.springframework.org/schema/security">  
     <intercept-url pattern="/oauth/token" access="IS_AUTHENTICATED_FULLY"/>  
     <anonymous enabled="false"/>  
     <http-basic entry-point-ref="clientAuthenticationEntryPoint"/>  
     <!-- include this only if you need to authenticate clients via request parameters -->  
     <custom-filter ref="clientCredentialsTokenEndpointFilter" after="BASIC_AUTH_FILTER"/>  
     <access-denied-handler ref="oauthAccessDeniedHandler"/>  
   </http>  
   <!-- The OAuth2 protected resources are separated out into their own block so we can deal with authorization and error handling  
     separately. This isn't mandatory, but it makes it easier to control the behaviour. -->  
   <http pattern="/test/*" create-session="never" entry-point-ref="oauthAuthenticationEntryPoint"  
      access-decision-manager-ref="accessDecisionManager" xmlns="http://www.springframework.org/schema/security">  
     <anonymous enabled="false"/>  
     <intercept-url pattern="/test/*" access="ROLE_USER"/>  
     <custom-filter ref="resourceServerFilter" before="PRE_AUTH_FILTER"/>  
     <access-denied-handler ref="oauthAccessDeniedHandler"/>  
   </http>  
   <bean id="oauthAuthenticationEntryPoint"  
      class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">  
     <property name="realmName" value="test"/>  
   </bean>  
   <bean id="clientAuthenticationEntryPoint"  
      class="org.springframework.security.oauth2.provider.error.OAuth2AuthenticationEntryPoint">  
     <property name="realmName" value="test/client"/>  
     <property name="typeName" value="Basic"/>  
   </bean>  
   <bean id="oauthAccessDeniedHandler"  
      class="org.springframework.security.oauth2.provider.error.OAuth2AccessDeniedHandler"/>  
   <bean id="clientCredentialsTokenEndpointFilter"  
      class="org.springframework.security.oauth2.provider.client.ClientCredentialsTokenEndpointFilter">  
     <property name="authenticationManager" ref="clientAuthenticationManager"/>  
   </bean>  
   <bean id="accessDecisionManager" class="org.springframework.security.access.vote.UnanimousBased"  
      xmlns="http://www.springframework.org/schema/beans">  
     <constructor-arg>  
       <list>  
         <bean class="org.springframework.security.oauth2.provider.vote.ScopeVoter"/>  
         <bean class="org.springframework.security.access.vote.RoleVoter"/>  
         <bean class="org.springframework.security.access.vote.AuthenticatedVoter"/>  
       </list>  
     </constructor-arg>  
   </bean>  
   <authentication-manager id="clientAuthenticationManager" xmlns="http://www.springframework.org/schema/security">  
     <authentication-provider user-service-ref="clientDetailsUserService"/>  
   </authentication-manager>  
   <bean id="passwordEncoder"  
      class="org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder">  
     <constructor-arg name="strength" value="11"/>  
   </bean>  
   <authentication-manager alias="authenticationManager" xmlns="http://www.springframework.org/schema/security">  
     <authentication-provider user-service-ref="userService">  
       <password-encoder ref="passwordEncoder"/>  
     </authentication-provider>  
   </authentication-manager>  
   <bean id="clientDetailsUserService"  
      class="org.springframework.security.oauth2.provider.client.ClientDetailsUserDetailsService">  
     <constructor-arg ref="clientDetails"/>  
   </bean>  
   <!-- Used for the persistenceof tokens (currently an in memory implementation) -->  
   <bean id="tokenStore" class="org.springframework.security.oauth2.provider.token.store.JdbcTokenStore">  
     <constructor-arg ref="dataSource"/>  
   </bean>  
   <bean id="tokenServices" class="org.springframework.security.oauth2.provider.token.DefaultTokenServices">  
     <property name="tokenStore" ref="tokenStore"/>  
     <property name="supportRefreshToken" value="true"/>  
     <property name="clientDetailsService" ref="clientDetails"/>  
   </bean>  
   <bean id="oAuth2RequestFactory"  
      class="org.springframework.security.oauth2.provider.request.DefaultOAuth2RequestFactory">  
     <constructor-arg ref="clientDetails"/>  
   </bean>  
   <bean id="userApprovalHandler"  
      class="org.springframework.security.oauth2.provider.approval.TokenStoreUserApprovalHandler">  
     <property name="tokenStore" ref="tokenStore"/>  
     <property name="requestFactory" ref="oAuth2RequestFactory"/>  
   </bean>  
   <!-- authorization-server aka AuthorizationServerTokenServices is an interface that defines everything necessary for token management -->  
   <oauth:authorization-server client-details-service-ref="clientDetails" token-services-ref="tokenServices"  
                 user-approval-handler-ref="userApprovalHandler">  
     <oauth:authorization-code/>  
     <oauth:implicit/>  
     <oauth:refresh-token/>  
     <oauth:client-credentials/>  
     <oauth:password/>  
   </oauth:authorization-server>  
   <oauth:resource-server id="resourceServerFilter" resource-id="test" token-services-ref="tokenServices"/>  
   <bean id="clientDetails"  
      class="org.ateam.common.service.ClientService">  
   </bean>  
   <sec:global-method-security pre-post-annotations="enabled" proxy-target-class="true">  
     <!--you could also wire in the expression handler up at the layer of the http filters. See https://jira.springsource.org/browse/SEC-1452 -->  
     <sec:expression-handler ref="oauthExpressionHandler"/>  
   </sec:global-method-security>  
   <oauth:expression-handler id="oauthExpressionHandler"/>  
   <oauth:web-expression-handler id="oauthWebExpressionHandler"/>  
 </beans>  

Clone the repo and change it accordingly for your needs. Happy coding!