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