howitzer 2.2.0 → 2.3.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 (124) hide show
  1. checksums.yaml +4 -4
  2. data/CHANGELOG.md +16 -1
  3. data/LICENSE +1 -1
  4. data/README.md +16 -16
  5. data/generators/base_generator.rb +1 -1
  6. data/generators/config/config_generator.rb +1 -4
  7. data/generators/config/templates/boot.rb +1 -1
  8. data/generators/config/templates/capybara.rb +1 -3
  9. data/generators/config/templates/default.yml +5 -19
  10. data/generators/config/templates/drivers/browserstack.rb +1 -1
  11. data/generators/config/templates/drivers/crossbrowsertesting.rb +1 -1
  12. data/generators/config/templates/drivers/headless_chrome.rb +1 -1
  13. data/generators/config/templates/drivers/headless_firefox.rb +1 -1
  14. data/generators/config/templates/drivers/sauce.rb +1 -1
  15. data/generators/config/templates/drivers/selenium.rb +1 -1
  16. data/generators/config/templates/drivers/selenium_grid.rb +2 -2
  17. data/generators/config/templates/drivers/testingbot.rb +1 -1
  18. data/generators/cucumber/templates/env.rb +1 -1
  19. data/generators/cucumber/templates/hooks.rb +8 -2
  20. data/generators/cucumber/templates/transformers.rb +1 -1
  21. data/generators/prerequisites/templates/factory_bot.rb +1 -1
  22. data/generators/root/templates/Gemfile.erb +4 -10
  23. data/generators/rspec/templates/spec_helper.rb +4 -4
  24. data/generators/turnip/templates/spec_helper.rb +4 -4
  25. data/generators/web/templates/example_page.rb +1 -1
  26. data/lib/howitzer/cache.rb +1 -1
  27. data/lib/howitzer/capybara_helpers.rb +27 -7
  28. data/lib/howitzer/email.rb +2 -2
  29. data/lib/howitzer/exceptions.rb +21 -21
  30. data/lib/howitzer/gmail_api/client.rb +13 -4
  31. data/lib/howitzer/log.rb +6 -6
  32. data/lib/howitzer/mailgun_api/client.rb +3 -2
  33. data/lib/howitzer/mailgun_api/response.rb +1 -2
  34. data/lib/howitzer/mailtrap_api/client.rb +1 -1
  35. data/lib/howitzer/meta/actions.rb +13 -16
  36. data/lib/howitzer/meta/element.rb +12 -10
  37. data/lib/howitzer/utils/string_extensions.rb +6 -2
  38. data/lib/howitzer/version.rb +1 -1
  39. data/lib/howitzer/web/base_section.rb +1 -1
  40. data/lib/howitzer/web/capybara_methods_proxy.rb +11 -5
  41. data/lib/howitzer/web/element_dsl.rb +104 -45
  42. data/lib/howitzer/web/iframe_dsl.rb +2 -2
  43. data/lib/howitzer/web/page.rb +4 -14
  44. data/lib/howitzer/web/page_dsl.rb +15 -6
  45. data/lib/howitzer/web/page_validator.rb +25 -26
  46. data/lib/howitzer/web/section.rb +5 -2
  47. data/lib/howitzer/web/section_dsl.rb +64 -30
  48. data/lib/howitzer.rb +2 -2
  49. metadata +24 -161
  50. data/.coveralls.yml +0 -1
  51. data/.gitignore +0 -14
  52. data/.rspec +0 -3
  53. data/.rubocop.yml +0 -60
  54. data/.ruby-gemset +0 -1
  55. data/.travis.yml +0 -8
  56. data/Gemfile +0 -14
  57. data/ISSUE_TEMPLATE.md +0 -16
  58. data/MAINTENANCE.md +0 -32
  59. data/Rakefile +0 -38
  60. data/features/cli_help.feature +0 -31
  61. data/features/cli_new.feature +0 -393
  62. data/features/cli_unknown.feature +0 -17
  63. data/features/cli_update.feature +0 -223
  64. data/features/cli_version.feature +0 -14
  65. data/features/step_definitions/common_steps.rb +0 -34
  66. data/features/support/env.rb +0 -1
  67. data/generators/config/templates/drivers/poltergeist.rb +0 -11
  68. data/generators/config/templates/drivers/webkit.rb +0 -6
  69. data/generators/root/templates/.gitignore +0 -21
  70. data/generators/root/templates/.rubocop.yml.erb +0 -56
  71. data/generators/turnip/templates/.rspec +0 -1
  72. data/howitzer.gemspec +0 -39
  73. data/lib/howitzer/mail_adapters/debugmail.rb +0 -0
  74. data/spec/config/custom.yml +0 -9
  75. data/spec/spec_helper.rb +0 -73
  76. data/spec/support/generator_helper.rb +0 -21
  77. data/spec/support/logger_helper.rb +0 -13
  78. data/spec/support/shared_examples/capybara_context_holder.rb +0 -33
  79. data/spec/support/shared_examples/capybara_methods_proxy.rb +0 -94
  80. data/spec/support/shared_examples/dynamic_section_methods.rb +0 -35
  81. data/spec/support/shared_examples/element_dsl.rb +0 -242
  82. data/spec/support/shared_examples/meta_highlight_xpath.rb +0 -41
  83. data/spec/unit/generators/base_generator_spec.rb +0 -283
  84. data/spec/unit/generators/config_generator_spec.rb +0 -61
  85. data/spec/unit/generators/cucumber_generator_spec.rb +0 -62
  86. data/spec/unit/generators/emails_generator_spec.rb +0 -35
  87. data/spec/unit/generators/prerequisites_generator_spec.rb +0 -53
  88. data/spec/unit/generators/root_generator_spec.rb +0 -86
  89. data/spec/unit/generators/rspec_generator_spec.rb +0 -36
  90. data/spec/unit/generators/tasks_generator_spec.rb +0 -31
  91. data/spec/unit/generators/templates/cucumber_spec.rb +0 -97
  92. data/spec/unit/generators/templates/rspec_spec.rb +0 -88
  93. data/spec/unit/generators/templates/turnip_spec.rb +0 -98
  94. data/spec/unit/generators/turnip_generator_spec.rb +0 -52
  95. data/spec/unit/generators/web_generator_spec.rb +0 -52
  96. data/spec/unit/lib/cache_spec.rb +0 -85
  97. data/spec/unit/lib/capybara_helpers_spec.rb +0 -730
  98. data/spec/unit/lib/email_spec.rb +0 -186
  99. data/spec/unit/lib/gmail_api/client_spec.rb +0 -26
  100. data/spec/unit/lib/howitzer_spec.rb +0 -92
  101. data/spec/unit/lib/init_spec.rb +0 -2
  102. data/spec/unit/lib/log_spec.rb +0 -122
  103. data/spec/unit/lib/mail_adapters/abstract_spec.rb +0 -62
  104. data/spec/unit/lib/mail_adapters/gmail_spec.rb +0 -128
  105. data/spec/unit/lib/mail_adapters/mailgun_spec.rb +0 -158
  106. data/spec/unit/lib/mail_adapters/mailtrap_spec.rb +0 -130
  107. data/spec/unit/lib/mailgun_api/client_spec.rb +0 -80
  108. data/spec/unit/lib/mailgun_api/connector_spec.rb +0 -54
  109. data/spec/unit/lib/mailgun_api/response_spec.rb +0 -28
  110. data/spec/unit/lib/mailtrap_api/client_spec.rb +0 -67
  111. data/spec/unit/lib/meta/element_spec.rb +0 -59
  112. data/spec/unit/lib/meta/entry_spec.rb +0 -77
  113. data/spec/unit/lib/meta/iframe_spec.rb +0 -66
  114. data/spec/unit/lib/meta/section_spec.rb +0 -43
  115. data/spec/unit/lib/utils/string_extensions_spec.rb +0 -77
  116. data/spec/unit/lib/web/base_section_spec.rb +0 -43
  117. data/spec/unit/lib/web/element_dsl_spec.rb +0 -31
  118. data/spec/unit/lib/web/iframe_dsl_spec.rb +0 -203
  119. data/spec/unit/lib/web/page_dsl_spec.rb +0 -74
  120. data/spec/unit/lib/web/page_spec.rb +0 -385
  121. data/spec/unit/lib/web/page_validator_spec.rb +0 -276
  122. data/spec/unit/lib/web/section_dsl_spec.rb +0 -165
  123. data/spec/unit/lib/web/section_spec.rb +0 -70
  124. data/spec/unit/version_spec.rb +0 -8
