NPM – no sudo

I was listening to a John Papa course on gulp, and he mentioned that you don’t have to use sudo. Googling stuff around that, I found this.

npm01

And in case you hadn’t noticed, that is now a quarter of the year passed.

Advertisements

Jasmine: starting out

Get the Jasmine download. If you don’t want to use GitHub… and I don’t, go here , and download the most recent jasmine-standalone-(version).zip, and expand it. You can then make that the start of a template for your file/folder structure:

jasmine01

jasmine02

By convention, the spec folder contains your tests… or checks, as the fashion might be starting to have it. The Jasmine folks have done a great job of giving you a basic JavaScript application and Jasmine test application that you can use. SpecRunner.html is the file you execute to run the tests, giving you this:

jasmine03

Schweeeet. I did no editing, and no compilation (well, ref the latter, of course not).

In fact the Jasmine folks have gone 1 better: even though when you look at the spec and src folders, and at SpecRunner.html, it’s all pretty much self-documenting, they also have a good documentation section:

jasmine04

As a final action, I changed a test expectation in the delivered set from false to true, just so you can see what failure looks like:

jasmine05

If you are not using Karma as the test-runner (and this setup does not assume Karma), then it is worth emphasising that the SpecRunner.html is what you execute, or can execute, in a manual situation, with importantly, its references to the Spec files (that is the unit test files), and the JavaScript source files under test:

ManualCall01


<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Jasmine Spec Runner v2.2.0</title>

  <link rel="shortcut icon" type="image/png" href="lib/jasmine-2.2.0/jasmine_favicon.png">
  <link rel="stylesheet" href="lib/jasmine-2.2.0/jasmine.css">

  <script src="lib/jasmine-2.2.0/jasmine.js"></script>
  <script src="lib/jasmine-2.2.0/jasmine-html.js"></script>
  <script src="lib/jasmine-2.2.0/boot.js"></script>

  <!-- include source files here... -->
  <script src="src/Player.js"></script>
  <script src="src/Song.js"></script>

  <!-- include spec files here... -->
  <script src="spec/SpecHelper.js"></script>
  <script src="spec/PlayerSpec.js"></script>

</head>

<body>
</body>
</html>


fin01
or if you prefer…

fin02

Testing vs Checking

I was at a testing conference on Friday. Something of a new experience for me. Quite a different dynamic from a developer conference. I might have got more value from going to the Hands-On workshops (budget allowing, but I think I have had my allotted days 🙂 )…

TestBash2015_01

TestBash2015_02

A word I had never heard before was Checking… at least not repeated so frequently in any other place. People nodding sagely at its mention. Getting home, I googled Testing vs. Checking, and this post appeared, which feels like the Testing equivalent of the Agile Manifesto, well, not quite, but it’s couched in those kind of terms. The author is James Bach, with Michael Bolton. James Bach is the author (if I have understood) of Rapid Software Testing. It feels like a more risk-based approach than that of the ISQTB, but the latter would doubtless say they value the risk-based focus as much as anyone.

At the end of the day (that’s literally, not figuratively), in something called the 99 second talks, someone railed in favour of the AST, which when you look for that in a testing context, gives you this. Very interesting contrast, in terms of marketing, to the ISQTB approach.

Finally, drifting even further away from the intitial theme, some more links:

http://www.developsense.com

http://www.softwaretestpro.com/List/Podcasts

http://www.satisfice.com/

iTunes: moving computers

Intuitive. Easy to use. Sure, they’re synonyms. As someone who tends to restrict their use of Apple products to music and podcasts, I’m normally prepared to accept that those products do their job well, with a minimum of fuss, as I have no evidence to the contrary.

iTunesBackup01

But sometimes

I moved laptops recently. As I’m starting to use Spotify a bit more than my iTunes library, I was in no immediate rush to transfer. Came the day, I googled for how to transfer the library. Found this page, i.e. an Apple support page, even though on previous use, I had found there was some assumed knowledge, as though all users were regular Mac/iPad etc users, familiar with the detail. But fine.

