page_magic 2.0.4 → 2.0.10

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 (53) hide show
  1. checksums.yaml +4 -4
  2. data/VERSION +1 -1
  3. data/lib/page_magic/session.rb +12 -3
  4. metadata +55 -90
  5. data/.codeclimate.yml +0 -4
  6. data/.pullreview.yml +0 -14
  7. data/.rspec +0 -1
  8. data/.rubocop.yml +0 -39
  9. data/.simplecov +0 -10
  10. data/.zsh_config +0 -6
  11. data/Dockerfile +0 -11
  12. data/Gemfile +0 -24
  13. data/Gemfile.lock +0 -175
  14. data/Makefile +0 -17
  15. data/Rakefile +0 -32
  16. data/circle.yml +0 -8
  17. data/page_magic.gemspec +0 -128
  18. data/spec/lib/active_support/core_ext/object/to_query_test.rb +0 -78
  19. data/spec/page_magic/class_methods_spec.rb +0 -92
  20. data/spec/page_magic/comparator/fuzzy_spec.rb +0 -44
  21. data/spec/page_magic/comparator/literal_spec.rb +0 -41
  22. data/spec/page_magic/comparator/null_spec.rb +0 -35
  23. data/spec/page_magic/comparator/parameter_map_spec.rb +0 -75
  24. data/spec/page_magic/driver_spec.rb +0 -40
  25. data/spec/page_magic/drivers/poltergeist_spec.rb +0 -8
  26. data/spec/page_magic/drivers/rack_test_spec.rb +0 -8
  27. data/spec/page_magic/drivers/selenium_spec.rb +0 -15
  28. data/spec/page_magic/drivers_spec.rb +0 -48
  29. data/spec/page_magic/element/locators_spec.rb +0 -36
  30. data/spec/page_magic/element/not_found_spec.rb +0 -24
  31. data/spec/page_magic/element/query/multiple_results_spec.rb +0 -14
  32. data/spec/page_magic/element/query/single_result_spec.rb +0 -21
  33. data/spec/page_magic/element/query_spec.rb +0 -38
  34. data/spec/page_magic/element/selector_spec.rb +0 -166
  35. data/spec/page_magic/element_context_spec.rb +0 -72
  36. data/spec/page_magic/element_definition_builder_spec.rb +0 -19
  37. data/spec/page_magic/element_spec.rb +0 -256
  38. data/spec/page_magic/elements/config_spec.rb +0 -203
  39. data/spec/page_magic/elements_spec.rb +0 -125
  40. data/spec/page_magic/instance_methods_spec.rb +0 -90
  41. data/spec/page_magic/mapping_spec.rb +0 -181
  42. data/spec/page_magic/session_methods_spec.rb +0 -40
  43. data/spec/page_magic/session_spec.rb +0 -149
  44. data/spec/page_magic/transitions_spec.rb +0 -43
  45. data/spec/page_magic/utils/string_spec.rb +0 -29
  46. data/spec/page_magic/utils/url_spec.rb +0 -9
  47. data/spec/page_magic/wait_methods_spec.rb +0 -35
  48. data/spec/page_magic/watcher_spec.rb +0 -22
  49. data/spec/page_magic/watchers_spec.rb +0 -80
  50. data/spec/page_magic_spec.rb +0 -115
  51. data/spec/spec_helper.rb +0 -15
  52. data/spec/support/shared_contexts.rb +0 -5
  53. data/spec/support/shared_examples.rb +0 -25
