page_magic 1.0.0.alpha21 → 1.0.0

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 (48) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +4 -1
  3. data/Gemfile +1 -1
  4. data/Gemfile.lock +9 -7
  5. data/README.md +181 -78
  6. data/VERSION +1 -1
  7. data/lib/page_magic/class_methods.rb +8 -7
  8. data/lib/page_magic/driver.rb +7 -7
  9. data/lib/page_magic/drivers.rb +6 -6
  10. data/lib/page_magic/element/locators.rb +24 -0
  11. data/lib/page_magic/element/query.rb +1 -0
  12. data/lib/page_magic/element/selector.rb +11 -9
  13. data/lib/page_magic/element.rb +47 -85
  14. data/lib/page_magic/element_context.rb +25 -5
  15. data/lib/page_magic/element_definition_builder.rb +39 -0
  16. data/lib/page_magic/elements.rb +24 -27
  17. data/lib/page_magic/exceptions.rb +11 -8
  18. data/lib/page_magic/instance_methods.rb +23 -21
  19. data/lib/page_magic/session.rb +43 -44
  20. data/lib/page_magic/session_methods.rb +28 -0
  21. data/lib/page_magic/wait_methods.rb +18 -0
  22. data/lib/page_magic/watcher.rb +41 -0
  23. data/lib/page_magic/watchers.rb +43 -0
  24. data/lib/page_magic.rb +13 -9
  25. data/spec/element_spec.rb +58 -160
  26. data/spec/page_magic/class_methods_spec.rb +7 -6
  27. data/spec/page_magic/driver_spec.rb +14 -13
  28. data/spec/page_magic/drivers_spec.rb +7 -6
  29. data/spec/page_magic/element/locators_spec.rb +33 -0
  30. data/spec/page_magic/element/query_spec.rb +44 -19
  31. data/spec/page_magic/element/selector_spec.rb +45 -3
  32. data/spec/page_magic/element_context_spec.rb +41 -11
  33. data/spec/page_magic/element_definition_builder_spec.rb +76 -0
  34. data/spec/page_magic/elements_spec.rb +94 -141
  35. data/spec/page_magic/instance_methods_spec.rb +15 -10
  36. data/spec/page_magic/session_methods_spec.rb +36 -0
  37. data/spec/page_magic/session_spec.rb +78 -79
  38. data/spec/page_magic/wait_methods_spec.rb +41 -0
  39. data/spec/page_magic/watchers_spec.rb +74 -0
  40. data/spec/page_magic_spec.rb +9 -9
  41. data/spec/spec_helper.rb +1 -0
  42. data/spec/support/shared_contexts/nested_elements_html_context.rb +16 -0
  43. data/spec/support/shared_contexts/{webapp_context.rb → webapp_fixture_context.rb} +0 -0
  44. data/spec/support/shared_examples.rb +25 -0
  45. data/spec/watcher_spec.rb +49 -0
  46. metadata +23 -11
  47. data/lib/page_magic/element/method_observer.rb +0 -20
  48. data/spec/member_methods_spec.rb +0 -2
@@ -0,0 +1,43 @@
1
+ require 'page_magic/watcher'
2
+
3
+ module PageMagic
4
+ # module Watchers - contains methods for adding watchers and checking them
5
+ module Watchers
6
+ ELEMENT_MISSING_MSG = 'Unable to defined watcher: Element or method with the name %s can not be found'
7
+
8
+ # @param [Symbol] name - the name of the watcher
9
+ # @return [Boolean] true if a change is detected
10
+ def changed?(name)
11
+ watched_element = watcher(name)
12
+ watched_element.last != watched_element.check(self).last
13
+ end
14
+
15
+ # register a new watcher
16
+ # @param [Object] name of the watcher/element
17
+ # @param [Symbol] method - the method on the watched element to check
18
+ # @yieldreturn [Object] the value that should be checked
19
+ # @example
20
+ # watch(:price, :text)
21
+ # @example
22
+ # watch(:something) do
23
+ # # more complicated code to get value
24
+ # end
25
+ def watch(name, method = nil, &block)
26
+ fail ElementMissingException, (ELEMENT_MISSING_MSG % name) unless block || respond_to?(name)
27
+ watched_element = block ? Watcher.new(name, &block) : Watcher.new(name, method)
28
+ watchers << watched_element.check(self)
29
+ end
30
+
31
+ # retrieve a watcher given its name
32
+ # @param [Symbol] name the name of the watcher
33
+ # @return [Watcher] watcher with the given name
34
+ def watcher(name)
35
+ watchers.find { |watcher| watcher.name == name }
36
+ end
37
+
38
+ # @return [Array] registered watchers
39
+ def watchers
40
+ @watchers ||= []
41
+ end
42
+ end
43
+ end
data/lib/page_magic.rb CHANGED
@@ -1,21 +1,32 @@
1
1
  $LOAD_PATH.unshift("#{File.dirname(__FILE__)}")
