Categories
code development krugle programming

Adding HTTP Headers to WaTiN tests

EDIT (2010-08-17 21:26 GMT) : I found a bug in the COM interop that prevented the code from compiling on certain machines. This has now been fixed so if you copied this code before, please try it again.

It’s taken me a while to figure this one out, so I’m putting up a post in case anyone else has a problem. In our system, we need to inject specific headers into each request to simulate our live environment, which means either injecting those expected headers into our tests or having different controller behaviour for dev and live environments.

WaTiN is great for all the other tests we do, but it doesn’t currently support adding HTTP headers to a request, and after a look through the source code, I can see the hoops they’d have to jump through to make it cross-browser. For our purposes, we just needed IE support, so we have the option of intercepting the events on the IE instance directly.

MyHeaders is a property of type object for COM interoperability. It uses the SHDocVw dll to interact with IE. If you allow MyHeaders to be null, you will get an infinite loop and a StackOverflow. I will not guarantee anything about this code, but I hope it’s one small step towards native WaTiN cross-browser HTTP headers support. I am happy to hear about any success you have using or extending this. I will leave setting of test-specific values and compatibility for other browsers as an exercise for the reader.

Snippet

        private object MyHeaders { get; set; }

        private void beforenavigate2replaceheaders(object pDisp, ref object URL, ref object Flags, ref object TargetFrameName, ref object PostData, ref object Headers, ref bool Cancel)
        {
            if (Headers == null)
            {
                Cancel = true;
                object objTestHeaders = MyHeaders;
                _ieInstance.Navigate2(ref URL, ref Flags, ref TargetFrameName, ref PostData, ref objTestHeaders);
            }
        }
 
        private void beforenavigatereplaceheaders(string URL, int Flags, string TargetFrameName, ref object PostData, string Headers, ref bool Cancel)
        {
            if (Headers == null)
            {
                Cancel = true;
                object objFlags = Flags;
                object objTargetFrameName = TargetFrameName;
                object objTestHeaders = MyHeaders;
                _ieInstance.Navigate(URL, ref objFlags, ref objTargetFrameName, ref PostData, ref objTestHeaders);
            }
        }

        private void SetUpBrowser()
        {
            CloseBrowser();
            Settings.AutoMoveMousePointerToTopLeft = false;
            Settings.MakeNewIeInstanceVisible = true;
            Settings.WaitForCompleteTimeOut = 120;

            _ieInstance = new SHDocVw.InternetExplorerClass();
            MyHeaders = "Content-Type: application/json\r\n";
            ((SHDocVw.InternetExplorerClass)_ieInstance).BeforeNavigate += beforenavigatereplaceheaders;
            ((SHDocVw.InternetExplorerClass)_ieInstance).BeforeNavigate2 += beforenavigate2replaceheaders;
            _browser = new IE(_ieInstance) { AutoClose = true });
        }