日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

UIAutomation 自动化

發布時間:2024/9/20 编程问答 36 豆豆
生活随笔 收集整理的這篇文章主要介紹了 UIAutomation 自动化 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

Introduction

UI Automation是Microsoft .NET 3.0框架下提供的一種用于自動化測試的技術,是在MSAA基礎上建立的,MSAA就是Microsoft Active Accessibility。UI Automation在某些方面超過了MSAA,UI自動化提供了Windows Vista中,微軟Windows XP的全部功能,和Windows Server 2003。

在UI Automation中,所有的窗體、控件都表現為一個AutomationElement,?AutomationElement?中包含此控件或窗體的屬性,在實現自動化的過程中,我們通過其相關屬性進行對控件自動化操作。對于UI用戶界面來說,所有顯示在桌面上的UI,其實際是一個UI Tree,根節點是desktop。我們可以使用UI Spy或者是SPY++來獲得Window和Control的相關信息。在UI Automation里,根節點表示為AutomationElemnet.RootElement.?通過根節點,我們可以通過窗體或控件的Process Id、Process Name或者Window Name找到相應的子AutomationElement,例如Dialog、Button、TextBox、Checkbox等標準控件,通過控件所對應的Pattern進行相關的操作。

UI Automation structure

如下圖所示:


1.?在服務端由UIAutomationProvider.dll和UIAutomationTypes.dll提供。

???? 2.?在客戶端由UIAutomationClient.dll和UIAutomationTypes.dll提供。

???? 3.?UIAutomationCore.dll為UI自動化的核心部分,負責Server端和Client端的交互。

???? 4.?UIAUtomationClientSideProvides.dll為客戶端程序提供自動化支持。

使用UI Automation實現自動化測試--2

本文通過一個實例來介紹怎樣使用UI Automation實現軟件的自動化測試。

1. 首先建立一個待測試的winform程序,即UI Automation的服務端。

下面是button事件處理程序。

private?void?button1_Click(object?sender,?EventArgs?e)

{

?????int?i =?int.Parse(textBox1.Text);

?????int?j =?int.Parse(textBox2.Text);

???? textBox3.Text = (i + j).ToString();

}

2. 建立一個測試程序,做UI Automaion的客戶端。

添加引用:UIAutomationClient.dll 和 UIAutomationTypes.dll


??2using?System.Diagnostics;
??3using?System.Threading;
??4using?System.Windows.Automation.Provider;
??5using?System.Windows.Automation.Text;
??6using?System.Windows.Automation;
??7
??8namespace?UIAutomationTest
??9{
?10????class?Program
?11????{
?12????????static?void?Main(string[]?args)
?13????????{
?14????????????try
?15????????????{
?16????????????????Console.WriteLine("\nBegin?WinForm?UIAutomation?test?run\n");
?17????????????????//?launch?Form1?application
?18????????????????//?get?refernce?to?main?Form?control
?19????????????????//?get?references?to?user?controls
?20????????????????//?manipulate?application
?21????????????????//?check?resulting?state?and?determine?pass/fail
?22
?23????????????????Console.WriteLine("\nBegin?WinForm?UIAutomation?test?run\n");
?24????????????????Console.WriteLine("Launching?WinFormTest?application");
?25????????????????//啟動被測試的程序
?26????????????????Process?p?=?Process.Start(@"E:\Project\WinFormTest\WinFormTest\bin\Debug\WinFormTest.exe");
?27
?28????????????????//自動化根元素
?29????????????????AutomationElement?aeDeskTop?=?AutomationElement.RootElement;
?30
?31????????????????Thread.Sleep(2000);
?32????????????????AutomationElement?aeForm?=?AutomationElement.FromHandle(p.MainWindowHandle);
?33????????????????//獲得對主窗體對象的引用,該對象實際上就是?Form1?應用程序(方法一)
?34????????????????//if?(null?==?aeForm)
?35????????????????//{
?36????????????????//????Console.WriteLine("Can?not?find?the?WinFormTest?from.");
?37????????????????//}
?38
?39????????????????//獲得對主窗體對象的引用,該對象實際上就是?Form1?應用程序(方法二)
?40????????????????int?numWaits?=?0;
?41????????????????do
?42????????????????{
?43????????????????????Console.WriteLine("Looking?for?WinFormTest……");
?44????????????????????//查找第一個自動化元素
?45????????????????????aeForm?=?aeDeskTop.FindFirst(TreeScope.Children,?new?PropertyCondition(
?46????????????????????????AutomationElement.NameProperty,?"Form1"));
?47????????????????????++numWaits;
?48????????????????????Thread.Sleep(100);
?49????????????????}?while?(null?==?aeForm?&&?numWaits?<?50);
?50????????????????if?(null?==?aeForm)
?51????????????????????throw?new?NullReferenceException("Failed?to?find?WinFormTest.");
?52????????????????else
?53????????????????????Console.WriteLine("Found?it!");
?54
?55????????????????Console.WriteLine("Finding?all?user?controls");
?56????????????????//找到第一次出現的Button控件
?57????????????????AutomationElement?aeButton?=?aeForm.FindFirst(TreeScope.Children,
?58??????????????????new?PropertyCondition(AutomationElement.NameProperty,?"button1"));
?59
?60????????????????//找到所有的TextBox控件
?61????????????????AutomationElementCollection?aeAllTextBoxes?=?aeForm.FindAll(TreeScope.Children,
?62????????????????????new?PropertyCondition(AutomationElement.ControlTypeProperty,?ControlType.Edit));
?63
?64????????????????//?控件初始化的順序是先初始化后添加到控件
?65????????????????//?this.Controls.Add(this.textBox3);??????????????????
?66????????????????//?this.Controls.Add(this.textBox2);
?67????????????????//?this.Controls.Add(this.textBox1);
?68
?69????????????????AutomationElement?aeTextBox1?=?aeAllTextBoxes[2];
?70????????????????AutomationElement?aeTextBox2?=?aeAllTextBoxes[1];
?71????????????????AutomationElement?aeTextBox3?=?aeAllTextBoxes[0];
?72
?73????????????????Console.WriteLine("Settiing?input?to?'30'");
?74????????????????//通過ValuePattern設置TextBox1的值
?75????????????????ValuePattern?vpTextBox1?=?(ValuePattern)aeTextBox1.GetCurrentPattern(ValuePattern.Pattern);
?76????????????????vpTextBox1.SetValue("30");
?77????????????????Console.WriteLine("Settiing?input?to?'50'");
?78????????????????//通過ValuePattern設置TextBox2的值
?79????????????????ValuePattern?vpTextBox2?=?(ValuePattern)aeTextBox2.GetCurrentPattern(ValuePattern.Pattern);
?80????????????????vpTextBox2.SetValue("50");
?81????????????????Thread.Sleep(1500);
?82????????????????Console.WriteLine("Clickinig?on?button1?Button.");
?83????????????????//通過InvokePattern模擬點擊按鈕
?84????????????????InvokePattern?ipClickButton1?=?(InvokePattern)aeButton.GetCurrentPattern(InvokePattern.Pattern);
?85????????????????ipClickButton1.Invoke();
?86????????????????Thread.Sleep(1500);
?87
?88????????????????//驗證計算的結果與預期的結果是否相符合
?89????????????????Console.WriteLine("Checking?textBox3?for?'80'");
?90????????????????TextPattern?tpTextBox3?=?(TextPattern)aeTextBox3.GetCurrentPattern(TextPattern.Pattern);
?91????????????????string?result?=?tpTextBox3.DocumentRange.GetText(-1);//獲取textbox3中的值
?92????????????????//獲取textbox3中的值
?93????????????????//string?result?=?(string)aeTextBox2.GetCurrentPropertyValue(ValuePattern.ValueProperty);
?94????????????????if?("80"?==?result)
?95????????????????{
?96????????????????????Console.WriteLine("Found?it.");
?97????????????????????Console.WriteLine("TTest?scenario:?*PASS*");
?98????????????????}
?99????????????????else
100????????????????{
101????????????????????Console.WriteLine("Did?not?find?it.");
102????????????????????Console.WriteLine("Test?scenario:?*FAIL*");
103????????????????}
104
105????????????????Console.WriteLine("Close?application?in?5?seconds.");
106????????????????Thread.Sleep(5000);
107????????????????//實現關閉被測試程序
108????????????????WindowPattern?wpCloseForm?=?(WindowPattern)aeForm.GetCurrentPattern(WindowPattern.Pattern);
109????????????????wpCloseForm.Close();
110
111????????????????Console.WriteLine("\nEnd?test?run\n");
112????????????}
113????????????catch?(Exception?ex)
114????????????{
115????????????????Console.WriteLine("Fatal?error:?"?+?ex.Message);
116????????????}
117????????}
118????}
119}
120

使用UI Automation實現自動化測試--3

Chapter 3 ?UI Automation中的幾個重要屬性

Control Tree of the AutomationElement

在UI Automation控件樹中,根節點為Desktop window,?其他運行在用戶桌面的窗體都作為Desktop window的子節點。

如下圖所示:

Desktop window可通過AutomationElement.RootElement屬性獲取,子節點中的窗體或對話框可通過

AutomationElement.RootElement.FindAll(TreeScope.Descendants, condition)


AutomationElement.RootElement.FindFirt(TreeScope.Descendants, condition)來獲取.

AutomationElement property