2
2
  require 'capybara'
3
3
  require 'page_magic/exceptions'
4
+ require 'page_magic/wait_methods'
5
+ require 'page_magic/watchers'
4
6
  require 'page_magic/session'
5
- require 'page_magic/instance_methods'
7
+ require 'page_magic/session_methods'
6
8
  require 'page_magic/elements'
7
- require 'page_magic/class_methods'
8
9
  require 'page_magic/element_context'
9
10
  require 'page_magic/element'
11
+ require 'page_magic/class_methods'
12
+ require 'page_magic/instance_methods'
10
13
  require 'page_magic/drivers'
11
14
 
12
15
  # module PageMagic - PageMagic is an api for modelling pages in a website.
13
16
  module PageMagic
14
17
  class << self
18
+ # @return [Drivers] registered drivers
15
19
  def drivers
16
20
  @drivers ||= Drivers.new.tap(&:load)
17
21
  end
18
22
 
23
+ def included(clazz)
24
+ clazz.class_eval do
25
+ include(InstanceMethods)
26
+ extend(Elements, ClassMethods)
27
+ end
28
+ end
29
+
19
30
  # Visit this page based on the class level registered url
20
31
  # @param [Object] application rack application (optional)
21
32
  # @param [Symbol] browser name of browser
@@ -32,12 +43,5 @@ module PageMagic
32
43
 
33
44
  Session.new(Capybara::Session.new(browser, application), url)
34
45
  end
35
-
36
- def included(clazz)
37
- clazz.class_eval do
38
- include(InstanceMethods)
39
- extend(Elements, ClassMethods)
40
- end
41
- end
42
46
  end
43
47
  end
data/spec/element_spec.rb CHANGED
@@ -14,6 +14,17 @@ module PageMagic
14
14
 
15
15
  let(:page) { session.current_page }
16
16
 
17
+ # let!(:browser) { double('browser') }
18
+
19
+ subject do
20
+ described_class.new(:page_element, page)
21
+ end
22
+
23
+ it_behaves_like 'session accessor'
24
+ it_behaves_like 'element watcher'
25
+ it_behaves_like 'waiter'
26
+ it_behaves_like 'element locator'
27
+
17
28
  describe 'inheriting' do
18
29
  it 'lets you create custom elements' do
19
30
  custom_element = Class.new(described_class) do
@@ -32,185 +43,58 @@ module PageMagic
32
43
  end
33
44
  end
34
45
 
35
- it 'should raise an error if a selector has not been specified' do
36
- page_element = described_class.new(:name, Object.new, type: :element)
37
- expect { page_element.browser_element }.to raise_error(PageMagic::UndefinedSelectorException)
38
- end
39
-
40
- describe '#respond_to?' do
41
- subject do
42
- described_class.new(:name,
43
- Object.new,
44
- type: :element,
45
- prefetched_browser_element: double(element_method: '')) do
46
- element :sub_element, css: '.sub-element'
47
- end
48
- end
49
- it 'checks for methods on self' do
50
- expect(subject.respond_to?(:session)).to eq(true)
51
- end
52
-
53
- it 'checks against registered elements' do
54
- expect(subject.respond_to?(:sub_element)).to eq(true)
55
- end
56
-
57
- it 'checks for the method of the browser_element' do
58
- expect(subject.respond_to?(:element_method)).to eq(true)
59
- end
60
- end
61
-
62
- describe '#browser_element' do
63
- let!(:browser) { double('browser') }
64
-
65
- context 'options supplied to selector' do
66
- it 'passes them on to the cappybara finder method' do
67
- options = { count: 1 }
68
- xpath_selector = '//div/input'
69
- expect(page.session.raw_session).to receive(:find).with(:xpath, xpath_selector, options)
70
- described_class.new(:my_input,
71
- page,
72
- type: :text_field,
73
- selector: { xpath: xpath_selector }.merge(options)).browser_element
46
+ describe 'EVENT_TYPES' do
47
+ context 'methods created' do
48
+ it 'creates methods for each of the event types' do
49
+ missing = described_class::EVENT_TYPES.find_all { |event| !subject.respond_to?(event) }
50
+ expect(missing).to be_empty
74
51
  end
