rautomation 0.9.2 → 0.9.3

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 748478d3036c775c96382a911bccd9e8253ef1ac
4
- data.tar.gz: e7bf598b813dd955fcbea0c2d50f143159a06380
3
+ metadata.gz: d5f0b5a12282ceff2cdd88c9851065c7e3785a51
4
+ data.tar.gz: f4de36829f09d006d979165664cd9c679cbe8bcc
5
5
  SHA512:
6
- metadata.gz: b391f11900769761f78426e9ba26029b08cad3e2c68723ab32cf64026611697db96e6dfdefb93e875ecc21045ba24005b56ddfc53b56e4e7215ea389b1e8d256
7
- data.tar.gz: 623f4f71ac5c00c18524a1bb151a5b80e2a86a3745253f6887ba85ff929acb70f1eec5662acc86b469895ffde75b64811cdfd973528ec64a900fd5ef7bd7a2c0
6
+ metadata.gz: 6f8b6e450dff617cb3a1b1b372d3319c45a3f86117c701971753959b22ed5cf05a7046fc082355ff51c510f79403d4ec6b805507b22c31266077d1fc7ea7188d
7
+ data.tar.gz: 375e1b71b72b399694cdc306a3e0f877c8974f68ab77d7d99c411b4f82589c3ee3b713ef83fdffe5c57d95de69b929072a4d88317fa85dac01b5eabf405deea3
data/Gemfile.lock CHANGED
@@ -1,7 +1,7 @@
1
1
  PATH
2
2
  remote: .
3
3
  specs:
4
- rautomation (0.9.2)
4
+ rautomation (0.9.3)
5
5
  ffi
6
6
 
7
7
  GEM
data/History.rdoc CHANGED
@@ -1,3 +1,9 @@
1
+ == 0.9.3
2
+
3
+ === MsUia adapter
4
+ * Added the ability to limit the scope to children only when looking for a control
5
+ * Fixed issues with ListBox controls not firing index change events
6
+
1
7
  == 0.9.2 / 2013-05-19
2
8
 
3
9
  === Win32 adapter
data/README.rdoc CHANGED
@@ -57,8 +57,8 @@ Check out the documentation for other possible usages!
57
57
 
58
58
  Available adapters:
59
59
  * :win_32 - uses Windows API directly with FFI (default)
60
- * :autoit - uses AutoIt for automation
61
60
  * :ms_uia - an experimental adapter
61
+ * :autoit - uses AutoIt for automation (DEPRECATED)
62
62
 
63
63
  When using AutoIt adapter:
64
64
  You might need administrative privileges if running for the first time and you haven't installed AutoIt before!
