.NET Zone is brought to you in partnership with:

Jonathan creates software, mostly with C#, XAML, and HTML5/JS. He was awarded the Microsoft MVP in the "Client Application Development section in January 2011 Jon is a DZone MVB and is not an employee of DZone and has posted 23 posts at DZone. You can read more from them at their website. View Full User Profile

Coded UI Tests: Property “ReadOnly” Cannot Retrieved Due to the Current State of Edit

08.07.2012
| 28532 views |
  • submit to reddit

Did you ever encounter this error while trying to retrieve a property value from an AutomationElement ? I did !

Don’t worry, there is always a work-around, and I’ve found one.

In this post, we’ll dig a little more into this issue and give a little example of the “Coded UI Tests” fun :-)

The issue

Let’s create a little demo application wich contains only one control : a RichTextBox set as readonly.

<RichTextBox IsReadOnly="True" Margin="3" />

It may be interesting in a coded ui test to verify that the RichTextBox is really read only. Doing so seems pretty easy with Visual Studio :

  1. Target the element using the coded ui test recorder;
  2. In the code, get ReadOnly property value from the WpfEdit element;
 
[TestMethod]
public void CodedUITestMethod1()
{
    //The target richTextBlock is of WpfEdit type
    WpfEdit uIItemEdit = UIMap.UIPropertyXXXcannotberWindow.UIItemEdit;
 
    //Assert it is really readonly
    Assert.IsTrue(uIItemEdit.ReadOnly);
}

By running this code, you will be disappointed to get this exception : “Property “ReadOnly” cannot be retrieved due to the current state of Edit” ! I try to google this error but nothing is what I found :-( !

How I solved it !

I struggled a lot with the API and I found out that the read only property is also available via an another way.

First of all, you have to add the UIAutomationClient.dll assembly as a reference.

The solution is to get the native element linked to the WpfEdit which is of AutomationElement type. With it I can retrieve the the TextPattern which is supported by the RichTextBox automation peer.

This pattern can be use to select the whole text in the RichTextbox. Then you can retrieve the selection with the same pattern and ask for the IsReadOnly attribute value.

Pretty easy to find no ? (I am just kidding here :-s) !

The resulting, commented, code is here :

 
public static bool IsReadOnly(this WpfEdit richText)
{
    if (richText == null) throw new ArgumentNullException("richText");
 
    //We are in WPF so NativeElement is of AutomationElement type.
    var element = richText.NativeElement as AutomationElement;
 
    //Retrieve the TextPattern,
    var pattern = element.GetCurrentPattern(TextPattern.Pattern) as TextPattern;
    if (pattern == null)
    throw
     new InvalidOperationException("Cannot retrieve the info from the control");
 
    //use the pattern to select the whole RichTextBox
    pattern.DocumentRange.Select();
 
    //    use the pattern to get the selection
    var selection = pattern.GetSelection();
 
     
    if (selection.Any())
    {
        //Retrieve the value of the IsReadOnly attribute
        var attValue = selection[0]
                     .GetAttributeValue(TextPattern.IsReadOnlyAttribute);
        if (attValue == null)
        throw
         new InvalidOperationException("Cannot retrieve the info from the control");
 
        //This is a boolean my dear
        return bool.Parse(attValue.ToString());
    }
 
    throw
      new InvalidOperationException("Cannot retrieve the info from the control");
}

If you are struggling with the same kind of issue, please share it with us in the comment. You may also find intersting the list of available attributes for the TextPattern : http://msdn.microsoft.com/en-us/library/ms608656.aspx

Published at DZone with permission of Jon Antoine, author and DZone MVB. (source)

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)