howitzer 2.0.3 → 2.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (139) hide show
  1. checksums.yaml +5 -5
  2. data/CHANGELOG.md +69 -11
  3. data/LICENSE +1 -1
  4. data/README.md +21 -17
  5. data/bin/howitzer +7 -6
  6. data/generators/base_generator.rb +31 -17
  7. data/generators/config/config_generator.rb +11 -3
  8. data/generators/config/templates/boot.rb +3 -3
  9. data/generators/config/templates/capybara.rb +6 -131
  10. data/generators/config/templates/default.yml +34 -13
  11. data/generators/config/templates/drivers/appium.rb +25 -0
  12. data/generators/config/templates/drivers/browserstack.rb +23 -0
  13. data/generators/config/templates/drivers/crossbrowsertesting.rb +29 -0
  14. data/generators/config/templates/drivers/headless_chrome.rb +15 -0
  15. data/generators/config/templates/drivers/headless_firefox.rb +23 -0
  16. data/generators/config/templates/drivers/sauce.rb +25 -0
  17. data/generators/config/templates/drivers/selenium.rb +24 -0
  18. data/generators/config/templates/drivers/selenium_grid.rb +31 -0
  19. data/generators/config/templates/drivers/testingbot.rb +24 -0
  20. data/generators/cucumber/cucumber_generator.rb +2 -2
  21. data/generators/cucumber/templates/common_steps.rb +3 -3
  22. data/generators/cucumber/templates/cucumber.rake +5 -13
  23. data/generators/cucumber/templates/cuke_sniffer.rake +2 -2
  24. data/generators/cucumber/templates/env.rb +9 -1
  25. data/generators/cucumber/templates/hooks.rb +8 -2
  26. data/generators/cucumber/templates/transformers.rb +11 -25
  27. data/generators/emails/emails_generator.rb +2 -2
  28. data/generators/emails/templates/example_email.rb +1 -1
  29. data/generators/prerequisites/prerequisites_generator.rb +3 -3
  30. data/generators/prerequisites/templates/base.rb +1 -1
  31. data/generators/prerequisites/templates/{factory_girl.rb → factory_bot.rb} +7 -6
  32. data/generators/prerequisites/templates/users.rb +1 -1
  33. data/generators/root/root_generator.rb +3 -3
  34. data/generators/root/templates/Gemfile.erb +16 -22
  35. data/generators/rspec/rspec_generator.rb +2 -2
  36. data/generators/rspec/templates/rspec.rake +8 -8
  37. data/generators/rspec/templates/spec_helper.rb +6 -5
  38. data/generators/tasks/tasks_generator.rb +2 -2
  39. data/generators/turnip/templates/spec_helper.rb +6 -5
  40. data/generators/turnip/turnip_generator.rb +2 -2
  41. data/generators/web/templates/example_page.rb +1 -1
  42. data/generators/web/web_generator.rb +2 -2
  43. data/lib/howitzer/cache.rb +20 -19
  44. data/lib/howitzer/capybara_helpers.rb +58 -13
  45. data/lib/howitzer/email.rb +3 -2
  46. data/lib/howitzer/exceptions.rb +21 -20
  47. data/lib/howitzer/gmail_api/client.rb +31 -0
  48. data/lib/howitzer/gmail_api.rb +7 -0
  49. data/lib/howitzer/log.rb +6 -6
  50. data/lib/howitzer/mail_adapters/gmail.rb +96 -0
  51. data/lib/howitzer/mail_adapters/mailgun.rb +4 -2
  52. data/lib/howitzer/mail_adapters/mailtrap.rb +108 -0
  53. data/lib/howitzer/mailgun_api/client.rb +3 -2
  54. data/lib/howitzer/mailgun_api/connector.rb +1 -0
  55. data/lib/howitzer/mailgun_api/response.rb +1 -2
  56. data/lib/howitzer/mailtrap_api/client.rb +52 -0
  57. data/lib/howitzer/mailtrap_api.rb +7 -0
  58. data/lib/howitzer/meta/actions.rb +35 -0
  59. data/lib/howitzer/meta/element.rb +40 -0
  60. data/lib/howitzer/meta/entry.rb +62 -0
  61. data/lib/howitzer/meta/iframe.rb +41 -0
  62. data/lib/howitzer/meta/section.rb +30 -0
  63. data/lib/howitzer/meta.rb +11 -0
  64. data/lib/howitzer/utils/string_extensions.rb +6 -2
  65. data/lib/howitzer/version.rb +1 -1
  66. data/lib/howitzer/web/base_section.rb +1 -1
  67. data/lib/howitzer/web/capybara_context_holder.rb +1 -0
  68. data/lib/howitzer/web/capybara_methods_proxy.rb +15 -6
  69. data/lib/howitzer/web/element_dsl.rb +104 -44
  70. data/lib/howitzer/web/iframe_dsl.rb +23 -3
  71. data/lib/howitzer/web/page.rb +16 -4
  72. data/lib/howitzer/web/page_dsl.rb +19 -7
  73. data/lib/howitzer/web/page_validator.rb +27 -26
  74. data/lib/howitzer/web/section.rb +13 -2
  75. data/lib/howitzer/web/section_dsl.rb +65 -30
  76. data/lib/howitzer.rb +66 -10
  77. metadata +67 -133
  78. data/.coveralls.yml +0 -1
  79. data/.gitignore +0 -14
  80. data/.rspec +0 -3
  81. data/.rubocop.yml +0 -44
  82. data/.ruby-gemset +0 -1
  83. data/.travis.yml +0 -7
  84. data/Gemfile +0 -13
  85. data/MAINTENANCE.md +0 -32
  86. data/Rakefile +0 -22
  87. data/features/cli_help.feature +0 -31
  88. data/features/cli_new.feature +0 -349
  89. data/features/cli_unknown.feature +0 -17
  90. data/features/cli_update.feature +0 -178
  91. data/features/cli_version.feature +0 -14
  92. data/features/step_definitions/common_steps.rb +0 -29
  93. data/features/support/env.rb +0 -1
  94. data/features/support/transformers.rb +0 -3
  95. data/generators/root/templates/.gitignore +0 -21
  96. data/generators/root/templates/.rubocop.yml +0 -35
  97. data/generators/turnip/templates/.rspec +0 -1
  98. data/howitzer.gemspec +0 -37
  99. data/lib/howitzer/mail_adapters/debugmail.rb +0 -0
  100. data/spec/config/custom.yml +0 -9
  101. data/spec/spec_helper.rb +0 -72
  102. data/spec/support/generator_helper.rb +0 -21
  103. data/spec/support/logger_helper.rb +0 -13
  104. data/spec/support/mailgun_unit_client.rb +0 -68
  105. data/spec/support/shared_examples/capybara_context_holder.rb +0 -33
  106. data/spec/support/shared_examples/capybara_methods_proxy.rb +0 -94
  107. data/spec/support/shared_examples/dynamic_section_methods.rb +0 -35
  108. data/spec/support/shared_examples/element_dsl.rb +0 -242
  109. data/spec/unit/generators/base_generator_spec.rb +0 -272
  110. data/spec/unit/generators/config_generator_spec.rb +0 -38
  111. data/spec/unit/generators/cucumber_generator_spec.rb +0 -62
  112. data/spec/unit/generators/emails_generator_spec.rb +0 -35
  113. data/spec/unit/generators/prerequisites_generator_spec.rb +0 -53
  114. data/spec/unit/generators/root_generator_spec.rb +0 -72
  115. data/spec/unit/generators/rspec_generator_spec.rb +0 -36
  116. data/spec/unit/generators/tasks_generator_spec.rb +0 -31
  117. data/spec/unit/generators/turnip_generator_spec.rb +0 -52
  118. data/spec/unit/generators/web_generator_spec.rb +0 -52
  119. data/spec/unit/lib/cache_spec.rb +0 -85
  120. data/spec/unit/lib/capybara_helpers_spec.rb +0 -696
  121. data/spec/unit/lib/email_spec.rb +0 -186
  122. data/spec/unit/lib/howitzer_spec.rb +0 -40
  123. data/spec/unit/lib/init_spec.rb +0 -2
  124. data/spec/unit/lib/log_spec.rb +0 -122
  125. data/spec/unit/lib/mail_adapters/abstract_spec.rb +0 -62
  126. data/spec/unit/lib/mail_adapters/mailgun_spec.rb +0 -163
  127. data/spec/unit/lib/mailgun_api/client_spec.rb +0 -58
  128. data/spec/unit/lib/mailgun_api/connector_spec.rb +0 -54
  129. data/spec/unit/lib/mailgun_api/response_spec.rb +0 -28
  130. data/spec/unit/lib/utils/string_extensions_spec.rb +0 -77
  131. data/spec/unit/lib/web/base_section_spec.rb +0 -43
  132. data/spec/unit/lib/web/element_dsl_spec.rb +0 -22
  133. data/spec/unit/lib/web/iframe_dsl_spec.rb +0 -144
  134. data/spec/unit/lib/web/page_dsl_spec.rb +0 -74
  135. data/spec/unit/lib/web/page_spec.rb +0 -349
  136. data/spec/unit/lib/web/page_validator_spec.rb +0 -276
  137. data/spec/unit/lib/web/section_dsl_spec.rb +0 -165
  138. data/spec/unit/lib/web/section_spec.rb +0 -63
  139. data/spec/unit/version_spec.rb +0 -8
