howitzer 2.0.1 → 2.0.2

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 (40) hide show
  1. checksums.yaml +4 -4
  2. data/.rubocop.yml +6 -0
  3. data/.travis.yml +4 -3
  4. data/CHANGELOG.md +18 -1
  5. data/Gemfile +1 -1
  6. data/README.md +3 -1
  7. data/Rakefile +1 -1
  8. data/bin/howitzer +3 -3
  9. data/features/cli_new.feature +2 -0
  10. data/generators/config/templates/capybara.rb +13 -11
  11. data/generators/config/templates/default.yml +2 -0
  12. data/generators/cucumber/cucumber_generator.rb +2 -1
  13. data/generators/cucumber/templates/cuke_sniffer.rake +21 -0
  14. data/generators/cucumber/templates/env.rb +6 -0
  15. data/generators/root/templates/Gemfile.erb +1 -0
  16. data/generators/rspec/templates/spec_helper.rb +2 -1
  17. data/generators/turnip/templates/spec_helper.rb +2 -1
  18. data/howitzer.gemspec +2 -1
  19. data/lib/howitzer.rb +1 -0
  20. data/lib/howitzer/capybara_helpers.rb +1 -1
  21. data/lib/howitzer/exceptions.rb +1 -0
  22. data/lib/howitzer/version.rb +1 -1
  23. data/lib/howitzer/web/capybara_methods_proxy.rb +26 -1
  24. data/lib/howitzer/web/element_dsl.rb +16 -3
  25. data/lib/howitzer/web/iframe_dsl.rb +34 -17
  26. data/lib/howitzer/web/page.rb +1 -0
  27. data/lib/howitzer/web/page_dsl.rb +2 -1
  28. data/lib/howitzer/web/page_validator.rb +5 -1
  29. data/spec/spec_helper.rb +1 -2
  30. data/spec/support/shared_examples/capybara_methods_proxy.rb +8 -8
  31. data/spec/support/shared_examples/dynamic_section_methods.rb +4 -4
  32. data/spec/support/shared_examples/element_dsl.rb +66 -53
  33. data/spec/unit/generators/cucumber_generator_spec.rb +8 -2
  34. data/spec/unit/lib/cache_spec.rb +1 -1
  35. data/spec/unit/lib/mailgun_api/client_spec.rb +6 -6
  36. data/spec/unit/lib/web/iframe_dsl_spec.rb +67 -22
  37. data/spec/unit/lib/web/page_spec.rb +25 -25
  38. data/spec/unit/lib/web/page_validator_spec.rb +37 -22
  39. data/spec/unit/lib/web/section_dsl_spec.rb +3 -3
  40. metadata +20 -5
@@ -19,7 +19,7 @@ RSpec.describe Howitzer::Web::Page do
19
19
  .with("Open #{described_class} page by '#{url_value}' url").once.ordered
20
20
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
21
21
  expect(session).to receive(:visit).with(url_value).once.ordered
22
- expect(described_class).to receive(:given).once.ordered { true }
22
+ expect(described_class).to receive(:given).once.ordered.and_return(true)
23
23
  expect(subject).to eq(true)
24
24
  end
25
25
  end
@@ -33,7 +33,7 @@ RSpec.describe Howitzer::Web::Page do
33
33
  .with("Open #{described_class} page by '#{url_value}' url").once.ordered
34
34
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
35
35
  expect(session).to receive(:visit).with(url_value).once.ordered
36
- expect(described_class).to receive(:given).once.ordered { true }
36
+ expect(described_class).to receive(:given).once.ordered.and_return(true)
37
37
  expect(subject).to eq(true)
38
38
  end
39
39
  end
@@ -41,12 +41,12 @@ RSpec.describe Howitzer::Web::Page do
41
41
  let(:url_value) { 'http://example.com/users' }
42
42
  subject { described_class.open }
43
43
  it do
44
- expect(described_class).to receive(:expanded_url).with({}, nil) { url_value }.once.ordered
44
+ expect(described_class).to receive(:expanded_url).with({}, nil).and_return(url_value).once.ordered
45
45
  expect(Howitzer::Log).to receive(:info)
