TestNG #DataProvider with log4j - selenium-webdriver

When I use log4j and TestNG #DataProvider I was able to generate logs for the below code, but when I use #DataProvider the logs are getting overwritten. I tried to use #BeforeTest but it's not working. Any idea on how can I generate for logs for all the my rows?
public class DemoTest extends baseFX {
public static Logger Log = LogManager.getLogger(baseFX.class.getName());
#Test(dataProvider="DataProvider", groups = { "baseFX" })
public void loginPageNav(String Test, String newMemEmail, String newMemPass ) throws Exception {
driver=driverSetup();
Log.info("Driver is initialized");
//Creating object for the Index to the class
IndexPage indexpage = new IndexPage(driver);
Log.info("Navigated to Index Page");
//invoke method
indexpage.clickLogin().click();
Log.info("Clicked on Login");
//Creating an object for the login page and invoke its elements
LoginPage loginpage = new LoginPage(driver);
loginpage.getPassword().sendKeys(password);
loginpage.loginBtn().click();
Log.info("Member successfully logged in");
//driver.manage().timeouts().implicitlyWait(2, TimeUnit.SECONDS);
driver.close();
}
#DataProvider
public Object[][] DataProvider() throws Exception{
Object[][] arrayObject = ReadExcelData.getExcelData("./src/test/java/Autopkg/TestData/Demo.xlsx", "Sheet1");
return arrayObject;
}
//#AfterTest
//public void tearDown(){
//}
}
I use log4j configuration file:
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="WARN">
<Properties>
<Property name="basePath">./logs</Property>
</Properties>
<Appenders>
<RollingFile name="File" fileName="${basePath}/prints.log" filePattern="${basePath}/prints-%d{yyyy-MM-dd}.log">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
<SizeBasedTriggeringPolicy size="1000" />
</RollingFile>
<Console name="Console" target="SYSTEM_OUT">
<PatternLayout pattern="%d{HH:mm:ss.SSS} [%t] %-5level %logger{36} - %msg%n"/>
</Console>
</Appenders>
<Loggers>
<Root level="trace">
<AppenderRef ref="File"/>
</Root>
</Loggers>
</Configuration>

Related

react-native android app crashes on launch using branch.io react-native-branch

