Monday, March 26, 2012

Javascript from within .NET


Target:
In this post we’ll discuss how to out of curiosity run easily complex Javascript functionality in C# using WebBrowser control (however without using WinForms).

Background:
We can achieve our target via building Web application where one of the web pages will contain JavaScript code. JavaScript method can then be invoked and its results can be returned to server (for instance with simple JQuery).
However, we don’t want to build Web application just to execute some single JavaScript function (but with important output). 

So is it possible to run JavaScript in C# without heavy artillery?

After quick googling, we’ve found couples of tools, most prominent and free are Jint and Javascript.Net.
Both open sources are pretty easy to use in case we want to run simple JavaScript code.
But what happens when JavaScript resides at some 3rd party website and obfuscated?
JavaScript interpreter is not enough in such case, we need browser capabilities in order to load 3rd party obfuscated JavaScript module and run its methods.
With a little help from Google and combining suggestions and tricks from different sources, we compiled a nice solution.

1.Creation of static HTML page
First of all, we created a static HTMLpage HTMLPage1.html with all the relevant scripts definitions. In following example, we’ve created a sample page with 2 references:
1. Reference to obfuscated online 3rd party JavaScript Api which contain class ApiClass with asynchronous function DoSomething().
2. Reference to custom JavaScript file that we created and it is situated at our output directory
In the body of the page, we wrapped calls to both our and external JavaScript API methods with simple functions that receives a list of parameters (in the examples below only one parameter, but it can be freely extended to more) and a callback (will be discussed later)
<html>
  <head>                          
    <script type="text/javascript" src="myJsClass.js"></script>
    <script type="text/javascript" src="http://someObfuscatedApi"></script>               
    <title>Hi</title>
  </head>

  <body> 
    <script type="text/javascript">
        function CallJsMethod(jsParameter, callback) {
            someClass = new someObfuscatedAPI.ApiClass();
            return someClass.DoSomething(jsParameter,function(result){
                callback(result);           
            });
        }

        function CallMyJsMethod(jsParameter, callback) {
            someOtherClass = new myJsClass.MyApiClass();       
            var result = someOtherClass.DoSomethingElse(jsParameter);           
            callback(result);           
        }          
    </script>
   </body>
</html>

2.Running WebBrowser control
Next step is to create and to execute the WebBrowser control in our module.
WebBrowser is a Windows.Forms control, as such it should be executed as Single-Threaded Apartment (STA) process.
In order to start using JavaScript it should be fully loaded in a browser (and we know that from a DocumentCompleted event of the browser).
The following code will do the trick:
public class JsExecuter
{               
    private string m_JsMethod;
    private object[] m_JsParameters;

    public void ExecuteJavaScript(string jsMethod, object[] jsParameters)
    {
       m_JsMethod = jsMethod;                
       m_JsParameters = jsParameters;              
       runBrowserThread();
    }

    private void runBrowserThread()
    {                
       var th = new Thread(() =>
       {
          using (WebBrowser webBrowser = new WebBrowser()
          {
             InitBrowser(webBrowser);
             Application.Run();
          }
        });
        th.SetApartmentState(ApartmentState.STA);
        th.Start();               
    } 

    //load our html page and so all the referenced scripts inside
    private void InitBrowser(WebBrowser webBrowser)
    {
       webBrowser.DocumentCompleted += browser_DocumentCompleted;                
       string curDir = Directory.GetCurrentDirectory();
       webBrowser.Url = new Uri(String.Format("file:///{0}/HTMLPage1.html",curDir));
    }

    private void browser_DocumentCompleted (object sender, WebBrowserDocumentCompletedEventArgs e)
    {
       WebBrowser br = sender as WebBrowser;
       br.Document.InvokeScript(m_JsMethod,m_JsParameters);                     
     }             
}

3.Calling the module and using the callback
Now we know how to create a WebBrowser control and make the call to JavaScript methods from it.The last thing that is left to do is to explain how to use the callbacks.
 
public delegate void ResultArrivedHandler(string results);

// in order to allow communication from JavaScript 
//[ComVisible(true)] should be defined
[ComVisible(true)]
public class CallBack
{
      public ResultArrivedHandler ResultArrived { get; set; }    