46
46
  .with("Open #{described_class} page by '#{url_value}' url").once.ordered
47
47
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
48
48
  expect(session).to receive(:visit).with(url_value).once.ordered
49
- expect(described_class).to receive(:given).once.ordered { true }
49
+ expect(described_class).to receive(:given).once.ordered.and_return(true)
50
50
  expect(subject).to eq(true)
51
51
  end
52
52
  end
@@ -55,7 +55,7 @@ RSpec.describe Howitzer::Web::Page do
55
55
  let(:url_value) { 'http://example.com/users' }
56
56
  subject { described_class.open(validate: false) }
57
57
  it do
58
- expect(described_class).to receive(:expanded_url).with({}, nil) { url_value }.once.ordered
58
+ expect(described_class).to receive(:expanded_url).with({}, nil).and_return(url_value).once.ordered
59
59
  expect(Howitzer::Log).to receive(:info).with("Open #{described_class} page by '#{url_value}' url").once.ordered
60
60
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
61
61
  expect(session).to receive(:visit).with(url_value).once.ordered
@@ -67,11 +67,11 @@ RSpec.describe Howitzer::Web::Page do
67
67
  let(:url_value) { 'http://example.com/users/1' }
68
68
  subject { described_class.open(validate: true, id: 1) }
69
69
  it do
70
- expect(described_class).to receive(:expanded_url).with({ id: 1 }, nil) { url_value }.once.ordered
70
+ expect(described_class).to receive(:expanded_url).with({ id: 1 }, nil).and_return(url_value).once.ordered
71
71
  expect(Howitzer::Log).to receive(:info).with("Open #{described_class} page by '#{url_value}' url").once.ordered
72
72
  expect(described_class).to receive(:retryable).ordered.once.and_call_original
73
73
  expect(session).to receive(:visit).with(url_value).once.ordered
74
- expect(described_class).to receive(:given).once.ordered { true }
74
+ expect(described_class).to receive(:given).once.ordered.and_return(true)
75
75
  expect(subject).to eq(true)
76
76
  end
77
77
  end
@@ -81,7 +81,7 @@ RSpec.describe Howitzer::Web::Page do
81
81
  subject { described_class.given }
82
82
  before do
83
83
  expect(described_class).to receive(:displayed?).with(no_args).once
84
- expect(described_class).to receive(:instance) { true }
84
+ expect(described_class).to receive(:instance).and_return(true)
85
85
  end
86
86
  it { is_expected.to be_truthy }
87
87
  end
@@ -90,8 +90,8 @@ RSpec.describe Howitzer::Web::Page do
90
90
  let(:page) { double }
91
91
  subject { described_class.instance.title }
92
92
  before do
93
- allow_any_instance_of(described_class).to receive(:check_validations_are_defined!) { true }
94
- allow(session).to receive(:current_url) { 'google.com' }
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
95
  end
96
96
  it do
97
97
  expect(session).to receive(:title)
@@ -102,17 +102,17 @@ RSpec.describe Howitzer::Web::Page do
102
102
  describe '.current_page' do
103
103
  subject { described_class.current_page }
104
104
  context 'when matched_pages has no pages' do
105
- before { allow(described_class).to receive(:matched_pages) { [] } }
105
+ before { allow(described_class).to receive(:matched_pages).and_return([]) }
106
106
  it { is_expected.to eq(described_class::UnknownPage) }
107
107
  end
108
108
  context 'when matched_pages has more than 1 page' do
109
109
  let(:foo_page) { double(inspect: 'FooPage') }
110
110
  let(:bar_page) { double(inspect: 'BarPage') }
111
111
  before do
112
- allow_any_instance_of(described_class).to receive(:check_validations_are_defined!) { true }
113
- allow(session).to receive(:current_url) { 'http://test.com' }
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
114
  allow(session).to receive(:title) { 'Test site' }
115
- allow(described_class).to receive(:matched_pages) { [foo_page, bar_page] }
115
+ allow(described_class).to receive(:matched_pages).and_return([foo_page, bar_page])
116
116
  end
117
117
  it do
