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
@@ -17,29 +17,34 @@
17
17
  ###########################################################
18
18
  # TEST ENVIRONMENTS SETTINGS #
19
19
  ###########################################################
20
+ user_agent: # if blank, then default agent
20
21
  page_load_idle_timeout: 20
21
22
  maximized_window: true # Specify maximized browser window size
22
23
 
23
- # Specify one of the following drivers: selenium, selenium_grid, webkit, poltergeist, phantomjs, sauce,
24
- # testingbot, browserstack, headless_chrome
25
- driver: phantomjs
24
+ # Run scenarios in the order they were 'defined' (default).
25
+ # 'random' - shuffle scenarios before running.
26
+ # Specify SEED to reproduce the shuffling from a previous run. e.g. 'random:5738'
27
+ test_order: defined
28
+
29
+ # Specify one of the following drivers: selenium, selenium_grid, sauce,
30
+ # testingbot, browserstack, crossbrowsertesting, headless_chrome, headless_firefox, appium
31
+ driver: headless_chrome
26
32
 
27
33
  # -Selenium-
28
34
  # specify one of next browsers: iexplore (ie), firefox (ff), chrome, safari
29
35
  selenium_browser: ff
30
36
 
31
37
  # -Headless Chrome-
32
- # List of available flags (http://peter.sh/experiments/chromium-command-line-switches/)
33
- headless_chrome_flags: "--window-size=1920x1080, --disable-gpu"
38
+ # List of available flags (https://peter.sh/experiments/chromium-command-line-switches/)
39
+ headless_chrome_flags: "window-size=1920x1080, disable-gpu"
40
+
41
+ # -Headless Firefox-
42
+ # For use custom screen size "maximized_window" should be false
43
+ headless_firefox_flags: "-height=1920, -width=1080"
34
44
 
35
45
  # -Selenium Grid-
36
46
  selenium_hub_url: "http://example.com:4444/wd/hub"
37
47
 
38
- # -PhantomJS/Poltergeist-
39
- # specify settings for poltergeist
40
- phantom_ignore_js_errors: false
41
- phantom_ignore_ssl_errors: true
42
-
43
48
  rspec_wait_timeout: 10
44
49
 
45
50
  ###########################################################
@@ -49,7 +54,7 @@
49
54
  cloud_auth_pass: api_key_or_api_secret_or_access_key
50
55
  cloud_platform: any
51
56
  cloud_browser_name: Chrome
52
- cloud_browser_version: '31'
57
+ cloud_browser_version: 'latest'
53
58
  cloud_max_duration: '1800'
54
59
  cloud_http_idle_timeout: 40
55
60
 
@@ -68,6 +73,14 @@
68
73
  cloud_bstack_build: 'v1'
69
74
  cloud_bstack_mobile_device:
70
75
 
76
+ # -CrossBrowserTesting (https://app.crossbrowsertesting.com/selenium/run)
77
+ cloud_cbt_name: 'Howitzer Example'
78
+ cloud_cbt_build: '1.0'
79
+ cloud_cbt_os_api_name: 'Win7x64-C1'
80
+ cloud_cbt_screen_resolution: '1024x768'
81
+ cloud_cbt_record_video: 'true'
82
+ cloud_cbt_record_network: 'true'
83
+
71
84
  ###########################################################
72
85
  # CAPYBARA SETTINGS #
73
86
  ###########################################################
@@ -88,8 +101,16 @@
88
101
  ###########################################################
89
102
  mail_adapter: mailgun
90
103
  mail_wait_time: 60
104
+ mail_sleep_time: 3
91
105
 
92
- # -Mailgun- (http://www.mailgun.com/)
106
+ # -Mailgun- (https://mailgun.com/)
93
107
  mailgun_key: mailgun_account_private_key
94
108
  mailgun_domain: mailgun_domain_with_stored_method
