howitzer 1.0.2 → 1.1.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (67) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +1 -0
  3. data/.gitignore +3 -1
  4. data/.ruby-gemset +1 -0
  5. data/.travis.yml +4 -1
  6. data/.yardopts +5 -0
  7. data/CHANGELOG.md +23 -1
  8. data/CONTRIBUTING.md +14 -0
  9. data/GETTING_STARTED.md +283 -183
  10. data/Gemfile +3 -2
  11. data/LICENSE +1 -1
  12. data/README.md +93 -39
  13. data/Rakefile +4 -0
  14. data/bin/howitzer +34 -5
  15. data/features/cli_help.feature +3 -2
  16. data/features/cli_new.feature +1 -1
  17. data/features/cli_unknown.feature +1 -1
  18. data/features/cli_update.feature +84 -0
  19. data/features/step_definitions/common_steps.rb +9 -1
  20. data/generators/base_generator.rb +30 -15
  21. data/generators/config/config_generator.rb +7 -7
  22. data/generators/config/templates/custom.yml +1 -0
  23. data/generators/config/templates/default.yml +35 -5
  24. data/generators/cucumber/templates/env.rb +2 -2
  25. data/generators/cucumber/templates/transformers.rb +3 -1
  26. data/generators/root/templates/Gemfile +5 -3
  27. data/generators/root/templates/Rakefile +2 -0
  28. data/generators/rspec/templates/example_spec.rb +3 -3
  29. data/generators/rspec/templates/spec_helper.rb +6 -7
  30. data/howitzer.gemspec +15 -15
  31. data/lib/howitzer/capybara/settings.rb +125 -49
  32. data/lib/howitzer/helpers.rb +161 -94
  33. data/lib/howitzer/mailgun/client.rb +1 -1
  34. data/lib/howitzer/tasks/framework.rake +3 -0
  35. data/lib/howitzer/utils.rb +1 -1
  36. data/lib/howitzer/utils/locator_store.rb +1 -1
  37. data/lib/howitzer/utils/log.rb +1 -1
  38. data/lib/howitzer/utils/page_validator.rb +1 -1
  39. data/lib/howitzer/version.rb +1 -1
  40. data/lib/howitzer/web_page.rb +11 -11
  41. data/spec/spec_helper.rb +25 -22
  42. data/spec/support/generator_helper.rb +8 -1
  43. data/spec/unit/generators/base_generator_spec.rb +242 -0
  44. data/spec/unit/generators/config_generator_spec.rb +34 -0
  45. data/spec/unit/generators/cucumber_generator_spec.rb +45 -0
  46. data/spec/unit/generators/emails_generator_spec.rb +31 -0
  47. data/spec/unit/generators/pages_generator_spec.rb +33 -0
  48. data/spec/unit/generators/root_generator_spec.rb +35 -0
  49. data/spec/unit/generators/rspec_generator_spec.rb +36 -0
  50. data/spec/unit/generators/tasks_generator_spec.rb +31 -0
  51. data/spec/unit/lib/capybara/dsl_ex_spec.rb +11 -11
  52. data/spec/unit/lib/capybara/settings_spec.rb +336 -58
  53. data/spec/unit/lib/email_spec.rb +17 -17
  54. data/spec/unit/lib/helpers_spec.rb +699 -315
  55. data/spec/unit/lib/mailgun/client_spec.rb +9 -9
  56. data/spec/unit/lib/mailgun/connector_spec.rb +20 -20
  57. data/spec/unit/lib/mailgun/response_spec.rb +9 -9
  58. data/spec/unit/lib/settings_spec.rb +6 -6
  59. data/spec/unit/lib/utils/data_generator/data_storage_spec.rb +31 -31
  60. data/spec/unit/lib/utils/data_generator/gen_spec.rb +20 -20
  61. data/spec/unit/lib/utils/locator_store_spec.rb +39 -39
  62. data/spec/unit/lib/utils/log_spec.rb +42 -42
  63. data/spec/unit/lib/utils/page_validator_spec.rb +69 -70
  64. data/spec/unit/lib/web_page_spec.rb +91 -69
  65. data/spec/unit/version_spec.rb +3 -3
  66. metadata +100 -78
  67. data/spec/unit/generators/generators_spec.rb +0 -175
