ContentControl ist nicht sichtbar, wenn die Anwendung über den UI-Automatisierungstest gestartet wird. Es ist jedoch sichtbar, wenn die Anwendung vom Benutzer gestartet wird
Wir verwenden das Prisma und WPF, um Anwendungen zu erstellen. Vor kurzem haben wir begonnen, UI Automation (UIA) zum Testen unserer App zu verwenden. Beim Ausführen des UIA-Tests ist jedoch ein merkwürdiges Verhalten aufgetreten. Hier ist die vereinfachte Shell:
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock
Grid.Row="0" Grid.Column="0"
Name="loadingProgressText"
VerticalAlignment="Center" HorizontalAlignment="Center"
Text="Loading, please wait..."/>
<Border
Grid.Row="0"
x:Name="MainViewArea">
<Grid>
...
</Grid>
</Border>
<!-- Popup -->
<ContentControl
x:Name="PopupContentControl"
Grid.Row="0"
prism:RegionManager.RegionName="PopupRegion"
Focusable="False">
</ContentControl>
<!-- ErrorPopup -->
<ContentControl
x:Name="ErrorContentControl"
Grid.Row="0"
prism:RegionManager.RegionName="ErrorRegion"
Focusable="False">
</ContentControl>
</Grid>
In unserer App verwenden wir Ebenen (Popup
undErrorPopup
) versteckenMainViewArea, um den Zugriff auf die Steuerelemente zu verweigern. ZeigenPopup
verwenden wir folgende Methode:
//In constructor of current ViewModel we store _popupRegion instance to the local variable:
_popupRegion = _regionManager.Regions["PopupRegion"];
//---
private readonly Stack<UserControl> _popups = new Stack<UserControl>();
public void ShowPopup(UserControl popup)
{
_popups.Push(popup);
_popupRegion.Add(PopupView);
_popupRegion.Activate(PopupView);
}
public UserControl PopupView
{
get
{
if (_popups.Any())
return _popups.Peek();
return null;
}
}
Ähnlich zeigen wirErrorPopup
über alle Elemente unserer Anwendung:
// In constructor we store _errorRegion:
_errorRegion = _regionManager.Regions["ErrorRegion"]
// ---
private UserControl _error_popup;
public void ShowError(UserControl popup)
{
if (_error_popup == null)
{
_error_popup = popup;
_errorRegion.Add(_error_popup);
_errorRegion.Activate(_error_popup);
}
}
Mistics ...
Wenn wir es als Benutzer ausführen (Doppelklick auf das App-Symbol), sehen wir beide benutzerdefinierten Steuerelemente (mitAutomationElement.FindFirst
Methode oder durchVisual UI Automation Verify). Aber wenn wir es mit UI Automation Test starten -ErrorPopup
verschwindet aus dem Baum der Steuerelemente. Wir versuchen die Anwendung so zu starten:
System.Diagnostics.Process.Start(pathToExeFile);
Ich denke, dass wir etwas verpasst haben. Aber was?
Bearbeiten Sie # 1
Wie @chrismead sagte, haben wir versucht, unsere App mit auszuführenUseShellExecute
flag auf true gesetzt, aber das hilft nicht. Aber wenn wir von App startencmd Linie, und klicken Sie manuell auf die Schaltfläche,Popup
undErrorPopup
sind im Automatisierungssteuerungsbaum sichtbar.
Thread appThread = new Thread(delegate()
{
_userAppProcess = new Process();
_userAppProcess.StartInfo.FileName = pathToExeFile;
_userAppProcess.StartInfo.WorkingDirectory = System.IO.Directory.GetCurrentDirectory();
_userAppProcess.StartInfo.UseShellExecute = true;
_userAppProcess.Start();
});
appThread.SetApartmentState(ApartmentState.STA);
appThread.Start();
Einer unserer Vorschläge ist, wann wir die Methode anwendenFindAll
oderFindFirst
Um die Schaltfläche zum Klicken zu durchsuchen, hat window den UI-Automatisierungsstatus zwischengespeichert und aktualisiert ihn nicht.
Bearbeiten Sie # 2 Wir haben diese Erweiterungsmethode der Prismenbibliothek gefundenIRegionManager.RegisterViewWithRegion(RegionNames.OurRegion, typeof(Views.OurView))
habe ein seltsames Verhalten. Wenn wir es nicht mehr benutzen, löst dies unser Problem. Jetzt können wir ErrorView und jede Art von Ansicht in sehenPopupContentControl
und Anwendungsaktualisierungen UIA-Elementbaumstruktur. Dies ist jedoch keine Antwort - "Hören Sie einfach auf, diese Funktion zu verwenden"!
ImMainViewArea
wir haben einContentControl
, wodurch der Inhalt abhängig von den Benutzeraktionen aktualisiert wird und wir nur den ersten geladenen sehen könnenUserControl
dazuContentControl.Content
Eigentum. Dies wird folgendermaßen durchgeführt:
IRegionManager regionManager = Container.Resolve<IRegionManager>();
regionManager.RequestNavigate(RegionNames.MainContentRegion, this.Uri);
Wenn wir die Ansicht ändern, werden in der UI-Automatisierungsstruktur keine Aktualisierungen durchgeführt. Stattdessen wird die erste geladene Ansicht darin gespeichert. Aber visuell beobachten wir einen anderenView
, undWPFInspector zeigt es richtig (es zeigt keinen UI-Automatisierungsbaum), aber Inspect.exe - nicht.
Auch unser Vorschlag, dass Fenster eine Art Caching verwenden, ist falsch - das Caching im UI Automation-Client müssen wir explizit aktivieren, aber wir tun es nicht.