118
118
  expect { subject }.to raise_error(
@@ -124,7 +124,7 @@ RSpec.describe Howitzer::Web::Page do
124
124
  end
125
125
  context 'when matched_pages has only 1 page' do
126
126
  let(:foo_page) { double(to_s: 'FooPage') }
127
- before { allow(described_class).to receive(:matched_pages) { [foo_page] } }
127
+ before { allow(described_class).to receive(:matched_pages).and_return([foo_page]) }
128
128
  it { is_expected.to eq(foo_page) }
129
129
  end
130
130
  end
@@ -132,15 +132,15 @@ RSpec.describe Howitzer::Web::Page do
132
132
  describe '.displayed?' do
133
133
  subject { described_class.displayed? }
134
134
  context 'when page is opened' do
135
- before { allow(described_class).to receive(:opened?) { true } }
135
+ before { allow(described_class).to receive(:opened?).and_return(true) }
136
136
  it { is_expected.to eq(true) }
137
137
  end
138
138
  context 'when page is not opened' do
139
139
  before do
140
- allow(described_class).to receive(:current_page) { 'FooPage' }
141
- allow(session).to receive(:current_url) { 'http://test.com' }
142
- allow(session).to receive(:title) { 'Test site' }
143
- allow(described_class).to receive(:opened?) { false }
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
144
  end
145
145
  it do
146
146
  expect { subject }.to raise_error(
@@ -153,7 +153,7 @@ RSpec.describe Howitzer::Web::Page do
153
153
  end
154
154
 
155
155
  describe '.current_url' do
156
- before { allow(Capybara).to receive_message_chain(:current_session, :current_url) { 'http://example.com' } }
156
+ before { allow(Capybara).to receive_message_chain(:current_session, :current_url).and_return('http://example.com') }
157
157
  it 'should return current url page' do
158
158
  expect(Howitzer::Web::Page.current_url).to eq('http://example.com')
159
159
  end
@@ -286,7 +286,7 @@ RSpec.describe Howitzer::Web::Page do
286
286
  describe '#initialize' do
287
287
  subject { described_class.send(:new) }
288
288
  before do
289
- expect_any_instance_of(described_class).to receive(:check_validations_are_defined!).once { true }
289
+ expect_any_instance_of(described_class).to receive(:check_validations_are_defined!).once.and_return(true)
290
290
  end
291
291
  context 'when maximized_window is true' do
292
292
  let(:driver) { double }
@@ -317,10 +317,10 @@ RSpec.describe Howitzer::Web::Page do
317
317
  subject { described_class.instance.reload }
318
318
  let(:visit) { double }
319
319
  before do
320
- allow(session).to receive(:current_url) { 'google.com' }
320
+ allow(session).to receive(:current_url).and_return('google.com')
321
321
  end
322
322
  it do
323
- expect(Howitzer::Log).to receive(:info) { "Reload 'google.com'" }
323
+ expect(Howitzer::Log).to receive(:info).and_return("Reload 'google.com'")
324
324
  expect(session).to receive(:visit).with('google.com')
325
325
  subject
326
326
  end
@@ -328,7 +328,7 @@ RSpec.describe Howitzer::Web::Page do
328
328
 
329
329
  describe '#capybara_context' do
330
330
  subject { described_class.instance.capybara_context }
331
- before { expect(Capybara).to receive(:current_session) { :context } }
331
+ before { expect(Capybara).to receive(:current_session).and_return(:context) }
332
332
  it { is_expected.to eq(:context) }
333
333
  end
334
334
 
@@ -11,6 +11,8 @@ RSpec.describe Howitzer::Web::PageValidator do
11
11
  Class.new do
12
12
  include Howitzer::Web::ElementDsl
13
13
  include Howitzer::Web::PageValidator
14
+ element :foo, 'a'
15
+ element :bar, :xpath, ->(v) { v }
14
16
  def self.name
15
17
  'TestWebPageClass'
16
18
  end
@@ -42,14 +44,14 @@ RSpec.describe Howitzer::Web::PageValidator do
42
44
  context 'when element_presence validation is specified' do
43
45
  context 'when simple selector' do
44
46
  before do
45
- web_page.class.validate :element_presence, :test_locator
47
+ web_page.class.validate :element_presence, :foo
46
48
  end
47
49
  it { expect { subject }.to_not raise_error }
48
50
  end
49
51
 
50
52
  context 'when lambda selector' do
51
53
  before do
52
- web_page.class.validate :element_presence, :test_locator, 'some_text'
54
+ web_page.class.validate :element_presence, :bar, 'some_text'
53
55
  end
54
56
  it { expect { subject }.to_not raise_error }
55
57
  end
@@ -66,13 +68,13 @@ RSpec.describe Howitzer::Web::PageValidator do
66
68
  context 'as string' do
67
69
  let(:name) { 'url' }
68
70
  context '(as string)' do
69
- let(:value) { /foo/ }
71
+ let(:value) { 'foo' }
70
72
  it do
71
73
  is_expected.to be_a(Proc)
72
74
  expect(described_class.validations[web_page.class][:url]).to be_a Proc
73
75
  end
74
76
  end
75
- context '(as symbol)' do
77
+ context '(as regexp)' do
76
78
  let(:value) { /foo/ }
77
79
  it do
78
80
  is_expected.to be_a(Proc)
@@ -92,7 +94,7 @@ RSpec.describe Howitzer::Web::PageValidator do
92
94
  context 'when name = :element_presence' do
93
95
  let(:name) { :element_presence }
94
96
  context '(as string)' do
95
- let(:value) { 'test_locator' }
97
+ let(:value) { 'bar' }
96
98
  let(:additional_value) { 'some string' }
97
99
  it do
98
100
  is_expected.to be_a(Proc)
@@ -100,23 +102,36 @@ RSpec.describe Howitzer::Web::PageValidator do
100
102
  end
101
103
  end
102
104
  context '(as symbol)' do
103
- let(:value) { :test_locator }
105
+ let(:value) { :foo }
104
106
  it do
105
107
  is_expected.to be_a(Proc)
106
108
  expect(described_class.validations[web_page.class][:element_presence]).to eql(subject)
107
109
  end
108
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
109
124
  end
110
125
  context 'when name = :title' do
111
126
  let(:name) { :title }
112
127
  context '(as string)' do
113
- let(:value) { /foo/ }
128
+ let(:value) { 'foo' }
114
129
  it do
115
130
  is_expected.to be_a(Proc)
116
131
  expect(described_class.validations[web_page.class][:title]).to be_a Proc
117
132
  end
118
133
  end
119
- context '(as symbol)' do
134
+ context '(as regexp)' do
120
135
  let(:value) { /foo/ }
121
136
  it do
122
137
  is_expected.to be_a(Proc)
@@ -157,15 +172,15 @@ RSpec.describe Howitzer::Web::PageValidator do
157
172
  end
158
173
  context 'when all matches' do
159
174
  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 }
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)
163
178
  end