95
- mailgun_sleep_time: 3
109
+
110
+ # -Mailtrap- (https://mailtrap.io/)
111
+ mailtrap_api_token: private_api_key
112
+ mailtrap_inbox_id: inbox_id
113
+
114
+ # -Gmail-
115
+ gmail_login: gmail_address
116
+ gmail_password: gmail_password
@@ -0,0 +1,25 @@
1
+ CapybaraHelpers.load_driver_gem!(:appium, 'appium_capybara', 'appium_capybara')
2
+
3
+ Capybara.register_driver(:appium) do |app|
4
+ caps = {}
5
+ caps['deviceName'] = Howitzer.appium_device_name
6
+ caps['deviceOrientation'] = Howitzer.appium_device_orientation
7
+ caps['platformVersion'] = Howitzer.appium_platform_version
8
+ caps['platformName'] = Howitzer.appium_platform_name
9
+ caps['browserName'] = Howitzer.appium_browser_name
10
+
11
+ url = Howitzer.appium_url
12
+
13
+ appium_lib_options = {
14
+ server_url: url
15
+ }
16
+ all_options = {
17
+ appium_lib: appium_lib_options,
18
+ caps: caps
19
+ }
20
+ Appium::Capybara::Driver.new app, all_options
21
+ end
22
+
23
+ Capybara::Screenshot.class_eval do
24
+ register_driver :appium, &registered_drivers[:selenium]
25
+ end
@@ -0,0 +1,23 @@
1
+ Capybara.register_driver :browserstack do |app|
2
+ caps = CapybaraHelpers.required_cloud_caps.merge(
3
+ project: Howitzer.cloud_bstack_project,
4
+ build: Howitzer.cloud_bstack_build
5
+ )
6
+ caps[:resolution] = Howitzer.cloud_bstack_resolution if Howitzer.cloud_bstack_resolution.present?
7
+ caps[:device] = Howitzer.cloud_bstack_mobile_device if Howitzer.cloud_bstack_mobile_device.present?
8
+ if Howitzer.user_agent.present?
9
+ if CapybaraHelpers.chrome_browser?
10
+ caps['chromeOptions'] = { 'args' => ["--user-agent=#{Howitzer.user_agent}"] }
11
+ elsif CapybaraHelpers.ff_browser?
12
+ profile = Selenium::WebDriver::Firefox::Profile.new
13
+ profile['general.useragent.override'] = Howitzer.user_agent
14
+ caps[:firefox_profile] = profile
15
+ end
16
+ end
17
+ url = "https://#{Howitzer.cloud_auth_login}:#{Howitzer.cloud_auth_pass}@hub.browserstack.com/wd/hub"
18
+ CapybaraHelpers.cloud_driver(app, caps, url)
19
+ end
20
+
21
+ Capybara::Screenshot.class_eval do
22
+ register_driver :browserstack, &registered_drivers[:selenium]
23
+ end
@@ -0,0 +1,29 @@
1
+ # :crossbrowsertesting driver
2
+
3
+ Capybara.register_driver :crossbrowsertesting do |app|
4
+ caps = {}
5
+ caps['name'] = Howitzer.cloud_cbt_name
6
+ caps['build'] = Howitzer.cloud_cbt_build
7
+ caps['browser_api_name'] = Howitzer.cloud_browser_name + Howitzer.cloud_browser_version.to_s
8
+ caps['os_api_name'] = Howitzer.cloud_cbt_os_api_name
9
+ caps['screen_resolution'] = Howitzer.cloud_cbt_screen_resolution
10
+ caps['record_video'] = Howitzer.cloud_cbt_record_video
11
+ caps['record_network'] = Howitzer.cloud_cbt_record_network
12
+ caps['max_duration'] = Howitzer.cloud_max_duration
13
+ if Howitzer.user_agent.present?
14
+ if CapybaraHelpers.chrome_browser?
15
+ caps['chromeOptions'] = { 'args' => ["--user-agent=#{Howitzer.user_agent}"] }
16
+ elsif CapybaraHelpers.ff_browser?
17
+ profile = Selenium::WebDriver::Firefox::Profile.new
18
+ profile['general.useragent.override'] = Howitzer.user_agent
19
+ caps[:firefox_profile] = profile
20
+ end
21
+ end
22
+ url = "https://#{CGI.escape(Howitzer.cloud_auth_login)}:#{Howitzer.cloud_auth_pass}"\
23
+ '@hub.crossbrowsertesting.com/wd/hub'
24
+ CapybaraHelpers.cloud_driver(app, caps, url)
25
+ end
26
+
27
+ Capybara::Screenshot.class_eval do
28
+ register_driver :crossbrowsertesting, &registered_drivers[:selenium]
29
+ end
@@ -0,0 +1,15 @@
1
+ # :headless_chrome driver
2
+
3
+ Capybara.register_driver :headless_chrome do |app|
4
+ startup_flags = ['headless']
5
+ startup_flags << 'start-fullscreen' if Howitzer.maximized_window
6
+ startup_flags << "user-agent=#{Howitzer.user_agent}" if Howitzer.user_agent.present?
7
+ startup_flags.concat(Howitzer.headless_chrome_flags.split(/\s*,\s*/)) if Howitzer.headless_chrome_flags
8
+ options = Selenium::WebDriver::Chrome::Options.new(args: startup_flags)
9
+ params = { browser: :chrome, options: options }
10
+ Capybara::Selenium::Driver.new app, **params
11
+ end
12
+
13
+ Capybara::Screenshot.class_eval do
14
+ register_driver :headless_chrome, &registered_drivers[:selenium]
15
+ end
@@ -0,0 +1,23 @@
1
+ # :headless_firefox driver
2
+
3
+ Capybara.register_driver :headless_firefox do |app|
4
+ startup_flags = ['--headless']
5
+ startup_flags.concat(Howitzer.headless_firefox_flags.split(/\s*,\s*/)) if Howitzer.headless_firefox_flags
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(args: startup_flags, profile: ff_profile)
15
+ params = { browser: :firefox, options: options }
16
+ Capybara::Selenium::Driver.new app, **params
17
+ end
18
+
19
+ Capybara.javascript_driver = :headless_firefox
20
+
21
+ Capybara::Screenshot.class_eval do
22
+ register_driver :headless_firefox, &registered_drivers[:selenium]
23
+ end
@@ -0,0 +1,25 @@
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 = "https://#{Howitzer.cloud_auth_login}:#{Howitzer.cloud_auth_pass}@ondemand.saucelabs.com/wd/hub"
20
+ CapybaraHelpers.cloud_driver(app, caps, url)
21
+ end
22
+
23
+ Capybara::Screenshot.class_eval do
24
+ register_driver :sauce, &registered_drivers[:selenium]
25
+ 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,31 @@
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
28
+
29
+ Capybara::Screenshot.class_eval do
30
+ register_driver :selenium_grid, &registered_drivers[:selenium]
31
+ end
@@ -0,0 +1,24 @@
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 = "https://#{Howitzer.cloud_auth_login}:#{Howitzer.cloud_auth_pass}@hub.testingbot.com/wd/hub"
19
+ CapybaraHelpers.cloud_driver(app, caps, url)
20
+ end
21
+
22
+ Capybara::Screenshot.class_eval do
23
+ register_driver :testingbot, &registered_drivers[:selenium]
24
+ end
@@ -19,9 +19,9 @@ module Howitzer
19
19
  protected
