mohawk 0.1.4 → 0.2

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.
Files changed (73) hide show
  1. data/.gitmodules +3 -3
  2. data/Changelog +6 -1
  3. data/Rakefile +2 -3
  4. data/cucumber.yml +1 -1
  5. data/features/combo_box.feature +8 -0
  6. data/features/menu.feature +8 -0
  7. data/features/step_definitions/button_steps.rb +1 -1
  8. data/features/step_definitions/combo_box_steps.rb +13 -1
  9. data/features/step_definitions/control_steps.rb +1 -1
  10. data/features/step_definitions/menu_steps.rb +7 -2
  11. data/features/support/WindowsForms.exe +0 -0
  12. data/features/support/screens/main_screen.rb +3 -0
  13. data/features/table.feature +7 -7
  14. data/features/text.feature +4 -0
  15. data/lib/mohawk/accessors.rb +3 -0
  16. data/lib/mohawk/adapters/uia/button.rb +14 -0
  17. data/lib/mohawk/adapters/uia/checkbox.rb +22 -0
  18. data/lib/mohawk/adapters/uia/control.rb +83 -0
  19. data/lib/mohawk/adapters/uia/element_locator.rb +19 -0
  20. data/lib/mohawk/adapters/uia/menu_item.rb +48 -0
  21. data/lib/mohawk/adapters/uia/radio.rb +22 -0
  22. data/lib/mohawk/adapters/uia/select_list.rb +53 -0
  23. data/lib/mohawk/adapters/uia/spinner.rb +30 -0
  24. data/lib/mohawk/adapters/uia/tab_control.rb +26 -0
  25. data/lib/mohawk/adapters/uia/table.rb +62 -0
  26. data/lib/mohawk/adapters/uia/table_row.rb +73 -0
  27. data/lib/mohawk/adapters/uia/text_box.rb +47 -0
  28. data/lib/mohawk/adapters/uia/tree_view.rb +22 -0
  29. data/lib/mohawk/adapters/uia/value_control.rb +20 -0
  30. data/lib/mohawk/adapters/uia/window.rb +64 -0
  31. data/lib/mohawk/adapters/uia_adapter.rb +36 -50
  32. data/lib/mohawk/version.rb +1 -1
  33. data/lib/mohawk/waiter.rb +18 -0
  34. data/lib/mohawk/win_32.rb +12 -0
  35. data/lib/mohawk.rb +26 -14
  36. data/mohawk.gemspec +2 -2
  37. data/spec/lib/mohawk/adapters/uia/control_spec.rb +46 -0
  38. data/spec/lib/mohawk/adapters/uia/table_row_spec.rb +36 -0
  39. data/spec/lib/mohawk/waiter_spec.rb +39 -0
  40. data/spec/lib/mohawk_spec.rb +115 -92
  41. data/spec/lib/navigation_spec.rb +14 -20
  42. data/spec/spec_helper.rb +1 -1
  43. metadata +49 -67
  44. data/lib/mohawk/accessors/button.rb +0 -20
  45. data/lib/mohawk/accessors/checkbox.rb +0 -24
  46. data/lib/mohawk/accessors/combo.rb +0 -37
  47. data/lib/mohawk/accessors/control.rb +0 -24
  48. data/lib/mohawk/accessors/label.rb +0 -15
  49. data/lib/mohawk/accessors/link.rb +0 -9
  50. data/lib/mohawk/accessors/menu_item.rb +0 -21
  51. data/lib/mohawk/accessors/radio.rb +0 -19
  52. data/lib/mohawk/accessors/spinner.rb +0 -27
  53. data/lib/mohawk/accessors/table.rb +0 -69
  54. data/lib/mohawk/accessors/table_row.rb +0 -62
  55. data/lib/mohawk/accessors/tabs.rb +0 -30
  56. data/lib/mohawk/accessors/text.rb +0 -29
  57. data/lib/mohawk/accessors/tree_view.rb +0 -32
  58. data/spec/lib/mohawk/accessors/button_spec.rb +0 -45
  59. data/spec/lib/mohawk/accessors/checkbox_spec.rb +0 -46
  60. data/spec/lib/mohawk/accessors/combo_spec.rb +0 -119
  61. data/spec/lib/mohawk/accessors/control_spec.rb +0 -47
  62. data/spec/lib/mohawk/accessors/label_spec.rb +0 -29
  63. data/spec/lib/mohawk/accessors/link_spec.rb +0 -34
  64. data/spec/lib/mohawk/accessors/menu_spec.rb +0 -32
  65. data/spec/lib/mohawk/accessors/radio_spec.rb +0 -35
  66. data/spec/lib/mohawk/accessors/spinner_spec.rb +0 -43
  67. data/spec/lib/mohawk/accessors/table_row_spec.rb +0 -28
  68. data/spec/lib/mohawk/accessors/table_spec.rb +0 -262
  69. data/spec/lib/mohawk/accessors/tabs_spec.rb +0 -58
  70. data/spec/lib/mohawk/accessors/text_spec.rb +0 -51
  71. data/spec/lib/mohawk/accessors/tree_view_spec.rb +0 -98
  72. data/spec/lib/mohawk/adapters/uia_adapter_spec.rb +0 -55
  73. data/spec/table_stubber.rb +0 -55
