rautomation 0.9.2 → 0.9.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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