Design Issue with Automated Test (Selenium WebDriver + Spring Boot + Cucumber + Page Object Model + PageFactory Pattern) - spring

I am building an automated test framework using these tools and concepts -
Selenium WebDriver
Cucumber (For BDD)
Spring Boot
Page Object Model
PageFactory Pattern
Everything is working fine and I am happy with what I have built. Following Page Object Model, I have created PageObject classes which are basically models of actual web pages. I am also using PageFactory pattern to automatically instantiate WebElements.
I have leveraged Spring Boot, for awesomeness. By awesomeness I mean stuff like auto injecting configurations throughout the application, dependency injection required to achieve sharing of the test world between Step Definition classes while performing Cucumber Tests, and other goals which would have been a bit tedious to achieve without it.
Given the background, let's now come to my question.
I want my Page Objects to be Spring managed beans/components. I am initializing my Page Objects using PageFactory.initElements(WebDriver driver, Object page) method from the constructor. As far as my knowledge takes me, if page objects are initialized before the pages are actually loaded in browser, then any attempts to invoke action on their web elements will result in StaleStateException. Correct? So, if I make my page objects Spring managed beans, how do I control the initialization of its web elements? I can remove the PageFactory's initialization method from the constructor and put it in some other method which I can later call to instantiate it. But I wany to know if there is any better approach to this.
The program should be able to autowire page objects in Step Definition classes of Cucumber, but elements of those objects should be instantiated whenever the actual page is loaded in the browser or some action method is called to interact with the web element.
Is it good idea to make PageObjects spring beans, if you are following Page Object Model and PageFactory?

It seems that PageFactory.initElements() method only creates proxies of actual web elements rather than caching them. So, no matter when I do the initialization, every time when a method is called on a WebElement, the driver will first find it on the current page and then simulate the action on the WebElement.
The only thing that will cause state state is if the page changes or reloads. Thank you for pointing this out.
But whenever we use #CacheLookup annotation, we will be losing one of the page factory benefit as it will find the element once and then keep a reference to it, hence, we are more likely to see StaleElementExceptions.
This blog might help others - http://www.seleniumeasy.com/selenium-tutorials/page-factory-pattern-in-selenium-webdriver

Related

Jersey (javax.ws.rs): how to do initialisation at page level ONLY not at application level

I need to do a lot of initialisation for few pages when they are called for only first time. Here is a decent post that addresses this: Initialize database on Jersey webapp startup
But the problem with the above approach is that the initialisation is done at application level which I don't want. I am not sure if and when a particular page will be called and so I want to go with initialisation only when the page is called for the first time.
Any thoughts on how to achieve this when using jersey. (Spring has #PostConstruct and #PreDestroy for this purpose at controller/page level... so some thing similar is what I need). A small example or code will help greatly.

Single instance of an object per transaction

I have a use case, that theoretically seems to me as it would be a solved problem. But i'm not able to find a sure fired implementation.
I've created a RESTful API, using Apache CXF, Spring and Hibernate
This application encompasses a standard Service-Proxy-DAO layered structure
I need to instantiate a custom logger object at my service (or pre-service) layer and initialize a bunch of parameters which will remain constant, for the most part through every call that goes through my application layers and back.
How can i, for every individual service call, initialize this logger object once, and use it across all my layers without having to instantiate it everytime. Either i inject the initialized object in every class i need or something on those lines.
I don't want to use static blocks, or pass the object in method signatures.
Is there anything that i can use as a part of the Spring, CXF or other java framework that allows me to implement this use-case.
EDIT: I would define a transaction as a single call to a web service endpoint, from invocation to response.
ThreadLocal would be an ideal candidate to solve your problem.
UPDATE:
Creating a thread local that is available in all the places where this "shared" reference is required will give all these contexts access to this resource without having to pass the reference around.
see http://www.appneta.com/blog/introduction-to-javas-threadlocal-storage/ - looks like a good explanation of how to use thread local and also deals with your problem space.

Integrate JSF2 and Spring3 (with AOP)

I am using Spring and JSF2 a lot and was wondering what the best way to integrate them is? Now i understand there are basically two ways to do this, but i have some problems with both:
a) Use normal #ManagedBean, and inject Spring-Services into that beans using #ManagedProperty: The problem is that i can't use Spring-AOP inside a #ManagedBean obviously, because it is not Spring-managed. I usually use an arround-aspect on every method annotated with my custom annotation #DatabaseOperation. Another example would be #Secured from Spring-Security and so on. I use a lot of AOP in my project and not beeing able to use them on "the top level" is really limiting for me.
b) Use SpringBeanFacesELResolver to make everything managed by Spring. On the pro side is that AOP works like a charm, but the cons are big too:
No ViewScope. I am not sure if i can trust custom view scope implementations like this https://github.com/michail-nikolaev/primefaces-spring-scopes on productive systems?
Serialization is not possible. It's already pretty complicated, but once i use AOP i can't get it to work because org.springframework.aop.aspectj.AspectJPointcutAdvisor is not Serializable
So my question is: How do you overcome this issues? How do YOU integrate JSF2 and Spring3.x? I have been using possibility b) mostly, but on my next project i need session replication..
Any further suggestions?
The main integration pain point of the two frameworks is that JSF is usually used in a stateful way. to make the integration the most seamless, you would have to let Spring handle the statefulness and page navigations aspects himself instead of JSF, as well as bean creation and scoping.
The second important integration point is at the level of the view expression language. We want to be able to access spring beans while building the view, which means the managed bean layer is no longer needed.
The best integration available for the two frameworks is provided by introducing Spring webflow, see here for further details. With SWF, JSF no longer manages beans itself, this is done by Spring. JSF does not manage page navigation anymore, this handled in the SWF flow definition.
Also the statefulness is handled by SWF. The flow definition XML file replaces large parts of the faces-config.xml for view navigation, transition actions, bean definition, etc.
Using the SWF JSF integration means that your faces-config.xml is mostly empty. Expression language accessing directly spring beans can be used while building the view, and a view scope is available.
If you want to keep a page isolated from the rest of the application, youcan create a flow with a single view state and self-transitions. An advantage of SWF is that it prevents duplicate form submissions via a POST-REDIRECT-GET mechanism that works transparently out of the box.