I'm finding difficulties while using the branch.io(react-native-branch) integration for android for deep-linking app is getting stop after applying changes in mainactivity.java.
react:v17.0.2
react-native:v0.66.4
react-native-branch:v^5.4.0
Androidmanifest.xml
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="com.eneff.branchandroid">
<uses-permission android:name="android.permission.INTERNET" />
<uses-permission android:name="com.google.android.gms.permission.AD_ID"/>
<application
android:allowBackup="true"
android:name="com.eneff.branchandroid.CustomApplicationClass"
android:icon="#mipmap/ic_launcher"
android:label="#string/app_name"
android:supportsRtl="true"
android:theme="#style/AppTheme">
<activity
android:name=".MainActivity"
android:launchMode="singleTask"
android:label="#string/app_name"
android:theme="#style/AppTheme.NoActionBar">
<intent-filter>
<action android:name="android.intent.action.MAIN" />
<category android:name="android.intent.category.LAUNCHER" />
</intent-filter>
<!-- Branch URI Scheme -->
<intent-filter>
<data android:scheme="branchandroid" android:host="open" />
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
</intent-filter>
<!-- Branch App Links -->
<intent-filter android:autoVerify="true">
<action android:name="android.intent.action.VIEW" />
<category android:name="android.intent.category.DEFAULT" />
<category android:name="android.intent.category.BROWSABLE" />
<data android:scheme="https" android:host="uobg.app.link" />
</intent-filter>
</activity>
<!-- Branch keys -->
<!-- (Omit if setting keys in branch.json) -->
<meta-data android:name="io.branch.sdk.BranchKey" android:value="key_live_gdzsepIaUf7wG3dEWb3aBkmcutm0PwJa"/>
<meta-data android:name="io.branch.sdk.BranchKey.test" android:value="key_test_edwDakKcMeWzJ3hC3aZs9kniyuaWGCTa"/>
</application>
</manifest>
MainActivity.java
import com.facebook.react.ReactActivity;
import com.facebook.react.ReactActivityDelegate;
import com.facebook.react.ReactRootView;
import com.swmansion.gesturehandler.react.RNGestureHandlerEnabledRootView;
import io.branch.rnbranch.*;
import android.content.Intent;
public class MainActivity extends ReactActivity {
/**
* Returns the name of the main component registered from JavaScript. This is used to schedule
* rendering of the component.
*/
#Override
protected String getMainComponentName() {
return "G4Plus";
}
#Override
protected void onStart() {
super.onStart();
RNBranchModule.initSession(getIntent().getData(), this);
}
#Override
public void onNewIntent(Intent intent) {
super.onNewIntent(intent);
if (intent != null &&
intent.hasExtra("branch_force_new_session") &&
intent.getBooleanExtra("branch_force_new_session",false)) {
RNBranchModule.onNewIntent(intent);}
}
#Override
protected ReactActivityDelegate createReactActivityDelegate() {
return new ReactActivityDelegate(this, getMainComponentName()) {
#Override
protected ReactRootView createRootView() {
return new RNGestureHandlerEnabledRootView(MainActivity.this);
}
};
}
}
MainApplication.java
package com.g4plus;
import android.app.Application;
import android.content.Context;
import com.facebook.react.PackageList;
import com.facebook.react.ReactApplication;
import com.swmansion.reanimated.ReanimatedPackage;
import com.facebook.react.ReactInstanceManager;
import com.facebook.react.ReactNativeHost;
import com.facebook.react.ReactPackage;
import com.facebook.react.bridge.JSIModulePackage;
import com.facebook.soloader.SoLoader;
import java.lang.reflect.InvocationTargetException;
import java.util.List;
import com.swmansion.reanimated.ReanimatedJSIModulePackage;
import io.branch.rnbranch.RNBranchModule;
public class MainApplication extends Application implements ReactApplication {
private final ReactNativeHost mReactNativeHost =
new ReactNativeHost(this) {
#Override
public boolean getUseDeveloperSupport() {
return BuildConfig.DEBUG;
}
#Override
protected List<ReactPackage> getPackages() {
#SuppressWarnings("UnnecessaryLocalVariable")
List<ReactPackage> packages = new PackageList(this).getPackages();
// Packages that cannot be autolinked yet can be added manually here, for example:
// packages.add(new MyReactNativePackage());
return packages;
}
#Override
protected String getJSMainModuleName() {
return "index";
}
#Override
protected JSIModulePackage getJSIModulePackage() {
return new ReanimatedJSIModulePackage(); // <- add
}
// overide for branch
};
#Override
public ReactNativeHost getReactNativeHost() {
return mReactNativeHost;
}
#Override
public void onCreate() {
super.onCreate();
RNBranchModule.getAutoInstance(this);
SoLoader.init(this, /* native exopackage */ false);
initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
}
/**
* Loads Flipper in React Native templates. Call this in the onCreate method with something like
* initializeFlipper(this, getReactNativeHost().getReactInstanceManager());
*
* #param context
* #param reactInstanceManager
*/
private static void initializeFlipper(
Context context, ReactInstanceManager reactInstanceManager) {
if (BuildConfig.DEBUG) {
try {
/*
We use reflection here to pick up the class that initializes Flipper,
since Flipper library is not available in release mode
*/
Class<?> aClass = Class.forName("com.g4plus.ReactNativeFlipper");
aClass
.getMethod("initializeFlipper", Context.class, ReactInstanceManager.class)
.invoke(null, context, reactInstanceManager);
} catch (ClassNotFoundException e) {
e.printStackTrace();
} catch (NoSuchMethodException e) {
e.printStackTrace();
} catch (IllegalAccessException e) {
e.printStackTrace();
} catch (InvocationTargetException e) {
e.printStackTrace();
}
}
}
}
I have taken references from the branch.io(react-native-branch) developer guide
https://help.branch.io/developers-hub/docs/react-native
try to downgrade this to version 5.0.0 I was having the same issue on my setup

Mock the body of an intermediate route executed in Camel Tests

