Search code examples
c#.netwpfcoded-ui-testsmicrosoft-ui-automation

UIAComWrapper failing to return child nodes of WPF control that was previously COLLAPSED


I am attempting to create Coded UI tests on a WPF application. I am using Visual Studio 2019 to create / run the tests.

I am running into a strange behavior where a WPF button that was collapsed at startup (but is later made visible/enabled) is not showing any child nodes using any of the FindXXX methods available to the AutomationElement object associated with the button. Other buttons that were not collapsed do not seem to have this problem. I should note that the reason I am expecting child nodes for this WPF button is that in the XAML it is defined similar to the following:

<Button x:Name="ButtonStop" Grid.Row="0" Grid.Column="2" Command="{Binding TheVm.StopCommand}">
  <Button.Style>
    <Style TargetType="{x:Type Button}" BasedOn="{StaticResource ButtonStyleA}">
      <Setter Property="Visibility" Value="Collapsed"/>
      <Style.Triggers>
        <DataTrigger Binding="{Binding TheVm.DisplayButton}" Value="False">
          <Setter Property="Visibility" Value="Visible"/>
        </DataTrigger>
      </Style.Triggers>
    </Style>
  </Button.Style>
  <StackPanel Style="{StaticResource ControlsStackPanelStyle}">
    <Image Source="pack://application:,,,/Assets/icon1.png" Style="{StaticResource ControlsButtonImageStyle}"/>
    <ContentPresenter Content="Stop" Style="{StaticResource ControlsButtonTextStyle}"/>
  </StackPanel>
</Button>

Using the INSPECT.EXE application I can see the child nodes of this button correctly, but when I traverse the AutomationElements I have access to they are missing.

The test code I am using to check the human-readable text is:

// Wait for 'Stop' button to become enabled, and verify correct text
uIButtonStopButton.WaitForControlEnabled();         
var displayText = (!uIButtonStopButton.DisplayText.Equals(""))
                   ? uIButtonStopButton.DisplayText 
                   : GetFirstNodeText(uIButtonStopButton.NativeElement as AutomationElement;
Assert.AreEqual("Stop", displayText, "Stop button doesn\'t have correct text.");

Where the GetFirstNodeText method is as follows:

private static string GetFirstNodeText(AutomationElement automationElement)
{
  if (automationElement != null)
  {
    // Get first AutomationElement node that is a 'text' control-type
    var textEl = automationElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.LocalizedControlTypeProperty, "text"));
    if (textEl != null) return textEl.Current.Name;
  }
  return "";
}

An additional (interesting) piece of information: I tried a similar test using Appium/WinAppDriver and had an almost identical experience - no child nodes on the formerly collapsed button.

What could be causing this and do you have any advice for this?


Solution

  • To verify your are working with up-to-date AutomationElement objects, be sure to check this question about refreshing your controls.

    But since you mentioned having a almost identical problem using WinAppDriver, I rather think the problem will be with the application under test. If you have access to the source code / developers working on that code, please take a closer look to the code/xaml involving this button and its children. The problem will most likely be found there.