A library transfer consists broadly of two steps, of course: a backup, and a restore. I read through the instructions on the page, and set about doing the backup. The backup, to my external hard drive, went swimmingly. They’re always great, those backups, aren’t they.  I did a sample check that, yes, there was a parent iTunes folder, yes, there are the subfolders I’m expecting, all great. Still no rush to do the restore. Today, I decided, It’s Time. Follow the instructions for the Restore. Of course, you might review all of the steps looking pro-actively for gotchas before you start the  backup, even. But until you actually perform the steps, you don’t necessarily realise there is a gap. To wit…

“Then choose the iTunes Library file inside.”

Oh, a) what is that? b) couldn’t you have asked in the Backup steps to check it was there?

Ref a) it took no time to understand it was a file with a suffix of [.itl]. Yes I had some on the disk… but not the one I needed, so consequently I have to go and redo the backup (The symptom btw was that the titles appeared in iTunes… but iTunes could not locate the files themselves). Ref b), well that would have been answered by doing a better, more pro-active job with a).

It will wait until another day, but I do find the Apple Help rubbish sometimes. In fairness, that may be no worse than Windows Help.

Wassefferr.

Mixing Concrete

From this site:

A very simple and easy way to remember a popular concrete formula is the 1:2:3 ratio. What this means is one part cement, two parts sand and three parts gravel. Once you become efficient at estimating how much cement you need for a project you can simply multiply these ratios to save time.

Calling HTML from JavaScript, and JavaScript from HTML

Very trivial, but wanted just to show that using an external JS file rather than in-line, I can

  • set the innerHTML of a div from a JS file (which feels a little bit wrong – the UI can know about the “view model”, but the “view model” shouldn’t know about the JS)
  • call a JS function in an external file from say a button in the HTML

That is shown below.

For a while I struggled with getting the HTML to recognise the JS file, even though in the WebMatrix project that created it, the JS file was/is definitely in the right position. In the end, I just moved the files to my main IIS location, rather than get WebMatrix or Visual Studio to create a dynamic IIS (you know what I mean):


 

htmlx04

 


 

htmlx01


 

 


 

htmlx03

 


 

htmlx021

 


 


<!doctype html>

<html>
<head>
    <title>Some title</title>
    <meta charset="utf-8">
    <meta name="viewport" content="width=device-width, initial-scale=1">
    	<link rel="stylesheet" href="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/css/bootstrap.min.css">
    <script src="http://maxcdn.bootstrapcdn.com/bootstrap/3.2.0/js/bootstrap.min.js"></script>

</head>
<body>

<div class="container">

<div id="output"></div>


        <script src="js/script.js"></script>
        <button type="button" class="btn btn-default" onclick="x()"></button></div>
</body>
</html>
function x() {
    alert("test");
}

output.innerHTML = "testing";

Coded UI and Silverlight: edit of the generated record and playback

So it works – this is all the classes squeezed into one. This doesn’t even assert, but it is a big step to get Silverlight CodedUI working under my own steam:

http://pastebin.com/tnubRP0q


using System.Threading.Tasks;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Input;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UITesting.HtmlControls;
using Microsoft.VisualStudio.TestTools.UITesting.SilverlightControls;
using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
using Mouse = Microsoft.VisualStudio.TestTools.UITesting.Mouse;
using MouseButtons = System.Windows.Forms.MouseButtons;

[CodedUITest]
public class MyUi : SilverlightControl
{

    [TestMethod]
    public void BasicCodedUiObjectModelTest()
    {
        BrowserWindow.Launch("http://localhost/DenSite/SmallSL01TestPage.html");
        SilverlightEdit uICalc1Edit = UISmallSL01InternetExpWindow.UISmallSL01Document.
                UISilverlightControlHoPane.UIItemCustom.UIMainPageMainPage.MahEdit;
        uICalc1Edit.Text = "422f"; 
        Playback.Wait(1000);
    }

