Configuring Specflow+ Runner for parallel test execution across different Browsers - selenium-webdriver

I am using Specflow+ Runner for my automation testing using Selenium/Appium grid at the backend and want to test my scripts in parallel across multiple Browsers
I have referred to the examples from Specflow examples repository (https://github.com/SpecFlowOSS/SpecFlow.Plus.Examples/tree/master/SeleniumGridWebTest) and using the following Default.srprofile
<?xml version="1.0" encoding="utf-8"?>
<TestProfile xmlns="http://www.specflow.org/schemas/plus/TestProfile/1.5">
<Settings projectName="SpecflowTrial" />
<Execution stopAfterFailures="0" testThreadCount="5" testSchedulingMode="Sequential" retryCount="0" apartmentState="MTA" />
<Environment testThreadIsolation="Process" />
<TestAssemblyPaths>
<TestAssemblyPath>SpecflowTrial.dll</TestAssemblyPath>
</TestAssemblyPaths>
<Report>
<Template name="Report\ReportTemplate.cshtml" />
</Report>
<Targets>
<Target name="Browser_Safari">
<Filter>Browser_Safari</Filter>
<DeploymentTransformationSteps>
<EnvironmentVariable variable="Test_Browser" value="Safari" />
</DeploymentTransformationSteps>
<Environment testThreadIsolation="Process" />
</Target>
<Target name="Browser_Chrome">
<Filter>Browser_Chrome</Filter>
<DeploymentTransformationSteps>
<EnvironmentVariable variable="Test_Browser" value="Chrome" />
</DeploymentTransformationSteps>
<Environment testThreadIsolation="Process" />
</Target>
<Target name="Browser_Firefox">
<Filter>Browser_Firefox</Filter>
<DeploymentTransformationSteps>
<EnvironmentVariable variable="Test_Browser" value="Firefox" />
</DeploymentTransformationSteps>
<Environment testThreadIsolation="Process" />
</Target>
</Targets>
<TestThreads>
<TestThread id="0">
<TestAffinity>testpath:Target:Browser_Safari</TestAffinity>
</TestThread>
<TestThread id="1">
<TestAffinity>testpath:Target:Browser_Chrome</TestAffinity>
</TestThread>
<TestThread id="2">
<TestAffinity>testpath:Target:Browser_Firefox</TestAffinity>
</TestThread>
</TestThreads>
</TestProfile>
where the filters are applied to tags on the scenarios
My problem is that when running all tests in parallel, sometimes the tests are triggered across different browsers and sometimes it is triggered for the same Browsers, in this case, all run on either Chrome, Firefox or Safari.
What is the correct configuration that should be used to trigger tests in parallel across different browsers?
Update:
The above question was resolved bumping the SpecRun to version 3.6.2

Related

WPF: what could happen if 2 instances of my application report to the same log [duplicate]

I'm using a RollingFileAppender to log some info to a file with a conversionPattern (in the web.config) that looks like this for the header of each log section:
<conversionPattern value="%date - %property{userId} - %property{method}%newline--------------------------------%newline%message%newline%newline"/>
I'd like to log details under this header as bullet points. I'm currently trying to use another RollingFileAppender that logs to the same file with a simple conversionPattern of just a dash, like this:
<conversionPattern value="- %message%newline"/>
But these messages aren't making it into the log file. I'm using Log.Info() for the header and Log.Debug() for the bullet points and filtering each appender on their respective log levels. Is what I'm trying to do possible? Or is there a better way to get header and detail information into a log file from log4net?
Yes you can have two log4net appenders that append (write) to the same log file.
You need to place the following line in each of your Appenders:
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
This will make log4net use a minimal locking model that allows multiple processes to write to the same file.
Here's an example XML that uses two appenders writing to the same log file:
<log4net debug="false">
<appender name="RollingLogFileAppender1" type="log4net.Appender.RollingFileAppender">
<!-- this configures a log for the application messages -->
<file value="TestLog.log" />
<appendToFile value="true" />
<!-- next line uses a minimal locking model that allows multiple processes to write to the same file -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<!-- make the most recent log the highest numbered log -->
<countDirection value="1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date{MM-dd-yyyy HH:mm:ss.ff} [%property{NDC}] %message%newline [Thread: %thread] %c{1} Method:%method(%file{1}, Line:%line) %newline" />
</layout>
<!-- The following two filters insure only log requests of
version '1' use this Appender -->
</appender>
<appender name="RollingLogFileAppender2" type="log4net.Appender.RollingFileAppender">
<file value="TestLog.log" />
<appendToFile value="true" />
<!-- next line uses a minimal locking model that allows multiple processes to write to the same file -->
<lockingModel type="log4net.Appender.FileAppender+MinimalLock" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="10" />
<maximumFileSize value="10MB" />
<staticLogFileName value="true" />
<!-- make the most recent log the highest numbered log -->
<countDirection value="1" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%-5level %date{MM-dd-yyyy HH:mm:ss.ff} [%property{NDC}] [Thread: %thread] %c{1} Method:%method(%file{1}, Line:%line) %newline%message" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingLogFileAppender1" />
<appender-ref ref="RollingLogFileAppender2" />
</root>
This can be found in the Apache documentation here:
Apache Log4Net Docs
Just search on this page for 'same file'.
Hope this helps.
You could realize if there is any problem with log4net checking the output window on visual studio. The library log errors there, very useful to detect configuration mistakes.

Selenium Grid: Tests are running in sequence at on node at one time

I Need to run a sequence of 2 tests in parallel in 2 node machine at
same time.But currently 1st test gets executed in 1st node and after
the execution is finished,second test gets started in second node. Max
Instance for each node is set to 1.
Here is my suite file:
<!-- <package name="com.fico.triad.test.ApportionmentMethods" />
<package name="com.fico.triad.test.Audit" /> <package name="com.fico.triad.test.AuditTrial" /> --> <package
name="com.fico.triad.test.AuditTrialChangeDetailLog" />
I am using Thread local here also.Any help would be appreciated.
You can do it using TestNG framework with Selenium. Just refer below testng.xml file and edit your classes name accordingly :
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE suite SYSTEM "http://testng.org/testng-1.0.dtd">
<suite name="Parallel test suite" parallel="classes" thread-count="2">
<test name="Test 1">
<classes>
<class name="com.sd.selenium.FirstTestSelenium" />
<class
name="com.sd.selenium.practice.Monday_Test_Selenium_Till_Scrum_Call" />
</classes>
</test>
</suite>
Note:
1) Two classes must be in different packages.
2) You need to run entire project as TestNG Suite by selecting this xml file as your suite . Refer below image :

