howitzer 2.0.3 → 2.1.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.
- checksums.yaml +4 -4
- data/.rubocop.yml +8 -2
- data/.travis.yml +3 -3
- data/CHANGELOG.md +27 -11
- data/Gemfile +1 -0
- data/ISSUE_TEMPLATE.md +16 -0
- data/README.md +2 -1
- data/Rakefile +18 -2
- data/bin/howitzer +7 -6
- data/features/cli_help.feature +1 -1
- data/features/cli_new.feature +51 -11
- data/features/cli_update.feature +44 -4
- data/features/cli_version.feature +1 -1
- data/features/step_definitions/common_steps.rb +5 -0
- data/generators/base_generator.rb +30 -16
- data/generators/config/config_generator.rb +13 -3
- data/generators/config/templates/boot.rb +1 -1
- data/generators/config/templates/capybara.rb +2 -128
- data/generators/config/templates/default.yml +20 -3
- data/generators/config/templates/drivers/browserstack.rb +19 -0
- data/generators/config/templates/drivers/crossbrowsertesting.rb +25 -0
- data/generators/config/templates/drivers/headless_chrome.rb +16 -0
- data/generators/config/templates/drivers/phantomjs.rb +20 -0
- data/generators/config/templates/drivers/poltergeist.rb +11 -0
- data/generators/config/templates/drivers/sauce.rb +21 -0
- data/generators/config/templates/drivers/selenium.rb +24 -0
- data/generators/config/templates/drivers/selenium_grid.rb +27 -0
- data/generators/config/templates/drivers/testingbot.rb +20 -0
- data/generators/config/templates/drivers/webkit.rb +6 -0
- data/generators/cucumber/cucumber_generator.rb +2 -2
- data/generators/cucumber/templates/cucumber.rake +0 -8
- data/generators/cucumber/templates/env.rb +1 -1
- data/generators/cucumber/templates/transformers.rb +11 -25
- data/generators/emails/emails_generator.rb +2 -2
- data/generators/emails/templates/example_email.rb +1 -1
- data/generators/prerequisites/prerequisites_generator.rb +3 -3
- data/generators/prerequisites/templates/base.rb +1 -1
- data/generators/prerequisites/templates/{factory_girl.rb → factory_bot.rb} +6 -6
- data/generators/prerequisites/templates/users.rb +1 -1
- data/generators/root/root_generator.rb +2 -2
- data/generators/root/templates/.rubocop.yml +2 -2
- data/generators/root/templates/Gemfile.erb +14 -18
- data/generators/rspec/rspec_generator.rb +2 -2
- data/generators/rspec/templates/spec_helper.rb +1 -1
- data/generators/tasks/tasks_generator.rb +2 -2
- data/generators/turnip/templates/spec_helper.rb +1 -1
- data/generators/turnip/turnip_generator.rb +2 -2
- data/generators/web/web_generator.rb +2 -2
- data/howitzer.gemspec +3 -1
- data/lib/howitzer/capybara_helpers.rb +25 -8
- data/lib/howitzer/gmail_api.rb +7 -0
- data/lib/howitzer/gmail_api/client.rb +22 -0
- data/lib/howitzer/mail_adapters/gmail.rb +93 -0
- data/lib/howitzer/mail_adapters/mailgun.rb +2 -2
- data/lib/howitzer/mail_adapters/mailtrap.rb +105 -0
- data/lib/howitzer/mailtrap_api.rb +7 -0
- data/lib/howitzer/mailtrap_api/client.rb +52 -0
- data/lib/howitzer/version.rb +1 -1
- data/lib/howitzer/web/page.rb +13 -1
- data/lib/howitzer/web/page_dsl.rb +1 -1
- data/spec/config/custom.yml +1 -1
- data/spec/spec_helper.rb +1 -0
- data/spec/unit/generators/base_generator_spec.rb +23 -12
- data/spec/unit/generators/config_generator_spec.rb +27 -6
- data/spec/unit/generators/cucumber_generator_spec.rb +8 -8
- data/spec/unit/generators/emails_generator_spec.rb +2 -2
- data/spec/unit/generators/prerequisites_generator_spec.rb +7 -7
- data/spec/unit/generators/root_generator_spec.rb +25 -22
- data/spec/unit/generators/rspec_generator_spec.rb +4 -4
- data/spec/unit/generators/tasks_generator_spec.rb +2 -2
- data/spec/unit/generators/turnip_generator_spec.rb +7 -7
- data/spec/unit/generators/web_generator_spec.rb +3 -3
- data/spec/unit/lib/capybara_helpers_spec.rb +2 -1
- data/spec/unit/lib/gmail_api/client_spec.rb +26 -0
- data/spec/unit/lib/mail_adapters/gmail_spec.rb +128 -0
- data/spec/unit/lib/mail_adapters/mailgun_spec.rb +13 -18
- data/spec/unit/lib/mail_adapters/mailtrap_spec.rb +130 -0
- data/spec/unit/lib/mailgun_api/client_spec.rb +31 -9
- data/spec/unit/lib/mailtrap_api/client_spec.rb +67 -0
- data/spec/unit/lib/web/page_spec.rb +30 -1
- metadata +63 -8
- data/features/support/transformers.rb +0 -3
- data/spec/support/mailgun_unit_client.rb +0 -68
@@ -0,0 +1,11 @@
|
|
1
|
+
# :poltergeist driver
|
2
|
+
|
3
|
+
CapybaraHelpers.load_driver_gem!(:poltergeist, 'capybara/poltergeist', 'poltergeist')
|
4
|
+
|
5
|
+
Capybara.register_driver :poltergeist do |app|
|
6
|
+
Capybara::Poltergeist::Driver.new(
|
7
|
+
app,
|
8
|
+
js_errors: !Howitzer.phantom_ignore_js_errors,
|
9
|
+
phantomjs_options: ["--ignore-ssl-errors=#{Howitzer.phantom_ignore_ssl_errors ? 'yes' : 'no'}"]
|
10
|
+
)
|
11
|
+
end
|
@@ -0,0 +1,21 @@
|
|
1
|
+
# :sauce driver
|
2
|
+
|
3
|
+
Capybara.register_driver :sauce do |app|
|
4
|
+
caps = CapybaraHelpers.required_cloud_caps.merge(
|
5
|
+
maxDuration: Howitzer.cloud_max_duration,
|
6
|
+
idleTimeout: Howitzer.cloud_sauce_idle_timeout,
|
7
|
+
recordScreenshots: Howitzer.cloud_sauce_record_screenshots,
|
8
|
+
videoUploadOnPass: Howitzer.cloud_sauce_video_upload_on_pass
|
9
|
+
)
|
10
|
+
if Howitzer.user_agent.present?
|
11
|
+
if CapybaraHelpers.chrome_browser?
|
12
|
+
caps['chromeOptions'] = { 'args' => ["--user-agent=#{Howitzer.user_agent}"] }
|
13
|
+
elsif CapybaraHelpers.ff_browser?
|
14
|
+
profile = Selenium::WebDriver::Firefox::Profile.new
|
15
|
+
profile['general.useragent.override'] = Howitzer.user_agent
|
16
|
+
caps[:firefox_profile] = profile
|
17
|
+
end
|
18
|
+
end
|
19
|
+
url = "http://#{Howitzer.cloud_auth_login}:#{Howitzer.cloud_auth_pass}@ondemand.saucelabs.com:80/wd/hub"
|
20
|
+
CapybaraHelpers.cloud_driver(app, caps, url)
|
21
|
+
end
|
@@ -0,0 +1,24 @@
|
|
1
|
+
# :selenium driver
|
2
|
+
|
3
|
+
Capybara.register_driver :selenium do |app|
|
4
|
+
params = { browser: Howitzer.selenium_browser.to_s.to_sym }
|
5
|
+
if CapybaraHelpers.ff_browser?
|
6
|
+
ff_profile = Selenium::WebDriver::Firefox::Profile.new.tap do |profile|
|
7
|
+
profile['network.http.phishy-userpass-length'] = 255
|
8
|
+
profile['browser.safebrowsing.malware.enabled'] = false
|
9
|
+
profile['network.automatic-ntlm-auth.allow-non-fqdn'] = true
|
10
|
+
profile['network.ntlm.send-lm-response'] = true
|
11
|
+
profile['network.automatic-ntlm-auth.trusted-uris'] = Howitzer.app_host
|
12
|
+
profile['general.useragent.override'] = Howitzer.user_agent if Howitzer.user_agent.present?
|
13
|
+
end
|
14
|
+
options = Selenium::WebDriver::Firefox::Options.new(profile: ff_profile)
|
15
|
+
params[:options] = options
|
16
|
+
end
|
17
|
+
if CapybaraHelpers.chrome_browser?
|
18
|
+
args = []
|
19
|
+
args << 'start-fullscreen' if Howitzer.maximized_window
|
20
|
+
args << "user-agent=#{Howitzer.user_agent}" if Howitzer.user_agent.present?
|
21
|
+
params[:options] = Selenium::WebDriver::Chrome::Options.new(args: args)
|
22
|
+
end
|
23
|
+
Capybara::Selenium::Driver.new app, params
|
24
|
+
end
|
@@ -0,0 +1,27 @@
|
|
1
|
+
# :selenium_grid driver
|
2
|
+
|
3
|
+
Capybara.register_driver :selenium_grid do |app|
|
4
|
+
caps = if CapybaraHelpers.ie_browser?
|
5
|
+
Selenium::WebDriver::Remote::Capabilities.internet_explorer
|
6
|
+
elsif CapybaraHelpers.ff_browser?
|
7
|
+
Selenium::WebDriver::Remote::Capabilities.firefox
|
8
|
+
elsif CapybaraHelpers.chrome_browser?
|
9
|
+
Selenium::WebDriver::Remote::Capabilities.chrome
|
10
|
+
elsif CapybaraHelpers.safari_browser?
|
11
|
+
Selenium::WebDriver::Remote::Capabilities.safari
|
12
|
+
else
|
13
|
+
raise Howitzer::UnknownBrowserError, "Unknown '#{Howitzer.selenium_browser}' selenium_browser." \
|
14
|
+
' Check your settings, it should be one of' \
|
15
|
+
' [:ie, :iexplore, :ff, :firefox, :chrome, :safari]'
|
16
|
+
end
|
17
|
+
if Howitzer.user_agent.present?
|
18
|
+
if CapybaraHelpers.chrome_browser?
|
19
|
+
caps['chromeOptions'] = { 'args' => ["--user-agent=#{Howitzer.user_agent}"] }
|
20
|
+
elsif CapybaraHelpers.ff_browser?
|
21
|
+
profile = Selenium::WebDriver::Firefox::Profile.new
|
22
|
+
profile['general.useragent.override'] = Howitzer.user_agent
|
23
|
+
caps[:firefox_profile] = profile
|
24
|
+
end
|
25
|
+
end
|
26
|
+
Capybara::Selenium::Driver.new(app, browser: :remote, url: Howitzer.selenium_hub_url, desired_capabilities: caps)
|
27
|
+
end
|
@@ -0,0 +1,20 @@
|
|
1
|
+
# :testingbot driver
|
2
|
+
|
3
|
+
Capybara.register_driver :testingbot do |app|
|
4
|
+
caps = CapybaraHelpers.required_cloud_caps.merge(
|
5
|
+
maxduration: Howitzer.cloud_max_duration,
|
6
|
+
idletimeout: Howitzer.cloud_testingbot_idle_timeout,
|
7
|
+
screenshot: Howitzer.cloud_testingbot_screenshots
|
8
|
+
)
|
9
|
+
if Howitzer.user_agent.present?
|
10
|
+
if CapybaraHelpers.chrome_browser?
|
11
|
+
caps['chromeOptions'] = { 'args' => ["--user-agent=#{Howitzer.user_agent}"] }
|
12
|
+
elsif CapybaraHelpers.ff_browser?
|
13
|
+
profile = Selenium::WebDriver::Firefox::Profile.new
|
14
|
+
profile['general.useragent.override'] = Howitzer.user_agent
|
15
|
+
caps[:firefox_profile] = profile
|
16
|
+
end
|
17
|
+
end
|
18
|
+
url = "http://#{Howitzer.cloud_auth_login}:#{Howitzer.cloud_auth_pass}@hub.testingbot.com/wd/hub"
|
19
|
+
CapybaraHelpers.cloud_driver(app, caps, url)
|
20
|
+
end
|
@@ -14,51 +14,43 @@ end
|
|
14
14
|
|
15
15
|
Cucumber::Rake::Task.new(:cucumber, 'Run all cucumber scenarios') do |t|
|
16
16
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
17
|
-
t.fork = false
|
18
17
|
t.cucumber_opts = opts.call(t.instance_variable_get(:@task_name))
|
19
18
|
end
|
20
19
|
|
21
20
|
Cucumber::Rake::Task.new(:features, 'Run all workable scenarios (without @wip and @bug tags)') do |t|
|
22
21
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
23
|
-
t.fork = false
|
24
22
|
t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags ~@wip --tags ~@bug"
|
25
23
|
end
|
26
24
|
|
27
25
|
namespace :features do
|
28
26
|
Cucumber::Rake::Task.new(:wip, 'Run scenarios in progress (with @wip tag)') do |t|
|
29
27
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
30
|
-
t.fork = false
|
31
28
|
t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags @wip"
|
32
29
|
end
|
33
30
|
|
34
31
|
Cucumber::Rake::Task.new(:bug, 'Run scenarios with known bugs (with @bug tag)') do |t|
|
35
32
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
36
|
-
t.fork = false
|
37
33
|
t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags @bug"
|
38
34
|
end
|
39
35
|
|
40
36
|
Cucumber::Rake::Task.new(:smoke, 'Run workable smoke scenarios (with @smoke tag)') do |t|
|
41
37
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
42
|
-
t.fork = false
|
43
38
|
t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags @smoke --tags ~@wip --tags ~@bug"
|
44
39
|
end
|
45
40
|
|
46
41
|
Cucumber::Rake::Task.new(:bvt, 'Run workable build verification test scenarios') do |t|
|
47
42
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
48
|
-
t.fork = false
|
49
43
|
t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))}
|
50
44
|
--tags ~@wip --tags ~@bug --tags ~@smoke --tags ~@p1 --tags ~@p2"
|
51
45
|
end
|
52
46
|
|
53
47
|
Cucumber::Rake::Task.new(:p1, 'Run workable scenarios with normal priority (with @p1 tag)') do |t|
|
54
48
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
55
|
-
t.fork = false
|
56
49
|
t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags ~@wip --tags ~@bug --tags @p1"
|
57
50
|
end
|
58
51
|
|
59
52
|
Cucumber::Rake::Task.new(:p2, 'Run workable scenarios with low priority (with @p2 tag)') do |t|
|
60
53
|
Howitzer.current_rake_task = t.instance_variable_get :@task_name
|
61
|
-
t.fork = false
|
62
54
|
t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags ~@wip --tags ~@bug --tags @p2"
|
63
55
|
end
|
64
56
|
end
|
@@ -10,29 +10,15 @@
|
|
10
10
|
# @example
|
11
11
|
# 'When I fill first name field with FACTORY_USER1[:first_name] value'
|
12
12
|
# #=> build(:user).first_name
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
22
|
-
|
23
|
-
# | FACTORY_USER1[:name] | FACTORY_USER1[:email] |
|
24
|
-
# #=> build(:user).name and build(:user).email
|
25
|
-
Transform /^table:.*$/ do |table|
|
26
|
-
raw = table.raw.map do |array|
|
27
|
-
array.map do |el|
|
28
|
-
data = /FACTORY_(?<factory>[a-z_]+)(?<num>\d*)(?:\[\:(?<property>.+)\])?/i.match(el)
|
29
|
-
next(el) unless data
|
30
|
-
res = FactoryGirl.given_by_number(data[:factory].downcase, data[:num])
|
31
|
-
next(res) if data[:property].blank?
|
32
|
-
res.send(data[:property])
|
33
|
-
end
|
13
|
+
# When 'I fill first name field with {factory} value' do |name|
|
14
|
+
# ...
|
15
|
+
# end
|
16
|
+
ParameterType(
|
17
|
+
name: 'factory',
|
18
|
+
regexp: /(?:factory|FACTORY)_([A-Za-z_]+)(\d*)(?:\[\:(.+)\])?/,
|
19
|
+
transformer: lambda do |_, factory, num, property|
|
20
|
+
res = FactoryGirl.given_by_number(factory.downcase, num)
|
21
|
+
res = res.send(property) if property
|
22
|
+
res
|
34
23
|
end
|
35
|
-
|
36
|
-
ast_table = Cucumber::Core::Ast::DataTable.new(raw, location)
|
37
|
-
Cucumber::MultilineArgument::DataTable.new(ast_table)
|
38
|
-
end
|
24
|
+
)
|
@@ -6,7 +6,7 @@ module Howitzer
|
|
6
6
|
def manifest
|
7
7
|
{ files:
|
8
8
|
[
|
9
|
-
{ source: '
|
9
|
+
{ source: 'factory_bot.rb', destination: 'prerequisites/factory_bot.rb' },
|
10
10
|
{ source: 'users.rb', destination: 'prerequisites/factories/users.rb' },
|
11
11
|
{ source: 'base.rb', destination: 'prerequisites/models/base.rb' },
|
12
12
|
{ source: 'user.rb', destination: 'prerequisites/models/user.rb' }
|
@@ -16,9 +16,9 @@ module Howitzer
|
|
16
16
|
protected
|
17
17
|
|
18
18
|
def banner
|
19
|
-
<<-
|
19
|
+
<<-MSG
|
20
20
|
* Pre-requisites integration to the framework ...
|
21
|
-
|
21
|
+
MSG
|
22
22
|
end
|
23
23
|
end
|
24
24
|
end
|
@@ -1,11 +1,11 @@
|
|
1
|
-
# @see http://www.rubydoc.info/gems/
|
2
|
-
require '
|
1
|
+
# @see http://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md
|
2
|
+
require 'factory_bot'
|
3
3
|
|
4
|
-
|
5
|
-
|
4
|
+
FactoryBot.definition_file_paths = [File.join(__dir__, 'factories')]
|
5
|
+
FactoryBot.find_definitions
|
6
6
|
|
7
|
-
# This module holds custom
|
8
|
-
module
|
7
|
+
# This module holds custom FactoryBot methods
|
8
|
+
module FactoryBot
|
9
9
|
# Fetches data from the cache, using factory name and number.
|
10
10
|
# If there is data in the cache with the given name and number,
|
11
11
|
# then that data is returned. Otherwise it stores firstly and then returns
|
@@ -10,7 +10,7 @@ AllCops:
|
|
10
10
|
LineLength:
|
11
11
|
Max: 120
|
12
12
|
|
13
|
-
|
13
|
+
Layout/CaseIndentation:
|
14
14
|
Enabled: false
|
15
15
|
|
16
16
|
Style/EmptyElse:
|
@@ -20,7 +20,7 @@ Lint/AmbiguousRegexpLiteral:
|
|
20
20
|
Enabled: false
|
21
21
|
|
22
22
|
Lint/AmbiguousBlockAssociation:
|
23
|
-
Enabled: false
|
23
|
+
Enabled: false
|
24
24
|
|
25
25
|
Style/CaseEquality:
|
26
26
|
Enabled: false
|
@@ -1,28 +1,24 @@
|
|
1
1
|
source 'https://rubygems.org'
|
2
2
|
|
3
|
+
gem 'capybara-screenshot'
|
4
|
+
<%= "gem 'cucumber', '~>3.0'\n" if cucumber -%>
|
5
|
+
<%= "gem 'cuke_sniffer', require: false\n" if cucumber -%>
|
6
|
+
gem 'factory_bot'
|
7
|
+
gem 'howitzer'
|
8
|
+
gem 'pry'
|
9
|
+
gem 'pry-byebug'
|
10
|
+
gem 'repeater'
|
11
|
+
gem 'rest-client'
|
12
|
+
<%= "gem 'rspec', '~>3.2'\n" if rspec || turnip -%>
|
13
|
+
gem 'rubocop'
|
14
|
+
<%= "gem 'turnip'\n" if turnip -%>
|
15
|
+
<%= "gem 'syntax'\n" if cucumber -%>
|
16
|
+
|
3
17
|
# Uncomment it if you are going to use 'webkit' driver. QT library should be installed.
|
4
18
|
# See https://github.com/thoughtbot/capybara-webkit/wiki/Installing-Qt-and-compiling-capybara-webkit
|
5
19
|
#
|
6
20
|
# gem 'capybara-webkit'
|
7
21
|
|
8
|
-
gem 'howitzer'
|
9
22
|
# Uncomment it if you are going to use 'poltergeist' driver. PhantomJS should be installed.
|
10
23
|
# See https://github.com/jnicklas/capybara#poltergeist
|
11
24
|
# gem 'poltergeist', git: 'https://github.com/teampoltergeist/poltergeist.git', branch: :master
|
12
|
-
gem 'rest-client'
|
13
|
-
gem 'repeater'
|
14
|
-
gem 'factory_girl'
|
15
|
-
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'
|
27
|
-
gem 'pry'
|
28
|
-
gem 'pry-byebug'
|
@@ -10,7 +10,7 @@ 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
|
13
|
+
config.include FactoryBot::Syntax::Methods
|
14
14
|
|
15
15
|
config.disable_monkey_patching!
|
16
16
|
config.color = true
|
@@ -9,7 +9,7 @@ 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
|
12
|
+
config.include FactoryBot::Syntax::Methods
|
13
13
|
|
14
14
|
config.disable_monkey_patching!
|
15
15
|
config.color = true
|