@@ -2,27 +2,27 @@ require 'spec_helper'
2
2
  require 'howitzer/utils/log'
3
3
  include LoggerHelper
4
4
 
5
- describe "Logger" do
5
+ RSpec.describe 'Logger' do
6
6
  let(:path) { File.join(log_path,'log.txt') }
7
- context "#log" do
7
+ context '#log' do
8
8
  subject { log }
9
9
  let(:other_log) { Howitzer::Log.instance }
10
- it { expect(subject).to be_a_kind_of(Howitzer::Log) }
11
- it { expect(subject).to equal(other_log) }
10
+ it { is_expected.to be_a_kind_of(Howitzer::Log) }
11
+ it { is_expected.to equal(other_log) }
12
12
  end
13
13
 
14
- context ".print_feature_name" do
14
+ context '.print_feature_name' do
15
15
  let(:feature) { 'Some feature' }
16
16
  let(:expected_result) { "*** Feature: SOME FEATURE ***\n"}
17
17
  subject { read_file(path) }
18
18
  before { log.print_feature_name(feature) }
19
19
  after { clear_file(path) }
20
- it { expect(subject).to include(expected_result) }
20
+ it { is_expected.to include(expected_result) }
21
21
  end
22
22
 
23
- context ".settings_as_formatted_text" do
24
- let(:formatted_text) { Faker::Lorem.sentence }
25
- let(:as_formatted_text) { double() }
23
+ context '.settings_as_formatted_text' do
24
+ let(:formatted_text) { FFaker::Lorem.sentence }
25
+ let(:as_formatted_text) { double }
26
26
  let(:expected_result) { formatted_text }
27
27
  subject { read_file(path) }
28
28
  before do
@@ -30,77 +30,77 @@ describe "Logger" do
30
30
  log.settings_as_formatted_text
31
31
  end
32
32
  after { clear_file(path) }
33
- it { expect(subject).to include(expected_result) }
33
+ it { is_expected.to include(expected_result) }
34
34
  end
35
35
 
36
- context ".print_scenario_name" do
36
+ context '.print_scenario_name' do
37
37
  let(:expected_result) { " => Scenario: Some scenario\n" }
38
38
  let(:scenario) { 'Some scenario' }
39
39
  subject { read_file(path) }
40
40
  before { log.print_scenario_name(scenario) }
41
41
  after { clear_file(path) }
42
- it { expect(subject).to include(expected_result) }
42
+ it { is_expected.to include(expected_result) }
43
43
  end
44
44
 
45
- context ".error" do
46
- context "when one argument given" do
45
+ context '.error' do
46
+ context 'when one argument given' do
47
47
  subject { log.error(*args) }
48
- context "when exception given as argument" do
49
- let(:args) { [StandardError.new("Exception_error_message")] }
50
- it { expect {subject}.to raise_error(StandardError, "Exception_error_message") }
48
+ context 'when exception given as argument' do
49
+ let(:args) { [StandardError.new('Exception_error_message')] }
50
+ it { expect {subject}.to raise_error(StandardError, 'Exception_error_message') }
51
51
  end
52
- context "when message given as argument" do
53
- let(:args) { ["Runtime_error_message"] }
54
- it { expect {subject}.to raise_error(RuntimeError, "Runtime_error_message") }
52
+ context 'when message given as argument' do
53
+ let(:args) { ['Runtime_error_message'] }
54
+ it { expect {subject}.to raise_error(RuntimeError, 'Runtime_error_message') }
55
55
  end
56
- context "when error object given as arg " do
56
+ context 'when error object given as arg ' do
57
57
  let(:error_object) { ErrorObject = StandardError.new }
58
58
  let(:args) { error_object }
59
59
  it { expect {subject}.to raise_error(StandardError) }
60
- it { expect(read_file(path)).to include("[ERROR] [StandardError] StandardError") }
60
+ it { expect(read_file(path)).to include('[ERROR] [StandardError] StandardError') }
61
61
  end
62
- context "when number given as arg" do
62
+ context 'when number given as arg' do
63
63
  let(:args) { 123 }
64
64
  it { expect {subject}.to raise_error(RuntimeError) }
65
65
  end
66
66
  end
67
- context "when two arguments given" do
67
+ context 'when two arguments given' do
68
68
  subject { log.error(*args) }
