Selenium driver management in Springboot - selenium-webdriver

I am trying to create a selenium framework using spring boot. What I am trying to accomplish it spring-boot should manage selenium driver creation, even when we run the test in parallel and if possible I want to avoid passing driver object in page class constructor.
So I created a bean class like below
#Bean
public WebDriver getDriver(){
return new ChromeDriver();
}
it worked fine for the Single test. But for multiple tests in parallel, I changed the scope of the above method to the prototype, and when I ran the test it started multiple tests but it didn't work as I expected and commands started firing in the wrong browser. I know I am missing something related to Thread/parallel stuff. It would be really helpful if someone can guide me or someone can share git repo where spring-boot and selenium are used.

You could try changing the scope to thread with:
#Bean
#Scope(value = "thread", proxyMode = ScopedProxyMode.TARGET_CLASS)
public WebDriver getDriver(){
return new ChromeDriver();
}
#Bean
public static CustomScopeConfigurer customScopeConfigurer()
{
CustomScopeConfigurer scopeConfigurer = new CustomScopeConfigurer();
Map<String, Object> scopes = new HashMap<>();
scopes.put("thread", SimpleThreadScope.class);
scopeConfigurer.setScopes(scopes);
return scopeConfigurer;
}

Related

Handling CORS during development Spring Boot and reactjs application

this problem is kinda new to me because I used to develop angular applications earlier but now I have reactjs as a front-end technology.
My problem is CORS. My react app works on port 3000 and my spring boot app on 8080. Adding #CrossOrigin on my controller handles the problem pretty well but is there a way to somehow configure this on the front-end side? Something like a switch that you flip when app is supposed to work locally and stop this when working in production environment?
Yes. You can use reverse proxy.
It’s very common problem.
See here.
http://www.pierre-beitz.eu/2017/01/24/Dealing-with-CORS-in-a-Development-Environment-Using-a-Reverse-Proxy.html
By that all requests would be going to api and will further resolve issue.
Right now on phone. Can come on lappy if you have any more questions.
Adding another solution post comment
Add the following code in your MainApplication.java
#Bean
public FilterRegistrationBean corsFilter() {
UrlBasedCorsConfigurationSource source = new UrlBasedCorsConfigurationSource();
CorsConfiguration config = new CorsConfiguration();
config.setAllowCredentials(true);
config.addAllowedOrigin("http://domain1.com");
config.addAllowedHeader("*");
config.addAllowedMethod("*");
source.registerCorsConfiguration("/**", config);
FilterRegistrationBean bean = new FilterRegistrationBean(new CorsFilter(source));
bean.setOrder(0);
return bean;
}
and map the class with #Configuration annotation

Updating index.android.bundle from remote server in react native [Android]

