page_magic 1.2.8 → 2.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 (101) hide show
  1. checksums.yaml +5 -5
  2. data/.rubocop.yml +23 -4
  3. data/.simplecov +5 -3
  4. data/.zsh_config +6 -0
  5. data/Dockerfile +11 -0
  6. data/Gemfile +13 -13
  7. data/Gemfile.lock +136 -148
  8. data/Makefile +17 -0
  9. data/README.md +26 -5
  10. data/Rakefile +12 -2
  11. data/VERSION +1 -1
  12. data/circle.yml +3 -1
  13. data/lib/active_support/core_ext/object/to_query.rb +84 -0
  14. data/lib/page_magic.rb +31 -24
  15. data/lib/page_magic/class_methods.rb +5 -2
  16. data/lib/page_magic/comparator.rb +37 -0
  17. data/lib/page_magic/comparator/fuzzy.rb +23 -0
  18. data/lib/page_magic/comparator/literal.rb +22 -0
  19. data/lib/page_magic/comparator/null.rb +26 -0
  20. data/lib/page_magic/comparator/parameter_map.rb +52 -0
  21. data/lib/page_magic/driver.rb +3 -0
  22. data/lib/page_magic/drivers.rb +6 -5
  23. data/lib/page_magic/drivers/poltergeist.rb +2 -0
  24. data/lib/page_magic/drivers/rack_test.rb +3 -1
  25. data/lib/page_magic/drivers/selenium.rb +4 -2
  26. data/lib/page_magic/element.rb +35 -15
  27. data/lib/page_magic/element/locators.rb +8 -5
  28. data/lib/page_magic/element/not_found.rb +38 -0
  29. data/lib/page_magic/element/query.rb +21 -20
  30. data/lib/page_magic/element/query/multiple_results.rb +21 -0
  31. data/lib/page_magic/element/query/prefetched_result.rb +26 -0
  32. data/lib/page_magic/element/query/single_result.rb +20 -0
  33. data/lib/page_magic/element/selector.rb +41 -16
  34. data/lib/page_magic/element/selector/methods.rb +18 -0
  35. data/lib/page_magic/element/selector/model.rb +21 -0
  36. data/lib/page_magic/element_context.rb +7 -21
  37. data/lib/page_magic/element_definition_builder.rb +20 -24
  38. data/lib/page_magic/elements.rb +65 -69
  39. data/lib/page_magic/elements/config.rb +103 -0
  40. data/lib/page_magic/elements/inheritance_hooks.rb +15 -0
  41. data/lib/page_magic/elements/types.rb +25 -0
  42. data/lib/page_magic/exceptions.rb +6 -1
  43. data/lib/page_magic/instance_methods.rb +8 -3
  44. data/lib/page_magic/mapping.rb +79 -0
  45. data/lib/page_magic/session.rb +15 -35
  46. data/lib/page_magic/session_methods.rb +3 -1
  47. data/lib/page_magic/transitions.rb +49 -0
  48. data/lib/page_magic/utils/string.rb +18 -0
  49. data/lib/page_magic/utils/url.rb +20 -0
  50. data/lib/page_magic/wait_methods.rb +3 -0
  51. data/lib/page_magic/watcher.rb +12 -17
  52. data/lib/page_magic/watchers.rb +31 -15
  53. data/page_magic.gemspec +15 -11
  54. data/spec/lib/active_support/core_ext/object/to_query_test.rb +78 -0
  55. data/spec/page_magic/class_methods_spec.rb +66 -37
  56. data/spec/page_magic/comparator/fuzzy_spec.rb +44 -0
  57. data/spec/page_magic/comparator/literal_spec.rb +41 -0
  58. data/spec/page_magic/comparator/null_spec.rb +35 -0
  59. data/spec/page_magic/comparator/parameter_map_spec.rb +75 -0
  60. data/spec/page_magic/driver_spec.rb +26 -28
  61. data/spec/page_magic/drivers/poltergeist_spec.rb +6 -7
  62. data/spec/page_magic/drivers/rack_test_spec.rb +6 -9
  63. data/spec/page_magic/drivers/selenium_spec.rb +11 -12
  64. data/spec/page_magic/drivers_spec.rb +38 -29
  65. data/spec/page_magic/element/locators_spec.rb +28 -25
  66. data/spec/page_magic/element/not_found_spec.rb +24 -0
  67. data/spec/page_magic/element/query/multiple_results_spec.rb +14 -0
  68. data/spec/page_magic/element/query/single_result_spec.rb +21 -0
  69. data/spec/page_magic/element/query_spec.rb +26 -45
  70. data/spec/page_magic/element/selector_spec.rb +120 -110
  71. data/spec/page_magic/element_context_spec.rb +47 -87
  72. data/spec/page_magic/element_definition_builder_spec.rb +14 -71
  73. data/spec/page_magic/element_spec.rb +256 -0
  74. data/spec/page_magic/elements/config_spec.rb +203 -0
  75. data/spec/page_magic/elements_spec.rb +90 -134
  76. data/spec/page_magic/instance_methods_spec.rb +65 -63
  77. data/spec/page_magic/mapping_spec.rb +181 -0
  78. data/spec/page_magic/session_methods_spec.rb +29 -25
  79. data/spec/page_magic/session_spec.rb +109 -199
  80. data/spec/page_magic/transitions_spec.rb +43 -0
  81. data/spec/page_magic/utils/string_spec.rb +29 -0
  82. data/spec/page_magic/utils/url_spec.rb +9 -0
  83. data/spec/page_magic/wait_methods_spec.rb +16 -22
  84. data/spec/page_magic/watcher_spec.rb +22 -0
  85. data/spec/page_magic/watchers_spec.rb +58 -62
  86. data/spec/page_magic_spec.rb +37 -29
  87. data/spec/spec_helper.rb +9 -2
  88. data/spec/support/shared_contexts.rb +3 -1
  89. data/spec/support/shared_examples.rb +17 -17
  90. metadata +101 -48
  91. data/lib/page_magic/element/query_builder.rb +0 -48
  92. data/lib/page_magic/element/selector_methods.rb +0 -13
  93. data/lib/page_magic/matcher.rb +0 -121
  94. data/spec/element_spec.rb +0 -249
  95. data/spec/page_magic/element/query_builder_spec.rb +0 -108
  96. data/spec/page_magic/matcher_spec.rb +0 -336
  97. data/spec/support/shared_contexts/files_context.rb +0 -7
  98. data/spec/support/shared_contexts/nested_elements_html_context.rb +0 -16
  99. data/spec/support/shared_contexts/rack_application_context.rb +0 -9
  100. data/spec/support/shared_contexts/webapp_fixture_context.rb +0 -39
  101. data/spec/watcher_spec.rb +0 -61