164
179
  it { is_expected.to be_truthy }
165
180
  end
166
181
  context 'when first validation fails' do
167
182
  before do
168
- expect(web_page_class.instance).to receive(:current_url).once { 'http://test.com/bar' }
183
+ expect(web_page_class.instance).to receive(:current_url).once.and_return('http://test.com/bar')
169
184
  expect(web_page_class.instance).to receive(:has_title?).never
170
185
  allow(web_page_class).to receive(:has_login_element?).with(no_args).never
171
186
  end
@@ -186,15 +201,15 @@ RSpec.describe Howitzer::Web::PageValidator do
186
201
  end
187
202
  context 'when all matches' do
188
203
  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 }
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)
192
207
  end
193
208
  it { is_expected.to be_truthy }
194
209
  end
195
210
  context 'when first validation fails' do
196
211
  before do
197
- expect(web_page_class.instance).to receive(:current_url).once { 'http://test.com/bar' }
212
+ expect(web_page_class.instance).to receive(:current_url).once.and_return('http://test.com/bar')
198
213
  expect(web_page_class.instance).to receive(:has_title?).never
199
214
  allow(web_page_class).to receive(:has_login_element?).with(no_args).never
200
215
  end
@@ -215,15 +230,15 @@ RSpec.describe Howitzer::Web::PageValidator do
215
230
  end
216
231
  context 'when all matches' do
217
232
  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 }
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)
221
236
  end