data/.gitmodules CHANGED
@@ -1,3 +1,3 @@
1
- [submodule "mohawk-testing-app"]
2
- path = mohawk-testing-app
3
- url = git://github.com/leviwilson/mohawk-testing-app.git
1
+ [submodule "mohawk-testing-app"]
2
+ path = mohawk-testing-app
3
+ url = git://github.com/leviwilson/mohawk-testing-app.git
data/Changelog CHANGED
@@ -1,6 +1,11 @@
1
- === Version 0.1.4
1
+ === Version 0.2 / 2014-05-09
2
+ * Enhancements
3
+ * Swapped out the underlying driver to use the uia gem
4
+
5
+ === Version 0.1.4 / 2014-02-05
2
6
  * Enhancements
3
7
  * make it more explicit if you want to add a row to the selection
8
+ * added another adapter that uses the uia gem
4
9
 
5
10
  === Version 0.1.0 / 2013-10-03
6
11
  * Enhancments
data/Rakefile CHANGED
@@ -1,3 +1,4 @@
1
+ require 'bundler/setup'
1
2
  require 'bundler/gem_tasks'
2
3
  require 'rspec/core/rake_task'
3
4
  require 'rubygems'
@@ -11,8 +12,6 @@ RSpec::Core::RakeTask.new(:spec) do |spec|
11
12
  end
12
13
  task :spec
13
14
 
14
- Cucumber::Rake::Task.new(:features) do |t|
15
- t.profile = 'default'
16
- end
15
+ Cucumber::Rake::Task.new(:features)
17
16
 
18
17
  task :default => :spec
data/cucumber.yml CHANGED
@@ -1 +1 @@
1
- default: --no-source --color --format pretty
1
+ default: --no-source --color --format pretty
@@ -8,6 +8,10 @@ Feature: Working with combo boxes
8
8
  When I select the value "Orange" from the "fruits" combo box
9
9
  Then the "Orange" option should be selected in the "fruits" combo box
10
10
 
11
+ Scenario: Selecting items by regex
12
+ When I select the regex value "[Or]an" from the "fruits" combo box
13
+ Then the "Orange" option should be selected in the "fruits" combo box
14
+
11
15
  Scenario: Selecting multiple items
12
16
  Given we toggle the multi-select button
13
17
  When I select indexes "0, 1, 2" from the "fruits_list" combo box
@@ -34,3 +38,7 @@ Feature: Working with combo boxes
34
38
  | Coconut |
35
39
  | Orange |
36
40
  | Passion Fruit |
41
+
42
+ Scenario: Interacting with ListBox controls
43
+ When I select the value "Orange" from the "fruits_list" combo box
44
+ Then the application should know that "Orange" was selected
@@ -1,5 +1,13 @@
1
1
  Feature: Working with menu items
2
2
 
3
+ Scenario: Selecting a menu item by text
4
+ When I select the menu item by text
5
+ Then I should see the "About" window
6
+
3
7
  Scenario: Selecting an item from the menu
4
8
  When I select the menu item in the path "File | Roundabout Way | To | About"
5
9
  Then I should see the "About" window