Available examples of the usage of the Camel Test component show how to test the expectations of a route:
However what I need to do is mock the body (manually setting it) of an intermediate route, e.g.:
<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="exampleBean" class="xxx.ExampleBean"/>
<routeContext id="routesTest" xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="direct:route1" />
<to uri="direct:route2" />
<log message="${body}"/>
</route>
<route>
<from uri="direct:route2"/>
<to uri="bean:exampleBean"/>
<to uri="direct:route3" />
</route>
<route>
<from uri="direct:route3"/>
<log message="${body}"/>
</route>
</routeContext>
</beans>
In this scenario I want to completely avoid the actual execution of bean:exampleBean, mocking the result of its execution.
My test class:
public class MyTests extends CamelSpringTestSupport {
#Produce(uri = "direct:route1")
protected ProducerTemplate inputProducerTemplate;
#EndpointInject(uri = "mock:bean:exampleBean")
protected MockEndpoint mockBeanExampleBean;
#Test
public void testRoute() throws Exception {
CompletableFuture<Object> future = inputProducerTemplate.asyncSendBody("direct:route1", "Some message");
Object o = future.get();
}
#Override
public String isMockEndpoints() {
return "bean:exampleBean";
}
#Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("spring/gesti-test-application-context.xml");
}
}
public class ExampleBean {
public String enhance(String message) {
System.out.println(message);
//Here I would call a REST API
return "MY API RESULT";
}
}
When using mockBeanExampleBean.whenAnyExchangeReceived(exchange -> exchange.getMessage().setBody("My message")); it allows to override the input to exampleBean, but doesn't avoid its execution.
In the context of your unit test, route2 might be a "mock" component instead. A clean way of achieving that is to declare the route(s) in the properties file. The legibility of the routes gets harder, though.
Then, you could:
#EndpointInject("mock://route2")
MockEndpoint mockSecondStep;
mockSecondStep.whenExchangeReceived(1, e -> {
List whatever = new ArrayList<>();
e.getMessage().setBody(whatever);
});
I solved it using an InterceptStrategy:
public class MyTests extends CamelSpringTestSupport {
#Test
public void testRoute() throws Exception {
CompletableFuture<Object> future = template.asyncSendBody("direct:route1", "Some message");
Object o = future.get();
assertEquals("INTERCEPTED!", o);
}
#Override
protected AbstractApplicationContext createApplicationContext() {
return new ClassPathXmlApplicationContext("spring/gesti-test-application-context.xml");
}
#Override
protected RouteBuilder createRouteBuilder() {
return new RouteBuilder() {
#Override
public void configure() {
context.getProcessorDefinition("bean:exampleBean").addInterceptStrategy(
(context, definition, target, nextTarget) -> exchange -> exchange.getOut().setBody("INTERCEPTED!"));
}
};
}
}
public class ExampleBean {
public String enhance(String message) {
System.out.println(message);
//Here I would call a REST API
return "MY API RESULT";
}
}

How to pass parameters to Apache Camel through command line?

I use Apache Camel’s Spring Main to boot my Camel application. I need my application to read the command line arguments to set some parameters. So, I cannot use property files.
At the moment, I can pass arguments via the JVM system properties, and it works well:
Application.java
public class Application extends org.apache.camel.spring.Main {
public static void main(String[] args) throws Exception {
Application app = new Application();
instance = app;
app.run(args);
}
}
camel-context.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"
xsi:schemaLocation="
http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans.xsd
http://camel.apache.org/schema/spring http://camel.apache.org/schema/spring/camel-spring.xsd">
<bean id="shutdownBean" class="com.example.ShutdownBean" />
<camelContext xmlns="http://camel.apache.org/schema/spring">
<route>
<from uri="file:{{inputFile}}?noop=true"/>
<to uri="bean:shutdownBean" />
</route>
</camelContext>
</beans>
I run the app with java com.example.Application -DinputFile=C:/absolute/path/to/watch and everything works fine:
…
FileEndpoint INFO Using default memory based idempotent repository with cache max size: 1000
InternalRouteStartupManager INFO Route: route1 started and consuming from: file://C:/absolute/path/to/watch
AbstractCamelContext INFO Total 1 routes, of which 1 are started
…
But I would like to have some input validation and make the app easier to use because -D could be confusing for a non Java user. So I change Application.java:
public class Application extends org.apache.camel.spring.Main {
private File inputFile;
public static void main(String[] args) throws Exception {
Application app = new Application();
instance = app;
app.run(args);
}
public Application() {
addOption(new ParameterOption("i", "inputFile", "The input file", "inputFile") {
#Override
protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
File file = FileUtils.getFile(parameter);
// some business validation
setInputFile(file);
}
});
}
private void setInputFile(File inputFile) {
this.inputFile = inputFile;
}
}
Then, I could use the following command to run the application: java com.example.Application -inputFile C:/absolute/path/to/watch
How can I use my inputFile field into my Camel route?
Call addProperty(String key, String value) in your doProcess method. Then it will be accessible throught {{key}} notation.
MyApplication:
public final class MyApplication extends Main {
private MyApplication() {
super();
addCliOption("g", "greeting", "Greeting");
addCliOption("n", "name", "Who to greet");
}
public static void main(String[] args) throws Exception {
MyApplication app = new MyApplication();
app.configure().addRoutesBuilder(MyRouteBuilder.class);
app.run(args);
}
private void addCliOption(String abbrevation, String parameterName, String description) {
addOption(new ParameterOption(abbrevation, parameterName, description, parameterName) {
protected void doProcess(String arg, String parameter, LinkedList<String> remainingArgs) {
addProperty("console." + parameterName, parameter);
}
});
}
}
MyRouteBuilder:
public class MyRouteBuilder extends RouteBuilder {
#Override
public void configure() throws Exception {
from("quartz:foo")
.log("{{console.greeting}} {{console.name}}");
}
}
java org.apache.camel.example.MyApplication -greeting Hello -name Morgan
23:10:25.862 [DefaultQuartzScheduler-MyCoolCamel_Worker-1] INFO route1 - Hello Morgan
23:10:26.832 [DefaultQuartzScheduler-MyCoolCamel_Worker-2] INFO route1 - Hello Morgan
23:10:27.829 [DefaultQuartzScheduler-MyCoolCamel_Worker-3] INFO route1 - Hello Morgan

