Create custom testng html report with browser name against method name - report

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

Related

How can I edit the default TestNG html 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

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;
}
}

<table:column> Roo-tag for property of referenced entity

I've got a two classes (pupil, class) in a Roo-project and their scaffolded views.
pupil and class have a 1:1 relationship
In the list.jspx of pupil I'd like to display a column for a property of class.
I don't know the correct attributes to give to the table:column-tag.
This following example gives the error:
SpelEvaluationException: EL1027Epos 4): Indexing into type 'com.pupil' is not supported
<table:table data="${pupil}" duplicate="true" id="l_com_pupil" path="/admin/pupil" z="user-managed">
<table:column id="c_com_pupil_pupilName" property="pupilName" z="user-managed"/>
<!-- I'd like to display the attribute teacher_name of the class 'class' here but it doesn't work -->
<table:column id="c_com_pupil_class_teacherName" property="teacherName" z="user-managed"/>
</table:table>
Instead of messing around with the jspx files, you can simply do this by implementing a converter for the Teacher entity within the ApplicationServiceFactoryBean.java.
See the below conversion method for an example.
static class com.mycompany.test.controllers.ApplicationConversionServiceFactoryBean.TeacherConverter implements org.springframework.core.convert.converter.Converter<com.mycompany.test.domain.master.Teacher, java.lang.String> {
public String convert(Teacher teacher) {
return new StringBuilder().append(teacher.getName()).toString();
}
}
By default, Roo generates these converters and they are stored within the ApplicationConversionServiceFactoryBean_Roo_ConversionService.aj file.
You can push in refactor the related method for the Teacher entity from this aspectJ file into the
ApplicationServiceFactoryBean.java file and then implement your own conversion which will be used to show the Teacher name across the application as in the above example.
Cheers and all the best with Roo!
This is how I did it, not for listing, but rather for showing the name of the teacher when you view the pupil entity:
Edit the controller and specifically the method show (in the java file, not in the aj file, of course).
Add an attribute to your UI Model, for instance "teacherName" (use Model.addAttribute), where you populate the teacherName with the desired name.
Add in the show.jspx file something like:
<div><label for="_pupilTeacher">Teacher Name:</label><div class="box">${teacherName}</div></div><br/>
(alternatively, you could create a new tagx file with your own parameters)
Hope it helped.
Radu

Flex data binding with View-Model pattern

I'm trying to move toward using the View/Model/View-Model or Presentation Model pattern in a Flex application since it definitely feels like the "correct" way to do things. I have a question about how something should work with Flex data binding though.
Say I have a Project model class which contains a bindable name field. I want to make a report to display information about the project. The title of the report should be [Project Name] Summary. I want to make a View-Model class to provide the backing for the report. This SummaryViewModel class will have a title field to provide the report title.
In my report mxml I would bind the title label to summaryModel.title, however title needs to somehow be bound to projectModel.name so if the name is changed in another part of the program the report title updates also.
What's the correct way to accomplish this "two-level" data binding in Flex? Should I be doing things a different way?
Let's say you have a model like this:
[Bindable]
public class Project {
public var name:String;
}
And you have your presentation model:
[Bindable]
public class SummaryPresentationModel
{
private var projectModel:Project = new Project();
public var title:String;
}
In your constructor, you can data bind the setter of the model to a function that sets the title:
public function SummaryPresentationModel() {
BindingUtils.bindSetter(modelNameChanged, projectModel, "name");
}
And then set the value of title:
private function modelNameChanged(newValue:String):void {
title = "[" + projectModel.name + "] Summary";
}
You are then free to bind to the summaryPM.title and everything will chain to the UI when projectModel.name changes.
You can get more complicated and use a "getter" function on title (as opposed to just setting it like I am here), but you need to propagate the change notification. I is not too terribly difficult to do, but I find that this method is a bit easier to follow.
Hope this helps!
No different than any other binding, they will both be updated (both being the place you're putting the title and the summary model).
If you post how you are defining your values I can help you with syntax, but this isn't a difficult binding operation. Where things get mildly more complicated would be with two way binding.

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")

Resources