This is the fourth post in this series on the extensibility of Coded UI Test. Before reading this, you should read the previous posts of this series to better understand this post.

The interfaces (or rather the abstract classes) required to implement for writing technology adapter for Coded UI Test are as lightweight as possible. Many methods are simple property calls. For another large number, there are smart default algorithms in the engine. These methods are there only for the advance or specific corner scenario for a given technology. In many cases, you would just return null or throw NotSupportedException from these methods to let the engine proceed with the default algorithm. However, still writing a good meaningful extension could easily be couple of weeks to few months cost depending on the complexity of the underlying technology. Similarly, even for this sample, it would be difficult to explain all the code. I have grouped methods\properties in appropriate regions leaving out the important ones outside any region. I will explain the important ones only.

ExcelTechnologyManager

This class extends UITechnologyManager and is responsible for providing the core services for Excel technology adapter. Also, notice that this class (and other classes extending UITechnologyElement) is required to be visible to COM (as done by putting [ComVisible(true)] attribute).

public override string TechnologyName

The TechnologyName is the unique & meaningful name that identifies this technology adapter. Here I use “Excel” as the name.

public override int GetControlSupportLevel(IntPtr windowHandle)

The GetControlSupportLevel() is meant to get the support level (or the confidence of the technology adapter in supporting) the given window handle. The higher the value, the more confident the extension is in supporting the window. The engine simply picks the extension that is most confident. Here I check the class name of the window to see if this is an Excel worksheet or not. If it is Excel worksheet, I return high value else 0.

public override IUITechnologyElement GetFocusedElement(
        IntPtr windowHandle)
public override IUITechnologyElement GetElementFromPoint(
        int pointX, int pointY)
public override IUITechnologyElement GetElementFromWindowHandle(
        IntPtr windowHandle)
public override IUITechnologyElement GetElementFromNativeElement(
        object nativeElement)
public override IUITechnologyElement ConvertToThisTechnology(
    IUITechnologyElement elementToConvert, out int supportLevel)

The above methods are various ways in which engine asks for technology specific UI element. The technology manager needs to support these. The code here is simple and self-explanatory.

public override string ParseQueryId(
        string queryElement, out object parsedQueryIdCookie)

While using Coded UI Test, the user specifies various property name\value pair as search properties. All these together form search query id. Since the match\search for same query id can be called multiple times, the ParseQueryId() function gives the technology manager a way to optimize the parsing of query id by parsing it once and returning the cached cookie. The engine then uses this cached cookie to match\search. The actual implementation just uses the helper Parse() API present in AndCondition class to do the parsing.

public override bool MatchElement(IUITechnologyElement element,
    object parsedQueryIdCookie, out bool useEngine)

A control search can be performed in one of the two ways by the technology manager – either support the Search() method or ask engine (by throwing NotSupportedException from Search()) to do breadth-first navigation & use MatchElement() method to do the search. In MatchElement(), the manager can again use the AndConditon.Match() API to do the task.

ExcelElement

This class extends UITechnologyElement and is responsible for representing an Excel UI element. Most of the code here is returning simple properties about the element like the Name. Two important ones are described below –

public override IQueryElement QueryId

This property returns the search query id i.e. a condition made out of property name\value pair that is good enough to uniquely identify the control during playback. The technology author needs to come up with good query id under all cases (like when there are duplicate controls) to ensure resilient playback. The Name is good property to use here because Excel does not allow worksheets to have duplicate name.

public override void CacheProperties()

This method is called during recording to ask the element to cache or take snapshot of all the important properties so that those are available to engine even after the actual UI has disappeared from the screen.

ExcelWorksheetElement

This class inherits from ExcelElement and overrides few properties to provide worksheet specific information. The code here is simple.

ExcelCellElement

This class inherits from ExcelElement and overrides few properties to provide cell specific information. The code here is simple. The main property to look at is QueryId – for cell, I as the author, decided that RowIndex and ColumnIndex are more appropriate than the Name.

In next blog, I will explain the property provider for this sample.