data/VERSION CHANGED
@@ -1 +1 @@
1
- 0.9.2
1
+ 0.9.3
Binary file
@@ -20,68 +20,74 @@ array<String^>^ AutomatedSelectList::Selection::get() {
20
20
  int AutomatedSelectList::GetOptions(const char* options[]) {
21
21
  auto selectionItems = SelectionItems;
22
22
 
23
- if( NULL != options ) {
24
- StringHelper::CopyNames(selectionItems, options);
25
- }
23
+ if( NULL != options ) {
24
+ StringHelper::CopyNames(selectionItems, options);
25
+ }
26
26
 
27
- return selectionItems->Count;
27
+ return selectionItems->Count;
28
28
  }
29
29
 
30
30
  bool AutomatedSelectList::SelectByIndex(const int whichItem)
31
31
  {
32
- try {
33
- auto selectionItems = _control->FindAll(System::Windows::Automation::TreeScope::Subtree, SelectionCondition);
34
- Select(selectionItems[whichItem]);
35
- return true;
36
- } catch(Exception^ e) {
37
- Console::WriteLine(e->ToString());
38
- return false;
39
- }
32
+ try {
33
+ auto selectionItems = _control->FindAll(System::Windows::Automation::TreeScope::Subtree, SelectionCondition);
34
+ Select(selectionItems[whichItem]);
35
+ return true;
36
+ } catch(Exception^ e) {
37
+ Console::WriteLine(e->ToString());
38
+ return false;
39
+ }
40
40
  }
41
41
 
42
42
  bool AutomatedSelectList::SelectByValue(const char* whichItem)
43
43
  {
44
- try {
45
- auto nameCondition = gcnew PropertyCondition(AutomationElement::NameProperty, gcnew String(whichItem));
46
- auto selectionAndNameCondition = gcnew AndCondition(SelectionCondition, nameCondition);
47
-
48
- Select(_control->FindFirst(System::Windows::Automation::TreeScope::Subtree, selectionAndNameCondition));
49
- return true;
50
- } catch(Exception^ e) {
51
- Console::WriteLine(e->ToString());
52
- return false;
53
- }
44
+ try {
45
+ auto nameCondition = gcnew PropertyCondition(AutomationElement::NameProperty, gcnew String(whichItem));
46
+ auto selectionAndNameCondition = gcnew AndCondition(SelectionCondition, nameCondition);
47
+
48
+ Select(_control->FindFirst(System::Windows::Automation::TreeScope::Subtree, selectionAndNameCondition));
49
+ return true;
50
+ } catch(Exception^ e) {
51
+ Console::WriteLine(e->ToString());
52
+ return false;
53
+ }
54
54
  }
55
55
 
56
56
  bool AutomatedSelectList::GetValueByIndex(const int whichItem, char* comboValue, const int comboValueSize)
57
57
  {
58
- try {
59
- auto selectionItem = SelectionItems[whichItem];
60
- auto nameProperty = dynamic_cast<String^>(selectionItem->GetCurrentPropertyValue(AutomationElement::NameProperty));
61
-
62
- StringHelper::CopyToUnmanagedString(nameProperty, comboValue, comboValueSize);
63
- return true;
64
- } catch(Exception^ e) {
65
- Console::WriteLine(e->ToString());
66
- return false;
67
- }
58
+ try {
59
+ auto selectionItem = SelectionItems[whichItem];
60
+ auto nameProperty = dynamic_cast<String^>(selectionItem->GetCurrentPropertyValue(AutomationElement::NameProperty));
61
+
62
+ StringHelper::CopyToUnmanagedString(nameProperty, comboValue, comboValueSize);
63
+ return true;
64
+ } catch(Exception^ e) {
65
+ Console::WriteLine(e->ToString());
66
+ return false;
67
+ }
68
68
  }
69
69
 
70
70
  int AutomatedSelectList::SelectedIndex::get() {
71
- int selectedIndex = 0;
72
- for each(AutomationElement^ selectionItem in SelectionItems) {
73
- auto selectionPattern = dynamic_cast<SelectionItemPattern^>(selectionItem->GetCurrentPattern(SelectionItemPattern::Pattern));
74
- if( selectionPattern->Current.IsSelected ) {
75
- return selectedIndex;
76
- }
77
- ++selectedIndex;
78
- }
79
- return -1;
71
+ int selectedIndex = 0;
72
+ for each(AutomationElement^ selectionItem in SelectionItems) {
73
+ auto selectionPattern = dynamic_cast<SelectionItemPattern^>(selectionItem->GetCurrentPattern(SelectionItemPattern::Pattern));
74
+ if( selectionPattern->Current.IsSelected ) {
75
+ return selectedIndex;
76
+ }
77
+ ++selectedIndex;
78
+ }
79
+ return -1;
80
80
  }
81
81
 
82
82
 
83
83
  void AutomatedSelectList::Select(AutomationElement^ itemToSelect)
84
84
  {
85
- auto selectionPattern = dynamic_cast<SelectionItemPattern^>(itemToSelect->GetCurrentPattern(SelectionItemPattern::Pattern));
86
- selectionPattern->Select();
85
+ auto selectionPattern = dynamic_cast<SelectionItemPattern^>(itemToSelect->GetCurrentPattern(SelectionItemPattern::Pattern));
86
+
87
+ try {
88
+ AutomationClicker::MouseClickOn(itemToSelect);
89
+ } catch(Exception^) {}
90
+
91
+ if( !selectionPattern->Current.IsSelected )
92
+ selectionPattern->Select();
87
93
  }
@@ -1,5 +1,6 @@
1
1
  #pragma once
2
2
  #include "AutomationControl.h"
3
+ #include "AutomationClicker.h"
3
4
  #include "StringHelper.h"
4
5
 
5
6
  using namespace System::Windows::Automation;
@@ -10,9 +10,14 @@ ref class AutomationClicker : AutomationControl
10
10
  public:
11
11
  AutomationClicker(const HWND windowHandle) : AutomationControl(windowHandle) {}
12
12
  AutomationClicker(const FindInformation& findInformation) : AutomationControl(findInformation) {}
13
+ AutomationClicker(AutomationElement^ automationElement) : AutomationControl(automationElement) {}
13
14
  bool Click();
14
15
  void MouseClick();
15
16
 
17
+ static void MouseClickOn(AutomationElement^ automationElement) {
18
+ (gcnew AutomationClicker(automationElement))->MouseClick();
19
+ }
20
+
16
21
  private:
17
22
  bool CanInvoke();
18
23
  void Invoke();
@@ -19,6 +19,10 @@ AutomationControl::AutomationControl(const FindInformation& findInformation)
19
19
  }
20
20
  }
21
21
 
22
+ AutomationControl::AutomationControl(AutomationElement^ automationElement) {
23
+ _control = automationElement;
24
+ }
25
+
22
26
  void AutomationControl::Value::set(String^ value) {
23
27
  AsValuePattern->SetValue(value);
24
28
  }
@@ -9,6 +9,7 @@ ref class AutomationControl
9
9
  public:
10
10
  AutomationControl(const HWND windowHandle);
11
11
  AutomationControl(const FindInformation& findInformation);
12
+ AutomationControl(AutomationElement^ automationElement);
12
13
 