75
- end
76
-
77
- it 'should find by xpath' do
78
- element = described_class.new(:my_input,
79
- page,
80
- type: :text_field,
81
- selector: { xpath: '//div/label/input' }).browser_element
82
- expect(element.value).to eq('filled in')
83
- end
84
-
85
- it 'should locate an element using its id' do
86
- element = described_class.new(:my_input,
87
- page,
88
- type: :text_field,
89
- selector: { id: 'field_id' }).browser_element
90
- expect(element.value).to eq('filled in')
91
- end
92
-
93
- it 'should locate an element using its name' do
94
- element = described_class.new(:my_input,
95
- page,
96
- type: :text_field,
97
- selector: { name: 'field_name' }).browser_element
98
- expect(element.value).to eq('filled in')
99
- end
100
-
101
- it 'should locate an element using its label' do
102
- element = described_class.new(:my_input,
103
- page,
104
- type: :text_field,
105
- selector: { label: 'enter text' }).browser_element
106
- expect(element[:id]).to eq('field_id')
107
- end
108
-
109
- it 'should locate an element using css' do
110
- element = described_class.new(:my_input,
111
- page,
112
- type: :text_field,
113
- selector: { css: "input[name='field_name']" }).browser_element
114
- expect(element[:id]).to eq('field_id')
115
- end
116
-
117
- it 'should return a prefetched value' do
118
- element = described_class.new(:help, page, type: :link, prefetched_browser_element: :prefetched_object)
119
- expect(element.browser_element).to eq(:prefetched_object)
120
- end
121
-
122
- it 'should raise errors for unsupported criteria' do
123
- element = described_class.new(:my_link,
124
- page,
125
- type: :link,
126
- selector: { unsupported: '' })
127
-
128
- expect { element.browser_element }.to raise_error(PageMagic::UnsupportedCriteriaException)
129
- end
130
-
131
- context 'text selector' do
132
- it 'should locate a link' do
133
- element = described_class.new(:my_link,
134
- page,
135
- type: :link,
136
- selector: { text: 'link in a form' }).browser_element
137
- expect(element[:id]).to eq('form_link')
138
- end
139
-
140
- it 'should locate a button' do
141
- element = described_class.new(:my_button, page, type: :button, selector: { text: 'a button' }).browser_element
142
- expect(element[:id]).to eq('form_button')
143
- end
144
- end
145
- end
146
52
 
147
- describe '#section?' do
148
- context 'element definitions exist' do
149
- subject do
150
- described_class.new(:my_link, page, type: :button, selector: { text: 'a button' }) do
151
- element :thing, text: 'text'
53
+ context 'method called' do
54
+ let(:browser_element) { instance_double(Capybara::Node::Element) }
55
+ subject do
56
+ described_class.new(browser_element, page)
152
57
  end
153
- end
154
- it 'returns true' do
155
- expect(subject.section?).to eq(true)
156
- end
157
- end
158
-
159
- context 'method defined' do
160
- subject do
161
- described_class.new(:my_link, :page, type: :link, selector: { text: 'my link' }) do
162
- def custom_method
163
- end
58
+ it 'calls the browser_element passing on all args' do
59
+ expect(browser_element).to receive(:select).with(:args)
60
+ subject.select :args
164
61
  end
165
62
  end
166
-
167
- it 'returns true' do
168
- expect(subject.section?).to eq(true)
169
- end
170
- end
171
-
172
- context 'neither method or elements defined' do
173
- subject do
174
- described_class.new(:my_link, :page, type: :link, selector: { text: 'my link' })
175
- end
176
- it 'returns false' do
177
- expect(subject.section?).to eq(false)
178
- end
179
63
  end
180
64
  end
181
65
 
182
- describe 'session' do
183
- it 'should have a handle to the session' do
184
- expect(described_class.new(:help, page, type: :link, selector: :selector).session).to eq(page.session)
66
+ describe '#initialize' do
67
+ it 'sets the parent element' do
68
+ instance = described_class.new(page, :parent_page_element)
69
+ expect(instance.parent_page_element).to eq(:parent_page_element)
185
70
  end
186
71
  end
187
72
 
188
73
  describe 'hooks' do
189
74
  subject do