@@ -1,76 +1,19 @@
1
- module PageMagic
2
- describe ElementDefinitionBuilder do
3
- describe '#initialize' do
4
- context 'selector missing' do
5
- context 'object prefetched' do
6
- it 'does not raise an error' do
7
- execution = proc do
8
- described_class.new(definition_class: Element,
9
- type: :element,
10
- selector: nil,
11
- element: Object.new)
12
- end
13
- expect(&execution).to_not raise_exception
14
- end
15
- end
16
-
17
- context 'selector defined on the definition_class' do
18
- it 'uses the selector on the class' do
19
- definition_class = Class.new(Element) do
20
- selector css: 'selector'
21
- end
22
-
23
- builder = described_class.new(definition_class: definition_class,
24
- type: :element,
25
- selector: nil)
26
-
27
- expect(builder.selector).to eq(css: 'selector')
28
- end
29
- end
30
-
31
- context 'selector nil' do
32
- it 'raises an error' do
33
- execution = proc { described_class.new(definition_class: Element, type: :element, selector: nil) }
34
- expect(&execution).to raise_exception UndefinedSelectorException, described_class::INVALID_SELECTOR_MSG
35
- end
36
- end
37
-
38
- context 'selector empty' do
39
- it 'raises an error' do
40
- execution = proc { described_class.new(definition_class: Element, type: :element, selector: {}) }
41
- expect(&execution).to raise_exception UndefinedSelectorException, described_class::INVALID_SELECTOR_MSG
42
- end
43
- end
44
- end
45
-
46
- context 'selector defined on definition_class' do
47
- it 'uses the supplied selector' do
48
- definition_class = Class.new(Element) do
49
- selector css: 'selector'
50
- end
51
-
52
- expected_selector = { id: 'id' }
53
- builder = described_class.new(definition_class: definition_class,
54
- type: :element,
55
- selector: expected_selector)
56
-
57
- expect(builder.selector).to eq(expected_selector)
58
- end
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::ElementDefinitionBuilder do
4
+ describe '#build' do
5
+ it 'returns an instance of `definition_class`' do
6
+ options = { count: 1 }
7
+ builder = described_class.new(
8
+ definition_class: PageMagic::Element,
9
+ selector: PageMagic::Element::Selector.find(:xpath).build(:text_field, '//xpath', options: options)
10
+ )
11
+
12
+ allow_any_instance_of(PageMagic::Element::Query::SingleResult).to receive(:execute) do |_query, element, &block|
13
+ block.call(element)
59
14
  end
