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 +1,22 @@
1
1
  source 'https://rubygems.org'
2
2
 
3
- # Uncomment it if you are going to use 'webkit' driver. QT library should be installed.
4
- # See https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit
5
- #
6
- # gem 'capybara-webkit'
3
+ ruby '>=2.6.8'
7
4
 
8
- gem 'howitzer'
9
- # Uncomment it if you are going to use 'poltergeist' driver. PhantomJS should be installed.
10
- # See https://github.com/jnicklas/capybara#poltergeist
11
- # gem 'poltergeist', git: 'https://github.com/teampoltergeist/poltergeist.git', branch: :master
12
- gem 'rest-client'
13
- gem 'repeater'
14
- gem 'factory_girl'
15
5
  gem 'capybara-screenshot'
16
- <% if cucumber %>
17
- gem 'syntax'
18
- gem 'cucumber', '~>2.0'
19
- gem 'cuke_sniffer', require: false
20
- <% elsif rspec %>
21
- gem 'rspec', '~>3.2'
22
- <% elsif turnip %>
23
- gem 'rspec', '~>3.2'
24
- gem 'turnip'
25
- <% end %>
26
- gem 'rubocop'
6
+ <%= "gem 'cucumber', '>=3.0', '<7'\n" if cucumber -%>
7
+ <%= "gem 'cuke_sniffer', require: false\n" if cucumber -%>
8
+ gem 'factory_bot'
9
+ gem 'howitzer'
27
10
  gem 'pry'
28
11
  gem 'pry-byebug'
12
+ gem 'repeater'
13
+ gem 'rest-client'
14
+ <%= "gem 'rspec', '~>3.2'\n" if rspec || turnip -%>
15
+ gem 'rubocop'
16
+ <%= "gem 'rubocop-rspec'\n" if rspec || turnip -%>
17
+ <%= "gem 'turnip'\n" if turnip -%>
18
+ <%= "gem 'syntax'\n" if cucumber -%>
19
+
20
+ # Uncomment it if you are going to use 'appium' driver. Appium and Android SDK should be installed.
21
+ # See https://appium.io/docs/en/about-appium/getting-started/
22
+ # gem 'appium_capybara'
@@ -15,9 +15,9 @@ module Howitzer
15
15
  protected
16
16
 
17
17
  def banner
18
- <<-EOS
18
+ <<-MSG
19
19
  * RSpec integration to the framework ...
20
- EOS
20
+ MSG
21
21
  end
22
22
  end
23
23
  end
@@ -10,43 +10,43 @@ end
10
10
 
11
11
  RSpec::Core::RakeTask.new(:rspec, 'Run all rspec scenarios') do |t|
12
12
  Howitzer.current_rake_task = t.name
13
- t.opts = opts.call(t.name)
13
+ t.rspec_opts = opts.call(t.name)
14
14
  end
15
15
 
16
16
  RSpec::Core::RakeTask.new(:features, 'Run all workable scenarios (without @wip and @bug tags)') do |t|
17
17
  Howitzer.current_rake_task = t.name
18
- t.opts = "#{opts.call(t.name)} --tag ~wip --tag ~bug"
18
+ t.rspec_opts = "#{opts.call(t.name)} --tag ~wip --tag ~bug"
19
19
  end
20
20
 
21
21
  namespace :features do
22
22
  RSpec::Core::RakeTask.new(:wip, 'Run scenarios in progress (with @wip tag)') do |t|
23
23
  Howitzer.current_rake_task = t.name
24
- t.opts = "#{opts.call(t.name)} --tag wip"
24
+ t.rspec_opts = "#{opts.call(t.name)} --tag wip"
25
25
  end
26
26
 
27
27
  RSpec::Core::RakeTask.new(:bug, 'Run scenarios with known bugs (with @bug tag)') do |t|
28
28
  Howitzer.current_rake_task = t.name
29
- t.opts = "#{opts.call(t.name)} --tag bug"
29
+ t.rspec_opts = "#{opts.call(t.name)} --tag bug"
30
30
  end
31
31
 
32
32
  RSpec::Core::RakeTask.new(:smoke, 'Run workable smoke scenarios (with @smoke tag)') do |t|
