How can I edit the default TestNG html report - report

I don't want to create a new one or a custom listener. Is that possible? Where is the html report created in TestNG?

SuiteHTMLReporter [source] is the reporter creating the html report. You can extend and override. Disable default listeners and add your own.

I know this is old , but these reports can be edited and custom reports can be made like below. I have explained here how TestHTMLReporter can be edited
With your customReport You'd have to implement IReporter , extend TestListenerAdapter and override generateReport method if you want to implement a custom TestHTMLReporter . For other reporters you may have to do things a bit differently but the concept will remain the same. You'd achieve custom 'TestHTMLReporter' like below .
Create a CustomReport.java file in your project and copy-paste the whole content of TestHTMLReporter.java , change the name of file in getOutputFile method and it would look like below
public class CustomReport extends TestListenerAdapter implements IReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites,
String outputDirectory) {
}
...
//paste the content of TestHTMLReporter.java here
...
...
Make sure all your imports are in place from TestHTMLReporter.java
Now, in this file change as per your requirement . For ex: if you'd like to add the end time of each of the test then at the correct place in generateTable method add the below snippet
// Test class
String testClass = tr.getTestClass().getName();
long testMillis = tr.getEndMillis();
String testMillisString = Long.toString(testMillis);
if (testClass != null) {
pw.append("<br>").append("Test class Name: ").append(testClass);
// this line to add end time in ms
pw.append("<br>").append("End Time(ms): ").append(testMillisString);
// Test name
String testName = tr.getTestName();
if (testName != null) {
pw.append(" (").append(testName).append(")");
}
Then you'll get like below
Now, You'll get two reports one with default and the other with your file name.
The only thing now remains is switching off the default reporting listeners, so you get only one report. For that you can follow this or you may search for solutions. Hope this helps

Related

Adding type to a document uploaded in Alfresco through behaviour

I am trying to associate a document type to xz:xylo, whenever a document is uploaded in a particular workspace of Alfresco, it should get attached to a type which I defined in xylomodel.xml.
I am trying to achieve this via Alfresco behaviour as procceding via Share has some limitation for my requirement.
Can anyone please correct me if the code attached is syntactically correct and I am approaching correctly.
enter code here
public class ApplyXyloAspect implements NodeServicePolicies.OnCreateNodePolicy {`
private NodeService nodeService;
private PolicyComponent policyComponent;
// Behaviours
private Behaviour onCreateNode;
}
/**
^When a document of type #XyloCmsType(name = "X:xz:Xylo") is created than aspects from xyloModel.xml
^needs to be applied
*/
public void init() {
// Create behaviours
if workspace=workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg
org.alfresco.repo.node.NodeServicePolicies this.onCreateNode = new JavaBehaviour(this, "onCreateNode", NotificationFrequency.FIRST_EVENT);
// Bind behaviours to node policies
this.policyComponent.bindClassBehaviour(Qname.createQName(NamespaceService.ALFRESCO_URI, "onCreateNode"),
Qname.createQName(XYLO.NAMESPACE_XYLO_CONTENT_MODEL, XYLO.TYPE_xz_xyloModel),
this.onCreateNode
);
}
Depending on your requirements you might be better off achieving this through Folder Rules.
If folder rules are not adequate, or if I'm misunderstanding your use of the very specific NodeRef of workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg then I would just check in the onCreateNode method if the created node's parent matches that NodeRef, rather than trying to check in the init method.
so in your init method you would just do something like this:
this.onCreateNode = new JavaBehaviour(this, "onCreateNode", Behaviour.NotificationFrequency.FIRST_EVENT);
this.policyComponent.bindClassBehaviour(NodeServicePolicies.OnCreateNodePolicy.QNAME, Qname.createQName(XYLO.NAMESPACE_XYLO_CONTENT_MODEL, XYLO.TYPE_xz_xyloModel), this.onCreateNode);
And then just check if the node is a child of the node you're trying to have be the parent, in this case you said it would be workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg.
So the onCreateNode method would look something like this.
#Override
public void onCreateNode(ChildAssociationRef childAssociationRef){
NodeRef idealParentNodeRef = new NodeRef("workspace://SpacesStore/973e1b8d-bf61-8196-3278-fbbf0b4375gg");
NodeRef nodeRef = childAssociationRef.getChildRef();
NodeRef parentRef = childAssociationRef.getParentRef();
//First double check and make sure all the nodes exist.
if(nodeService.exists(nodeRef) && nodeService.exists(parentRef) && nodeService.exists(idealParentNodeRef)){
//then check if the parentRef and the idealParentNodeRef match
if(parentRef.equals(idealParentNodeRef)){
nodeService.addAspect(nodeRef, /*QName of the Aspect you want to add*/);
}
}
}
If you know for a fact the node/workspace you're uploading to will be very specific every time you could just do this, though I would probably also suggest throwing in some error handling, logging, etc. but this would get you started at least.
Note that, generally, you shouldn't necessarily expect the NodeRef to stay the same every time, granted, I'm just showing you what you could do based on the information from your post rather than what you should do (which would be finding some other way to reference the NodeRef/workspace you're trying to use, and going on from there, depending on whether that NodeRef/workspace is a Folder or Site, or something else).
Hope this helps.

Create custom testng html report with browser name against method name

I am working on cross browser testing and each of test methods in multiple classes run on 4 browsers Chrome, Firefox, IE, Safari.
The testng HTML reports & extent reports generated have the test methods in a column but I also need the browser name against each test method.
Even if the testng HTML reports would have the browser name against the test method would be great.
I found this link but I just need the browser column next to method column to custom report in the link
You can do it like here. But it would be better to use reporting features for that e.g. you may pass any test name and description to report see docs.
You can do that by creating a customized TestHTMLReporter . Pass any data in your CustomReport.java class and generate your own report like below. I have also explained it here
With your customReport You'd have to implement IReporter , extend TestListenerAdapter and override generateReport method if you want to implement a custom TestHTMLReporter . For other reporters you may have to do things a bit differently but the concept will remain the same. You'd achieve custom 'TestHTMLReporter' like below .
Create a CustomReport.java file in your project and copy-paste the whole content of TestHTMLReporter.java , change the name of file in getOutputFile method and it would look like below
public class CustomReport extends TestListenerAdapter implements IReporter {
#Override
public void generateReport(List<XmlSuite> xmlSuites, List<ISuite> suites,
String outputDirectory) {
}
...
//paste the content of TestHTMLReporter.java here
...
...
Make sure all your imports are in place from TestHTMLReporter.java
Now, in this file change as per your requirement . For ex: if you'd like to add the end time of each of the test then at the correct place in generateTable method add the below snippet
// Test class
String testClass = tr.getTestClass().getName();
long testMillis = tr.getEndMillis();
String testMillisString = Long.toString(testMillis);
if (testClass != null) {
pw.append("<br>").append("Test class Name: ").append(testClass);
// this line to add end time in ms
pw.append("<br>").append("End Time(ms): ").append(testMillisString);
// Test name
String testName = tr.getTestName();
if (testName != null) {
pw.append(" (").append(testName).append(")");
}
Then you'll get like below
Now, You'll get two reports one with default and the other with your file name.
The only thing now remains is switching off the default reporting listeners, so you get only one report. For that you can follow this or you may search for solutions. Hope this helps

Dynamic data-driven website localization

I have a website that reads some of its content from a database, I need this website in both languages, English and Arabic.
the needed content is duplicated in the database in both languages. lets say I have a En_Name and Ar_Name columns in my database.
and for example for the Arabic version of the website a link will display a text from Ar_Name , and with the English one it should display the text from the En_Name.
for the static content in my website I think it is a good idea to use the ASP.NET default localization using (.resx files). but what I don't know is how to do the localization for the dynamic section of the website.
So, how can I make the same hyperlink read once from the Ar_Name field, and then from the En_Name based on the users choice (Localization)?
There are many ways to accomplish this. You've not mentioned which database technology you are using, so my example is with Entity Framework. You may need to customise this to your own situation.
Something similar may be possible with LinqToSql or other ORMs. If you are using something else entirely, then the key is to have a central class that you pass something consistent to (hence the interface) that does the translation.
For example, if I was using Entity Framework, every table in the database that had these two fields I'd add an interface that exposes those fields. Then I'd have a helper class with a method that took any entity with that interface and checked the current localisation and return the correct version of the text.
public interface IBilingualEntity
{
// Defines a consistent interface that indicates which language version
// each thing is in.
string Ar_Name { get; }
string En_Name { get; }
}
public partial MyEntity : IBilingualEntity
{
// This is a class generate by Entity Framework. But it could
// be anything really if you are using some other framework.
//
// Nothing to do here as the other side of the partial
// should already implement the interface with the code
// generated from Entity Framework. If not, implement the
// interface and return the correct language version in
// the property.
}
// This is the helper that works out which language version to use.
public class BilingualHelper
{
public string GetName(IBilingualEntity entity)
{
// NOTE: You may have to strip away the region part of the name
// but off the top of my head I can't remember the format.
// If you are using something else to store the culture you'll
// have to reference that instead.
var cultureName = Thread.CurrentThread.CurrentUICulture.Name;
if (cultureName == "ar")
return entity.Ar_Name;
return entity.En_Name;
}
}

Public variables in MVC 3 Razor _ViewStart

I'm building a site on the new Razor engine that comes with MVC 3 (and loving the new syntax!). However, I am at a loss about using public properties / constants with it. I know that with WebForms we could add a public property in code behind:
public string ImageFolder { get; set; }
I would like to define important variables in one global place that my views can access, starting with paths to CSS files and images:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
var ContentFolder = "~/Content";
var CssFolder = ContentFolder + "/Stylesheets";
var ImageFolder = ContentFolder + "/Images";
}
I have tried putting the above code block in _Layout, as well as inside _ViewStart. However, accessing them from child views fails miserably. I thought of defining a public property in the above code block but it doesn't compile.
Solutions?
As far as I have seen, noone uses code behind with Razor.
I guess I should be able to inherit from the default view and define my properties there (as described on Stack).
But I'm strongly hoping that there should be an easier way to do something so simple?
I decided to follow yet another path, and extended UrlHelper to provide paths to all three folders I think I might need:
public static class ExtensionMethods
{
private const string ImagesFolder = "~/Images";
private const string StylesheetsFolder = "~/Stylesheets";
private const string ScriptsFolder = "~/Scripts";
public static string Images(this UrlHelper url)
{
return url.Content(ImagesFolder);
}
public static string Stylesheets(this UrlHelper url)
{
return url.Content(StylesheetsFolder);
}
public static string Scripts(this UrlHelper url)
{
return url.Content(ScriptsFolder);
}
}
All good to go... almost :-) I'm now wondering if there's a place where I would be able to define the using MyNamespace.Helper statement would go in order for these extension methods to be available application-wide. In the old days we would add an entry in web.config:
<system.web>
<pages>
<namespaces>
<add namespace="MyNamespace.Helper"/>
</namespaces>
</pages>
</system.web>
This doesn't seem to work with Razor :-( I tried adding a using statement in _ViewStart.cshtml but no luck either - the only way for my extension methods to be visible is to add a using statement on a particular page, which again isn't ideal.
Any suggestions? Have any of you seen an explanation of Razor's order of page parsing & delivery?
Your can create a folder "App_Code" and create a file "GlobalVal.cshtml".
bellow is a sample code in the file:
#functions{
public static readonly string __siteHome = "http://www.example.com";
public static readonly string __siteResource = "http://resource.example.com";
}
and bellow is a sample using it:
#GlobalVal.__siteHome
Use the PageData property:
#{
Layout = "~/Views/Shared/_Layout.cshtml";
PageData.Add("ContentFolder", "~/Content");
}
and inside _Layout.cshtml:
<%=PageData["ContentFolder"]%>
In _layout view
#{
App.AnyName = "abc";
}
In Inherit view
#{
var anyVariable = App.AnyName;
}
Just place the constants in a public module inside your app_code folder, or if you don't want to do that just create a clasas in app_code and use the using (imports) keyword to import the namespace (class name) in each view and you can use it that way.
Alternatively, if it makes sense to do so, just add them in your view model - remember, it might not make sense to add those vars to your model, but it can make sense to add them to your view model! This is what the view model is for, and this view model can grab the constant values from a public module or class or you can even set it in your actual view model itself, this way you will only define the values in one place and you don't need to use any namespace imports into each view :)
Let me know how it goes and if there is anything else I can do to help you out.
In vb.net but same as csharp and its easy to understand since it's vb.
Public class YourModel
// this is where you have the normal model you have... No big deal
End Class
...
// now you make the view model urself
...
Public class MyViewModel
Public MyNormalModel as YourModel
//notice we r declaring ur normal model as a variable, u can use a property instead
Public MyPathConstant1 as string = "abc"
Public MyPathConstant2 as string = "abc"
Public MyPathConstant3 as string = "abc"
End Class
Now, you gotta set the value of MyNormalModel to ur current model instance, although you can do that in ur controller, it's best practice to create a method inside the MyViewModel class that takes a copy of ur current model as argument and does the setting of MyNormalModel to the current model we just passed in the argument.
You can still make that call in your controller, but on another note, what people prefer to do is, instead of passing the whole normal model as a property, the just take the bits and pieces they need from the normal model and place them into the view (ie: you might just need half the properties in the normal model to be in the view model). This is because, remember, the view model will be passed to the view and they don't wanna pass things they wont use :). But this means you are going to need to set each of those properties one by one most likely (unless those exact ones are encapsulated in a sub class which usually doesn't happen by chance lol).
I kept it in one so you can just copy the normal model over in one shot for simplicity.
Now when you pass the view model to your view (MyViewModel) you will be able to use and access the normal model through the object notation and it's properties, eg... Model.MyNormalModel.Property1. Etc and do whatever you want with it in the view... Also, you can access the rest of your view model (the const values that we set) like this... Model.MyPathConstant1 and Model.MyPathConstant2 etc... So you have access to practically everything you want, ur normal model and whatever else you added later on all through what is now called your view model.
Please excuse typos -writing from and ipad lol. Let me know if this is making more sense.
You could use the built-in property of UrlHelper Content:
#Url.Content("~/Content/Stylsheets")
#Url.Content("~/Content/Images")

Unity 2 trouble referencing RegisterInstance using InjectonProperty

I have the following code:
Unity Container:
Settings settings = CreateSettings();
container.RegisterInstance(settings)
.RegisterType<MyHttpHandler>(new InjectionProperty[]
{
// How do I tell Unity to inject my settings created above?
new InjectionProperty("Settings", new ResolvedParameter(????))
});
MyHttpHandler:
public class MyHttpHandler: IHttpHandler
{
public MyHttpHandler()
{
IoC.Inject(this);
}
public Settings Settings
{
get;
set;
}
}
How do I tell Unity to inject the settings? This works just fine with interfaces but not sure how to proceed here.
Any help is appreciated.
It just goes off the type. You've registered an instance for the Settings class, so you just need to tell it to inject that type:
container.RegisterInstance(settings)
.RegisterType<MyHttpHandler>(
new InjectionProperty("Settings", new ResolvedParameter<Settings>());
(Note that you don't need the extra array, RegisterType takes a variable parameter list.)
Since this is a common requirement, there are shorthands you can use. First off, if you're resolving a dependency and you just need the default (non-named) registration, you don't need to use ResovledParameter, you can just pass the type object:
container.RegisterType(settings)
.RegisterType<MyHttpHandler>(
new InjectionProperty("Settings", typeof(Settings));
But, we can also go simpler than that. If you're using the default for a property based on the type, you don't need to pass the value at all - the container will simply use the type of the property. So you can just say:
container.RegisterType(settings)
.RegisterType<MyHttpHandler>(
new InjectionProperty("Settings"));
and the container will figure it out.

Resources