222
237
  it { is_expected.to be_truthy }
223
238
  end
224
239
  context 'when first validation fails' do
225
240
  before do
226
- expect(web_page_class.instance).to receive(:current_url).once { 'http://test.com/bar' }
241
+ expect(web_page_class.instance).to receive(:current_url).once.and_return('http://test.com/bar')
227
242
  expect(web_page_class.instance).to receive(:title).never
228
243
  allow(web_page_class).to receive(:has_no_login_element?).with(no_args).never
229
244
  end
@@ -253,8 +268,8 @@ RSpec.describe Howitzer::Web::PageValidator do
253
268
  allow(Howitzer::Web::PageValidator).to receive(:validations).with(no_args) do
254
269
  { web_page1_class => 1, web_page2_class => 2 }
255
270
  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 }
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)
258
273
  end
259
274
  it { is_expected.to eq([web_page1_class]) }
260
275
  end
@@ -148,9 +148,9 @@ RSpec.describe Howitzer::Web::SectionDsl do
148
148
  let(:context3) { double }
149
149
  let(:capybara_element) { double }
150
150
  before do
151
- expect(session).to receive(:find).with(*finder_args).once { context2 }
152
- expect(context2).to receive(:find).with('#klass') { context3 }
153
- expect(context3).to receive(:find).with(:xpath, './/a') { capybara_element }
151
+ expect(session).to receive(:find).with(*finder_args).once.and_return(context2)
152
+ expect(context2).to receive(:find).with('#klass').and_return(context3)
153
+ expect(context3).to receive(:find).with(:xpath, './/a').and_return(capybara_element)
154
154
  end
155
155
 
156
156
  it 'can work with nested section' do
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: howitzer
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.0.1
4
+ version: 2.0.2
5
5
  platform: ruby
6
6
  authors:
7
7
  - Roman Parashchenko
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2016-11-15 00:00:00.000000000 Z
11
+ date: 2017-03-27 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: activesupport
@@ -114,20 +114,34 @@ dependencies:
114
114
  - - "~>"
115
115
  - !ruby/object:Gem::Version
116
116
  version: '3.2'
117
+ - !ruby/object:Gem::Dependency
118
+ name: rspec-wait
119
+ requirement: !ruby/object:Gem::Requirement
120
+ requirements:
121
+ - - ">="
122
+ - !ruby/object:Gem::Version
123
+ version: '0'
124
+ type: :runtime
125
+ prerelease: false
126
+ version_requirements: !ruby/object:Gem::Requirement
127
+ requirements:
128
+ - - ">="
129
+ - !ruby/object:Gem::Version
130
+ version: '0'
117
131
  - !ruby/object:Gem::Dependency
118
132
  name: selenium-webdriver
119
133
  requirement: !ruby/object:Gem::Requirement
120
134
  requirements:
121
135
  - - "<"
122
136
  - !ruby/object:Gem::Version
123
- version: '3'
137
+ version: '4.0'
124
138
  type: :runtime
125
139
  prerelease: false
126
140
  version_requirements: !ruby/object:Gem::Requirement
127
141
  requirements:
128
142
  - - "<"
129
143
  - !ruby/object:Gem::Version
130
- version: '3'
144
+ version: '4.0'
131
145
  - !ruby/object:Gem::Dependency
132
146
  name: sexy_settings
133
147
  requirement: !ruby/object:Gem::Requirement
@@ -238,6 +252,7 @@ files:
238
252
  - generators/cucumber/cucumber_generator.rb
239
253
  - generators/cucumber/templates/common_steps.rb
240
254
  - generators/cucumber/templates/cucumber.rake
255
+ - generators/cucumber/templates/cuke_sniffer.rake
241
256
  - generators/cucumber/templates/env.rb
242
257
  - generators/cucumber/templates/example.feature
243
258
  - generators/cucumber/templates/hooks.rb
@@ -360,7 +375,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
360
375
  version: '0'
361
376
  requirements: []
362
377
  rubyforge_project:
363
- rubygems_version: 2.6.6
378
+ rubygems_version: 2.6.10
364
379
  signing_key:
365
380
  specification_version: 4
366
381
  summary: Ruby based framework for acceptance testing