33
33
  Howitzer.current_rake_task = t.name
34
- t.opts = "#{opts.call(t.name)} --tag smoke --tag ~wip --tag ~bug"
34
+ t.rspec_opts = "#{opts.call(t.name)} --tag smoke --tag ~wip --tag ~bug"
35
35
  end
36
36
 
37
37
  RSpec::Core::RakeTask.new(:bvt, 'Run workable build verification test scenarios') do |t|
38
38
  Howitzer.current_rake_task = t.name
39
- t.opts = "#{opts.call(t.name)} --tag ~wip --tag ~bug --tag ~p1 --tag ~p2 --tag ~smoke"
39
+ t.rspec_opts = "#{opts.call(t.name)} --tag ~wip --tag ~bug --tag ~p1 --tag ~p2 --tag ~smoke"
40
40
  end
41
41
 
42
42
  RSpec::Core::RakeTask.new(:p1, 'Run workable scenarios with normal priority (with @p1 tag)') do |t|
43
43
  Howitzer.current_rake_task = t.name
44
- t.opts = "#{opts.call(t.name)} --tag p1 --tag ~wip --tag ~bug"
44
+ t.rspec_opts = "#{opts.call(t.name)} --tag p1 --tag ~wip --tag ~bug"
45
45
  end
46
46
 
47
47
  RSpec::Core::RakeTask.new(:p2, 'Run workable scenarios with low priority (with @p2 tag)') do |t|
48
48
  Howitzer.current_rake_task = t.name
49
- t.opts = "#{opts.call(t.name)} --tag p2 --tag ~wip --tag ~bug"
49
+ t.rspec_opts = "#{opts.call(t.name)} --tag p2 --tag ~wip --tag ~bug"
50
50
  end
51
51
  end
52
52
 
@@ -2,7 +2,7 @@ require 'capybara/rspec/features'
2
2
  require_relative '../config/boot'
3
3
  require_relative '../config/capybara'
4
4
 
5
- Dir['./spec/support/**/*.rb'].each { |f| require f }
5
+ Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
6
6
 
7
7
  RSpec.configure do |config|
8
8
  Howitzer::Log.settings_as_formatted_text
@@ -10,13 +10,14 @@ RSpec.configure do |config|
10
10
  Howitzer::Cache.store(:cloud, :start_time, Time.now.utc)
11
11
  Howitzer::Cache.store(:cloud, :status, true)
12
12
 
13
- config.include FactoryGirl::Syntax::Methods
13
+ config.include FactoryBot::Syntax::Methods
14
14
 
15
15
  config.disable_monkey_patching!
16
16
  config.color = true
17
17
  config.wait_timeout = Howitzer.rspec_wait_timeout
18
+ config.order = Howitzer.test_order.presence || :defined
18
19
 
19
- config.before(:each) do
20
+ config.before do
20
21
  scenario_name =
21
22
  if RSpec.current_example.description.blank?
22
23
  RSpec.current_example.metadata[:full_description]
@@ -27,12 +28,12 @@ RSpec.configure do |config|
27
28
  @session_start = CapybaraHelpers.duration(Time.now.utc - Howitzer::Cache.extract(:cloud, :start_time))
28
29
  end
29
30
 
30
- config.after(:each) do
31
+ config.after do
31
32
  Howitzer::Cache.clear_all_ns
32
33
  if CapybaraHelpers.cloud_driver?
33
34
  session_end = CapybaraHelpers.duration(Time.now.utc - Howitzer::Cache.extract(:cloud, :start_time))
34
35
  Howitzer::Log.info "CLOUD VIDEO #{@session_start} - #{session_end}" \
35
- " URL: #{CapybaraHelpers.cloud_resource_path(:video)}"
36
+ " URL: #{CapybaraHelpers.cloud_resource_path(:video)}"
36
37
  elsif CapybaraHelpers.ie_browser?
37
38
  Howitzer::Log.info 'IE reset session'
38
39
  Capybara.current_session.execute_script("void(document.execCommand('ClearAuthenticationCache', false));")
@@ -10,9 +10,9 @@ module Howitzer
10
10
  protected
