Coded UI Tests : Property “ReadOnly” cannot be retrieved due to the current state of Edit

, , 4 Comments

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.
[xml] <RichTextBox IsReadOnly="True" Margin="3" />[/xml]

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;
  3. In the code, Assert that the value is equal to ‘True’.

[csharp][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);
}[/csharp]

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 :
[csharp]
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");
}
[/csharp]

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

A demo solution is available on my DropBox folder as usual.

 

4 Responses

  1. Karthik

    04/04/2016 8 h 54 min

    Hi Jonathan Antoine,
    Can you please suggest a way to find the read only feature for other type of controls?

    I'm stuck with WinClient control and the above code is failing there(Although, i have made changes to the code for the type)

    Please help!

    Thanks,
    Karthik

Comments are closed.