Accepting a certificate that was not issued by a trusted certificate authority via CodedUI

Introduction

As we starve to have our testing environments as close as possible to our production environment is often the case that we also do set https on out test servers. For the security reasons, however, this are often self-signed certificates. This brings us to a small problem during our test automation.

By default we are pushed to accept the certificate that was not issued by a trusted certificate authority and we are shown the following page:

Security Certificate Page

Now, getting to click a button on a page is not a big deal. Still there is a problem, not in all environments this page is shown. Also, how do we recognize this page correctly?

Let’s check together a solution I came up with.

Implementing CertificateErrorPage

We can declare a HtmlDocument that will represent this page then as we know that this page is shown from a resource, we can used this in order to identify it.

Using a small trick, we will check if this page is shown and if so accept the certificate. In this way we will solve this problem once for all.

public class CertificateErrorPage : HtmlDocument
{
    protected const string sslResource = @"res://ieframe.dll/invalidcert.htm?SSLError=25165952#";

    private HtmlHyperlink _acceptLink;

    public CertificateErrorPage(BrowserWindow browserWindow)
        : base(browserWindow)
    {
        this.SearchProperties[HtmlDocument.PropertyNames.PageUrl] = 
            sslResource + browserWindow.Uri.AbsoluteUri;
    }

    protected HtmlHyperlink AcceptLink
    {
        get 
        {
            if (_acceptLink == null)
            {
                _acceptLink = new HtmlHyperlink(this);

                _acceptLink.SearchProperties.Add(HtmlControl.PropertyNames.Id, "overridelink");
            }

            return _acceptLink; 
        }
    }

    /// 
    /// Emulates the Click on "Continue to this website (not recommended)"
    /// link shown in the page.
    /// 
    public void AcceptCertificate()
    {
        Mouse.Click(AcceptLink);
    }

    /// 
    /// In case you do not want to continue with the security certificate that
    /// was issued by a non trusted certificate authority,
    /// you can choose to close this page.
    /// 
    public void CloseWebPage()
    {
        this.CloseWebPage();
    }
}

As I already mentioned, we know that once IE is showing the page in question, he retrieves it from a resource. The address of that resource is res://ieframe.dll/invalidcert.htm?SSLError=25165952.

We will use this information to identify our page. As you can see in our class constructor we are filtering on PageUrl parameter.

Once we got the right page, we can proceed.

The only element we are interested in this page is the “Continue to this website” link. We should search this element based on it’s ID as you may have a text that varies based on the language settings on your machine.
We are not exposing this element to the users of our class, instead we are going to expose only the actions that are available for this page. As you can see, two possible actions can come out of this page; we can accept to continue or decline and close the page.

In case we do accept the certificate, we are going to emulate a click on our previously found link, otherwise, in case of declining the certificate we will simply close the browser.

Now we need to see how to take advantage of our newly created window.

Using the code

After we launched our browser window, we just need to create the instance of our CertificateErrorPage page and pass the instance of our browser.

Now it is sufficient to verify if our page exists and if so call the AcceptCertificate() method.

Let’s see it in an example:

[TestMethod]
public void CodedUITestMethod1()
{
    BrowserWindow browserWindow = 
        BrowserWindow.Launch(new Uri(@"https://www.google.com"));

    CertificateErrorPage certificateErrorPage = 
        new CertificateErrorPage(browserWindow);

    if (certificateErrorPage.Exists)
    {
        certificateErrorPage.AcceptCertificate();
    }   
}

In the case the page is not shown, the Exists property will return false and no action will be needed. Otherwise, we will search for our hyperlink and preform a click on it.

You can now try it, instead of getting to google.com, by accessing a page that uses a certificate that was not issued by a trusted certificate authority. You will see that it works.

It’s simple and effective and I hope you liked it.

Happy coding!

Starting an InPrivate instance of Internet Explorer in CodedUI

During the preparation of one of my CodedUI tests I came in situation in which I needed to start Internet Explorer with InPrivate Browsing set to active. There is no such a property on BrowserWindow object that can be set, probably because this is a specific Internet Explorer option (although present as functionality with a different name on other browsers). So how do we do it?

A quick search on Google, surprisingly, didn’t gave any results. So I dug into this small challenge.

In order to start Internet Explorer with InPrivate Browsing set to active it is necessary to pass the -private argument to the call of the executable. So how to pass an argument to the BrowserWindow instance that we are creating?

It’s not obvious as not often used but, BrowserWindow.Launch static method has, aside the usual signature accepting an Uri object as a parameter, an overload that accepts a variable number of string  arguments (params string[]). The string arguments specified in the call of this method, will be passed as arguments to the process that is going to be started by invoking the BrowserWindow.Launch, in this case to the process of Internet Explorer. This is quite handy as we can pass our URL and and the necessary -private argument to Internet Explorer and achieve the desired result.

BrowserWindow.Launch("http://www.google.com/", "-private");

How does it work?

If you peek inside the BrowserWindow class, you will see that underneath it is starting a process and it passes all of the parameters as an array of string to the Arguments property.

Process process = 
    new Process {StartInfo = {FileName = "iexplore.exe"}};
StringBuilder commandLine = new StringBuilder();
Array.ForEach(
    arguments, 
    str => commandLine.AppendFormat(
        CultureInfo.InvariantCulture, 
        "{0} ", 
        new object[] { str }));
process.StartInfo.Arguments = commandLine.ToString();
process.Start();

The same can be achieved also by using the following approach:

Process ieInPrivate = new Process();
ieInPrivate.StartInfo.FileName = "iexplore";
ieInPrivate.StartInfo.Arguments = "http://www.google.com/ -private";
ieInPrivate.StartInfo.WindowStyle = ProcessWindowStyle.Maximized;
ieInPrivate.Start();

BrowserWindow browser = BrowserWindow.FromProcess(ieInPrivate);

At the end the result will be a successfully launched Internet Explorer with InPrivate Browsing set to active.
InPrivate

There are also some other handy option that you can pass to Internet Explorer like -extoff that will start Internet Explorer in No Add-ons mode. For a complete list of options check the following page on MSDN.

Happy coding!