juil. 03

Recently, I was playing with WatiN to do some integration and web testing, and I have "discovered" the concept of session merging in the browsers.

What is this ? By default, the browsers (Internet Explorer, Firefox, ...) are sharing the session information of a website (for instance the authentication information) between its tabs and different instances. What does implies in practice ? Just launch one instance of your favorite browser and log into an application (mail, ...). Then launch another instance (for instance another process) of the same browser and go to the same website. You should be logged in, even if you had not checked the magic checkbox "Remember me". Why are they doing this ? Just because many websites expect this behavior. Just imagine how surfing would behave without session merging in an application when it open popups ?

Just note that all website do NOT manage their authentication in the same way, and so, some of them may not be affected by session merging.

So, that's a feature ok. But when you do some web testing and that you would like to launch several browser logged in with different users to check simultaneous actions or things like that, this feature can be very very annoying.

But Internet Explorer 8 has added a new feature, that allow you to surf in a new session, meaning you just deactivate explicitely the session merging. How to do that ? Simple:

  • either from an existing Internet Explorer windows, juts use the menu File / New Session
  • from command line, use IExplore.exe -nomerge

What about in COM ?

Let's go back to my testing session. I was manipulating the DLL "Interop.SHDocVw.dll" to drive my browser and to create a new instance of Internet Explorer, I was just using the syntax new InternetExplorerClass. So how can I use this feature using the COM component ? Well, so far, I haven't found any way to do that directly so I'm waiting for your comments ! :-)

Anyway, I am using a workaround, that has been highly inspired of the source code of WatiN, just updating it to take into account the notion of session merging, and giving enough time to Internet Explorer to start.

To make this compile, you will need two references:

  • Interop.SHDocVw.dll : The COM wrapper exposing the Internet Explorer's classes
  • WatiN.Core.dll : The DLL of WatiN to be able to use the very nice TryFuncUntilTimeOut class and to collect the running instances of IE using the ShellWindows2 class
using System;
using System.Diagnostics;
using SHDocVw;
using WatiN.Core.Native.InternetExplorer;
using WatiN.Core.UtilityClasses;
 
namespace ClassLibrary1
{
   public class IEFactory
   {
      /// <summary>
      /// Start Internet Explorer without session merging
      /// </summary>
      /// <returns>The IE process</returns>
      private Process StartIEProcess()
      {
         string argument = "-nomerge about:blank";
         var process = Process.Start("IExplore.exe", argument);
         if ( process == null )
            throw new InvalidOperationException("The IExplore.exe process can't be started");
 
         return process;
      }
 
      /// <summary>
      /// Start a new instance of Internet Explorer and attach it to a IWebBrowser2 object
      /// </summary>
      /// <returns>The COM object corresponding to the running instance</returns>
      public IWebBrowser2 DemarreInstanceCOM()
      {
         //1. Let's count the current number of IE instances
         int count = new ShellWindows2().Count;
 
         //2. Start the process
         Process process = StartIEProcess();
 
         //3. Let's find the handle of the new running IE
         //   We will try for a maximum of 5 seconds, with trial every 100ms 
         //   if we had not been successful
         var getWindowHandle = new TryFuncUntilTimeOut(5) { SleepTime = 100 };
         int windowHandle = getWindowHandle.Try<int>(() => process.MainWindowHandle.ToInt32());
 
         //4. If we got the handle, let's get the browser
         var allBrowsers = new ShellWindows2();
         if ( windowHandle != 0 )
         {
            foreach ( var browser in allBrowsers )
               if ( ( (IWebBrowser2)browser ).HWND == windowHandle )
                  return browser as IWebBrowser2;
         }
         //5. Otherwise, let's take the first instance on a blank page
         else
         {
            //for that we'll wait until a new instance of IE is running
            var action = new TryFuncUntilTimeOut(5) { SleepTime = 100 };
            action.Try<bool>(() => new ShellWindows2().Count > count);
 
            foreach ( var browser in new ShellWindows2() )
               if ( ( (IWebBrowser2)browser ).LocationURL == "about:blank" )
                  return browser as IWebBrowser2;
         }
 
         //6. We had not been able to start the instance
         throw new InvalidOperationException("Internet Explorer could not be started");
      }
   }
}

Other information ?