      //indicates default member for the object. It allows us to pass  
      //CallBack instance directly to JavaScript, and so JavaScript will
      //invoke its default member
      [DispId(0)]
      public void Call(string result)
      {
         Application.ExitThread();

         if (ResultArrived != null)
         {
            ResultArrived(result);
         }
      }
}

In the code above we defined a class named CallBack. An instance of this class will be passed as a callback to our JavaScript wrapper methods (see Creation of static Html page section).

When a result arrives from JavaScript, the ResultArrived event will be raised to notify our module’s clients.

4.Sample client code:

class Program
{
  static void Main(string[] args)
  { 
    CallBack cb = new CallBack(); 
    cb.ResultArrived += new ResultArrivedHandler(x =>Console.WriteLine(x));
    JsExecuter gs = new JsExecuter();

    // last parameter in parameter list will be callback object
    gs.ExecuteJavaScript("CallJsMethod", new object[] { "some parameter", cb }); 
  }
}
Here we created a CallBack object and subscribed to its ResultArrived event (just prints the results to Output).
Then, we just called to our module. Notice how the parameters and especially CallBack instance were passed (the CallBack instance is the last parameter !).

Epilogue:
That’s all! Simple and elegant solution for pretty tricky problem.
But there is still one big con for this solution and it’s of course the use of the WebBrowser control.
Yes, memory leak issues are still there and weren’t solved (online discussion thread: http://social.msdn.microsoft.com/Forums/en-US/ieextensiondevelopment/thread/88c21427-e765-46e8-833d-6021ef79e0c8).
It’s not a big deal if your application doesn’t run a lot of JavaScript methods.
However if it runs for hours and performs thousands calls to a module above then depending on your machine it can hang or stuck.

Wednesday, March 7, 2012

Best Practices - JavaScript Programming Part 2


Best Practices -
JavaScript Programming
Part 2


Object Oriented Programming

The advantages of OO Programming vs. Procedural Programming are well known but exceed the scope of this post. While JavaScript is not a classic OO language such as Java/C++/C#, it holds many OO capabilities.
Although the syntax of OO programming in JS can be confusing at first, it becomes a very handy and easy to use feature once you get used to it.


Objects(Classes):

As a prototype based language JavaScript does not have classes, therefore it does not contain a ‘class’ statement. Instead, classes can be simulated through functions.

Let’s observe the following example:

function ListItem() { }

We’ve just simulated a class called ListItem. Cool hah?


Objects and Constructors:

Instantiating is done using the ‘new’ keyword. The function itself is used as a constructor.

var li = new ListItem();

Pay Attention: calling the constructor function without the 'new' keyword will result in a regular execution of the function instead of creating a new instance.


Members/Properties:

function ListItem(headline) {
    this.Headline = headline;
}

var headLineItem = new ListItem("HeadLine");

Here the constructor receives one parameter. The HeadLine property is initialized.


Methods:

function ListItem(headline) {
    this.Headline = headline;
    this.ToString = function () {
        return "ListItem:" + this.Headline;
    }
}

var headlineItem = new ListItem("HeadLine");
var stringRepresentation = headlineItem.ToString();

I think we got the idea…


Prototype:

Much like the extension methods mechanism in C#, JavaScript allows the programmer to extend the functionality of an object outside its constructor's scope. This is done using prototype.
For instance, let’s take the object from above and add to it the ability to alert its headline to the screen:

ListItem.prototype.AlertHeadline = function () {
    alert(this.Headline);
}

What we did here was to add the method AlertHeadline() to the object ListItem.
We can now run it from any ListItem instance:

headLineItem.AlertHeadLine();

*Note: prototyping should be used wisely. There’s no sense in extending a local object that exists in your own code with a method written in a different place – just add the method to the constructor function's scope.  In case we choose to extend an external object, we should keep all of our prototype extension methods in a single place (Extensions.js file for example). Otherwise, it can be a major headache trying to track down a prototype method, especially in complex environments that contain a lot of code.
A great example for the use of prototype is the String.format extension:

String.prototype.format = function () {
    var str = this;
    var i = arguments.length;
    while (i--) {
        str = str.replace(new RegExp('\\{' + i + '\\}', 'gm'), 
            arguments[i]);
    }
    return str;
};


JQuery

JavaScript is executed by the built in interpreters of browsers. Though there are standards, different browsers may execute the same JS code slightly different from one another. To ensure the correct execution of your JS code it is advised to use JQuery wherever possible, especially for DOM traversal and AJAX.


Final Words

As I said before, all that is written here comes from my own personal experience. These practices work for me and will hopefully work for some of you.
Enjoy.

Back to: Part 1

Best Practices - JavaScript Programming Part 1


Best Practices -
JavaScript Programming 
Part 1


JavaScript is one of the most popular programming languages today. It is widely used by web developers and client side programmers all over the world. But here’s the thing, while technology companies are strict about their server side code to be structured and readable, the client side code does not get the same attention. Often, the web programming is being delegated to 3rd parties or to server developers who are inexperienced with client development. This can lead to a poorly written client which is OK if it’s a throwaway, but what if the code is there to stay and change over time?
This post is for developers who are familiar with JavaScript but want to get a little bit better at it.  All of the tips given hereby are from my own personal experience, they are not scientific facts and should not be accepted as such.



General Styling

A good place to start is the general appearance of the code. If you’re going to take anything from this post, let it be this: MAKE YOUR CODE READABLE!!! There’s no greater hell than trying to understand a sloppily written JavaScript code, especially if it was written by someone else.
Readability can be fairly achieved by following a few basic guidelines:


Use meaningful variable names, even if they get long. For example:

            var divBuilder is better than var db.


Limit the length of your methods, methods should be no longer than 8 – 10 lines.


Newspaper Paradigm:

Let’s observe the following code:

$(document).ready(function ()
{
    ContactPage.RegisterForEvents();
    ContactPage.FillContactInfo();
    ContactPage.FillAdditionalInfo();
});

You’ve never seen this code before but I bet you can guess what it does. This is due to the newspaper like layout of the method, we’re presented with headlines instead of overwhelming details that are kept out of sight at this level. This way we can directly look up the piece of code that interests us without going through tons of irrelevant data.



Seperation

In the earlier days it was customary to embed scripts inside the Html content. As the years went by, with the improvement of browsers JavaScript engines the use of JavaScript increased dramatically and the scripts volume grew accordingly. Nowadays, separation of the JS code to external JS files will produce a much cleaner and readable Html.



NameSpacing

In JavaScript much like in C, we can add variables to the global scope. For instance we can write the line x = 3 anywhere in the code, then after the evaluation of this line by the interpreter we can successfully reference x from anywhere. When working side by side with external JS code, this can cause naming collisions.
A good solution for this issue is to use namespacing


Let’s look at the following example:

var MathExtensions = {
    PI : 3.14159265,
    Add: function (a, b) {
        return a + b;
    },
    ...
}

In this example we use the JavaScript object literal syntax to create a namespace. The variable PI lives inside the MathExtensions context. To reference it, we’ll have to write :
MathExtensions.PI.

 Same goes for the method Add, we’ll have to use:

MathExtensions.Add(3,5).

For those who come from the statically typed languages world, this may resemble a static class. 
*Note: One may also notice that the value of MathExtensions variable is in fact a valid JSON (Java Script Object Notation).  



Constants

It is almost always a good idea to use constant variables to avoid magic numbers and strings inside the code, especially strings that represent Html classes or IDs.
It was more than once that I encountered lines of code that look like this:

var element = document.getElementById("ActionButton");

or JQuery equivalent:

var element = $("#ActionButton");

If one day we decide to change the ID (or class) of an element (which may happen in web design), we’re in for a risky adventure of tracking down all the references to this element’s ID in the code and change them.

A better way would be to store all these magic strings in variables. A namespace for classes or IDs is advisable. For instance, for the example above we’ll use something like this:


var Classes = {
    ActionButtonID: "ActionButton",
    InputTextBoxClass: "InputTextBox"
    ...
};

The reference will change to:

var element = $("#" + Classes.ActionButtonID);




DRY

The last example emphasizes the practice of a very important principle in programming called the DRY principle. DRY stands for ‘Don’t Repeat Yourself’, but what it really means is ‘One Place To Change’. In the example, when we want to change the class name for an element we’ll change only the value in the Classes namespace.
Do not hold multiple pieces of code that do the same work. If you come across a situation in which you need the same JS code in two different web pages, do NOT duplicate it. Instead, you can hold a shared scripts JS file and reference it from both pages.



More to come in part 2








Monday, March 5, 2012

A Practical Guide - From manual to automated QA

Below is a short talk about PicScout's QA practices, which was delivered by Uri Lavi during Agile Practitioners 2012 conference.



Feel free to share with us any additional insights about your own experience in QA automation.