190
- described_class.new(:my_button, page, type: :button, selector: { id: 'my_button' }) do
75
+ Class.new(described_class) do
191
76
  before_events do
192
77
  call_in_before_hook
193
78
  end
194
- end
79
+ end.new(double('button', click: true), page)
195
80
  end
196
81
  context 'method called in before hook' do
197
82
  it 'calls methods on the page element' do
198
- expect(page.browser).to receive(:find).and_return(double('button', click: true))
199
83
  expect(subject).to receive(:call_in_before_hook)
200
84
  subject.click
201
85
  end
202
86
  end
203
87
 
204
- context 'method called in before hook' do
88
+ context 'method called in after hook' do
205
89
  subject do
206
- described_class.new(:my_button, page, type: :button, selector: { id: 'my_button' }) do
90
+ Class.new(described_class) do
207
91
  after_events do
208
92
  call_in_after_hook
209
93
  end
210
- end
94
+ end.new(double('button', click: true), page)
211
95
  end
96
+
212
97
  it 'calls methods on the page element' do
213
- expect(page.browser).to receive(:find).and_return(double('button', click: true))
214
98
  expect(subject).to receive(:call_in_after_hook)
215
99
  subject.click
216
100
  end
@@ -230,22 +114,36 @@ module PageMagic
230
114
  expect(page.form_by_css).to be_visible
231
115
  end
232
116
 
233
- context 'method not on capybara browser element' do
234
- it 'uses the parent page element' do
235
- page_class.class_eval do
236
- def parent_method
237
- :called
238
- end
239
- end
240
- expect(page.form_by_css.parent_method).to eq(:called)
241
- end
242
- end
243
-
244
117
  context 'no element definition and not a capybara method' do
245
118
  it 'throws and exception' do
246
119
  expect { page.form_by_css.bobbins }.to raise_exception NoMethodError
247
120
  end
248
121
  end
249
122
  end
123
+
124
+ describe '#respond_to?' do
125
+ subject do
126
+ Class.new(described_class) do
127
+ element :sub_element, css: '.sub-element'
128
+ end.new(double(element_method: ''), :parent_page_element)
129
+ end
130
+ it 'checks for methods on self' do
131
+ expect(subject.respond_to?(:session)).to eq(true)
132
+ end
133
+
134
+ it 'checks against registered elements' do
135
+ expect(subject.respond_to?(:sub_element)).to eq(true)
136
+ end
137
+
138
+ it 'checks for the method of the browser_element' do
139
+ expect(subject.respond_to?(:element_method)).to eq(true)
140
+ end
141
+ end
142
+
143
+ describe '#session' do
144
+ it 'should have a handle to the session' do
145
+ expect(subject.session).to eq(page.session)
146
+ end
147
+ end
250
148
  end
251
149
  end
@@ -6,12 +6,6 @@ module PageMagic
6
6
  clazz.include(InstanceMethods)
7
7
  end
8
8
  end
9
- describe '#url' do
10
- it 'get/sets a value' do
11
- subject.url(:url)
12
- expect(subject.url).to eq(:url)
13
- end
14
- end
15
9
 
16
10
  describe 'on_load' do
17
11
  context 'block not set' do
@@ -29,6 +23,13 @@ module PageMagic
29
23
  end
30
24
  end
31
25
 
26
+ describe '#url' do
27
+ it 'get/sets a value' do
28
+ subject.url(:url)
29
+ expect(subject.url).to eq(:url)
30
+ end
31
+ end
32
+
32
33
  describe '#visit' do
33
34
  include_context :webapp_fixture
34
35
  it 'passes all options to create an active session on the registered url' do
@@ -6,19 +6,6 @@ module PageMagic
6
6
  described_class.new :custom_browser
7
7
  end
8
8
 
9
- describe '#supports?' do
10
- context 'browser is in supported browsers' do
11
- it 'returns true' do
12
- expect(subject.support?(:custom_browser)).to eq(true)
13
- end
14
- end
15
-
16
- context 'browser is not in supported browsers' do
17
- it 'returns false' do
18
- expect(subject.support?(:unsupported_browser)).to eq(false)
19
- end
20
- end
21
- end
22
9
  describe '#build' do
23
10
  it 'returns the result of the block passed to the driver class constructor' do
24
11
  subject = described_class.new(:custom_browser)do
@@ -37,5 +24,19 @@ module PageMagic
37
24
  subject.build(:rack_app, options: :options, browser: :browser)
38
25
  end
39
26
  end
