SegmentedEntryFilter

protected override void UnconditionalRun(IUITestActionStack stack)
{
    AXUtils.LoadManager("UIA");
    if(target == null &&
        stack.Count > 0 &&
        stack.Peek().UIElement != null && 
        stack.Peek().ActionName == "Left Click" &&
        stack.Peek().UIElement.ClassName == "Uia.Button" &&
        stack.Peek().UIElement.Name == "")
    {
        UITechnologyElement button = stack.Peek().UIElement;
        var children = button.Parent().Children();
        foreach (var child in children)
        {
            if (child.GetRequestedState(AccessibleStates.Focused)
                != AccessibleStates.Default)
            {
                target = child;
                break;
            }
        }
    }
}

The SegmentedEntryFilter is the only filter which uses the UnconditionalRun method. It's used to cache the target text edit box before the dropdown is interacted with. This is necessary because once you click inside the dropdown, it's no longer possible to tell what edit box is focused.

protected override void Run(IUITestActionStack stack)
{
    IUITechnologyElement element = stack.Peek().UIElement;

    AXUtils.LoadManager("UIA");

    // If we're clicking on the whole row, we can just
    // go down to the first column's value.
    if(element.ControlTypeName == "DataItem")
    {
        RecreateAsTyping(stack, element.Child(0).Child(0).Name);
        return;
    }

    // Otherwise we must be clicking on some column in
    // the row, so we can go up to the whole row, and
    // back down to the first column.
    element = element.Parent().Parent().Child(0).Child(0);
    RecreateAsTyping(stack, element.Name);
}

The Run method finds the text that would be put into the text edit box by the dropdown, and passes that to RecreateAsTyping to change the actions stack to simply type out this text. The comments do a good job of explaining this method.

private void RecreateAsTyping(IUITestActionStack stack,  string value)
{
    stack.Pop();
    while(stack.Count >= 2 &&
        stack.Peek().UIElement != null &&
        stack.Peek().UIElement.ClassName == "Uia.Button" &&
        stack.Peek().UIElement.Name == "")
    {
        stack.Pop();
    }

    if(target != null)
    {
        var sendKeys = new SendKeysAction();
        sendKeys.Text = "{Ctrl}{Left}{Shift}{Ctrl}{Right}" + value + "{Tab}";
        stack.Push(sendKeys);
        target = null;
    }
}

This function actually changes the action stack to type into a simple typing action. The reason we have to continually pop the stack is that sometimes tons of button press actions are created for unknown reasons. The key combo before typing the value is to select the text in the entry field if it's not empty.

Last edited Aug 1, 2014 at 7:25 PM by wgoodin, version 4