Configuration file for browsers in Webdriver - selenium-webdriver

My apologies in advance if this question is not so clear but bear with me and I'll try to explain.
I am in the process of re-jigging my personal automation framework based on recent exposure to other frameworks using a different programming language. Usually I create my automation framework using Selenium webdriver java binding but lately I've been using c#.
In the past, i create a baseDriver class that contains the following type of code -
public static String browser = System.getProperty("browser");
static {
if(browser.equalsIgnoreCase("firefox")) {
setWebDriverToFirefox();
} else if(browser.equalsIgnoreCase("chrome")) {
if(platform.equalsIgnoreCase("Mac")) {
CHROME_DRIVER = CHROME_DRIVER + "_mac";
} else if(platform.equalsIgnoreCase("LINUX")) {
CHROME_DRIVER = CHROME_DRIVER + "_linux";
} else {
CHROME_DRIVER = CHROME_DRIVER + "_win.exe";
}
setWebDriverToChrome();
} else if(browser.equalsIgnoreCase("safari")) {
setWebDriverToSafari();
} else {
if(os_arch.contains("64")){
IE_DRIVER = IE_DRIVER + "_x64.exe";
} else {
IE_DRIVER = IE_DRIVER + "_win32.exe";
}
}
This enables me to switch browsers and i run this using testng.xml file
What I want to do now is to have a config file that would enable me define these properties and then access them either using maven or testng when running the tests.
Has anyone implemented something similar?

Create a properties file which references those browsers. Read the properties file in during initialization then access the property when needed to switch.

Related

.NET 7 Distributed Transactions issues

I am developing small POC application to test .NET7 support for distributed transactions since this is pretty important aspect in our workflow.
So far I've been unable to make it work and I'm not sure why. It seems to me either some kind of bug in .NET7 or im missing something.
In short POC is pretty simple, it runs WorkerService which does two things:
Saves into "bussiness database"
Publishes a message on NServiceBus queue which uses MSSQL Transport.
Without Transaction Scope this works fine however, when adding transaction scope I'm asked to turn on support for distributed transactions using:
TransactionManager.ImplicitDistributedTransactions = true;
Executable code in Worker service is as follows:
protected override async Task ExecuteAsync(CancellationToken stoppingToken)
{
int number = 0;
try
{
while (!stoppingToken.IsCancellationRequested)
{
number = number + 1;
using var transactionScope = TransactionUtils.CreateTransactionScope();
await SaveDummyDataIntoTable2Dapper($"saved {number}").ConfigureAwait(false);
await messageSession.Publish(new MyMessage { Number = number }, stoppingToken)
.ConfigureAwait(false);
_logger.LogInformation("Publishing message {number}", number);
_logger.LogInformation("Worker running at: {time}", DateTimeOffset.Now);
transactionScope.Complete();
_logger.LogInformation("Transaction complete");
await Task.Delay(1000, stoppingToken);
}
}
catch (Exception e)
{
_logger.LogError("Exception: {ex}", e);
throw;
}
}
Transaction scope is created with the following parameters:
public class TransactionUtils
{
public static TransactionScope CreateTransactionScope()
{
var transactionOptions = new TransactionOptions();
transactionOptions.IsolationLevel = IsolationLevel.ReadCommitted;
transactionOptions.Timeout = TransactionManager.MaximumTimeout;
return new TransactionScope(TransactionScopeOption.Required, transactionOptions,TransactionScopeAsyncFlowOption.Enabled);
}
}
Code for saving into database uses simple dapper GenericRepository library:
private async Task SaveDummyDataIntoTable2Dapper(string data)
{
using var scope = ServiceProvider.CreateScope();
var mainTableRepository =
scope.ServiceProvider
.GetRequiredService<MainTableRepository>();
await mainTableRepository.InsertAsync(new MainTable()
{
Data = data,
UpdatedDate = DateTime.Now
});
}
I had to use scope here since repository is scoped and worker is singleton so It cannot be injected directly.
I've tried persistence with EF Core as well same results:
Transaction.Complete() line passes and then when trying to dispose of transaction scope it hangs(sometimes it manages to insert couple of rows then hangs).
Without transaction scope everything works fine
I'm not sure what(if anything) I'm missing here or simply this still does not work in .NET7?
Note that I have MSDTC enable on my machine and im executing this on Windows 10
We've been able to solve this by using the following code.
With this modification DTC is actually invoked correctly and works from within .NET7.
using var transactionScope = TransactionUtils.CreateTransactionScope().EnsureDistributed();
Extension method EnsureDistributed implementation is as follows:
public static TransactionScope EnsureDistributed(this TransactionScope ts)
{
Transaction.Current?.EnlistDurable(DummyEnlistmentNotification.Id, new DummyEnlistmentNotification(),
EnlistmentOptions.None);
return ts;
}
internal class DummyEnlistmentNotification : IEnlistmentNotification
{
internal static readonly Guid Id = new("8d952615-7f67-4579-94fa-5c36f0c61478");
public void Prepare(PreparingEnlistment preparingEnlistment)
{
preparingEnlistment.Prepared();
}
public void Commit(Enlistment enlistment)
{
enlistment.Done();
}
public void Rollback(Enlistment enlistment)
{
enlistment.Done();
}
public void InDoubt(Enlistment enlistment)
{
enlistment.Done();
}
This is 10year old code snippet yet it works(im guessing because .NET Core merely copied and refactored the code from .NET for DistributedTransactions, which also copied bugs).
What it does it creates Distributed transaction right away rather than creating LTM transaction then promoting it to DTC if required.
More details explanation can be found here:
https://www.davidboike.dev/2010/04/forcibly-creating-a-distributed-net-transaction/
https://github.com/davybrion/companysite-dotnet/blob/master/content/blog/2010-03-msdtc-woes-with-nservicebus-and-nhibernate.md
Ensure you're using Microsoft.Data.SqlClient +v5.1
Replace all "usings" System.Data.SqlClient > Microsoft.Data.SqlClient
Ensure ImplicitDistributedTransactions is set True:
TransactionManager.ImplicitDistributedTransactions = true;
using (var ts = new TransactionScope(your options))
{
TransactionInterop.GetTransmitterPropagationToken(Transaction.Current);
... your code ..
ts.Complete();
}

Context switching issue in appium mobile automation

Hi I tried switching from native to hybrid pages in mobile automation . it throws an error chrome driver is already in use. How to fix it in mobile automation.
If you need to automate android app using java, you can switch between contexts using the below method.
public final String WEBVIEW = "WEBVIEW_com.maxsoft.testextractor";
public final String NATIVE_APP = "NATIVE_APP";
public void switchContextTo(String context){
if (context.toLowerCase().equals(WEBVIEW.toLowerCase())) {
androidDriver.context(WEBVIEW); // set context to WEBVIEW_1
} else {
androidDriver.context(NATIVE_APP); // set context to NATIVE_APP
}
}

Where have my config settings gone?

After some long and complicated stories, I came upon code very similar to this, and have been using it fine for months. Yesterday I changed a great many things, and now this code no longer works.
public void OpenConfig(string configDir)
{
if (string.IsNullOrWhiteSpace(configDir))
{
configDir = AppDomain.CurrentDomain.BaseDirectory;
}
var sharedConfigPath = Path.Combine(configDir, ConfigFileName);
var map = new ExeConfigurationFileMap { ExeConfigFilename = sharedConfigPath };
sharedConfig = ConfigurationManager.OpenMappedExeConfiguration(map, ConfigurationUserLevel.None);
logger.Trace("'{0}' set 'SharedConfigPath' to '{1}'.", GetType().Name, sharedConfig.FilePath);
}
Then, I get config values like this:
ServicePollingInterval = GetIntegerAppSetting("ServicePollingInterval"),
where
private static int GetIntegerAppSetting(string settingName, bool throwOnMissing = false)
{
string setting = null;
if (settingTag != null)
var settingTag = sharedConfig.AppSettings.Settings[settingName];
{
setting = settingTag.Value;
}
if (setting == null)
{
if (throwOnMissing)
{
logger.Trace("App Setting '{0}' not configured. Throwing an exception.", settingName);
throw new EalsConfigurationException(settingName, "App Setting not configured.");
}
logger.Trace("App Setting '{0}' not configured. Defaulting to -1.", settingName);
return -1;
}
int i;
if (!int.TryParse(setting, out i))
{
logger.Trace("App Setting '{0}' not valid as Integer. Throwing an exception.", settingName);
throw new EalsConfigurationException(setting, "App Setting '{0}' not valid as Integer.");
}
return i;
}
But, now basically overnight, the call var settingTag = sharedConfig.AppSettings.Settings[settingName]; returns settingTag as null, because there are no appSettings items in that collection.
I have been working on this project for months, and I put this config code in way in the beginning because I had several executables running in the same folder, and I want them to all use the same config. I am really stumped (not surprised) that I made no memorable code changes to config.
Can anyone see what I might have screwed up, or guess at what external influences I may have changed, or at anything that could suddenly cause all the sections of this Configuration object to be empty.
One suspicion I have, but cannot trace, is a change in what user that app runs as. It's complicated: I have a WCF service hosted in a Windows Services, consumed by a WPF application.
Trial and error has brought to light some sort of answer. When coding and debugging with separate WCF library, host, and client, projects, you need the same config settings in all three projects. Sometimes VS2013 (I dunno about others) auto-hosts the WCF library, in some unknown process somewhere, and for this reason you need a copy of app.config in the library project, even though it is not an executable.

Enterprise Library 5: Creating instances of Enterprise Library objects

I am using Enterprise Library 5.0 in my win-form Application.
1. Regarding creating instances of Enterprise Library objects
What is the best way to Resolve the reference for Logging / exception objects? In our application, we have different applications in solution. So Solutions have below project:
CommonLib (Class Lib)
CustomerApp (winform app)
CustWinService (win service proj)
ClassLib2 (class Lib)
I have implemented logging / exceptions as below in CommonLib project. Created a class AppLog as below:
public class AppLog
{
public static LogWriter defaultWriter = EnterpriseLibraryContainer.Current.GetInstance<LogWriter>();
public static ExceptionManager exManager = EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>();
public AppLog()
{
}
public static void WriteLog(string LogMessage, string LogCategories)
{
// Create a LogEntry and populate the individual properties.
if (defaultWriter.IsLoggingEnabled())
{
string[] Logcat = LogCategories.Split(",".ToCharArray());
LogEntry entry2 = new LogEntry();
entry2.Categories = Logcat;
entry2.EventId = 9007;
entry2.Message = LogMessage;
entry2.Priority = 9;
entry2.Title = "Logging Block Examples";
defaultWriter.Write(entry2);
}
}
}
And then I used Applog class as below for logging and exception in different projects:
try
{
AppLog.WriteLog("This is Production Log Entry.", "ExceCategory");
string strtest = string.Empty;
strtest = strtest.Substring(1);
}
catch (Exception ex)
{
bool rethrow = AppLog.exManager.HandleException(ex, "ExcePolicy");
}
So its the correct way to use Logging and Exception? or any other way i can improve it?
2. Logging File Name dynamic
In logging block, we have fileName which need to be set in app.config file. Is there a way I can assign fileName value dynamically through coding? Since I don't want to hard code it in config file and paths are different for production and development environment.
Thanks
TShah
To keep your application loosely coupled and easier to test, I would recommend defining separate logging and exception handling interfaces, then having your AppLog class implement both. Your application can then perform logging and exception handling via those interfaces, with AppLog providing the implementation.
You can have a different file name set per environment using config transforms, which I believe you can use in a winforms application by using Slow Cheetah.

Silverlight communication with XML RPC console server

I want to comunicate with Console XML RPC server from my silvelight application. Is it possibile?
Steps:
1. Start the Console XML RPC server
Code for Console XML RPC server is this:
using System;
using System.Collections;
using System.Runtime.Remoting;
using System.Runtime.Remoting.Channels;
using System.Runtime.Remoting.Channels.Http;
using CookComputing.XmlRpc;
public class StateNameServer : MarshalByRefObject, IStateName
{
public string GetStateName(int stateNumber)
{
return "whatever";
}
}
class _
{
static void Main(string[] args)
{
IDictionary props = new Hashtable();
props["name"] = "MyHttpChannel";
props["port"] = 5678;
HttpChannel channel = new HttpChannel(props,null,new XmlRpcServerFormatterSinkProvider());
ChannelServices.RegisterChannel(channel,false);
RemotingConfiguration.RegisterWellKnownServiceType(
typeof(StateNameServer),"statename.rem",WellKnownObjectMode.Singleton);
Console.WriteLine("Press <ENTER> to shutdown");
Console.ReadLine();
}
}
Run Silverlight application
I used the code from http://code.google.com/p/xmlrpc-silverlight/
I created new Silverlight application to which I have attached the code from that link. When I start web site (in localhost with port 1139) which executes my SL app happens SecurityException.
void ResponseResponse(IAsyncResult result)
{
XmlRpcHelperRequestState state = result.AsyncState as XmlRpcHelperRequestState;
try
{
state.Response = (HttpWebResponse)state.Request.EndGetResponse(result);
...
}
catch (Exception e)
{
// comes here with SecurityException
}
finally
{
...
}
}
I am using VS2008 Professional,XP Professional, .net 3.5, Silverlight3. I will gladly provide any additional information (or code) which is needed.
I suspect that this is a case of a missing clientaccesspolicy.xml file.
Since your silverlight app will have been launched from another authority it will attempt to access this file the http://localhost:5678/. Since you little test doesn't support that file Silverlight blocks this cross "domain" activity.

Resources