howitzer 2.0.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (56) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +3 -0
  3. data/CHANGELOG.md +21 -1
  4. data/features/cli_new.feature +1 -0
  5. data/features/cli_update.feature +1 -0
  6. data/generators/base_generator.rb +3 -1
  7. data/generators/config/templates/capybara.rb +1 -1
  8. data/generators/config/templates/default.yml +4 -2
  9. data/generators/cucumber/cucumber_generator.rb +1 -0
  10. data/generators/cucumber/templates/common_steps.rb +1 -1
  11. data/generators/cucumber/templates/env.rb +0 -28
  12. data/generators/cucumber/templates/hooks.rb +29 -0
  13. data/generators/prerequisites/templates/user.rb +2 -0
  14. data/generators/prerequisites/templates/users.rb +2 -2
  15. data/generators/root/templates/Gemfile.erb +1 -1
  16. data/generators/rspec/templates/spec_helper.rb +9 -2
  17. data/generators/turnip/templates/spec_helper.rb +9 -2
  18. data/generators/web/templates/example_page.rb +0 -1
  19. data/howitzer.gemspec +1 -3
  20. data/lib/howitzer.rb +7 -0
  21. data/lib/howitzer/cache.rb +1 -1
  22. data/lib/howitzer/capybara_helpers.rb +2 -2
  23. data/lib/howitzer/email.rb +26 -8
  24. data/lib/howitzer/exceptions.rb +19 -19
  25. data/lib/howitzer/mail_adapters/abstract.rb +4 -3
  26. data/lib/howitzer/mail_adapters/mailgun.rb +6 -5
  27. data/lib/howitzer/mailgun_api/client.rb +1 -1
  28. data/lib/howitzer/version.rb +1 -1
  29. data/lib/howitzer/web/base_section.rb +3 -3
  30. data/lib/howitzer/web/capybara_context_holder.rb +19 -0
  31. data/lib/howitzer/web/capybara_methods_proxy.rb +27 -19
  32. data/lib/howitzer/web/element_dsl.rb +52 -13
  33. data/lib/howitzer/web/iframe_dsl.rb +3 -7
  34. data/lib/howitzer/web/page.rb +14 -21
  35. data/lib/howitzer/web/page_dsl.rb +32 -4
  36. data/lib/howitzer/web/page_validator.rb +15 -16
  37. data/lib/howitzer/web/section_dsl.rb +3 -7
  38. data/spec/config/custom.yml +1 -1
  39. data/spec/spec_helper.rb +1 -7
  40. data/spec/support/shared_examples/capybara_context_holder.rb +3 -3
  41. data/spec/support/shared_examples/element_dsl.rb +128 -18
  42. data/spec/unit/generators/base_generator_spec.rb +15 -16
  43. data/spec/unit/generators/cucumber_generator_spec.rb +2 -0
  44. data/spec/unit/generators/root_generator_spec.rb +1 -1
  45. data/spec/unit/lib/capybara_helpers_spec.rb +2 -2
  46. data/spec/unit/lib/email_spec.rb +37 -6
  47. data/spec/unit/lib/{howitzer.rb → howitzer_spec.rb} +9 -0
  48. data/spec/unit/lib/mail_adapters/abstract_spec.rb +1 -1
  49. data/spec/unit/lib/mail_adapters/mailgun_spec.rb +4 -4
  50. data/spec/unit/lib/web/base_section_spec.rb +3 -1
  51. data/spec/unit/lib/web/element_dsl_spec.rb +7 -2
  52. data/spec/unit/lib/web/page_dsl_spec.rb +22 -0
  53. data/spec/unit/lib/web/page_spec.rb +79 -44
  54. data/spec/unit/lib/web/page_validator_spec.rb +94 -51
  55. data/spec/unit/lib/web/section_spec.rb +4 -2
  56. metadata +10 -8
@@ -28,6 +28,7 @@ RSpec.describe 'Generators' do
28
28
  },
29
29
  { name: '/features/support', is_directory: true },
30
30
  { name: '/features/support/env.rb', is_directory: false, size: template_file_size('cucumber', 'env.rb') },