    public UISmallSL01InternetExpWindow UISmallSL01InternetExpWindow {
        get {
            if ((mUISmallSL01InternetExpWindow == null)) {
                mUISmallSL01InternetExpWindow = new UISmallSL01InternetExpWindow();
            }
            return mUISmallSL01InternetExpWindow;
        }
    }

    private UISmallSL01InternetExpWindow mUISmallSL01InternetExpWindow;
}

public class UISmallSL01InternetExpWindow : BrowserWindow {
    // ctor not needed for the basic test...
    //public UISmallSL01InternetExpWindow()
    //{
    //    #region Search Criteria
    //    //this.SearchProperties[UITestControl.PropertyNames.Name] = "SmallSL01";
    //    //this.SearchProperties[UITestControl.PropertyNames.ClassName] = "IEFrame";
    //    //this.WindowTitles.Add("SmallSL01");
    //    #endregion
    //}

    public UISmallSL01Document UISmallSL01Document {
        get {
            mUISmallSL01Document = null; // debug
            if ((mUISmallSL01Document == null)) {
                mUISmallSL01Document = new UISmallSL01Document(this);
            }
            return mUISmallSL01Document;
        }
    }

    private UISmallSL01Document mUISmallSL01Document;

} // UISmallSL01InternetExpWindow : BrowserWindow 

public class UISmallSL01Document : HtmlDocument {

    public UISmallSL01Document(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
       // this.SearchProperties[HtmlDocument.PropertyNames.Id] = null;
       // this.SearchProperties[HtmlDocument.PropertyNames.RedirectingPage] = "False";
//this.SearchProperties[HtmlDocument.PropertyNames.FrameDocument] = "False";
       // this.FilterProperties[HtmlDocument.PropertyNames.Title] = "SmallSL01";
        //this.FilterProperties[HtmlDocument.PropertyNames.AbsolutePath] = "/DenSite/SmallSL01TestPage.html";
        //this.FilterProperties[HtmlDocument.PropertyNames.PageUrl] = "http://localhost/DenSite/xSmallSL01TestPage.html";
        this.WindowTitles.Add("SmallSL01");

    }

    public UISilverlightControlHoPane UISilverlightControlHoPane
    {
        get
        {
            if ((mUISilverlightControlHoPane == null))
            {
                mUISilverlightControlHoPane = new UISilverlightControlHoPane(this);
            }
            return mUISilverlightControlHoPane;
        }
    }

    private UISilverlightControlHoPane mUISilverlightControlHoPane;

}

public class UISilverlightControlHoPane : HtmlDiv
{

    public UISilverlightControlHoPane(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
        #region Search Criteria
        //this.SearchProperties[HtmlDiv.PropertyNames.Id] = "silverlightControlHost";
        //this.SearchProperties[HtmlDiv.PropertyNames.Name] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.InnerText] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.Title] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.Class] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.ControlDefinition] = "id=\"silverlightControlHost\"";
        //this.FilterProperties[HtmlDiv.PropertyNames.TagInstance] = "1";
        //this.WindowTitles.Add("SmallSL01");
        #endregion
    }

    public UIItemCustom UIItemCustom
    {
        get
        {
            if ((this.mUIItemCustom == null))
            {
                this.mUIItemCustom = new UIItemCustom(this);
            }
            return this.mUIItemCustom;
        }
    }

    private UIItemCustom mUIItemCustom;
} //UISilverlightControlHoPane : HtmlDiv

public class UIItemCustom : HtmlCustom
{

    public UIItemCustom(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
        //this.SearchProperties["TagName"] = "OBJECT";
        //this.SearchProperties["Id"] = null;
        //this.SearchProperties[UITestControl.PropertyNames.Name] = null;
        //this.FilterProperties["Class"] = null;
        //this.FilterProperties["ControlDefinition"] = "width=\"100%\" height=\"100%\" data=\"data:ap";
        //this.FilterProperties["TagInstance"] = "1";
        //this.WindowTitles.Add("SmallSL01");
    }