Here is the link to the blog I have found explaining about session merging : http://blogs.msdn.com/ie/archive/2009/05/06/session-cookies-sessionstorage-and-ie8.aspx

juil. 02

 Beautiful Code

Leading Programmers Explain How They Think

By Andy Oram and Greg Wilson


Find it on Amazon

Summary of the editor

This unique and insightful book is a collection of master classes in software design.
In each chapter, today's leading programmers walk through elegant solutions to hard problems, and explain what make those solutions so appealing.

This is not simply another design patterns book, or another software engineering treatise on the right and wrong ways to do things. Instead, it gives you the chance to look over the shoulder of some superb software designers and see the world through their eyes.

Thirty-eight master coders think aloud as they work through a project's architecture, the tradeoffs made in its construction, and those moments when it was important to break rules.

My criticsm and comments

This book is an interesting reading to do, but to me, a bit inegal. Some chapters are very good and interesting and let's say I was less sensitive to other ones. What i will do here, is just giving a word about some chapters I found among the ones of best added values.

Chapter 2 : "Subversion's delta-editor interface as ontology" by Karl Fogel

This chapter will show a concrete example of how a classical problem can be solve : tree comparison. It uses as example one core API of Subversion, written in 2000 and still unchanged until now. The main interesting part is showing how you can do the choice of implementing a restrictive API to force users to use it in a given manner. As a consequence, all the future code becomes very predictible and the current porgram is much more robust.

Chapter 7 : "Beautiful tests" by Alberto Savoia

I'm working in TDD for years now and this chapter just bring some testing approach to you. It starts with a very simple code example : the dichotomic search. This algorithm seem to be very simple but 12 years have been necessary to provide the first implementation proven to be bug-free, even with dealing with very large arrays.

What I like in this chapter ? The explanation of the testing strategy : which test you can write and until which point you go to be almost sure your code is bug-free.

Chapter 8 : "On-the-fly code generation for image processing" by Charles Petzold

Charles Petzold is delivering here a very interesting chapter, showing two meanings of the word "beautiful". It starts with a simple - and elegant - code to apply raster operation on images. It works good but is not so performant. As a consequence, he shows us how can generate IL code that will do the image transformation, and above all will be fast. His strategy ? Just generate minimalistic code, that won't have any loop or predicate, limiting the numboer of access to array element, ...

Chapter 14 : "How elegant code evolves with hardwares : The case of Gaussian elimination" by Jack Dongarra and Piotr Luszczek

They present here the evolution of one of the core method of the system LINPACK, LAPACK and ScaLAPACK. What is very interesting is how they made evolve the code to adapt it to the successive computer architecture.

Chapter 17 : "Another level of indirection" by Diomidis Spinellis

A nice explanation of the implementation of the core of FreeBSD dedicated to the IO operation: how an additionnal level of indirection can elegantly support the different type of file system : FAT-32, ISO-9660, NTFS, ... and can even simply support their specificities like security checks. 

Chapter 23 : "Distributed programming with MapReduce" by Jeff Dean and Sanjay Ghemawat

MapReduce is used internally at Google to execute processing of a huge number of data on a huge number of computers. They describe here how we can take advantage of this framework / API to let our programs being executed on a large scale of clusters, and then re-collecting the data into the main application. One of the introduction sentence is clear enough :

"Suppose that you have 20 billion documents, and you want to generate a count of how often each unique word occurs in the documents. With an average document size of 20 KB, just reading through the 400 terabytes of data on one machine will take roughly four months."

Chapter 31 : "Emacspeak : the complete audio desktop" by T. V. Raman

He explains here how he took the Emacs system to provide him with an audio system. What was the most interesting ? The way he does. Indeed he didn't modified the original code but worked in AOP (Aspect oriented Programmation) using the advice functionality of Lisp to provide Emacs with new aspects : the ability to speak.

Conclusion

This book shows interesting code in various languages. Maybe some chapters will be harder to read because you are so unfamiliar with Haskell or Lisp. But anyway, go for them ! They will show interesting thoughts and may point out some functionality of the used language that will let you think "How I would do that in .NET ?". No doubt that this book will inspire you and give you many new ideas !

Go for it !

Want to find more about the books I have read ? Go to my bookshelf to find the few criticism I have already made !

Tags: