I'm trying to access the Type property of the custom prompt dialog from an automation test. So the element for the Type (text box or text block) is collapsed because no one needs to see it, I just need it for logical processing on automation side.
I don't understand why it can't be located despite being available in the tree. or is there another why to get such access?
XAML:
<controls:PromptDialog ...
AutomationProperties.AutomationId="PromptView"
d:DataContext="{d:DesignInstance Type=viewModels:PromptViewModel}">
<Grid Margin="{StaticResource MarginThickness}">
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="{StaticResource Gutter}" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<!--Prompt-->
<Grid Grid.Row="0"
Visibility="{Binding IsShowingPrompt, Converter={StaticResource BooleanToVisibilityConverter}}">
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition Height="4" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="{StaticResource Gutter}" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<!--Image-->
<ContentControl Grid.Row="0"
Grid.Column="0"
Content="{Binding}">
<ContentControl.Resources>
<DataTemplate DataType="{x:Type viewModels:PromptViewModel}">
<Image Name="Image" />
//displaying image per type
</ContentControl.Resources>
</ContentControl>
<ScrollViewer Grid.Row="0"
Grid.Column="2"
Focusable="False"
VerticalScrollBarVisibility="Auto"
HorizontalScrollBarVisibility="Disabled"
MaxHeight="400">
<StackPanel>
<TextBlock behaviors:TextBoxHyperlinkBehavior.Text="{Binding Text}"
TextWrapping="Wrap"
Focusable="False"
VerticalAlignment="Center"
HorizontalAlignment="Left"
FontFamily="{Binding Font.Name}"
Foreground="{Binding FontColor}"
AutomationProperties.AutomationId="PrompView_Text" />
<TextBox Visibility="Collapsed"
Text="{Binding Type}"
AutomationProperties.AutomationId="PromptView_Type" />
</StackPanel>
</ScrollViewer>
<!--Commands-->
<UniformGrid Grid.Row="2" Rows="1" HorizontalAlignment="Right">
// buttons
</UniformGrid>
</Grid>
</controls:PromptDialog> Appium:
public IVisualElement Type => _appiumSession.CreateVisualAppiumElement("PromptView_Type");
Or
public AppiumWebElement Type => _appiumSession.FindElementByAccessibilityId("PromptView_Type");
Error:
OpenQA.Selenium.WebDriverTimeoutException : Timed out after 10 seconds
---- OpenQA.Selenium.WebDriverException : An element could not be located on the page using the given search parameters.
Any pointers are highly appreciated,
thanks
I don't know anything about Appium, but the problem could be solve with .net automation api very easily.
// Must find top window of app first or could cause overflow easily.
var topWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children,
new PropertyCondition(AutomationElement.AutomationIdProperty, "Id of top window"));
// Find out your target element if it's in visual tree, whatever it's collapsed or not.
// You can also Find out another element in the middle first to reduce the search work.
var target = topWindow.FindFirst(TreeScope.Descendants,
new PropertyCondition(AutomationElement.AutomationIdProperty, "PromptView_Type"));
// retrieve the value.
var val = ((ValuePattern)target.GetCurrentPattern(ValuePattern.Pattern)).Current.Value;
You have to add reference to UIAutomationClient.dll and UIAutomationType.dll to make this code work.
Update for .net core app
For .net core(3.0, 3.1, 5.0), there's a huge difference about how an automation peer answer inquiry than .net framework app. Automation peer will not answer inquiry if it's offscreen(control's visibility had been set to collapsed or hidden) unless inquiry was targeting raw view. So we have to force inquiry target to make it works.
var topWindow = AutomationElement.RootElement.FindFirst(TreeScope.Children, new PropertyCondition(AutomationElement.AutomationIdProperty, "Id of top window"));
AutomationElement target = null;
var cr = new CacheRequest()
{
TreeFilter = Automation.RawViewCondition,
};
using (cr.Activate())
{
target = topWindow.FindFirst(TreeScope.Descendants, new PropertyCondition(AutomationElement.AutomationIdProperty, "PromptView_Type"));
}