    public UIMainPageMainPage UIMainPageMainPage
    {
        get
        {
            if ((this.mUIMainPageMainPage == null))
            {
                this.mUIMainPageMainPage = new UIMainPageMainPage(this);
            }
            return this.mUIMainPageMainPage;
        }
    }

    private UIMainPageMainPage mUIMainPageMainPage;
} //UIItemCustom : HtmlCustom

public class UIMainPageMainPage : SilverlightControl
{

    public UIMainPageMainPage(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
        // This next line must be present - comment it out to see the Coded UI failures
        this.SearchProperties[UITestControl.PropertyNames.ControlType] = "MainPage";
        //this.WindowTitles.Add("SmallSL01");

    }

    public SilverlightEdit MahEdit
    {
        get
        {
            mmahEdit = null; //debug
            if ((this.mmahEdit == null))
            {
                // The next line must be present...
                mmahEdit = new SilverlightEdit(this);

                // The next line must reference a control - break the name to see the error
                this.mmahEdit.SearchProperties[SilverlightEdit.PropertyNames.AutomationId] = "Calc1";
                //this.mmahEdit.WindowTitles.Add("SmallSL01");

            }
            return this.mmahEdit;
        }
    }

    private SilverlightEdit mmahEdit;

} // UIMainPageMainPage : SilverlightControl

The result:
NonsenseBut01

A little refactoring…

using System.Threading.Tasks;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Input;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UITesting.HtmlControls;
using Microsoft.VisualStudio.TestTools.UITesting.SilverlightControls;
using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
using Mouse = Microsoft.VisualStudio.TestTools.UITesting.Mouse;
using MouseButtons = System.Windows.Forms.MouseButtons;

[CodedUITest]
public class MyUi : SilverlightControl
{

    [TestMethod]
    public void BasicCodedUiObjectModelTest()
    {
        BrowserWindow.Launch("http://localhost/DenSite/SmallSL01TestPage.html");
        SilverlightEdit uICalc1Edit = GetEditControl();
        uICalc1Edit.Text = "422f";
        Playback.Wait(10000);
    }

    private SilverlightEdit GetEditControl()
    {
        return browserWindow.SLDocument.SLDiv.SlCustom.SLControl.MyEditControl;
    }

    public IEWindow browserWindow {
        get {
            if ((mUISmallSL01InternetExpWindow == null)) {
                mUISmallSL01InternetExpWindow = new IEWindow();
            }
            return mUISmallSL01InternetExpWindow;
        }
    }

    private IEWindow mUISmallSL01InternetExpWindow;
}

public class IEWindow : BrowserWindow {
    // ctor not needed for the basic test...
    //public UISmallSL01InternetExpWindow()
    //{
    //    #region Search Criteria
    //    //this.SearchProperties[UITestControl.PropertyNames.Name] = "SmallSL01";
    //    //this.SearchProperties[UITestControl.PropertyNames.ClassName] = "IEFrame";
    //    //this.WindowTitles.Add("SmallSL01");
    //    #endregion
    //}

    public SilverlightDocument SLDocument
    {
        get {
            mUISmallSL01Document = null; // debug
            if ((mUISmallSL01Document == null)) {
                mUISmallSL01Document = new SilverlightDocument(this);
            }
            return mUISmallSL01Document;
        }
    }

    private SilverlightDocument mUISmallSL01Document;

} // UISmallSL01InternetExpWindow : BrowserWindow 

public class SilverlightDocument : HtmlDocument {

    public SilverlightDocument(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
       // this.SearchProperties[HtmlDocument.PropertyNames.Id] = null;
       // this.SearchProperties[HtmlDocument.PropertyNames.RedirectingPage] = "False";
//this.SearchProperties[HtmlDocument.PropertyNames.FrameDocument] = "False";
       // this.FilterProperties[HtmlDocument.PropertyNames.Title] = "SmallSL01";
        //this.FilterProperties[HtmlDocument.PropertyNames.AbsolutePath] = "/DenSite/SmallSL01TestPage.html";
        //this.FilterProperties[HtmlDocument.PropertyNames.PageUrl] = "http://localhost/DenSite/xSmallSL01TestPage.html";
        this.WindowTitles.Add("SmallSL01");

    }