I am creating a demo react native app that is implementing aeroFS https://github.com/redbooth/react-native-auto-updater library
[An aerofs library is nothing but each time when app opens it will check for update from remote server and if update is available it will download and ask the user to apply for the update without play store].
So far the app is able to download the file but after download i am not able to see any changes in the app.I'm sure the newly downloaded bundle is not used in the activity.
On further checking inside the library i found the following method in ReactNativeAutoUpdaterActivity class (main class):-
#Override
#Nullable
public String getJSBundleFile() {
updater=ReactNativeAutoUpdater.getInstance(this.getApplicationContext());
updater.setMetadataAssetName(this.getMetadataAssetName());
return updater.getLatestJSCodeLocation();
}
The ReactNativeAutoUpdaterActivity extends from ReactActivity which does not have this method.I think this is moved to ReactNativeHost so i knew this is the problem but now should i implement my own react native host class to over ride the method so that once new bundle file is downloaded i can apply it to app.
MainApplication.java
import android.content.SharedPreferences;
import android.preference.PreferenceManager;
.
.
.
#Override
public void onCreate(){
super.onCreate();
SharedPreferences preferences =
PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
preferences.edit().putString("debug_http_host", "128.xxx.xxx.xxx:1234").apply();
}
When using a remote VM, port 8081 is not exposed, so:
npm start -- --reset-cache --port=1234
AppDelegate.m (iOS):
jsCodeLocation = [NSURL URLWithString:#"http://128.xxx.xxx.xxx:1234/index.js"];

xUnit test project connection string

I would like to know the recommended approach to getting a connection string from a config file for my xUnit .net core test project.
I have set up a test project using the new Visual Studio 2017 xUnit Test project template for .net core. This project will run my integration tests that reference 2 different .net core class library projects - one of which will talk to the database using EF Core.
I understand that normally the connection string should not be set or accessed in a class library project - it should be the application that consumes the class library that should set the connection string.
However, in this case it appears that the xUnit test project is treated somewhat like a class library project. I have not seen any examples of how to set up some sort of config file and access that from the test project. How do I access the connection string from a config file so that my test project can consume my Datalayer class library project and pass in the appropriate connection string?
I was able to access the connection string from my xUnit test project by creating a DbOptionsFactory class that returns a DbContextOptions object initialized with a connection string that it reads from an appsettings.json configuration file.
This requires a dependency on Microsoft.Extensions.Configuration
public static class DbOptionsFactory
{
static DbOptionsFactory()
{
var config = new ConfigurationBuilder()
.AddJsonFile("appsettings.json")
.Build();
var connectionString = config["Data:DefaultConnection:ConnectionString"];
DbContextOptions = new DbContextOptionsBuilder<MyDbContext>()
.UseSqlServer(connectionString)
.Options;
}
public static DbContextOptions<MyDbContext> DbContextOptions { get; }
}
appsettings.json
{
"Data": {
"DefaultConnection": {
"Name": "MyDbContext",
"ConnectionString": "connection string goes here"
}
}
}
When instantiating my DbContext I pass in the optionsBuilder object that has the connection string from the configuration file like so:
using (var context = new MyDbContext(DbOptionsFactory.DbContextOptions))
{
// access db here
}
Hope this helps anyone else that runs into the same issue.

Spring-boot: add application to tomcat server

I have a back-end which is build on spring-boot and then some custom code from my school built upon that.
The front-end is pure angular application which I serve from a different server trough a gulp serve.
They're only connected by REST calls.
There's already an authentication module running on the backend and to now I need to serve this angular application from the same tomcat server the back-end is running on so it can also use this authentication module.
I've found this about multiple connectors so I copied it as following class to set up multiple connectors:
#ConfigurationProperties
public class TomcatConfiguration {
#Bean
public EmbeddedServletContainerFactory servletContainer() {
TomcatEmbeddedServletContainerFactory tomcat = new TomcatEmbeddedServletContainerFactory();
//tomcat.addAdditionalTomcatConnectors(createSslConnector());
return tomcat;
}
private Connector createSslConnector() {
Connector connector = new Connector("org.apache.coyote.http11.Http11NioProtocol");
Http11NioProtocol protocol = (Http11NioProtocol) connector.getProtocolHandler();
try {
File keystore = new ClassPathResource("keystore").getFile();
File truststore = new ClassPathResource("keystore").getFile();
connector.setScheme("https");
connector.setSecure(true);
connector.setPort(8443);
protocol.setSSLEnabled(true);
protocol.setKeystoreFile(keystore.getAbsolutePath());
protocol.setKeystorePass("changeit");
protocol.setTruststoreFile(truststore.getAbsolutePath());
protocol.setTruststorePass("changeit");
protocol.setKeyAlias("apitester");
return connector;
} catch (IOException ex) {
throw new IllegalStateException("can't access keystore: [" + "keystore"
+ "] or truststore: [" + "keystore" + "]", ex);
}
}
}
Problem is that I don't see or find how I should setup these connectors so they serve from my angularJS build folder.
Upon searching I came upon Spring-Boot : How can I add tomcat connectors to bind to controller but I'm not sure if in that solution I should change my current application or make a parent application for both applications.
My current application main looks like this:
#Configuration
#ComponentScan({"be.ugent.lca","be.ugent.sherpa.configuration"})
#EnableAutoConfiguration
#EnableSpringDataWebSupport
public class Application extends SpringBootServletInitializer{
public static void main(String[] args) {
SpringApplication.run(Application.class, args);
}
}
If possible I'd like some more info about what connectors are in the spring-boot context.
If this is not the way to go I'd like someone to be able to conform this second solution or suggest a change in my code.
I'm really not sure enough about these solution that I want to go breaking my application over it. (though it's backed up with github)
Just place your AngularJS + other front-end assets into src/main/resources/static folder, Spring Boot will serve them automatically.

GAE : java.lang.NoClassDefFoundError: com/google/appengine/api/blobstore/BlobstoreServiceFactory

Kindly help me with this. I am using blob store for saving images and it is working perfectly fine on my local environment. But when I deploy the same code the cloud it is throwing me the exception : java.lang.NoClassDefFoundError: com/google/appengine/api/blobstore/BlobstoreServiceFactory
I am using GAE 1.8.4
Most likely, appengine-api.jar is missing from your war/WEB-INF/lib/ folder.
If you use Eclipse, click on the Problems tab. You may see a warning saying that this jar is not available on a server. Right click on this warning, select QuickFix, select "Copy..." option. Or copy this jar to this directory manually.
In my case the required jar was inside the WEB-INF/lib folder but the error was still occuring... I found that this error was occuring because Jetty 9 was not done yet with class loading startup process while one of my initialization class was requiring BlobstoreService:
public class InitializeAppContextListener implements ServletContextListener {
private BlobstoreService blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
So I had to postpone instance variable initialization once context is fully loaded as follow:
public class InitializeAppContextListener implements ServletContextListener {
private BlobstoreService blobstoreService;
public void contextInitialized(ServletContextEvent event) {
blobstoreService = BlobstoreServiceFactory.getBlobstoreService();
Then the webapp was able to start normally again. This new behavior appeared after we had upgraded from servlet-api 2.5 to 3.1 with JDK 1.8...

Resources