11
11
 
12
12
  def banner
13
- <<-EOF
13
+ <<-MSG
14
14
  * Base rake task generation ...
15
- EOF
15
+ MSG
16
16
  end
17
17
  end
18
18
  end
@@ -1,7 +1,7 @@
1
1
  require_relative '../config/boot'
2
2
  require_relative '../config/capybara'
3
3
 
4
- Dir['./spec/support/**/*.rb'].each { |f| require f }
4
+ Dir['./spec/support/**/*.rb'].sort.each { |f| require f }
5
5
 
6
6
  RSpec.configure do |config|
7
7
  Howitzer::Log.settings_as_formatted_text
@@ -9,13 +9,14 @@ RSpec.configure do |config|
9
9
  Howitzer::Cache.store(:cloud, :start_time, Time.now.utc)
10
10
  Howitzer::Cache.store(:cloud, :status, true)
11
11
 
12
- config.include FactoryGirl::Syntax::Methods
12
+ config.include FactoryBot::Syntax::Methods
13
13
 
14
14
  config.disable_monkey_patching!
15
15
  config.color = true
16
16
  config.wait_timeout = Howitzer.rspec_wait_timeout
17
+ config.order = Howitzer.test_order.presence || :defined
17
18
 
18
- config.before(:each) do
19
+ config.before do
19
20
  scenario_name =
20
21
  if RSpec.current_example.description.blank?
21
22
  RSpec.current_example.metadata[:full_description]
@@ -26,12 +27,12 @@ RSpec.configure do |config|
26
27
  @session_start = CapybaraHelpers.duration(Time.now.utc - Howitzer::Cache.extract(:cloud, :start_time))
27
28
  end
28
29
 
29
- config.after(:each) do
30
+ config.after do
30
31
  Howitzer::Cache.clear_all_ns
31
32
  if CapybaraHelpers.cloud_driver?
32
33
  session_end = CapybaraHelpers.duration(Time.now.utc - Howitzer::Cache.extract(:cloud, :start_time))
33
34
  Howitzer::Log.info "CLOUD VIDEO #{@session_start} - #{session_end}" \
34
- " URL: #{CapybaraHelpers.cloud_resource_path(:video)}"
35
+ " URL: #{CapybaraHelpers.cloud_resource_path(:video)}"
35
36
  elsif CapybaraHelpers.ie_browser?
36
37
  Howitzer::Log.info 'IE reset session'
37
38
  Capybara.current_session.execute_script("void(document.execCommand('ClearAuthenticationCache', false));")
@@ -18,9 +18,9 @@ module Howitzer
18
18
  protected
19
19
 
20
20
  def banner
21
- <<-EOS
21
+ <<-MSG
22
22
  * Turnip integration to the framework ...
23
- EOS
23
+ MSG
24
24
  end
25
25
  end
26
26
  end
@@ -1,7 +1,7 @@
1
1
  # This class is example of web page
2
2
  class ExamplePage < Howitzer::Web::Page
3
3
  path '/'