Per-Request DependencyResolver in Web API

In MVC, a ModelValidatorProvider is instantiated and called to validate a model on each request. This means that in a DI environment, it can take dependencies on objects scoped within a single request, such as a Unit of Work or Database context. In Web API, this appears to have been significantly changed. Instead of being instantiated per-request, the ModelValidatorProvider appears to be long-lived and instantiated within the application startup. The WebAPI then caches the results from the ModelValidatorProvider per-type, meaning that the ModelValidator cannot take any dependencies from DI.
I am trying to implement my ModelValidator to use a factory using a Service Locator (please, no automatic 'anti-pattern' comments!). This would allow me to construct an internal validator object within each request, which would be able to take dependencies from the container. However, I cannot get hold of a Dependency Resolver or container scoped to the current request from within this ModelValidator which is essentially scoped as a Singleton. I've tried to use GlobalConfiguration.Configuration.DependencyResolver, but this only returns globally-scoped services (from the root scope, also mentioned here)
I'm working in Autofac, so an autofac-specific solution would be suitable (e.g. MVC has AutofacDependencyResolver.Current, which internally uses DependencyResolver.GetService). There is no equivalent available in the WebAPI integration, presumably because of the reason mentioned above where the global DependencyResolver only returns globally-scoped services.
The reason I'm trying to do this (as well as for my own use) is to implement the Web API integration for FluentValidation, which currently does not exist. There have been two attempts so far, but neither of these handle the Dependency Injection issue and instead result in a single static ModelValidator.
Things I've tried so far:
Using GlobalConfiguration.Configuration.DependencyResolver (returns objects from the root scope)
Taking a dependency on Func<IComponentContext> (always returns the root context)
In an answer which has since been removed, it was suggested to remove IModelValidatorProvider service from the Web API config. This had to be done using reflection since the interface and the implementing classes are all defined as internal, but it did make the validators work better (because the ModelValidator was constructed per request). However, there is a significant performance hit to doing it this way due to the use of reflection to check for validators on the model and every property it has, so I don't want to take this option.
Filip W's answer suggests using HttpRequestMessage to get the Dependency Scope, but I've not found anything such as HttpRequestMessage.Current which would provide access to this object from within a long-lived object - if that could be achieved I believe everything would fall into place.
To get current dependency scope, you have to use (surprise, surprise :) GetDependencyScope() of the current HttpRequestMessage (more about which you can read up on MSDN) instead of GlobalConfiguration.
I blogged about Web API per-request dependency scope a while ago - that should be helpful.

Good strategy for Spring Framework end-to-end testing

So this is a rather "big" question, but what I'm trying to accomplish is the following:
I have a Spring application, MVC, JDBC (MySQL) and JSP running on tomcat.
My objective is to test the entire "stack" using a proper method.
What I have so far is Junit using Selenium to simulate an actual user interacting with the application (requires a dummy account for that), and performing different validations such as, see if element is present in the page, see if the database has a specific value or if a value matches the database.
1st concern is that this is actually using the database so it's hard to test certain scenarios. I would really like to be able to mock the database. Have it emulate specific account configs, data states etc
2nd concern is that given the fact that I use what is in the database, and data is continuously changing, it is hard to predict behavior, and therefore properly asserting
I looked at Spring Test but it allows for testing outside a servlet container, so no JSP and no Javascript testing possible.
I saw DBUtils documentation but not sure if it will help me in this case
So, to my fellow developers, I would like to ask for tips to:
Run selenium tests on top of a mocked database
Allow different configs per test
Keep compatibility with Maven/Gradle
I have started with an ordered autowire feature to support this kind of stubbing.
It's basically an idea that i took over from the Seam framework i was working with in the past but i couldnt find yet a similar thing in spring.
The idea is to have a precedence annotation (fw, app,mock,...) that will be used to resolve the current implementation of an autowired bean. This is easy already in xml but not with java config.
So we have our normal repository beans in with app precedence and a test package stubbing these classes with mock precedence.
If both are in the classpath spring would normally fail with a duplicate bean found exception. In our case the extended beanfactory simply takes the bean with the highest precedence.
Im not sure if the order annotation of spring could be used directly but i prefered to have "well defined" precedence scopes anyway, so it will be clear for our developers what this is about.
! While this is a nice approach to stub so beans for testing i would not use it to replace a database definition but rather go with an inmemory database like hsql, like some previous answers mentionned already. !

Resources