@@ -1,166 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe PageMagic::Element::Selector do
4
- describe '.find' do
5
- it 'returns the constant with the given name' do
6
- expect(described_class.find(:css)).to be(described_class::CSS)
7
- end
8
-
9
- context 'when selector not found' do
10
- it 'raises an exception' do
11
- expect { described_class.find(:invalid) }.to raise_exception(PageMagic::UnsupportedCriteriaException)
12
- end
13
- end
14
- end
15
-
16
- describe '#build' do
17
- it 'puts the locator and element type in to the result' do
18
- expect(described_class.new.build(:field, :locator)).to have_attributes(
19
- args: [:locator]
20
- )
21
- end
22
-
23
- context 'when exact matching is required' do
24
- it 'is added to options' do
25
- expect(described_class.new(exact: true).build(:field, :locator)).to have_attributes(
26
- options: { exact: true }
27
- )
28
- end
29
- end
30
-
31
- context 'when supports_type true' do
32
- it 'includes the element type' do
33
- expect(described_class.new(supports_type: true).build(:field, :locator)).to have_attributes(
34
- args: %i[field locator]
35
- )
36
- end
37
- end
38
-
39
- # TODO: - new class?
40
- context 'when selector formatter is provided' do
41
- subject(:selector) do
42
- described_class.new do |param|
43
- "formatted_#{param}".to_sym
44
- end
45
- end
46
-
47
- it 'uses the formatter' do
48
- expect(selector.build(:field, :locator)).to have_attributes(
49
- args: [:formatted_locator]
50
- )
51
- end
52
- end
53
-
54
- context 'when type supplied' do
55
- it 'is added to the result' do
56
- expect(described_class.new(:css).build(:field, :locator)).to have_attributes(
57
- args: %i[css locator]
58
- )
59
- end
60
- end
61
- end
62
-
63
- describe '#initialize' do
64
- context 'when exact' do
65
- it 'sets the option' do
66
- subject = described_class.new(exact: true).build(:element_type, {})
67
- expect(subject.options).to eq({ exact: true })
68
- end
69
- end
70
- end
71
-
72
- describe 'predefined selectors' do
73
- shared_examples 'a selector' do |named: false, **options|
74
- def selector_name
75
- self.class.metadata[:parent_example_group][:description].to_sym
76
- end
77
-
78
- subject do
79
- described_class.find(selector_name).build(:element_type, :locator)
80
- end
81
-
82
- it 'contains the selector args' do
83
- name_arg = named && (named == true ? selector_name : named)
84
-
85
- expected_args = [name_arg, :locator].compact
86
- expect(subject.args).to eq(expected_args)
87
- end
88
-
89
- it 'contains the options' do
90
- expect(subject.options).to eq(options)
91
- end
92
- end
93
-
94
- let(:capybara_element) do
95
- html_source = <<~HTML_SOURCE
96
- <a href='#'>a link</a>
97
-
98
-
99
- <div id='form' class="form">
100
- <a id='form_link' href='/page2'>link in a form</a>
101
- <label>enter text
102
- <input id='field_id' name='field_name' class='input_class' type='text' value='filled in'/>
103
- </label>
104
- <button id='form_button' type='submit' value='a button'/>
105
- </form>
106
- HTML_SOURCE
107
- PageMagic::Element.load(html_source)
108
- end
109
-
110
- describe 'label' do
111
- it_behaves_like 'a selector', named: :field, exact: true
112
-
113
- it 'finds elements by label' do
114
- selector = described_class.find(:label).build(:text_field, 'enter text')
115
- query = PageMagic::Element::Query::SingleResult.new(*selector.args)
116
- expect(query.execute(capybara_element)[:name]).to eq('field_name')
117
- end
118
- end
119
-
120
- describe 'name' do
121
- it 'formats locators' do
122
- name = 'my_button'
123
- expect(described_class::NAME.build(:element_type, name)).to have_attributes(
124
- args: ["*[name='#{name}']"],
125
- options: {}
126
- )
127
- end
128
-
129
- it 'finds elements by name' do
130
- selector = described_class.find(:name).build(:text_field, 'field_name')
131
- query = PageMagic::Element::Query::SingleResult.new(*selector.args)
132
- expect(query.execute(capybara_element)[:name]).to eq('field_name')
133
- end
134
- end
135
-
136
- describe 'xpath' do
137
- it_behaves_like 'a selector', named: true
138
-
139
- it 'finds elements by xpath' do
140
- selector = described_class.find(:xpath).build(:element, '//div/label/input')
141
- query = PageMagic::Element::Query::SingleResult.new(*selector.args)
142
- expect(query.execute(capybara_element)[:name]).to eq('field_name')
143
- end
144
- end
145
-
146
- describe 'id' do
147
- it_behaves_like 'a selector', named: true
148
-
149
- it 'finds elements by id' do
150
- selector = described_class.find(:id).build(:text_field, 'field_id')
151
- query = PageMagic::Element::Query::SingleResult.new(*selector.args)
152
- expect(query.execute(capybara_element)[:name]).to eq('field_name')
153
- end
154
- end
155
-
156
- describe 'text' do
157
- it_behaves_like 'a selector', named: :element_type
158
-
159
- it 'finds elements by text' do
160
- selector = described_class.find(:text).build(:link, 'a link')
161
- query = PageMagic::Element::Query::SingleResult.new(*selector.args)
162
- expect(query.execute(capybara_element).text).to eq('a link')
163
- end
164
- end
165
- end
166
- end
@@ -1,72 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- RSpec.describe PageMagic::ElementContext do
4
- describe '#method_missing' do
5
- let(:element_class) do
6
- Class.new(PageMagic::Element)
7
- end
8
-
9
- context 'when method is a element definition' do
10
- it 'returns the sub page element' do
11
- element_class.link(:a_link, text: 'a link')
12
- element = described_class.new(element_class.load("<a href='#'>a link</a>")).a_link
13
- expect(element.text).to eq('a link')
14
- end
15
-
16
- it 'passes arguments through to the element definition' do
17
- element_class.link(:pass_through, css: 'a') { |args| args[:passed_through] = true }
18
-
19
- args = {}
20
- described_class.new(element_class.load("<a href='#'>a link</a>")).pass_through(args)
21
- expect(args[:passed_through]).to eq(true)
22
- end
23
-
24
- it 'does not evaluate any of the other definitions' do
25
- element_class.link(:a_link, text: 'a link')
26
- element_class.link(:another_link, :selector) { raise('should not have been evaluated') }
27
-
28
- described_class.new(element_class.load("<a href='#'>a link</a>")).a_link
29
- end
30
- end
31
-
32
- context 'when the method is found on page_element' do
33
- it 'calls page_element method' do
34
- element_class.define_method(:page_method) do
35
- :called
36
- end
37
-
38
- expect(described_class.new(element_class.load("<a href='#'>a link</a>")).page_method).to eq(:called)
39
- end
40
- end
41
-
42
- context 'when the method is not found on page_element or as a element definition' do
43
- it 'raises an error' do
44
- expect do
45
- described_class.new(PageMagic::Element.load('')).missing_method
46
- end.to raise_error(PageMagic::ElementMissingException)
47
- end
48
- end
49
- end
50
-
51
- describe '#respond_to?' do
52
- let(:page_element_class) do
53
- Class.new(PageMagic::Element) do
54
- link(:a_link, text: 'a link')
55
- end
56
- end
57
-
58
- context 'when the page_element responds to method name' do
59
- it 'returns true' do
60
- element = described_class.new(page_element_class.load("<a href='#'>a link</a>"))
61
- expect(element).to respond_to(:a_link)
62
- end
63
- end
64
-
65
- context 'when the method is not on the page_element' do
66
- it 'calls super' do
67
- element = described_class.new(page_element_class.load("<a href='#'>a link</a>")).a_link
68
- expect(element.text).to respond_to(:methods)
69
- end
70
- end
71
- end
72
- end
@@ -1,19 +0,0 @@
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)
14
- end
15
-
16
- expect(builder.build(:capybara_object)).to have_attributes(browser_element: :capybara_object)
17
- end
18
- end
19
- end
@@ -1,256 +0,0 @@
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