10
+
11
+ Scenario: Clicking an item from the menu
12
+ When I click the menu item in the path "File | Roundabout Way | To | About"
13
+ Then I should see the "About" window
@@ -3,7 +3,7 @@ When /^I click the "(.*?)" button$/ do |name|
3
3
  end
4
4
 
5
5
  Then /^I should see the "(.*?)" window$/ do |window_title|
6
- RAutomation::Window.new(:title => window_title).wait_until_exists
6
+ Mohawk::Waiter.wait_until { Uia.find_element title: window_title }
7
7
  end
8
8
 
9
9
  When /^I look at the value of the "(.*?)" control$/ do |name|
@@ -10,6 +10,10 @@ When /^I select the value "(.*?)" from the "(.*?)" combo box$/ do |index, name|
10
10
  on(MainScreen).send "#{name.to_field}=", index
11
11
  end
12
12
 
13
+ When(/^I select the regex value "([^"]*)" from the "([^"]*)" combo box$/) do |regex, name|
14
+ on(MainScreen).send "#{name.to_field}=", /#{regex}/
15
+ end
16
+
13
17
  When(/^I clear the item at index "([^"]*)" from the "([^"]*)" combo box$/) do |which, name|
14
18
  on(MainScreen).send("clear_#{name.to_field}", which.to_i)
15
19
  end
@@ -19,7 +23,11 @@ When(/^I clear item "([^"]*)" from the "([^"]*)" combo box$/) do |which, name|
19
23
  end
20
24
 
21
25
  Then /^the "(.*?)" option(s)? should be selected in the "(.*?)" combo box$/ do |value, has_multiple, name|
22
- on(MainScreen).send("#{name.to_field}_selections").should eq(value.split(', '))
26
+ if has_multiple
27
+ on(MainScreen).send("#{name.to_field}_selections").should eq(value.split(', '))
28
+ else
29
+ on(MainScreen).send("#{name.to_field}").should eq(value)
30
+ end
23
31
  end
24
32
 
25
33
  When /^I look at the options for the "(.*?)" combo box"$/ do |name|
@@ -34,3 +42,7 @@ end
34
42
  Given(/^we toggle the multi-select button$/) do
35
43
  on(MainScreen).toggle_multi
36
44
  end
45
+
46
+ Then(/^the application should know that "([^"]*)" was selected$/) do |expected_value|
47
+ on(MainScreen).fruits_label.should eq(expected_value)
48
+ end
@@ -7,5 +7,5 @@ When(/^I click the control identified by "([^"]*)"$/) do |what|
7
7
  end
8
8
 
9
9
  Then(/^the "([^"]*)" screen should be shown$/) do |screen|
10
- on(AboutScreen).should be_active
10
+ on(AboutScreen).should be_present
11
11
  end
@@ -1,5 +1,10 @@
1
- When /^I select the menu item in the path "(.*?)"$/ do |menu_path|
1
+ When(/^I select the menu item by text$/) do
2
+ on(MainScreen).menu_item_by_text
3
+ end
4
+
5
+ When /^I (select|click) the menu item in the path "(.*?)"$/ do |select_or_click, menu_path|
2
6
  menu_item_method = menu_path.gsub(/ (\| )?/, "_").downcase
7
+ menu_item_method.prepend('click_') if select_or_click == 'click'
3
8
  on(MainScreen).send menu_item_method
4
- end
9
+ end
5
10
 
Binary file
@@ -3,6 +3,7 @@ class MainScreen
3
3
  window(:title => /MainFormWindow/)
4
4
 
5
5
  text(:text_field, :id => "textField")
6
+ text(:text_box_field, :id => "multiLineTextField")
6
7
  text(:masked_text_field, :id => "maskedTextBox")
7
8
  button(:data_entry_form_button, :value => "Data Entry Form")
8
9
  button(:about, :value => "About")
@@ -16,8 +17,10 @@ class MainScreen
16
17
  checkbox(:first_checkbox, :id => "checkBox")
17
18
  radio(:first_radio, :id => "radioButton1")
18
19
  label(:label_control, :id => "label1")
20
+ label(:fruits_label, :id => 'fruitsLabel')
19
21
  link(:link_control, :id => "linkLabel1")
20
22
  menu_item(:file_roundabout_way_to_about, :path => ["File", "Roundabout Way", "To", "About"])