69
- context "when given text as first arg and caller as second" do
70
- let(:args) { ["Some_text","two_args_caller"] }
69
+ context 'when given text as first arg and caller as second' do
70
+ let(:args) { %w(Some_text two_args_caller) }
71
71
  it { expect {subject}.to raise_error(RuntimeError) }
72
- it { expect(read_file(path)).to include("[ERROR] [RuntimeError] Some_text") }
73
- it { expect(read_file(path)).to include("two_args_caller") }
72
+ it { expect(read_file(path)).to include('[ERROR] [RuntimeError] Some_text') }
73
+ it { expect(read_file(path)).to include('two_args_caller') }
74
74
  end
75
- context "when given class inherited from Exception as first arg and message as second" do
75
+ context 'when given class inherited from Exception as first arg and message as second' do
76
76
  let(:error_class) {SomeError = Class.new(Exception) }
77
- let(:args) { [error_class,"some text"] }
78
- it { expect { subject }.to raise_error(error_class,"some text") }
79
- it { expect(read_file(path)).to include("[ERROR] [SomeError] some text") }
77
+ let(:args) { [error_class, 'some text'] }
78
+ it { expect { subject }.to raise_error(error_class, 'some text') }
79
+ it { expect(read_file(path)).to include('[ERROR] [SomeError] some text') }
80
80
  end
81
- context "when given some class as first arg and (message) as second" do
82
- let(:some_class) { SomeClass = Class.new() }
83
- let(:args) { [some_class, "some text" ] }
81
+ context 'when given some class as first arg and (message) as second' do
82
+ let(:some_class) { SomeClass = Class.new }
83
+ let(:args) { [some_class, 'some text'] }
84
84
  it { expect{subject}.to raise_error(RuntimeError) }
85
85
  it { expect(read_file(path)).to include("[ERROR] [RuntimeError] SomeClass\n\tsome text") }
86
86
  end
87
- context "when number given as first arg and message as second" do
87
+ context 'when number given as first arg and message as second' do
88
88
  let(:args) { [123, 'some text' ] }
89
89
  it { expect{subject}.to raise_error(RuntimeError) }
90
90
  it { expect(read_file(path)).to include("[ERROR] [RuntimeError] 123\n\tsome text") }
91
91
  end
92
- context "when nubmers given as args" do
92
+ context 'when nubmers given as args' do
93
93
  let(:args) { [123,123] }
94
94
  it { expect{subject}.to raise_error(TypeError) }
95
95
  end
96
96
  end
97
- context "when three arguments given" do
97
+ context 'when three arguments given' do
98
98
  subject { log.error(*args) }
99
- context "when NameError given as first arg, message as second and caller as third" do
100
- let(:args) { [NameError, "Name_error_text","three_args_caller"] }
99
+ context 'when NameError given as first arg, message as second and caller as third' do
100
+ let(:args) { [NameError, 'Name_error_text', 'three_args_caller'] }
101
101
  it { expect {subject}.to raise_error(NameError) }
102
- it { expect(read_file(path)).to include("[ERROR] [NameError] Name_error_text") }
103
- it { expect(read_file(path)).to include("three_args_caller") }
102
+ it { expect(read_file(path)).to include('[ERROR] [NameError] Name_error_text') }
103
+ it { expect(read_file(path)).to include('three_args_caller') }
104
104
  end
105
105
  end
106
106
  end
@@ -1,14 +1,14 @@
1
1
  require 'spec_helper'
2
- require "howitzer/utils/page_validator"
3
- require "howitzer/utils/locator_store"
2
+ require 'howitzer/utils/page_validator'
3
+ require 'howitzer/utils/locator_store'
4
4
 
5
- describe Howitzer::Utils::PageValidator do
6
- describe ".validations" do
5
+ RSpec.describe Howitzer::Utils::PageValidator do
6
+ describe '.validations' do
7
7
  it { expect(subject.validations).to eql({}) }
8
8
  end
9
9
  end
10
10
 
11
- describe "PageValidator" do
11
+ RSpec.describe 'PageValidator' do
12
12
  let(:web_page_class) do
13
13
  Class.new do
14
14
  include LocatorStore
@@ -19,35 +19,35 @@ describe "PageValidator" do
19
19
  end
20
20
  end
