page_magic 2.0.0.alpha1 → 2.0.0

Sign up to get free protection for your applications and to get access to all the features.
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
@@ -0,0 +1,14 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Element::Query::MultipleResults do
4
+ describe '#find' do
5
+ context 'when multiple results found' do
6
+ it 'returns an array' do
7
+ element = PageMagic::Element.load('<a></a><a></a>')
8
+ subject = described_class.new('a')
9
+ result = subject.execute(element)
10
+ expect(result.size).to eq(2)
11
+ end
12
+ end
13
+ end
14
+ end
@@ -0,0 +1,21 @@
1
+ # frozen_string_literal: true
2
+
3
+ RSpec.describe PageMagic::Element::Query::SingleResult do
4
+ describe '#find' do
5
+ context 'when more than one result is returned' do
6
+ it 'raises an error' do
7
+ element = PageMagic::Element.load('<a></a><a></a>')
8
+ query = described_class.new('a')
9
+ expected_message = 'Ambiguous match, found 2 elements matching visible css "a"'
10
+ expect { query.execute(element) }.to raise_error PageMagic::AmbiguousQueryException, expected_message
11
+ end
12
+ end
13
+
14
+ it 'returns the result of the capybara query' do
15
+ element = PageMagic::Element.load('<a>link</a>')
16
+ query = described_class.new('a')
17
+ result = query.execute(element)
18
+ expect(result.text).to eq('link')
19
+ end
20
+ end
21
+ end
@@ -1,58 +1,37 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module PageMagic
4
- class Element
5
- describe Query do
6
- include_context :webapp_fixture
7
-
8
- let(:page) do
9
- elements_page = Class.new do
10
- include PageMagic
11
- url '/elements'
12
- end
13
- elements_page.visit(application: rack_app).current_page
14
- end
15
-
16
- describe '#execute' do
17
- context 'no results found' do
18
- subject do
19
- QueryBuilder.find(:link).build({ css: 'wrong' })
20
- end
21
-
22
- it 'raises an error' do
23
- expected_message = 'Unable to find css "wrong"'
24
- expect { subject.execute(page.browser) }.to raise_exception(ElementMissingException, expected_message)
25
- end
26
- end
27
-
28
- context 'to many results returned' do
29
- subject do
30
- QueryBuilder.find(:link).build({ css: 'a' })
31
- end
3
+ RSpec.describe PageMagic::Element::Query do
4
+ describe '#execute' do
5
+ it 'calls find' do
6
+ subject = described_class.new
7
+ allow(subject).to receive(:find)
8
+
9
+ subject.execute(:capybara_element)
10
+ expect(subject).to have_received(:find).with(:capybara_element)
11
+ end
32
12
 
33
- it 'raises an error' do
34
- expected_message = 'Ambiguous match, found 2 elements matching visible css "a"'
35
- expect { subject.execute(page.browser) }.to raise_error AmbiguousQueryException, expected_message
36
- end
37
- end
13
+ context 'when a formatter supplied' do
14
+ it 'uses it' do
15
+ subject = described_class.new
16
+ allow(subject).to receive(:find) { |_r, &formatter| formatter.call(:result) }
38
17
 
39
- context 'multiple results found' do
40
- subject do
41
- QueryBuilder.find(:link).build({ css: 'a' }, {}, multiple_results: true)
42
- end
18
+ result = subject.execute(:capybara_element) { |capybara_result| "formatter_called_on_#{capybara_result}" }
19
+ expect(result).to eq('formatter_called_on_result')
20
+ end
21
+ end
43
22
 
44
- it 'returns an array' do
45
- result = subject.execute(page.browser)
46
- expect(result).to be_a(Array)
47
- expect(result.size).to eq(2)
23
+ context 'when no results are found' do
24
+ subject(:query_class) do
25
+ Class.new(described_class) do
26
+ def find(element)
27
+ element.find('missing')
48
28
  end
49
29
  end
30
+ end
50
31
 
51
- it 'returns the result of the capybara query' do
52
- query = QueryBuilder.find(:link).build({ id: 'form_link' })
53
- result = query.execute(page.browser)
54
- expect(result.text).to eq('link in a form')
55
- end
32
+ it 'Returns `NotFound`' do
33
+ element = PageMagic::Element.load('<html></html>')
34
+ expect(query_class.new.execute(element)).to be_a(PageMagic::Element::NotFound)
56
35
  end
57
36
  end
58
37
  end
@@ -1,157 +1,165 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module PageMagic
4
- class Element
5
- describe Selector do
6
- describe '.find' do
7
- it 'returns the constant with the given name' do
8
- expect(Selector.find(:css)).to be(described_class::CSS)
9
- end
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
10
8
 
11
- context 'selector not found' do
12
- it 'raises an exception' do
13
- expect { Selector.find(:invalid) }.to raise_exception(UnsupportedCriteriaException)
14
- end
15
- end
9
+ context 'when selector not found' do
10
+ it 'raises an exception' do
11
+ expect { described_class.find(:invalid) }.to raise_exception(PageMagic::UnsupportedCriteriaException)
16
12
  end