4
- validate :url, %r{\A(?:.*?:\/\/)?[^\/]*\/?\z}
4
+ validate :url, %r{\A(?:.*?://)?[^/]*/?\z}
5
5
 
6
6
  section :menu
7
7
 
@@ -14,9 +14,9 @@ module Howitzer
14
14
  protected
15
15
 
16
16
  def banner
17
- <<-EOS
17
+ <<-MSG
18
18
  * PageOriented pattern structure generation ...
19
- EOS
19
+ MSG
20
20
  end
21
21
  end
22
22
  end
@@ -4,7 +4,7 @@ module Howitzer
4
4
  # Data can be stored in memory using this class
5
5
  #
6
6
  module Cache
7
- SPECIAL_NS_LIST = [:cloud].freeze #:nodoc:
7
+ SPECIAL_NS_LIST = [:cloud].freeze # :nodoc:
8
8
  @data ||= {}
9
9
 
10
10
  class << self
@@ -12,35 +12,35 @@ module Howitzer
12
12
 
13
13
  # Saves data into memory. Marking by a namespace and a key
14
14
  #
15
- # @param ns [String] a namespace
15
+ # @param namespace [String] a namespace
16
16
  # @param key [String] a key that should be uniq within the namespace
17
17
  # @param value [Object] everything you want to store in Memory
18
18
  # @raise [NoDataError] if the namespace missing
19
19
 
20
- def store(ns, key, value)
21
- check_ns(ns)
22
- @data[ns][key] = value
20
+ def store(namespace, key, value)
21
+ check_ns(namespace)
22
+ @data[namespace][key] = value
23
23
  end
24
24
 
25
25
  # Gets data from memory. Can get all namespace or single data value in namespace using key
26
26
  #
27
- # @param ns [String] a namespace
27
+ # @param namespace [String] a namespace
28
28
  # @param key [String] key that isn't necessary required
29
29
  # @return [Object, Hash] all data from the namespace if the key is ommited, otherwise returs
30
30
  # all data for the namespace
31
31
  # @raise [NoDataError] if the namespace missing
32
32
 
33
- def extract(ns, key = nil)
34
- check_ns(ns)
35
- key ? @data[ns][key] : @data[ns]
33
+ def extract(namespace, key = nil)
34
+ check_ns(namespace)
35
+ key ? @data[namespace][key] : @data[namespace]
36
36
  end
37
37
 
38
38
  # Deletes all data from a namespace
39
39
  #
40
- # @param ns [String] a namespace
40
+ # @param namespace [String] a namespace
41
41
 
42
- def clear_ns(ns)
43
- init_ns(ns)
42
+ def clear_ns(namespace)
43
+ init_ns(namespace)
44
44
  end
45
45
 
46
46
  # Deletes all namespaces with data
@@ -53,17 +53,18 @@ module Howitzer
53
53
 
54
54
  private
55
55
 
56
- def check_ns(ns)
57
- raise Howitzer::NoDataError, 'Data storage namespace can not be empty' unless ns
58
- init_ns(ns) if ns_absent?(ns)
56
+ def check_ns(namespace)
57
+ raise Howitzer::NoDataError, 'Data storage namespace can not be empty' unless namespace
58
+
59
+ init_ns(namespace) if ns_absent?(namespace)
59
60
  end
60
61
 
61
- def ns_absent?(ns)
62
- !@data.key?(ns)
62
+ def ns_absent?(namespace)
63
+ !@data.key?(namespace)
63
64
  end
64
65
 
65
- def init_ns(ns)
66
- @data[ns] = {}
66
+ def init_ns(namespace)
67
+ @data[namespace] = {}
67
68
  end
68
69
  end
69
70
  end
@@ -1,16 +1,52 @@
1
1
  require 'rest-client'
2
2
  require 'howitzer/exceptions'
3
3
 
4
+ # There is an issue with supporting Ruby 3 by Selenium Webdriver 3.x version
5
+ # https://github.com/SeleniumHQ/selenium/issues/9001
6
+ # Migration to Selenium Webdriver 4 is planned when it will be released without alfa, beta stages.
7
+ if Gem::Requirement.new('>=3').satisfied_by?(Gem::Version.new(RUBY_VERSION)) ||
8
+ Gem::Requirement.new(['>=3', '<4']).satisfied_by?(Gem::Version.new(Selenium::WebDriver::VERSION))
9
+ module Selenium
10
+ module WebDriver
11
+ module Remote
12
+ class Bridge # rubocop:disable Style/Documentation
13
+ class << self
14
+ alias original_handshake handshake
15
+
16
+ def handshake(opts = {})
17
+ original_handshake(**opts)
18
+ end
19
+ end
20
+ end
21
+ end
22
+ end
23
+ end
24
+ end
25
+
4
26
  module Howitzer
5
27
  # This module holds capybara helpers methods
6
28
  module CapybaraHelpers
7
- CHECK_YOUR_SETTINGS_MSG = 'Please check your settings'.freeze #:nodoc:
29
+ CHECK_YOUR_SETTINGS_MSG = 'Please check your settings'.freeze # :nodoc:
30
+ HOWITZER_KNOWN_BROWSERS = [ # :nodoc:
31
+ CLOUD_BROWSERS = [
32
+ SAUCE = :sauce,
33
+ TESTINGBOT = :testingbot,
34
+ BROWSERSTACK = :browserstack,
35
+ CROSSBROWSERTESTING = :crossbrowsertesting
36
+ ].freeze,
37
+ LOCAL_BROWSERS = [
38
+ HEADLESS_CHROME = :headless_chrome,
39
+ HEADLESS_FIREFOX = :headless_firefox,
40
+ SELENIUM = :selenium,
41
+ SELENIUM_GRID = :selenium_grid
42
+ ].freeze
43
+ ].freeze
8
44
 
9
45
  # @return [Boolean] true if current driver related with SauceLab,
10
46
  # Testingbot or Browserstack cloud service
11
47
 
12
48
  def cloud_driver?
13
- %i[sauce testingbot browserstack].include?(Howitzer.driver.to_sym)
49
+ CLOUD_BROWSERS.include?(Howitzer.driver.to_sym)
14
50
  end
15
51
 
16
52
  # @return [Boolean] whether or not current browser is
@@ -64,7 +100,7 @@ module Howitzer
64
100
 
65
101
  def update_cloud_job_status(json_data = {})
66
102
  case Howitzer.driver.to_sym
67
- when :sauce then update_sauce_job_status(json_data)
103
+ when SAUCE then update_sauce_job_status(json_data)
68
104
  else
69
105
  '[NOT IMPLEMENTED]'
70
106
  end
@@ -102,7 +138,8 @@ module Howitzer
102
138
 
103
139
  def cloud_driver(app, caps, url)
104
140
  http_client = ::Selenium::WebDriver::Remote::Http::Default.new
105
- http_client.timeout = Howitzer.cloud_http_idle_timeout
141
+ http_client.read_timeout = Howitzer.cloud_http_idle_timeout
142
+ http_client.open_timeout = Howitzer.cloud_http_idle_timeout
106
143
 
107
144
  options = {
108
145
  url: url,
@@ -110,7 +147,7 @@ module Howitzer
110
147
  http_client: http_client,
111
148
  browser: :remote
112
149
  }
113
- driver = Capybara::Selenium::Driver.new(app, options)
150
+ driver = Capybara::Selenium::Driver.new(app, **options)
114
151
  driver.browser.file_detector = remote_file_detector
115
152
  driver
116
153
  end
@@ -121,7 +158,7 @@ module Howitzer
121
158
 
122
159
  def cloud_resource_path(kind)
123
160
  case Howitzer.driver.to_sym
124
- when :sauce then sauce_resource_path(kind)
161
+ when SAUCE then sauce_resource_path(kind)
125
162
  else
126
163
  '[NOT IMPLEMENTED]'
127
164
  end
@@ -136,24 +173,32 @@ module Howitzer
136
173
 
137
174
  def cloud_browser?(*browser_aliases)
138
175
  unless Howitzer.cloud_browser_name.nil?
139
- return browser_aliases.include?(Howitzer.cloud_browser_name.to_s.to_sym)
176
+ return browser_aliases.include?(Howitzer.cloud_browser_name.to_s.downcase.to_sym)
140
177
  end
178
+
141
179
  raise Howitzer::CloudBrowserNotSpecifiedError, CHECK_YOUR_SETTINGS_MSG
142
180
  end
143
181
 
144
182
  def selenium_browser?(*browser_aliases)
145
- unless Howitzer.selenium_browser.nil?
146
- return browser_aliases.include?(Howitzer.selenium_browser.to_s.to_sym)
147
- end
183
+ return browser_aliases.include?(Howitzer.selenium_browser.to_s.to_sym) unless Howitzer.selenium_browser.nil?
184
+
148
185
  raise Howitzer::SelBrowserNotSpecifiedError, CHECK_YOUR_SETTINGS_MSG
149
186
  end
150
187
 
151
188
  def selenium_driver?
152
- Howitzer.driver.to_sym == :selenium
189
+ Howitzer.driver.to_sym == SELENIUM
190
+ end
191
+
192
+ def headless_chrome_driver?
193
+ Howitzer.driver.to_sym == HEADLESS_CHROME
194
+ end
195
+
196
+ def headless_firefox_driver?
197
+ Howitzer.driver.to_sym == HEADLESS_FIREFOX
153
198
  end
154
199
 
155
200
  def selenium_grid_driver?
156
- Howitzer.driver.to_sym == :selenium_grid
201
+ Howitzer.driver.to_sym == SELENIUM_GRID
157
202
  end
158
203
 
159
204
  def prefix_name
@@ -174,7 +219,7 @@ module Howitzer
174
219
  end
175
220
 
176
221
  def update_sauce_job_status(json_data = {})
177
- host = "http://#{Howitzer.cloud_auth_login}:#{Howitzer.cloud_auth_pass}@saucelabs.com"
222
+ host = "https://#{Howitzer.cloud_auth_login}:#{Howitzer.cloud_auth_pass}@saucelabs.com"
178
223
  path = "/rest/v1/#{Howitzer.cloud_auth_login}/jobs/#{session_id}"
179
224
  url = "#{host}#{path}"
180
225
  ::RestClient.put url, json_data.to_json, content_type: :json, accept: :json
@@ -12,6 +12,7 @@ module Howitzer
12
12
 
13
13
  def self.adapter
14
14
  return @adapter if @adapter
15
+
15
16
  self.adapter = Howitzer.mail_adapter.to_sym
16
17
  @adapter
17
18
  end
@@ -78,8 +79,8 @@ module Howitzer
78
79
  def self.find_by_recipient(recipient, params = {})
79
80
  if defined?(subject_value).nil? || subject_value.nil?
80
81
  raise Howitzer::NoEmailSubjectError, "Please specify email subject. For example:\n" \
81
- "class SomeEmail < Howitzer::Email\n" \
82
- " subject ‘some subject text’\nend"
82
+ "class SomeEmail < Howitzer::Email\n" \
83
+ " subject ‘some subject text’\nend"
83
84
  end
84
85
  new(adapter.find(recipient, expand_subject(params), wait: wait_time_value))
85
86
  end
@@ -1,23 +1,24 @@
1
1
  # This module holds all custom howitzer exceptions
2
2
  module Howitzer
3
- CommunicationError = Class.new(StandardError) #:nodoc:
4
- ParseError = Class.new(StandardError) #:nodoc:
5
- InvalidApiKeyError = Class.new(StandardError) #:nodoc:
6
- BadElementParamsError = Class.new(StandardError) #:nodoc:
7
- NoValidationError = Class.new(StandardError) #:nodoc:
8
- UnknownValidationError = Class.new(StandardError) #:nodoc:
9
- EmailNotFoundError = Class.new(StandardError) #:nodoc:
10
- NoAttachmentsError = Class.new(StandardError) #:nodoc:
11
- DriverNotSpecifiedError = Class.new(StandardError) #:nodoc:
12
- UnknownDriverError = Class.new(StandardError) #:nodoc:
13
- CloudBrowserNotSpecifiedError = Class.new(StandardError) #:nodoc:
14
- SelBrowserNotSpecifiedError = Class.new(StandardError) #:nodoc:
15
- UnknownBrowserError = Class.new(StandardError) #:nodoc:
16
- IncorrectPageError = Class.new(StandardError) #:nodoc:
17
- AmbiguousPageMatchingError = Class.new(StandardError) #:nodoc:
18
- NoMailAdapterError = Class.new(StandardError) #:nodoc:
19
- NoPathForPageError = Class.new(StandardError) #:nodoc:
20
- NoEmailSubjectError = Class.new(StandardError) #:nodoc:
21
- NoDataError = Class.new(StandardError) #:nodoc:
22
- UndefinedElementError = Class.new(StandardError) #:nodoc:
3
+ CommunicationError = Class.new(StandardError) # :nodoc:
4
+ ParseError = Class.new(StandardError) # :nodoc:
5
+ InvalidApiKeyError = Class.new(StandardError) # :nodoc:
6
+ BadElementParamsError = Class.new(StandardError) # :nodoc:
7
+ NoValidationError = Class.new(StandardError) # :nodoc:
8
+ UnknownValidationError = Class.new(StandardError) # :nodoc:
9
+ EmailNotFoundError = Class.new(StandardError) # :nodoc:
10
+ NoAttachmentsError = Class.new(StandardError) # :nodoc:
11
+ DriverNotSpecifiedError = Class.new(StandardError) # :nodoc:
12
+ UnknownDriverError = Class.new(StandardError) # :nodoc:
13
+ CloudBrowserNotSpecifiedError = Class.new(StandardError) # :nodoc:
14
+ SelBrowserNotSpecifiedError = Class.new(StandardError) # :nodoc:
15
+ UnknownBrowserError = Class.new(StandardError) # :nodoc:
16
+ IncorrectPageError = Class.new(StandardError) # :nodoc:
17
+ AmbiguousPageMatchingError = Class.new(StandardError) # :nodoc:
18
+ NoMailAdapterError = Class.new(StandardError) # :nodoc:
19
+ NoPathForPageError = Class.new(StandardError) # :nodoc:
20
+ NoEmailSubjectError = Class.new(StandardError) # :nodoc:
21
+ NoDataError = Class.new(StandardError) # :nodoc:
22
+ UndefinedElementError = Class.new(StandardError) # :nodoc:
23
+ UndefinedSexySettingError = Class.new(StandardError) # :nodoc:
23
24
  end
@@ -0,0 +1,31 @@
1
+ module Howitzer
2
+ module GmailApi
3
+ # A GmailApi::Client object is used to communicate with the Gmail API.
4
+ class Client
5
+ def self.load_gmail_gem!
6
+ require 'gmail'
7
+ rescue LoadError
8
+ raise LoadError, "Unable to load `gmail` library, please add following code to your Gemfile:\n\ngem 'gmail'"
9
+ end
10
+ load_gmail_gem!
11
+
12
+ def initialize
13
+ self.client = Gmail.connect(Howitzer.gmail_login, Howitzer.gmail_password)
14
+ end
15
+
16
+ # Finds message according to given parameters
17
+ #
18
+ # @param recipient [String] this is recipient mail address for message filtering
19
+ # @param subject [String] this is subject of the message to filter particular message
20
+ # @return [Gmail::Message] gmail message object
21
+
22
+ def find_message(recipient, subject)
23
+ client.inbox.emails(to: recipient, subject: subject).last
24
+ end
25
+
26
+ private
27
+
28
+ attr_accessor :client
29
+ end
30
+ end
31
+ end
@@ -0,0 +1,7 @@
1
+ module Howitzer
2
+ # This module holds simple implementation of gmail api client
3
+ module GmailApi
4
+ end
5
+ end
6
+
7
+ require 'howitzer/gmail_api/client'
data/lib/howitzer/log.rb CHANGED
@@ -80,13 +80,13 @@ module Howitzer
80
80
  Logger['ruby_log'].trace = true
81
81
  end
82
82
 
83
- #:nocov:
83
+ # :nocov:
84
84
  def log_without_formatting
85
85
  self.base_formatter = blank_formatter
86
86
  yield
87
87
  self.base_formatter = default_formatter
88
88
  end
89
- #:nocov:
89
+ # :nocov:
90
90
 
91
91
  def console_log
92
92
  StdoutOutputter.new(:console).tap { |o| o.only_at(INFO, DEBUG, WARN) }
@@ -96,13 +96,13 @@ module Howitzer
96
96
  StderrOutputter.new(:error, 'level' => ERROR)
97
97
  end
98
98
 
99
- #:nocov:
99
+ # :nocov:
100
100
  def blank_formatter
101
101
  PatternFormatter.new(pattern: '%m')
102
102
  end
103
- #:nocov:
103
+ # :nocov:
104
104
 
105
- #:nocov:
105
+ # :nocov:
106
106
  def default_formatter
107
107
  params = if Howitzer.hide_datetime_from_log
108
108
  { pattern: '[%l] %m' }
@@ -111,7 +111,7 @@ module Howitzer
111
111
  end
112
112
  PatternFormatter.new(params)
113
113
  end
114
- #:nocov:
114
+ # :nocov:
115
115
 
116
116
  def base_formatter=(formatter)
117
117
  @logger.outputters.each { |outputter| outputter.formatter = formatter }