21
21
  let(:web_page) { web_page_class.new }
22
- describe "#check_validations_are_defined!" do
22
+ describe '#check_validations_are_defined!' do
23
23
  subject { web_page.check_validations_are_defined! }
24
- context "when no validation specified" do
24
+ context 'when no validation specified' do
25
25
  it do
26
26
  expect(log).to receive(:error).with(Howitzer::NoValidationError, "No any page validation was found for 'TestWebPageClass' page").once.and_call_original
27
27
  expect { subject }.to raise_error(Howitzer::NoValidationError)
28
28
  end
29
29
  end
30
- context "when old validation style is using" do
31
- before { web_page_class.const_set("URL_PATTERN",/Foo/) }
32
- after { web_page_class.send :remove_const, "URL_PATTERN"}
30
+ context 'when old validation style is using' do
31
+ before { web_page_class.const_set('URL_PATTERN',/Foo/) }
32
+ after { web_page_class.send :remove_const, 'URL_PATTERN' }
33
33
  it do
34
- expect(web_page_class).to receive(:validates).with(:url, pattern: /Foo/).and_return{ Howitzer::Utils::PageValidator.validations['TestWebPageClass'] = {}}
34
+ expect(web_page_class).to receive(:validates).with(:url, pattern: /Foo/){ Howitzer::Utils::PageValidator.validations['TestWebPageClass'] = {}}
35
35
  expect{subject}.to_not raise_error
36
36
  end
37
37
  end
38
- context "when title validation is specified" do
38
+ context 'when title validation is specified' do
39
39
  before do
40
40
  web_page.class.validates :title, pattern: /Foo/
41
41
  end
42
42
  it { expect{subject}.to_not raise_error }
43
43
  end
44
- context "when url validation is specified" do
44
+ context 'when url validation is specified' do
45
45
  before do
46
46
  web_page.class.validates :url, pattern: /Foo/
47
47
  end
48
48
  it { expect{subject}.to_not raise_error }
49
49
  end
50
- context "when element_presence validation is specified" do
50
+ context 'when element_presence validation is specified' do
51
51
  before do
52
52
  web_page.class.validates :element_presence, locator: :test_locator
53
53
  end
@@ -55,88 +55,88 @@ describe "PageValidator" do
55
55
  end
56
56
  end
57
57
 
58
- describe ".validates" do
58
+ describe '.validates' do
59
59
  before do
60
60
  Howitzer::Utils::PageValidator.validations[web_page.class.name] = nil
61
61
  end
62
62
  subject { web_page.class.validates(name, options) }
63
- context "when name = :url" do
64
- context "as string" do
65
- let(:name) { "url" }
66
- context "when options is correct" do
67
- context "(as string)" do
68
- let(:options) { {"pattern" => /foo/} }
63
+ context 'when name = :url' do
64
+ context 'as string' do
65
+ let(:name) { 'url' }
66
+ context 'when options is correct' do
67
+ context '(as string)' do
68
+ let(:options) { {'pattern' => /foo/} }
69
69
  it do
70
- expect(subject).to be_a(Proc)
70
+ is_expected.to be_a(Proc)
71
71
  expect(Howitzer::Utils::PageValidator.validations[web_page.class.name][:url]).to be_a Proc
72
72
  end
73
73
  end
74
- context "(as symbol)" do
74
+ context '(as symbol)' do
75
75
  let(:options) { {pattern: /foo/} }
76
76
  it do
77
- expect(subject).to be_a(Proc)
77
+ is_expected.to be_a(Proc)
78
78
  expect(Howitzer::Utils::PageValidator.validations[web_page.class.name][:url]).to be_a Proc
79
79
  end
80
80
  end
81
81
  end
82
- context "when options is incorrect" do
83
- context "(missing pattern)" do
82
+ context 'when options is incorrect' do
83
+ context '(missing pattern)' do
84
84
  let(:options) { {} }
85
85
  it do
86
86
  expect(log).to receive(:error).with(Howitzer::WrongOptionError, "Please specify ':pattern' option as Regexp object").once.and_call_original
87
87
  expect { subject }.to raise_error(Howitzer::WrongOptionError)
88
88
  end
89
89
  end
90
- context "(string pattern)" do
91
- let(:options) { {pattern: "foo"} }
90
+ context '(string pattern)' do
91
+ let(:options) { {pattern: 'foo'} }
92
92
  it do