27
+
28
+ describe '#supports?' do
29
+ context 'browser is in supported browsers' do
30
+ it 'returns true' do
31
+ expect(subject.support?(:custom_browser)).to eq(true)
32
+ end
33
+ end
34
+
35
+ context 'browser is not in supported browsers' do
36
+ it 'returns false' do
37
+ expect(subject.support?(:unsupported_browser)).to eq(false)
38
+ end
39
+ end
40
+ end
40
41
  end
41
42
  end
@@ -3,12 +3,6 @@ module PageMagic
3
3
  describe Drivers do
4
4
  subject { described_class.new }
5
5
  let(:expected_driver) { Driver.new(:browser_driver) }
6
- describe '#register' do
7
- it 'stores the driver' do
8
- subject.register expected_driver
9
- expect(subject.all).to eq([expected_driver])
10
- end
11
- end
12
6
 
13
7
  describe '#find' do
14
8
  it 'returns the registered driver' do
@@ -34,5 +28,12 @@ module PageMagic
34
28
  expect(subject.find(:custom_browser)).to be(::CustomDriver)
35
29
  end
36
30
  end
31
+
32
+ describe '#register' do
33
+ it 'stores the driver' do
34
+ subject.register expected_driver
35
+ expect(subject.all).to eq([expected_driver])
36
+ end
37
+ end
37
38
  end
38
39
  end
@@ -0,0 +1,33 @@
1
+ module PageMagic
2
+ class Element
3
+ describe Locators do
4
+ subject(:element_clazz) do
5
+ Class.new do
6
+ extend(Elements)
7
+ include(Locators)
8
+ end
9
+ end
10
+ subject { element_clazz.new }
11
+
12
+ describe '#element_by_name' do
13
+ it 'returns the required element' do
14
+ selector = { id: 'child' }
15
+ element_clazz.element :child1, selector
16
+ element_clazz.element :child2, id: 'child 2'
17
+
18
+ expected_builder = ElementDefinitionBuilder.new(definition_class: Element, type: :element, selector: selector)
19
+
20
+ expect(subject.element_by_name(:child1)).to eq(expected_builder)
21
+ end
22
+
23
+ context 'element not found' do
24
+ it 'raises an error' do
25
+ expected_message = (described_class::ELEMENT_NOT_DEFINED_MSG % :child)
26
+ command = proc { subject.element_by_name(:child) }
27
+ expect(&command).to raise_exception ElementMissingException, expected_message
28
+ end
29
+ end
30
+ end
31
+ end
32
+ end
33
+ end
@@ -1,6 +1,13 @@
1
1
  module PageMagic
2
2
  class Element
3
3
  describe Query do
4
+ it 'has a predefined query for each element type' do
5
+ missing = PageMagic::Elements::TYPES.find_all do |type|
6
+ !described_class.constants.include?(type.upcase.to_sym)
7
+ end
8
+ expect(missing).to be_empty
9
+ end
10
+
4
11
  describe '.find' do
5
12
  it 'finds the constant with the given name' do
6
13
  expect(Query.find(:button)).to be(described_class::BUTTON)
@@ -42,35 +49,53 @@ module PageMagic
42
49
  end
43
50
 
44
51
  class Query
45
- describe 'predefined queries' do
46
- it 'has a predefined query for each element type' do
47
- missing = PageMagic::Elements::TYPES.find_all do |type|
48
- !Query.constants.include?(type.upcase.to_sym)
49
- end
50
- expect(missing).to be_empty
52
+ describe BUTTON do
53
+ it 'has an element type' do
54
+ expect(described_class.type).to eq(:button)
51
55
  end
56
+ end
52
57
 
53
- describe 'queries for form fields' do
54
- it 'uses field as the element type' do
55
- expect(TEXT_FIELD.type).to eq(:field)
56
- end
57
- it 'uses the same query for all form field types' do
58
- expect(TEXT_FIELD).to eq(CHECKBOX).and eq(SELECT_LIST).and eq(RADIOS).and eq(TEXTAREA)
59
- end
58
+ describe ELEMENT do
59
+ it ' does not has an element type' do
60
+ expect(described_class.type).to be_nil
60
61
  end
62
+ end
61
63
 
62
- it 'uses link as the element type for link' do
63
- expect(LINK.type).to eq(:link)
64
+ describe LINK do
65
+ it 'has an element type' do
66
+ expect(described_class.type).to eq(:link)
64
67
  end
68
+ end
65
69
 