NLog MethodCall

I've got a silverlight project and I'm trying to configure NLog for calling static method but it doesn't (using Nlog.config).
I'm following this example.
Here's Nlog.config code:
...
<targets>
<target name="m" xsi:type="MethodCall"
className="NLogTestSilver.MainPage, NLogTestSilver"
methodName="LogMethod">
<parameter layout="${level}" />
<parameter layout="${message}" />
</target>
</targets>
<rules>
<logger name="*" minlevel="Debug" writeTo="m" />
</rules>
...
Assembly name = NLogTestSilver.dll
Here's MainPage.xaml.cs code:
namespace NLogTestSilver
{
public partial class MainPage : UserControl
{
public static Logger Logger = LogManager.GetCurrentClassLogger();
public MainPage()
{
InitializeComponent();
Logger.Fatal("Fatality");
}
public static void LogMethod(string level, string message)
{
System.Windows.Browser.HtmlPage.Window.Alert(level + " " + message);
}
}
}
P.S. Programmatic configuration works well.
So it was found out that an exception is thrown in NLog.Targets.MethodCallTarget.InitializeTarget() method while processing className parameter.
If we change
className="NLogTestSilver.MainPage, NLogTestSilver"
to
className="NLogTestSilver.MainPage, NLogTestSilver,
Version=1.0.0.0, Culture=neutral, PublicKeyToken=xxxxxxxxxxxxxxxx"
it works great.
Where xxxxxxxxxxxxxxxx is public key token of our assembley.

log4net configuration for Event Logging

