我有一个 WPF 应用程序,我正在尝试使用FlaUI对其进行自动化。我正面临一个问题DxTabControl
。我已经提供Automation IDs
给DxTabControl
. 我正在使用动态DXTabControl.ItemHeaderTemplate
生成TabItems
。根据 DevExpress 团队的说法,DXTabControl.ItemHeaderTemplate
不支持AutoamtionPeer
因此添加了自定义实现来覆盖其默认行为。
TabControl
现在,我可以看到TabItems
. Inspect.exe
现在,我的要求是访问当前选定的 Tabitem 并使用下面 XAML 中提到的 AutoamtionID 找到 CloseButton 并关闭它。再次粘贴到线下。由于会生成多个 TabItems,因此我无法获取 Current active/Selected TabItem
。
下面XAML
是
<dx:DXTabControl AutomationProperties.AutomationId="ViewsParentTabControl"
MaxWidth="4000"
MaxHeight="4000"
Margin="1,0,-1,0"
Focusable="False"
ItemsSource="{Binding OpenViews}"
SelectedIndex="{Binding SelectedTabIndex}"
TabContentCacheMode="CacheTabsOnSelecting">
<dx:DXTabControl.ItemHeaderTemplate>
<DataTemplate DataType="viewModels1:OpenViewDefinitionViewModel">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<TextBlock Name="CreatedViewName"
MaxWidth="100"
Text="{Binding Data.ViewDefinition.Name}"
TextTrimming="CharacterEllipsis"
ToolTip="{Binding DisplayName}" />
<TextBlock Grid.Row="0" Grid.Column="1"><Run Text=" [" /><Run Text="{Binding ItemsCount, FallbackValue=0, Mode=OneWay}" /><Run Text="]" /></TextBlock>
<controls2:ProgressIndicator AutomationProperties.AutomationId="ProgressCurrentView"
Grid.Row="0"
Grid.Column="3"
Width="14"
Margin="4,0,0,0"
VerticalAlignment="Center"
CircleBorder="{StaticResource ListBoxItem.Foreground}"
CircleFill="{StaticResource ListBoxItem.Foreground}"
IndicatorEnabled="{Binding IsDataLoading}" />
<Button AutomationProperties.AutomationId="CloseCurrentViewButton"
Grid.Row="0"
Grid.Column="2"
Width="10"
Height="10"
Margin="10,1,0,0"
Padding="0"
HorizontalAlignment="Right"
BorderThickness="0"
Command="{Binding DataContext.CloseItemCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=dx:DXTabControl}}"
CommandParameter="{Binding}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Close">
<Path
Data="F1 M 26.9166,22.1667L 37.9999,33.25L 49.0832,22.1668L 53.8332,26.9168L 42.7499,38L 53.8332,49.0834L 49.0833,53.8334L 37.9999,42.75L 26.9166,53.8334L 22.1666,49.0833L 33.25,38L 22.1667,26.9167L 26.9166,22.1667 Z"
Fill="White"
Stretch="Fill" />
</Button>
</Grid>
</DataTemplate>
</dx:DXTabControl.ItemHeaderTemplate>
<dx:DXTabControl.ItemTemplate>
<DataTemplate DataType="viewModels1:OpenViewDefinitionViewModel">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<local:VoyagesGridControl />
<local:VoyageValidationUserControl
Grid.Row="1"
Grid.Column="0"
MinHeight="100"
MaxHeight="300"
Visibility="{Binding Path=IsVoyageValidationShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<local:VoyageHistoryUserControl
Grid.Row="2"
Grid.Column="0"
MinHeight="300"
MaxHeight="300"
Visibility="{Binding Path=IsVoyageHistoryShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<local:VesselHistoryUserControl
Grid.Row="3"
Grid.Column="0"
MinHeight="300"
MaxHeight="300"
Visibility="{Binding Path=IsVesselHistoryShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<local:VoyageEvents
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="1"
VerticalAlignment="Top"
Visibility="{Binding Path=IsVoyageEventsShowing, FallbackValue=Collapsed, Converter={StaticResource BooleanToVisibilityConverter}}" />
<controls2:ProgressIndicator AutomationProperties.AutomationId="showProgressForLoadingViews"
Grid.Row="0"
Grid.RowSpan="3"
Grid.Column="0"
Width="80"
HorizontalAlignment="Center"
VerticalAlignment="Center"
CircleBorder="{StaticResource ListBox.BorderBrush}"
CircleFill="{StaticResource ListBox.BorderBrush}"
IndicatorEnabled="{Binding IsDataLoading}" />
<!-- Buttons -->
<Grid Grid.Row="4" Grid.Column="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="Auto" />
</Grid.ColumnDefinitions>
<StackPanel
Grid.Column="0"
VerticalAlignment="Center"
Orientation="Horizontal">
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Last Refresh:" />
<TextBlock
Margin="2,0,4,0"
VerticalAlignment="Center"
Text="{Binding LoadDate, StringFormat=G}" />
</StackPanel>
<Button AutomationProperties.AutomationId="AddNewVoyageButton"
Grid.Row="0"
Grid.Column="1"
Padding="0"
Command="{Binding AddVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Add a new voyage to this View (ALT + A)">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Add}" />
<Label Style="{StaticResource MwLabelStyle}">_Add</Label>
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="refreshVoyageButton"
Grid.Row="0"
Grid.Column="2"
Padding="0"
Command="{Binding RefreshVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Refresh the this View (modified entries are left unchanged)">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Refresh}" />
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Refresh" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="showVoyageHistroyButton"
Grid.Column="4"
Margin="2,2,2,2"
Padding="0"
VerticalAlignment="Center"
Command="{Binding ShowVoyageHistoryCommand}"
Focusable="False"
ToolTip="Show the selected voyage's change history"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource ShowVoyageHistory}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Hide Voyage History"
Visibility="{Binding IsVoyageHistoryShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Show Voyage History"
Visibility="{Binding IsVoyageHistoryShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="showVesselHistroyButton"
Grid.Column="5"
Margin="2,2,2,2"
Padding="0"
VerticalAlignment="Center"
Command="{Binding ShowVesselHistoryCommand}"
Focusable="False"
ToolTip="Show the selected vessel's voyage history"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource ShowVesselHistory}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Hide Vessel History"
Visibility="{Binding IsVesselHistoryShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Show Vessel History"
Visibility="{Binding IsVesselHistoryShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="showVoyageButton"
Grid.Column="6"
Margin="2,2,2,2"
Padding="0"
VerticalAlignment="Center"
Command="{Binding ShowVesselVisitsCommand}"
Focusable="False"
ToolTip="Show the selected voyage's events"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Anchor}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Hide Voyage Events"
Visibility="{Binding IsVoyageEventsShowing, Converter={StaticResource BooleanToVisibilityConverter}}" />
<TextBlock
Style="{StaticResource MwTextBlockLabelStyle}"
Text="Show Voyage Events"
Visibility="{Binding IsVoyageEventsShowing, Converter={StaticResource MwBoolToVisibilityConverterReverse}}" />
</StackPanel>
</Button>
<Border Grid.Row="0" Grid.Column="8">
<Border.Style>
<Style TargetType="Border">
<Style.Triggers>
<DataTrigger Binding="{Binding IsDuplicateView, Mode=TwoWay}" Value="true">
<Setter Property="Background" Value="LightGreen" />
</DataTrigger>
</Style.Triggers>
</Style>
</Border.Style>
<Button AutomationProperties.AutomationId="DuplicateCheckButton"
Padding="0"
Command="{Binding DuplicateVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Switch to duplicate Voyages (ALT + D)"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Duplicate}" />
<AccessText Style="{StaticResource MwAccessTextLabelStyle}" Text="{Binding VoyageDuplicateText}" />
</StackPanel>
</Button>
</Border>
<Button AutomationProperties.AutomationId="PublishVoyagesButton"
Grid.Row="0"
Grid.Column="9"
Padding="0"
Command="{Binding PublishVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Publish any modified Voyages (ALT + P)"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Publish}" />
<AccessText Style="{StaticResource MwAccessTextLabelStyle}" Text="{Binding VoyagePublishText}" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="UndoSingleVoyageButton"
Grid.Row="0"
Grid.Column="10"
Padding="0"
Command="{Binding UndoSingleChangedVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Locally Undo unpublished changes to the selected voyage"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Undo}" />
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Undo Selected" />
</StackPanel>
</Button>
<Button AutomationProperties.AutomationId="UndoandUnpublishVoyageButton"
Grid.Row="0"
Grid.Column="11"
Padding="0"
Command="{Binding UndoChangedVoyagesCommand}"
Focusable="False"
Style="{StaticResource MwButtonStyle}"
ToolTip="Locally Undo any changed and unpublished voyages"
Visibility="{Binding Data.ViewDefinition.IsInternalView, Converter={StaticResource MwBoolToVisibilityConverterReverse}}">
<StackPanel Orientation="Horizontal">
<ContentControl Height="26" Content="{StaticResource Undo}" />
<TextBlock Style="{StaticResource MwTextBlockLabelStyle}" Text="Undo All" />
</StackPanel>
</Button>
</Grid>
</Grid>
</DataTemplate>
</dx:DXTabControl.ItemTemplate>
</dx:DXTabControl>
我FlaUI
定位控件的方法如下
public IMainWindow ConfirmCreatedView()
{
_logger.Info("Checking the newly created View on the screen");
//Apoorv: Need to find TabItem here
_controlAction.Highlight(ViewsTabControl); // This highlights the TabControl- Works
int NumberOfActiveTabs = ViewsTabControl.TabItems.Length; // This gives me no of TabItems
TabItem SelectedTab= ViewsTabControl.SelectedTabItem as TabItem; // Gives me Null here
var newTab = ViewsTabControl.SelectedTabItemIndex ; // Give me -1 here
_controlAction.Highlight(ViewsTabControl.TabItems[2]); // Works. It highlights the TabItem at position 2
_controlAction.ClickWait<TabItem>(ViewsTabControl.TabItems[2]); // This goes and clicks the tab item
TabItem SelectedTabs = ViewsTabControl.SelectedTabItem as TabItem;
var check = ViewsTabControl.TabItems[2].FindAllChildren();
// TabItem ti = ViewsTabControl.SelectedItem as TabItem;
//_controlAction.Highlight()
_controlAction.Highlight(CloseCurrentView); // highlights the close button atTabItem[0]
_controlAction.Click<Button>(CloseCurrentView); // closes it
return this;
}
我正在使用FlaUI
查找TabControl
使用AutomationID
,如下所示
private Tab ViewsTabControl => _uiAutomation.FindElement("ViewsParentTabControl", Automation.FindBy.Id).AsTab();
private TabItem ViewsTabItem => _uiAutomation.FindElement("DXTabItem", Automation.FindBy.Id).AsTabItem();
我想TabItem
根据索引找到当前活跃的,然后通过自动化点击关闭按钮。
TabItem SelectedTab= ViewsTabControl.SelectedTabItem as TabItem; // Gives me Null here
var newTab = ViewsTabControl.SelectedTabItemIndex ; // Give me -1 here