page_magic 2.0.0.alpha1 → 2.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 (90) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +5 -2
  3. data/.zsh_config +5 -5
  4. data/Dockerfile +2 -1
  5. data/Gemfile +2 -1
  6. data/Gemfile.lock +9 -5
  7. data/Makefile +7 -3
  8. data/README.md +16 -4
  9. data/VERSION +1 -1
  10. data/lib/active_support/core_ext/object/to_query.rb +6 -6
  11. data/lib/page_magic.rb +15 -16
  12. data/lib/page_magic/class_methods.rb +1 -1
  13. data/lib/page_magic/comparator.rb +37 -0
  14. data/lib/page_magic/comparator/fuzzy.rb +23 -0
  15. data/lib/page_magic/comparator/literal.rb +22 -0
  16. data/lib/page_magic/comparator/null.rb +26 -0
  17. data/lib/page_magic/comparator/parameter_map.rb +52 -0
  18. data/lib/page_magic/drivers.rb +2 -2
  19. data/lib/page_magic/element.rb +19 -8
  20. data/lib/page_magic/element/locators.rb +4 -4
  21. data/lib/page_magic/element/not_found.rb +38 -0
  22. data/lib/page_magic/element/query.rb +19 -27
  23. data/lib/page_magic/element/query/multiple_results.rb +21 -0
  24. data/lib/page_magic/element/query/prefetched_result.rb +26 -0
  25. data/lib/page_magic/element/query/single_result.rb +20 -0
  26. data/lib/page_magic/element/selector.rb +38 -16
  27. data/lib/page_magic/element/selector/methods.rb +18 -0
  28. data/lib/page_magic/element/selector/model.rb +21 -0
  29. data/lib/page_magic/element_context.rb +5 -21
  30. data/lib/page_magic/element_definition_builder.rb +17 -24
  31. data/lib/page_magic/elements.rb +62 -102
  32. data/lib/page_magic/elements/config.rb +103 -0
  33. data/lib/page_magic/elements/inheritance_hooks.rb +15 -0
  34. data/lib/page_magic/elements/types.rb +25 -0
  35. data/lib/page_magic/exceptions.rb +3 -0
  36. data/lib/page_magic/instance_methods.rb +2 -2
  37. data/lib/page_magic/mapping.rb +79 -0
  38. data/lib/page_magic/session.rb +10 -32
  39. data/lib/page_magic/session_methods.rb +1 -1
  40. data/lib/page_magic/transitions.rb +49 -0
  41. data/lib/page_magic/utils/string.rb +4 -0
  42. data/lib/page_magic/utils/url.rb +20 -0
  43. data/lib/page_magic/watcher.rb +10 -17
  44. data/lib/page_magic/watchers.rb +28 -15
  45. data/spec/page_magic/class_methods_spec.rb +64 -37
  46. data/spec/page_magic/comparator/fuzzy_spec.rb +44 -0
  47. data/spec/page_magic/comparator/literal_spec.rb +41 -0
  48. data/spec/page_magic/comparator/null_spec.rb +35 -0
  49. data/spec/page_magic/comparator/parameter_map_spec.rb +75 -0
  50. data/spec/page_magic/driver_spec.rb +25 -29
  51. data/spec/page_magic/drivers/poltergeist_spec.rb +4 -7
  52. data/spec/page_magic/drivers/rack_test_spec.rb +4 -9
  53. data/spec/page_magic/drivers/selenium_spec.rb +9 -12
  54. data/spec/page_magic/drivers_spec.rb +36 -29
  55. data/spec/page_magic/element/locators_spec.rb +26 -25
  56. data/spec/page_magic/element/not_found_spec.rb +24 -0
  57. data/spec/page_magic/element/query/multiple_results_spec.rb +14 -0
  58. data/spec/page_magic/element/query/single_result_spec.rb +21 -0
  59. data/spec/page_magic/element/query_spec.rb +26 -47
  60. data/spec/page_magic/element/selector_spec.rb +118 -110
  61. data/spec/page_magic/element_context_spec.rb +46 -88
  62. data/spec/page_magic/element_definition_builder_spec.rb +12 -71
  63. data/spec/page_magic/element_spec.rb +256 -0
  64. data/spec/page_magic/elements/config_spec.rb +200 -0
  65. data/spec/page_magic/elements_spec.rb +87 -138
  66. data/spec/page_magic/instance_methods_spec.rb +63 -63
  67. data/spec/page_magic/mapping_spec.rb +181 -0
  68. data/spec/page_magic/session_methods_spec.rb +27 -25
  69. data/spec/page_magic/session_spec.rb +109 -198
  70. data/spec/page_magic/transitions_spec.rb +43 -0
  71. data/spec/page_magic/utils/string_spec.rb +20 -27
  72. data/spec/page_magic/utils/url_spec.rb +9 -0
  73. data/spec/page_magic/wait_methods_spec.rb +14 -22
  74. data/spec/page_magic/watcher_spec.rb +22 -0
  75. data/spec/page_magic/watchers_spec.rb +56 -62
  76. data/spec/page_magic_spec.rb +27 -24
  77. data/spec/spec_helper.rb +7 -3
  78. data/spec/support/shared_examples.rb +15 -17
  79. metadata +48 -15
  80. data/lib/page_magic/element/query_builder.rb +0 -61
  81. data/lib/page_magic/element/selector_methods.rb +0 -16
  82. data/lib/page_magic/matcher.rb +0 -130
  83. data/spec/element_spec.rb +0 -251
  84. data/spec/page_magic/element/query_builder_spec.rb +0 -110
  85. data/spec/page_magic/matcher_spec.rb +0 -338
  86. data/spec/support/shared_contexts/files_context.rb +0 -9
  87. data/spec/support/shared_contexts/nested_elements_html_context.rb +0 -18
  88. data/spec/support/shared_contexts/rack_application_context.rb +0 -11
  89. data/spec/support/shared_contexts/webapp_fixture_context.rb +0 -41
  90. data/spec/watcher_spec.rb +0 -64
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: page_magic
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.0.alpha1
4
+ version: 2.0.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Leon Davis
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2021-05-13 00:00:00.000000000 Z
11
+ date: 2021-07-01 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -94,6 +94,20 @@ dependencies:
94
94
  - - ">="
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0'
97
+ - !ruby/object:Gem::Dependency
98
+ name: rubocop-rspec
99
+ requirement: !ruby/object:Gem::Requirement
100
+ requirements:
101
+ - - ">="
102
+ - !ruby/object:Gem::Version
103
+ version: '0'
104
+ type: :development
105
+ prerelease: false
106
+ version_requirements: !ruby/object:Gem::Requirement
107
+ requirements:
108
+ - - ">="
109
+ - !ruby/object:Gem::Version
110
+ version: '0'
97
111
  - !ruby/object:Gem::Dependency
