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.
- checksums.yaml +4 -4
- data/.rubocop.yml +5 -2
- data/.zsh_config +5 -5
- data/Dockerfile +2 -1
- data/Gemfile +2 -1
- data/Gemfile.lock +9 -5
- data/Makefile +7 -3
- data/README.md +16 -4
- data/VERSION +1 -1
- data/lib/active_support/core_ext/object/to_query.rb +6 -6
- data/lib/page_magic.rb +15 -16
- data/lib/page_magic/class_methods.rb +1 -1
- data/lib/page_magic/comparator.rb +37 -0
- data/lib/page_magic/comparator/fuzzy.rb +23 -0
- data/lib/page_magic/comparator/literal.rb +22 -0
- data/lib/page_magic/comparator/null.rb +26 -0
- data/lib/page_magic/comparator/parameter_map.rb +52 -0
- data/lib/page_magic/drivers.rb +2 -2
- data/lib/page_magic/element.rb +19 -8
- data/lib/page_magic/element/locators.rb +4 -4
- data/lib/page_magic/element/not_found.rb +38 -0
- data/lib/page_magic/element/query.rb +19 -27
- data/lib/page_magic/element/query/multiple_results.rb +21 -0
- data/lib/page_magic/element/query/prefetched_result.rb +26 -0
- data/lib/page_magic/element/query/single_result.rb +20 -0
- data/lib/page_magic/element/selector.rb +38 -16
- data/lib/page_magic/element/selector/methods.rb +18 -0
- data/lib/page_magic/element/selector/model.rb +21 -0
- data/lib/page_magic/element_context.rb +5 -21
- data/lib/page_magic/element_definition_builder.rb +17 -24
- data/lib/page_magic/elements.rb +62 -102
- data/lib/page_magic/elements/config.rb +103 -0
- data/lib/page_magic/elements/inheritance_hooks.rb +15 -0
- data/lib/page_magic/elements/types.rb +25 -0
- data/lib/page_magic/exceptions.rb +3 -0
- data/lib/page_magic/instance_methods.rb +2 -2
- data/lib/page_magic/mapping.rb +79 -0
- data/lib/page_magic/session.rb +10 -32
- data/lib/page_magic/session_methods.rb +1 -1
- data/lib/page_magic/transitions.rb +49 -0
- data/lib/page_magic/utils/string.rb +4 -0
- data/lib/page_magic/utils/url.rb +20 -0
- data/lib/page_magic/watcher.rb +10 -17
- data/lib/page_magic/watchers.rb +28 -15
- data/spec/page_magic/class_methods_spec.rb +64 -37
- data/spec/page_magic/comparator/fuzzy_spec.rb +44 -0
- data/spec/page_magic/comparator/literal_spec.rb +41 -0
- data/spec/page_magic/comparator/null_spec.rb +35 -0
- data/spec/page_magic/comparator/parameter_map_spec.rb +75 -0
- data/spec/page_magic/driver_spec.rb +25 -29
- data/spec/page_magic/drivers/poltergeist_spec.rb +4 -7
- data/spec/page_magic/drivers/rack_test_spec.rb +4 -9
- data/spec/page_magic/drivers/selenium_spec.rb +9 -12
- data/spec/page_magic/drivers_spec.rb +36 -29
- data/spec/page_magic/element/locators_spec.rb +26 -25
- data/spec/page_magic/element/not_found_spec.rb +24 -0
- data/spec/page_magic/element/query/multiple_results_spec.rb +14 -0
- data/spec/page_magic/element/query/single_result_spec.rb +21 -0
- data/spec/page_magic/element/query_spec.rb +26 -47
- data/spec/page_magic/element/selector_spec.rb +118 -110
- data/spec/page_magic/element_context_spec.rb +46 -88
- data/spec/page_magic/element_definition_builder_spec.rb +12 -71
- data/spec/page_magic/element_spec.rb +256 -0
- data/spec/page_magic/elements/config_spec.rb +200 -0
- data/spec/page_magic/elements_spec.rb +87 -138
- data/spec/page_magic/instance_methods_spec.rb +63 -63
- data/spec/page_magic/mapping_spec.rb +181 -0
- data/spec/page_magic/session_methods_spec.rb +27 -25
- data/spec/page_magic/session_spec.rb +109 -198
- data/spec/page_magic/transitions_spec.rb +43 -0
- data/spec/page_magic/utils/string_spec.rb +20 -27
- data/spec/page_magic/utils/url_spec.rb +9 -0
- data/spec/page_magic/wait_methods_spec.rb +14 -22
- data/spec/page_magic/watcher_spec.rb +22 -0
- data/spec/page_magic/watchers_spec.rb +56 -62
- data/spec/page_magic_spec.rb +27 -24
- data/spec/spec_helper.rb +7 -3
- data/spec/support/shared_examples.rb +15 -17
- metadata +48 -15
- data/lib/page_magic/element/query_builder.rb +0 -61
- data/lib/page_magic/element/selector_methods.rb +0 -16
- data/lib/page_magic/matcher.rb +0 -130
- data/spec/element_spec.rb +0 -251
- data/spec/page_magic/element/query_builder_spec.rb +0 -110
- data/spec/page_magic/matcher_spec.rb +0 -338
- data/spec/support/shared_contexts/files_context.rb +0 -9
- data/spec/support/shared_contexts/nested_elements_html_context.rb +0 -18
- data/spec/support/shared_contexts/rack_application_context.rb +0 -11
- data/spec/support/shared_contexts/webapp_fixture_context.rb +0 -41
- data/spec/watcher_spec.rb +0 -64
@@ -1,38 +1,40 @@
|
|
1
1
|
# frozen_string_literal: true
|
2
2
|
|
3
|
-
|
4
|
-
|
5
|
-
|
6
|
-
|
7
|
-
|
8
|
-
OpenStruct.new(session: session).tap do |o|
|
9
|
-
o.extend(described_class)
|
10
|
-
end
|
3
|
+
require 'ostruct'
|
4
|
+
RSpec.describe PageMagic::SessionMethods do
|
5
|
+
subject(:session_methods) do
|
6
|
+
OpenStruct.new(session: session).tap do |o|
|
7
|
+
o.extend(described_class)
|
11
8
|
end
|
9
|
+
end
|
10
|
+
|
11
|
+
let(:session) do
|
12
|
+
rack_app = instance_double(Proc, call: [200, {}, ['<html><head><title>page1</title></head></html>']])
|
13
|
+
PageMagic.session(application: rack_app, url: '/page1')
|
14
|
+
end
|
12
15
|
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
end
|
16
|
+
describe '#execute_script' do
|
17
|
+
it 'returns the output of Session#execute_script' do
|
18
|
+
allow(session.raw_session).to receive(:execute_script).with(:script).and_return(:result)
|
19
|
+
expect(session_methods.execute_script(:script)).to eq(:result)
|
18
20
|
end
|
21
|
+
end
|
19
22
|
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
end
|
23
|
+
describe '#page' do
|
24
|
+
it 'returns the current page of the session' do
|
25
|
+
expect(session_methods.page).to eq(session.current_page)
|
24
26
|
end
|
27
|
+
end
|
25
28
|
|
26
|
-
|
27
|
-
|
28
|
-
|
29
|
-
end
|
29
|
+
describe '#path' do
|
30
|
+
it 'returns the path of the session' do
|
31
|
+
expect(session_methods.path).to eq(session.current_path)
|
30
32
|
end
|
33
|
+
end
|
31
34
|
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
end
|
35
|
+
describe '#url' do
|
36
|
+
it 'returns the url of the session' do
|
37
|
+
expect(session_methods.url).to eq(session.current_url)
|
36
38
|
end
|
37
39
|
end
|
38
40
|
end
|
@@ -1,253 +1,164 @@
|
|
1
|
-
#
|
2
|
-
module PageMagic
|
3
|
-
describe Session do
|
4
|
-
let(:page) do
|
5
|
-
Class.new do
|
6
|
-
include PageMagic
|
7
|
-
url 'http://url.com'
|
8
|
-
end
|
9
|
-
end
|
10
|
-
|
11
|
-
subject { described_class.new(browser) }
|
1
|
+
# frozen_string_literal: true
|
12
2
|
|
13
|
-
|
14
|
-
|
3
|
+
RSpec.describe PageMagic::Session do
|
4
|
+
subject(:session) { described_class.new(browser, 'http://base.url') }
|
15
5
|
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
end
|
22
|
-
end
|
6
|
+
let(:page) do
|
7
|
+
Class.new do
|
8
|
+
include PageMagic
|
9
|
+
end
|
10
|
+
end
|
23
11
|
|
24
|
-
|
25
|
-
|
26
|
-
|
12
|
+
let(:browser) do
|
13
|
+
rack_application = Class.new do
|
14
|
+
def self.call(_env)
|
15
|
+
[200, {}, ['ok']]
|
27
16
|
end
|
17
|
+
end
|
28
18
|
|
29
|
-
|
30
|
-
|
31
|
-
allow(browser).to receive(:current_url).and_return(page.url)
|
32
|
-
expect(subject.current_page).to be_an_instance_of(page)
|
33
|
-
end
|
34
|
-
end
|
19
|
+
Capybara::Session.new(:rack_test, rack_application)
|
20
|
+
end
|
35
21
|
|
36
|
-
|
37
|
-
|
38
|
-
|
39
|
-
|
40
|
-
end
|
22
|
+
describe '#current_page' do
|
23
|
+
let(:another_page_class) do
|
24
|
+
Class.new do
|
25
|
+
include PageMagic
|
41
26
|
end
|
42
27
|
end
|
43
28
|
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
end
|
29
|
+
it 'returns the current page' do
|
30
|
+
session.visit(page, url: 'http://base.url')
|
31
|
+
expect(session.current_page).to be_an_instance_of(page)
|
48
32
|
end
|
49
33
|
|
50
|
-
|
51
|
-
it
|
52
|
-
|
34
|
+
context 'when the page url has changed' do
|
35
|
+
it 'returns the mapped page object' do
|
36
|
+
session.define_page_mappings '/another_page1' => another_page_class
|
37
|
+
browser.visit('/another_page1')
|
38
|
+
expect(session.current_page).to be_an_instance_of(another_page_class)
|
53
39
|
end
|
54
40
|
end
|
41
|
+
end
|
55
42
|
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
end
|
43
|
+
describe '#current_path' do
|
44
|
+
it "returns the browser's current path" do
|
45
|
+
browser.visit('/url')
|
46
|
+
expect(session.current_path).to eq(browser.current_path)
|
47
|
+
end
|
48
|
+
end
|
63
49
|
|
64
|
-
|
65
|
-
|
66
|
-
|
67
|
-
|
68
|
-
expect(subject.transitions.key(:page)).to be(expected_matcher)
|
69
|
-
end
|
70
|
-
end
|
50
|
+
describe '#current_url' do
|
51
|
+
it "returns the browser's current url" do
|
52
|
+
browser.visit('/url')
|
53
|
+
expect(session.current_url).to eq(session.current_url)
|
71
54
|
end
|
55
|
+
end
|
72
56
|
|
73
|
-
|
74
|
-
|
75
|
-
|
76
|
-
|
57
|
+
describe '#define_page_mappings' do
|
58
|
+
context 'when the mapping includes a literal' do
|
59
|
+
it 'creates a matcher to contain the specification' do
|
60
|
+
session.define_page_mappings path: :page
|
61
|
+
expect(session.transitions.to_h).to include(PageMagic::Mapping.new(:path) => :page)
|
77
62
|
end
|
63
|
+
end
|
78
64
|
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
84
|
-
end
|
65
|
+
context 'when the mapping is a matcher' do
|
66
|
+
it 'leaves it intact' do
|
67
|
+
expected_matcher = PageMagic::Mapping.new(:page)
|
68
|
+
session.define_page_mappings expected_matcher => :page
|
69
|
+
expect(session.transitions.key(:page)).to be(expected_matcher)
|
85
70
|
end
|
86
71
|
end
|
72
|
+
end
|
87
73
|
|
88
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
74
|
+
describe '#execute_script' do
|
75
|
+
it 'calls the execute script method on the capybara session' do
|
76
|
+
allow(browser).to receive(:execute_script).with(:script).and_return(:result)
|
77
|
+
expect(session.execute_script(:script)).to be(:result)
|
78
|
+
end
|
92
79
|
|
93
|
-
|
94
|
-
|
95
|
-
subject.define_page_mappings '/page' => :mapped_page_using_string
|
96
|
-
expect(subject.instance_eval { find_mapped_page('/page') }).to be(:mapped_page_using_string)
|
97
|
-
end
|
80
|
+
context 'when the Capybara session does not support #execute_script' do
|
81
|
+
let(:browser) { Capybara::Driver::Base.new }
|
98
82
|
|
99
|
-
|
100
|
-
|
101
|
-
|
102
|
-
expect(subject.instance_eval { find_mapped_page('/page') }).to eq(:mapped_page_using_string)
|
103
|
-
end
|
104
|
-
end
|
83
|
+
it 'raises an error' do
|
84
|
+
expected_message = described_class::UNSUPPORTED_OPERATION_MSG
|
85
|
+
expect { session.execute_script(:script) }.to raise_error(PageMagic::NotSupportedException, expected_message)
|
105
86
|
end
|
87
|
+
end
|
88
|
+
end
|
106
89
|
|
107
|
-
|
108
|
-
|
109
|
-
|
90
|
+
describe '#method_missing' do
|
91
|
+
before do
|
92
|
+
page.class_eval do
|
93
|
+
def my_method
|
94
|
+
:called
|
110
95
|
end
|
111
96
|
end
|
112
97
|
end
|
113
98
|
|
114
|
-
|
115
|
-
|
116
|
-
|
117
|
-
|
118
|
-
|
119
|
-
it 'returns matching page mappings' do
|
120
|
-
subject.define_page_mappings '/page' => :mapped_page_using_string
|
121
|
-
expect(subject.instance_eval { matches('/page') }).to eq([:mapped_page_using_string])
|
122
|
-
end
|
99
|
+
it 'delegates to current page' do
|
100
|
+
session = described_class.new(browser).visit(page, url: 'http://base.url')
|
101
|
+
expect(session.my_method).to be(:called)
|
102
|
+
end
|
103
|
+
end
|
123
104
|
|
124
|
-
|
125
|
-
|
126
|
-
|
127
|
-
|
128
|
-
expect(subject.instance_eval { matches('/page') }).to eq(expected_result)
|
129
|
-
end
|
130
|
-
end
|
105
|
+
describe '#respond_to?' do
|
106
|
+
it 'checks self' do
|
107
|
+
session = described_class.new(browser)
|
108
|
+
expect(session.respond_to?(:current_url)).to eq(true)
|
131
109
|
end
|
132
110
|
|
133
|
-
|
134
|
-
|
111
|
+
context 'when method is not on self' do
|
112
|
+
before do
|
135
113
|
page.class_eval do
|
136
114
|
def my_method
|
137
115
|
:called
|
138
116
|
end
|
139
117
|
end
|
140
|
-
|
141
|
-
session = PageMagic::Session.new(browser).visit(page, url: url)
|
142
|
-
expect(session.my_method).to be(:called)
|
143
|
-
end
|
144
|
-
end
|
145
|
-
|
146
|
-
context '#respond_to?' do
|
147
|
-
subject do
|
148
|
-
PageMagic::Session.new(browser).tap do |s|
|
149
|
-
allow(s).to receive(:current_page).and_return(page.new)
|
150
|
-
end
|
151
|
-
end
|
152
|
-
it 'checks self' do
|
153
|
-
expect(subject.respond_to?(:current_url)).to eq(true)
|
154
118
|
end
|
155
119
|
|
156
120
|
it 'checks the current page' do
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
expect(subject.respond_to?(:my_method)).to eq(true)
|
121
|
+
session = described_class.new(browser)
|
122
|
+
session.visit(page, url: '/')
|
123
|
+
expect(session.respond_to?(:my_method)).to eq(true)
|
161
124
|
end
|
162
125
|
end
|
126
|
+
end
|
163
127
|
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
170
|
-
before do
|
171
|
-
base_url << '/'
|
172
|
-
end
|
173
|
-
|
174
|
-
context 'path has / at the beginning' do
|
175
|
-
it 'produces compound url' do
|
176
|
-
expect(subject.send(:url, base_url, path)).to eq(expected_url)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
context 'path does not have / at the beginning' do
|
181
|
-
it 'produces compound url' do
|
182
|
-
expect(subject.send(:url, base_url, "/#{path}")).to eq(expected_url)
|
183
|
-
end
|
184
|
-
end
|
185
|
-
end
|
186
|
-
|
187
|
-
context 'current_url does not have a / on the end' do
|
188
|
-
context 'path has / at the beginning' do
|
189
|
-
it 'produces compound url' do
|
190
|
-
expect(subject.send(:url, base_url, "/#{path}")).to eq(expected_url)
|
191
|
-
end
|
192
|
-
end
|
193
|
-
|
194
|
-
context 'path does not have / at the beginning' do
|
195
|
-
it 'produces compound url' do
|
196
|
-
expect(subject.send(:url, base_url, path)).to eq(expected_url)
|
197
|
-
end
|
198
|
-
end
|
128
|
+
describe '#visit' do
|
129
|
+
context 'when a page is supplied' do
|
130
|
+
it 'sets the current page' do
|
131
|
+
session.define_page_mappings '/page' => page
|
132
|
+
session.visit(page)
|
133
|
+
expect(session.current_page).to be_a(page)
|
199
134
|
end
|
200
|
-
end
|
201
135
|
|
202
|
-
|
203
|
-
|
204
|
-
|
205
|
-
|
136
|
+
it 'uses the base url and the path in the page mappings' do
|
137
|
+
session = described_class.new(browser, 'http://base.url')
|
138
|
+
session.define_page_mappings '/page' => page
|
139
|
+
session.visit(page)
|
140
|
+
expect(session.current_url).to eq('http://base.url/page')
|
206
141
|
end
|
207
142
|
|
208
|
-
|
209
|
-
|
210
|
-
session.define_page_mappings '/page' => page
|
143
|
+
it 'raises an error when page no page mappings are found' do
|
144
|
+
expect do
|
211
145
|
session.visit(page)
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
it 'uses the base url and the path in the page mappings' do
|
216
|
-
session.define_page_mappings '/page' => page
|
217
|
-
expect(browser).to receive(:visit).with("#{url}/page")
|
218
|
-
session.visit(page)
|
219
|
-
end
|
220
|
-
|
221
|
-
context 'no mappings found' do
|
222
|
-
it 'raises an error' do
|
223
|
-
expect { session.visit(page) }.to raise_exception InvalidURLException, described_class::URL_MISSING_MSG
|
224
|
-
end
|
225
|
-
end
|
226
|
-
|
227
|
-
context 'mapping is a regular expression' do
|
228
|
-
it 'raises an error' do
|
229
|
-
session.define_page_mappings(/mapping/ => page)
|
230
|
-
expect { session.visit(page) }.to raise_exception InvalidURLException, described_class::REGEXP_MAPPING_MSG
|
231
|
-
end
|
232
|
-
end
|
146
|
+
end.to raise_exception PageMagic::InvalidURLException, described_class::URL_MISSING_MSG
|
147
|
+
end
|
233
148
|
|
234
|
-
|
235
|
-
|
236
|
-
|
237
|
-
|
238
|
-
|
239
|
-
session.define_page_mappings('/page' => page)
|
240
|
-
session.visit(page)
|
241
|
-
expect(on_load_hook_called).to eq(true)
|
242
|
-
end
|
149
|
+
it 'calls the onload hook' do
|
150
|
+
on_load_hook_called = false
|
151
|
+
page.on_load { on_load_hook_called = true }
|
152
|
+
session.visit(page, url: 'http://base.url')
|
153
|
+
expect(on_load_hook_called).to eq(true)
|
243
154
|
end
|
155
|
+
end
|
244
156
|
|
245
|
-
|
246
|
-
|
247
|
-
|
248
|
-
|
249
|
-
|
250
|
-
end
|
157
|
+
context 'when `url` is supplied' do
|
158
|
+
it 'visits that url' do
|
159
|
+
expected_url = 'http://base.url/page'
|
160
|
+
session.visit(url: expected_url)
|
161
|
+
expect(browser.current_url).to eq(expected_url)
|
251
162
|
end
|
252
163
|
end
|
253
164
|
end
|
@@ -0,0 +1,43 @@
|
|
1
|
+
# frozen_string_literal: true
|
2
|
+
|
3
|
+
RSpec.describe PageMagic::Transitions do
|
4
|
+
describe '#mapped_page' do
|
5
|
+
context 'when a match is match found' do
|
6
|
+
it 'returns the page class' do
|
7
|
+
mappings = described_class.new('/page' => :mapped_page_using_string)
|
8
|
+
expect(mappings.mapped_page('/page')).to be(:mapped_page_using_string)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
context 'when more than one match is found' do
|
13
|
+
it 'returns the most specific match' do
|
14
|
+
mappings = described_class.new(%r{/page} => :mapped_page_using_regex, '/page' => :mapped_page_using_string)
|
15
|
+
expect(mappings.mapped_page('/page')).to eq(:mapped_page_using_string)
|
16
|
+
end
|
17
|
+
end
|
18
|
+
|
19
|
+
context 'when a mapping is not found' do
|
20
|
+
it 'returns nil' do
|
21
|
+
mappings = described_class.new({})
|
22
|
+
expect(mappings.mapped_page('/unmapped_page')).to be(nil)
|
23
|
+
end
|
24
|
+
end
|
25
|
+
end
|
26
|
+
|
27
|
+
describe '#url_for' do
|
28
|
+
it 'returns the url for the mapped page' do
|
29
|
+
page = Object.new
|
30
|
+
mappings = described_class.new('/mapping' => page)
|
31
|
+
expect(mappings.url_for(page, base_url: 'http://base.url')).to eq('http://base.url/mapping')
|
32
|
+
end
|
33
|
+
|
34
|
+
context 'when page mapping is a regular expression' do
|
35
|
+
it 'raises an error' do
|
36
|
+
page = Object.new
|
37
|
+
mappings = described_class.new(/mapping/ => page)
|
38
|
+
expect { mappings.url_for(page, base_url: 'http://base.url') }
|
39
|
+
.to raise_exception PageMagic::InvalidURLException, described_class::REGEXP_MAPPING_MSG
|
40
|
+
end
|
41
|
+
end
|
42
|
+
end
|
43
|
+
end
|