13
+ end
14
+ end
17
15
 
18
- describe '#build' do
19
- it 'puts the locator and element type in to the result' do
20
- expect(subject.build(:field, :locator)).to eq([:locator])
21
- end
22
-
23
- context 'exact is set to true' do
24
- subject do
25
- described_class.new(exact: true)
26
- end
27
-
28
- it 'includes the requirement for the match to be exact' do
29
- expect(subject.build(:field, :locator)).to include(exact: true)
30
- end
31
- end
32
-
33
- context 'supports_type flag set to true in constructor' do
34
- subject do
35
- described_class.new(supports_type: true)
36
- end
37
- it 'includes the element type in the result' do
38
- expect(subject.build(:field, :locator)).to eq(%i[field locator])
39
- end
40
- end
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
41
22
 
42
- context 'formatter supplied to constructor' do
43
- subject do
44
- described_class.new do |param|
45
- "formatted_#{param}".to_sym
46
- end
47
- end
48
- it 'uses the formatter' do
49
- expect(subject.build(:field, :locator)).to eq([:formatted_locator])
50
- end
51
- end
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
52
30
 
53
- context 'name supplied to constructor' do
54
- subject do
55
- described_class.new(:css)
56
- end
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
57
38
 
58
- it 'is added to the result' do
59
- expect(subject.build(:field, :locator)).to eq(%i[css locator])
60
- end
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
61
44
  end
62
45
  end
63
46
 
64
- describe '#initialize' do
65
- it 'sets exact to false by default' do
66
- expect(subject.exact).to eq(false)
67
- end
47
+ it 'uses the formatter' do
48
+ expect(selector.build(:field, :locator)).to have_attributes(
49
+ args: [:formatted_locator]
50
+ )
68
51
  end
69
52
  end
70
53
 
71
- class Selector
72
- shared_examples 'named selector' do |options|
73
- it 'adds name to the result' do
74
- expected = [described_class.name, :locator, options].compact
75
- expect(described_class.build(:element_type, :locator)).to eq(expected)
76
- end
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
+ )
77
59
  end
60
+ end
61
+ end
78
62
 
79
- shared_examples 'anonymous selector' do
80
- it 'does not have a name' do
81
- expect(described_class.name).to eq(nil)
82
- end
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 })
83
68
  end
69
+ end
70
+ end
84
71
 
85
- shared_examples 'element type selector' do
86
- it 'adds the element type to the result' do
87
- expect(described_class.supports_type).to eq(true)
88
- end
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
89
76
  end
90
77
 
91
- shared_examples 'non element type selector' do
92
- it 'adds the element type to the result' do
93
- expect(described_class.supports_type).to eq(false)
94
- end
78
+ subject do
79
+ described_class.find(selector_name).build(:element_type, :locator)
95
80
  end
96
81
 
97
- describe NAME do
98
- it_behaves_like 'anonymous selector'
99
- it_behaves_like 'non element type selector'
82
+ it 'contains the selector args' do
83
+ name_arg = named && (named == true ? selector_name : named)
100
84
 
101
- it 'formats locators' do
102
- button_name = 'my_button'
103
- expect(described_class.build(:button, button_name)).to eq(["*[name='#{button_name}']"])
104
- end
85
+ expected_args = [name_arg, :locator].compact
86
+ expect(subject.args).to eq(expected_args)
105
87
  end
106
88
 
107
- describe XPATH do
108
- it_behaves_like 'named selector'
109
- it_behaves_like 'non element type selector'
89
+ it 'contains the options' do
90
+ expect(subject.options).to eq(options)
110
91
  end
92
+ end
111
93
 
112
- describe ID do
113
- it_behaves_like 'named selector'
114
- it_behaves_like 'non element type selector'
115
- end
94
+ let(:capybara_element) do
95
+ html_source = <<~HTML_SOURCE
96
+ <a href='#'>a link</a>
116
97
 
117
- describe LABEL do
118
- it_behaves_like 'named selector', exact: true
119
- it_behaves_like 'non element type selector'
120
- end
121
98
 
122
- describe TEXT do
123
- it_behaves_like 'anonymous selector'
124
- it_behaves_like 'element type selector'
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')
125
117
  end
126
118
  end
127
119
 
128
- context 'integration' do
129
- include_context :webapp_fixture
130
- let(:capybara_session) { Capybara::Session.new(:rack_test, rack_app).tap { |s| s.visit('/elements') } }
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
131
128
 
132
129
  it 'finds elements by name' do
133
- query = QueryBuilder.find(:text_field).build({ name: 'field_name' })
134
- expect(query.execute(capybara_session)[:name]).to eq('field_name')
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')
135
133
  end
134
+ end
135
+
136
+ describe 'xpath' do
137
+ it_behaves_like 'a selector', named: true
136
138
 
137
139
  it 'finds elements by xpath' do
138
- query = QueryBuilder.find(:element).build({ xpath: '//div/label/input' })
139
- expect(query.execute(capybara_session)[:name]).to eq('field_name')
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')
140
143
  end