98
112
  name: ruby-debug-ide
99
113
  requirement: !ruby/object:Gem::Requirement
@@ -147,6 +161,11 @@ files:
147
161
  - lib/active_support/core_ext/object/to_query.rb
148
162
  - lib/page_magic.rb
149
163
  - lib/page_magic/class_methods.rb
164
+ - lib/page_magic/comparator.rb
165
+ - lib/page_magic/comparator/fuzzy.rb
166
+ - lib/page_magic/comparator/literal.rb
167
+ - lib/page_magic/comparator/null.rb
168
+ - lib/page_magic/comparator/parameter_map.rb
150
169
  - lib/page_magic/driver.rb
151
170
  - lib/page_magic/drivers.rb
152
171
  - lib/page_magic/drivers/poltergeist.rb
@@ -154,54 +173,68 @@ files:
154
173
  - lib/page_magic/drivers/selenium.rb
155
174
  - lib/page_magic/element.rb
156
175
  - lib/page_magic/element/locators.rb
176
+ - lib/page_magic/element/not_found.rb
157
177
  - lib/page_magic/element/query.rb
158
- - lib/page_magic/element/query_builder.rb
178
+ - lib/page_magic/element/query/multiple_results.rb
179
+ - lib/page_magic/element/query/prefetched_result.rb
180
+ - lib/page_magic/element/query/single_result.rb
159
181
  - lib/page_magic/element/selector.rb
160
- - lib/page_magic/element/selector_methods.rb
182
+ - lib/page_magic/element/selector/methods.rb
183
+ - lib/page_magic/element/selector/model.rb
161
184
  - lib/page_magic/element_context.rb
162
185
  - lib/page_magic/element_definition_builder.rb
163
186
  - lib/page_magic/elements.rb
187
+ - lib/page_magic/elements/config.rb
188
+ - lib/page_magic/elements/inheritance_hooks.rb
189
+ - lib/page_magic/elements/types.rb
164
190
  - lib/page_magic/exceptions.rb
165
191
  - lib/page_magic/instance_methods.rb