在UI Automation中有如下幾個重要屬性:

  • AutomationIdProperty:?通過AutomationId來查找AutomationElement。
  • NameProperty:通過控件的Name屬性來查找AutomationElement。
  • ControlType:通過控件的類型來查找AutomationElement
  • AutomationId:?唯一地標識自動化元素,將其與同級相區分。
  • Name:??WPF?按鈕的Content?屬性、Win32?按鈕的Caption?屬性以及?HTML?圖像的ALT?屬性都映射到?UI?自動化視圖中的同一個屬性?Name。
  • 注:PropertyCondition類是用來對相關屬性進行條件匹配,在控件樹中查找控件時,可以通過最佳匹配來找到相應的控件。

    如下代碼列出了使用不同的屬性來構建PropertyCondition,通過PropertyCondition來查找控件樹中的控件.


    public?class?PropertyConditions
    ????{
    ????????static?PropertyCondition?propertyCondition;
    ????????///?<summary>
    ????????///?Create?PropertyCondition?by?AutomationId
    ????????///?</summary>
    ????????///?<param?name="automationId">Control?AutomationId</param>
    ????????///?<returns>Return?PropertyCondition?instance</returns>
    ????????public?static?PropertyCondition?GetAutomationIdProperty(object?automationId)
    ????????{
    ????????????propertyCondition?=?new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId);
    ????????????return?propertyCondition;
    ????????}
    ????????///?<summary>
    ????????///?
    ????????///?</summary>
    ????????///?<param?name="controlType"></param>
    ????????///?<returns></returns>
    ????????public?static?PropertyCondition?GetControlTypeProperty(object?controlType)
    ????????{
    ????????????propertyCondition?=?new?PropertyCondition(AutomationElement.ControlTypeProperty,?controlType);
    ????????????return?propertyCondition;
    ????????}
    ????????///?<summary>
    ????????///?
    ????????///?</summary>
    ????????///?<param?name="controlName"></param>
    ????????///?<returns></returns>
    ????????public?static?PropertyCondition?GetNameProperty(object?controlName)
    ????????{
    ????????????propertyCondition?=?new?PropertyCondition(AutomationElement.NameProperty,?controlName);
    ????????????return?propertyCondition;
    ????????}
    ????????///?<summary>
    ????????///?Find?element?by?specific?PropertyCondition
    ????????///?</summary>
    ????????///?<param?name="condition">PropertyCondition?instance</param>
    ????????///?<returns>Target?automation?element</returns>
    ????????public?static?AutomationElement?FindElement(PropertyCondition?condition)
    ????????{
    ????????????return?AutomationElement.RootElement.FindFirst(TreeScope.Descendants,?condition);
    ????????}
    ????}

    使用UI Automation實現自動化測試--4.1 (DockPattern)

    DockPattern用于操作可停靠容器控件,我們最熟悉的VS2005/2008中的ToolBox,Solution Explorer都可以設置不同的DockPosition, 但是目前并不支持DockPattern,所以無法做為實例來講。使用DockPattern的前提為控件支持DockPattern。?DockPattern中的DockPosition有六個枚舉變量,即Bottom、Left、Right、Top、Fill和None。如果控件支持DockPattern,?則可以獲取相對應的DockPosition以及設置控件的DockPosition。

    如下代碼是獲取控件的DockPattern、獲取控件當前的DockPosition以及設置控件的DockPosition。


    #region?DockPattern?helper
    ????????///?<summary>
    ????????///?Get?DockPattern
    ????????///?</summary>
    ????????///?<param?name="element">AutomationElement?instance</param>
    ????????///?<returns>DockPattern?instance</returns>
    ????????public?static?DockPattern?GetDockPattern(AutomationElement?element)
    ????????{
    ????????????object?currentPattern;
    ????????????if?(!element.TryGetCurrentPattern(DockPattern.Pattern,?out?currentPattern))
    ????????????{
    ????????????????throw?new?Exception(string.Format("Element?with?AutomationId?'{0}'?and?Name?'{1}'?does?not?support?the?DockPattern.",
    ????????????????????element.Current.AutomationId,?element.Current.Name));
    ????????????}
    ????????????return?currentPattern?as?DockPattern;
    ????????}
    ????????///?<summary>
    ????????///?Get?DockPosition
    ????????///?</summary>
    ????????///?<param?name="element">AutomationElement?instance</param>
    ????????///?<returns>DockPosition?instance</returns>
    ????????public?static?DockPosition?GetDockPosition(AutomationElement?element)
    ????????{
    ????????????return?GetDockPattern(element).Current.DockPosition;
    ????????}
    ????????///?<summary>
    ????????///?Set?DockPosition
    ????????///?</summary>
    ????????///?<param?name="element">AutomationElement?instance</param>
    ????????public?static?void?SetDockPattern(AutomationElement?element,?DockPosition?dockPosition)
    ????????{
    ????????????GetDockPattern(element).SetDockPosition(dockPosition);
    ????????}
    ????????#endregion

    使用UI Automation實現自動化測試--4.2 (ExpandCollapsePattern)

    ExpandCollapsePattern

    表示以可視方式進行展開(以顯示內容)和折疊(以隱藏內容)的控件。例如ComboBox控件支持ExpandCollapsePattern。

    ExpandCollapsePattern有兩個主要方法:

    Expand()方法:隱藏?AutomationElement?的全部子代節點、控件或內容。

    Collapse()方法:顯示?AutomationElement?的全部子節點、控件或內容。

    ????? 以下代碼是用ExpandCollapsePattern來測試ComboBox控件的Expand和Collapse。

    using?System;using?System.Text;using?System.Diagnostics;using?System.Threading;using?System.Windows.Automation;namespace?UIATest{????class?Program????{????????static?void?Main(string[]?args)????????{????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");????????????int?processId?=?process.Id;????????????AutomationElement?element?=?FindElementById(processId,?"comboBox1");????????????ExpandCollapsePattern?currentPattern?=?GetExpandCollapsePattern(element);????????????currentPattern.Expand();????????????Thread.Sleep(1000);????????????currentPattern.Collapse();????????}????????///?<summary>????????///?Get?the?automation?elemention?of?current?form.????????///?</summary>????????///?<param?name="processId">Process?Id</param>????????///?<returns>Target?element</returns>????????public?static?AutomationElement?FindWindowByProcessId(int?processId)????????{????????????AutomationElement?targetWindow?=?null;????????????int?count?=?0;????????????try????????????{????????????????Process?p?=?Process.GetProcessById(processId);????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);????????????????return?targetWindow;????????????}????????????catch?(Exception?ex)????????????{????????????????count++;????????????????StringBuilder?sb?=?new?StringBuilder();????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();????????????????if?(count?>?5)????????????????{????????????????????throw?new?InvalidProgramException(message,?ex);????????????????}????????????????else????????????????{????????????????????return?FindWindowByProcessId(processId);????????????????}????????????}????????}????????///?<summary>????????///?Get?the?automation?element?by?automation?Id.????????///?</summary>????????///?<param?name="windowName">Window?name</param>????????///?<param?name="automationId">Control?automation?Id</param>????????///?<returns>Automatin?element?searched?by?automation?Id</returns>????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)????????{????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));????????????return?tarFindElement;????????}????????ExpandCollapsePattern?helper????}}

    ????? 以下代碼為被測程序的xaml文件:


    ?1<Window?x:Class="WpfApp.Window1"
    ?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    ?4????Title="Window1"?Height="219"?Width="353">
    ?5????<Grid>
    ?6????????<ComboBox?Name="comboBox1"?Height="23"?VerticalAlignment="Top"?Margin="94,58,0,0"?HorizontalAlignment="Left"?Width="119">
    ?7????????????<ComboBoxItem>kaden</ComboBoxItem>
    ?8????????????<ComboBoxItem>sam</ComboBoxItem>
    ?9????????</ComboBox>
    10????</Grid>
    11</Window>

    ?

    使用UI Automation實現自動化測試--4.3 (InvokePattern)

    InvokePattern

    InvokePattern是UIA中最常用的Pattern之一,WPF和Winform中的button控件都支持InvokePattern。

    對InvokePattern的Invoke()方法的調用應立即返回,沒有出現阻止情況。但是,此行為完全依賴于?Microsoft UI?自動化提供程序實現。在調用?Invoke()?會引起阻止問題(如Winform中的模式對話框,但是WPF中的對話框的處理方式和winform不同,所以可以使用Invoke()方法來操作WPF中的模式對話框,因為WPF中的模式對話框不會出現阻止的問題)的情況下,要調用此方法,則需要另起線程來操作。


    using?System;
    using?System.Text;
    using?System.Diagnostics;
    using?System.Threading;
    using?System.Windows.Automation;
    namespace?UIATest
    {
    ????class?Program
    ????{
    ????????static?void?Main(string[]?args)
    ????????{
    ????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    ????????????int?processId?=?process.Id;
    ????????????AutomationElement?element?=?FindElementById(processId,?"button1");
    ????????????InvokePattern?currentPattern?=?GetInvokePattern(element);
    ????????????currentPattern.Invoke();
    ????????}
    ????????///?<summary>
    ????????///?Get?the?automation?elemention?of?current?form.
    ????????///?</summary>
    ????????///?<param?name="processId">Process?Id</param>
    ????????///?<returns>Target?element</returns>
    ????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    ????????{
    ????????????AutomationElement?targetWindow?=?null;
    ????????????int?count?=?0;
    ????????????try
    ????????????{
    ????????????????Process?p?=?Process.GetProcessById(processId);
    ????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    ????????????????return?targetWindow;
    ????????????}
    ????????????catch?(Exception?ex)
    ????????????{
    ????????????????count++;
    ????????????????StringBuilder?sb?=?new?StringBuilder();
    ????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    ????????????????if?(count?>?5)
    ????????????????{
    ????????????????????throw?new?InvalidProgramException(message,?ex);
    ????????????????}
    ????????????????else
    ????????????????{
    ????????????????????return?FindWindowByProcessId(processId);
    ????????????????}
    ????????????}
    ????????}
    ????????///?<summary>
    ????????///?Get?the?automation?element?by?automation?Id.
    ????????///?</summary>
    ????????///?<param?name="windowName">Window?name</param>
    ????????///?<param?name="automationId">Control?automation?Id</param>
    ????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
    ????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
    ????????{
    ????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
    ????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
    ????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
    ????????????return?tarFindElement;
    ????????}
    ????????#region?InvokePattern?helper
    ????????///?<summary>
    ????????///?Get?InvokePattern
    ????????///?</summary>
    ????????///?<param?name="element">AutomationElement?instance</param>
    ????????///?<returns>InvokePattern?instance</returns>
    ????????public?static?InvokePattern?GetInvokePattern(AutomationElement?element)
    ????????{
    ????????????object?currentPattern;
    ????????????if?(!element.TryGetCurrentPattern(InvokePattern.Pattern,?out?currentPattern))
    ????????????{
    ????????????????throw?new?Exception(string.Format("Element?with?AutomationId?'{0}'?and?Name?'{1}'?does?not?support?the?InvokePattern.",
    ????????????????????element.Current.AutomationId,?element.Current.Name));
    ????????????}
    ????????????return?currentPattern?as?InvokePattern;
    ????????}
    ????????#endregion
    ????}
    }


    被測程序xaml代碼如下:


    <Window?x:Class="WpfApp.Window1"
    ????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    ????Title="Window1"?Height="219"?Width="353">
    ????<Grid>
    ????????<Button?Height="23"?HorizontalAlignment="Left"?Click="button1_Click"?Margin="50,0,0,62"?Name="button1"?VerticalAlignment="Bottom"?Width="75">Button</Button>
    ????</Grid>
    </Window>


    對應的cs文件:


    using?System;
    using?System.Collections.Generic;
    using?System.Linq;
    using?System.Text;
    using?System.Windows;
    using?System.Windows.Controls;
    using?System.Windows.Data;
    using?System.Windows.Documents;
    using?System.Windows.Input;
    using?System.Windows.Media;
    using?System.Windows.Media.Imaging;
    using?System.Windows.Navigation;
    using?System.Windows.Shapes;
    namespace?WpfApp
    {
    ????///?<summary>
    ????///?Interaction?logic?for?Window1.xaml
    ????///?</summary>
    ????public?partial?class?Window1?:?Window
    ????{
    ????????public?Window1()
    ????????{
    ????????????InitializeComponent();
    ????????}
    ????????private?void?button1_Click(object?sender,?RoutedEventArgs?e)
    ????????{
    ????????????MessageBox.Show("Use?InvokePattern?invoke?button.");
    ????????}
    ????}
    }

    ????? 本文主要針對InvokePattern的Invoke方法來操作button控件。

    使用UI Automation實現自動化測試--4.4 (ValuePattern)

    ValuePattern是UI Automation中最常見的Pattern之一,Winform和WPF的TextBox控件都支持ValuePattern。

    ValuePattern的一個重要的方法是SetValue,在允許調用?SetValue?之前,控件應將其?IsEnabledProperty?設置為?true?并將其?IsReadOnlyProperty?設置為?false。

    通過ValuePattern的Current屬性可以獲得控件的value和IsReadOnly屬性。

    實現?Value?控件模式時,請注意以下準則和約定:

    如果任何項的值是可編輯的,則諸如?ListItem?和?TreeItem?等控件必須支持?ValuePattern,而不管控件的當前編輯模式如何。如果子項是可編輯的,則父控件還必須支持ValuePattern。

    ????下面的例子是通過ValuePattern來給TextBox設置和獲取值:


    ?1using?System;
    ?2using?System.Text;
    ?3using?System.Diagnostics;
    ?4using?System.Threading;
    ?5using?System.Windows.Automation;
    ?6
    ?7namespace?UIATest
    ?8{
    ?9????class?Program
    10????{
    11????????static?void?Main(string[]?args)
    12????????{
    13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    14????????????int?processId?=?process.Id;
    15????????????AutomationElement?element?=?FindElementById(processId,?"textBox1");
    16????????????ValuePattern?currentPattern?=?GetValuePattern(element);
    17????????????Console.WriteLine("Is?read?only:'{0}',?TextBox?text?is:'{1}'",?currentPattern.Current.IsReadOnly,?currentPattern.Current.Value);
    18????????????currentPattern.SetValue("KadenKang");
    19????????????Console.WriteLine("After?using?the?SetValue,?the?TextBox?value?is?'{0}'",?currentPattern.Current.Value);
    20????????????
    21????????}
    22
    23????????///?<summary>
    24????????///?Get?the?automation?elemention?of?current?form.
    25????????///?</summary>
    26????????///?<param?name="processId">Process?Id</param>
    27????????///?<returns>Target?element</returns>
    28????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    29????????{
    30????????????AutomationElement?targetWindow?=?null;
    31????????????int?count?=?0;
    32????????????try
    33????????????{
    34????????????????Process?p?=?Process.GetProcessById(processId);
    35????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    36????????????????return?targetWindow;
    37????????????}
    38????????????catch?(Exception?ex)
    39????????????{
    40????????????????count++;
    41????????????????StringBuilder?sb?=?new?StringBuilder();
    42????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    43????????????????if?(count?>?5)
    44????????????????{
    45????????????????????throw?new?InvalidProgramException(message,?ex);
    46????????????????}
    47????????????????else
    48????????????????{
    49????????????????????return?FindWindowByProcessId(processId);
    50????????????????}
    51????????????}
    52????????}
    53
    54????????///?<summary>
    55????????///?Get?the?automation?element?by?automation?Id.
    56????????///?</summary>
    57????????///?<param?name="windowName">Window?name</param>
    58????????///?<param?name="automationId">Control?automation?Id</param>
    59????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
    60????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
    61????????{
    62????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
    63????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
    64????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
    65????????????return?tarFindElement;
    66????????}
    67
    68????????ValuePattern?helper
    87????}
    88}
    89

    下面的代碼是xaml設計:


    1<Window?x:Class="WpfApp.Window1"
    2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4????Title="Window1"?Height="219"?Width="353">
    5????<Grid>
    6????????<TextBox?Height="23"?Margin="50,20,160,0"?Name="textBox1"?VerticalAlignment="Top"?MaxLength="5">textBox?text</TextBox>
    7????</Grid>
    8</Window>
    9

    ?????本文通過簡單的實例介紹了UI Automation中的ValuePattern及其使用方法。

    使用UI Automation實現自動化測試--4.5 (WindowPattern)

    WindowPattern 控件模式用于支持在傳統的 圖形用戶界面 (GUI) 內提供基于基本窗口的功能的控件。必須實現此控件模式的控件的示例包括頂級應用程序窗口、多文檔界面 (MDI) 子窗口、大小可調的拆分窗格控件、模式對話框以及氣球狀幫助窗口。可以使用WindowPattern來對window進行操作,例如驗證window是否激活,是否最大化、最小化、正常模式以及關閉window等。
    ???? 下面的代碼演示了WindowPattern的使用方法:?


    ?1using?System;
    ?2using?System.Text;
    ?3using?System.Diagnostics;
    ?4using?System.Threading;
    ?5using?System.Windows.Automation;
    ?6
    ?7namespace?UIATest
    ?8{
    ?9????class?Program
    10????{
    11????????static?void?Main(string[]?args)
    12????????{
    13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    14????????????int?processId?=?process.Id;
    15????????????AutomationElement?element?=?FindWindowByProcessId(processId);
    16????????????WindowPattern?currentPattern?=?GetWindowPattern(element);
    17????????????
    18????????????//Set?window?visual?state?to?Maximized
    19????????????currentPattern.SetWindowVisualState(WindowVisualState.Maximized);
    20????????????Thread.Sleep(1000);
    21
    22????????????//Set?window?visual?state?to?Normal
    23????????????currentPattern.SetWindowVisualState(WindowVisualState.Normal);
    24????????????Thread.Sleep(1000);
    25
    26????????????//Set?window?visual?state?to?Minimized
    27????????????currentPattern.SetWindowVisualState(WindowVisualState.Minimized);
    28????????????
    29????????????//Close?window
    30????????????currentPattern.Close();????????????
    31????????}
    32
    33????????///?<summary>
    34????????///?Get?the?automation?elemention?of?current?form.
    35????????///?</summary>
    36????????///?<param?name="processId">Process?Id</param>
    37????????///?<returns>Target?element</returns>
    38????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    39????????{
    40????????????AutomationElement?targetWindow?=?null;
    41????????????int?count?=?0;
    42????????????try
    43????????????{
    44????????????????Process?p?=?Process.GetProcessById(processId);
    45????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    46????????????????return?targetWindow;
    47????????????}
    48????????????catch?(Exception?ex)
    49????????????{
    50????????????????count++;
    51????????????????StringBuilder?sb?=?new?StringBuilder();
    52????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    53????????????????if?(count?>?5)
    54????????????????{
    55????????????????????throw?new?InvalidProgramException(message,?ex);
    56????????????????}
    57????????????????else
    58????????????????{
    59????????????????????return?FindWindowByProcessId(processId);
    60????????????????}
    61????????????}
    62????????}
    63
    64????????WindowPattern?helper
    83????}
    84}

    使用UI Automation實現自動化測試--4.6.1 (SelectionItemPattern)

    SelectionItemPattern

    支持SelectionItemPattern的控件有ListView、ListBox、RadioButton、GridView等。

  • 1.?????????SelectionItemPattern的三個重要方法:
  • 1.?????????AddToSelection:將當前元素添加到所選項的集合。
  • 2.?????????RemoveFromSelection:?從選定項的集合中移除當前元素。
  • 3.?????????Select:?取消所有已選中的項,然后選擇當前元素。
  • 2.?????????SelectionItemPattern的Current屬性可通過Current屬性的IsSelected屬性來判斷AutomationElement是否被selected.
  • ?????如下代碼演示了使用SelectionItemPattern來操作RadioButton控件。


    ?1using?System;
    ?2using?System.Text;
    ?3using?System.Diagnostics;
    ?4using?System.Threading;
    ?5using?System.Windows.Automation;
    ?6
    ?7namespace?UIATest
    ?8{
    ?9????class?Program
    10????{
    11????????static?void?Main(string[]?args)
    12????????{
    13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    14????????????int?processId?=?process.Id;
    15
    16????????????AutomationElement?element?=?FindElementById(processId,?"radioButton1");
    17????????????SelectionItemPattern?selectionItemPattern?=?GetSelectionItemPattern(element);
    18????????????selectionItemPattern.Select();
    19????????}
    20
    21????????///?<summary>
    22????????///?Get?the?automation?elemention?of?current?form.
    23????????///?</summary>
    24????????///?<param?name="processId">Process?Id</param>
    25????????///?<returns>Target?element</returns>
    26????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    27????????{
    28????????????AutomationElement?targetWindow?=?null;
    29????????????int?count?=?0;
    30????????????try
    31????????????{
    32????????????????Process?p?=?Process.GetProcessById(processId);
    33????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    34????????????????return?targetWindow;
    35????????????}
    36????????????catch?(Exception?ex)
    37????????????{
    38????????????????count++;
    39????????????????StringBuilder?sb?=?new?StringBuilder();
    40????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    41????????????????if?(count?>?5)
    42????????????????{
    43????????????????????throw?new?InvalidProgramException(message,?ex);
    44????????????????}
    45????????????????else
    46????????????????{
    47????????????????????return?FindWindowByProcessId(processId);
    48????????????????}
    49????????????}
    50????????}
    51
    52
    53????????///?<summary>
    54????????///?Get?the?automation?element?by?automation?Id.
    55????????///?</summary>
    56????????///?<param?name="windowName">Window?name</param>
    57????????///?<param?name="automationId">Control?automation?Id</param>
    58????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
    59????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
    60????????{
    61????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
    62????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
    63????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
    64????????????return?tarFindElement;
    65????????}
    66
    67????????SelectItemPattern
    86????}
    87}
    88

    ???? 以下代碼為XAML:


    1<Window?x:Class="WpfApp.Window1"
    2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4????Title="Window1"?Height="219"?Width="353">
    5????<Grid>
    6????????<RadioButton?Height="16"?HorizontalAlignment="Right"?Margin="0,46,10,0"?Name="radioButton1"?VerticalAlignment="Top"?Width="120">RadioButton</RadioButton>
    7????</Grid>
    8</Window>
    9

    ????本文簡單介紹了SelectionItemPattern以及使用SelectionItemPattern來操作RadioButton。

    使用UI Automation實現自動化測試--4.6.2 (SelectItemPattern Demo)

    ?如下代碼演示了使用SelectionItemPattern來實現listview item 的多選操作:


    ??1using?System;
    ??2using?System.Text;
    ??3using?System.Diagnostics;
    ??4using?System.Threading;
    ??5using?System.Windows.Automation;
    ??6
    ??7namespace?UIATest
    ??8{
    ??9????class?Program
    ?10????{
    ?11????????static?void?Main(string[]?args)
    ?12????????{
    ?13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    ?14????????????int?processId?=?process.Id;
    ?15
    ?16????????????Thread.Sleep(1000);
    ?17????????????MutlSelect(new?int[]?{?0,?1?},?processId,?false);
    ?18????????}
    ?19
    ?20????????///?<summary>
    ?21????????///?Get?the?automation?elemention?of?current?form.
    ?22????????///?</summary>
    ?23????????///?<param?name="processId">Process?Id</param>
    ?24????????///?<returns>Target?element</returns>
    ?25????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    ?26????????{
    ?27????????????AutomationElement?targetWindow?=?null;
    ?28????????????int?count?=?0;
    ?29????????????try
    ?30????????????{
    ?31????????????????Process?p?=?Process.GetProcessById(processId);
    ?32????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    ?33????????????????return?targetWindow;
    ?34????????????}
    ?35????????????catch?(Exception?ex)
    ?36????????????{
    ?37????????????????count++;
    ?38????????????????StringBuilder?sb?=?new?StringBuilder();
    ?39????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    ?40????????????????if?(count?>?5)
    ?41????????????????{
    ?42????????????????????throw?new?InvalidProgramException(message,?ex);
    ?43????????????????}
    ?44????????????????else
    ?45????????????????{
    ?46????????????????????return?FindWindowByProcessId(processId);
    ?47????????????????}
    ?48????????????}
    ?49????????}
    ?50
    ?51
    ?52????????///?<summary>
    ?53????????///?Get?the?automation?element?by?automation?Id.
    ?54????????///?</summary>
    ?55????????///?<param?name="windowName">Window?name</param>
    ?56????????///?<param?name="automationId">Control?automation?Id</param>
    ?57????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
    ?58????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
    ?59????????{
    ?60????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
    ?61????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
    ?62????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
    ?63????????????return?tarFindElement;
    ?64????????}
    ?65????????
    ?66????????///?<summary>
    ?67????????///?Bulk?select?the?list?item
    ?68????????///?</summary>
    ?69????????///?<param?name="indexes">List?item?index?collection</param>
    ?70????????///?<param?name="processId">Application?process?Id</param>
    ?71????????///?<param?name="isSelectAll">Is?select?all?or?not</param>
    ?72????????public?static?void?MutlSelect(int[]?indexes,?int?processId,?bool?isSelectAll)
    ?73????????{
    ?74????????????AutomationElement?targetElement?=?FindElementById(processId,?"listView1");
    ?75
    ?76????????????AutomationElementCollection?rows?=
    ?77????????????????targetElement.FindAll(TreeScope.Descendants,
    ?78????????????????new?PropertyCondition(AutomationElement.ControlTypeProperty,?ControlType.ListItem));
    ?79
    ?80????????????object?multiSelect;
    ?81
    ?82????????????if?(isSelectAll)
    ?83????????????{
    ?84????????????????for?(int?i?=?1;?i?<?rows.Count?-?1;?i++)
    ?85????????????????{
    ?86????????????????????if?(rows[i].TryGetCurrentPattern(SelectionItemPattern.Pattern,?out?multiSelect))
    ?87????????????????????{
    ?88????????????????????????(multiSelect?as?SelectionItemPattern).AddToSelection();
    ?89????????????????????}
    ?90????????????????}
    ?91????????????}
    ?92????????????else
    ?93????????????{
    ?94????????????????if?(indexes.Length?>?0)
    ?95????????????????{
    ?96????????????????????for?(int?j?=?0;?j?<?indexes.Length;?j++)
    ?97????????????????????{
    ?98????????????????????????int?tempIndex?=?indexes[j];
    ?99????????????????????????if?(rows[tempIndex].TryGetCurrentPattern(SelectionItemPattern.Pattern,?out?multiSelect))
    100????????????????????????{
    101????????????????????????????(multiSelect?as?SelectionItemPattern).AddToSelection();
    102????????????????????????}
    103????????????????????}
    104????????????????}
    105????????????}
    106????????}
    107
    108????????SelectItemPattern
    127????}
    128}

    ????? 如下代碼為對應的XAML:


    ?1<Window?x:Class="WpfApp.Window2"
    ?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    ?4????Title="Window2"?Height="412"?Width="585">
    ?5????<Grid>
    ?6????????<ListView?Margin="2,97,0,163"?Name="listView1">
    ?7????????????<ListViewItem>Kaden</ListViewItem>
    ?8????????????<ListViewItem>KangYi</ListViewItem>
    ?9????????????<ListViewItem>John</ListViewItem>
    10????????</ListView>
    11????</Grid>
    12</Window>
    13

    使用UI Automation實現自動化測試--4.7 (TogglePattern)

    TogglePattern

    支持TogglePattern的控件有CheckBox,TreeView中的button控件等。

  • 1.???????TogglePattern的方法
  • Toggle方法用于操作可以循環通過的一組狀態并在設置后保持某種狀態。

  • 2.???????TogglePattern屬性
  • Current屬性中的ToggleState有如下三種狀態:

  • 1.?????????On
  • 2.?????????Off
  • 3.?????????Indeterminate
  • ????如下代碼演示了使用TogglePattern來操作CheckBox控件。


    ?1using?System;
    ?2using?System.Text;
    ?3using?System.Diagnostics;
    ?4using?System.Threading;
    ?5using?System.Windows.Automation;
    ?6
    ?7namespace?UIATest
    ?8{
    ?9????class?Program
    10????{
    11????????static?void?Main(string[]?args)
    12????????{
    13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    14????????????int?processId?=?process.Id;
    15
    16????????????Thread.Sleep(1000);
    17????????????AutomationElement?element?=?FindElementById(processId,?"checkBox1");
    18????????????TogglePattern?togglePattern?=?GetTogglePattern(element);
    19????????????togglePattern.Toggle();
    20????????}
    21
    22????????///?<summary>
    23????????///?Get?the?automation?elemention?of?current?form.
    24????????///?</summary>
    25????????///?<param?name="processId">Process?Id</param>
    26????????///?<returns>Target?element</returns>
    27????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    28????????{
    29????????????AutomationElement?targetWindow?=?null;
    30????????????int?count?=?0;
    31????????????try
    32????????????{
    33????????????????Process?p?=?Process.GetProcessById(processId);
    34????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    35????????????????return?targetWindow;
    36????????????}
    37????????????catch?(Exception?ex)
    38????????????{
    39????????????????count++;
    40????????????????StringBuilder?sb?=?new?StringBuilder();
    41????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    42????????????????if?(count?>?5)
    43????????????????{
    44????????????????????throw?new?InvalidProgramException(message,?ex);
    45????????????????}
    46????????????????else
    47????????????????{
    48????????????????????return?FindWindowByProcessId(processId);
    49????????????????}
    50????????????}
    51????????}
    52
    53????????///?<summary>
    54????????///?Get?the?automation?element?by?automation?Id.
    55????????///?</summary>
    56????????///?<param?name="windowName">Window?name</param>
    57????????///?<param?name="automationId">Control?automation?Id</param>
    58????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
    59????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
    60????????{
    61????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
    62????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
    63????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
    64????????????return?tarFindElement;
    65????????}
    66
    67????????TogglePattern?helper
    83????}
    84}
    85

    ???? 如下代碼為對應的XAML:


    1<Window?x:Class="WpfApp.Window1"
    2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    4????Title="Window1"?Height="219"?Width="353">
    5????<Grid>
    6????????<CheckBox?HorizontalAlignment="Right"?Margin="0,75,10,89"?Name="checkBox1"?Width="120">CheckBox</CheckBox>
    7????</Grid>
    8</Window>

    使用UI Automation實現自動化測試--4.8 (GridPattern)

    GridPattern

    支持GridPattern的最常見的控件為GridView,?在WPF中使用ListView和GridView組合即可得到相應的GridView。

    GridPattern的方法

    GetItem:此方法有兩個參數,即DataGrid的Row和Column。

    通過GridPattern的GetItem方法可以獲取DataGrid中的某個確定的單元格,進而對單元進行操作。

    對單元格的操作主要有以下幾個方面:

  • 1.???????編輯單元個中的數據。
  • 2.???????獲取單元格中的數據。
  • 3.???????獲取單元格中嵌套的AutomationElement(一般使用與自定義控件中)。
  • GridPattern的屬性

    GridPattern的Current屬性中有如下兩個屬性:

  • 1.???????RowCount屬性:GridPattern二維表格的行數。
  • 2.???????ColumnCount屬性:GridPattern二維表格列數。
  • 下面我們通過一個實例來演示自動化測試中如何使用GridPattern來測試GridView的方法:


    ?1using?System;
    ?2using?System.Text;
    ?3using?System.Diagnostics;
    ?4using?System.Threading;
    ?5using?System.Windows.Automation;
    ?6
    ?7namespace?UIATest
    ?8{
    ?9????class?Program
    10????{
    11????????static?void?Main(string[]?args)
    12????????{
    13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    14????????????int?processId?=?process.Id;
    15????????????Thread.Sleep(1000);
    16
    17????????????GridPattern?Test
    30????????}
    31
    32????????///?<summary>
    33????????///?Get?the?automation?elemention?of?current?form.
    34????????///?</summary>
    35????????///?<param?name="processId">Process?Id</param>
    36????????///?<returns>Target?element</returns>
    37????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    38????????{
    39????????????AutomationElement?targetWindow?=?null;
    40????????????int?count?=?0;
    41????????????try
    42????????????{
    43????????????????Process?p?=?Process.GetProcessById(processId);
    44????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    45????????????????return?targetWindow;
    46????????????}
    47????????????catch?(Exception?ex)
    48????????????{
    49????????????????count++;
    50????????????????StringBuilder?sb?=?new?StringBuilder();
    51????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    52????????????????if?(count?>?5)
    53????????????????{
    54????????????????????throw?new?InvalidProgramException(message,?ex);
    55????????????????}
    56????????????????else
    57????????????????{
    58????????????????????return?FindWindowByProcessId(processId);
    59????????????????}
    60????????????}
    61????????}
    62
    63????????///?<summary>
    64????????///?Get?the?automation?element?by?automation?Id.
    65????????///?</summary>
    66????????///?<param?name="windowName">Window?name</param>
    67????????///?<param?name="automationId">Control?automation?Id</param>
    68????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
    69????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
    70????????{
    71????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
    72????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
    73????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
    74????????????return?tarFindElement;
    75????????}
    76
    77????????GridPattern?helper
    95????}
    96}
    97

    ????對應的XAML代碼如下:


    ?1<Window?x:Class="WpfApp.GridView"
    ?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    ?4????Title="GridView"?Height="426"?Width="558">
    ?5????<Grid>
    ?6????????<!--將鼠標放在方框的邊緣點擊就會產生相應的分割線生成Grid.RowDefinitions-->
    ?7????????<Grid.RowDefinitions>
    ?8????????????<!--Auto,實際作用就是取實際控件所需的最小值;值為*或N*,實際作用就是取盡可能大的值;數字,絕對尺寸-->
    ?9????????????<RowDefinition?Height="*"?/>
    10????????????<RowDefinition?Height="auto"?MinHeight="95"?/>
    11????????????<RowDefinition?Height="22"?/>
    12????????</Grid.RowDefinitions>
    13????????<ListView?Name="listview1"?MinWidth="280"?Grid.RowSpan="2"?MouseMove="listview1_MouseMove">
    14????????????<ListView.View>
    15????????????????<GridView?x:Name="gridView1">
    16????????????????????<GridViewColumn?Header="EmployeeID"?DisplayMemberBinding="{Binding?Path=EmployeeID}"></GridViewColumn>
    17????????????????????<GridViewColumn?Header="FirstName"?DisplayMemberBinding="{Binding?Path=FirstName}"></GridViewColumn>
    18????????????????????<GridViewColumn?Header="LastName"?DisplayMemberBinding="{Binding?Path=LastName}"></GridViewColumn>
    19????????????????????<GridViewColumn?Header="Address"?DisplayMemberBinding="{Binding?Path=Address}"></GridViewColumn>
    20????????????????</GridView>
    21????????????</ListView.View>
    22????????</ListView>
    23????</Grid>
    24
    25</Window>
    26

    ????GridView窗體后臺代碼如下:


    ?1using?System;
    ?2using?System.Collections.Generic;
    ?3using?System.Linq;
    ?4using?System.Text;
    ?5using?System.Windows;
    ?6using?System.Windows.Controls;
    ?7using?System.Windows.Data;
    ?8using?System.Windows.Documents;
    ?9using?System.Windows.Input;
    10using?System.Windows.Media;
    11using?System.Windows.Media.Imaging;
    12using?System.Windows.Shapes;
    13using?System.Data.SqlClient;
    14using?System.Data;
    15
    16namespace?WpfApp
    17{
    18????///?<summary>
    19????///?Interaction?logic?for?GridView.xaml
    20????///?</summary>
    21????public?partial?class?GridView?:?Window
    22????{
    23????????public?GridView()
    24????????{
    25????????????InitializeComponent();
    26????????????getData();
    27????????}
    28????????SqlDataAdapter?sda;
    29????????DataTable?dt;
    30????????void?getData()
    31????????{
    32????????????//Northwind?database?download?path:http://download.csdn.net/down/845087/beyondchina123
    33????????????//init?sqlconnection
    34????????????SqlConnectionStringBuilder?connbuilder?=?new?SqlConnectionStringBuilder();
    35????????????connbuilder.DataSource?=?".";//本地服務器
    36????????????connbuilder.IntegratedSecurity?=?true;//Windows集成驗證
    37????????????connbuilder.InitialCatalog?=?"Northwind";//數據庫為Northwind
    38????????????SqlConnection?conn?=?new?SqlConnection(connbuilder.ConnectionString);
    39????????????sda?=?new?SqlDataAdapter("select?EmployeeID,FirstName,LastName,Address?from?Employees?",?conn);
    40????????????SqlCommandBuilder?commbuilder?=?new?SqlCommandBuilder(sda);
    41????????????dt?=?new?DataTable();
    42????????????sda.Fill(dt);
    43????????????listview1.ItemsSource?=?dt.DefaultView;
    44????????}
    45??????}
    46}
    47
    48

    ?????本文主要簡單介紹了GridPattern以及GridPattern在測試中是使用方法。

    使用UI Automation實現自動化測試--4.9 (ScrollPattern)

    ScrollPattern

    ScrollPattern是用來操作控件的滾動條,目前支持ScrollPattern的控件有ListBox,listView,GridView,TreeView.

    ScrollPattern主要方法

  • 1.?????????Scroll?水平和垂直滾動內容區域的可見區域滾動,?Scroll有兩個參數,其類型為ScrollAmount枚舉類型。
  • 2.?????????ScrollHorizontal?按指定的?ScrollAmount?水平滾動內容區域的當前可見區域滾動。
  • 3.?????????ScrollVertical?按指定的?ScrollAmount?垂直滾動內容區域的當前可見區域滾動。
  • ScrollPattern屬性

  • VerticallyScrollable?屬性用于判定是否可以垂直滾動。
  • HorizontallyScrollable?屬性用于判定是否可以水平滾動。
  • HorizontalScrollPercent?獲取當前水平滾動條的位置。
  • VerticalScrollPercent?獲取當前垂直滾動條的位置。
  • 下面我們通過一個實例來演示自動化測試中如何使用ScrollPattern來測試GridView中滾動條的方法:


    ??1using?System;
    ??2using?System.Text;
    ??3using?System.Diagnostics;
    ??4using?System.Threading;
    ??5using?System.Windows.Automation;
    ??6
    ??7namespace?UIATest
    ??8{
    ??9????class?Program
    ?10????{
    ?11????????static?void?Main(string[]?args)
    ?12????????{
    ?13????????????Process?process?=?Process.Start(@"F:\CSharpDotNet\AutomationTest\ATP\WpfApp\bin\Debug\WpfApp.exe");
    ?14????????????int?processId?=?process.Id;
    ?15????????????Thread.Sleep(1000);
    ?16
    ?17????????????ScrollPattern
    ?31????????????
    ?32????????}
    ?33
    ?34????????///?<summary>
    ?35????????///?Get?the?automation?elemention?of?current?form.
    ?36????????///?</summary>
    ?37????????///?<param?name="processId">Process?Id</param>
    ?38????????///?<returns>Target?element</returns>
    ?39????????public?static?AutomationElement?FindWindowByProcessId(int?processId)
    ?40????????{
    ?41????????????AutomationElement?targetWindow?=?null;
    ?42????????????int?count?=?0;
    ?43????????????try
    ?44????????????{
    ?45????????????????Process?p?=?Process.GetProcessById(processId);
    ?46????????????????targetWindow?=?AutomationElement.FromHandle(p.MainWindowHandle);
    ?47????????????????return?targetWindow;
    ?48????????????}
    ?49????????????catch?(Exception?ex)
    ?50????????????{
    ?51????????????????count++;
    ?52????????????????StringBuilder?sb?=?new?StringBuilder();
    ?53????????????????string?message?=?sb.AppendLine(string.Format("Target?window?is?not?existing.try?#{0}",?count)).ToString();
    ?54????????????????if?(count?>?5)
    ?55????????????????{
    ?56????????????????????throw?new?InvalidProgramException(message,?ex);
    ?57????????????????}
    ?58????????????????else
    ?59????????????????{
    ?60????????????????????return?FindWindowByProcessId(processId);
    ?61????????????????}
    ?62????????????}
    ?63????????}
    ?64
    ?65
    ?66????????///?<summary>
    ?67????????///?Get?the?automation?element?by?automation?Id.
    ?68????????///?</summary>
    ?69????????///?<param?name="windowName">Window?name</param>
    ?70????????///?<param?name="automationId">Control?automation?Id</param>
    ?71????????///?<returns>Automatin?element?searched?by?automation?Id</returns>
    ?72????????public?static?AutomationElement?FindElementById(int?processId,?string?automationId)
    ?73????????{
    ?74????????????AutomationElement?aeForm?=?FindWindowByProcessId(processId);
    ?75????????????AutomationElement?tarFindElement?=?aeForm.FindFirst(TreeScope.Descendants,
    ?76????????????new?PropertyCondition(AutomationElement.AutomationIdProperty,?automationId));
    ?77????????????return?tarFindElement;
    ?78????????}
    ?79
    ?80????????GetScrollPattern?helper
    ?98????}
    ?99}
    100

    ???XAML源碼:


    ?1<Window?x:Class="WpfApp.GridView"
    ?2????xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    ?3????xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    ?4????Title="GridView"?Height="280"?Width="467">
    ?5????<Grid>
    ?6????????<!--將鼠標放在方框的邊緣點擊就會產生相應的分割線生成Grid.RowDefinitions-->
    ?7????????<Grid.RowDefinitions>
    ?8????????????<!--Auto,實際作用就是取實際控件所需的最小值;值為*或N*,實際作用就是取盡可能大的值;數字,絕對尺寸-->
    ?9????????????<RowDefinition?Height="*"?/>
    10????????????<RowDefinition?Height="auto"?MinHeight="95"?/>
    11????????????<RowDefinition?Height="22"?/>
    12????????</Grid.RowDefinitions>
    13????????<ListView?Name="listview1"?MinWidth="280"?Grid.RowSpan="2"?MouseMove="listview1_MouseMove">
    14????????????<ListView.View>
    15????????????????<GridView?x:Name="gridView1">
    16????????????????????<GridViewColumn?Header="EmployeeID"?DisplayMemberBinding="{Binding?Path=EmployeeID}"></GridViewColumn>
    17????????????????????<GridViewColumn?Header="FirstName"?DisplayMemberBinding="{Binding?Path=FirstName}"></GridViewColumn>
    18????????????????????<GridViewColumn?Header="LastName"?DisplayMemberBinding="{Binding?Path=LastName}"></GridViewColumn>
    19????????????????????<GridViewColumn?Header="Address"?DisplayMemberBinding="{Binding?Path=Address}"></GridViewColumn>
    20????????????????</GridView>
    21????????????</ListView.View>
    22????????</ListView>
    23????????<!--Grid.Row="1"用來設置WrapPanel及Button應該在父容器的什么位置-->
    24????</Grid>
    25
    26</Window>

    ?????? 后臺CS源碼:


    ?1using?System;
    ?2using?System.Collections.Generic;
    ?3using?System.Linq;
    ?4using?System.Text;
    ?5using?System.Windows;
    ?6using?System.Windows.Controls;
    ?7using?System.Windows.Data;
    ?8using?System.Windows.Documents;
    ?9using?System.Windows.Input;
    10using?System.Windows.Media;
    11using?System.Windows.Media.Imaging;
    12using?System.Windows.Shapes;
    13using?System.Data.SqlClient;
    14using?System.Data;
    15
    16namespace?WpfApp
    17{
    18????///?<summary>
    19????///?Interaction?logic?for?GridView.xaml
    20????///?</summary>
    21????public?partial?class?GridView?:?Window
    22????{
    23????????public?GridView()
    24????????{
    25????????????InitializeComponent();
    26????????????getData();
    27????????}
    28????????SqlDataAdapter?sda;
    29????????DataTable?dt;
    30????????void?getData()
    31????????{
    32????????????//init?sqlconnection
    33????????????SqlConnectionStringBuilder?connbuilder?=?new?SqlConnectionStringBuilder();
    34????????????connbuilder.DataSource?=?".";//本地服務器
    35????????????connbuilder.IntegratedSecurity?=?true;//Windows集成驗證
    36????????????connbuilder.InitialCatalog?=?"TestDB";//數據庫為Northwind
    37????????????SqlConnection?conn?=?new?SqlConnection(connbuilder.ConnectionString);
    38????????????sda?=?new?SqlDataAdapter("select?EmployeeID,FirstName,LastName,Address?from?Employees?",?conn);
    39????????????SqlCommandBuilder?commbuilder?=?new?SqlCommandBuilder(sda);
    40????????????//sda.UpdateCommand?=?commbuilder.GetUpdateCommand();
    41????????????dt?=?new?DataTable();
    42????????????//sda.AcceptChangesDuringUpdate?=?true;
    43????????????sda.Fill(dt);
    44????????????listview1.ItemsSource?=?dt.DefaultView;
    45????????}
    46????}
    47}
    48
    49

    ?????? 數據庫及數據庫表源碼:


    ?1USE?[master]
    ?2GO
    ?3/******?Object:??Database?TestDB????Script?Date:?10/17/2009?16:08:09?******/
    ?4IF??EXISTS?(SELECT?name?FROM?sys.databases?WHERE?name?=?N'TestDB')
    ?5DROP?DATABASE?[TestDB]
    ?6CREATE?DATABASE?TestDB?ON??PRIMARY?
    ?7(?NAME?=?N'TestDB',?FILENAME?=?N'C:\TestDB.mdf'?,?SIZE?=?2688KB?,?MAXSIZE?=?UNLIMITED,?FILEGROWTH?=?80KB?)
    ?8?LOG?ON?
    ?9(?NAME?=?N'TestDB_log',?FILENAME?=?N'C:\TestDB.ldf'?,?SIZE?=?1024KB?,?MAXSIZE?=?UNLIMITED,?FILEGROWTH?=?10%)
    10GO
    11
    12use?TestDB
    13
    14CREATE?TABLE?[dbo].[Employees](
    15????[EmployeeID]?[int]?IDENTITY(1,1)?primary?key?NOT?NULL,
    16????[LastName]?[varchar](20)?NOT?NULL,
    17????[FirstName]?[varchar](10)?NOT?NULL,
    18????[Address]?[varchar](60)?NULL
    19)?
    20
    21GO
    22truncate?table?employees
    23declare?@i?int
    24set?@i?=?1
    25while?@i<25
    26begin
    27
    28insert?into?Employees
    29(
    30???LastName,
    31???FirstName,
    32???[Address]
    33)?
    34values
    35('Kaden'+cast(@i?as?varchar),?'Kang'+cast(@i?as?varchar),?'Nanjing,?Jiangsu,?China'+cast(@i?as?varchar))
    36set?@i=@i+1
    37end
    38
    39

    ????????本文簡單介紹了ScrollPattern以及使用ScrollPattern來操作垂直水平滾動條。

    總結

    以上是生活随笔為你收集整理的UIAutomation 自动化的全部內容,希望文章能夠幫你解決所遇到的問題。

    如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。

    观看免费av | 精品国产伦一区二区三区观看体验 | 夜夜视频欧洲 | 国产手机免费视频 | av一二三区 | 福利片视频区 | 日韩伦理一区二区三区av在线 | 久久国产午夜精品理论片最新版本 | 国产精品久久久久婷婷 | 日韩激情视频在线观看 | 国产黄大片 | 欧美一区二区在线免费观看 | 97香蕉久久超级碰碰高清版 | 在线精品在线 | 九九九九免费视频 | 亚洲精品动漫成人3d无尽在线 | 99久久超碰中文字幕伊人 | 国产中文欧美日韩在线 | 91丨九色丨蝌蚪丨对白 | 日日日天天天 | 欧美一区二视频在线免费观看 | 久久精品一二三区白丝高潮 | 久久久免费看片 | 日韩免费网址 | 69av国产| 日本黄色免费在线 | 国内精品久久久久久久久久清纯 | 91精品国产高清 | 久久精品国产一区二区电影 | 成年人免费在线观看网站 | 97超碰人人澡人人爱 | 国产精品一区二区三区99 | 亚欧日韩成人h片 | 黄色国产成人 | 色综合天 | 91尤物国产尤物福利在线播放 | 日韩av在线免费看 | 五月婷婷丁香 | www黄免费| 国产在线精品区 | 亚洲精品理论 | 96亚洲精品久久 | 久爱精品在线 | www.黄色片网站| 一区二区三区四区在线 | 国产精品 999| 国产成人三级在线播放 | 久草在线视频精品 | 午夜在线免费视频 | 久久免费视频2 | 九九九视频精品 | 在线观看v片 | 91视频大全| 亚洲午夜在线视频 | 最近最新mv字幕免费观看 | 亚洲一区二区麻豆 | 欧美aⅴ在线观看 | 中文字幕中文字幕中文字幕 | av在线在线 | 99视频偷窥在线精品国自产拍 | 婷婷久久综合网 | 亚洲闷骚少妇在线观看网站 | 色黄久久久久久 | 中文一区二区三区在线观看 | 久久精品草 | 欧美 日韩 国产 成人 在线 | 国产精品淫 | 久久精品在线免费观看 | 久久a级片| 96久久精品 | 成年人免费在线观看网站 | 99久久精品久久久久久动态片 | 99r精品视频在线观看 | 91chinesexxx | 人人狠狠综合久久亚洲婷 | 黄色三级免费网址 | 欧美精品中文字幕亚洲专区 | 精品国产乱码久久 | 色天天久久 | 91在线小视频 | 伊人色综合网 | 欧美日本日韩aⅴ在线视频 插插插色综合 | 国产精品高潮呻吟久久av无 | 婷婷深爱激情 | 亚洲japanese制服美女 | av黄免费看 | 深爱激情婷婷网 | 日韩在线视频一区二区三区 | 国产精品久久久久久高潮 | 国产中文字幕在线播放 | av三级在线免费观看 | 日韩精品免费一区二区 | 国产高清av免费在线观看 | 97视频免费观看2区 亚洲视屏 | 狂野欧美激情性xxxx欧美 | 久精品在线 | 91av视频导航 | 欧美俄罗斯性视频 | 日韩成人精品一区二区 | 亚洲视频综合在线 | 日日夜夜中文字幕 | 亚洲精品视频久久 | 8x成人在线 | 天天天天爱天天躁 | 中文字幕一区二区三区在线视频 | 色www免费视频| 国产一二三四在线视频 | 婷婷九九 | 日韩欧美网址 | 久久九九久久精品 | 午夜久久电影网 | 在线观看精品视频 | 日韩综合一区二区三区 | 8x成人免费视频 | 黄色软件在线看 | 丁香激情综合久久伊人久久 | 美女免费视频一区二区 | 欧美国产日韩在线观看 | 精品视频www | 国产午夜三级一区二区三桃花影视 | 日韩在线免费播放 | 久久久久国产一区二区 | 久久精品91视频 | 欧美综合在线观看 | 国产精品国产三级国产不产一地 | 欧美综合在线视频 | 视频在线播放国产 | 国产精品少妇 | 色婷婷成人网 | 精品国产精品久久一区免费式 | 国产精品九九九九九 | av色网站 | 国产在线色站 | 99999精品视频 | 日本中文字幕在线播放 | 精品免费国产一区二区三区四区 | 亚洲精品国偷拍自产在线观看蜜桃 | 国内精品久久久久影院一蜜桃 | 国产喷水在线 | 激情九九| 在线观看岛国片 | 国产无套一区二区三区久久 | 欧美日韩在线免费观看视频 | 亚洲国产视频a | 精品在线一区二区 | 97人人添人澡人人爽超碰动图 | 人人爽人人看 | 玖玖玖影院 | 激情视频综合网 | 国产免费视频一区二区裸体 | 国产美女网 | 日韩av中文 | 99久免费精品视频在线观看 | 国产精品成人在线观看 | 麻豆成人在线观看 | 免费av观看网站 | 欧美精品做受xxx性少妇 | 91亚州| www久久久久 | 日韩美女久久 | 亚洲综合欧美精品电影 | 青青河边草免费直播 | 亚洲精品国产视频 | 99精品国产免费久久 | 欧美日韩国产综合一区二区 | 韩国精品一区二区三区六区色诱 | 香蕉在线视频播放网站 | 久久亚洲欧美日韩精品专区 | 玖玖爱免费视频 | 久草在线视频资源 | 国产短视频在线播放 | 亚洲天堂香蕉 | 狠日日| 美女国内精品自产拍在线播放 | 日韩在线观看 | 国产亚洲精品久久久久久久久久久久 | 麻豆91精品91久久久 | 2018好看的中文在线观看 | 亚洲高清网站 | 久久99精品国产99久久6尤 | 欧美精品久久久久久久久久白贞 | 亚洲精品在线国产 | 91av手机在线观看 | 伊人影院99 | 色婷婷激情综合 | 黄色小网站在线 | 亚洲精品999| 久久伊人91| 麻豆免费视频 | 最近日本中文字幕a | 国产极品尤物在线 | 国产黄色免费观看 | 国产一二区免费视频 | 最新国产在线 | 91亚洲精品久久久久图片蜜桃 | 久久视频国产 | 青青草国产免费 | 久久视频国产 | 亚洲另类在线视频 | 国产精品18久久久久久不卡孕妇 | 日韩国产精品久久 | 亚洲国产日韩一区 | 日本免费一二三区 | 亚洲精品福利在线观看 | 九九99 | 国产黄色av | 激情图片区 | 69国产精品视频 | www.干| 国产一级精品在线观看 | 欧美另类交人妖 | 美女网站视频免费黄 | 国产精品v欧美精品 | 婷婷在线看 | 成人在线黄色电影 | 99在线免费视频观看 | 99在线播放 | 亚洲午夜精品久久久久久久久久久久 | 中文字幕在线一区二区三区 | 国产成人精品女人久久久 | 亚洲国产福利视频 | 99久久精品免费视频 | 久久永久免费 | 久久免费看 | www色网站 | 天天爱综合 | 久久久久在线观看 | 成人综合婷婷国产精品久久免费 | 98超碰在线观看 | 婷婷电影在线观看 | 免费亚洲一区二区 | 99热这里只有精品在线观看 | 欧美男男激情videos | 欧美日韩国产伦理 | 亚州欧美精品 | 成人免费视频免费观看 | 久久久久久久久久久国产精品 | 啪啪免费试看 | 亚洲精品系列 | 午夜精品剧场 | 亚洲成人av片 | 玖玖玖精品 | 黄色大片入口 | 青青草国产在线 | 九九有精品 | a黄色影院 | 中文字幕一区二区三区精华液 | www.色国产 | 久久久国产精品人人片99精片欧美一 | 欧美老少交| 九九热在线精品视频 | 中文字幕一区二区三区视频 | 在线成人一区 | 天天色天天上天天操 | 久久精品79国产精品 | 欧美乱熟臀69xxxxxx | 99国产视频 | 中文 一区二区 | 欧美一级免费片 | 成人蜜桃| 在线看黄色的网站 | 麻豆成人网 | 日本久久精品 | 国产一区二区成人 | 亚洲综合欧美日韩狠狠色 | 久久视频在线观看中文字幕 | 国产精品欧美久久久久久 | 成人一区二区在线观看 | 日韩欧美在线观看一区二区 | 免费久久网 | 亚洲一区二区三区miaa149 | 日本公乱妇视频 | 久久综合之合合综合久久 | 日韩精品一区二区三区电影 | 日韩欧美在线不卡 | 蜜臀一区二区三区精品免费视频 | 日批视频 | 欧美精品久久久久性色 | 国产xx在线 | 欧美日韩视频在线观看一区二区 | 日本精品中文字幕在线观看 | 亚洲精品视频在 | 日韩精品91偷拍在线观看 | 久久久久在线视频 | 一级精品视频在线观看宜春院 | 五月天丁香综合 | 亚洲精品456在线播放 | 国内视频 | 欧美一区二区三区免费观看 | 青春草免费在线视频 | 日本在线中文在线 | 久久免费一级片 | 久久96国产精品久久99软件 | 国产成人三级 | 国产99久久精品一区二区永久免费 | 黄色视屏在线免费观看 | 免费视频色 | 1000部国产精品成人观看 | 91精品啪在线观看国产 | 黄色小网站在线观看 | 久操97| 亚洲精品高清在线 | 久热电影 | av先锋中文字幕 | 爱爱一区 | 久久国产日韩 | 日韩xxx视频 | 91丨porny丨九色 | 国产视频网站在线观看 | 日日夜夜免费精品视频 | 色婷婷 亚洲 | 一区二区中文字幕在线 | 日韩精品中文字幕一区二区 | 婷婷av网| 久久久久免费精品国产 | 成人a在线观看高清电影 | 欧美日韩国产免费视频 | 五月天久久综合网 | 中文字幕制服丝袜av久久 | 一区二区av | 在线亚洲天堂网 | 成人在线一区二区三区 | 香蕉视频国产在线观看 | 欧美在线视频一区二区三区 | a在线观看国产 | 午夜av片 | 美女视频黄在线观看 | 国产一区在线视频 | 小草av在线播放 | 综合五月婷婷 | 国产成人综 | 毛片随便看 | 日韩电影中文,亚洲精品乱码 | 日本中出在线观看 | 69av视频在线 | 天天色天天骑天天射 | 国产日韩欧美视频在线观看 | 亚洲精品女人 | 午夜黄色大片 | 天天操天天色天天射 | 亚洲激情免费 | 久久乐九色婷婷综合色狠狠182 | www中文在线| 国产视频二 | 中文在线资源 | 日韩av中文字幕在线免费观看 | 日韩乱色精品一区二区 | 超碰97中文 | 免费观看视频黄 | www.色五月.com| 国产成本人视频在线观看 | 国产永久免费 | 91国内产香蕉| 99热精品免费观看 | 亚洲精品久久久蜜臀下载官网 | 亚洲精品免费在线观看视频 | 免费亚洲精品视频 | 久草爱视频 | 91精品在线免费观看视频 | 久久国产成人午夜av影院宅 | 免费观看黄 | 日本久久免费电影 | 国产精品色 | 国产99久久久欧美黑人 | 久久久久黄色 | 狠狠色噜噜狠狠狠 | 国产一级片免费观看 | 在线观看成人小视频 | 久久艹久久 | 在线视频18在线视频4k | 欧美另类美少妇69xxxx | 久久午夜精品 | 国产精品久久久久久妇 | 国产高清在线视频 | 久久精品99视频 | 亚洲精品久久久蜜臀下载官网 | 友田真希x88av | 成人97人人超碰人人99 | av在线最新 | 97精品国产aⅴ | 国产精品一区二区三区免费看 | 91在线色| 一本一道久久a久久综合蜜桃 | 国产成人精品一区二区在线 | www.亚洲黄| 99热999| 天天综合区 | 国产精品亚洲视频 | 中文字幕高清 | 麻豆传媒视频观看 | 亚洲人成人99网站 | 人人插人人舔 | 综合精品久久 | 久久久黄色免费网站 | 色综合久久精品 | 亚洲人人网 | 欧美日韩在线免费观看 | 天天插夜夜操 | 911精品视频| 一区二区不卡视频在线观看 | 国产成人精品综合久久久 | 亚洲成aⅴ人片久久青草影院 | 日韩精品欧美专区 | 精品99免费 | 一区免费视频 | 国产剧情一区二区 | 毛片区 | 97超碰中文字幕 | 性色va| 国产美女视频一区 | 日韩中文在线电影 | ,午夜性刺激免费看视频 | 久久综合久久综合九色 | 中文字幕网址 | 亚州精品天堂中文字幕 | 成人资源在线 | 国产高清在线免费视频 | 成人在线播放免费观看 | 亚洲成aⅴ人在线观看 | 夜夜操综合网 | 3d黄动漫免费看 | 国产玖玖精品视频 | 国内毛片毛片 | 在线视频日韩一区 | 国产精品免费在线视频 | 在线看成人 | 日韩在线视频网站 | 中文字幕在线观看视频免费 | av免费福利 | 欧美日韩国产mv | 国产理伦在线 | 一级片视频在线 | 成人毛片一区 | 久久国产美女视频 | 五月婷网| 久久歪歪| 亚洲国产日韩精品 | 97超视频 | 亚洲深爱激情 | 日韩91在线 | 亚洲国产电影在线观看 | 色五月色开心色婷婷色丁香 | 在线 欧美 日韩 | 丁香九月婷婷 | 日日麻批40分钟视频免费观看 | 国产精品三级视频 | 久久电影国产免费久久电影 | 中文字幕视频网 | 天堂av一区二区 | 中文字幕永久免费 | 蜜臀av性久久久久av蜜臀三区 | 国产aa精品| 日韩国产精品久久 | 久久精品视频观看 | 夜夜操综合网 | av一区在线| 国产精品黄网站在线观看 | 精品在线二区 | 久久九九国产精品 | 99视频国产精品 | 久草热久草视频 | 日日干天天爽 | 久久综合久久八八 | 麻豆视频免费版 | 三级动态视频在线观看 | 三级av在线 | 国产va在线观看免费 | 国产专区视频在线观看 | 中文字幕久久精品亚洲乱码 | 国产精品v a免费视频 | 国产精品videoxxxx | 国产 日韩 欧美 自拍 | 欧美国产日韩久久 | 久久99精品久久久久久久久久久久 | 最近中文字幕大全中文字幕免费 | 欧美在线a视频 | 国产美女黄网站免费 | 亚洲视频免费在线看 | 日韩免费电影网 | 五月婷在线播放 | 国产精品精品国产色婷婷 | 日韩av在线免费看 | 在线播放视频一区 | 中文乱幕日产无线码1区 | 在线av资源 | 国产自制av | 国产精品9999| 欧美日韩亚洲一 | 天天射射天天 | 日韩精品一区二区免费视频 | 中日韩男男gay无套 日韩精品一区二区三区高清免费 | 国产精品久久久久久久7电影 | 色综合小说 | 五月婷婷久久丁香 | 91精品国产99久久久久久久 | 久久兔费看a级 | 丝袜网站在线观看 | 2022久久国产露脸精品国产 | 九九色在线 | 成人91在线 | 91在线观看欧美日韩 | 天天操天天射天天操 | www国产亚洲精品久久网站 | 天堂视频一区 | 男女拍拍免费视频 | 亚洲精品成人av在线 | 国产精品美女久久久久久网站 | 精品视频免费播放 | 久久久国产精品一区二区三区 | 丁香狠狠 | 精品91视频 | 欧美日韩二区三区 | 久久一本综合 | 93久久精品日日躁夜夜躁欧美 | 91日韩精品视频 | 国产精品亚洲成人 | 日本精品视频一区二区 | 插插插色综合 | 91九色精品女同系列 | 三级性生活视频 | 国产成人免费av电影 | 九九国产视频 | 六月天色婷婷 | 免费网站看av片 | 九色porny真实丨国产18 | 1024手机基地在线观看 | 狠狠综合久久av | 国产高清中文字幕 | 久久午夜精品视频 | 黄色一及电影 | 欧美在线观看视频一区二区 | 天天色天天操综合网 | 超碰精品在线 | 久草a视频| 亚洲综合爱 | 久久r精品| 日本黄色a级大片 | 91在线观看高清 | 久久9精品 | 韩国视频一区二区三区 | av网站播放| 日韩久久精品一区二区三区下载 | 国产日本亚洲 | 天天综合精品 | 我要看黄色一级片 | 在线观看中文字幕一区二区 | 亚洲国产精品推荐 | 狠狠狠狠狠狠天天爱 | 九九在线视频 | 日本精油按摩3 | 91免费试看 | 视频在线观看日韩 | 日韩精品高清不卡 | 亚洲国产三级在线 | 黄色av网站在线免费观看 | 日本午夜在线亚洲.国产 | 亚洲一区二区观看 | 亚洲成年片 | 国产黄色片一级 | 久久精品7 | 欧美日韩中文在线观看 | 亚洲在线色 | 日韩三级一区 | 五月综合激情网 | av免费线看 | 99久久精品久久久久久动态片 | 91激情在线视频 | 久久精品理论 | 欧美大荫蒂xxx | 九九三级毛片 | 国产一二区视频 | 日本三级不卡 | 国产精品久久久久久久av大片 | 亚洲欧美日韩精品久久奇米一区 | 亚洲激情国产精品 | 精品久久综合 | 午夜精品一区二区三区可下载 | 亚洲国产午夜视频 | 国产亚洲免费观看 | 亚洲 综合 国产 精品 | 久久免费99精品久久久久久 | 毛片一区二区 | 久久精品伊人 | 国产精品黑丝在线观看 | 1024手机基地在线观看 | 91人人爽人人爽人人精88v | 五月天婷婷在线播放 | 九九视频精品免费 | 欧美永久视频 | 美女国产免费 | 亚洲永久精品视频 | 午夜精品一区二区国产 | 亚洲精品一区二区在线观看 | 久99久视频 | 午夜资源站 | 国产视频一区二区在线观看 | 久久精品www人人爽人人 | 国产精品久久网 | 狠狠狠狠狠狠 | 九九色综合 | 欧美日韩高清在线一区 | 99久久激情| 欧美精品一区二区免费 | 久久久久久久电影 | 精品一区二区6 | 97在线观 | 久久久久成人精品亚洲国产 | 久久www免费人成看片高清 | 久久激情久久 | 激情五月婷婷综合网 | 色狠狠久久av五月综合 | 免费a级观看 | 国产精品毛片一区二区 | 国产91丝袜在线播放动漫 | 国产精品欧美一区二区三区不卡 | 欧美成人h版电影 | 黄色成人av | 国产精品视频app | 日本久久久久久科技有限公司 | 国产美女精品人人做人人爽 | 国产成人av在线 | 丁香婷婷综合激情 | 99re国产 | 天天射,天天干 | 激情黄色av | www激情久久 | 在线观看免费国产小视频 | av女优中文字幕在线观看 | 精品国内| 成人黄色大片在线免费观看 | 奇米四色影狠狠爱7777 | 亚洲第一中文网 | 五月天免费网站 | 超碰在线天天 | 五月天天色 | 精品视频在线免费 | 99精品区 | 在线成人看片 | 激情综合啪 | 91精品在线观看视频 | 国产高清专区 | 超碰电影在线观看 | 久久精品伊人 | 国产一区二区在线免费观看 | 国色天香第二季 | 国产黄网在线 | 在线黄网站 | 亚洲精品国产精品99久久 | 国产成人精品av久久 | 91资源在线视频 | av三级在线看 | 久久刺激视频 | 国产日韩精品在线观看 | 在线免费观看视频你懂的 | 亚洲欧美乱综合图片区小说区 | 亚洲国产天堂av | 久草免费在线 | 久草在线手机观看 | 中文字幕在线国产精品 | 成人一级电影在线观看 | 亚洲色图 校园春色 | 天天操狠狠操夜夜操 | 国产精品久久网 | av在线收看| 欧美日韩免费一区二区三区 | 99视频精品免费观看, | 六月婷色 | 美女av免费看 | 97视频资源| av黄色免费网站 | 久草精品视频在线观看 | 99c视频高清免费观看 | 丁香婷婷久久 | va视频在线 | 色爽网站 | 欧美日韩激情网 | 国产视频日韩视频欧美视频 | 成人国产精品 | 日韩试看| 亚洲欧美日韩精品久久奇米一区 | 日韩有码中文字幕在线 | 国产中文字幕大全 | 国产成人高清在线 | 国产在线中文字幕 | 日韩免费看片 | 国产精品美女久久久久久2018 | 手机看片午夜 | 久久亚洲综合色 | 91av影视 | 亚洲黄网站 | 久久草精品 | 国产中出在线观看 | 狠狠五月天 | 十八岁免进欧美 | 人人玩人人添人人澡超碰 | 国产91精品在线观看 | 免费观看一区 | 久久国产精品精品国产色婷婷 | 欧美日韩久久不卡 | 国产成人精品网站 | 天天干天天射天天插 | 玖玖在线免费视频 | 麻豆视频免费在线 | 欧美一区二区日韩一区二区 | 五月天婷婷狠狠 | 成人av在线看 | 日日爽天天操 | 国产精品无av码在线观看 | 成年人黄色在线观看 | 91麻豆网站 | 在线视频观看成人 | 中文字幕视频一区 | 日本激情动作片免费看 | 日韩v在线 | 视频在线观看国产 | 在线免费高清一区二区三区 | 不卡电影免费在线播放一区 | 正在播放日韩 | 成人激情开心网 | 日韩在线观看影院 | 人人澡人摸人人添学生av | 视频在线观看入口黄最新永久免费国产 | 色视频在线 | 午夜成人免费电影 | 久久免费视频这里只有精品 | 日本大片免费观看在线 | 国产在线美女 | 91视频在线观看免费 | 999久久精品 | 国产精品福利av | 午夜在线观看影院 | 天天射天天干天天爽 | 天天射天天爱天天干 | 欧洲一区二区在线观看 | 美女久久久久久久久久 | 久久亚洲综合色 | 亚洲精品小区久久久久久 | 精品在线看| 久久任你操 | 激情婷婷六月 | 91精品视频在线看 | 国产视频精品网 | 日韩在线观看视频网站 | 18性欧美xxxⅹ性满足 | 久久久久久久久久久综合 | 又黄又刺激的视频 | 久久久久久久久久网站 | 亚洲精品a区 | 草久久av| 九九99| 日韩三级视频在线观看 | 日日夜夜天天综合 | 视频一区二区精品 | 亚洲成人频道 | 亚洲精品国产自产拍在线观看 | 久久久久久久久久影视 | 九九九免费视频 | 色婷婷中文 | 99热这里是精品 | 国产精品孕妇 | 亚洲精品国产成人av在线 | 成人在线免费观看视视频 | 国产又粗又长又硬免费视频 | 日本激情中文字幕 | 成在线播放 | 四虎永久免费 | 中文字幕在线第一页 | 亚洲精品a区 | 黄色免费av | 国产中文视频 | 伊人久久国产 | 欧美日韩免费一区二区 | 免费网址在线播放 | 九九热精品视频在线观看 | 久久久久久久久久久免费视频 | 日本不卡123区 | 久久伦理网 | 视频在线观看99 | 欧美久久久久久久 | 免费观看www视频 | 成人在线小视频 | 一区二区三区免费播放 | 国产精品久久艹 | av在线进入 | 亚洲日本中文字幕在线观看 | 日韩一二三区不卡 | 日本中文字幕免费观看 | 懂色av一区二区在线播放 | 欧美色插 | 国产第一页精品 | 久久久久久国产精品 | 精品久久久久一区二区国产 | av手机版| 日韩成人免费观看 | 国产无遮挡又黄又爽馒头漫画 | 国产剧情av在线播放 | 日韩精品视频第一页 | 黄色的网站免费看 | 成人av电影在线观看 | 亚洲成色 | 91福利试看 | 成人动图 | 丁香六月网 | 狠狠色丁香久久综合网 | 97超碰免费在线观看 | 免费看黄的视频 | 不卡国产视频 | 国产一区二区久久久 | 五月丁婷婷 | 亚洲精品午夜久久久久久久 | wwwwww黄 | 黄色视屏免费在线观看 | 在线观看亚洲免费视频 | 欧美日韩国产一区二区三区 | 91一区二区在线 | 日韩在线视频网站 | www.国产在线视频 | 亚洲片在线资源 | 久久久久久久久毛片精品 | 国产精品免费一区二区三区 | 91插插插网站 | 精品国产成人在线 | 国产96在线观看 | 狠狠色婷婷丁香六月 | 亚洲全部视频 | 国产69精品久久久久99尤 | а天堂中文最新一区二区三区 | 国产1区2区3区精品美女 | 日韩欧美一区二区在线播放 | 国产玖玖在线 | 免费福利片2019潦草影视午夜 | 国产一区二区在线精品 | 国产中文字幕视频在线观看 | 黄色av电影| 欧美日韩高清一区二区 国产亚洲免费看 | 最近日本字幕mv免费观看在线 | 国产精品一区二 | 免费日韩一区二区三区 | 欧美日韩免费在线观看视频 | 欧美成a人片在线观看久 | 天天射天天拍 | 麻豆影视网 | 亚洲一区不卡视频 | 99精品视频在线播放观看 | 国产精品一区二区无线 | 在线a亚洲视频播放在线观看 | 日韩黄色软件 | 三级av网 | 国产在线观看地址 | 久久午夜羞羞影院 | 日韩在线网 | 91视频这里只有精品 | 欧美十八 | 日韩一区二区三区视频在线 | 中文字幕免费成人 | 狠狠干网址 | 五月开心激情 | 日本久久99 | 久久婷综合 | 玖玖视频免费在线 | 国内精品一区二区 | va视频在线观看 | 久久久久久久久艹 | 97免费在线观看视频 | 伊人www22综合色 | 久久久久国产精品厨房 | 久久国产精品99国产 | 99热日本 | 丁香婷婷深情五月亚洲 | 国产高潮久久 | 日日干夜夜骑 | 九九热免费视频在线观看 | 91av在线不卡 | 午夜视频在线观看一区 | jizz999| 久久午夜精品视频 | 91精品欧美 | 久久久久久久久久网站 | 免费视频你懂得 | 国产91在线观看 | 精品国产乱码久久久久久天美 | 中文字幕国产 | 在线国产能看的 | 亚洲成人影音 | 成人一级在线观看 | 国产一区二区在线看 | 91亚洲精品乱码久久久久久蜜桃 | 欧美成人精品欧美一级乱 | 91麻豆精品91久久久久同性 | 香蕉视频最新网址 | 国产色在线,com | 欧美a√在线 | 中文字幕中文字幕在线中文字幕三区 | 国产剧情一区二区在线观看 | 亚洲另类视频在线观看 | 亚洲精品国产综合99久久夜夜嗨 | 99日精品 | 在线视频国产区 | 国产精品久久久久久欧美 | 狠狠操天天射 | 色资源二区在线视频 | 免费观看成年人视频 | 日韩经典一区二区三区 | 久久精品美女 | 99在线观看 | 免费黄色av电影 | 久久久精品 一区二区三区 国产99视频在线观看 | 成人黄色毛片视频 | 国产永久网站 | 超碰最新网址 | 日本三级不卡视频 | 天天久久夜夜 | 激情在线免费视频 | 国产成人精品一区在线 | 久久精品美女视频网站 | 婷婷深爱| 97人人模人人爽人人少妇 | 91在线入口| 日韩大片在线免费观看 | 韩日精品在线 | 黄色网址中文字幕 | 中文字幕中文字幕在线一区 | 福利久久久 | 国产精品久久久精品 | 成人全视频免费观看在线看 | 2018好看的中文在线观看 | 中文乱码视频在线观看 | 国产精品综合久久久久 | 韩日视频在线 | 91网址在线 | 狠狠操狠狠插 | 亚洲精品在线观看网站 | 日韩精品在线视频免费观看 | 91在线视频免费观看 | 黄网站色视频 | 成人在线视 | 黄色网址a| 91毛片在线| 毛片3 | 亚洲高清久久久 | 天天干,天天操 | 丰满少妇在线观看 | 99视频这里只有 | 国产精品女人网站 | 免费下载高清毛片 | 奇米网8888 | 亚洲激情影院 | 午夜久久影视 | 少妇bbb搡bbbb搡bbbb | 亚洲影视九九影院在线观看 | 久久国产精品久久国产精品 | 国产精品成 | 午夜三级在线 | 精品99久久 | 麻豆视频免费在线播放 | 中文字幕精 | 日韩久久精品一区二区三区 | 日韩精品视频免费在线观看 | 久色网| 狂野欧美激情性xxxx | 日韩综合一区二区 | 久草在线视频首页 | 免费在线观看不卡av | 国产精品久久久久久一二三四五 | 在线视频观看你懂的 | 91精品一区二区三区久久久久久 | 亚洲一区二区视频 | 射九九 | 国产精品剧情 | 99视频在线看| 久草精品视频在线看网站免费 | 五月激情电影 | a级国产乱理论片在线观看 特级毛片在线观看 | 91热爆视频 | 精品亚洲网| 日韩区欧美久久久无人区 | 国产精品 日韩 | 亚洲国产精品一区二区久久,亚洲午夜 | 91网址在线看 | 99久久久久久久久久 | 高潮毛片无遮挡高清免费 | 日日日日| 91大神精品视频在线观看 | 四虎在线永久免费观看 | 97超碰人人澡人人爱 | www.com黄色| 啪啪动态视频 | 亚洲日本色| 久久国产经典 | 久久婷亚洲五月一区天天躁 | 二区三区在线 | 成人亚洲欧美 | 91亚洲视频在线观看 | 96精品高清视频在线观看软件特色 | 日日夜夜天天干 | 91精品视频在线看 | 免费电影一区二区三区 | 手机在线黄色网址 |