13
14
  property AutomationElement^ Element {
14
15
  AutomationElement^ get() { return _control; }
@@ -8,26 +8,47 @@ AutomationFinder::AutomationFinder(AutomationElement^ automationElement)
8
8
 
9
9
  AutomationElementCollection^ AutomationFinder::Find(...array<Condition^>^ conditions)
10
10
  {
11
- return _automationElement->FindAll(System::Windows::Automation::TreeScope::Subtree, SomethingOrEverything(conditions));
11
+ return Find(Subtree, conditions);
12
+ }
13
+
14
+ AutomationElementCollection^ AutomationFinder::Find(const UIAutomation::TreeScope scope, ...array<Condition^>^ conditions)
15
+ {
16
+ return _automationElement->FindAll(scope, SomethingOrEverything(conditions));
12
17
  }
13
18
 
14
19
  AutomationElement^ AutomationFinder::FindFirst(...array<Condition^>^ conditions)
15
20
  {
16
- return _automationElement->FindFirst(System::Windows::Automation::TreeScope::Subtree, SomethingOrEverything(conditions));
21
+ return FindFirst(Subtree, conditions);
22
+ }
23
+
24
+ AutomationElement^ AutomationFinder::FindFirst(const UIAutomation::TreeScope scope, ...array<Condition^>^ conditions)
25
+ {
26
+ return _automationElement->FindFirst(scope, SomethingOrEverything(conditions));
17
27
  }
18
28
 
19
29
  AutomationElement^ AutomationFinder::Find(const FindInformation& findInformation)
20
30
  {
31
+ auto scope = findInformation.onlySearchChildren ? Children : Subtree;
32
+
21
33
  switch(findInformation.how) {
22
34
  case FindMethod::Id:
23
35
  {
24
36
  auto searchCondition = gcnew PropertyCondition(AutomationElement::AutomationIdProperty, gcnew String(findInformation.data.stringData));
25
- return FindAt(findInformation.index, searchCondition);
37
+ if( 0 == findInformation.index ) {
38
+ return FindFirst(scope, searchCondition);
39
+ }
40
+
41
+ return FindAt(scope, findInformation.index, searchCondition);
26
42
  }
27
43
  case FindMethod::Value:
28
44
  {
29
45
  auto searchCondition = gcnew PropertyCondition(AutomationElement::NameProperty, gcnew String(findInformation.data.stringData));
30
- return FindAt(findInformation.index, searchCondition);
46
+
47
+ if( 0 == findInformation.index ) {
48
+ return FindFirst(scope, searchCondition);
49
+ }
50
+
51
+ return FindAt(scope, findInformation.index, searchCondition);
31
52
  }
32
53
  case FindMethod::Focus:
33
54
  return AutomationElement::FocusedElement;
@@ -42,7 +63,12 @@ AutomationElement^ AutomationFinder::Find(const FindInformation& findInformation
42
63
 
43
64
  AutomationElement^ AutomationFinder::FindAt(const int whichItem, ...array<Condition^>^ conditions)
44
65
  {
45
- return Find(conditions)[whichItem];
66
+ return FindAt(Subtree, whichItem, conditions);
67
+ }
68
+
69
+ AutomationElement^ AutomationFinder::FindAt(const UIAutomation::TreeScope scope, const int whichItem, ...array<Condition^>^ conditions)
70
+ {
71
+ return Find(scope, conditions)[whichItem];
46
72
  }
47
73
 
48
74
  Condition^ AutomationFinder::SomethingOrEverything(...array<Condition^>^ conditions)
@@ -6,10 +6,13 @@ ref class AutomationFinder
6
6
  {
7
7
  public:
8
8
  AutomationFinder(AutomationElement^ automationElement);
9
- AutomationElementCollection^ Find(...array<Condition^>^ conditions);
10
9
  AutomationElement^ Find(const FindInformation& findInformation);
10
+ AutomationElementCollection^ Find(...array<Condition^>^ conditions);
11
+ AutomationElementCollection^ Find(const UIAutomation::TreeScope scope, ...array<Condition^>^ conditions);
11
12
  AutomationElement^ FindFirst(...array<Condition^>^ conditions);
13
+ AutomationElement^ FindFirst(const UIAutomation::TreeScope scope, ...array<Condition^>^ conditions);
12
14
  AutomationElement^ FindAt(const int whichItem, ...array<Condition^>^ conditions);
15
+ AutomationElement^ FindAt(const UIAutomation::TreeScope scope, const int whichItem, ...array<Condition^>^ conditions);
13
16
 
14
17
  static property Condition^ IsSelectionItem {
15
18
  Condition^ get() {
@@ -42,6 +45,8 @@ public:
42
45
  }
43
46
 
44
47
  private:
48
+ static UIAutomation::TreeScope Subtree = UIAutomation::TreeScope::Subtree;
49
+ static UIAutomation::TreeScope Children = UIAutomation::TreeScope::Children;
45
50
  AutomationElement^ _automationElement;
46
51
  Condition^ SomethingOrEverything(...array<Condition^>^ conditions);
47
52
  };
@@ -20,6 +20,7 @@
20
20
 
21
21
  using namespace System;
22
22
  using namespace System::Runtime::InteropServices;
23
+ namespace UIAutomation = System::Windows::Automation;
23
24
 
24
25
  typedef enum {
25
26
  Handle = 1,
@@ -32,6 +33,7 @@ typedef enum {
32
33
  typedef struct _FindInformation {
33
34
  HWND rootWindow;
34
35
  int index;
36
+ bool onlySearchChildren;
35
37
  FindMethod how;
36
38
  union {
37
39
  char stringData[256];
@@ -98,6 +98,7 @@
98
98
  this.personListView.TabIndex = 0;
99
99
  this.personListView.UseCompatibleStateImageBehavior = false;
100
100
  this.personListView.View = System.Windows.Forms.View.Details;
101
+ this.personListView.SelectedIndexChanged += new System.EventHandler(this.personListView_SelectedIndexChanged);
101
102
  //
102
103
  // columnName
103
104
  //
@@ -42,5 +42,10 @@ namespace WindowsForms
42
42
  }
43
43
  }
44
44
 
45
+ private void personListView_SelectedIndexChanged(object sender, EventArgs e)
46
+ {
47
+
48
+ }
49
+
45
50
  }
46
51
  }
@@ -0,0 +1,77 @@
1
+ namespace WindowsForms
2
+ {
3
+ partial class DataGridView
4
+ {
5
+ /// <summary>
6
+ /// Required designer variable.
7
+ /// </summary>
8
+ private System.ComponentModel.IContainer components = null;
9
+
10
+ /// <summary>
11
+ /// Clean up any resources being used.
12
+ /// </summary>
13
+ /// <param name="disposing">true if managed resources should be disposed; otherwise, false.</param>
14
+ protected override void Dispose(bool disposing)
15
+ {
16
+ if (disposing && (components != null))
17
+ {
18
+ components.Dispose();
19
+ }
20
+ base.Dispose(disposing);
21
+ }
22
+
23
+ #region Windows Form Designer generated code
24
+
25
+ /// <summary>
26
+ /// Required method for Designer support - do not modify
27
+ /// the contents of this method with the code editor.
28
+ /// </summary>
29
+ private void InitializeComponent()
30
+ {
31
+ this.buttonClose = new System.Windows.Forms.Button();
32
+ this.dataGridView1 = new System.Windows.Forms.DataGridView();
33
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).BeginInit();
34
+ this.SuspendLayout();
35
+ //
36
+ // buttonClose
37
+ //
38
+ this.buttonClose.Location = new System.Drawing.Point(13, 13);
39
+ this.buttonClose.Name = "buttonClose";
40
+ this.buttonClose.Size = new System.Drawing.Size(75, 23);
41
+ this.buttonClose.TabIndex = 0;
42
+ this.buttonClose.Text = "Close";
43
+ this.buttonClose.UseVisualStyleBackColor = true;
44
+ this.buttonClose.Click += new System.EventHandler(this.buttonClose_Click);
45
+ //
46
+ // dataGridView1
47
+ //
48
+ this.dataGridView1.Anchor = ((System.Windows.Forms.AnchorStyles)((((System.Windows.Forms.AnchorStyles.Top | System.Windows.Forms.AnchorStyles.Bottom)
49
+ | System.Windows.Forms.AnchorStyles.Left)
50
+ | System.Windows.Forms.AnchorStyles.Right)));
51
+ this.dataGridView1.ColumnHeadersHeightSizeMode = System.Windows.Forms.DataGridViewColumnHeadersHeightSizeMode.AutoSize;
52
+ this.dataGridView1.Location = new System.Drawing.Point(13, 56);
53
+ this.dataGridView1.Name = "dataGridView1";
54
+ this.dataGridView1.Size = new System.Drawing.Size(641, 190);
55
+ this.dataGridView1.TabIndex = 1;
56
+ //
57
+ // DataGridView
58
+ //
59
+ this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
60
+ this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
61
+ this.ClientSize = new System.Drawing.Size(666, 258);
62
+ this.Controls.Add(this.dataGridView1);
63
+ this.Controls.Add(this.buttonClose);
64
+ this.Name = "DataGridView";
65
+ this.Text = "DataGridView";
66
+ this.Load += new System.EventHandler(this.DataGridView_Load);
67
+ ((System.ComponentModel.ISupportInitialize)(this.dataGridView1)).EndInit();
68
+ this.ResumeLayout(false);
69
+
70
+ }
71
+
72
+ #endregion
73
+
74
+ private System.Windows.Forms.Button buttonClose;
75
+ private System.Windows.Forms.DataGridView dataGridView1;
76
+ }
77
+ }
@@ -0,0 +1,42 @@
1
+ using System;
2
+ using System.Linq;
3
+ using System.Windows.Forms;
4
+ using FizzWare.NBuilder;
5
+
6
+ namespace WindowsForms
7
+ {
8
+ public partial class DataGridView : Form
9
+ {
10
+ public DataGridView()
11
+ {
12
+ InitializeComponent();
13
+ }
14
+
15
+ public class Person
16
+ {
17
+ // ReSharper disable UnusedMember.Local
18
+ public String FirstName { get; set; }
19
+ public String LastName { get; set; }
20
+ public int Age { get; set; }
21
+ public String City { get; set; }
22
+ public String State { get; set; }
23
+ // ReSharper restore UnusedMember.Local
24
+ }
25
+
26
+ private void DataGridView_Load(object sender, EventArgs e)
27
+ {
28
+ var dataSource = new BindingSource();
29
+ foreach (var person in Builder<Person>.CreateListOfSize(50).Build())
30
+ {
31
+ dataSource.Add(person);
32
+ }
33
+ dataGridView1.AutoGenerateColumns = true;
34
+ dataGridView1.DataSource = dataSource;
35
+ }
36
+
37
+ private void buttonClose_Click(object sender, EventArgs e)
38
+ {
39
+ Close();
40
+ }
41
+ }
42
+ }
@@ -0,0 +1,120 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <root>
3
+ <!--
4
+ Microsoft ResX Schema
5
+
6
+ Version 2.0
7
+
8
+ The primary goals of this format is to allow a simple XML format
9
+ that is mostly human readable. The generation and parsing of the
10
+ various data types are done through the TypeConverter classes
11
+ associated with the data types.
12
+
13
+ Example:
14
+
15
+ ... ado.net/XML headers & schema ...
16
+ <resheader name="resmimetype">text/microsoft-resx</resheader>
17
+ <resheader name="version">2.0</resheader>
18
+ <resheader name="reader">System.Resources.ResXResourceReader, System.Windows.Forms, ...</resheader>
19
+ <resheader name="writer">System.Resources.ResXResourceWriter, System.Windows.Forms, ...</resheader>
20
+ <data name="Name1"><value>this is my long string</value><comment>this is a comment</comment></data>
21
+ <data name="Color1" type="System.Drawing.Color, System.Drawing">Blue</data>
22
+ <data name="Bitmap1" mimetype="application/x-microsoft.net.object.binary.base64">
23
+ <value>[base64 mime encoded serialized .NET Framework object]</value>
24
+ </data>
25
+ <data name="Icon1" type="System.Drawing.Icon, System.Drawing" mimetype="application/x-microsoft.net.object.bytearray.base64">
26
+ <value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
27
+ <comment>This is a comment</comment>
28
+ </data>
29
+
30
+ There are any number of "resheader" rows that contain simple
31
+ name/value pairs.
32
+
33
+ Each data row contains a name, and value. The row also contains a
34
+ type or mimetype. Type corresponds to a .NET class that support
35
+ text/value conversion through the TypeConverter architecture.
36
+ Classes that don't support this are serialized and stored with the
37
+ mimetype set.
38
+
39
+ The mimetype is used for serialized objects, and tells the
40
+ ResXResourceReader how to depersist the object. This is currently not
41
+ extensible. For a given mimetype the value must be set accordingly:
42
+
43
+ Note - application/x-microsoft.net.object.binary.base64 is the format
44
+ that the ResXResourceWriter will generate, however the reader can
45
+ read any of the formats listed below.
46
+
47
+ mimetype: application/x-microsoft.net.object.binary.base64
48
+ value : The object must be serialized with
49
+ : System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
50
+ : and then encoded with base64 encoding.
51
+
52
+ mimetype: application/x-microsoft.net.object.soap.base64
53
+ value : The object must be serialized with
54
+ : System.Runtime.Serialization.Formatters.Soap.SoapFormatter
55
+ : and then encoded with base64 encoding.
56
+
57
+ mimetype: application/x-microsoft.net.object.bytearray.base64
58
+ value : The object must be serialized into a byte array
59
+ : using a System.ComponentModel.TypeConverter
60
+ : and then encoded with base64 encoding.
61
+ -->
62
+ <xsd:schema id="root" xmlns="" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:msdata="urn:schemas-microsoft-com:xml-msdata">
63
+ <xsd:import namespace="http://www.w3.org/XML/1998/namespace" />
64
+ <xsd:element name="root" msdata:IsDataSet="true">
65
+ <xsd:complexType>
66
+ <xsd:choice maxOccurs="unbounded">
67
+ <xsd:element name="metadata">
68
+ <xsd:complexType>
69
+ <xsd:sequence>
70
+ <xsd:element name="value" type="xsd:string" minOccurs="0" />
71
+ </xsd:sequence>
72
+ <xsd:attribute name="name" use="required" type="xsd:string" />
73
+ <xsd:attribute name="type" type="xsd:string" />
74
+ <xsd:attribute name="mimetype" type="xsd:string" />
75
+ <xsd:attribute ref="xml:space" />
76
+ </xsd:complexType>
77
+ </xsd:element>
78
+ <xsd:element name="assembly">
79
+ <xsd:complexType>
80
+ <xsd:attribute name="alias" type="xsd:string" />
81
+ <xsd:attribute name="name" type="xsd:string" />
82
+ </xsd:complexType>
83
+ </xsd:element>
84
+ <xsd:element name="data">
85
+ <xsd:complexType>
86
+ <xsd:sequence>
87
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
88
+ <xsd:element name="comment" type="xsd:string" minOccurs="0" msdata:Ordinal="2" />
89
+ </xsd:sequence>
90
+ <xsd:attribute name="name" type="xsd:string" use="required" msdata:Ordinal="1" />
91
+ <xsd:attribute name="type" type="xsd:string" msdata:Ordinal="3" />
92
+ <xsd:attribute name="mimetype" type="xsd:string" msdata:Ordinal="4" />
93
+ <xsd:attribute ref="xml:space" />
94
+ </xsd:complexType>
95
+ </xsd:element>
96
+ <xsd:element name="resheader">
97
+ <xsd:complexType>
98
+ <xsd:sequence>
99
+ <xsd:element name="value" type="xsd:string" minOccurs="0" msdata:Ordinal="1" />
100
+ </xsd:sequence>
101
+ <xsd:attribute name="name" type="xsd:string" use="required" />
102
+ </xsd:complexType>
103
+ </xsd:element>
104
+ </xsd:choice>
105
+ </xsd:complexType>
106
+ </xsd:element>
107
+ </xsd:schema>
108
+ <resheader name="resmimetype">
109
+ <value>text/microsoft-resx</value>
110
+ </resheader>
111
+ <resheader name="version">
112
+ <value>2.0</value>
113
+ </resheader>
114
+ <resheader name="reader">
115
+ <value>System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
116
+ </resheader>
117
+ <resheader name="writer">
118
+ <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
119
+ </resheader>
120
+ </root>
@@ -68,6 +68,7 @@
68
68
  this.aboutToolStripMenuItem1 = new System.Windows.Forms.ToolStripMenuItem();
69
69
  this.treeView = new System.Windows.Forms.TreeView();
70
70
  this.multiLineTextField = new System.Windows.Forms.TextBox();
71
+ this.buttonDataGridView = new System.Windows.Forms.Button();
71
72
  this.automatableMonthCalendar1 = new WindowsForms.AutomatableMonthCalendar();
72
73
  this.groupBox1.SuspendLayout();
73
74
  this.groupBox2.SuspendLayout();
@@ -336,6 +337,7 @@
336
337
  this.FruitListBox.Name = "FruitListBox";
337
338
  this.FruitListBox.Size = new System.Drawing.Size(159, 95);
338
339
  this.FruitListBox.TabIndex = 14;
340
+ this.FruitListBox.SelectedIndexChanged += new System.EventHandler(this.FruitListBox_SelectedIndexChanged);
339
341
  //
340
342
  // menuStrip1
341
343
  //
@@ -414,19 +416,29 @@
414
416
  this.multiLineTextField.Size = new System.Drawing.Size(325, 123);
415
417
  this.multiLineTextField.TabIndex = 5;
416
418
  //
419
+ // buttonDataGridView
420
+ //
421
+ this.buttonDataGridView.Location = new System.Drawing.Point(12, 152);
422
+ this.buttonDataGridView.Name = "buttonDataGridView";
423
+ this.buttonDataGridView.Size = new System.Drawing.Size(95, 23);
424
+ this.buttonDataGridView.TabIndex = 18;
425
+ this.buttonDataGridView.Text = "Data Grid View";
426
+ this.buttonDataGridView.UseVisualStyleBackColor = true;
427
+ this.buttonDataGridView.Click += new System.EventHandler(this.buttonDataGridView_Click);
428
+ //
417
429
  // automatableMonthCalendar1
418
430
  //
419
431
  this.automatableMonthCalendar1.Location = new System.Drawing.Point(142, 474);
420
432
  this.automatableMonthCalendar1.MaxSelectionCount = 1;
421
433
  this.automatableMonthCalendar1.Name = "automatableMonthCalendar1";
422
434
  this.automatableMonthCalendar1.TabIndex = 17;
423
- this.automatableMonthCalendar1.DateChanged += new System.Windows.Forms.DateRangeEventHandler(this.automatableMonthCalendar1_DateChanged);
424
435
  //
425
436
  // MainFormWindow
426
437
  //
427
438
  this.AutoScaleDimensions = new System.Drawing.SizeF(6F, 13F);
428
439
  this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font;
429
440
  this.ClientSize = new System.Drawing.Size(657, 657);
441
+ this.Controls.Add(this.buttonDataGridView);
430
442
  this.Controls.Add(this.automatableMonthCalendar1);
431
443
  this.Controls.Add(this.multiLineTextField);
432
444
  this.Controls.Add(this.treeView);
@@ -495,7 +507,8 @@
495
507
  private System.Windows.Forms.ToolStripMenuItem aboutToolStripMenuItem1;
496
508
  private System.Windows.Forms.TreeView treeView;
497
509
  private System.Windows.Forms.TextBox multiLineTextField;
498
- private AutomatableMonthCalendar automatableMonthCalendar1;
510
+ private AutomatableMonthCalendar automatableMonthCalendar1;
511
+ private System.Windows.Forms.Button buttonDataGridView;
499
512
  }
500
513
  }
501
514
 
@@ -1,87 +1,78 @@
1
- using System;
2
- using System.Collections.Generic;
3
- using System.ComponentModel;
4
- using System.Data;
5
- using System.Drawing;
6
- using System.Linq;
7
- using System.Text;
8
- using System.Windows.Forms;
9
-
10
- namespace WindowsForms
11
- {
12
- public partial class MainFormWindow : Form
13
- {
14
- public MainFormWindow()
15
- {
16
- InitializeComponent();
17
- }
18
-
19
- private void label1_Click(object sender, EventArgs e)
20
- {
21
-
22
- }
23
-
24
- private void aboutButton_Click(object sender, EventArgs e)
25
- {
26
- AboutBox aboutBox = new AboutBox();
27
- aboutBox.Show();
28
- }
29
-
30
- private void button1_Click(object sender, EventArgs e)
31
- {
32
- this.Close();
33
- }
34
-
35
- private void checkBox_CheckedChanged(object sender, EventArgs e)
36
- {
37
- if (checkBox.Checked == true)
38
- checkBoxLabel.Text = "checkBox is on";
39
- else
40
- checkBoxLabel.Text = "checkBox is off";
41
- }
42
-
43
- private void radioButton1_CheckedChanged(object sender, EventArgs e)
44
- {
45
- radioButtonLabel.Text = "Option 1 selected";
46
- }
47
-
48
- private void radioButton2_CheckedChanged(object sender, EventArgs e)
49
- {
50
- radioButtonLabel.Text = "Option 2 selected";
51
- }
52
-
53
- private void radioButtonReset_Click(object sender, EventArgs e)
54
- {
55
- radioButton1.Checked = false;
56
- radioButton2.Checked = false;
57
- radioButtonLabel.Text = "No option selected";
58
- }
59
-
60
- private void FruitsComboBox_SelectedIndexChanged(object sender, EventArgs e)
61
- {
62
- fruitsLabel.Text = FruitsComboBox.Text;
63
- }
64
-
65
- private void nextFormButton_Click(object sender, EventArgs e)
66
- {
67
- DataEntryForm form = new DataEntryForm();
68
- form.Show();
69
- }
70
-
71
- private void buttonButton_Click(object sender, EventArgs e)
72
- {
73
- SimpleElementsForm buttonForm = new SimpleElementsForm();
74
- buttonForm.Show();
1
+ using System;
2
+ using System.Windows.Forms;
3
+
4
+ namespace WindowsForms
5
+ {
6
+ public partial class MainFormWindow : Form
7
+ {
8
+ public MainFormWindow()
9
+ {
10
+ InitializeComponent();
11
+ }
12
+
13
+ private void label1_Click(object sender, EventArgs e)
14
+ {
15
+
16
+ }
17
+
18
+ private void aboutButton_Click(object sender, EventArgs e)
19
+ {
20
+ var aboutBox = new AboutBox();
21
+ aboutBox.Show();
22
+ }
23
+
24
+ private void button1_Click(object sender, EventArgs e)
25
+ {
26
+ Close();
27
+ }
28
+
29
+ private void checkBox_CheckedChanged(object sender, EventArgs e)
30
+ {
31
+ checkBoxLabel.Text = checkBox.Checked ? "checkBox is on" : "checkBox is off";
32
+ }
33
+
34
+ private void radioButton1_CheckedChanged(object sender, EventArgs e)
35
+ {
36
+ radioButtonLabel.Text = "Option 1 selected";
37
+ }
38
+
39
+ private void radioButton2_CheckedChanged(object sender, EventArgs e)
40
+ {
41
+ radioButtonLabel.Text = "Option 2 selected";
42
+ }
43
+
44
+ private void radioButtonReset_Click(object sender, EventArgs e)
45
+ {
46
+ radioButton1.Checked = false;
47
+ radioButton2.Checked = false;
48
+ radioButtonLabel.Text = "No option selected";
75
49
  }
76
50
 
77
- private void dateTimePicker1_ValueChanged(object sender, EventArgs e)
51
+ private void FruitsComboBox_SelectedIndexChanged(object sender, EventArgs e)
78
52
  {
53
+ fruitsLabel.Text = FruitsComboBox.Text;
54
+ }
55
+
56
+ private void nextFormButton_Click(object sender, EventArgs e)
57
+ {
58
+ var form = new DataEntryForm();
59
+ form.Show();
60
+ }
79
61
 
62
+ private void buttonButton_Click(object sender, EventArgs e)
63
+ {
64
+ var buttonForm = new SimpleElementsForm();
65
+ buttonForm.Show();
80
66
  }
81
67
 
82
- private void automatableMonthCalendar1_DateChanged(object sender, DateRangeEventArgs e)
68
+ private void buttonDataGridView_Click(object sender, EventArgs e)
83
69
  {
70
+ new DataGridView().Show();
71
+ }
84
72
 
85
- }
86
- }
87
- }
73
+ private void FruitListBox_SelectedIndexChanged(object sender, EventArgs e)
74
+ {
75
+ fruitsLabel.Text = (string) FruitListBox.SelectedItem;
76
+ }
77
+ }
78
+ }
@@ -34,6 +34,9 @@
34
34
  <WarningLevel>4</WarningLevel>
35
35
  </PropertyGroup>
36
36
  <ItemGroup>
37
+ <Reference Include="FizzWare.NBuilder">
38
+ <HintPath>.\FizzWare.NBuilder.dll</HintPath>
39
+ </Reference>
37
40
  <Reference Include="System" />
38
41
  <Reference Include="System.Core" />
39
42
  <Reference Include="System.Xml.Linq" />
@@ -66,6 +69,12 @@
66
69
  <Compile Include="DataEntryForm.Designer.cs">
67
70
  <DependentUpon>DataEntryForm.cs</DependentUpon>
68
71
  </Compile>
72
+ <Compile Include="DataGridView.cs">
73
+ <SubType>Form</SubType>
74
+ </Compile>
75
+ <Compile Include="DataGridView.Designer.cs">
76
+ <DependentUpon>DataGridView.cs</DependentUpon>
77
+ </Compile>
69
78
  <Compile Include="SimpleElementsForm.cs">
70
79
  <SubType>Form</SubType>
71
80
  </Compile>
@@ -92,6 +101,9 @@
92
101
  <EmbeddedResource Include="DataEntryForm.resx">
93
102
  <DependentUpon>DataEntryForm.cs</DependentUpon>
94
103
  </EmbeddedResource>
104
+ <EmbeddedResource Include="DataGridView.resx">
105
+ <DependentUpon>DataGridView.cs</DependentUpon>
106
+ </EmbeddedResource>
95
107
  <EmbeddedResource Include="SimpleElementsForm.resx">
96
108
  <DependentUpon>SimpleElementsForm.cs</DependentUpon>
97
109
  </EmbeddedResource>
@@ -13,6 +13,7 @@ module RAutomation
13
13
  # @option locators [String, Regexp] :class Internal class name of the button
14
14
  # @option locators [String, Fixnum] :id Internal ID of the button
15
15
  # @option locators [String, Fixnum] :index 0-based index to specify n-th button if all other criteria match
16
+ # @option locators [String, Boolean] :children_only limit the scope of the search to children only
16
17
  # @see RAutomation::Window#button
17
18
  def initialize(window, locators)
18
19
  @window = window
@@ -25,6 +25,7 @@ module RAutomation
25
25
  info = SearchCriteria.new
26
26
  info.parent_window = parent
27
27
  info.index = locator[:index] || 0
28
+ info.children_only = locator[:children_only]
28
29
 
29
30
  case
30
31
  when locator[:hwnd]
@@ -61,6 +62,14 @@ module RAutomation
61
62
  self[:index] = value
62
63
  end
63
64
 
65
+ def children_only?
66
+ self[:children_only]
67
+ end
68
+
69
+ def children_only=(yes_or_no)
70
+ self[:children_only] = yes_or_no
71
+ end
72
+
64
73
  def parent_window
65
74
  self[:hwnd]
66
75
  end
@@ -95,6 +104,7 @@ module RAutomation
95
104
 
96
105
  layout :hwnd, :int,
97
106
  :index, :int,
107
+ :children_only, :bool,
98
108
  :how, HowToFind, :data, FindData
99
109
  end
100
110
 
@@ -1,27 +1,32 @@
1
1
  require "spec_helper"
2
2
 
3
3
  describe "MsUia::Control", :if => SpecHelper.adapter == :ms_uia do
4
+ let(:window) { RAutomation::Window.new(:title => /MainFormWindow/i) }
4
5
 
5
6
  it "control coordinates", :special => false do
6
- window = RAutomation::Window.new(:title => /MainFormWindow/i)
7
-
8
7
  window.maximize
9
8
  control = window.control(:id => "radioButtonReset")
10
9
  control.bounding_rectangle.should be_all {|coord| coord.between?(200, 400)}
11
10
  end
12
11
 
13
12
  it "control process id", :special => true do
14
- window = RAutomation::Window.new(:title => /MainFormWindow/i)
15
-
16
13
  control = window.control(:id => "radioButtonReset")
17
14
  control.new_pid.should == @pid1
18
15
  end
19
16
 
20
17
  it "has a class" do
21
- window = RAutomation::Window.new(:title => /MainFormWindow/i)
22
-
23
18
  control = window.control(:id => "radioButtonReset")
24
- control.control_class.should =~ /WindowsForms10.BUTTON.app.0.2bf8098_r1[0-9]_ad1/
19
+ control.control_class.should =~ /WindowsForms10.BUTTON.*/
20
+ end
21
+
22
+ it "can limit the search depth" do
23
+ window.button(:id => 'buttonDataGridView').click { true }
24
+ data_grid_window = RAutomation::Window.new(:title => /DataGridView/i)
25
+
26
+ start = Time.new
27
+ data_grid_window.button(:id => 'buttonClose', :children_only => true).exist?
28
+ elapsed_time = Time.new - start
29
+ elapsed_time.should be < 2
25
30
  end
26
31
 
27
32
  context RAutomation::Adapter::MsUia::UiaDll::SearchCriteria, :pure_unit => true do
@@ -62,4 +62,14 @@ describe "MsUia::ListBox", :if => SpecHelper.adapter == :ms_uia do
62
62
 
63
63
  list_box.strings.should == ["Apple", "Orange", "Mango"]
64
64
  end
65
+
66
+ it "fires events when the index changes" do
67
+ list_box = RAutomation::Window.new(:title => "MainFormWindow").list_box(:id => "FruitListBox")
68
+ label = RAutomation::Window.new(:title => "MainFormWindow").label(:id => "fruitsLabel")
69
+
70
+ ['Apple', 'Orange', 'Mango'].each_with_index do |value, index|
71
+ list_box.select index
72
+ label.value.should eq(value)
73
+ end
74
+ end
65
75
  end
@@ -33,7 +33,7 @@ describe "Win32::Window", :if => SpecHelper.adapter == :win_32 do
33
33
  end
34
34
 
35
35
  it "#controls" do
36
- window.controls(:class => /button/i).size.should == 12
36
+ window.controls(:class => /button/i).size.should == 13
37
37
  end
38
38
 
39
39
  context "#move" do
data/spec/spec_helper.rb CHANGED
@@ -1,6 +1,7 @@
1
1
  $LOAD_PATH.unshift(File.join(File.dirname(__FILE__), '..', 'lib'))
2
2
  require 'rautomation'
3
3
  require 'rspec'
4
+ require 'timeout'
4
5
 
5
6
  module SpecHelper
6
7
  # @private
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: rautomation
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.9.2
4
+ version: 0.9.3
5
5
  platform: ruby
6
6
  authors:
7
7
  - Jarmo Pertman
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2013-05-19 00:00:00.000000000 Z
11
+ date: 2013-07-22 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: ffi
@@ -158,6 +158,10 @@ files:
158
158
  - ext/WindowsForms/WindowsForms/DataEntryForm.Designer.cs
159
159
  - ext/WindowsForms/WindowsForms/DataEntryForm.cs
160
160
  - ext/WindowsForms/WindowsForms/DataEntryForm.resx
161
+ - ext/WindowsForms/WindowsForms/DataGridView.Designer.cs
162
+ - ext/WindowsForms/WindowsForms/DataGridView.cs
163
+ - ext/WindowsForms/WindowsForms/DataGridView.resx
164
+ - ext/WindowsForms/WindowsForms/FizzWare.NBuilder.dll
161
165
  - ext/WindowsForms/WindowsForms/MainFormWindow.Designer.cs
162
166
  - ext/WindowsForms/WindowsForms/MainFormWindow.cs
163
167
  - ext/WindowsForms/WindowsForms/MainFormWindow.resx