166
- - lib/page_magic/matcher.rb
192
+ - lib/page_magic/mapping.rb
167
193
  - lib/page_magic/session.rb
168
194
  - lib/page_magic/session_methods.rb
195
+ - lib/page_magic/transitions.rb
169
196
  - lib/page_magic/utils/string.rb
197
+ - lib/page_magic/utils/url.rb
170
198
  - lib/page_magic/wait_methods.rb
171
199
  - lib/page_magic/watcher.rb
172
200
  - lib/page_magic/watchers.rb
173
201
  - page_magic.gemspec
174
- - spec/element_spec.rb
175
202
  - spec/lib/active_support/core_ext/object/to_query_test.rb
176
203
  - spec/page_magic/class_methods_spec.rb
204
+ - spec/page_magic/comparator/fuzzy_spec.rb
205
+ - spec/page_magic/comparator/literal_spec.rb
206
+ - spec/page_magic/comparator/null_spec.rb
207
+ - spec/page_magic/comparator/parameter_map_spec.rb
177
208
  - spec/page_magic/driver_spec.rb
178
209
  - spec/page_magic/drivers/poltergeist_spec.rb
179
210
  - spec/page_magic/drivers/rack_test_spec.rb
180
211
  - spec/page_magic/drivers/selenium_spec.rb
181
212
  - spec/page_magic/drivers_spec.rb
182
213
  - spec/page_magic/element/locators_spec.rb
183
- - spec/page_magic/element/query_builder_spec.rb
214
+ - spec/page_magic/element/not_found_spec.rb
215
+ - spec/page_magic/element/query/multiple_results_spec.rb
216
+ - spec/page_magic/element/query/single_result_spec.rb
184
217
  - spec/page_magic/element/query_spec.rb
185
218
  - spec/page_magic/element/selector_spec.rb
186
219
  - spec/page_magic/element_context_spec.rb
187
220
  - spec/page_magic/element_definition_builder_spec.rb
221
+ - spec/page_magic/element_spec.rb
222
+ - spec/page_magic/elements/config_spec.rb
188
223
  - spec/page_magic/elements_spec.rb
189
224
  - spec/page_magic/instance_methods_spec.rb
190
- - spec/page_magic/matcher_spec.rb
225
+ - spec/page_magic/mapping_spec.rb
191
226
  - spec/page_magic/session_methods_spec.rb
192
227
  - spec/page_magic/session_spec.rb
228
+ - spec/page_magic/transitions_spec.rb
193
229
  - spec/page_magic/utils/string_spec.rb
230
+ - spec/page_magic/utils/url_spec.rb
194
231
  - spec/page_magic/wait_methods_spec.rb
232
+ - spec/page_magic/watcher_spec.rb
195
233
  - spec/page_magic/watchers_spec.rb
196
234
  - spec/page_magic_spec.rb
197
235
  - spec/spec_helper.rb
198
236
  - spec/support/shared_contexts.rb
199
- - spec/support/shared_contexts/files_context.rb
200
- - spec/support/shared_contexts/nested_elements_html_context.rb
201
- - spec/support/shared_contexts/rack_application_context.rb
202
- - spec/support/shared_contexts/webapp_fixture_context.rb
203
237
  - spec/support/shared_examples.rb
204
- - spec/watcher_spec.rb
205
238
  homepage: https://github.com/ladtech/page_magic
206
239
  licenses:
207
240
  - ruby
@@ -217,9 +250,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
217
250
  version: '2.1'
218
251
  required_rubygems_version: !ruby/object:Gem::Requirement
219
252
  requirements:
220
- - - ">"
253
+ - - ">="
221
254
  - !ruby/object:Gem::Version
222
- version: 1.3.1
255
+ version: '0'
223
256
  requirements: []
224
257
  rubygems_version: 3.1.4
225
258
  signing_key:
@@ -1,61 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'page_magic/element/query'
4
- module PageMagic
5
- class Element
6
- # class QueryBuilder - builds query to be executed on capybara driver, queries can include:
7
- # - requirements on element type
8
- # - selection criteria, modeled through the Selector class
9
- # - options
10
- class QueryBuilder
11
- class << self
12
- # Find a query using it's name
13
- # @param [Symbol] type the name of the required query in snakecase format
14
- # @return [QueryBuilder] returns the predefined query with the given name
15
- def find(type)
16
- query = constants.find { |constant| constant.to_s.casecmp(type.to_s).zero? }
17
- return ELEMENT unless query
18
-
19
- const_get(query)
20
- end
21
- end
22
-
23
- attr_reader :type
24
-
25
- # @param type -
26
- def initialize(type = nil)
27
- @type = type
28
- end
29
-
30
- # Build query parameters for Capybara's find method
31
- # @param [Hash] locator the location method e.g. text: 'button text'
32
- # @param [Hash] capybara_options additional options to be provided to Capybara. e.g. count: 3
33
- # @return [Array] list of compatible capybara query parameters.
34
- def build(locator, capybara_options = {}, multiple_results: false)
35
- args = [].tap do |array|
36
- selector = Selector.find(locator.keys.first)
37
- array << selector.build(type, locator.values.first)
38
- array << capybara_options unless capybara_options.empty?
39
- end.flatten
40
-
41
- Query.new(args, multiple_results: multiple_results)
42
- end
43
-
44
- ELEMENT = QueryBuilder.new
45
- TEXT_FIELD =
46
- CHECKBOX =
47
- SELECT_LIST =
48
- RADIO =
49
- TEXTAREA =
50
- FIELD =
51
- FILE_FIELD =
52
- FILLABLE_FIELD =
53
- RADIO_BUTTON =
54
- SELECT = QueryBuilder.new(:field)
55
-
56
- LINK = QueryBuilder.new(:link)
57
- LABEL = QueryBuilder.new(:label)
58
- BUTTON = QueryBuilder.new(:button)
59
- end
60
- end
61
- end
@@ -1,16 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- module PageMagic
4
- class Element
5
- # module SelectorMethods - adds method for getting and setting an element selector
6
- module SelectorMethods
7
- # Gets/Sets a selector
8
- # @param [Hash] selector method for locating the browser element. E.g. text: 'the text'
9
- def selector(selector = nil)
10
- return @selector unless selector
11
-
12
- @selector = selector
13
- end
14
- end
15
- end
16
- end
@@ -1,130 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require 'active_support/core_ext/object/to_query'
4
- module PageMagic
5
- # models mapping used to relate pages to uris
6
- class Matcher
7
- attr_reader :path, :parameters, :fragment
8
-
9
- # @param [Object] path String or Regular expression to match with
10
- # @param [Hash] parameters mapping of parameter name to literal or regex to match with
11
- # @param [Object] fragment String or Regular expression to match with
12
- # @raise [MatcherInvalidException] if at least one component is not specified
13
- def initialize(path = nil, parameters: nil, fragment: nil)
14
- raise MatcherInvalidException unless path || parameters || fragment
15
-
16
- @path = path
17
- @parameters = parameters
18
- @fragment = fragment
19
- end
20
-
21
- # @return [Boolean] true if no component contains a Regexp
22
- def can_compute_uri?
23
- !fuzzy?(fragment) && !fuzzy?(path) && !fuzzy?(parameters)
24
- end
25
-
26
- # @return [String] uri represented by this mapping
27
- def compute_uri
28
- path.to_s.dup.tap do |uri|
29
- uri << "?#{parameters.to_query}" if parameters
30
- uri << "##{fragment}" if fragment
31
- end
32
- end
33
-
34
- # @return [Fixnum] hash for instance
35
- def hash
36
- [path, parameters, fragment].hash
37
- end
38
-
39
- # @param [String] uri
40
- # @return [Boolean] returns true if the uri is matched against this matcher
41
- def match?(uri)
42
- uri = URI(uri)
43
- path_valid?(uri.path) && query_string_valid?(uri.query) && fragment_valid?(uri.fragment)
44
- end
45
-
46
- # compare this matcher against another
47
- # @param [Matcher] other
48
- # @return [Fixnum] -1 = smaller, 0 = equal to, 1 = greater than
49
- def <=>(other)
50
- results = %i[path parameters fragment].collect do |component|
51
- compare(send(component), other.send(component))
52
- end
53
- results.find { |result| !result.zero? } || 0
54
- end
55
-
56
- # check equality
57
- # @param [Matcher] other
58
- # @return [Boolean]
59
- def ==(other)
60
- return false unless other.is_a?(Matcher)
61
-
62
- path == other.path && parameters == other.parameters && fragment == other.fragment
63
- end
64
-
65
- alias eql? ==
66
-
67
- private
68
-
69
- def compare(this, other)
70
- return presence_comparison(this, other) unless this && other
71
-
72
- fuzzy_comparison(this, other)
73
- end
74
-
75
- def compatible?(string, comparitor)
76
- return true if comparitor.nil?
77
-
78
- if fuzzy?(comparitor)
79
- string =~ comparitor ? true : false
80
- else
81
- string == comparitor
82
- end
83
- end
84
-
85
- def fragment_valid?(string)
86
- compatible?(string, fragment)
87
- end
88
-
89
- def fuzzy?(component)
90
- return false unless component
91
-
92
- if component.is_a?(Hash)
93
- component.values.any? { |o| fuzzy?(o) }
94
- else
95
- component.is_a?(Regexp)
96
- end
97
- end
98
-
99
- def fuzzy_comparison(this, other)
100
- if fuzzy?(this)
101
- fuzzy?(other) ? 0 : 1
102
- else
103
- fuzzy?(other) ? -1 : 0
104
- end
105
- end
106
-
107
- def parameters_hash(string)
108
- CGI.parse(string.to_s.downcase).collect { |key, value| [key.downcase, value.first] }.to_h
109
- end
110
-
111
- def path_valid?(string)
112
- compatible?(string, path)
113
- end
114
-
115
- def presence_comparison(this, other)
116
- return 0 if this.nil? && other.nil?
117
- return 1 if this.nil? && other
118
-
119
- -1
120
- end
121
-
122
- def query_string_valid?(string)
123
- return true unless parameters
124
-
125
- parameters.none? do |key, value|
126
- !compatible?(parameters_hash(string)[key.downcase.to_s], value)
127
- end
128
- end
129
- end
130
- end
data/spec/element_spec.rb DELETED
@@ -1,251 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # rubocop:disable Metrics/ModuleLength
4
- module PageMagic
5
- describe Element do
6
- include_context :webapp_fixture
7
-
8
- let(:page_class) do
9
- Class.new do
10
- include PageMagic
11
- url '/elements'
12
- end
13
- end
14
-
15
- let(:session) { page_class.visit(application: rack_app) }
16
-
17
- let(:page) { session.current_page }
18
-
19
- let(:described_class) do
20
- Class.new(Element).tap { |clazz| clazz.parent_element(page) }
21
- end
22
-
23
- subject do
24
- described_class.new(:page_element)
25
- end
26
-
27
- it_behaves_like 'session accessor'
28
- it_behaves_like 'element watcher'
29
- it_behaves_like 'waiter'
30
- it_behaves_like 'element locator'
31
-
32
- describe '.after_events' do
33
- subject do
34
- Class.new(described_class)
35
- end
36
-
37
- context 'hook set' do
38
- it 'returns that hook' do
39
- hook = proc {}
40
- subject.after_events(&hook)
41
- expect(subject.after_events).to eq([described_class::DEFAULT_HOOK, hook])
42
- end
43
- end
44
- context 'hook not registered' do
45
- it 'returns the default hook' do
46
- expect(subject.after_events).to eq([described_class::DEFAULT_HOOK])
47
- end
48
- end
49
- end
50
-
51
- describe '.before_events' do
52
- subject do
53
- Class.new(described_class)
54
- end
55
-
56
- context 'hook set' do
57
- it 'returns that hook' do
58
- hook = proc {}
59
- subject.before_events(&hook)
60
- expect(subject.before_events).to eq([described_class::DEFAULT_HOOK, hook])
61
- end
62
- end
63
- context 'hook not registered' do
64
- it 'returns the default hook' do
65
- expect(subject.before_events).to eq([described_class::DEFAULT_HOOK])
66
- end
67
- end
68
- end
69
-
70
- describe '.inherited' do
71
- it 'copies before hooks' do
72
- before_hook = proc {}
73
- described_class.before_events(&before_hook)
74
- sub_class = Class.new(described_class)
75
- expect(sub_class.before_events).to include(before_hook)
76
- end
77
-
78
- it 'copies after hooks' do
79
- after_hook = proc {}
80
- described_class.after_events(&after_hook)
81
- sub_class = Class.new(described_class)
82
- expect(sub_class.after_events).to include(after_hook)
83
- end
84
-
85
- it 'lets sub classes defined their own elements' do
86
- custom_element = Class.new(described_class) do
87
- text_field :form_field, id: 'field_id'
88
-
89
- def self.name
90
- 'Form'
91
- end
92
- end
93
-
94
- page_class.class_eval do
95
- element custom_element, css: '.form'
96
- end
97
-
98
- expect(page.form.form_field).to be_visible
99
- end
100
- end
101
-
102
- describe '.watch' do
103
- let(:described_class) { Class.new(Element) }
104
- it 'adds a before hook with the watcher in it' do
105
- described_class.watch(:object_id)
106
- instance = described_class.new(:element)
107
-
108
- watcher_block = instance.before_events.last
109
- instance.instance_exec(&watcher_block)
110
- expect(instance.watchers.first.last).to eq(instance.object_id)
111
- end
112
- end
113
-
114
- describe 'EVENT_TYPES' do
115
- context 'methods created' do
116
- it 'creates methods for each of the event types' do
117
- missing = described_class::EVENT_TYPES.find_all { |event| !subject.respond_to?(event) }
118
- expect(missing).to be_empty
119
- end
120
-
121
- context 'method called' do
122
- let(:browser_element) { instance_double(Capybara::Node::Element) }
123
- subject do
124
- described_class.new(browser_element)
125
- end
126
- it 'calls the browser_element passing on all args' do
127
- expect(browser_element).to receive(:select).with(:args)
128
- subject.select :args
129
- end
130
- end
131
-
132
- context 'Capybara element does not respond to the method' do
133
- it 'raises an error' do
134
- expected_message = (described_class::EVENT_NOT_SUPPORTED_MSG % 'click')
135
- expect { subject.click }.to raise_error(NotSupportedException, expected_message)
136
- end
137
- end
138
- end
139
- end
140
-
141
- describe 'hooks' do
142
- subject do
143
- Class.new(described_class) do
144
- before_events do
145
- call_in_before_events
146
- end
147
- end.new(double('button', click: true))
148
- end
149
- context 'method called in before_events' do
150
- it 'calls methods on the page element' do
151
- expect(subject).to receive(:call_in_before_events)
152
- subject.click
153
- end
154
- end
155
-
156
- context 'method called in after_events' do
157
- subject do
158
- Class.new(described_class) do
159
- after_events do
160
- call_in_after_events
161
- end
162
- end.new(double('button', click: true))
163
- end
164
-
165
- it 'calls methods on the page element' do
166
- expect(subject).to receive(:call_in_after_events)
167
- subject.click
168
- end
169
- end
170
- end
171
-
172
- describe '#initialize' do
173
- it 'sets the parent element' do
174
- instance = described_class.new(:element)
175
- expect(instance.parent_element).to eq(page)
176
- end
177
-
178
- context 'inherited items' do
179
- let(:described_class) do
180
- Class.new(Element)
181
- end
182
-
183
- it 'copies the event hooks from the class' do
184
- before_hook = proc {}
185
- after_hook = proc {}
186
- described_class.before_events(&before_hook)
187
- described_class.after_events(&after_hook)
188
-
189
- instance = described_class.new(:element)
190
-
191
- expect(instance.before_events).to include(before_hook)
192
- expect(instance.after_events).to include(after_hook)
193
- end
194
- end
195
- end
196
-
197
- describe '#method_missing' do
198
- before do
199
- page_class.class_eval do
200
- element :form_by_css, css: '.form' do
201
- def parent_method
202
- :parent_method_called
203
- end
204
- link(:link_in_form, text: 'link in a form')
205
- end
206
- end
207
- end
208
-
209
- it 'can delegate to capybara' do
210
- expect(page.form_by_css).to be_visible
211
- end
212
-
213
- context 'no element definition and not a capybara method' do
214
- it 'calls method on parent element' do
215
- expect(page.form_by_css.link_in_form.parent_method).to eq(:parent_method_called)
216
- end
217
-
218
- context 'method not found on parent' do
219
- it 'throws and exception' do
220
- expect { page.form_by_css.link_in_a_form.bobbins }.to raise_exception ElementMissingException
221
- end
222
- end
223
- end
224
- end
225
-
226
- describe '#respond_to?' do
227
- subject do
228
- Class.new(described_class) do
229
- element :sub_element, css: '.sub-element'
230
- end.new(double(element_method: ''))
231
- end
232
- it 'checks for methods on self' do
233
- expect(subject.respond_to?(:session)).to eq(true)
234
- end
235
-
236
- it 'checks against registered elements' do
237
- expect(subject.respond_to?(:sub_element)).to eq(true)
238
- end
239
-
240
- it 'checks for the method of the browser_element' do
241
- expect(subject.respond_to?(:element_method)).to eq(true)
242
- end
243
- end
244
-
245
- describe '#session' do
246
- it 'should have a handle to the session' do
247
- expect(subject.session).to eq(page.session)
248
- end
249
- end
250
- end
251
- end