@@ -1,385 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/web/page'
3
- require 'howitzer/web/blank_page'
4
-
5
- RSpec.describe Howitzer::Web::Page do
6
- let(:session) { double(:session) }
7
- before { allow(Capybara).to receive(:current_session) { session } }
8
- describe '.open' do
9
- let(:retryable) { double }
10
- let(:check_correct_page_loaded) { double }
11
- let(:other_instance) { described_class.instance }
12
-
13
- context 'when custom user_agent specified' do
14
- let(:url_value) { 'http://example.com/users' }
15
- let(:driver) { double }
16
- subject { described_class.open(validate: false) }
17
- before do
18
- allow(Howitzer).to receive(:user_agent) { 'user_agent' }
19
- allow(described_class).to receive(:retryable)
20
- allow(described_class).to receive(:expanded_url)
21
- allow(Howitzer::Log).to receive(:info)
22
- end
23
- context 'with webkit driver' do
24
- before { allow(Howitzer).to receive(:driver) { 'webkit' } }
25
- it do
26
- expect(Capybara).to receive_message_chain(:current_session, :driver) { driver }
27
- expect(driver).to receive(:header).with('User-Agent', Howitzer.user_agent)
28
- subject
29
- end
30
- end
31
- context 'with poltergeist driver' do
32
- before { allow(Howitzer).to receive(:driver) { 'poltergeist' } }
33
- it do
34
- expect(Capybara).to receive_message_chain(:current_session, :driver) { driver }
35
- expect(driver).to receive(:add_headers).with('User-Agent' => Howitzer.user_agent)
36
- subject
37
- end
38
- end
39
- end
40
-
41
- context 'when validate missing' do
42
- context 'when params present' do
43
- let(:url_value) { 'http://example.com/users/1' }
44
- subject { described_class.open(id: 1) }
45
- it do
46
- expect(described_class).to receive(:expanded_url).with({ id: 1 }, nil) { url_value }.once.ordered
47
- expect(Howitzer::Log).to receive(:info)
48
- .with("Open #{described_class} page by '#{url_value}' url").once.ordered
49
- expect(described_class).to receive(:retryable).ordered.once.and_call_original
50
- expect(session).to receive(:visit).with(url_value).once.ordered
51
- expect(described_class).to receive(:given).once.ordered.and_return(true)
52
- expect(subject).to eq(true)
53
- end
54
- end
55
- context 'when custom processor specified' do
56
- let(:custom_processor) { double }
57
- let(:url_value) { 'http://example.com/users/1' }
58
- subject { described_class.open(id: 1, url_processor: custom_processor) }
59
- it do
60
- expect(described_class).to receive(:expanded_url).with({ id: 1 }, custom_processor) { url_value }.once.ordered
61
- expect(Howitzer::Log).to receive(:info)
62
- .with("Open #{described_class} page by '#{url_value}' url").once.ordered
63
- expect(described_class).to receive(:retryable).ordered.once.and_call_original
64
- expect(session).to receive(:visit).with(url_value).once.ordered
65
- expect(described_class).to receive(:given).once.ordered.and_return(true)
66
- expect(subject).to eq(true)
67
- end
68
- end
69
- context 'when params missing' do
70
- let(:url_value) { 'http://example.com/users' }
71
- subject { described_class.open }
72
- it do
73
- expect(described_class).to receive(:expanded_url).with({}, nil).and_return(url_value).once.ordered
74
- expect(Howitzer::Log).to receive(:info)
75
- .with("Open #{described_class} page by '#{url_value}' url").once.ordered
76
- expect(described_class).to receive(:retryable).ordered.once.and_call_original
77
- expect(session).to receive(:visit).with(url_value).once.ordered
78
- expect(described_class).to receive(:given).once.ordered.and_return(true)
79
- expect(subject).to eq(true)
80
- end
81
- end
82
- end
83
- context 'when validate: false' do
84
- let(:url_value) { 'http://example.com/users' }
85
- subject { described_class.open(validate: false) }
86
- it do
87
- expect(described_class).to receive(:expanded_url).with({}, nil).and_return(url_value).once.ordered
88
- expect(Howitzer::Log).to receive(:info).with("Open #{described_class} page by '#{url_value}' url").once.ordered
89
- expect(described_class).to receive(:retryable).ordered.once.and_call_original
90
- expect(session).to receive(:visit).with(url_value).once.ordered
91
- expect(described_class).not_to receive(:given)
92
- expect(subject).to be_nil
93
- end
94
- end
95
- context 'when validate: true with params' do
96
- let(:url_value) { 'http://example.com/users/1' }
97
- subject { described_class.open(validate: true, id: 1) }
98
- it do
99
- expect(described_class).to receive(:expanded_url).with({ id: 1 }, nil).and_return(url_value).once.ordered
100
- expect(Howitzer::Log).to receive(:info).with("Open #{described_class} page by '#{url_value}' url").once.ordered
101
- expect(described_class).to receive(:retryable).ordered.once.and_call_original
102
- expect(session).to receive(:visit).with(url_value).once.ordered
103
- expect(described_class).to receive(:given).once.ordered.and_return(true)
104
- expect(subject).to eq(true)
105
- end
106
- end
107
- end
108
-
109
- describe '.given' do
110
- subject { described_class.given }
111
- before do
112
- expect(described_class).to receive(:displayed?).with(no_args).once
113
- expect(described_class).to receive(:instance).and_return(true)
114
- end
115
- it { is_expected.to be_truthy }
116
- end
117
-
118
- describe '.title' do
119
- let(:page) { double }
120
- subject { described_class.instance.title }
121
- before do
122
- allow_any_instance_of(described_class).to receive(:check_validations_are_defined!).and_return(true)
123
- allow(session).to receive(:current_url).and_return('google.com')
124
- end
125
- it do
126
- expect(session).to receive(:title)
127
- subject
128
- end
129
- end
130
-
131
- describe '.current_page' do
132
- subject { described_class.current_page }
133
- context 'when matched_pages has no pages' do
134
- before { allow(described_class).to receive(:matched_pages).and_return([]) }
135
- it { is_expected.to eq(described_class::UnknownPage) }
136
- end
137
- context 'when matched_pages has more than 1 page' do
138
- let(:foo_page) { double(inspect: 'FooPage') }
139
- let(:bar_page) { double(inspect: 'BarPage') }
140
- before do
141
- allow_any_instance_of(described_class).to receive(:check_validations_are_defined!).and_return(true)
142
- allow(session).to receive(:current_url).and_return('http://test.com')
143
- allow(session).to receive(:title) { 'Test site' }
144
- allow(described_class).to receive(:matched_pages).and_return([foo_page, bar_page])
145
- end
146
- it do
147
- expect { subject }.to raise_error(
148
- Howitzer::AmbiguousPageMatchingError,
149
- "Current page matches more that one page class (FooPage, BarPage).\n" \
150
- "\tCurrent url: http://test.com\n\tCurrent title: Test site"
151
- )
152
- end
153
- end
154
- context 'when matched_pages has only 1 page' do
155
- let(:foo_page) { double(to_s: 'FooPage') }
156
- before { allow(described_class).to receive(:matched_pages).and_return([foo_page]) }
157
- it { is_expected.to eq(foo_page) }
158
- end
159
- end
160
-
161
- describe '.displayed?' do
162
- subject { described_class.displayed? }
163
- context 'when page is opened' do
164
- before { allow(described_class).to receive(:opened?).and_return(true) }
165
- it { is_expected.to eq(true) }
166
- end
167
- context 'when page is not opened' do
168
- before do
169
- allow(described_class).to receive(:current_page).and_return('FooPage')
170
- allow(session).to receive(:current_url).and_return('http://test.com')
171
- allow(session).to receive(:title).and_return('Test site')
172
- allow(described_class).to receive(:opened?).and_return(false)
173
- end
174
- it do
175
- expect { subject }.to raise_error(
176
- Howitzer::IncorrectPageError,
177
- "Current page: FooPage, expected: #{described_class}.\n" \
178
- "\tCurrent url: http://test.com\n\tCurrent title: Test site"
179
- )
180
- end
181
- end
182
- end
183
-
184
- describe '.current_url' do
185
- before { allow(Capybara).to receive_message_chain(:current_session, :current_url).and_return('http://example.com') }
186
- it 'should return current url page' do
187
- expect(Howitzer::Web::Page.current_url).to eq('http://example.com')
188
- end
189
- end
190
-
191
- describe '.site' do
192
- let!(:base_class) do
193
- Class.new(described_class) do
194
- site 'https://base.com'
195
- end
196
- end
197
- let!(:child_class1) do
198
- Class.new(base_class) do
199
- site 'https://child.com'
200
- end
201
- end
202
- let!(:child_class2) do
203
- Class.new(base_class)
204
- end
205
- let!(:child_class3) do
206
- Class.new(described_class)
207
- end
208
- it { expect(described_class.send(:site_value)).to eq('http://login:pass@my.website.com') }
209
- it { expect(base_class.send(:site_value)).to eq('https://base.com') }
210
- it { expect(child_class1.send(:site_value)).to eq('https://child.com') }
211
- it { expect(child_class2.send(:site_value)).to eq('https://base.com') }
212
- it { expect(child_class3.send(:site_value)).to eq('http://login:pass@my.website.com') }
213
- it 'should be protected' do
214
- expect { described_class.site('http://example.com') }.to raise_error(NoMethodError)
215
- end
216
- end
217
-
218
- describe '.expanded_url' do
219
- context 'when default url processor' do
220
- context 'when params present' do
221
- subject { test_page.expanded_url(id: 1) }
222
- context 'when page url specified' do
223
- context 'when BlankPage' do
224
- let(:test_page) { Howitzer::Web::BlankPage }
225
- it { is_expected.to eq('about:blank') }
226
- end
227
- context 'when other page' do
228
- let(:test_page) do
229
- Class.new(described_class) do
230
- site 'http://example.com'
231
- path '/users{/id}'
232
- end
233
- end
234
- it { is_expected.to eq('http://example.com/users/1') }
235
- end
236
- context 'when root not specified' do
237
- let(:test_page) do
238
- Class.new(described_class) do
239
- path '/users{/id}'
240
- end
241
- end
242
- it { is_expected.to eq('http://login:pass@my.website.com/users/1') }
243
- end
244
- end
245
- end
246
- context 'when custom url processor' do
247
- let(:test_page) do
248
- Class.new(described_class) do
249
- site 'http://example.com'
250
- path '/users{/id}'
251
- end
252
- end
253
- let(:custom_processor_class) do
254
- Class.new do
255
- def self.restore(_name, value)
256
- value.tr('-', ' ')
257
- end
258
-
259
- def self.match(_name)
260
- '.*'
261
- end
262
-
263
- def self.validate(_name, value)
264
- !(value =~ /^[\w ]+$/).nil?
265
- end
266
-
267
- def self.transform(_name, value)
268
- value.tr(' ', '+')
269
- end
270
- end
271
- end
272
- subject { test_page.expanded_url({ id: 'hello world' }, custom_processor_class) }
273
- it { is_expected.to eq('http://example.com/users/hello+world') }
274
- end
275
- context 'when page url missing' do
276
- subject { described_class.expanded_url }
277
- it do
278
- expect { subject }.to raise_error(
279
- ::Howitzer::NoPathForPageError,
280
- "Please specify path for '#{described_class}' page. Example: path '/home'"
281
- )
282
- end
283
- end
284
- end
285
- context 'when params missing' do
286
- let(:test_page) do
287
- Class.new(described_class) do
288
- site 'http://example.com'
289
- path '/users'
290
- end
291
- end
292
- subject { test_page.expanded_url }
293
- it { is_expected.to eq('http://example.com/users') }
294
- end
295
- end
296
-
297
- describe '.path' do
298
- subject { described_class.send(:path, value) }
299
- before { subject }
300
- context 'when value is number' do
301
- let(:value) { 1 }
302
- it do
303
- expect(described_class.send(:path_value)).to eql '1'
304
- expect(described_class.private_methods(true)).to include(:path_value)
305
- end
306
- end
307
- context 'when value is string' do
308
- let(:value) { '/users' }
309
- it do
310
- expect(described_class.send(:path_value)).to eql '/users'
311
- end
312
- end
313
- end
314
-
315
- describe '#initialize' do
316
- subject { described_class.send(:new) }
317
- before do
318
- expect_any_instance_of(described_class).to receive(:check_validations_are_defined!).once.and_return(true)
319
- end
320
- context 'when maximized_window is true' do
321
- let(:driver) { double }
322
- before { allow(Howitzer).to receive(:maximized_window) { true } }
323
- it do
324
- expect_any_instance_of(described_class).to receive_message_chain('current_window.maximize')
325
- subject
326
- end
327
- end
328
- context 'when maximized_window is true and driver is headless_chrome' do
329
- before do
330
- allow(Howitzer).to receive(:maximized_window) { true }
331
- allow(Capybara).to receive(:current_driver) { 'headless_chrome' }
332
- end
333
- it do
334
- expect_any_instance_of(described_class).not_to receive('current_window.maximize')
335
- subject
336
- end
337
- end
338
- context 'when maximized_window is false' do
339
- before { allow(Howitzer).to receive(:maximized_window) { false } }
340
- it do
341
- expect_any_instance_of(described_class).not_to receive('current_window.maximize')
342
- subject
343
- end
344
- end
345
- end
346
-
347
- describe 'inherited callback' do
348
- let(:page_class) { Class.new(described_class) }
349
- it 'can not be instantiated with new' do
350
- expect { page_class.new }.to raise_error(NoMethodError, "private method `new' called for #{page_class}")
351
- end
352
- end
353
-
354
- describe '#reload' do
355
- let(:wait_for_url) { double }
356
- subject { described_class.instance.reload }
357
- let(:visit) { double }
358
- before do
359
- allow(session).to receive(:current_url).and_return('google.com')
360
- end
361
- it do
362
- expect(Howitzer::Log).to receive(:info).and_return("Reload 'google.com'")
363
- expect(session).to receive(:visit).with('google.com')
364
- subject
365
- end
366
- end
367
-
368
- describe '#capybara_context' do
369
- subject { described_class.instance.capybara_context }
370
- before { expect(Capybara).to receive(:current_session).and_return(:context) }
371
- it { is_expected.to eq(:context) }
372
- end
373
-
374
- describe '#meta' do
375
- let(:page) { described_class.instance }
376
- it { expect(page.instance_variable_get(:@meta)).to be_nil }
377
- it { expect(page.meta).to be_an_instance_of(Howitzer::Meta::Entry) }
378
- it { expect(page.meta.context).to eq(page) }
379
- end
380
-
381
- describe 'includes proxied capybara methods' do
382
- let(:reciever) { described_class.instance }
383
- include_examples :capybara_methods_proxy
384
- end
385
- end
@@ -1,276 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/web/page_validator'
3
- require 'howitzer/web/element_dsl'
4
-
5
- RSpec.describe Howitzer::Web::PageValidator do
6
- describe '.validations' do
7
- it { expect(subject.validations).to be_a(Hash) }
8
- end
9
-
10
- let(:web_page_class) do
11
- Class.new do
12
- include Howitzer::Web::ElementDsl
13
- include Howitzer::Web::PageValidator
14
- element :foo, 'a'
15
- element :bar, :xpath, ->(v) { v }
16
- def self.name
17
- 'TestWebPageClass'
18
- end
19
- end
20
- end
21
- let(:web_page) { web_page_class.new }
22
- describe '#check_validations_are_defined!' do
23
- subject { web_page.check_validations_are_defined! }
24
- context 'when no validation specified' do
25
- it do
26
- expect { subject }.to raise_error(
27
- Howitzer::NoValidationError,
28
- "No any page validation was found for 'TestWebPageClass' page"
29
- )
30
- end
31
- end
32
- context 'when title validation is specified' do
33
- before do
34
- web_page.class.validate :title, /Foo/
35
- end
36
- it { expect { subject }.to_not raise_error }
37
- end
38
- context 'when url validation is specified' do
39
- before do
40
- web_page.class.validate :url, /Foo/
41
- end
42
- it { expect { subject }.to_not raise_error }
43
- end
44
- context 'when element_presence validation is specified' do
45
- context 'when simple selector' do
46
- before do
47
- web_page.class.validate :element_presence, :foo
48
- end
49
- it { expect { subject }.to_not raise_error }
50
- end
51
-
52
- context 'when lambda selector' do
53
- before do
54
- web_page.class.validate :element_presence, :bar, 'some_text'
55
- end
56
- it { expect { subject }.to_not raise_error }
57
- end
58
- end
59
- end
60
-
61
- describe '.validate' do
62
- before do
63
- described_class.validations[web_page.class] = nil
64
- end
65
- let(:additional_value) { nil }
66
- subject { web_page.class.validate(name, *[value, additional_value].compact) }
67
- context 'when name = :url' do
68
- context 'as string' do
69
- let(:name) { 'url' }
70
- context '(as string)' do
71
- let(:value) { 'foo' }
72
- it do
73
- is_expected.to be_a(Proc)
74
- expect(described_class.validations[web_page.class][:url]).to be_a Proc
75
- end
76
- end
77
- context '(as regexp)' do
78
- let(:value) { /foo/ }
79
- it do
80
- is_expected.to be_a(Proc)
81
- expect(described_class.validations[web_page.class][:url]).to be_a Proc
82
- end
83
- end
84
- end
85
- context 'as symbol' do
86
- let(:name) { :url }
87
- let(:value) { /foo/ }
88
- it do
89
- is_expected.to be_a(Proc)
90
- expect(described_class.validations[web_page.class][:url]).to be_a Proc
91
- end
92
- end
93
- end
94
- context 'when name = :element_presence' do
95
- let(:name) { :element_presence }
96
- context '(as string)' do
97
- let(:value) { 'bar' }
98
- let(:additional_value) { 'some string' }
99
- it do
100
- is_expected.to be_a(Proc)
101
- expect(described_class.validations[web_page.class][:element_presence]).to eql(subject)
102
- end
103
- end
104
- context '(as symbol)' do
105
- let(:value) { :foo }
106
- it do
107
- is_expected.to be_a(Proc)
108
- expect(described_class.validations[web_page.class][:element_presence]).to eql(subject)
109
- end
110
- end
111
-
112
- context 'when refers to unknown element' do
113
- let(:value) { :unknown }
114
- it do
115
- subject
116
- expect do
117
- described_class.validations[web_page.class][:element_presence].call(web_page, false)
118
- end.to raise_error(
119
- Howitzer::UndefinedElementError,
120
- ":element_presence validation refers to undefined 'unknown' element on 'TestWebPageClass' page."
121
- )
122
- end
123
- end
124
- end
125
- context 'when name = :title' do
126
- let(:name) { :title }
127
- context '(as string)' do
128
- let(:value) { 'foo' }
129
- it do
130
- is_expected.to be_a(Proc)
131
- expect(described_class.validations[web_page.class][:title]).to be_a Proc
132
- end
133
- end
134
- context '(as regexp)' do
135
- let(:value) { /foo/ }
136
- it do
137
- is_expected.to be_a(Proc)
138
- expect(described_class.validations[web_page.class][:title]).to be_a Proc
139
- end
140
- end
141
- end
142
- context 'when other name' do
143
- let(:name) { :unknown }
144
- let(:value) { '' }
145
- it do
146
- expect { subject }.to raise_error(Howitzer::UnknownValidationError, "unknown 'unknown' validation type")
147
- end
148
- end
149
- end
150
-
151
- describe '.opened?' do
152
- context 'when no one validation is defined' do
153
- subject { web_page_class.opened? }
154
- it do
155
- expect { subject }.to raise_error(
156
- Howitzer::NoValidationError,
157
- "No any page validation was found for 'TestWebPageClass' page"
158
- )
159
- end
160
- end
161
- context 'when all validations are defined' do
162
- context 'when sync is default' do
163
- subject { web_page_class.opened? }
164
- before do
165
- web_page_class.class_eval do
166
- include Singleton
167
- element :login, '#id'
168
- validate :url, /foo/
169
- validate :title, /Foo page/
170
- validate :element_presence, :login
171
- end
172
- end
173
- context 'when all matches' do
174
- before do
175
- allow(web_page_class.instance).to receive(:current_url).and_return('http://test.com/foo')
176
- allow(web_page_class.instance).to receive(:has_title?).and_return('Foo page')
177
- allow(web_page_class.instance).to receive(:has_login_element?).with(no_args).and_return(true)
178
- end
179
- it { is_expected.to be_truthy }
180
- end
181
- context 'when first validation fails' do
182
- before do
183
- expect(web_page_class.instance).to receive(:current_url).once.and_return('http://test.com/bar')
184
- expect(web_page_class.instance).to receive(:has_title?).never
185
- allow(web_page_class).to receive(:has_login_element?).with(no_args).never
186
- end
187
- it { is_expected.to be_falsey }
188
- end
189
- end
190
-
191
- context 'when sync is true' do
192
- subject { web_page_class.opened?(sync: true) }
193
- before do
194
- web_page_class.class_eval do
195
- include Singleton
196
- element :login, '#id'
197
- validate :url, /foo/
198
- validate :title, /Foo page/
199
- validate :element_presence, :login
200
- end
201
- end
202
- context 'when all matches' do
203
- before do
204
- allow(web_page_class.instance).to receive(:current_url).and_return('http://test.com/foo')
205
- allow(web_page_class.instance).to receive(:has_title?).and_return('Foo page')
206
- allow(web_page_class.instance).to receive(:has_login_element?).with(no_args).and_return(true)
207
- end
208
- it { is_expected.to be_truthy }
209
- end
210
- context 'when first validation fails' do
211
- before do
212
- expect(web_page_class.instance).to receive(:current_url).once.and_return('http://test.com/bar')
213
- expect(web_page_class.instance).to receive(:has_title?).never
214
- allow(web_page_class).to receive(:has_login_element?).with(no_args).never
215
- end
216
- it { is_expected.to be_falsey }
217
- end
218
- end
219
-
220
- context 'when sync is false' do
221
- subject { web_page_class.opened?(sync: false) }
222
- before do
223
- web_page_class.class_eval do
224
- include Singleton
225
- element :login, '#id'
226
- validate :url, /foo/
227
- validate :title, /Foo page/
228
- validate :element_presence, :login
229
- end
230
- end
231
- context 'when all matches' do
232
- before do
233
- allow(web_page_class.instance).to receive(:current_url).and_return('http://test.com/foo')
234
- allow(web_page_class.instance).to receive(:title).and_return('Foo page')
235
- allow(web_page_class.instance).to receive(:has_no_login_element?).with(no_args).and_return(false)
236
- end
237
- it { is_expected.to be_truthy }
238
- end
239
- context 'when first validation fails' do
240
- before do
241
- expect(web_page_class.instance).to receive(:current_url).once.and_return('http://test.com/bar')
242
- expect(web_page_class.instance).to receive(:title).never
243
- allow(web_page_class).to receive(:has_no_login_element?).with(no_args).never
244
- end
245
- it { is_expected.to be_falsey }
246
- end
247
- end
248
- end
249
- end
250
-
251
- describe 'web_page.validations' do
252
- it { expect(web_page_class.validations).to be_a(Hash) }
253
- end
254
-
255
- describe '#matched_pages' do
256
- let!(:web_page1_class) do
257
- Class.new do
258
- include Howitzer::Web::PageValidator
259
- end
260
- end
261
- let!(:web_page2_class) do
262
- Class.new do
263
- include Howitzer::Web::PageValidator
264
- end
265
- end
266
- subject { web_page2_class.matched_pages }
267
- before do
268
- allow(Howitzer::Web::PageValidator).to receive(:validations).with(no_args) do
269
- { web_page1_class => 1, web_page2_class => 2 }
270
- end
271
- expect(web_page1_class).to receive(:opened?).with(sync: false).and_return(true)
272
- expect(web_page2_class).to receive(:opened?).with(sync: false).and_return(false)
273
- end
274
- it { is_expected.to eq([web_page1_class]) }
275
- end
276
- end