66
- it 'uses the button element type for button' do
67
- expect(BUTTON.type).to eq(:button)
70
+ describe TEXT_FIELD do
71
+ it 'has an element type' do
72
+ expect(described_class.type).to eq(:field)
68
73
  end
69
74
 
70
- it 'does not use an element type for generic elements' do
71
- expect(ELEMENT.type).to eq(nil)
75
+ it 'the same as all form field types' do
76
+ expect(described_class).to eq(CHECKBOX).and eq(SELECT_LIST).and eq(RADIOS).and eq(TEXTAREA)
72
77
  end
73
78
  end
74
79
  end
80
+
81
+ context 'integration' do
82
+ include_context :webapp_fixture
83
+ let(:capybara_session) { Capybara::Session.new(:rack_test, rack_app).tap { |s| s.visit('/elements') } }
84
+ it 'finds fields' do
85
+ expect(capybara_session.all(*Query.find(:text_field).build(name: 'field_name')).size).to eq(1)
86
+ end
87
+
88
+ it 'finds buttons' do
89
+ expect(capybara_session.all(*Query.find(:button).build(text: 'a button')).size).to eq(1)
90
+ end
91
+
92
+ it 'finds links' do
93
+ expect(capybara_session.all(*Query.find(:link).build(text: 'a link')).size).to eq(1)
94
+ end
95
+
96
+ it 'finds elements' do
97
+ expect(capybara_session.all(*Query.find(:element).build(name: 'field_name')).size).to eq(1)
98
+ end
99
+ end
75
100
  end
76
101
  end
@@ -18,6 +18,16 @@ module PageMagic
18
18
  expect(subject.build(:field, :locator)).to eq([:locator])
19
19
  end
20
20
 
21
+ context 'exact is set to true' do
22
+ subject do
23
+ described_class.new(exact: true)
24
+ end
25
+
26
+ it 'includes the requirement for the match to be exact' do
27
+ expect(subject.build(:field, :locator)).to include(exact: true)
28
+ end
29
+ end
30
+
21
31
  context 'supports_type flag set to true in constructor' do
22
32
  subject do
23
33
  described_class.new(supports_type: true)
@@ -48,12 +58,19 @@ module PageMagic
48
58
  end
49
59
  end
50
60
  end
61
+
62
+ describe '#initialize' do
63
+ it 'sets exact to false by default' do
64
+ expect(subject.exact).to eq(false)
65
+ end
66
+ end
51
67
  end
52
68
 
53
69
  class Selector
54
- shared_examples 'named selector' do
70
+ shared_examples 'named selector' do |options|
55
71
  it 'adds name to the result' do
56
- expect(described_class.build(:element_type, :locator)).to eq([described_class.name, :locator])
72
+ expected = [described_class.name, :locator, options].compact
73
+ expect(described_class.build(:element_type, :locator)).to eq(expected)
57
74
  end
58
75
  end
59
76
 
@@ -96,7 +113,7 @@ module PageMagic
96
113
  end
97
114
 
98
115
  describe LABEL do
99
- it_behaves_like 'named selector', :field
116
+ it_behaves_like 'named selector', exact: true
100
117
  it_behaves_like 'non element type selector'
101
118
  end
102
119
 
@@ -105,5 +122,30 @@ module PageMagic
105
122
  it_behaves_like 'element type selector'
106
123
  end
107
124
  end
125
+
126
+ context 'integration' do
127
+ include_context :webapp_fixture
128
+ let(:capybara_session) { Capybara::Session.new(:rack_test, rack_app).tap { |s| s.visit('/elements') } }
129
+
130
+ it 'finds elements by name' do
131
+ expect(capybara_session.all(*Query.find(:text_field).build(name: 'field_name')).size).to eq(1)
132
+ end
133
+
134
+ it 'finds elements by xpath' do
135
+ expect(capybara_session.all(*Query.find(:element).build(xpath: '//div/input')).size).to eq(1)
136
+ end
137
+
138
+ it 'finds elements by id' do
139
+ expect(capybara_session.all(*Query.find(:text_field).build(id: 'field_id')).size).to eq(1)
140
+ end
141
+
142
+ it 'finds elements by label' do
143
+ expect(capybara_session.all(*Query.find(:text_field).build(label: 'enter text')).size).to eq(1)
144
+ end
145
+
146
+ it 'finds elements by text' do
147
+ expect(capybara_session.all(*Query.find(:link).build(text: 'a link')).size).to eq(1)
148
+ end
149
+ end
108
150
  end
109
151
  end