20
20
 
21
21
  def banner
22
- <<-EOS
22
+ <<-MSG
23
23
  * Cucumber integration to the framework ...
24
- EOS
24
+ MSG
25
25
  end
26
26
  end
27
27
  end
@@ -2,7 +2,7 @@
2
2
  # PREREQUISITES #
3
3
  #############################################################
4
4
 
5
- Given /^I have entered (.*) into the calculator$/ do |_input|
5
+ Given 'I have entered {float} into the calculator' do |_input|
6
6
  pending
7
7
  end
8
8
 
@@ -10,7 +10,7 @@ end
10
10
  # ACTIONS #
11
11
  ####################################
12
12
 
13
- When /^I press (.*)$/ do |_button|
13
+ When 'I press {word}' do |_button|
14
14
  pending
15
15
  end
16
16
 
@@ -18,6 +18,6 @@ end
18
18
  # CHECKS #
19
19
  ####################################
20
20
 
21
- Then /^the result should be (.*) on the screen$/ do |_output|
21
+ Then 'the result should be {float} on the screen' do |_output|
22
22
  pending
23
23
  end
@@ -14,52 +14,44 @@ 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
- t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags ~@wip --tags ~@bug"
22
+ t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags 'not @wip and not @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
- t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags @smoke --tags ~@wip --tags ~@bug"
38
+ t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags '@smoke and not @wip and not @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
- --tags ~@wip --tags ~@bug --tags ~@smoke --tags ~@p1 --tags ~@p2"
44
+ --tags 'not @wip and not @bug and not @smoke and not @p1 and not @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
- t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags ~@wip --tags ~@bug --tags @p1"
49
+ t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags 'not @wip and not @bug and @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
- t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags ~@wip --tags ~@bug --tags @p2"
54
+ t.cucumber_opts = "#{opts.call(t.instance_variable_get(:@task_name))} --tags 'not @wip and not @bug and @p2'"
63
55
  end