93
93
  expect(log).to receive(:error).with(Howitzer::WrongOptionError, "Please specify ':pattern' option as Regexp object").once.and_call_original
94
94
  expect { subject }.to raise_error(Howitzer::WrongOptionError)
95
95
  end
96
96
  end
97
- context "(not hash)" do
98
- let(:options) { "foo" }
97
+ context '(not hash)' do
98
+ let(:options) { 'foo' }
99
99
  it { expect{subject}.to raise_error(TypeError, "Expected options to be Hash, actual is 'String'") }
100
100
  end
101
101
  end
102
102
  end
103
- context "as symbol" do
103
+ context 'as symbol' do
104
104
  let(:name) { :url }
105
105
  let(:options) { {pattern: /foo/} }
106
106
  it do
107
- expect(subject).to be_a(Proc)
107
+ is_expected.to be_a(Proc)
108
108
  expect(Howitzer::Utils::PageValidator.validations[web_page.class.name][:url]).to be_a Proc
109
109
  end
110
110
  end
111
111
  end
112
- context "when name = :element_presence" do
112
+ context 'when name = :element_presence' do
113
113
  let(:name) { :element_presence }
114
- context "when options is correct" do
115
- context "(as string)" do
116
- let(:options) { {"locator" => 'test_locator'} }
114
+ context 'when options is correct' do
115
+ context '(as string)' do
116
+ let(:options) { {'locator' => 'test_locator'} }
117
117
  it do
118
- expect(subject).to be_a(Proc)
118
+ is_expected.to be_a(Proc)
119
119
  expect(Howitzer::Utils::PageValidator.validations[web_page.class.name][:element_presence]).to eql(subject)
120
120
  end
121
121
  end
122
- context "(as symbol)" do
122
+ context '(as symbol)' do
123
123
  let(:options) { {locator: :test_locator} }
124
124
  it do
125
- expect(subject).to be_a(Proc)
125
+ is_expected.to be_a(Proc)
126
126
  expect(Howitzer::Utils::PageValidator.validations[web_page.class.name][:element_presence]).to eql(subject)
127
127
  end
128
128
  end
129
129
  end
130
- context "when options is incorrect" do
131
- context "(missing locator)" do
130
+ context 'when options is incorrect' do
131
+ context '(missing locator)' do
132
132
  let(:options) { {} }
133
133
  it do
134
134
  expect(log).to receive(:error).with(Howitzer::WrongOptionError, "Please specify ':locator' option as one of page locator names").once.and_call_original
135
135
  expect { subject }.to raise_error(Howitzer::WrongOptionError)
136
136
  end
137
137
  end
138
- context "(blank locator name)" do
139
- let(:options) { {locator: ""} }
138
+ context '(blank locator name)' do
139
+ let(:options) { {locator: ''} }
140
140
  it do
141
141
  expect(log).to receive(:error).with(Howitzer::WrongOptionError, "Please specify ':locator' option as one of page locator names").once.and_call_original
142
142
  expect { subject }.to raise_error(Howitzer::WrongOptionError)
@@ -144,34 +144,34 @@ describe "PageValidator" do
144
144
  end
145
145
  end
146
146
  end
147
- context "when name = :title" do
147
+ context 'when name = :title' do
148
148
  let(:name) { :title }
149
- context "when options is correct" do
150
- context "(as string)" do
151
- let(:options) { {"pattern" => /foo/} }
149
+ context 'when options is correct' do
150
+ context '(as string)' do
151
+ let(:options) { {'pattern' => /foo/} }
152
152
  it do
153
- expect(subject).to be_a(Proc)
153
+ is_expected.to be_a(Proc)
154
154
  expect(Howitzer::Utils::PageValidator.validations[web_page.class.name][:title]).to be_a Proc
155
155
  end
156
156
  end
157
- context "(as symbol)" do
157
+ context '(as symbol)' do
158
158
  let(:options) { {pattern: /foo/} }
159
159
  it do
160
- expect(subject).to be_a(Proc)
160
+ is_expected.to be_a(Proc)
161
161
  expect(Howitzer::Utils::PageValidator.validations[web_page.class.name][:title]).to be_a Proc
162
162
  end
