Last active
May 9, 2019 08:20
-
-
Save rosskevin/5937888 to your computer and use it in GitHub Desktop.
Continuous Integration, parallel_tests, cucumber, headless, capybara-webkit, chrome. For mac and linux.Conditionally @show chrome browser (:selenium) in development if @show tag is used, otherwise run headless and *always* run headless in a CI environment regardless of the tag's presence. Check javascript errors automatically when using webkit.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# verified against log_in.feature for blake | |
# https://github.com/jnicklas/capybara/issues/1443 | |
# turn on webkit driver debug | |
$use_webkit = true | |
$use_chrome_instead_of_firefox = false | |
$webkit_debug = false | |
$wait_time = 5 | |
def webkit_driver | |
if $webkit_debug | |
return :webkit_debug | |
else | |
return :webkit | |
end | |
end | |
def webkit? | |
[:webkit, :webkit_debug].include? Capybara.current_driver | |
end | |
def selenium? | |
Capybara.javascript_driver == :selenium | |
end | |
if $use_chrome_instead_of_firefox | |
# Register chrome browser for the :selenium driver, can be triggered below with the combination of @javascript @show | |
Capybara.register_driver :selenium do |app| | |
Capybara::Selenium::Driver.new(app, :browser => :chrome) | |
end | |
end | |
# try to get a unique port, important for parallels tests | |
# if ENV['TEST_ENV_NUMBER'] | |
test_env_number = ENV['TEST_ENV_NUMBER'] | |
test_env_number ||= 1 | |
test_port = 9887 + test_env_number.to_i | |
#test_port += 1 while is_port_open?(@port) and not is_running_on_port?(@port) | |
puts "Capybara::Server.port: #{test_port} for test process: #{test_env_number}" | |
Capybara.server_port = test_port | |
# end | |
if $headless_server.nil? | |
# Unnecessary on mac, see https://github.com/leonid-shevtsov/headless/issues/31#issuecomment-8933108 | |
if !OS.mac? | |
require 'headless' | |
# allow display autopick (by default) | |
# allow each headless to destroy_at_exit (by default) | |
# allow each process to have their own headless by setting reuse: false | |
# $headless_server = Headless.new(reuse: false) | |
$headless_server = Headless.new(reuse: true, destroy_at_exit: false) | |
$headless_server.start | |
puts "Process[#{Process.pid}] started headless server display: #{$headless_server.display}" | |
end | |
end | |
at_exit do | |
unless $headless_server.nil? | |
puts "Process[#{Process.pid}] destroying headless server on display: #{$headless_server.display}" | |
$headless_server.destroy | |
end | |
end | |
# first time around, we need this set. | |
if $use_webkit | |
Capybara.default_driver = webkit_driver | |
# Capybara.current_driver = webkit_driver | |
# Capybara.javascript_driver = webkit_driver | |
end | |
# | |
# If the @show tag is present on a non-mac environment, ignore it, | |
# otherwise allow the combination of @javascript @show to trigger the | |
# :selenium driver (which is :chrome browser as configured above) | |
# | |
Before do |scenario| | |
if $use_webkit | |
Capybara.current_driver = webkit_driver | |
Capybara.javascript_driver = webkit_driver | |
end | |
# problem on @show with backgrounds: https://github.com/cucumber/cucumber/issues/52 | |
if should_show(scenario) | |
# for some reason, just using the `using_driver` doesn't get us all the way there, so set/reset the `javascript_driver` as necessary. | |
Capybara.current_driver = :selenium | |
Capybara.javascript_driver = :selenium # needed for @show with chrome, as it doesn't seem to explicitly set the javascript driver | |
end | |
# puts "Using #{Capybara.current_driver}/#{Capybara.javascript_driver}/#{Capybara.default_driver}" | |
end | |
After do |scenario| | |
# problem on @show with backgrounds: https://github.com/cucumber/cucumber/issues/52 | |
# puts "Done #{Capybara.current_driver}/#{Capybara.javascript_driver}/#{Capybara.default_driver}" | |
Capybara.use_default_driver | |
end | |
def should_show(scenario) | |
OS.mac? && (has_tag(scenario, '@show') || has_tag(scenario, '@leave_browser_open') || has_tag(scenario, '@single_step')) | |
end | |
def has_tag(scenario, tag) | |
(scenario.source_tags.map do |tag| | |
tag.name | |
end).include? tag | |
end | |
# Increase wait time for ajax retries | |
Capybara.default_wait_time = $wait_time | |
Before do |scenario| | |
@scenario = scenario | |
# reset to wait time in case something in the scenario upped it as it was long running | |
Capybara.default_wait_time = $wait_time | |
end | |
# webkit javascript check only | |
AfterStep do | |
if webkit? | |
begin | |
#puts "All Javascript errors: #{page.driver.error_messages}" | |
# puts "All console messages: #{page.driver.console_messages}" | |
real_error_messages = page.driver.error_messages | |
#real_error_messages = [] | |
#page.driver.error_messages.each_with_index do |e, i| | |
# # first two messages appear to be bogus, always. | |
# if (e[:line_number] == 0) && (e[:source].eql? 'undefined') && (e[:message].eql? 'TypeError: \'null\' is not an object') && i <= 1 | |
# # discard message | |
# else | |
# real_error_messages << e | |
# end | |
#end | |
if real_error_messages.length > 0 | |
unless real_error_messages.first[:source].include?('https://a.stripecdn.com/manage/assets/application.manage') | |
raise "Javascript errors: #{real_error_messages}" | |
end | |
end | |
rescue | |
puts "Failed to check javascript error messages." | |
end | |
end | |
end | |
After do |scenario| | |
if (scenario.failed?) | |
print_console_messages scenario | |
end | |
end | |
def print_console_messages(scenario) | |
return unless webkit? | |
begin | |
messages = page.driver.console_messages | |
if messages.presence && messages.size > 0 | |
print "\n--------------------------------------------------------------------------------------------------------------------------------------------" | |
print "\nConsole: #{scenario_unique_name(scenario)}: " | |
print "\n---------------------------------------------------------------------------\n" | |
messages.each do |console_message| | |
print "\n" | |
print console_message[:message] | |
end | |
print "\n--------------------------------------------------------------------------------------------------------------------------------------------" | |
else | |
print "\n--------------------------------------------------------------------------------------------------------------------------------------------" | |
print "\nNo Console messages for: #{scenario_unique_name(scenario)}: " | |
print "\n--------------------------------------------------------------------------------------------------------------------------------------------" | |
end | |
$stdout.flush | |
rescue | |
puts "Failed to write console messages." | |
end | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Note that this code as affected by cucumber/common#52