31
+ { name: '/features/support/hooks.rb', is_directory: false, size: template_file_size('cucumber', 'hooks.rb') },
31
32
  {
32
33
  name: '/features/support/transformers.rb',
33
34
  is_directory: false,
@@ -43,6 +44,7 @@ RSpec.describe 'Generators' do
43
44
  " * Cucumber integration to the framework ...
44
45
  Added 'features/step_definitions/common_steps.rb' file
45
46
  Added 'features/support/env.rb' file
47
+ Added 'features/support/hooks.rb' file
46
48
  Added 'features/support/transformers.rb' file
47
49
  Added 'features/example.feature' file
48
50
  Added 'tasks/cucumber.rake' file\n"
@@ -16,7 +16,7 @@ RSpec.describe 'Generators' do
16
16
  [
17
17
  { name: '/.gitignore', is_directory: false, size: 196 },
18
18
  { name: '/.rubocop.yml', is_directory: false, size: 584 },
19
- { name: '/Gemfile', is_directory: false, size: 605 },
19
+ { name: '/Gemfile', is_directory: false, size: 625 },
20
20
  { name: '/Rakefile', is_directory: false, size: template_file_size('root', 'Rakefile') }
21
21
  ]
22
22
  end
@@ -681,8 +681,8 @@ RSpec.describe Howitzer::CapybaraHelpers do
681
681
  describe '.load_driver_gem!' do
682
682
  subject { load_driver_gem!(:webkit, 'capybara-webkit', 'capybara-webkit') }
683
683
  context 'when possible to require' do
684
- before { allow(self).to receive(:require).with(:webkit) { true } }
685
- it { expect { subject }.not_to raise_error(LoadError) }
684
+ before { allow(self).to receive(:require).with('capybara-webkit') { true } }
685
+ it { expect { subject }.not_to raise_error }
686
686
  end
687
687
  context 'when impossible to require' do
688
688
  it do
@@ -37,22 +37,43 @@ RSpec.describe Howitzer::Email do
37
37
  describe '.subject' do
38
38
  it do
39
39
  described_class.send(:subject, message_subject)
40
- expect(described_class.instance_variable_get(:@subject)).to eql message_subject
40
+ expect(described_class.send(:subject_value)).to eql message_subject
41
+ expect(described_class.private_methods(true)).to include(:subject_value)
41
42
  end
42
43
  it 'should be protected' do
43
44
  expect { described_class.subject(message_subject) }.to raise_error(NoMethodError)
44
45
  end
45
46
  end
46
47
 
48
+ describe '.wait_time' do
49
+ subject { Class.new(described_class) }
50
+ it 'should be protected' do
51
+ expect { subject.wait_time(10) }.to raise_error(NoMethodError)
52
+ end
53
+
54
+ context 'when specified' do
55
+ before { subject.send(:wait_time, 10) }
56
+ it do
57
+ expect(subject.send(:wait_time_value)).to eql 10
58
+ expect(subject.private_methods(true)).to include(:wait_time_value)
59
+ end
60
+ end
61
+
62
+ context 'when missing' do
63
+ it do
64
+ expect(subject.send(:wait_time_value)).to eql 60
65
+ end
66
+ end
67
+ end
68
+
47
69
  describe '.find_by_recipient' do
48
70
  let(:recipient) { 'test@user.com' }
49
71
 
50
72
  context 'simple subject without parameters' do
51
- subject { described_class.find_by_recipient(recipient) }
52
73
  before { described_class.class_eval { subject 'Some title' } }
53
74
  it do
54
- expect(described_class.adapter).to receive(:find).with(recipient, 'Some title').once
55
- subject
75
+ expect(described_class.adapter).to receive(:find).with(recipient, 'Some title', wait: 60).once
76
+ described_class.find_by_recipient(recipient)
56
77
  end
57
78
  end
58
79
 
@@ -60,7 +81,7 @@ RSpec.describe Howitzer::Email do
60
81
  subject { described_class.find_by_recipient(recipient, name: 'Vasya') }
61
82
  before { described_class.class_eval { subject 'Some title from :name' } }
62
83
  it do
63
- expect(described_class.adapter).to receive(:find).with(recipient, 'Some title from Vasya').once
84
+ expect(described_class.adapter).to receive(:find).with(recipient, 'Some title from Vasya', wait: 60).once
64
85
  subject
65
86
  end
66
87
  end
@@ -69,12 +90,22 @@ RSpec.describe Howitzer::Email do
69
90
  subject { described_class.find_by_recipient(recipient, foo: 1, bar: 2) }
70
91
  before { described_class.class_eval { subject 'Some title with :foo and :bar' } }
71
92
  it do
72
- expect(described_class.adapter).to receive(:find).with(recipient, 'Some title with 1 and 2').once
93
+ expect(described_class.adapter).to receive(:find).with(recipient, 'Some title with 1 and 2', wait: 60).once
73
94
  subject
74
95
  end
75
96
  end
76
97
 
77
98
  context 'missing subject' do
99
+ subject { described_class.find_by_recipient(recipient) }
100
+ before do
101
+ described_class.instance_eval { undef :subject_value }
102
+ end
103
+ it do
104
+ expect { subject }.to raise_error(Howitzer::NoEmailSubjectError)
105
+ end
106
+ end
107
+
108
+ context 'nil subject' do
78
109
  subject { described_class.find_by_recipient(recipient) }
79
110
  before { described_class.class_eval { subject nil } }
80
111
  it do
@@ -28,4 +28,13 @@ RSpec.describe 'Howitzer' do
28
28
  it { expect(Howitzer.app_uri.site).to eq('http://redmine.strongqa.com') }
29
29
  end
30
30
  end
31
+ describe '.mailgun_idle_timeout' do
32
+ subject { Howitzer.mailgun_idle_timeout }
33
+ before do
34
+ expect_any_instance_of(Object).to receive(:puts).with(
35
+ "WARNING! 'mailgun_idle_timeout' setting is deprecated. Please replace with 'mail_wait_time' setting."
36
+ )
37
+ end
38
+ it { is_expected.to eq(0.5) }
39
+ end
31
40
  end
@@ -10,7 +10,7 @@ RSpec.describe Howitzer::MailAdapters::Abstract do
10
10
  let(:email_object) { Howitzer::Email.adapter.new(message) }
11
11
 
12
12
  describe '.find' do
13
- subject { described_class.find(recipient, message_subject) }
13
+ subject { described_class.find(recipient, message_subject, _wait: 10) }
14
14
  it { expect { subject }.to raise_error(NotImplementedError) }
15
15
  end
16
16
 
@@ -29,7 +29,7 @@ RSpec.describe 'Mailgun Email Adapter' do
29
29
  describe '.find' do
30
30
  let(:mailgun_message) { double(to_h: message) }
31
31
  let(:events) { double(to_h: { 'items' => [event] }) }
32
- subject { Howitzer::MailAdapters::Mailgun.find(recipient, message_subject) }
32
+ subject { Howitzer::MailAdapters::Mailgun.find(recipient, message_subject, wait: 0.01) }
33
33
 
34
34
  context 'when message is found' do
35
35
  let(:event) do
@@ -50,10 +50,10 @@ RSpec.describe 'Mailgun Email Adapter' do
50
50
  allow(Howitzer::MailgunApi::Connector.instance.client).to receive(:get).with(
51
51
  'mailgun@test.domain/events',
52
52
  params: { event: 'stored' }
53
- ).ordered.once { events }
53
+ ) { events }
54
54
  allow(Howitzer::MailgunApi::Connector.instance.client).to receive(:get_url).with(
55
55
  'https://si.api.mailgun.net/v3/domains/mg.strongqa.com/messages/1234567890'
56
- ).ordered.once { mailgun_message }
56
+ ) { mailgun_message }
57
57
  end