144
+ end
145
+
146
+ describe 'id' do
147
+ it_behaves_like 'a selector', named: true
141
148
 
142
149
  it 'finds elements by id' do
143
- query = QueryBuilder.find(:text_field).build({ id: 'field_id' })
144
- expect(query.execute(capybara_session)[:name]).to eq('field_name')
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')
145
153
  end
154
+ end
146
155
 
147
- it 'finds elements by label' do
148
- query = QueryBuilder.find(:text_field).build({ label: 'enter text' })
149
- expect(query.execute(capybara_session)[:name]).to eq('field_name')
150
- end
156
+ describe 'text' do
157
+ it_behaves_like 'a selector', named: :element_type
151
158
 
152
159
  it 'finds elements by text' do
153
- query = QueryBuilder.find(:link).build({ text: 'a link' })
154
- expect(query.execute(capybara_session).text).to eq('a link')
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')
155
163
  end
156
164
  end
157
165
  end
@@ -1,113 +1,71 @@
1
1
  # frozen_string_literal: true
2
2
 
3
- module PageMagic
4
- describe ElementContext do
5
- include_context :webapp_fixture
6
-
7
- let!(:elements_page) do
8
- Class.new do
9
- include PageMagic
10
- url '/elements'
11
- link(:a_link, text: 'a link')
12
- link(:prefetched, Object.new)
13
- end
14
- end
15
-
16
- let(:page) do
17
- elements_page.visit(application: rack_app).current_page
18
- end
19
-
20
- subject do
21
- described_class.new(page)
3
+ RSpec.describe PageMagic::ElementContext do
4
+ describe '#method_missing' do
5
+ let(:element_class) do
6
+ Class.new(PageMagic::Element)
22
7
  end
23
8
 
24
- let!(:session) do
25
- double('session', raw_session: double('browser'))
26
- end
27
-
28
- describe '#method_missing' do
29
- context 'method is a element defintion' do
30
- it 'returns the sub page element' do
31
- element = described_class.new(page).a_link
32
- expect(element.text).to eq('a link')
33
- end
34
-
35
- it 'passes arguments through to the element definition' do
36
- elements_page.links :pass_through, css: 'a' do |args|
37
- args[:passed_through] = true
38
- end
39
- args = {}
40
- described_class.new(page).pass_through(args)
41
- expect(args[:passed_through]).to eq(true)
42
- end
43
-
44
- it 'does not evaluate any of the other definitions' do
45
- elements_page.class_eval do
46
- link(:another_link, :selector) do
47
- raise('should not have been evaluated')
48
- end
49
- end
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
50
15
 
51
- described_class.new(page).a_link
52
- end
16
+ it 'passes arguments through to the element definition' do
17
+ element_class.link(:pass_through, css: 'a') { |args| args[:passed_through] = true }
53
18
 
54
- context 'more than one match found in the browser' do
55
- it 'returns an array of element definitions' do
56
- elements_page.links :links, css: 'a'
57
- links = described_class.new(page).links
58
- expect(links.find_all { |e| e.kind_of?(Element) }.size).to eq(2)
59
- expect(links.collect(&:text)).to eq(['a link', 'link in a form'])
60
- end
61
- end
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)
62
22
  end
63
23
 
64
- context 'method found on page_element' do
65
- it 'calls page_element method' do
66
- elements_page.class_eval do
67
- def page_method
68
- :called
69
- end
70
- end
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') }
71
27
 
72
- expect(described_class.new(page).page_method).to eq(:called)
73
- end
28
+ described_class.new(element_class.load("<a href='#'>a link</a>")).a_link
74
29
  end
30
+ end
75
31
 
76
- context 'element is prefetched' do
77
- it 'does not call find' do
78
- expect(subject).not_to receive(:find)
79
- described_class.new(page).prefetched
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
80
36
  end
81
- end
82
37
 
83
- context 'method not found on page_element or as a element definition' do
84
- it 'raises an error' do
85
- expect { elements_page.missing_method }.to raise_error(NoMethodError)
86
- end
38
+ expect(described_class.new(element_class.load("<a href='#'>a link</a>")).page_method).to eq(:called)
87
39
  end
88
40
  end
89
41
 
90
- describe '#respond_to?' do
91
- let(:page_element) do
92
- Class.new(Element) do
93
- link(:a_link, css: '.link')
94
- end
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)
95
47
  end
48
+ end
49
+ end
96
50
 
97
- subject do
98
- described_class.new(page_element.new(session))
51
+ describe '#respond_to?' do
52
+ let(:page_element_class) do
53
+ Class.new(PageMagic::Element) do
54
+ link(:a_link, text: 'a link')
99
55
  end
56
+ end
100
57
 
101
- context 'page_element responds to method name' do
102
- it 'returns true' do
103
- expect(subject.respond_to?(:a_link)).to eq(true)
104
- end
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)
105
62
  end
63
+ end
106
64
 
107
- context 'method is not on page_element' do
108
- it 'calls super' do
109
- expect(subject.respond_to?(:methods)).to eq(true)
110
- end
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)
111
69
  end
112
70
  end
113
71
  end