Not
Bu sayfaya erişim yetkilendirme gerektiriyor. Oturum açmayı veya dizinleri değiştirmeyi deneyebilirsiniz.
Bu sayfaya erişim yetkilendirme gerektiriyor. Dizinleri değiştirmeyi deneyebilirsiniz.
Not
Bu belgeler, ad alanında tanımlanan yönetilen UI Otomasyonu sınıflarını kullanmak isteyen .NET Framework geliştiricilerine System.Windows.Automation yöneliktir. UI Otomasyonu hakkında en son bilgiler için bkz. Windows Otomasyonu API'si: UI Otomasyonu.
Bu konu, UI Otomasyonu ağacı içindeki bir öğeyi bulmak için öğesinin nasıl ve ne zaman AutomationIdProperty kullanılabileceğini gösteren senaryolar ve örnek kod içerir.
AutomationIdPropertyeşdüzeylerinden bir UI Otomasyonu öğesini benzersiz olarak tanımlar. Denetim belirlemeyle ilgili özellik tanımlayıcıları hakkında daha fazla bilgi için bkz. UI Otomasyonu Özelliklere Genel Bakış.
Not
AutomationIdProperty ağaç genelinde benzersiz bir kimlik garantisi vermez; genellikle kapsayıcı ve kapsam bilgilerinin yararlı olması gerekir. Örneğin, bir uygulama birden çok alt menü öğesine sahip birden çok üst düzey menü öğesi içeren bir menü denetimi içerebilir. Bu ikincil menü öğeleri "Öğe1", "Öğe 2" gibi genel bir düzen tarafından tanımlanabilir ve üst düzey menü öğelerindeki alt öğeler için yinelenen tanımlayıcılara izin verilebilir.
Senaryolar
Öğeleri ararken doğru ve tutarlı sonuçlar elde etmek için kullanılması AutomationIdProperty gereken üç birincil UI Otomasyonu istemci uygulaması senaryosu belirlendi.
Not
AutomationIdProperty, üst düzey uygulama pencereleri, kimliği veya x:Uid olmayan Windows Presentation Foundation (WPF) denetimlerinden türetilen öğeler UI Otomasyonu ve denetim kimliği olmayan Win32 denetimlerinden türetilen öğeler UI Otomasyonu dışında denetim görünümündeki tüm UI Otomasyonu öğeleri tarafından desteklenir.
UI Otomasyonu ağacında belirli bir öğeyi bulmak için benzersiz ve bulunabilir bir AutomationID kullanın
- İlgi çekici bir kullanıcı arabirimi öğesini raporlamak AutomationIdProperty için UI Spy gibi bir araç kullanın. Bu değer daha sonra otomatikleştirilmiş test için bir test betiği gibi bir istemci uygulamasına kopyalanabilir ve yapıştırılabilir. Bu yaklaşım, çalışma zamanında bir öğeyi tanımlamak ve bulmak için gereken kodu azaltır ve basitleştirir.
Dikkat
Genel olarak, öğesinin yalnızca doğrudan alt öğelerini RootElementelde etmeyi denemelisiniz. Alt öğeler için yapılan bir arama yüzlerce, hatta binlerce öğede yinelenebilir ve büyük olasılıkla yığın taşmasıyla sonuçlanabilir. Belirli bir öğeyi daha düşük bir düzeyde elde etmeye çalışıyorsanız, aramanızı uygulama penceresinden veya daha düşük bir düzeydeki bir kapsayıcıdan başlatmanız gerekir.
///--------------------------------------------------------------------
/// <summary>
/// Finds all elements in the UI Automation tree that have a specified
/// AutomationID.
/// </summary>
/// <param name="targetApp">
/// The root element from which to start searching.
/// </param>
/// <param name="automationID">
/// The AutomationID value of interest.
/// </param>
/// <returns>
/// The collection of UI Automation elements that have the specified
/// AutomationID value.
/// </returns>
///--------------------------------------------------------------------
private AutomationElementCollection FindElementFromAutomationID(AutomationElement targetApp,
string automationID)
{
return targetApp.FindAll(
TreeScope.Descendants,
new PropertyCondition(AutomationElement.AutomationIdProperty, automationID));
}
'''--------------------------------------------------------------------
''' <summary>
''' Finds all elements in the UI Automation tree that have a specified
''' AutomationID.
''' </summary>
''' <param name="targetApp">
''' The root element from which to start searching.
''' </param>
''' <param name="automationID">
''' The AutomationID value of interest.
''' </param>
''' <returns>
''' The collection of automation elements that have the specified
''' AutomationID value.
''' </returns>
'''--------------------------------------------------------------------
Private Function FindElementFromAutomationID( _
ByVal targetApp As AutomationElement, _
ByVal automationID As String) As AutomationElementCollection
Return targetApp.FindAll( _
TreeScope.Descendants, _
New PropertyCondition( _
AutomationElement.AutomationIdProperty, automationID))
End Function 'FindElementFromAutomationID
Daha önce tanımlanmış bir AutomationElement'e dönmek için kalıcı bir yol kullanma
- Basit test betiklerinden sağlam kayıt ve kayıttan yürütme yardımcı programlarına kadar istemci uygulamaları, dosya açma iletişim kutusu veya menü öğesi gibi şu anda örneklenmemiş öğelere erişim gerektirebilir ve bu nedenle UI Otomasyonu ağacında yoktur. Bu öğeler yalnızca AutomationID, denetim desenleri ve olay dinleyicileri gibi UI Otomasyonu özellikleri kullanarak belirli bir kullanıcı arabirimi eylemleri dizisi yeniden üretilerek veya "kayıttan yürütülerek" örneklenebilir.
///--------------------------------------------------------------------
/// <summary>
/// Creates a UI Automation thread.
/// </summary>
/// <param name="sender">Object that raised the event.</param>
/// <param name="e">Event arguments.</param>
/// <remarks>
/// UI Automation must be called on a separate thread if the client
/// application itself could become a target for event handling.
/// For example, focus tracking is a desktop event that could involve
/// the client application.
/// </remarks>
///--------------------------------------------------------------------
private void CreateUIAThread(object sender, EventArgs e)
{
// Start another thread to do the UI Automation work.
ThreadStart threadDelegate = new ThreadStart(CreateUIAWorker);
Thread workerThread = new Thread(threadDelegate);
workerThread.Start();
}
///--------------------------------------------------------------------
/// <summary>
/// Delegated method for ThreadStart. Creates a UI Automation worker
/// class that does all UI Automation related work.
/// </summary>
///--------------------------------------------------------------------
public void CreateUIAWorker()
{
uiautoWorker = new FindByAutomationID(targetApp);
}
private FindByAutomationID uiautoWorker;
'''--------------------------------------------------------------------
''' <summary>
''' Creates a UI Automation thread.
''' </summary>
''' <param name="sender">Object that raised the event.</param>
''' <param name="e">Event arguments.</param>
''' <remarks>
''' UI Automation must be called on a separate thread if the client
''' application itself could become a target for event handling.
''' For example, focus tracking is a desktop event that could involve
''' the client application.
''' </remarks>
'''--------------------------------------------------------------------
Private Sub CreateUIAThread(ByVal sender As Object, ByVal e As EventArgs)
' Start another thread to do the UI Automation work.
Dim threadDelegate As New ThreadStart(AddressOf CreateUIAWorker)
Dim workerThread As New Thread(threadDelegate)
workerThread.Start()
End Sub
'''--------------------------------------------------------------------
''' <summary>
''' Delegated method for ThreadStart. Creates a UI Automation worker
''' class that does all UI Automation related work.
''' </summary>
'''--------------------------------------------------------------------
Public Sub CreateUIAWorker()
uiautoWorker = New UIAWorker(targetApp)
End Sub
Private uiautoWorker As UIAWorker
///--------------------------------------------------------------------
/// <summary>
/// Function to playback through a series of recorded events calling
/// a WriteToScript function for each event of interest.
/// </summary>
/// <remarks>
/// A major drawback to using AutomationID for recording user
/// interactions in a volatile UI is the probability of catastrophic
/// change in the UI. For example, the //Processes// dialog where items
/// in the listbox container can change with no input from the user.
/// This mandates that a record and playback application must be
/// reliant on the tester owning the UI being tested. In other words,
/// there has to be a contract between the provider and client that
/// excludes uncontrolled, external applications. The added benefit
/// is the guarantee that each control in the UI should have an
/// AutomationID assigned to it.
///
/// This function relies on a UI Automation worker class to create
/// the System.Collections.Generic.Queue object that stores the
/// information for the recorded user interactions. This
/// allows post-processing of the recorded items prior to actually
/// writing them to a script. If this is not necessary the interaction
/// could be written to the script immediately.
/// </remarks>
///--------------------------------------------------------------------
private void Playback(AutomationElement targetApp)
{
AutomationElement element;
foreach(ElementStore storedItem in uiautoWorker.elementQueue)
{
PropertyCondition propertyCondition =
new PropertyCondition(
AutomationElement.AutomationIdProperty, storedItem.AutomationID);
// Confirm the existence of a control.
// Depending on the controls and complexity of interaction
// this step may not be necessary or may require additional
// functionality. For example, to confirm the existence of a
// child menu item that had been invoked the parent menu item
// would have to be expanded.
element = targetApp.FindFirst(TreeScope.Descendants, propertyCondition);
if(element == null)
{
// Control not available, unable to continue.
// TODO: Handle error condition.
return;
}
WriteToScript(storedItem.AutomationID, storedItem.EventID);
}
}
///--------------------------------------------------------------------
/// <summary>
/// Generates script code and outputs the code to a text control in
/// the client.
/// </summary>
/// <param name="automationID">
/// The AutomationID of the current control.
/// </param>
/// <param name="eventID">
/// The event recorded on that control.
/// </param>
///--------------------------------------------------------------------
private void WriteToScript(string automationID, string eventID)
{
// Script code would be generated and written to an output file
// as plain text at this point, but for the
// purposes of this example we just write to the console.
Console.WriteLine(automationID + " - " + eventID);
}
'''--------------------------------------------------------------------
''' <summary>
''' Function to playback through a series of recorded events calling
''' a WriteToScript function for each event of interest.
''' </summary>
''' <remarks>
''' A major drawback to using AutomationID for recording user
''' interactions in a volatile UI is the probability of catastrophic
''' change in the UI. For example, the 'Processes' dialog where items
''' in the listbox container can change with no input from the user.
''' This mandates that a record and playback application must be
''' reliant on the tester owning the UI being tested. In other words,
''' there has to be a contract between the provider and client that
''' excludes uncontrolled, external applications. The added benefit
''' is the guarantee that each control in the UI should have an
''' AutomationID assigned to it.
'''
''' This function relies on a UI Automation worker class to create
''' the System.Collections.Generic.Queue object that stores the
''' information for the recorded user interactions. This
''' allows post-processing of the recorded items prior to actually
''' writing them to a script. If this is not necessary the interaction
''' could be written to the script immediately.
''' </remarks>
'''--------------------------------------------------------------------
Private Sub Playback(ByVal targetApp As AutomationElement)
Dim element As AutomationElement
Dim storedItem As ElementStore
For Each storedItem In uiautoWorker.elementQueue
Dim propertyCondition As New PropertyCondition( _
AutomationElement.AutomationIdProperty, storedItem.AutomationID)
' Confirm the existence of a control.
' Depending on the controls and complexity of interaction
' this step may not be necessary or may require additional
' functionality. For example, to confirm the existence of a
' child menu item that had been invoked the parent menu item
' would have to be expanded.
element = targetApp.FindFirst( _
TreeScope.Descendants, propertyCondition)
If element Is Nothing Then
' Control not available, unable to continue.
' TODO: Handle error condition.
Return
End If
WriteToScript(storedItem.AutomationID, storedItem.EventID)
Next storedItem
End Sub
'''--------------------------------------------------------------------
''' <summary>
''' Generates script code and outputs the code to a text control in
''' the client.
''' </summary>
''' <param name="automationID">
''' The AutomationID of the current control.
''' </param>
''' <param name="eventID">
''' The event recorded on that control.
''' </param>
'''--------------------------------------------------------------------
Private Sub WriteToScript( _
ByVal automationID As String, ByVal eventID As String)
' Script code would be generated and written to an output file
' as plain text at this point, but for the
' purposes of this example we just write to the console.
Console.WriteLine(automationID + " - " + eventID)
End Sub
Daha önce tanımlanmış bir AutomationElement'e dönmek için göreli yol kullanma
- Bazı durumlarda AutomationID'nin yalnızca eşdüzey öğeler arasında benzersiz olması garanti olduğundan, UI Otomasyonu ağacındaki birden çok öğe aynı AutomationID özellik değerlerine sahip olabilir. Bu gibi durumlarda, öğeler bir ebeveyne ve gerekirse bir büyükbabaya göre benzersiz olarak tanımlanabilir. Örneğin, bir geliştirici her biri birden çok alt menü öğesi içeren ve çocukların "Öğe1", "Öğe2" gibi sıralı AutomationID'lerle tanımlandığı bir menü çubuğu sağlayabilir. Daha sonra her menü öğesi, AutomationID ile birlikte üst öğesinin AutomationID değeri ve gerekirse büyükbabası tarafından benzersiz olarak tanımlanabilir.