From bbe0fa91d01fb9bc70d54e07ee393e857d92a267 Mon Sep 17 00:00:00 2001
From: Robert Speicher <rspeicher@gmail.com>
Date: Thu, 28 Jan 2016 20:45:03 -0500
Subject: [PATCH] Prevent transient Capybara timeouts during feature tests

The problem occurred because asset compilation takes a long time, so
when the asset cache didn't exist and the first test ran, it would often
(randomly) time out during the generation before the actual test even
had a chance to run.

Now we check if the cache exists before the suite runs, and if not, we
manually fire a request to the root URL in order to generate it. This
should allow subsequent tests to use the cached assets.
---
 features/support/capybara.rb |  8 ++++----
 spec/support/capybara.rb     |  6 ++++++
 spec/support/test_env.rb     | 17 ++++++++++++++++-
 3 files changed, 26 insertions(+), 5 deletions(-)

diff --git a/features/support/capybara.rb b/features/support/capybara.rb
index 4156c7ec484..38069ff8835 100644
--- a/features/support/capybara.rb
+++ b/features/support/capybara.rb
@@ -9,10 +9,6 @@ Capybara.register_driver :poltergeist do |app|
   Capybara::Poltergeist::Driver.new(app, js_errors: true, timeout: timeout)
 end
 
-Spinach.hooks.on_tag("javascript") do
-  Capybara.current_driver = Capybara.javascript_driver
-end
-
 Capybara.default_wait_time = timeout
 Capybara.ignore_hidden_elements = false
 
@@ -22,3 +18,7 @@ unless ENV['CI'] || ENV['CI_SERVER']
   # Keep only the screenshots generated from the last failing test suite
   Capybara::Screenshot.prune_strategy = :keep_last_run
 end
+
+Spinach.hooks.before_run do
+  TestEnv.warm_asset_cache
+end
diff --git a/spec/support/capybara.rb b/spec/support/capybara.rb
index fed1ab6ee33..a698f484df1 100644
--- a/spec/support/capybara.rb
+++ b/spec/support/capybara.rb
@@ -19,3 +19,9 @@ unless ENV['CI'] || ENV['CI_SERVER']
   # Keep only the screenshots generated from the last failing test suite
   Capybara::Screenshot.prune_strategy = :keep_last_run
 end
+
+RSpec.configure do |config|
+  config.before(:suite) do
+    TestEnv.warm_asset_cache
+  end
+end
diff --git a/spec/support/test_env.rb b/spec/support/test_env.rb
index 4f4743bff6d..0d1bd030f3c 100644
--- a/spec/support/test_env.rb
+++ b/spec/support/test_env.rb
@@ -146,6 +146,22 @@ module TestEnv
     FileUtils.chmod_R 0755, target_repo_path
   end
 
+  # When no cached assets exist, manually hit the root path to create them
+  #
+  # Otherwise they'd be created by the first test, often timing out and
+  # causing a transient test failure
+  def warm_asset_cache
+    return if warm_asset_cache?
+    return unless defined?(Capybara)
+
+    Capybara.current_session.driver.visit '/'
+  end
+
+  def warm_asset_cache?
+    cache = Rails.root.join(*%w(tmp cache assets test))
+    Dir.exist?(cache) && Dir.entries(cache).length > 2
+  end
+
   private
 
   def factory_repo_path
@@ -172,7 +188,6 @@ module TestEnv
     'gitlab-test-fork'
   end
 
-
   # Prevent developer git configurations from being persisted to test
   # repositories
   def git_env
-- 
GitLab