23
+ menu_item(:menu_item_by_text, text: 'About')
21
24
  tree_view(:tree_view, :id => "treeView")
22
25
  control(:value_control_field, :id => "automatableMonthCalendar1")
23
26
  spinner(:spinner, :id => 'numericUpDown1')
@@ -13,14 +13,14 @@ Feature: Working with tables
13
13
 
14
14
  Scenario: Selecting a row by matching cell information
15
15
  When we select the table row with the following information:
16
- | name | date_of_birth |
17
- | Anna Doe | 3/4/1975 |
16
+ | full_name | date_of_birth |
17
+ | Anna Doe | 3/4/1975 |
18
18
  Then the row with index "1" should be selected
19
19
 
20
20
  Scenario: Finding a row
21
21
  Then we can find the row with the following information:
22
- | name | date_of_birth | state |
23
- | John Doe | 12/15/1967 | FL |
22
+ | full_name | date_of_birth | state |
23
+ | John Doe | 12/15/1967 | FL |
24
24
 
25
25
  Scenario: Selecting a row from a child item
26
26
  When we select the "1"th table row
@@ -41,8 +41,8 @@ Feature: Working with tables
41
41
  Scenario: Clearing a row by matching cell information
42
42
  Given we add rows "0, 1" to the selection
43
43
  When we clear the table row with the following information:
44
- | name | date_of_birth |
45
- | Anna Doe | 3/4/1975 |
44
+ | full_name | date_of_birth |
45
+ | Anna Doe | 3/4/1975 |
46
46
  Then the row with index "1" should not be selected
47
47
 
48
48
  Scenario: Rows have cells
@@ -57,7 +57,7 @@ Feature: Working with tables
57
57
  | Anna Doe | 1 |
58
58
 
59
59
  Scenario: Retrieving the headers
60
- Then the table headers are "Name, Date of birth, State"
60
+ Then the table headers are "Full Name, Date of birth, State"
61
61
 
62
62
  Scenario: Retrieving a row value by its header
63
63
  Then the "date_of_birth" for the row at index "1" is "3/4/1975"
@@ -4,6 +4,10 @@ Scenario: Setting and getting text
4
4
  When I set the "text field" to the value "Some text"
5
5
  Then the "text field" should be "Some text"
6
6
 
7
+ Scenario: Setting and getting text from a text box control
8
+ When I set the "text box field" to the value "Some text"
9
+ Then the "text box field" should be "Some text"
10
+
7
11
  Scenario: Clearing text
8
12
  When I set the "text field" to the value "Text to be cleared"
9
13
  And I clear the "text field"
@@ -226,6 +226,9 @@ module Mohawk
226
226
  define_method("#{name}") do
227
227
  adapter.menu_item(locator).select
228
228
  end
229
+ define_method("click_#{name}") do
230
+ adapter.menu_item(locator).click
231
+ end
229
232
  end
230
233
 
231
234
  # Generates methods for working with table or list view controls