I'm trying to enable solution-wide logging by adding a stand-alone project that wraps log4net. I found a code on StackOverflow but the code is using some config file. I do not understand that bit. Here is the only static class:
using log4net;
using log4net.Config;
using System;
using System.IO;
namespace ExciteEngine2.LoggingManager {
//// TODO: Implement the additional GetLogger method signatures and log4net.LogManager methods that are not seen below.
public static class ExciteLog {
private static readonly string LOG_CONFIG_FILE = #"log4net.config";
public static ILog GetLogger(Type type) {
// If no loggers have been created, load our own.
if (LogManager.GetCurrentLoggers().Length == 0) {
LoadConfig();
}
return LogManager.GetLogger(type);
}
private static void LoadConfig() {
//// TODO: Do exception handling for File access issues and supply sane defaults if it's unavailable.
try {
XmlConfigurator.ConfigureAndWatch(new FileInfo(LOG_CONFIG_FILE));
}
catch (Exception ex) {
}
}
}
}
Now, there is no log4net.config anywhere. And in my main application project, I'm using the ILog as follows:
using log4net;
using ExciteEngine2.LoggingManager;
namespace ExciteEngine2.MainApplication {
internal static class Program {
public static readonly ILog ApplicationLogger = ExciteLog.GetLogger(typeof(Program));
private static void SetupLogging() {
log4net.Config.XmlConfigurator.Configure();
}
[STAThread] static void Main(string[] args) {
//Uninstall
foreach (string arg in args) {
if (arg.Split('=')[0] == "/u") {
Process.Start(new ProcessStartInfo(Environment.GetFolderPath(Environment.SpecialFolder.System) + "\\msiexec.exe", "/x " + arg.Split('=')[1]));
return;
}
}
Thread.CurrentThread.CurrentCulture = new CultureInfo("en-GB");
Thread.CurrentThread.CurrentUICulture = new CultureInfo("en-GB");
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
Application.ThreadException += new ThreadExceptionEventHandler(Application_ThreadException);
try {
ThemeResolutionService.ApplicationThemeName = ConfigurationManager.AppSettings["ThemeToUse"];
}
catch (Exception ex) {
ApplicationLogger.Error("Exception while setting Telerik Theme.", ex);
ThemeResolutionService.ApplicationThemeName = "ControlDefault";
}
DevExpress.UserSkins.OfficeSkins.Register();
DevExpress.UserSkins.BonusSkins.Register();
DevExpress.Skins.SkinManager.EnableFormSkins();
DevExpress.Skins.SkinManager.EnableMdiFormSkins();
//try {
if (args.Contains("/dx")) {
Application.Run(new AppMDIRibbonDX());
ApplicationLogger.Info("Application (DX) started.");
}
else {
Application.Run(new AppMDIRibbon());
ApplicationLogger.Info("Application started.");
}
//} catch (Exception ex) {
// ApplicationLogger.Fatal("Exception while initiating. Nothing can be done here.", ex);
// XtraMessageBox.Show(String.Format("Exception while initiating. Nothing can be done here.{0}Message: {1}", Environment.NewLine, ex.Message), "Excite Engine 2", MessageBoxButtons.OK, MessageBoxIcon.Error);
//}
}
private static void Application_ThreadException(object sender, ThreadExceptionEventArgs e) {
ApplicationLogger.Fatal("Application Level Exception.", e.Exception);
Thread t = (Thread)sender;
Exception threadexception = e.Exception;
string errormessage = String.Format("Thread ID: {0} [ {1} ]", t.ManagedThreadId, threadexception.Message);
XtraMessageBox.Show(String.Format("Application Level Exception!{1}{0}{1}Details:{1}{2}", errormessage, Environment.NewLine, threadexception.StackTrace), "Excite Engine 2", MessageBoxButtons.OK, MessageBoxIcon.Error);
}
}
}
As you can see from my flow, I'm executing this line of code thinking log4net will use my main application project's app.config: log4net.Config.XmlConfigurator.Configure();
And here is a line I added in AssemblyInfo.cs:
[assembly: log4net.Config.XmlConfigurator(Watch = true)]
Finally, the app.config for my Main application:
<?xml version="1.0"?>
<configuration>
<configSections>
<section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net"/>
</configSections>
<appSettings>
</appSettings>
<connectionStrings>
</connectionStrings>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0" />
</startup>
<log4net>
<root>
<level value="DEBUG" />
<appender-ref ref="LogFileAppender" />
</root>
<appender name="LogFileAppender" type="log4net.Appender.RollingFileAppender" >
<param name="File" value="Excite Engine 2 Log.log" />
<param name="AppendToFile" value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<param name="ConversionPattern" value="%-5p%d{ddd, dd-MMM-yyyy hh:mm:ss} - %m%n" />
</layout>
</appender>
<appender name="EventLogAppender" type="log4net.Appender.EventLogAppender" >
<applicationName value="Excite Engine 2" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-5level %logger [%property{NDC}] - %message%newline" />
</layout>
</appender>
</log4net>
</configuration>
When I run with <appender-ref ref="LogFileAppender" />, I get an empty file named Excite Engine 2 Log.log right next to my main EXE. And when I set <appender-ref ref="EventLogAppender" />, nothing happens in Event Viewer. Also, there is an attribute: <level value="DEBUG" /> thats really bothering me. What I want is a full EventViewer logging for my application regardless of the build configuration it is running in.
Appreciate if someone could guide me on this. Thanks!
I found a code on StackOverflow but
the code is using some config file. I
do not understand that bit.
The reason he's using a specific config file can be explained by the following taken from log4net's site:
The System.Configuration API is only
available if the configuration data is
in the application's config file; the
file named MyApp.exe.config or
Web.config. Because the
System.Configuration API does not
support reloading of the config file
the configuration settings cannot be
watched using the
log4net.Config.XmlConfigurator.ConfigureAndWatch
methods. The main advantage of using
the System.Configuration APIs to read
the configuration data is that it
requires less permissions than
accessing the configuration file
directly. The only way to configure an
application using the
System.Configuration APIs is to call
the
log4net.Config.XmlConfigurator.Configure()
method or the
log4net.Config.XmlConfigurator.Configure(ILoggerRepository)
method.
Edit:
To log to your log file you need to call your SetupLogging method above.
log4net.Config.XmlConfigurator.Configure();
This statement is never being called. It looks like you are calling LoadConfig() in your ExciteEngine2.LoggingManager but this uses a config file called log4net.config which you said doesn't exist. If you are putting your configuration in your app.config file then you need to call your SetupLogging method.

Resources