@@ -1,28 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/mailgun_api/client'
3
- require 'howitzer/exceptions'
4
-
5
- RSpec.describe Howitzer::MailgunApi::Response do
6
- let(:body) { { foo: 'bar' }.to_json }
7
- let(:response) { double(:response, body: body, code: 201) }
8
- describe '#body' do
9
- subject { described_class.new(response).body }
10
- it { is_expected.to eq('{"foo":"bar"}') }
11
- end
12
- describe '#code' do
13
- subject { described_class.new(response).code }
14
- it { is_expected.to eq(201) }
15
- end
16
- describe '#to_h' do
17
- subject { described_class.new(response).to_h }
18
- context 'when possible parse body' do
19
- it { is_expected.to eq('foo' => 'bar') }
20
- end
21
- context 'when impossible parse body' do
22
- let(:body) { "'123': '123' :123" }
23
- it do
24
- expect { subject }.to raise_error(Howitzer::ParseError)
25
- end
26
- end
27
- end
28
- end
@@ -1,77 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/utils/string_extensions'
3
-
4
- RSpec.describe Howitzer::Utils::StringExtensions do
5
- String.send(:include, Howitzer::Utils::StringExtensions)
6
-
7
- let(:page_name) { 'my' }
8
- let(:page_object) { double }
9
- before { stub_const('MyPage', page_object) }
10
- describe '#open' do
11
- subject { page_name.open(:exit) }
12
- before do
13
- expect(page_object).to receive(:open).with(:exit).once
14
- end
15
- it { is_expected.to be_nil }
16
- end
17
- describe '#given' do
18
- subject { page_name.given }
19
- before do
20
- allow(page_name).to receive(:as_page_class) { page_object }
21
- expect(page_object).to receive(:given).once
22
- end
23
- it { is_expected.to be_nil }
24
- end
25
- describe '#displayed?' do
26
- subject { page_name.displayed? }
27
- before do
28
- allow(page_name).to receive(:as_page_class) { page_object }
29
- expect(page_object).to receive(:displayed?).once
30
- end
31
- it { is_expected.to be_nil }
32
- end
33
- describe '#as_page_class' do
34
- subject { page_name.as_page_class }
35
- context 'when 1 word' do
36
- it { is_expected.to eql(page_object) }
37
- end
38
- context 'when more 1 word' do
39
- let(:page_name) { 'my super mega' }
40
- before { stub_const('MySuperMegaPage', page_object) }
41
- it { is_expected.to eql(page_object) }
42
- end
43
- context 'when plural word' do
44
- let(:page_name) { 'user notifications' }
45
- before { stub_const('UserNotificationsPage', page_object) }
46
- it { is_expected.to eql(page_object) }
47
- end
48
- end
49
- describe '#as_email_class' do
50
- subject { email_name.as_email_class }
51
- let(:my_email) { double }
52
- context 'when 1 word' do
53
- let(:email_name) { 'my' }
54
- before { stub_const('MyEmail', my_email) }
55
- it { is_expected.to eql(my_email) }
56
- end
57
- context 'when more 1 word' do
58
- let(:email_name) { 'my super mega' }
59
- before { stub_const('MySuperMegaEmail', my_email) }
60
- it { is_expected.to eql(my_email) }
61
- end
62
- context 'when plural word' do
63
- let(:email_name) { 'email notifications' }
64
- before { stub_const('EmailNotificationsEmail', my_email) }
65
- it { is_expected.to eql(my_email) }
66
- end
67
- end
68
- describe '#on' do
69
- let(:block) { -> {} }
70
- subject { page_name.on(&block) }
71
- before do
72
- allow(page_name).to receive(:as_page_class) { page_object }
73
- expect(page_object).to receive(:on).once
74
- end
75
- it { is_expected.to be_nil }
76
- end
77
- end
@@ -1,43 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/web/section_dsl'
3
- require 'howitzer/web/base_section'
4
-
5
- RSpec.describe Howitzer::Web::BaseSection do
6
- describe 'element dsl methods' do
7
- let(:parent) { double }
8
- let(:capybara_context) { double }
9
-
10
- let(:klass) { Class.new(described_class) }
11
- let(:klass_object) { klass.new(parent, capybara_context) }
12
- it 'returns correct capybara context' do
13
- expect(klass_object.capybara_context).to eq(capybara_context)
14
- end
15
-
16
- include_examples :element_dsl
17
- end
18
- describe 'DSL' do
19
- describe '.me' do
20
- it { expect { described_class.send(:me, '.foo') }.to raise_error(NoMethodError) }
21
- end
22
- end
23
-
24
- describe '.default_finder_args' do
25
- subject { described_class.default_finder_args }
26
- it { is_expected.to be_nil }
27
- end
28
-
29
- describe '#parent' do
30
- subject { described_class.new(:test, 1).parent }
31
- it { is_expected.to eq(:test) }
32
- end
33
-
34
- describe '#capybara_context' do
35
- subject { described_class.new(1, :test).capybara_context }
36
- it { is_expected.to eq(:test) }
37
- end
38
-
39
- describe 'includes proxied capybara methods' do
40
- let(:reciever) { Class.new(described_class).new(:test, 1) }
41
- include_examples :capybara_methods_proxy
42
- end
43
- end
@@ -1,22 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/web/element_dsl'
3
-
4
- RSpec.describe Howitzer::Web::ElementDsl do
5
- let(:klass) do
6
- Class.new do
7
- include Howitzer::Web::ElementDsl
8
- def capybara_scopes
9
- @_scopes ||= [Capybara.current_session]
10
- end
11
- end
12
- end
13
- let(:klass_object) { klass.new }
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
-
20
- include_examples :element_dsl
21
- include_examples :capybara_context_holder
22
- end
@@ -1,144 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/web/page'
3
-
4
- RSpec.describe Howitzer::Web::IframeDsl do
5
- let(:fb_page_class) do
6
- Class.new(Howitzer::Web::Page) do
7
- section :navbar, :xpath, './body' do
8
- element :like_button, '#foo_id'
9
- end
10
- end
11
- end
12
-
13
- let(:web_page_class) do
14
- Class.new(Howitzer::Web::Page)
15
- end
16
-
17
- before do
18
- allow_any_instance_of(fb_page_class).to receive(:check_validations_are_defined!)
19
- allow_any_instance_of(web_page_class).to receive(:check_validations_are_defined!)
20
- stub_const('FbPage', fb_page_class)
21
- end
22
-
23
- describe '.iframe' do
24
- context 'when selector is integer' do
25
- subject do
26
- web_page_class.class_eval do
27
- iframe :fb, 1
28
- end
29
- web_page_class
30
- end
31
-
32
- it 'should create public :fb_iframe instance method' do
33
- expect(subject.instance.public_methods(false)).to include(:fb_iframe)
34
- end
35
- it 'should create public :has_fb_iframe? instance method' do
36
- expect(subject.instance.public_methods(false)).to include(:has_fb_iframe?)
37
- end
38
- it 'should create public :has_no_fb_iframe? instance method' do
39
- expect(subject.instance.public_methods(false)).to include(:has_no_fb_iframe?)
40
- end
41
- it 'should be protected class method' do
42
- expect { subject.iframe :bar }.to raise_error(NoMethodError)
43
- expect(subject.protected_methods(true)).to include(:iframe)
44
- end
45
- end
46
-
47
- context 'when selector is not specified' do
48
- subject do
49
- web_page_class.class_eval do
50
- iframe :fb
51
- end
52
- web_page_class
53
- end
54
-
55
- it 'should raise error' do
56
- expect { subject }.to raise_error(ArgumentError, 'iframe selector arguments must be specified')
57
- end
58
- end
59
- end
60
-
61
- include_examples :capybara_context_holder
62
-
63
- describe 'dynamic_methods' do
64
- let(:web_page_object) { web_page_class.instance }
65
- let(:kontext) { double(:kontext) }
66
- before do
67
- allow(Capybara).to receive(:current_session) { kontext }
68
- end
69
- after { subject }
70
-
71
- describe '#name_iframe' do
72
- let(:block) { proc {} }
73
- context 'when no options' do
74
- subject { web_page_object.fb_iframe(&block) }
75
- before { web_page_class.class_eval { iframe :fb, 'foo' } }
76
- it do
77
- expect(kontext).to receive(:within_frame)
78
- .with('foo') { |&block| block.call }
79
- expect(block).to receive(:call).with(fb_page_class.instance)
80
- expect(fb_page_class).to receive(:displayed?).with(no_args)
81
- end
82
- end
83
- context 'when all possible options' do
84
- subject { web_page_object.fb_iframe(wait: 10, text: 'new', &block) }
85
- before { web_page_class.class_eval { iframe :fb, :xpath, './/foo', match: :first, text: 'origin' } }
86
- it do
87
- expect(kontext).to receive(:within_frame)
88
- .with(:xpath, './/foo', match: :first, wait: 10, text: 'new') { |&block| block.call }
89
- expect(block).to receive(:call).with(fb_page_class.instance)
90
- expect(fb_page_class).to receive(:displayed?).with(no_args)
91
- end
92
- end
93
- end
94
- describe '#has_name_iframe?' do
95
- subject { web_page_object.has_fb_iframe?(wait: 1, text: 'new') }
96
- context 'when first argument is integer' do
97
- before { web_page_class.class_eval { iframe :fb, 1, match: :first, text: 'origin' } }
98
- it do
99
- expect(kontext).to receive(:has_selector?)
100
- .with('iframe:nth-of-type(2)', match: :first, wait: 1, text: 'new')
101
- end
102
- end
103
- context 'when first argument is string' do
104
- before { web_page_class.class_eval { iframe :fb, 'loko', match: :first, text: 'origin' } }
105
- it { expect(kontext).to receive(:has_selector?).with(:frame, 'loko', match: :first, wait: 1, text: 'new') }
106
- end
107
- context 'when first argument is hash' do
108
- before { web_page_class.class_eval { iframe :fb, name: 'loko', match: :first, text: 'origin' } }
109
- it do
110
- expect(kontext).to receive(:has_selector?)
111
- .with(:frame, name: 'loko', match: :first, wait: 1, text: 'new')
112
- end
113
- end
114
- context 'when first argument is symbol' do
115
- before { web_page_class.class_eval { iframe :fb, :xpath, './/foo', match: :first, text: 'origin' } }
116
- it { expect(kontext).to receive(:has_selector?).with(:xpath, './/foo', match: :first, wait: 1, text: 'new') }
117
- end
118
- end
119
- describe '#has_no_name_iframe?' do
120
- subject { web_page_object.has_no_fb_iframe?(wait: 1, text: 'new') }
121
- context 'when first argument is integer' do
122
- before { web_page_class.class_eval { iframe :fb, 1, match: :first, text: 'origin' } }
123
- it do
124
- expect(kontext).to receive(:has_no_selector?)
125
- .with('iframe:nth-of-type(2)', match: :first, wait: 1, text: 'new')
126
- end
127
- end
128
- context 'when first argument is string' do
129
- before { web_page_class.class_eval { iframe :fb, 'loko', match: :first, text: 'origin' } }
130
- it { expect(kontext).to receive(:has_no_selector?).with(:frame, 'loko', match: :first, wait: 1, text: 'new') }
131
- end
132
- context 'when first argument is hash' do
133
- before { web_page_class.class_eval { iframe :fb, name: 'loko', match: :first, text: 'origin' } }
134
- it do
135
- expect(kontext).to receive(:has_no_selector?).with(:frame, name: 'loko', match: :first, wait: 1, text: 'new')
136
- end
137
- end
138
- context 'when first argument is symbol' do
139
- before { web_page_class.class_eval { iframe :fb, :xpath, './/foo', match: :first, text: 'origin' } }
140
- it { expect(kontext).to receive(:has_no_selector?).with(:xpath, './/foo', match: :first, wait: 1, text: 'new') }
141
- end
142
- end
143
- end
144
- end
@@ -1,74 +0,0 @@
1
- require 'spec_helper'
2
- require 'howitzer/web/page_dsl'
3
-
4
- RSpec.describe Howitzer::Web::PageDsl do
5
- let(:page) { Class.new { include Howitzer::Web::PageDsl } }
6
-
7
- describe '.on' do
8
- subject { page.on { 1 } }
9
- before { expect(Howitzer::Web::PageDsl::PageScope).to receive(:new).with(page) }
10
- it { is_expected.to be_nil }
11
- end
12
- end
13
-
14
- RSpec.describe Howitzer::Web::PageDsl::PageScope do
15
- let(:fake_page) { double }
16
- let(:page) { Class.new }
17
- before { allow(page).to receive(:given) { fake_page } }
18
-
19
- describe '.new' do
20
- subject { described_class.new(page) { bar } }
21
- before { expect_any_instance_of(described_class).to receive(:bar).with(no_args) { true } }
22
- it { is_expected.to be_a(described_class) }
23
- end
24
-
25
- describe '#is_expected' do
26
- let(:scope) { described_class.new(page) { 1 } }
27
- subject { scope.is_expected }
28
- before { expect(scope).to receive(:expect).with(fake_page) { true } }
29
- it { is_expected.to eq(true) }
30
- end
31
-
32
- describe '#method_missing' do
33
- context 'when starts with be_' do
34
- let(:scope) { described_class.new(page) { 1 } }
35
- subject { scope.be_a(described_class) }
36
- it { expect(subject.class).to eq(RSpec::Matchers::BuiltIn::BeAKindOf) }
37
- end
38
-
39
- context 'when starts with have_' do
40
- let(:scope) { described_class.new(page) { 1 } }
41
- subject { scope.have_content(described_class) }
42
- it { expect(subject.class).to eq(RSpec::Matchers::BuiltIn::Has) }
43
- end
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
-
67
- context 'when starts other prefix' do
68
- let(:scope) { described_class.new(page) { 1 } }
69
- subject { scope.foo(1, 2, 3) }
70
- before { expect(fake_page).to receive(:foo).with(1, 2, 3) { true } }
71
- it { is_expected.to eq(true) }
72
- end
73
- end
74
- end