log4net log file not being written when the app is deployed

I have a WPF app that uses log4net. When I run it in Visual Studio, the log file is created in the Debug or Release folder as expected.
However, when I create an installer and run the installed app, the log file is not created. I added the following lines to the code...
string logFilePath = ((Hierarchy)LogManager.GetRepository())
.Root.Appenders.OfType<FileAppender>()
.FirstOrDefault()?.File;
using (StreamWriter sw = new StreamWriter(#"d:\log.log")) {
sw.WriteLine("Log file: " + logFilePath);
}
...to enable me to check that the log file was being written in the location I expected. It showed me that the log file was supposed to be written to C:\Program Files (x86)\Physio Diary\PhysioDiaryClient.log which is what I expected.
However, the file doesn't exist. Any idea why?
Here is the top of the App.config file...
<?xml version="1.0"
encoding="utf-8"?>
<configuration>
<configSections>
<section name="log4net"
type="log4net.Config.Log4NetConfigurationSectionHandler,Log4net" />
</configSections>
<log4net>
<appender name="RollingFileAppender"
type="log4net.Appender.RollingFileAppender">
<param name="File"
value="PhysioDiaryClient.log" />
<appendToFile value="true" />
<rollingStyle value="Size" />
<maxSizeRollBackups value="2" />
<maximumFileSize value="1MB" />
<staticLogFileName value="true" />
<layout type="log4net.Layout.PatternLayout">
<conversionPattern value="%date [%thread] %-7level %logger - %message%newline%exception" />
</layout>
</appender>
<root>
<level value="DEBUG" />
<appender-ref ref="RollingFileAppender" />
</root>
</log4net>
The bottom of the file looks like this...
<startup>
<supportedRuntime version="v4.0"
sku=".NETFramework,Version=v4.5.2" />
</startup>
</configuration>
The bits in between are all to do with the WCF services that the app uses.
Anyone any ideas?
Edit: As a test, I tried hard-coding the log file path in App.config to my D: drive (so it's hard-coded, and no question of a permissions issue), but the file still wasn't created.
Thanks to #dymanoid for pointing me in the right direction. The log4net docs are a bit weak in this area, but I found this answer that pointed out that you can use normal environment variables in the config file.
With the aid of this list of environment variables, I ended up with the following...
<param name="File"
value="${LOCALAPPDATA}\Physio Diary\PhysioDiaryClient.log" />
This correctly write the file to C:\Users\MyUsername\AppData\Local\Physio Diary\PhysioDiaryClient.log
Hope this helps someone.

Silverlight Webpart: Error occurred in deployment step 'Activate Features' because of autognerated code

I'm developing multiple Silverlight-Webparts in a single Solution in VisualStudio 2012 for SharePoint 2010.
Sometimes this error occurs in {Project1}:
Error occurred in deployment step 'Activate Features':
Failed to instantiate file "SiteAssets/{Project1Folder}/$SilverlightXapFile$"
from module "Designer": Source path "Features\{Project1Folder}\{otherProject}.xap" not found.
Elements.xml
<?xml version="1.0" encoding="utf-8"?>
<Elements xmlns="http://schemas.microsoft.com/sharepoint/" >
<Module Name="{Module}" List="113" Url="_catalogs/wp">
<File Path="{Module}\{Webpart}.webpart" Url="{ProjectWebpart}.webpart" Type="GhostableInLibrary">
<Property Name="Group" Value="{Company}" />
</File>
</Module>
<Module Name="{Project}">
<File Path="{Project}\{Project1}.xap" Url="SiteAssets/{Project1Folder}/{Project1}.xap" />
<File Path="{Project}\{otherProject}.xap" Url="SiteAssets/{Project1Folder}/$SilverlightXapFile$" />
</Module>
</Elements>
Thanks to Subversion: I know Visual Studio added a line to Elements.xml of the {Project1} Webpart.
<File Path="{Project}\{otherProject}.xap" Url="SiteAssets/{Project1Folder}/$SilverlightXapFile$" />
When I delete this new line, it will work again.
My question:
How do I prevent VisualStudio from adding "wrong" references in Elements.xml to other Silverlight-Projects in the same solution?

Ant: Find the path of a file in a directory

I want to find the path of a file in a directory (similar to unix 'find' command or the 'which' command, but I need it to work platform-independent) and save it as a property.
Tried to use the whichresource ant task, but it doesn't do the trick (I think it's only good for looking inside jar files).
I would prefer if it would be pure ant and not to write my own task or use a 3rd-party extension.
Notice that there might be several instances of a file by that name in the path - I want it to only return the first instance (or at least I want to be able to choose only one).
Any suggestions?
One possibility is to use the first resource selector. For example to find a file called a.jar somewhere under directory jars:
<first id="first">
<fileset dir="jars" includes="**/a.jar" />
</first>
<echo message="${toString:first}" />
If there are no matching files nothing will be echoed, otherwise you'll get the path to the first match.
Here is an example which selects the first matching file. The logic is as follows:
find all matches using a fileset.
using pathconvert, store the result in a property, separating each matching file with line separator.
use a head filter to match the first matching file.
The functionality is encapsulated in a macrodef for reusability.
<project default="test">
<target name="test">
<find dir="test" name="*" property="match.1"/>
<echo message="found: ${match.1}"/>
<find dir="test" name="*.html" property="match.2"/>
<echo message="found: ${match.2}"/>
</target>
<macrodef name="find">
<attribute name="dir"/>
<attribute name="name"/>
<attribute name="property"/>
<sequential>
<pathconvert property="#{property}.matches" pathsep="${line.separator}">
<fileset dir="#{dir}">
<include name="#{name}"/>
</fileset>
</pathconvert>
<loadresource property="#{property}">
<string value="${#{property}.matches}"/>
<filterchain>
<headfilter lines="1"/>
</filterchain>
</loadresource>
</sequential>
</macrodef>
</project>
I created a macro based on martin-clayton's answer.
sample project with macro and a property file that is read from the found file
<?xml version="1.0" encoding="utf-8"?>
<project name="test properties file read" default="info">
<macrodef name="searchfile">
<attribute name="file" />
<attribute name="path" default="custom,." />
<attribute name="name" />
<sequential>
<first id="#{name}">
<multirootfileset basedirs="#{path}" includes="#{file}" erroronmissingdir="false" />
</first>
<property name="#{name}" value="${toString:#{name}}" />
</sequential>
</macrodef>
<searchfile name="custom.properties.file" file="config.properties" />
<property file="${custom.properties.file}" />
<target name="info" >
<echo>
origin ${config.origin}
</echo>
</target>

Resources