Unintelligible

Tuesday, May 8, 2007

Problem Installing .Net Framework 3.0

The .Net Framework 3.0 refused to install on my machine this morning - a quick look through the installation logs (particularly C:\DOCUME~1\<your user name>\LOCALS~1\Temp\VSW1\VSSWMSIFailInfo.txt) revealed the following:

Error 1402.Could not open key:
HKEY_LOCAL_MACHINE/SYSTEM/CurrentControlSet/Services/Eventlog/Security/ServiceModel 3.0.0.0.
System error 5. Verify that you have sufficient access to that key,
or contact your support personnel.

I am a local admin on my machine, so this surprised me a little. The permissions on this key were set to grant Full Control to the ASP.NET user. I granted myself Full Control, but this didn’t seem to help. Granting Everyone Full Control seemed to resolve the issue - other keys in the subtree grant Full Control to the local Administrator group and the System user, so I revoked permissions from Everyone and granted these access to the key once the installation was complete (ah, the power…).

posted by Nick at 6:55 pm - filed in .net  

Friday, May 4, 2007

Using WatiN to automate accessibility testing in .Net

WatiN is a web testing framework for .Net - it is a C# port of Watir, which is in Ruby. Both function by driving Internet Explorer and are fully scriptable, which means you can do things like:

[Test]
public void SearchForWatiNOnGoogle()
{
    using (IE ie = new IE("https://www.google.com"))
    {
        ie.TextField(Find.ByName("q")).TypeText("WatiN");
        ie.Button(Find.ByName("btnG")).Click();
        Assert.IsTrue(ie.ContainsText("WatiN"));
    }
}

This is from the WatiN documentation page, which is pretty helpful - as this shows, it’s easy to get started, and writing basic tests is straightforward (although perhaps not as fast as the Ruby version). WatiN also integrates well with NUnit and other testing frameworks (including TestDriven.Net and the Visual Studio 2005 test runner). I’ve been using this at work to run some basic accessibility tests on some of our web-based products; although accessibility testing can’t be completely automated, it’s pretty handy to be able to perform repetitive HTML inspections automatically. This checks that all <img> tags on a page have the required “alt” attribute (required in the WCAG 1.0 guidelines on images):

[Test]
public void CheckAllImagesHaveAltAttributes()
{
    using (IE ie = new IE("https://localhost/test.aspx"))
    {
        foreach (Image img in ie.Images)
            if (img.Alt == null || img.Alt.Trim().Length == 0)
                Assert.Fail(
                    String.Format("The image with id '{0}' "
                    + "and src '{1}' doesn't have a alt tag "
                    + "in '{2}'",
                    img.Id, img.Src, ie.Url)
                );
    }
}

This checks that all links on a page have a “title” attribute (an overly strict interpretation of the WCAG 1.0 guidelines on links):

[Test]
public void CheckAllLinksHaveTitleAttributes()
{
    using (IE ie = new IE("https://localhost/test.aspx"))
    {
        foreach (Link link in ie.Links)
            if (link.Title == null || link.Title.Trim().Length == 0)
                Assert.Fail(
                    String.Format("The link with id '{0}' "
                    + "and text '{1}' doesn't have a title tag "
                    + "in '{2}'",
                    link.Id, link.InnerHtml, ie.Url)
                );
    }
}

Or that all input fields in a form have an associated “label” tag (WCAG 1.0 guidelines on form labels):

delegate void TestInputFor(IE ie, Element inputField);
 
[Test]
public void CheckAllFormFieldsHaveLabels()
{
    using (IE ie = new IE("https://localhost/test.aspx"))
    {
        TestInputFor assertElementHasLabel =
            delegate(IE ieInstance, Element inputField)
        {
            //check whether the corresponding label exists.
            Debug.WriteLine("Checking whether element "
                + inputField.Id + " has a label");
            int cnt = 0;
            foreach (Label lbl in ieInstance.Labels)
                if (lbl.For.Equals(inputField.Id))
                    cnt++;
            //assert the label was found
            Assert.AreEqual(1, cnt,
                String.Format("Expected a label for text field"
                + " with ID {0}, but found {1:d} in page '{2}'",
                inputField.Id, cnt, ieInstance.Url));
        };
 
        foreach (CheckBox cb in ie.CheckBoxes)
        {
            assertElementHasLabel(ie, cb);
        }
 
        foreach (TextField tf in ie.TextFields)
        {
            if(tf.GetAttributeValue("type").Equals("hidden"))
                continue;
            assertElementHasLabel(ie, tf);
        }
 
        foreach (SelectList sl in ie.SelectLists)
        {
            assertElementHasLabel(ie, sl);
        }
 
        foreach (RadioButton rb in ie.RadioButtons)
        {
            assertElementHasLabel(ie, rb);
        }
    }
}

These are rather basic tests; and they are far from extensive. However, they should give a good idea how much time can be saved by automated testing, especially in the context of standard systems which get customised on a per-client basis (e.g. a content management system for which the layout is customised on a per-client basis; the tests are written once and can be run against each client’s version).

posted by Nick at 8:00 pm - filed in .net, accessibility, testing