163
163
  end
164
164
  end
165
- context "when options is incorrect" do
166
- context "(missing pattern)" do
165
+ context 'when options is incorrect' do
166
+ context '(missing pattern)' do
167
167
  let(:options) { {} }
168
168
  it do
169
169
  expect(log).to receive(:error).with(Howitzer::WrongOptionError, "Please specify ':pattern' option as Regexp object").once.and_call_original
170
170
  expect { subject }.to raise_error(Howitzer::WrongOptionError)
171
171
  end
172
172
  end
173
- context "(string pattern)" do
174
- let(:options) { {pattern: "foo"} }
173
+ context '(string pattern)' do
174
+ let(:options) { {pattern: 'foo'} }
175
175
  it do
176
176
  expect(log).to receive(:error).with(Howitzer::WrongOptionError, "Please specify ':pattern' option as Regexp object").once.and_call_original
177
177
  expect { subject }.to raise_error(Howitzer::WrongOptionError)
@@ -179,7 +179,7 @@ describe "PageValidator" do
179
179
  end
180
180
  end
181
181
  end
182
- context "when other name" do
182
+ context 'when other name' do
183
183
  let(:name) { :unknown }
184
184
  let(:options) { {} }
185
185
  it do
@@ -189,52 +189,52 @@ describe "PageValidator" do
189
189
  end
190
190
  end
191
191
 
192
- describe ".pages" do
192
+ describe '.pages' do
193
193
  subject { Howitzer::Utils::PageValidator.pages }
194
- it { expect(subject).to eq([]) }
194
+ it { is_expected.to eq([]) }
195
195
  it do
196
196
  subject << Class
197
- expect(subject).to eql([Class])
197
+ is_expected.to eql([Class])
198
198
  end
199
199
  end
200
200
 
201
- describe ".opened?" do
201
+ describe '.opened?' do
202
202
  subject { web_page_class.opened? }
203
- context "when no one validation is defined" do
203
+ context 'when no one validation is defined' do
204
204
  it do
205
205
  expect(log).to receive(:error).with(Howitzer::NoValidationError, "No any page validation was found for 'TestWebPageClass' page").once.and_call_original
206
206
  expect { subject }.to raise_error(Howitzer::NoValidationError)
207
207
  end
208
208
  end
209
- context "when all validations are defined" do
209
+ context 'when all validations are defined' do
210
210
  before do
211
211
  web_page_class.class_eval do
212
- add_locator :login, "#id"
212
+ add_locator :login, '#id'
213
213
  validates :url, pattern: /foo/
214
214
  validates :title, pattern: /Foo page/
215
215
  validates :element_presence, locator: :login
216
216
  end
217
217
  end
218
- context "when all matches" do
218
+ context 'when all matches' do
219
219
  before do
220
220
  allow(web_page_class).to receive(:url){ 'http://test.com/foo' }
221
221
  allow(web_page_class).to receive(:title){ 'Foo page' }
222
222
  allow(web_page_class).to receive(:first_element).with(:login){ true }
223
223
  end
224
- it { expect(subject).to be_true }
224
+ it { is_expected.to be_truthy }
225
225
  end
226
- context "when first does not match" do
226
+ context 'when first does not match' do
227
227
  before do
228
228
  expect(web_page_class).to receive(:url).once{ 'http://test.com/bar' }
229
229
  expect(web_page_class).to receive(:title).never
230
230
  expect(web_page_class).to receive(:first_element).never
231
231
  end
232
- it { expect(subject).to be_false }
232
+ it { is_expected.to be_falsey }
233
233
  end
234
234
  end
235
235
  end
236
236
 
237
- describe "#matched_pages" do
237
+ describe '#matched_pages' do
238
238
  let!(:web_page1_class) do
239
239
  Class.new do
240
240
  include Howitzer::Utils::PageValidator
@@ -260,7 +260,6 @@ describe "PageValidator" do
260
260
  end
261
261
  subject {web_page2_class.matched_pages }
262
262
  before { Howitzer::Utils::PageValidator.instance_variable_set(:@pages, [web_page1_class, web_page2_class]) }
263
- it { expect(subject).to eq([web_page1_class]) }
263
+ it { is_expected.to eq([web_page1_class]) }
264
264
  end
265
-
266
- end
265
+ end