Coded UI Test - Recording mouse clicks

March 30, 2015

Coded UI Tests are something I’ve always thought would be useful, but have only recently actually used. This post is details of the first issue that I came up against.

The Problem

When you record a Coded UI test, you tell VS you want to do so, run whatever application that you want to test, and then record a series of tests; usually this means clicking the screen. Here’s what one of the UI projects looks like after you finish recording:

CodedUIStructure

The designer file looks something like this for a series of clicks:

        public void RunBuildAnalysisAndClose()
        {
            #region Variable Declarations
            WpfButton uIValidateURIButton = this.UIWpfWindow.UIValidateURIButton;
            WpfButton uIBuildAnalysisButton = this.UIWpfWindow.UIBuildAnalysisButton;
            WinButton uICloseButton = this.UIBuildAnalysisWindow1.UICloseButton;
            WinButton uICloseButton1 = this.UIItemWindow.UICloseButton;
            #endregion

            // Click 'Validate URI' button
            Mouse.Click(uIValidateURIButton, new Point(677, 6));

            // Click 'Build Analysis' button
            Mouse.Click(uIBuildAnalysisButton, new Point(619, 9));

            // Click 'Close' button
            Mouse.Click(uICloseButton, new Point(16, 5));

            // Click 'Close' button
            Mouse.Click(uICloseButton1, new Point(30, 9));
        }

The recording that generated this was a quick test of a codeplex project of mine called TFS Utils.

My initial thought about this was: what happens when the buttons move around the screen, or the resolution changes. So I tried both of those things… and it still works. The points above are relative; what’s more: they are optional. The following is the same code, copied over to UIMap.cs and the points removed.



        public void RunBuildAnalysisAndCloseManual()
        {
            #region Variable Declarations
            WpfButton uIValidateURIButton = this.UIWpfWindow.UIValidateURIButton;
            WpfButton uIBuildAnalysisButton = this.UIWpfWindow.UIBuildAnalysisButton;
            WinButton uICloseButton = this.UIBuildAnalysisWindow1.UICloseButton;
            WinButton uICloseButton1 = this.UIItemWindow.UICloseButton;
            #endregion

            // Click 'Validate URI' button
            Mouse.Click(uIValidateURIButton);

            // Click 'Build Analysis' button
            Mouse.Click(uIBuildAnalysisButton);

            // Click 'Close' button
            Mouse.Click(uICloseButton);

            // Click 'Close' button
            Mouse.Click(uICloseButton1);
        }

Quick Point on the Points

Since this Point seemed effectively pointless, I had a look around, and it turns out there is a reason; which is for menu buttons, where you need to specify a particular point within the button; rather than just anywhere. I would argue that the default recording should be what’s above, as it seems cleaner. I’m not strictly sure who I would argue that with though.

Disabled Controls

If you look at the menu in the project referenced, you’ll see that the menu items enable only when the URI is validated. This took me a while to work out; because if it’s not available, it just breaks the test:



        public void RunBuildAnalysisAndCloseManual()
        {
            #region Variable Declarations
            WpfButton uIValidateURIButton = this.UIWpfWindow.UIValidateURIButton;
            WpfButton uIBuildAnalysisButton = this.UIWpfWindow.UIBuildAnalysisButton;
            WinButton uICloseButton = this.UIBuildAnalysisWindow1.UICloseButton;
            WinButton uICloseButton1 = this.UIItemWindow.UICloseButton;
            #endregion

            // Click 'Validate URI' button
            Mouse.Click(uIValidateURIButton);

            // Wait as long as 30 seconds for this control to become enabled
            uIBuildAnalysisButton.WaitForControlEnabled(30000);

            // Click 'Build Analysis' button
            Mouse.Click(uIBuildAnalysisButton);
            
            // Click 'Close' button
            Mouse.Click(uICloseButton);

            // Click 'Close' button
            Mouse.Click(uICloseButton1);
        }

It’s not difficult to see how this could be extracted into a helper method:



        private void ClickButton(WpfButton button)
        {
            button.WaitForControlEnabled(30000);                        
            Mouse.Click(button);
        }

Conclusion

From the above investigation, I’ve come to a few conclusions: 1. Don’t rely on the designer file (and don’t bother changing it, as it’s generated code) 2. Hand roll tests - you get far more control



Profile picture

A blog about one man's journey through code… and some pictures of the Peak District
Twitter

© Paul Michaels 2024