60
- end
61
-
62
- describe 'build_query' do
63
- it 'returns a capybara query' do
64
- options = { count: 1 }
65
- selector = { xpath: '//xpath' }
66
- builder = described_class.new(definition_class: Element,
67
- type: :text_field,
68
- selector: selector,
69
- element: Object.new,
70
- options: options)
71
15
 
72
- expect(builder.build_query).to eq(Element::Query.new([:xpath, '//xpath', options]))
73
- end
16
+ expect(builder.build(:capybara_object)).to have_attributes(browser_element: :capybara_object)
74
17
  end
75
18
  end
76
19
  end
@@ -0,0 +1,256 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Element do
4
+ let(:described_class) do
5
+ Class.new(PageMagic::Element) # rubocop:disable RSpec/DescribedClass
6
+ end
7
+
8
+ it_behaves_like 'session accessor'
9
+ it_behaves_like 'element watcher'
10
+ it_behaves_like 'waiter'
11
+ it_behaves_like 'element locator'
12
+
13
+ describe '.after_events' do
14
+ context 'when a hook is registered' do
15
+ it 'returns that hook' do
16
+ hook = proc {}
17
+ described_class.after_events(&hook)
18
+ expect(described_class.after_events).to eq([described_class::DEFAULT_HOOK, hook])
19
+ end
20
+ end
21
+
22
+ context 'when a hook is not registered' do
23
+ it 'returns the default hook' do
24
+ expect(described_class.after_events).to eq([described_class::DEFAULT_HOOK])
25
+ end
26
+ end
27
+ end
28
+
29
+ describe '.before_events' do
30
+ context 'when a is hook registered' do
31
+ it 'returns that hook' do
32
+ hook = proc {}
33
+ described_class.before_events(&hook)
34
+ expect(described_class.before_events).to eq([described_class::DEFAULT_HOOK, hook])
35
+ end
36
+ end
37
+
38
+ context 'when a hook is not registered' do
39
+ it 'returns the default hook' do
40
+ expect(described_class.before_events).to eq([described_class::DEFAULT_HOOK])
41
+ end
42
+ end
43
+ end
44
+
45
+ describe '.inherited' do
46
+ it 'copies before hooks on to the inheritor' do
47
+ before_hook = proc {}
48
+ described_class.before_events(&before_hook)
49
+ sub_class = Class.new(described_class)
50
+ expect(sub_class.before_events).to include(before_hook)
51
+ end
52
+
53
+ it 'copies after hooks on to the inheritor' do
54
+ after_hook = proc {}
55
+ described_class.after_events(&after_hook)
56
+ sub_class = Class.new(described_class)
57
+ expect(sub_class.after_events).to include(after_hook)
58
+ end
59
+
60
+ context 'when subclasses define their own elements' do
61
+ it 'puts the element definition on the sub class' do
62
+ custom_element = Class.new(described_class) do
63
+ text_field :form_field, id: 'field_id'
64
+ end
65
+ expect(custom_element.new(:page_element).element_definitions).to include(:form_field)
66
+ end
67
+
68
+ it 'does not put the definition on the parent class' do
69
+ Class.new(described_class) do
70
+ text_field :form_field, id: 'field_id'
71
+ end
72
+ expect(described_class.new(:page_element).element_definitions).not_to include(:form_field)
73
+ end
74
+ end
75
+ end
76
+
77
+ describe '.load' do
78
+ let(:page_source) do
79
+ <<-HTML
80
+ <div id='links'>
81
+ <a class='cta'>link text</a>
82
+ </div>
83
+ HTML
84
+ end
85
+
86
+ it 'returns an instance that works against the supplied string' do
87
+ subject = Class.new(described_class) do
88
+ element(:links, id: 'links') { link(:cta, css: '.cta') }
89
+ end
90
+ expect(subject.load(page_source).links.cta.text).to eq('link text')
91
+ end
92
+ end
93
+
94
+ describe '.watch' do
95
+ it 'adds a before hook' do
96
+ watch_block = described_class.watch(:object_id).last
97
+ expect(described_class.before_events).to include(watch_block)
98
+ end
99
+
100
+ describe 'the before hook that is added' do
101
+ it 'contains a watcher' do
102
+ watch_block = described_class.watch(:object_id).last
103
+ instance = described_class.new(:element)
104
+ instance.instance_exec(&watch_block)
105
+
106
+ watcher = instance.watchers.first
107
+ expect(watcher.observed_value).to eq(instance.object_id)
108
+ end
109
+ end
110
+ end
111
+
112
+ describe 'EVENT_TYPES' do
113
+ it 'creates methods for each of the event types' do
114
+ instance = described_class.new(:capybara_element)
115
+ missing = described_class::EVENT_TYPES.find_all { |event| !instance.respond_to?(event) }
116
+ expect(missing).to be_empty
117
+ end
118
+
119
+ context 'when one of the methods are called' do
120
+ it 'calls the browser_element passing on all args' do
121
+ browser_element = instance_double(Capybara::Node::Actions)
122
+ allow(browser_element).to receive(:select)
123
+ described_class.new(browser_element).select :args
124
+ expect(browser_element).to have_received(:select).with(:args)
125
+ end
126
+ end
127
+
128
+ context 'when the underlying capybara element does not respond to the method' do
129
+ it 'raises an error' do
130
+ expected_message = (described_class::EVENT_NOT_SUPPORTED_MSG % 'click')
131
+ browser_element = instance_double(Capybara::Node::Element)
132
+ page_element = described_class.new(browser_element)
133
+ expect { page_element.click }.to raise_error(PageMagic::NotSupportedException, expected_message)
134
+ end
135
+ end
136
+ end
137
+
138
+ describe 'hooks' do
139
+ context 'when a method called from within a before_events hook' do
140
+ let(:page_element_class) do
141
+ Class.new(described_class) do
142
+ before_events do
143
+ call_in_before_events
144
+ end
145
+ end
146
+ end
147
+
148
+ it 'delegates to the `PageMagic::Element`' do
149
+ capybara_button = instance_double(Capybara::Node::Element, click: true)
150
+ page_element = page_element_class.new(capybara_button)
151
+ allow(page_element).to receive(:call_in_before_events)
152
+ page_element.click
153
+ expect(page_element).to have_received(:call_in_before_events)
154
+ end
155
+ end
156
+
157
+ context 'when a method called from within a after_events hook' do
158
+ let(:page_element_class) do
159
+ Class.new(described_class) do
160
+ after_events do
161
+ call_in_after_events
162
+ end
163
+ end
164
+ end
165
+
166
+ it 'delegates to the `PageMagic::Element`' do
167
+ capybara_button = instance_double(Capybara::Node::Element, click: true)
168
+ page_element = page_element_class.new(capybara_button)
169
+ allow(page_element).to receive(:call_in_after_events)
170
+ page_element.click
171
+ expect(page_element).to have_received(:call_in_after_events)
172
+ end
173
+ end
174
+ end
175
+
176
+ describe '#initialize' do
177
+ it 'sets the parent element' do
178
+ described_class.parent_element(:page)
179
+ instance = described_class.new(:element)
180
+ expect(instance.parent_element).to eq(:page)
181
+ end
182
+
183
+ describe 'inherited items' do
184
+ it 'copies the before hooks' do
185
+ before_hook = proc {}
186
+ described_class.before_events(&before_hook)
187
+
188
+ instance = described_class.new(:element)
189
+ expect(instance.before_events).to include(before_hook)
190
+ end
191
+
192
+ it 'copies the after hooks' do
193
+ after_hook = proc {}
194
+ described_class.after_events(&after_hook)
195
+
196
+ instance = described_class.new(:element)
197
+ expect(instance.after_events).to include(after_hook)
198
+ end
199
+ end
200
+ end
201
+
202
+ describe '#method_missing' do
203
+ context 'when no sub element definition found' do
204
+ it 'delegates to the capybara element' do
205
+ instance = described_class.new(instance_double(Capybara::Node::Element, visible?: true))
206
+ expect(instance).to be_visible
207
+ end
208
+ end
209
+
210
+ context 'when method not found on the capybara element' do
211
+ it 'calls method on parent element' do
212
+ element = Struct.new(:parent_method).new(:called)
213
+ described_class.parent_element(element)
214
+ instance = described_class.new(:capybara_element)
215
+ expect(instance.parent_method).to eq(:called)
216
+ end
217
+ end
218
+
219
+ context 'when the method is not found on parent' do
220
+ it 'throws and exception' do
221
+ described_class.parent_element(:parent_element)
222
+ instance = described_class.new(:capybara_element)
223
+ expect { instance.bobbins }.to raise_exception NoMethodError
224
+ end
225
+ end
226
+ end
227
+
228
+ describe '#respond_to?' do
229
+ subject(:instance) do
230
+ capybara_element = Struct.new(:element_method).new(:called)
231
+ Class.new(described_class) do
232
+ element :sub_element, css: '.sub-element'
233
+ end.new(capybara_element)
234
+ end
235
+
236
+ it 'checks for methods on self' do
237
+ expect(instance).to respond_to(:session)
238
+ end
239
+
240
+ it 'checks against registered elements' do
241
+ expect(instance).to respond_to(:sub_element)
242
+ end
243
+
244
+ it 'checks for the method of the browser_element' do
245
+ expect(instance).to respond_to(:element_method)
246
+ end
247
+ end
248
+
249
+ describe '#session' do
250
+ it 'has a handle to the session' do
251
+ described_class.parent_element(instance_double(PageMagic::InstanceMethods, session: :session))
252
+ instance = described_class.new(:capybara_element)
253
+ expect(instance.session).to eq(:session)
254
+ end
255
+ end
256
+ end
@@ -0,0 +1,203 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Elements::Config do
4
+ describe '.build' do
5
+ it 'sets of the type' do
6
+ options = described_class.build([], :field)
7
+ expect(options.type).to eq(:field)
8
+ end
9
+
10
+ it 'sets the options' do
11
+ user_options = { option: 1 }
12
+ options = described_class.build([{ id: 'child' }, user_options], :field)
13
+ expect(options.options).to eq(user_options)
14
+ end
15
+
16
+ describe 'name' do
17
+ context 'when supplied' do
18
+ it 'sets it' do
19
+ options = described_class.build([:name], :field)
20
+ expect(options.name).to eq(:name)
21
+ end
22
+
23
+ context 'when an element class supplied' do
24
+ it 'uses the supplied name' do
25
+ element_class = Class.new(PageMagic::Element) do
26
+ selector({ css: 'class' })
27
+ def self.name
28
+ 'PageSection'
29
+ end
30
+ end
31
+
32
+ options = described_class.build([:supplied_name, element_class], :field)
33
+ expect(options.name).to eq(:supplied_name)
34
+ end
35
+ end
36
+ end
37
+
38
+ context 'when not supplied' do
39
+ context 'when an element class supplied' do
40
+ it 'uses the name of the class' do
41
+ element_class = Class.new(PageMagic::Element) do
42
+ selector({ css: 'class' })
43
+ def self.name
44
+ 'PageSection'
45
+ end
46
+ end
47
+
48
+ options = described_class.build([element_class], :field)
49
+ expect(options.name).to eq(:page_section)
50
+ end
51
+ end
52
+ end
53
+ end
54
+
55
+ describe 'selector' do
56
+ context 'when selector supplied' do
57
+ it 'sets the selector' do
58
+ options = described_class.build([{ id: 'child' }], :field)
59
+ expect(options.selector).to eq(PageMagic::Element::Selector.find(:id).build(:field, 'child'))
60
+ end
61
+
62
+ context 'when is empty hash' do
63
+ it 'raises an error' do
64
+ options = described_class.build([{}], :field)
65
+ expect { options.selector }.to raise_exception(PageMagic::InvalidConfigurationException,
66
+ described_class::INVALID_SELECTOR_MSG)
67
+ end
68
+ end
69
+
70
+ context 'when defined on both class and as parameter' do
71
+ it 'uses the supplied selector' do
72
+ options = described_class.build([{ css: 'supplied_selector' }], :field)
73
+ options.definition_class = Class.new(PageMagic::Element) do
74
+ selector css: 'class_selector'
75
+ end
76
+ expect(options.selector).to eq(PageMagic::Element::Selector.find(:css).build(:field, 'supplied_selector'))
77
+ end
78
+ end
79
+
80
+ context 'when page_element class supplied' do
81
+ it 'uses the selector on the class' do
82
+ expected_selector = { css: 'class' }
83
+ element_class = Class.new(PageMagic::Element) do
84
+ selector({ css: 'class' })
85
+ def self.name
86
+ 'PageSection'
87
+ end
88
+ end
89
+ options = described_class.build([element_class, expected_selector], :field)
90
+
91
+ expect(options.selector).to eq(PageMagic::Element::Selector.find(:css).build(:field, 'class'))
92
+ end
93
+ end
94
+ end
95
+
96
+ context 'when no selector supplied' do
97
+ context 'when page_element class supplied' do
98
+ it 'uses the selector on the class' do
99
+ element_class = Class.new(PageMagic::Element) do
100
+ selector({ css: 'class' })
101
+
102
+ def self.name
103
+ 'PageSection'
104
+ end
105
+ end
106
+ options = described_class.build([element_class], :field)
107
+
108
+ expect(options.selector).to eq(PageMagic::Element::Selector.find(:css).build(:field, 'class'))
109
+ end
110
+ end
111
+ end
112
+
113
+ context 'when no selector on class or page_element' do
114
+ context 'when dynamically assigned element definition block' do
115
+ it 'uses it' do
116
+ options = described_class.build([], :field)
117
+
118
+ options.definition_class = Class.new(PageMagic::Element) do
119
+ selector({ css: 'class' })
120
+ end
121
+
122
+ expect(options.selector).to eq(PageMagic::Element::Selector.find(:css).build(:field, 'class'))
123
+ end
124
+ end
125
+
126
+ context 'when not dynamically assigned' do
127
+ it 'raises and exception' do
128
+ options = described_class.build([], :field)
129
+ options.definition_class = Class.new(PageMagic::Element)
130
+ expect { options.selector }.to raise_exception(PageMagic::InvalidConfigurationException,
131
+ described_class::INVALID_SELECTOR_MSG)
132
+ end
133
+ end
134
+ end
135
+ end
136
+
137
+ it 'sets prefetched options' do
138
+ options = described_class.build(%i[page_section prefetched_element], :field)
139
+ expect(options.element).to eq(:prefetched_element)
140
+ end
141
+
142
+ context 'complex elements' do
143
+ let!(:element_class) do
144
+ Class.new(PageMagic::Element) do
145
+ def self.name
146
+ 'PageSection'
147
+ end
148
+ end
149
+ end
150
+ end
151
+ end
152
+
153
+ describe '.validate!' do
154
+ let(:options) do
155
+ {
156
+ type: :type,
157
+ selector: { css: 'css' },
158
+ element: :object,
159
+ element_class: Class.new(PageMagic::Element)
160
+ }
161
+ end
162
+
163
+ context 'when type nil' do
164
+ it 'raise an error' do
165
+ subject = described_class.new(options.except(:type))
166
+ expect { subject.validate! }.to raise_exception(PageMagic::InvalidConfigurationException,
167
+ described_class::TYPE_REQUIRED_MESSAGE)
168
+ end
169
+ end
170
+
171
+ describe '`element_class`' do
172
+ context 'when nil' do
173
+ it 'raise and error' do
174
+ subject = described_class.new(options.except(:element_class))
175
+ expect { subject.validate! }.to raise_exception(PageMagic::InvalidConfigurationException,
176
+ described_class::INVALID_ELEMENT_CLASS_MSG)
177
+ end
178
+ end
179
+
180
+ context 'not a type of `PageMagic::Element`' do
181
+ it 'raise and error' do
182
+ subject = described_class.new(options.update(element_class: Object))
183
+ expect { subject.validate! }.to raise_exception(PageMagic::InvalidConfigurationException,
184
+ described_class::INVALID_ELEMENT_CLASS_MSG)
185
+ end
186
+ end
187
+ end
188
+ end
189
+
190
+ describe '#selector' do
191
+ it 'returns a selector' do
192
+ input_options = {
193
+ type: :type,
194
+ selector: { css: 'css' },
195
+ options: { a: :b },
196
+ element: :object,
197
+ element_class: Class.new(PageMagic::Element)
198
+ }
199
+ options = described_class.new(input_options)
200
+ expect(options.selector).to eq(PageMagic::Element::Selector.find(:css).build(:type, 'css', options: { a: :b }))
201
+ end
202
+ end
203
+ end