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:
using System;
using System.Diagnostics;
using SHDocVw;
using WatiN.Core.Native.InternetExplorer;
using WatiN.Core.UtilityClasses;
namespace ClassLibrary1
{
public class IEFactory
{
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;
}
public IWebBrowser2 DemarreInstanceCOM()
{
int count = new ShellWindows2().Count;
Process process = StartIEProcess();
var getWindowHandle = new TryFuncUntilTimeOut(5) { SleepTime = 100 };
int windowHandle = getWindowHandle.Try<int>(() => process.MainWindowHandle.ToInt32());
var allBrowsers = new ShellWindows2();
if ( windowHandle != 0 )
{
foreach ( var browser in allBrowsers )
if ( ( (IWebBrowser2)browser ).HWND == windowHandle )
return browser as IWebBrowser2;
}
else
{
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;
}
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