@@ -0,0 +1,14 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class Button < Control
5
+ include Mohawk::Waiter
6
+ valid_patterns :invoke
7
+
8
+ def click
9
+ element.as(:invoke).invoke
10
+ end
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,22 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class CheckBox < Control
5
+ valid_patterns :toggle
6
+
7
+ def set_check(should_check)
8
+ toggle.toggle_state = should_check ? :on : :off
9
+ end
10
+
11
+ def checked?
12
+ toggle.toggle_state == :on
13
+ end
14
+
15
+ private
16
+ def toggle
17
+ element.as :toggle
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,83 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class Control
5
+ include Mohawk::Waiter
6
+
7
+ class << self
8
+ attr_reader :patterns
9
+
10
+ def valid_patterns(*patterns)
11
+ @patterns = patterns
12
+ end
13
+ end
14
+
15
+ def initialize(adapter, locator)
16
+ @parent = adapter.window.element
17
+ @locator = locator
18
+ end
19
+
20
+ def click
21
+ element.click
22
+ end
23
+
24
+ def focus
25
+ element.focus
26
+ end
27
+
28
+ def exist?
29
+ locate_element != nil
30
+ end
31
+ alias_method :exists?, :exist?
32
+
33
+ def enabled?
34
+ exist? && element.enabled?
35
+ end
36
+
37
+ def disabled?
38
+ !enabled?
39
+ end
40
+
41
+ def visible?
42
+ exist? && element.visible?
43
+ end
44
+
45
+ def element
46
+ @element ||= wait_until { locate_element }
47
+ end
48
+
49
+ def handle
50
+ element.handle
51
+ end
52
+
53
+ def value
54
+ element.name
55
+ end
56
+ alias_method :control_name, :value
57
+
58
+ def view
59
+ self
60
+ end
61
+
62
+ def method_missing(meth, *args, &block)
63
+ if element.respond_to? meth
64
+ element.send meth, *args, &block
65
+ else
66
+ super
67
+ end
68
+ end
69
+
70
+ private
71
+ def locate_element
72
+ scope = (@locator.delete(:children_only) && :children) || :descendants
73
+ locator = @locator.merge(scope: scope)
74
+
75
+ patterns = @locator.delete(:pattern) || self.class.patterns
76
+ locator.merge!(pattern: patterns) if patterns
77
+
78
+ @parent.find locator
79
+ end
80
+ end
81
+ end
82
+ end
83
+ end
@@ -0,0 +1,19 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ module ElementLocator
5
+ private
6
+ def find_element(value)
7
+ case value
8
+ when Regexp
9
+ all_items.find { |e| e.name =~ value }
10
+ when String
11
+ all_items.find { |e| e.name == value }
12
+ when Fixnum
13
+ all_items[value]
14
+ end
15
+ end
16
+ end
17
+ end
18
+ end
19
+ end
@@ -0,0 +1,48 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class MenuItem < Control
5
+ class MenuItemNotFound < StandardError; end
6
+
7
+ def select
8
+ menu_item.as(:invoke).invoke
9
+ end
10
+
11
+ def click
12
+ menu_item.click_center
13
+ end
14
+
15
+ def exist?
16
+ !!menu_item
17
+ rescue MenuItemNotFound
18
+ false
19
+ end
20
+ alias_method :exists?, :exist?
21
+
22
+ private
23
+ def menu_item
24
+ current_item = @parent
25
+ path.each_with_index do |menu_item, index|
26
+ current_item = current_item.filter(control_type: :menu_item, name: menu_item).first
27
+ raise MenuItemNotFound, menu_item unless current_item
28
+ try_to_expand current_item unless index == path.count - 1
29
+ end
30
+ current_item
31
+ end
32
+
33
+ def path
34
+ [@locator[:path] || @locator[:text]].flatten
35
+ end
36
+
37
+ def try_to_expand(item)
38
+ case
39
+ when item.patterns.include?(:expand_collapse)
40
+ item.as(:expand_collapse).expand
41
+ else
42
+ item.as(:invoke).invoke
43
+ end
44
+ end
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,22 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class Radio < Control
5
+ valid_patterns :selection_item
6
+
7
+ def set
8
+ selection_item.select
9
+ end
10
+
11
+ def set?
12
+ selection_item.selected?
13
+ end
14
+
15
+ private
16
+ def selection_item
17
+ element.as :selection_item
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
@@ -0,0 +1,53 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class SelectList < Control
5
+ include ElementLocator
6
+
7
+ def set(value)
8
+ which = find_element(value)
9
+ if select_list.multi_select?
10
+ which.add_to_selection
11
+ else
12
+ click_or_select which
13
+ end
14
+ end
15
+
16
+ def clear(value)
17
+ find_element(value).remove_from_selection
18
+ end
19
+
20
+ def value
21
+ values.first || ''
22
+ end
23
+
24
+ def values
25
+ selected_items.map &:name
26
+ end
27
+
28
+ def selected_items
29
+ select_list.selected_items
30
+ end
31
+
32
+ def options
33
+ all_items.map &:name
34
+ end
35
+
36
+ private
37
+ def select_list
38
+ element.as :selection
39
+ end
40
+
41
+ def all_items
42
+ select_list.selection_items
43
+ end
44
+
45
+ def click_or_select(item)
46
+ item.click
47
+ rescue
48
+ item.select
49
+ end
50
+ end
51
+ end
52
+ end
53
+ end
@@ -0,0 +1,30 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class Spinner < Control
5
+ valid_patterns :range_value
6
+
7
+ def value=(value)
8
+ spinner.value = value
9
+ end
10
+
11
+ def value
12
+ spinner.value
13
+ end
14
+
15
+ def increment
16
+ self.value = value + spinner.small_change
17
+ end
18
+
19
+ def decrement
20
+ self.value = value - spinner.small_change
21
+ end
22
+
23
+ private
24
+ def spinner
25
+ element.as :range_value
26
+ end
27
+ end
28
+ end
29
+ end
30
+ end
@@ -0,0 +1,26 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class TabControl < Control
5
+ include ElementLocator
6
+
7
+ def selected_tab=(which)
8
+ find_element(which).select
9
+ end
10
+
11
+ def value
12
+ all_items.find(&:selected?).name
13
+ end
14
+
15
+ def items
16
+ all_items.map &:name
17
+ end
18
+
19
+ private
20
+ def all_items
21
+ element.filter(control_type: :tab_item).map {|e| e.as :selection_item }
22
+ end
23
+ end
24
+ end
25
+ end
26
+ end
@@ -0,0 +1,62 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class Table < Control
5
+ include ElementLocator, Enumerable
6
+ valid_patterns :table
7
+
8
+ def select(which)
9
+ find_row_with(which).select
10
+ end
11
+
12
+ def add(which)
13
+ find_row_with(which).add
14
+ end
15
+
16
+ def clear(which)
17
+ find_row_with(which).clear
18
+ end
19
+
20
+ def headers
21
+ element.headers.map &:name
22
+ end
23
+
24
+ def [](index)
25
+ row_at(index)
26
+ end
27
+
28
+ def each
29
+ all_items.each { |row| yield row }
30
+ end
31
+
32
+ def find_row_with(row_info)
33
+ found_row = case row_info
34
+ when Hash
35
+ find_by_hash(row_info)
36
+ else
37
+ find_element(row_info)
38
+ end
39
+ raise "A row with #{row_info} was not found" unless found_row
40
+ found_row
41
+ end
42
+
43
+ def element
44
+ super.as(:table)
45
+ end
46
+
47
+ private
48
+ def find_by_hash(hash)
49
+ find { |r| r.all_match? hash }
50
+ end
51
+
52
+ def row_at(index)
53
+ TableRow.new self, index
54
+ end
55
+
56
+ def all_items
57
+ element.row_count.times.map { |index| TableRow.new self, index }
58
+ end
59
+ end
60
+ end
61
+ end
62
+ end
@@ -0,0 +1,73 @@
1
+ module Mohawk
2
+ module Adapters
3
+ module UIA
4
+ class TableRow
5
+ attr_reader :index
6
+
7
+ def initialize(table, index)
8
+ @table, @index = table, index
9
+ end
10
+
11
+ def name
12
+ element.name
13
+ end
14
+
15
+ def cells
16
+ element.items.map &:name
17
+ end
18
+
19
+ def select
20
+ selection_item.select
21
+ self
22
+ end
23
+
24
+ def add
25
+ selection_item.add_to_selection
26
+ self
27
+ end
28
+
29
+ def clear
30
+ selection_item.remove_from_selection
31
+ self
32
+ end
33
+
34
+ def selected?
35
+ selection_item.selected?
36
+ end
37
+
38
+ def all_match?(hash)
39
+ hash.all? do |key, value|
40
+ value_from_header(key) == "#{value}"
41
+ end
42
+ end
43
+
44
+ def to_hash
45
+ {text: element.name, row: index}
46
+ end
47
+
48
+ def method_missing(name, *args)
49
+ value_from_header name
50
+ end
51
+
52
+ def value_from_header(name)
53
+ which_column = header_methods.find_index {|h| h.to_s == name.to_s }
54
+ raise ArgumentError, "#{name} column does not exist in #{header_methods}" if which_column.nil?
55
+ cells[which_column]
56
+ end
57
+
58
+ private
59
+ def element
60
+ @element ||= @table.element.row_at(@index)
61
+ end
62
+
63
+ def selection_item
64
+ element.as :selection_item
65
+ end
66
+
67
+ def header_methods
68
+ @headers ||= @table.headers.map(&:to_method)
69
+ end
70
+ end
71
+ end
72
+ end
73
+ end