64
56
  end
65
57
 
@@ -1,11 +1,11 @@
1
1
  require 'cuke_sniffer'
2
2
 
3
3
  def path_to_features
4
- @_path_to_features ||= File.expand_path(File.join(__dir__, '..', 'features'))
4
+ @path_to_features ||= File.expand_path(File.join(__dir__, '..', 'features'))
5
5
  end
6
6
 
7
7
  def cuke_sniffer
8
- @_cuke_sniffer ||= CukeSniffer::CLI.new(
8
+ @cuke_sniffer ||= CukeSniffer::CLI.new(
9
9
  features_location: path_to_features,
10
10
  step_definitions_location: File.join(path_to_features, 'step_definitions'),
11
11
  hooks_location: File.join(path_to_features, 'support'),
@@ -2,7 +2,7 @@ require 'cucumber'
2
2
  require_relative '../../config/boot'
3
3
  require_relative '../../config/capybara'
4
4
 
5
- World(FactoryGirl::Syntax::Methods)
5
+ World(FactoryBot::Syntax::Methods)
6
6
  World(RSpec::Wait)
7
7
 
8
8
  RSpec.configure do |config|
@@ -10,6 +10,14 @@ RSpec.configure do |config|
10
10
  config.disable_monkey_patching!
11
11
  end
12
12
 
13
+ AfterConfiguration do |config|
14
+ if Howitzer.test_order.present?
15
+ order, seed = Howitzer.test_order.split(':')
16
+ config.instance_variable_get(:@options)[:order] = order
17
+ config.instance_variable_get(:@options)[:seed] ||= seed
18
+ end
19
+ end
20
+
13
21
  FileUtils.mkdir_p(Howitzer.log_dir)
14
22
 
15
23
  Howitzer::Log.settings_as_formatted_text
@@ -1,6 +1,12 @@
1
1
  Before do |scenario|
2
2
  Capybara.use_default_driver
3
- Howitzer::Log.print_feature_name(scenario.feature.name)
3
+ feature_name = \
4
+ if Gem::Requirement.new('>3').satisfied_by?(Gem::Version.new(Cucumber::VERSION))
5
+ File.read(scenario.location.file)[/Feature:\s(.+)/, 1]
6
+ else
7
+ scenario.feature.name
8
+ end
9
+ Howitzer::Log.print_feature_name(feature_name)
4
10
  Howitzer::Log.print_scenario_name(scenario.name)
5
11
  @session_start = CapybaraHelpers.duration(Time.now.utc - Howitzer::Cache.extract(:cloud, :start_time))
6
12
  end
@@ -10,7 +16,7 @@ After do |scenario|
10
16
  Howitzer::Cache.store(:cloud, :status, false) if scenario.failed?
11
17
  session_end = CapybaraHelpers.duration(Time.now.utc - Howitzer::Cache.extract(:cloud, :start_time))
12
18
  Howitzer::Log.info "CLOUD VIDEO #{@session_start} - #{session_end}" \
13
- " URL: #{CapybaraHelpers.cloud_resource_path(:video)}"
19
+ " URL: #{CapybaraHelpers.cloud_resource_path(:video)}"
14
20
  elsif CapybaraHelpers.ie_browser?
15
21
  Howitzer::Log.info 'IE reset session'
16
22
  Capybara.current_session.execute_script("void(document.execCommand('ClearAuthenticationCache', false));")
@@ -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
- Transform /FACTORY_([a-z_]+)(\d*)(?:\[\:(.+)\])?/i do |factory, num, property|
14
- res = FactoryGirl.given_by_number(factory.downcase, num)
15
- res = res.send(property) if property
16
- res
17
- end
18
-
19
- # Revives factories or factory properties from table to real values
20
- # @example
21
- # When I sign up with following data:
22
- # | name | email |
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 = FactoryBot.given_by_number(factory.downcase, num)
21
+ res = res.send(property) if property
22
+ res
34
23
  end
35
- location = Cucumber::Core::Ast::Location.of_caller
36
- ast_table = Cucumber::Core::Ast::DataTable.new(raw, location)
37
- Cucumber::MultilineArgument::DataTable.new(ast_table)
38
- end
24
+ )
@@ -10,9 +10,9 @@ module Howitzer
10
10
  protected
11
11
 
12
12
  def banner
13
- <<-EOS
13
+ <<-MSG
14
14
  * Email example generation ...
15
- EOS
15
+ MSG
16
16
  end
17
17
  end
18
18
  end
@@ -3,6 +3,6 @@ class TestEmail < Howitzer::Email
3
3
  subject 'Test email'
4
4
 
5
5
  def addressed_to?(new_user)
6
- plain_text_body =~ /Hi #{new_user}/ ? true : false
6
+ /Hi #{new_user}/ === plain_text_body
7
7
  end
8
8
  end
@@ -6,7 +6,7 @@ module Howitzer
6
6
  def manifest
7
7
  { files:
8
8
  [
9
- { source: 'factory_girl.rb', destination: 'prerequisites/factory_girl.rb' },
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
- <<-EOS
19
+ <<-MSG
20
20
  * Pre-requisites integration to the framework ...
21
- EOS
21
+ MSG
22
22
  end
23
23
  end
24
24
  end
@@ -1,6 +1,6 @@
1
1
  # The base model. Models allow to communicate with
2
2
  # AUT (application under test) api endpoints. They are used by
3
- # FactoryGirl on create
3
+ # FactoryBot on create
4
4
  #
5
5
  # To implement a custom model, override the following methods:
6
6
  # * {Base.find}
@@ -1,11 +1,11 @@
1
- # @see http://www.rubydoc.info/gems/factory_girl/file/GETTING_STARTED.md
2
- require 'factory_girl'
1
+ # @see https://www.rubydoc.info/gems/factory_bot/file/GETTING_STARTED.md
2
+ require 'factory_bot'
3
3
 
4
- FactoryGirl.definition_file_paths = [File.join(__dir__, 'factories')]
5
- FactoryGirl.find_definitions
4
+ FactoryBot.definition_file_paths = [File.join(__dir__, 'factories')]
5
+ FactoryBot.find_definitions
6
6
 
7
- # This module holds custom FactoryGirl methods
8
- module FactoryGirl
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
@@ -15,6 +15,7 @@ module FactoryGirl
15
15
  def self.given_by_number(factory, num)
16
16
  data = Howitzer::Cache.extract(factory, num.to_i)
17
17
  return data if data.present?
18
+
18
19
  Howitzer::Cache.store(factory, num.to_i, build(factory))
19
20
  end
20
21
  end
@@ -1,4 +1,4 @@
1
- FactoryGirl.define do
1
+ FactoryBot.define do
2
2
  factory :user do
3
3
  email { "u#{Gen.serial}@#{Howitzer.mailgun_domain}" }
4
4
  name { "FirstName LastName #{Gen.serial}" }
@@ -7,11 +7,11 @@ module Howitzer
7
7
  { files:
8
8
  [
9
9
  { source: '.gitignore', destination: '.gitignore' },
10
- { source: '.rubocop.yml', destination: '.rubocop.yml' },
11
10
  { source: 'Rakefile', destination: 'Rakefile' }
12
11
  ],
13
12
  templates:
14
13
  [
14
+ { source: '.rubocop.yml.erb', destination: '.rubocop.yml' },
15
15
  { source: 'Gemfile.erb', destination: 'Gemfile' }
16
16
  ] }
17
17
  end
@@ -19,9 +19,9 @@ module Howitzer
19
19
  protected
20
20
 
21
21
  def banner
22
- <<-EOF
22
+ <<-MSG
23
23
  * Root files generation ...
24
- EOF
24
+ MSG
25
25
  end
26
26
  end
27
27
  end