58
58
  it do
59
59
  expect(Howitzer::Email.adapter).to receive(:new).with(message).once
@@ -80,7 +80,7 @@ RSpec.describe 'Mailgun Email Adapter' do
80
80
  allow(Howitzer::MailgunApi::Connector.instance.client).to receive(:get).with(
81
81
  'mailgun@test.domain/events',
82
82
  params: { event: 'stored' }
83
- ).at_least(:twice).ordered { events }
83
+ ) { events }
84
84
  end
85
85
  it do
86
86
  expect { subject }.to raise_error(
@@ -9,7 +9,9 @@ RSpec.describe Howitzer::Web::BaseSection do
9
9
 
10
10
  let(:klass) { Class.new(described_class) }
11
11
  let(:klass_object) { klass.new(parent, capybara_context) }
12
- before { allow(klass_object).to receive(:capybara_context) { kontext } }
12
+ it 'returns correct capybara context' do
13
+ expect(klass_object.capybara_context).to eq(capybara_context)
14
+ end
13
15
 
14
16
  include_examples :element_dsl
15
17
  end
@@ -5,13 +5,18 @@ RSpec.describe Howitzer::Web::ElementDsl do
5
5
  let(:klass) do
6
6
  Class.new do
7
7
  include Howitzer::Web::ElementDsl
8
- def capybara_context
9
- Capybara.current_session
8
+ def capybara_scopes
9
+ @_scopes ||= [Capybara.current_session]
10
10
  end
11
11
  end
12
12
  end
13
13
  let(:klass_object) { klass.new }
14
14
 
15
+ it 'returns correct capybara context' do
16
+ allow(Capybara).to receive(:current_session) { 'session' }
17
+ expect(klass_object.capybara_context).to eq('session')
18
+ end
19
+
15
20
  include_examples :element_dsl
16
21
  include_examples :capybara_context_holder
17
22
  end
@@ -42,6 +42,28 @@ RSpec.describe Howitzer::Web::PageDsl::PageScope do
42
42
  it { expect(subject.class).to eq(RSpec::Matchers::BuiltIn::Has) }
43
43
  end
44
44
 
45
+ context 'when out' do
46
+ let(:outer_context) do
47
+ Class.new do
48
+ def initialize(klass)
49
+ @klass = klass
50
+ @a = 5
51
+ end
52
+
53
+ def scope
54
+ @klass.new(nil) { 1 }
55
+ end
56
+
57
+ def secret
58
+ '***'
59
+ end
60
+ end
61
+ end
62
+ let(:scope) { outer_context.new(described_class).scope }
63
+ it { expect(scope.out(:@a)).to eq(5) }
64
+ it { expect(scope.out(:secret)).to eq('***') }
65
+ end
66
+
45
67
  context 'when starts other prefix' do
46
68
  let(:scope) { described_class.new(page) { 1 } }
47
69
  subject { scope.foo(1, 2, 3) }
@@ -14,7 +14,21 @@ RSpec.describe Howitzer::Web::Page do
14
14
  let(:url_value) { 'http://example.com/users/1' }
15
15
  subject { described_class.open(id: 1) }
16
16
  it do
17
- expect(described_class).to receive(:expanded_url).with(id: 1) { url_value }.once.ordered
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 { 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
18
32
  expect(Howitzer::Log).to receive(:info)
19
33
  .with("Open #{described_class} page by '#{url_value}' url").once.ordered
20
34
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
@@ -27,7 +41,7 @@ RSpec.describe Howitzer::Web::Page do
27
41
  let(:url_value) { 'http://example.com/users' }
28
42
  subject { described_class.open }
29
43
  it do
30
- expect(described_class).to receive(:expanded_url).with({}) { url_value }.once.ordered
44
+ expect(described_class).to receive(:expanded_url).with({}, nil) { url_value }.once.ordered
31
45
  expect(Howitzer::Log).to receive(:info)
32
46
  .with("Open #{described_class} page by '#{url_value}' url").once.ordered
33
47
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
@@ -41,7 +55,7 @@ RSpec.describe Howitzer::Web::Page do
41
55
  let(:url_value) { 'http://example.com/users' }
42
56
  subject { described_class.open(validate: false) }
43
57
  it do
44
- expect(described_class).to receive(:expanded_url).with({}) { url_value }.once.ordered
58
+ expect(described_class).to receive(:expanded_url).with({}, nil) { url_value }.once.ordered
45
59
  expect(Howitzer::Log).to receive(:info).with("Open #{described_class} page by '#{url_value}' url").once.ordered
46
60
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
47
61
  expect(session).to receive(:visit).with(url_value).once.ordered
@@ -53,7 +67,7 @@ RSpec.describe Howitzer::Web::Page do
53
67
  let(:url_value) { 'http://example.com/users/1' }
54
68
  subject { described_class.open(validate: true, id: 1) }
55
69
  it do
56
- expect(described_class).to receive(:expanded_url).with(id: 1) { url_value }.once.ordered
70
+ expect(described_class).to receive(:expanded_url).with({ id: 1 }, nil) { url_value }.once.ordered
57
71
  expect(Howitzer::Log).to receive(:info).with("Open #{described_class} page by '#{url_value}' url").once.ordered
58
72
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
59
73
  expect(session).to receive(:visit).with(url_value).once.ordered
@@ -162,41 +176,72 @@ RSpec.describe Howitzer::Web::Page do
162
176
  let!(:child_class3) do
163
177
  Class.new(described_class)
164
178
  end
165
- it { expect(described_class.send(:app_host)).to eq('http://login:pass@my.website.com') }
166
- it { expect(base_class.send(:app_host)).to eq('https://base.com') }
167
- it { expect(child_class1.send(:app_host)).to eq('https://child.com') }
168
- it { expect(child_class2.send(:app_host)).to eq('https://base.com') }
169
- it { expect(child_class3.send(:app_host)).to eq('http://login:pass@my.website.com') }
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') }
170
184
  it 'should be protected' do
171
185
  expect { described_class.site('http://example.com') }.to raise_error(NoMethodError)
172
186
  end
173
187
  end
174
188
 
175
189
  describe '.expanded_url' do
176
- context 'when params present' do
177
- subject { test_page.expanded_url(id: 1) }
178
- context 'when page url specified' do
179
- context 'when BlankPage' do
180
- let(:test_page) { Howitzer::Web::BlankPage }
181
- it { is_expected.to eq('about:blank') }
182
- end
183
- context 'when other page' do
184
- let(:test_page) do
185
- Class.new(described_class) do
186
- site 'http://example.com'
187
- path '/users{/id}'
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
188
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}'
189
222
  end
190
- it { is_expected.to eq('http://example.com/users/1') }
191
223
  end
192
- context 'when root not specified' do
193
- let(:test_page) do
194
- Class.new(described_class) do
195
- path '/users{/id}'
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(' ', '+')
196
240
  end
197
241
  end
198
- it { is_expected.to eq('http://login:pass@my.website.com/users/1') }
199
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') }
200
245
  end
201
246
  context 'when page url missing' do
202
247
  subject { described_class.expanded_url }
@@ -225,11 +270,16 @@ RSpec.describe Howitzer::Web::Page do
225
270
  before { subject }
226
271
  context 'when value is number' do
227
272
  let(:value) { 1 }
228
- it { expect(described_class.instance_variable_get(:@path_template)).to eq('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
229
277
  end
230
278
  context 'when value is string' do
231
279
  let(:value) { '/users' }
232
- it { expect(described_class.instance_variable_get(:@path_template)).to eq('/users') }
280
+ it do
281
+ expect(described_class.send(:path_value)).to eql '/users'
282
+ end
233
283
  end
234
284
  end
235
285
 
@@ -257,21 +307,6 @@ RSpec.describe Howitzer::Web::Page do
257
307
 
258
308
  describe 'inherited callback' do
259
309
  let(:page_class) { Class.new(described_class) }
260
- context 'when abstract class without validations' do
261
- let!(:page_class) do
262
- Howitzer::Web::PageValidator.instance_variable_set(:@pages, [])
263
- Class.new(described_class)
264
- end
265
- it { expect(Howitzer::Web::PageValidator.pages).to eq([]) }
266
- end
267
- context 'when class has validations' do
268
- let!(:page_class) do
269
- allow(described_class).to receive(:validations) { { title: /some text/ } }
270
- Howitzer::Web::PageValidator.instance_variable_set(:@pages, [])
271
- Class.new(described_class)
272
- end
273
- it { expect(Howitzer::Web::PageValidator.pages).to eq([page_class]) }
274
- end
275
310
  it 'can not be instantiated with new' do
276
311
  expect { page_class.new }.to raise_error(NoMethodError, "private method `new' called for #{page_class}")
277
312
  end
@@ -58,7 +58,7 @@ RSpec.describe Howitzer::Web::PageValidator do
58
58
 
59
59
  describe '.validate' do
60
60
  before do
61
- described_class.validations[web_page.class.name] = nil
61
+ described_class.validations[web_page.class] = nil
62
62
  end
63
63
  let(:additional_value) { nil }
64
64
  subject { web_page.class.validate(name, *[value, additional_value].compact) }
@@ -69,14 +69,14 @@ RSpec.describe Howitzer::Web::PageValidator do
69
69
  let(:value) { /foo/ }
70
70
  it do
71
71
  is_expected.to be_a(Proc)
72
- expect(described_class.validations[web_page.class.name][:url]).to be_a Proc
72
+ expect(described_class.validations[web_page.class][:url]).to be_a Proc
73
73
  end
74
74
  end
75
75
  context '(as symbol)' do
76
76
  let(:value) { /foo/ }
77
77
  it do
78
78
  is_expected.to be_a(Proc)
79
- expect(described_class.validations[web_page.class.name][:url]).to be_a Proc
79
+ expect(described_class.validations[web_page.class][:url]).to be_a Proc
80
80
  end
81
81
  end
82
82
  end
@@ -85,7 +85,7 @@ RSpec.describe Howitzer::Web::PageValidator do
85
85
  let(:value) { /foo/ }
86
86
  it do
87
87
  is_expected.to be_a(Proc)
88
- expect(described_class.validations[web_page.class.name][:url]).to be_a Proc
88
+ expect(described_class.validations[web_page.class][:url]).to be_a Proc
89
89
  end
90
90
  end
91
91
  end
@@ -96,14 +96,14 @@ RSpec.describe Howitzer::Web::PageValidator do
96
96
  let(:additional_value) { 'some string' }
97
97
  it do
98
98
  is_expected.to be_a(Proc)
99
- expect(described_class.validations[web_page.class.name][:element_presence]).to eql(subject)
99
+ expect(described_class.validations[web_page.class][:element_presence]).to eql(subject)
100
100
  end
101
101
  end
102
102
  context '(as symbol)' do
103
103
  let(:value) { :test_locator }
104
104
  it do
105
105
  is_expected.to be_a(Proc)
106
- expect(described_class.validations[web_page.class.name][:element_presence]).to eql(subject)
106
+ expect(described_class.validations[web_page.class][:element_presence]).to eql(subject)
107
107
  end
108
108
  end
109
109
  end
@@ -113,14 +113,14 @@ RSpec.describe Howitzer::Web::PageValidator do
113
113
  let(:value) { /foo/ }
114
114
  it do
115
115
  is_expected.to be_a(Proc)
116
- expect(described_class.validations[web_page.class.name][:title]).to be_a Proc
116
+ expect(described_class.validations[web_page.class][:title]).to be_a Proc
117
117
  end
118
118
  end
119
119
  context '(as symbol)' do
120
120
  let(:value) { /foo/ }
121
121
  it do
122
122
  is_expected.to be_a(Proc)
123
- expect(described_class.validations[web_page.class.name][:title]).to be_a Proc
123
+ expect(described_class.validations[web_page.class][:title]).to be_a Proc
124
124
  end
125
125
  end
126
126
  end
@@ -133,18 +133,9 @@ RSpec.describe Howitzer::Web::PageValidator do
133
133
  end
134
134
  end
135
135
 
136
- describe '.pages' do
137
- subject { described_class.pages }
138
- it do
139
- expect(subject).not_to include(Symbol)
140
- subject << Symbol
141
- expect(subject).to include(Symbol)
142
- end
143
- end
144
-
145
136
  describe '.opened?' do
146
- subject { web_page_class.opened? }
147
137
  context 'when no one validation is defined' do
138
+ subject { web_page_class.opened? }
148
139
  it do
149
140
  expect { subject }.to raise_error(
150
141
  Howitzer::NoValidationError,
@@ -153,30 +144,91 @@ RSpec.describe Howitzer::Web::PageValidator do
153
144
  end
154
145
  end
155
146
  context 'when all validations are defined' do
156
- before do
157
- web_page_class.class_eval do
158
- include Singleton
159
- element :login, '#id'
160
- validate :url, /foo/
161
- validate :title, /Foo page/
162
- validate :element_presence, :login
147
+ context 'when sync is default' do
148
+ subject { web_page_class.opened? }
149
+ before do
150
+ web_page_class.class_eval do
151
+ include Singleton
152
+ element :login, '#id'
153
+ validate :url, /foo/
154
+ validate :title, /Foo page/
155
+ validate :element_presence, :login
156
+ end
157
+ end
158
+ context 'when all matches' do
159
+ before do
160
+ allow(web_page_class.instance).to receive(:current_url) { 'http://test.com/foo' }
161
+ allow(web_page_class.instance).to receive(:has_title?) { 'Foo page' }
162
+ allow(web_page_class.instance).to receive(:has_login_element?).with(no_args) { true }
163
+ end
164
+ it { is_expected.to be_truthy }
165
+ end
166
+ context 'when first validation fails' do
167
+ before do
168
+ expect(web_page_class.instance).to receive(:current_url).once { 'http://test.com/bar' }
169
+ expect(web_page_class.instance).to receive(:has_title?).never
170
+ allow(web_page_class).to receive(:has_login_element?).with(no_args).never
171
+ end
172
+ it { is_expected.to be_falsey }
163
173
  end
164
174
  end
165
- context 'when all matches' do
175
+
176
+ context 'when sync is true' do
177
+ subject { web_page_class.opened?(sync: true) }
166
178
  before do
167
- allow(web_page_class.instance).to receive(:current_url) { 'http://test.com/foo' }
168
- allow(web_page_class.instance).to receive(:title) { 'Foo page' }
169
- allow(web_page_class).to receive(:has_login_element?).with(no_args) { true }
179
+ web_page_class.class_eval do
180
+ include Singleton
181
+ element :login, '#id'
182
+ validate :url, /foo/
183
+ validate :title, /Foo page/
184
+ validate :element_presence, :login
185
+ end
186
+ end
187
+ context 'when all matches' do
188
+ before do
189
+ allow(web_page_class.instance).to receive(:current_url) { 'http://test.com/foo' }
190
+ allow(web_page_class.instance).to receive(:has_title?) { 'Foo page' }
191
+ allow(web_page_class.instance).to receive(:has_login_element?).with(no_args) { true }
192
+ end
193
+ it { is_expected.to be_truthy }
194
+ end
195
+ context 'when first validation fails' do
196
+ before do
197
+ expect(web_page_class.instance).to receive(:current_url).once { 'http://test.com/bar' }
198
+ expect(web_page_class.instance).to receive(:has_title?).never
199
+ allow(web_page_class).to receive(:has_login_element?).with(no_args).never
200
+ end
201
+ it { is_expected.to be_falsey }
170
202
  end
171
- it { is_expected.to be_truthy }
172
203
  end
173
- context 'when first validation fails' do
204
+
205
+ context 'when sync is false' do
206
+ subject { web_page_class.opened?(sync: false) }
174
207
  before do
175
- expect(web_page_class.instance).to receive(:current_url).once { 'http://test.com/bar' }
176
- expect(web_page_class.instance).to receive(:title).never
177
- allow(web_page_class).to receive(:has_login_element?).with(no_args).never
208
+ web_page_class.class_eval do
209
+ include Singleton
210
+ element :login, '#id'
211
+ validate :url, /foo/
212
+ validate :title, /Foo page/
213
+ validate :element_presence, :login
214
+ end
215
+ end
216
+ context 'when all matches' do
217
+ before do
218
+ allow(web_page_class.instance).to receive(:current_url) { 'http://test.com/foo' }
219
+ allow(web_page_class.instance).to receive(:title) { 'Foo page' }
220
+ allow(web_page_class.instance).to receive(:has_no_login_element?).with(no_args) { false }
221
+ end
222
+ it { is_expected.to be_truthy }
223
+ end
224
+ context 'when first validation fails' do
225
+ before do
226
+ expect(web_page_class.instance).to receive(:current_url).once { 'http://test.com/bar' }
227
+ expect(web_page_class.instance).to receive(:title).never
228
+ allow(web_page_class).to receive(:has_no_login_element?).with(no_args).never
229
+ end
230
+ it { is_expected.to be_falsey }
178
231
  end
179
- it { is_expected.to be_falsey }
180
232
  end
181
233
  end
182
234
  end
@@ -189,30 +241,21 @@ RSpec.describe Howitzer::Web::PageValidator do
189
241
  let!(:web_page1_class) do
190
242
  Class.new do
191
243
  include Howitzer::Web::PageValidator
192
- def self.name
193
- 'TestWebPage1Class'
194
- end
195
-
196
- def self.opened?
197
- true
198
- end
199
244
  end
200
245
  end
201
-
202
246
  let!(:web_page2_class) do
203
247
  Class.new do
204
248
  include Howitzer::Web::PageValidator
205
- def self.name
206
- 'TestWebPage2Class'
207
- end
208
-
209
- def self.opened?
210
- false
211
- end
212
249
  end
213
250
  end
214
251
  subject { web_page2_class.matched_pages }
215
- before { described_class.instance_variable_set(:@pages, [web_page1_class, web_page2_class]) }
252
+ before do
253
+ allow(Howitzer::Web::PageValidator).to receive(:validations).with(no_args) do
254
+ { web_page1_class => 1, web_page2_class => 2 }
255
+ end
256
+ expect(web_page1_class).to receive(:opened?).with(sync: false) { true }
257
+ expect(web_page2_class).to receive(:opened?).with(sync: false) { false }
258
+ end
216
259
  it { is_expected.to eq([web_page1_class]) }
217
260
  end
218
261
  end