    public SilverlightDiv SLDiv
    {
        get
        {
            if ((mUISilverlightControlHoPane == null))
            {
                mUISilverlightControlHoPane = new SilverlightDiv(this);
            }
            return mUISilverlightControlHoPane;
        }
    }

    private SilverlightDiv mUISilverlightControlHoPane;

}

public class SilverlightDiv : HtmlDiv
{

    public SilverlightDiv(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
        #region Search Criteria
        //this.SearchProperties[HtmlDiv.PropertyNames.Id] = "silverlightControlHost";
        //this.SearchProperties[HtmlDiv.PropertyNames.Name] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.InnerText] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.Title] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.Class] = null;
        //this.FilterProperties[HtmlDiv.PropertyNames.ControlDefinition] = "id=\"silverlightControlHost\"";
        //this.FilterProperties[HtmlDiv.PropertyNames.TagInstance] = "1";
        //this.WindowTitles.Add("SmallSL01");
        #endregion
    }

    public SilverlightCustom SlCustom
    {
        get
        {
            if ((this.mUIItemCustom == null))
            {
                this.mUIItemCustom = new SilverlightCustom(this);
            }
            return this.mUIItemCustom;
        }
    }

    private SilverlightCustom mUIItemCustom;
} //UISilverlightControlHoPane : HtmlDiv

public class SilverlightCustom : HtmlCustom
{

    public SilverlightCustom(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
        //this.SearchProperties["TagName"] = "OBJECT";
        //this.SearchProperties["Id"] = null;
        //this.SearchProperties[UITestControl.PropertyNames.Name] = null;
        //this.FilterProperties["Class"] = null;
        //this.FilterProperties["ControlDefinition"] = "width=\"100%\" height=\"100%\" data=\"data:ap";
        //this.FilterProperties["TagInstance"] = "1";
        //this.WindowTitles.Add("SmallSL01");
    }

    public SilverlightUtilityControl SLControl
    {
        get
        {
            if ((this.mUIMainPageMainPage == null))
            {
                this.mUIMainPageMainPage = new SilverlightUtilityControl(this);
            }
            return this.mUIMainPageMainPage;
        }
    }

    private SilverlightUtilityControl mUIMainPageMainPage;
} //UIItemCustom : HtmlCustom

public class SilverlightUtilityControl : SilverlightControl
{

    public SilverlightUtilityControl(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {
        // This next line must be present - comment it out to see the Coded UI failures
        this.SearchProperties[UITestControl.PropertyNames.ControlType] = "MainPage";
        //this.WindowTitles.Add("SmallSL01");

    }

    public SilverlightEdit MyEditControl {
        get
        {
            mmahEdit = null; //debug
            if ((this.mmahEdit == null))
            {
                // The next line must be present...
                mmahEdit = new SilverlightEdit(this);

                // The next line must reference a control - break the name to see the error
                this.mmahEdit.SearchProperties[SilverlightEdit.PropertyNames.AutomationId] = "Calc1";
                //this.mmahEdit.WindowTitles.Add("SmallSL01");

            }
            return this.mmahEdit;
        }
    }

    private SilverlightEdit mmahEdit;

} // UIMainPageMainPage : SilverlightControl

Now pass through the url and the AutomationId, strip away the redundant stuff…


using System.Threading.Tasks;
using System;
using System.CodeDom.Compiler;
using System.Collections.Generic;
using System.Drawing;
using System.Text.RegularExpressions;
using System.Windows.Input;
using Microsoft.VisualStudio.TestTools.UITest.Extension;
using Microsoft.VisualStudio.TestTools.UITesting;
using Microsoft.VisualStudio.TestTools.UITesting.HtmlControls;
using Microsoft.VisualStudio.TestTools.UITesting.SilverlightControls;
using Microsoft.VisualStudio.TestTools.UITesting.WinControls;
using Microsoft.VisualStudio.TestTools.UnitTesting;
using Keyboard = Microsoft.VisualStudio.TestTools.UITesting.Keyboard;
using Mouse = Microsoft.VisualStudio.TestTools.UITesting.Mouse;
using MouseButtons = System.Windows.Forms.MouseButtons;

[CodedUITest]
public class MyUi : SilverlightControl
{
    [TestMethod]
    public void BasicCodedUiObjectModelTest() {
        SilverlightEdit uICalc1Edit = GetEditControl("http://localhost/DenSite/SmallSL01TestPage.html","Calc1");
        uICalc1Edit.Text = "42"; 
        Playback.Wait(1000);
    }

