Tag Archives: automation

My PowerShell video course is available!

For the last months, I have been working on my PowerShell 5 recipes video course. It is now finally published!

Why?

Why make a video course? – you might ask. I come from a system development background, having worked with many development platforms in my time (Java, .NET, Lotus Notes, JavaScript, etc.) Back in 2011, after resisted for a while, I decided to learn PowerShell. So I dived in, head first. Why? Because I realized that in order to get a better delivery process for software, we need a broader scope than just the development per se. We need to get a holistic view of the environment the applications will run in, and we need to automate the deployment. This has become more and more evident with the coming of DevOps and is key to continuous delivery.

I am first and foremost a PowerShell user, and I do not consider myself an expert. Maybe a little more advanced than the average user, though. When the opportunity came to create a video course, the temptation to do something new to me as too hard to resist. I hope I have been able to keep the view of the user, resulting in a pragmatic, hands-on, course.

For whom?

The course is thought to be a smorgasbord of relevant topics in PowerShell that is relevant to the daily work of developers as well as IT. For people new to PowerShell, it will get you started by installing, and/or upgrading to the latest versions (even on Linux), customize, and set up the environment for your preferences. For developers, it gives you hands-on guidance to set up automated build and deployment. For DevOps (and IT), it guides you in provisioning Azure resources. For more advanced users, it gives you recipes on how to develop reusable scripts, handle modules and publishing your scripts to repositories.

Enjoy!

Internet Explorer automation/Watin: catching navigation error codes

One question have troubled me for some time when automating Internet Explorer (actually, I am doing web testing with Watin): how to test for HTTP status codes. Finally, I figured out how to do this. The lies in an event that the InternetExplorer object raises when navigation is unsuccessful.

I ended up with writing a C# helper class:

using System.Net;
using WatiN.Core;
using SHDocVw;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using System.Globalization;
namespace Test
{
    public class NavigationObserver
    {
        private HttpStatusCode _statusCode;
        public NavigationObserver(IE ie)
        {
            InternetExplorer internetExplorer = (InternetExplorer)ie.InternetExplorer;
            internetExplorer.NavigateError += new DWebBrowserEvents2_NavigateErrorEventHandler(IeNavigateError);
        }
        public void ShouldHave(HttpStatusCode expectedStatusCode)
        {
            if (!_statusCode.Equals(expectedStatusCode))
            {
                Assert.Fail(string.Format(CultureInfo.InvariantCulture, "Wrong status code. Expected {0}, but was {1}",
                    expectedStatusCode, _statusCode));
            }
        }
        private void IeNavigateError(object pDisp, ref object URL, ref object Frame, ref object StatusCode, ref bool Cancel)
        {
            _statusCode = (HttpStatusCode)StatusCode;
        }
    }
}

Note that I use Visual Studio test runner to run my web tests. Then, I can use this in my test:

using (IE ie = new IE())
{
    NavigationObserver observer = new NavigationObserver(ie);
    ie.GoTo("http://some.where.com");
    observer.ShouldHave(HttpStatusCode.NotFound);
}

Sending POST requests with Watin

When doing web testing using Watin, it is not trivial to be able to do a POST request to the server. However, with the help this article on microsoft.com, I was able to figure out how. I ended up with writing this class:

public class Navigator
{
    private IE _ie;

    public Navigator(IE ie) { _ie = ie; }

    public void Post(Uri baseUri, params KeyValuePair<string, object>[] postData)
    {
        object flags = null;
        object targetFrame = null;
        object headers = "Content-Type: application/x-www-form-urlencoded" + Convert.ToChar(10) + Convert.ToChar(13);
        object postDataBytes = MakeByteStreamOf(postData);
        object resourceLocator = baseUri.ToString();
        IWebBrowser2 browser = (IWebBrowser2)_ie.InternetExplorer;
        browser.Navigate2(ref resourceLocator, ref flags, ref targetFrame, ref postDataBytes, ref headers);
        _ie.WaitForComplete();
    }

    private static byte[] MakeByteStreamOf(KeyValuePair<string, object>[] postData)
    {
        StringBuilder sb = new StringBuilder();
        if (postData.Length > 0)
        {
            foreach (KeyValuePair<string, object> postDataEntry in postData)
            {
                sb.Append(postDataEntry.Key).Append('=').Append(postDataEntry.Value).Append('&');
            }
            sb.Remove(sb.Length - 1, 1);
        }
        return ASCIIEncoding.ASCII.GetBytes(sb.ToString());
    }
}

For example, I can use it like so:

using (IE ie = new IE())
{
    Navigator navigator = new Navigator(ie);
    navigator.Post(new Uri("http://www.foo.com/"), new KeyValuePair<string, object>("p", 1));
    Assert.AreEqual("OK", ie.Text);
}