howitzer 2.0.0 → 2.0.1
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 +3 -0
- data/CHANGELOG.md +21 -1
- data/features/cli_new.feature +1 -0
- data/features/cli_update.feature +1 -0
- data/generators/base_generator.rb +3 -1
- data/generators/config/templates/capybara.rb +1 -1
- data/generators/config/templates/default.yml +4 -2
- data/generators/cucumber/cucumber_generator.rb +1 -0
- data/generators/cucumber/templates/common_steps.rb +1 -1
- data/generators/cucumber/templates/env.rb +0 -28
- data/generators/cucumber/templates/hooks.rb +29 -0
- data/generators/prerequisites/templates/user.rb +2 -0
- data/generators/prerequisites/templates/users.rb +2 -2
- data/generators/root/templates/Gemfile.erb +1 -1
- data/generators/rspec/templates/spec_helper.rb +9 -2
- data/generators/turnip/templates/spec_helper.rb +9 -2
- data/generators/web/templates/example_page.rb +0 -1
- data/howitzer.gemspec +1 -3
- data/lib/howitzer.rb +7 -0
- data/lib/howitzer/cache.rb +1 -1
- data/lib/howitzer/capybara_helpers.rb +2 -2
- data/lib/howitzer/email.rb +26 -8
- data/lib/howitzer/exceptions.rb +19 -19
- data/lib/howitzer/mail_adapters/abstract.rb +4 -3
- data/lib/howitzer/mail_adapters/mailgun.rb +6 -5
- data/lib/howitzer/mailgun_api/client.rb +1 -1
- data/lib/howitzer/version.rb +1 -1
- data/lib/howitzer/web/base_section.rb +3 -3
- data/lib/howitzer/web/capybara_context_holder.rb +19 -0
- data/lib/howitzer/web/capybara_methods_proxy.rb +27 -19
- data/lib/howitzer/web/element_dsl.rb +52 -13
- data/lib/howitzer/web/iframe_dsl.rb +3 -7
- data/lib/howitzer/web/page.rb +14 -21
- data/lib/howitzer/web/page_dsl.rb +32 -4
- data/lib/howitzer/web/page_validator.rb +15 -16
- data/lib/howitzer/web/section_dsl.rb +3 -7
- data/spec/config/custom.yml +1 -1
- data/spec/spec_helper.rb +1 -7
- data/spec/support/shared_examples/capybara_context_holder.rb +3 -3
- data/spec/support/shared_examples/element_dsl.rb +128 -18
- data/spec/unit/generators/base_generator_spec.rb +15 -16
- data/spec/unit/generators/cucumber_generator_spec.rb +2 -0
- data/spec/unit/generators/root_generator_spec.rb +1 -1
- data/spec/unit/lib/capybara_helpers_spec.rb +2 -2
- data/spec/unit/lib/email_spec.rb +37 -6
- data/spec/unit/lib/{howitzer.rb → howitzer_spec.rb} +9 -0
- data/spec/unit/lib/mail_adapters/abstract_spec.rb +1 -1
- data/spec/unit/lib/mail_adapters/mailgun_spec.rb +4 -4
- data/spec/unit/lib/web/base_section_spec.rb +3 -1
- data/spec/unit/lib/web/element_dsl_spec.rb +7 -2
- data/spec/unit/lib/web/page_dsl_spec.rb +22 -0
- data/spec/unit/lib/web/page_spec.rb +79 -44
- data/spec/unit/lib/web/page_validator_spec.rb +94 -51
- data/spec/unit/lib/web/section_spec.rb +4 -2
- 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:
|
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(
|
685
|
-
it { expect { subject }.not_to raise_error
|
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
|
data/spec/unit/lib/email_spec.rb
CHANGED
@@ -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.
|
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
|
-
|
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
|
-
)
|
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
|
-
)
|
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
|
-
)
|
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
|
-
|
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
|
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(:
|
166
|
-
it { expect(base_class.send(:
|
167
|
-
it { expect(child_class1.send(:
|
168
|
-
it { expect(child_class2.send(:
|
169
|
-
it { expect(child_class3.send(:
|
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
|
177
|
-
|
178
|
-
|
179
|
-
context 'when
|
180
|
-
|
181
|
-
|
182
|
-
|
183
|
-
|
184
|
-
|
185
|
-
|
186
|
-
|
187
|
-
|
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
|
-
|
193
|
-
|
194
|
-
|
195
|
-
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
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
|
-
|
157
|
-
web_page_class.
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
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
|
-
|
175
|
+
|
176
|
+
context 'when sync is true' do
|
177
|
+
subject { web_page_class.opened?(sync: true) }
|
166
178
|
before do
|
167
|
-
|
168
|
-
|
169
|
-
|
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
|
-
|
204
|
+
|
205
|
+
context 'when sync is false' do
|
206
|
+
subject { web_page_class.opened?(sync: false) }
|
174
207
|
before do
|
175
|
-
|
176
|
-
|
177
|
-
|
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
|
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
|