    private SilverlightEdit GetEditControl(string Url, string AutomationId) {
        return browserWindow(Url).SLDocument.SLDiv.SlCustom.SLControl.MyEditControl(AutomationId);
    }

    public IEWindow browserWindow(string Url){
      
        if ((mIeWindow == null)) {
            mIeWindow = new IEWindow(Url);
        }
        return mIeWindow;
    }

    private IEWindow mIeWindow;
}
 
public class IEWindow : BrowserWindow {

   public IEWindow(string Url) {
        BrowserWindow.Launch(Url);
   }

    public IEWindow() {
        this.SearchProperties[UITestControl.PropertyNames.Name] = "SmallSL01";
    }

    public SilverlightDocument SLDocument {
        get {
            if ((mUISmallSL01Document == null)) {
                mUISmallSL01Document = new SilverlightDocument(this);
            }
            return mUISmallSL01Document;
        }
    }

    private SilverlightDocument mUISmallSL01Document;

} // UISmallSL01InternetExpWindow : BrowserWindow 

public class SilverlightDocument : HtmlDocument {

    public SilverlightDocument(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {}

    public SilverlightDiv SLDiv {
        get {
            if ((mUISilverlightControlHoPane == null)) {
                mUISilverlightControlHoPane = new SilverlightDiv(this);
            }
            return mUISilverlightControlHoPane;
        }
    }

    private SilverlightDiv mUISilverlightControlHoPane;
}

public class SilverlightDiv : HtmlDiv {

    public SilverlightDiv(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    { }

    public SilverlightCustom SlCustom {
        get  {
            if ((this.mUIItemCustom == null)) {
                this.mUIItemCustom = new SilverlightCustom(this);
            }
            return this.mUIItemCustom;
        }
    }

    private SilverlightCustom mUIItemCustom;
} //UISilverlightControlHoPane : HtmlDiv

public class SilverlightCustom : HtmlCustom {

    public SilverlightCustom(UITestControl searchLimitContainer) :
        base(searchLimitContainer)
    {}

    public SilverlightUtilityControl SLControl {
        get {
            if ((this.mUIMainPageMainPage == null)) {
                this.mUIMainPageMainPage = new SilverlightUtilityControl(this);
            }
            return this.mUIMainPageMainPage;
        }
    } 

    private SilverlightUtilityControl mUIMainPageMainPage;
} //UIItemCustom : HtmlCustom

public class SilverlightUtilityControl : SilverlightControl {

    public SilverlightUtilityControl(UITestControl searchLimitContainer) :
        base(searchLimitContainer) {
        // This next line must be present - comment it out to see the Coded UI failures
        this.SearchProperties[UITestControl.PropertyNames.ControlType] = "MainPage";
    }

    public SilverlightEdit MyEditControl (string AutomationId) {
        
        if ((this.mmahEdit == null)) {
            // The next line must be present...
            mmahEdit = new SilverlightEdit(this);

            // The next line must reference a control - break the name to see the error
            this.mmahEdit.SearchProperties[SilverlightEdit.PropertyNames.AutomationId] = AutomationId;
        }
        return this.mmahEdit;
    }

    private SilverlightEdit mmahEdit;

} // UIMainPageMainPage : SilverlightControl

http://pastebin.com/sKMKPxMd